Commit 13d0b82b authored by Russ Cox's avatar Russ Cox

runtime: implement time.now in assembly on plan9, solaris, windows

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
parent 50fc0f1a
...@@ -160,19 +160,6 @@ runtime·nanotime(void) ...@@ -160,19 +160,6 @@ runtime·nanotime(void)
return ns; 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 #pragma textflag NOSPLIT
void void
runtime·itoa(int32 n, byte *p, uint32 len) runtime·itoa(int32 n, byte *p, uint32 len)
......
...@@ -436,19 +436,6 @@ runtime·nanotime(void) ...@@ -436,19 +436,6 @@ runtime·nanotime(void)
return runtime·sysvicall0((uintptr)runtime·nanotime1); 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 #pragma textflag NOSPLIT
int32 int32
runtime·open(int8* path, int32 oflag, int32 mode) runtime·open(int8* path, int32 oflag, int32 mode)
......
...@@ -301,6 +301,13 @@ runtime·systime(KSYSTEM_TIME *timeaddr) ...@@ -301,6 +301,13 @@ runtime·systime(KSYSTEM_TIME *timeaddr)
return 0; return 0;
} }
#pragma textflag NOSPLIT
int64
runtime·unixnano(void)
{
return (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
}
static void static void
badsystime(void) badsystime(void)
{ {
...@@ -314,22 +321,6 @@ runtime·nanotime(void) ...@@ -314,22 +321,6 @@ runtime·nanotime(void)
return runtime·systime(INTERRUPT_TIME) * 100LL; 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. // Calling stdcall on os stack.
#pragma textflag NOSPLIT #pragma textflag NOSPLIT
static void* static void*
......
...@@ -158,7 +158,7 @@ TEXT runtime·nanotime(SB),NOSPLIT,$0-8 ...@@ -158,7 +158,7 @@ TEXT runtime·nanotime(SB),NOSPLIT,$0-8
RET RET
// func now() (sec int64, nsec int32) // func now() (sec int64, nsec int32)
TEXT time·now(SB),NOSPLIT,$8 TEXT time·now(SB),NOSPLIT,$0-12
CALL nanotime<>(SB) CALL nanotime<>(SB)
// generated code for // generated code for
......
...@@ -101,6 +101,19 @@ TEXT runtime·nsec(SB),NOSPLIT,$8 ...@@ -101,6 +101,19 @@ TEXT runtime·nsec(SB),NOSPLIT,$8
MOVL $-1, ret_hi+8(FP) MOVL $-1, ret_hi+8(FP)
RET 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 TEXT runtime·notify(SB),NOSPLIT,$0
MOVL $28, AX MOVL $28, AX
INT $64 INT $64
......
...@@ -91,6 +91,26 @@ TEXT runtime·nsec(SB),NOSPLIT,$0 ...@@ -91,6 +91,26 @@ TEXT runtime·nsec(SB),NOSPLIT,$0
MOVQ AX, ret+8(FP) MOVQ AX, ret+8(FP)
RET 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 TEXT runtime·notify(SB),NOSPLIT,$0
MOVQ $28, BP MOVQ $28, BP
SYSCALL SYSCALL
......
...@@ -327,3 +327,23 @@ TEXT runtime·osyield1(SB),NOSPLIT,$0 ...@@ -327,3 +327,23 @@ TEXT runtime·osyield1(SB),NOSPLIT,$0
MOVQ libc·sched_yield(SB), AX MOVQ libc·sched_yield(SB), AX
CALL AX CALL AX
RET 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
...@@ -365,3 +365,16 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20 ...@@ -365,3 +365,16 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20
CALL AX CALL AX
MOVL BP, SP MOVL BP, SP
RET 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
...@@ -384,3 +384,24 @@ TEXT runtime·usleep2(SB),NOSPLIT,$16 ...@@ -384,3 +384,24 @@ TEXT runtime·usleep2(SB),NOSPLIT,$16
CALL AX CALL AX
MOVQ 8(SP), SP MOVQ 8(SP), SP
RET 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment