| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build !faketime |
| |
| #include "go_asm.h" |
| #include "textflag.h" |
| #include "time_windows.h" |
| |
| TEXT time·now(SB),NOSPLIT,$0-20 |
| loop: |
| MOVL (_INTERRUPT_TIME+time_hi1), AX |
| MOVL (_INTERRUPT_TIME+time_lo), CX |
| MOVL (_INTERRUPT_TIME+time_hi2), DI |
| CMPL AX, DI |
| JNE loop |
| |
| // w = DI:CX |
| // multiply by 100 |
| MOVL $100, AX |
| MULL CX |
| IMULL $100, DI |
| ADDL DI, DX |
| // w*100 = DX:AX |
| MOVL AX, mono+12(FP) |
| MOVL DX, mono+16(FP) |
| |
| wall: |
| MOVL (_SYSTEM_TIME+time_hi1), CX |
| MOVL (_SYSTEM_TIME+time_lo), AX |
| MOVL (_SYSTEM_TIME+time_hi2), DX |
| CMPL CX, DX |
| JNE wall |
| |
| // w = DX:AX |
| // convert to Unix epoch (but still 100ns units) |
| #define delta 116444736000000000 |
| SUBL $(delta & 0xFFFFFFFF), AX |
| SBBL $(delta >> 32), DX |
| |
| // nano/100 = DX:AX |
| // split into two decimal halves by div 1e9. |
| // (decimal point is two spots over from correct place, |
| // but we avoid overflow in the high word.) |
| MOVL $1000000000, CX |
| DIVL CX |
| MOVL AX, DI |
| MOVL DX, SI |
| |
| // DI = nano/100/1e9 = nano/1e11 = sec/100, DX = SI = nano/100%1e9 |
| // split DX into seconds and nanoseconds by div 1e7 magic multiply. |
| MOVL DX, AX |
| MOVL $1801439851, CX |
| MULL CX |
| SHRL $22, DX |
| MOVL DX, BX |
| IMULL $10000000, DX |
| MOVL SI, CX |
| SUBL DX, CX |
| |
| // DI = sec/100 (still) |
| // BX = (nano/100%1e9)/1e7 = (nano/1e9)%100 = sec%100 |
| // CX = (nano/100%1e9)%1e7 = (nano%1e9)/100 = nsec/100 |
| // store nsec for return |
| IMULL $100, CX |
| MOVL CX, nsec+8(FP) |
| |
| // DI = sec/100 (still) |
| // BX = sec%100 |
| // construct DX:AX = 64-bit sec and store for return |
| MOVL $0, DX |
| MOVL $100, AX |
| MULL DI |
| ADDL BX, AX |
| ADCL $0, DX |
| MOVL AX, sec+0(FP) |
| MOVL DX, sec+4(FP) |
| RET |