]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: implement time.now in assembly on plan9, solaris, windows
authorRuss Cox <rsc@golang.org>
Mon, 8 Sep 2014 03:40:59 +0000 (23:40 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 8 Sep 2014 03:40:59 +0000 (23:40 -0400)
These all used a C implementation that contained 64-bit divide by 1000000000.
On 32-bit systems that ends up in the 64-bit C divide support, which makes
other calls and ends up using a fair amount of stack. We could convert them
to Go but then they'd still end up in software 64-bit divide code. That would
be okay, because Go code can split the stack, but it's still unnecessary.

Write time·now in assembly, just like on all the other systems, and use the
actual hardware support for 64/32 -> 64/32 division. This cuts the software
routines out entirely.

The actual code to do the division is copied and pasted from the sys_darwin_*.s files.

LGTM=alex.brainman
R=golang-codereviews, alex.brainman
CC=aram, golang-codereviews, iant, khr, r
https://golang.org/cl/136300043

src/pkg/runtime/os_plan9.c
src/pkg/runtime/os_solaris.c
src/pkg/runtime/os_windows.c
src/pkg/runtime/sys_darwin_amd64.s
src/pkg/runtime/sys_plan9_386.s
src/pkg/runtime/sys_plan9_amd64.s
src/pkg/runtime/sys_solaris_amd64.s
src/pkg/runtime/sys_windows_386.s
src/pkg/runtime/sys_windows_amd64.s

index f82471079307322ea0685ba532981a0abaa2e378..853f3ef7a17ae9d79a44b91e6b02517f061672cd 100644 (file)
@@ -160,19 +160,6 @@ runtime·nanotime(void)
        return ns;
 }
 
-#pragma textflag NOSPLIT
-void
-time·now(int64 sec, int32 nsec)
-{
-       int64 ns;
-
-       ns = runtime·nanotime();
-       sec = ns / 1000000000LL;
-       nsec = ns - sec * 1000000000LL;
-       FLUSH(&sec);
-       FLUSH(&nsec);
-}
-
 #pragma textflag NOSPLIT
 void
 runtime·itoa(int32 n, byte *p, uint32 len)
index c6c2a8a7a13e1463397ca16f5743c3778ef3784a..e35d2b9971846d63ea7b8bfa3c1f4b27537fd8c3 100644 (file)
@@ -436,19 +436,6 @@ runtime·nanotime(void)
        return runtime·sysvicall0((uintptr)runtime·nanotime1);
 }
 
-#pragma textflag NOSPLIT
-void
-time·now(int64 sec, int32 usec)
-{
-       int64 ns;
-
-       ns = runtime·nanotime();
-       sec = ns / 1000000000LL;
-       usec = ns - sec * 1000000000LL;
-       FLUSH(&sec);
-       FLUSH(&usec);
-}
-
 #pragma textflag NOSPLIT
 int32
 runtime·open(int8* path, int32 oflag, int32 mode)
index d7f7a5a3b430ef54affd1e3019545666376218b0..a4d77f6b753cf31f03fab3f922f1dee4365e92c8 100644 (file)
@@ -301,6 +301,13 @@ runtime·systime(KSYSTEM_TIME *timeaddr)
        return 0;
 }
 
