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.
9 #include "time_windows.h"
11 TEXT time·now(SB),NOSPLIT,$0-20
12 MOVW $_INTERRUPT_TIME, R3
22 // wintime = R1:R0, multiply by 100
24 MULLU R0, R2, (R4, R3) // R4:R3 = R1:R0 * R2
27 // wintime*100 = R4:R3
31 MOVW $_SYSTEM_TIME, R3
41 // w = R1:R0 in 100ns untis
42 // convert to Unix epoch (but still 100ns units)
43 #define delta 116444736000000000
44 SUB.S $(delta & 0xFFFFFFFF), R0
45 SBC $(delta >> 32), R1
49 MULLU R0, R2, (R4, R3) // R4:R3 = R1:R0 * R2
52 MOVW R3, R1 // R4:R3 -> R2:R1
55 // multiply nanoseconds by reciprocal of 10**9 (scaled by 2**61)
56 // to get seconds (96 bit scaled result)
57 MOVW $0x89705f41, R3 // 2**61 * 10**-9
58 MULLU R1,R3,(R6,R5) // R7:R6:R5 = R2:R1 * R3
62 // unscale by discarding low 32 bits, shifting the rest by 29
63 MOVW R6>>29,R6 // R7:R6 = (R7:R6:R5 >> 61)
67 // subtract (10**9 * sec) from nsec to get nanosecond remainder
68 MOVW $1000000000, R5 // 10**9
69 MULLU R6,R5,(R9,R8) // R9:R8 = R7:R6 * R5
71 SUB.S R8,R1 // R2:R1 -= R9:R8
74 // because reciprocal was a truncated repeating fraction, quotient
75 // may be slightly too small -- adjust to make remainder < 10**9
76 CMP R5,R1 // if remainder > 10**9
77 SUB.HS R5,R1 // remainder -= 10**9
78 ADD.HS $1,R6 // sec += 1