github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/time_windows_arm.s (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !faketime
     6  // +build !faketime
     7  
     8  #include "go_asm.h"
     9  #include "textflag.h"
    10  #include "time_windows.h"
    11  
    12  TEXT time·now(SB),NOSPLIT|NOFRAME,$0-20
    13  	MOVW    $0, R0
    14  	MOVB    runtime·useQPCTime(SB), R0
    15  	CMP	$0, R0
    16  	BNE	useQPC
    17  	MOVW	$_INTERRUPT_TIME, R3
    18  loop:
    19  	MOVW	time_hi1(R3), R1
    20  	DMB	MB_ISH
    21  	MOVW	time_lo(R3), R0
    22  	DMB	MB_ISH
    23  	MOVW	time_hi2(R3), R2
    24  	CMP	R1, R2
    25  	BNE	loop
    26  
    27  	// wintime = R1:R0, multiply by 100
    28  	MOVW	$100, R2
    29  	MULLU	R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
    30  	MULA	R1, R2, R4, R4
    31  
    32  	// wintime*100 = R4:R3
    33  	MOVW	R3, mono+12(FP)
    34  	MOVW	R4, mono+16(FP)
    35  
    36  	MOVW	$_SYSTEM_TIME, R3
    37  wall:
    38  	MOVW	time_hi1(R3), R1
    39  	DMB	MB_ISH
    40  	MOVW	time_lo(R3), R0
    41  	DMB	MB_ISH
    42  	MOVW	time_hi2(R3), R2
    43  	CMP	R1, R2
    44  	BNE	wall
    45  
    46  	// w = R1:R0 in 100ns untis
    47  	// convert to Unix epoch (but still 100ns units)
    48  	#define delta 116444736000000000
    49  	SUB.S   $(delta & 0xFFFFFFFF), R0
    50  	SBC     $(delta >> 32), R1
    51  
    52  	// Convert to nSec
    53  	MOVW    $100, R2
    54  	MULLU   R0, R2, (R4, R3)    // R4:R3 = R1:R0 * R2
    55  	MULA    R1, R2, R4, R4
    56  	// w = R2:R1 in nSec
    57  	MOVW    R3, R1	      // R4:R3 -> R2:R1
    58  	MOVW    R4, R2
    59  
    60  	// multiply nanoseconds by reciprocal of 10**9 (scaled by 2**61)
    61  	// to get seconds (96 bit scaled result)
    62  	MOVW	$0x89705f41, R3		// 2**61 * 10**-9
    63  	MULLU	R1,R3,(R6,R5)		// R7:R6:R5 = R2:R1 * R3
    64  	MOVW	$0,R7
    65  	MULALU	R2,R3,(R7,R6)
    66  
    67  	// unscale by discarding low 32 bits, shifting the rest by 29
    68  	MOVW	R6>>29,R6		// R7:R6 = (R7:R6:R5 >> 61)
    69  	ORR	R7<<3,R6
    70  	MOVW	R7>>29,R7
    71  
    72  	// subtract (10**9 * sec) from nsec to get nanosecond remainder
    73  	MOVW	$1000000000, R5	// 10**9
    74  	MULLU	R6,R5,(R9,R8)   // R9:R8 = R7:R6 * R5
    75  	MULA	R7,R5,R9,R9
    76  	SUB.S	R8,R1		// R2:R1 -= R9:R8
    77  	SBC	R9,R2
    78  
    79  	// because reciprocal was a truncated repeating fraction, quotient
    80  	// may be slightly too small -- adjust to make remainder < 10**9
    81  	CMP	R5,R1	// if remainder > 10**9
    82  	SUB.HS	R5,R1   //    remainder -= 10**9
    83  	ADD.HS	$1,R6	//    sec += 1
    84  
    85  	MOVW	R6,sec_lo+0(FP)
    86  	MOVW	R7,sec_hi+4(FP)
    87  	MOVW	R1,nsec+8(FP)
    88  	RET
    89  useQPC:
    90  	B	runtime·nowQPC(SB)		// tail call
    91