1// Copyright 2009 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
7#include "go_asm.h"
8#include "textflag.h"
9#include "time_windows.h"
10
11TEXT time·now(SB),NOSPLIT,$0-20
12loop:
13	MOVL	(_INTERRUPT_TIME+time_hi1), AX
14	MOVL	(_INTERRUPT_TIME+time_lo), CX
15	MOVL	(_INTERRUPT_TIME+time_hi2), DI
16	CMPL	AX, DI
17	JNE	loop
18
19	// w = DI:CX
20	// multiply by 100
21	MOVL	$100, AX
22	MULL	CX
23	IMULL	$100, DI
24	ADDL	DI, DX
25	// w*100 = DX:AX
26	MOVL	AX, mono+12(FP)
27	MOVL	DX, mono+16(FP)
28
29wall:
30	MOVL	(_SYSTEM_TIME+time_hi1), CX
31	MOVL	(_SYSTEM_TIME+time_lo), AX
32	MOVL	(_SYSTEM_TIME+time_hi2), DX
33	CMPL	CX, DX
34	JNE	wall
35
36	// w = DX:AX
37	// convert to Unix epoch (but still 100ns units)
38	#define delta 116444736000000000
39	SUBL	$(delta & 0xFFFFFFFF), AX
40	SBBL $(delta >> 32), DX
41
42	// nano/100 = DX:AX
43	// split into two decimal halves by div 1e9.
44	// (decimal point is two spots over from correct place,
45	// but we avoid overflow in the high word.)
46	MOVL	$1000000000, CX
47	DIVL	CX
48	MOVL	AX, DI
49	MOVL	DX, SI
50
51	// DI = nano/100/1e9 = nano/1e11 = sec/100, DX = SI = nano/100%1e9
52	// split DX into seconds and nanoseconds by div 1e7 magic multiply.
53	MOVL	DX, AX
54	MOVL	$1801439851, CX
55	MULL	CX
56	SHRL	$22, DX
57	MOVL	DX, BX
58	IMULL	$10000000, DX
59	MOVL	SI, CX
60	SUBL	DX, CX
61
62	// DI = sec/100 (still)
63	// BX = (nano/100%1e9)/1e7 = (nano/1e9)%100 = sec%100
64	// CX = (nano/100%1e9)%1e7 = (nano%1e9)/100 = nsec/100
65	// store nsec for return
66	IMULL	$100, CX
67	MOVL	CX, nsec+8(FP)
68
69	// DI = sec/100 (still)
70	// BX = sec%100
71	// construct DX:AX = 64-bit sec and store for return
72	MOVL	$0, DX
73	MOVL	$100, AX
74	MULL	DI
75	ADDL	BX, AX
76	ADCL	$0, DX
77	MOVL	AX, sec+0(FP)
78	MOVL	DX, sec+4(FP)
79	RET
80