+#pragma textflag NOSPLIT
+int64
+runtime·unixnano(void)
+{
+       return (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
+}
+
 static void
 badsystime(void)
 {
@@ -314,22 +321,6 @@ runtime·nanotime(void)
        return runtime·systime(INTERRUPT_TIME) * 100LL;
 }
 
-#pragma textflag NOSPLIT
-void
-time·now(int64 sec, int32 usec)
-{
-       int64 ns;
-
-       // SystemTime is 100s of nanoseconds since January 1, 1601.
-       // Convert to nanoseconds since January 1, 1970.
-       ns = (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
-
-       sec = ns / 1000000000LL;
-       usec = ns - sec * 1000000000LL;
-       FLUSH(&sec);
-       FLUSH(&usec);
-}
-
 // Calling stdcall on os stack.
 #pragma textflag NOSPLIT
 static void*
index 2f98bfb06cf36f0c4f61cc14bffbfe5f2b5cb8d1..bd397d72a76ae538f81b938499a6b8574fa83c68 100644 (file)
@@ -158,7 +158,7 @@ TEXT runtime·nanotime(SB),NOSPLIT,$0-8
        RET
 
 // func now() (sec int64, nsec int32)
-TEXT time·now(SB),NOSPLIT,$8
+TEXT time·now(SB),NOSPLIT,$0-12
        CALL    nanotime<>(SB)
 
        // generated code for
index dfa09613e411b358a531c325437df46765a9f89a..7432981813885437ff3de88e257010ed9e8cb384 100644 (file)
@@ -101,6 +101,19 @@ TEXT runtime·nsec(SB),NOSPLIT,$8
        MOVL    $-1, ret_hi+8(FP)
        RET
 
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+       CALL    runtime·nanotime(SB)
+       MOVL    0(SP), AX
+       MOVL    4(SP), DX
+
+       MOVL    $1000000000, CX
+       DIVL    CX
+       MOVL    AX, sec+0(FP)
+       MOVL    $0, sec+4(FP)
+       MOVL    DX, nsec+8(FP)
+       RET
+
 TEXT runtime·notify(SB),NOSPLIT,$0
        MOVL    $28, AX
        INT     $64
index 08ddc3ffa812daf2f87fe850329122316d664920..954c0c27bb5309babb2d9e3e28708a99a19107ab 100644 (file)
@@ -91,6 +91,26 @@ TEXT runtime·nsec(SB),NOSPLIT,$0
        MOVQ    AX, ret+8(FP)
        RET
 
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+       CALL    runtime·nanotime(SB)
+       MOVQ    0(SP), AX
+
+       // generated code for
+       //      func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+       // adapted to reduce duplication
+       MOVQ    AX, CX
+       MOVQ    $1360296554856532783, AX
+       MULQ    CX
+       ADDQ    CX, DX
+       RCRQ    $1, DX
+       SHRQ    $29, DX
+       MOVQ    DX, sec+0(FP)
+       IMULQ   $1000000000, DX
+       SUBQ    DX, CX
+       MOVL    CX, nsec+8(FP)
+       RET
+
 TEXT runtime·notify(SB),NOSPLIT,$0
        MOVQ    $28, BP
        SYSCALL
index 2055d6c80b26c154c6062e4059f42edc283efad9..093315c4a46aa069edb8a48f0977e7a511fddda0 100644 (file)
@@ -327,3 +327,23 @@ TEXT runtime·osyield1(SB),NOSPLIT,$0
        MOVQ    libc·sched_yield(SB), AX
        CALL    AX
        RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+       CALL    runtime·nanotime(SB)
+       MOVQ    0(SP), AX
+
+       // generated code for
+       //      func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+       // adapted to reduce duplication
+       MOVQ    AX, CX
+       MOVQ    $1360296554856532783, AX
+       MULQ    CX
+       ADDQ    CX, DX
+       RCRQ    $1, DX
+       SHRQ    $29, DX
+       MOVQ    DX, sec+0(FP)
+       IMULQ   $1000000000, DX
+       SUBQ    DX, CX
+       MOVL    CX, nsec+8(FP)
+       RET
index f4d561feea42dccc385d1fc759652305021c0a45..a9e096f018f6a4184f48e6e7eb4361227949a68a 100644 (file)
@@ -365,3 +365,16 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20
        CALL    AX
        MOVL    BP, SP
        RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+       CALL    runtime·unixnano(SB)
+       MOVL    0(SP), AX
+       MOVL    4(SP), DX
+
+       MOVL    $1000000000, CX
+       DIVL    CX
+       MOVL    AX, sec+0(FP)
+       MOVL    $0, sec+4(FP)
+       MOVL    DX, nsec+8(FP)
+       RET
index e5890e04ae637cd42fba3cafd1cff28c0c0e46df..21f73daf098764551193634f8065f41f376bcfb2 100644 (file)
@@ -384,3 +384,24 @@ TEXT runtime·usleep2(SB),NOSPLIT,$16
        CALL    AX
        MOVQ    8(SP), SP
        RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+       CALL    runtime·unixnano(SB)
+       MOVQ    0(SP), AX
+
+       // generated code for
+       //      func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+       // adapted to reduce duplication
+       MOVQ    AX, CX
+       MOVQ    $1360296554856532783, AX
+       MULQ    CX
+       ADDQ    CX, DX
+       RCRQ    $1, DX
+       SHRQ    $29, DX
+       MOVQ    DX, sec+0(FP)
+       IMULQ   $1000000000, DX
+       SUBQ    DX, CX
+       MOVL    CX, nsec+8(FP)
+       RET
+