2010-01-06 18:58:55 -07:00
|
|
|
// 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.
|
|
|
|
|
[dev.cc] runtime: convert assembly files for C to Go transition
The main change is that #include "zasm_GOOS_GOARCH.h"
is now #include "go_asm.h" and/or #include "go_tls.h".
Also, because C StackGuard is now Go _StackGuard,
the assembly name changes from const_StackGuard to
const__StackGuard.
In asm_$GOARCH.s, add new function getg, formerly
implemented in C.
The renamed atomics now have Go wrappers, to get
escape analysis annotations right. Those wrappers
are in CL 174860043.
LGTM=r, aram
R=r, aram
CC=austin, dvyukov, golang-codereviews, iant, khr
https://golang.org/cl/168510043
2014-11-11 15:06:22 -07:00
|
|
|
#include "go_asm.h"
|
|
|
|
#include "go_tls.h"
|
2014-09-04 21:05:18 -06:00
|
|
|
#include "textflag.h"
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2011-08-27 07:17:00 -06:00
|
|
|
// void runtime·asmstdcall(void *c);
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·asmstdcall(SB),NOSPLIT,$0
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVL fn+0(FP), BX
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2011-08-27 07:17:00 -06:00
|
|
|
// SetLastError(0).
|
|
|
|
MOVL $0, 0x34(FS)
|
2010-09-11 19:45:16 -06:00
|
|
|
|
2011-08-27 07:17:00 -06:00
|
|
|
// Copy args to the stack.
|
2011-08-29 22:43:54 -06:00
|
|
|
MOVL SP, BP
|
2014-01-16 21:58:10 -07:00
|
|
|
MOVL libcall_n(BX), CX // words
|
2011-09-14 00:19:45 -06:00
|
|
|
MOVL CX, AX
|
|
|
|
SALL $2, AX
|
|
|
|
SUBL AX, SP // room for args
|
2010-09-11 19:45:16 -06:00
|
|
|
MOVL SP, DI
|
2014-01-16 21:58:10 -07:00
|
|
|
MOVL libcall_args(BX), SI
|
2010-06-11 02:38:12 -06:00
|
|
|
CLD
|
2010-09-11 19:45:16 -06:00
|
|
|
REP; MOVSL
|
|
|
|
|
2011-08-29 22:43:54 -06:00
|
|
|
// Call stdcall or cdecl function.
|
|
|
|
// DI SI BP BX are preserved, SP is not
|
2014-01-16 21:58:10 -07:00
|
|
|
CALL libcall_fn(BX)
|
2011-08-29 22:43:54 -06:00
|
|
|
MOVL BP, SP
|
2010-09-11 19:45:16 -06:00
|
|
|
|
2011-08-27 07:17:00 -06:00
|
|
|
// Return result.
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVL fn+0(FP), BX
|
2014-01-16 21:58:10 -07:00
|
|
|
MOVL AX, libcall_r1(BX)
|
|
|
|
MOVL DX, libcall_r2(BX)
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2011-08-27 07:17:00 -06:00
|
|
|
// GetLastError().
|
2011-09-14 00:19:45 -06:00
|
|
|
MOVL 0x34(FS), AX
|
2014-01-16 21:58:10 -07:00
|
|
|
MOVL AX, libcall_err(BX)
|
2010-09-11 19:45:16 -06:00
|
|
|
|
2011-01-20 07:21:04 -07:00
|
|
|
RET
|
2010-09-11 19:45:16 -06:00
|
|
|
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·badsignal2(SB),NOSPLIT,$24
|
2012-03-12 13:55:18 -06:00
|
|
|
// stderr
|
|
|
|
MOVL $-12, 0(SP)
|
|
|
|
MOVL SP, BP
|
2014-11-18 17:55:15 -07:00
|
|
|
CALL *runtime·_GetStdHandle(SB)
|
2012-03-12 13:55:18 -06:00
|
|
|
MOVL BP, SP
|
|
|
|
|
|
|
|
MOVL AX, 0(SP) // handle
|
|
|
|
MOVL $runtime·badsignalmsg(SB), DX // pointer
|
|
|
|
MOVL DX, 4(SP)
|
|
|
|
MOVL runtime·badsignallen(SB), DX // count
|
|
|
|
MOVL DX, 8(SP)
|
|
|
|
LEAL 20(SP), DX // written count
|
|
|
|
MOVL $0, 0(DX)
|
|
|
|
MOVL DX, 12(SP)
|
|
|
|
MOVL $0, 16(SP) // overlapped
|
2014-11-18 17:55:15 -07:00
|
|
|
CALL *runtime·_WriteFile(SB)
|
2012-03-12 13:55:18 -06:00
|
|
|
MOVL BP, SI
|
|
|
|
RET
|
|
|
|
|
2011-02-01 09:49:24 -07:00
|
|
|
// faster get/set last error
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·getlasterror(SB),NOSPLIT,$0
|
2011-02-01 09:49:24 -07:00
|
|
|
MOVL 0x34(FS), AX
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
MOVL AX, ret+0(FP)
|
2011-02-01 09:49:24 -07:00
|
|
|
RET
|
|
|
|
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·setlasterror(SB),NOSPLIT,$0
|
2011-02-01 09:49:24 -07:00
|
|
|
MOVL err+0(FP), AX
|
|
|
|
MOVL AX, 0x34(FS)
|
|
|
|
RET
|
|
|
|
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
// Called by Windows as a Vectored Exception Handler (VEH).
|
|
|
|
// First argument is pointer to struct containing
|
|
|
|
// exception record and context pointers.
|
2014-10-14 18:11:11 -06:00
|
|
|
// Handler function is stored in AX.
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
// Return 0 for 'not handled', -1 for handled.
|
|
|
|
TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
|
2014-03-28 00:35:00 -06:00
|
|
|
MOVL ptrs+0(FP), CX
|
2014-09-08 14:56:46 -06:00
|
|
|
SUBL $40, SP
|
2014-03-28 00:35:00 -06:00
|
|
|
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
// save callee-saved registers
|
2014-08-27 12:43:07 -06:00
|
|
|
MOVL BX, 28(SP)
|
2011-11-06 17:00:14 -07:00
|
|
|
MOVL BP, 16(SP)
|
|
|
|
MOVL SI, 20(SP)
|
|
|
|
MOVL DI, 24(SP)
|
2011-01-19 13:10:15 -07:00
|
|
|
|
2014-10-14 18:11:11 -06:00
|
|
|
MOVL AX, SI // save handler address
|
|
|
|
|
2014-09-08 14:56:46 -06:00
|
|
|
// find g
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
get_tls(DX)
|
2014-07-09 21:55:35 -06:00
|
|
|
CMPL DX, $0
|
|
|
|
JNE 3(PC)
|
|
|
|
MOVL $0, AX // continue
|
|
|
|
JMP done
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVL g(DX), DX
|
|
|
|
CMPL DX, $0
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
JNE 2(PC)
|
|
|
|
CALL runtime·badsignal2(SB)
|
2014-09-08 14:56:46 -06:00
|
|
|
|
|
|
|
// save g and SP in case of stack switch
|
|
|
|
MOVL DX, 32(SP) // g
|
|
|
|
MOVL SP, 36(SP)
|
|
|
|
|
|
|
|
// do we need to switch to the g0 stack?
|
|
|
|
MOVL g_m(DX), BX
|
|
|
|
MOVL m_g0(BX), BX
|
|
|
|
CMPL DX, BX
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
JEQ g0
|
2014-09-08 14:56:46 -06:00
|
|
|
|
|
|
|
// switch to the g0 stack
|
|
|
|
get_tls(BP)
|
|
|
|
MOVL BX, g(BP)
|
|
|
|
MOVL (g_sched+gobuf_sp)(BX), DI
|
|
|
|
// make it look like mstart called us on g0, to stop traceback
|
|
|
|
SUBL $4, DI
|
|
|
|
MOVL $runtime·mstart(SB), 0(DI)
|
|
|
|
// traceback will think that we've done SUBL
|
|
|
|
// on this stack, so subtract them here to match.
|
|
|
|
// (we need room for sighandler arguments anyway).
|
|
|
|
// and re-save old SP for restoring later.
|
|
|
|
SUBL $40, DI
|
|
|
|
MOVL SP, 36(DI)
|
|
|
|
MOVL DI, SP
|
|
|
|
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
g0:
|
2014-09-08 14:56:46 -06:00
|
|
|
MOVL 0(CX), BX // ExceptionRecord*
|
|
|
|
MOVL 4(CX), CX // Context*
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
MOVL BX, 0(SP)
|
|
|
|
MOVL CX, 4(SP)
|
|
|
|
MOVL DX, 8(SP)
|
2014-10-14 18:11:11 -06:00
|
|
|
CALL SI // call handler
|
2014-03-28 00:35:00 -06:00
|
|
|
// AX is set to report result back to Windows
|
2014-08-27 12:43:07 -06:00
|
|
|
MOVL 12(SP), AX
|
2011-01-19 13:10:15 -07:00
|
|
|
|
2014-09-08 14:56:46 -06:00
|
|
|
// switch back to original stack and g
|
|
|
|
// no-op if we never left.
|
|
|
|
MOVL 36(SP), SP
|
|
|
|
MOVL 32(SP), DX
|
|
|
|
get_tls(BP)
|
|
|
|
MOVL DX, g(BP)
|
|
|
|
|
2014-07-09 21:55:35 -06:00
|
|
|
done:
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
// restore callee-saved registers
|
2011-11-06 17:00:14 -07:00
|
|
|
MOVL 24(SP), DI
|
|
|
|
MOVL 20(SP), SI
|
|
|
|
MOVL 16(SP), BP
|
2014-08-27 12:43:07 -06:00
|
|
|
MOVL 28(SP), BX
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
|
2014-09-08 14:56:46 -06:00
|
|
|
ADDL $40, SP
|
runtime: use VEH, not SEH, for windows/386 exception handling
Structured Exception Handling (SEH) was the first way to handle
exceptions (memory faults, divides by zero) on Windows.
The S might as well stand for "stack-based": the implementation
interprets stack addresses in a few different ways, and it gets
subtly confused by Go's management of stacks. It's also something
that requires active maintenance during cgo switches, and we've
had bugs in that maintenance in the past.
We have recently come to believe that SEH cannot work with
Go's stack usage. See http://golang.org/issue/7325 for details.
Vectored Exception Handling (VEH) is more like a Unix signal
handler: you set it once for the whole process and forget about it.
This CL drops all the SEH code and replaces it with VEH code.
Many special cases and 7 #ifdefs disappear.
VEH was introduced in Windows XP, so Go on windows/386 will
now require Windows XP or later. The previous requirement was
Windows 2000 or later. Windows 2000 immediately preceded
Windows XP, so Windows 2000 is the only affected version.
Microsoft stopped supporting Windows 2000 in 2010.
See http://golang.org/s/win2000-golang-nuts for details.
Fixes #7325.
LGTM=alex.brainman, r
R=golang-codereviews, alex.brainman, stephen.gutekanst, dave
CC=golang-codereviews, iant, r
https://golang.org/cl/74790043
2014-03-24 19:22:16 -06:00
|
|
|
// RET 4 (return and pop 4 bytes parameters)
|
|
|
|
BYTE $0xC2; WORD $4
|
|
|
|
RET // unreached; make assembler happy
|
2017-02-03 17:26:13 -07:00
|
|
|
|
2014-10-14 18:11:11 -06:00
|
|
|
TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
|
|
|
|
MOVL $runtime·exceptionhandler(SB), AX
|
|
|
|
JMP runtime·sigtramp(SB)
|
|
|
|
|
|
|
|
TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
|
|
|
|
// is never called
|
|
|
|
INT $3
|
|
|
|
|
|
|
|
TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
|
|
|
|
MOVL $runtime·lastcontinuehandler(SB), AX
|
|
|
|
JMP runtime·sigtramp(SB)
|
2011-01-19 13:10:15 -07:00
|
|
|
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·ctrlhandler(SB),NOSPLIT,$0
|
2011-09-17 01:57:59 -06:00
|
|
|
PUSHL $runtime·ctrlhandler1(SB)
|
|
|
|
CALL runtime·externalthreadhandler(SB)
|
|
|
|
MOVL 4(SP), CX
|
|
|
|
ADDL $12, SP
|
|
|
|
JMP CX
|
|
|
|
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·profileloop(SB),NOSPLIT,$0
|
2011-09-17 01:57:59 -06:00
|
|
|
PUSHL $runtime·profileloop1(SB)
|
|
|
|
CALL runtime·externalthreadhandler(SB)
|
|
|
|
MOVL 4(SP), CX
|
2014-09-08 15:01:40 -06:00
|
|
|
ADDL $12, SP
|
2011-09-17 01:57:59 -06:00
|
|
|
JMP CX
|
|
|
|
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
|
2011-02-14 10:15:13 -07:00
|
|
|
PUSHL BP
|
|
|
|
MOVL SP, BP
|
|
|
|
PUSHL BX
|
|
|
|
PUSHL SI
|
|
|
|
PUSHL DI
|
2012-01-08 17:23:07 -07:00
|
|
|
PUSHL 0x14(FS)
|
2011-09-17 01:57:59 -06:00
|
|
|
MOVL SP, DX
|
2011-02-14 10:15:13 -07:00
|
|
|
|
|
|
|
// setup dummy m, g
|
2015-01-06 21:38:44 -07:00
|
|
|
SUBL $m__size, SP // space for M
|
2011-09-17 01:57:59 -06:00
|
|
|
MOVL SP, 0(SP)
|
2015-01-06 21:38:44 -07:00
|
|
|
MOVL $m__size, 4(SP)
|
2016-10-17 16:41:56 -06:00
|
|
|
CALL runtime·memclrNoHeapPointers(SB) // smashes AX,BX,CX
|
2011-09-17 01:57:59 -06:00
|
|
|
|
2011-02-14 10:15:13 -07:00
|
|
|
LEAL m_tls(SP), CX
|
2012-01-08 17:23:07 -07:00
|
|
|
MOVL CX, 0x14(FS)
|
2011-09-17 01:57:59 -06:00
|
|
|
MOVL SP, BX
|
2015-01-06 21:38:44 -07:00
|
|
|
SUBL $g__size, SP // space for G
|
2011-02-14 10:15:13 -07:00
|
|
|
MOVL SP, g(CX)
|
2011-09-17 01:57:59 -06:00
|
|
|
MOVL SP, m_g0(BX)
|
|
|
|
|
|
|
|
MOVL SP, 0(SP)
|
2015-01-06 21:38:44 -07:00
|
|
|
MOVL $g__size, 4(SP)
|
2016-10-17 16:41:56 -06:00
|
|
|
CALL runtime·memclrNoHeapPointers(SB) // smashes AX,BX,CX
|
2015-01-06 21:38:44 -07:00
|
|
|
LEAL g__size(SP), BX
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVL BX, g_m(SP)
|
2016-01-06 10:17:46 -07:00
|
|
|
|
|
|
|
LEAL -32768(SP), CX // must be less than SizeOfStackReserve set by linker
|
2014-09-09 12:02:37 -06:00
|
|
|
MOVL CX, (g_stack+stack_lo)(SP)
|
2014-11-18 17:55:15 -07:00
|
|
|
ADDL $const__StackGuard, CX
|
2015-01-05 09:29:21 -07:00
|
|
|
MOVL CX, g_stackguard0(SP)
|
|
|
|
MOVL CX, g_stackguard1(SP)
|
2014-09-09 12:02:37 -06:00
|
|
|
MOVL DX, (g_stack+stack_hi)(SP)
|
2011-02-14 10:15:13 -07:00
|
|
|
|
2015-04-13 18:48:05 -06:00
|
|
|
PUSHL AX // room for return value
|
2011-09-17 01:57:59 -06:00
|
|
|
PUSHL 16(BP) // arg for handler
|
|
|
|
CALL 8(BP)
|
2011-02-14 10:15:13 -07:00
|
|
|
POPL CX
|
2015-04-13 18:48:05 -06:00
|
|
|
POPL AX // pass return value to Windows in AX
|
2011-02-14 10:15:13 -07:00
|
|
|
|
|
|
|
get_tls(CX)
|
|
|
|
MOVL g(CX), CX
|
2014-09-09 12:02:37 -06:00
|
|
|
MOVL (g_stack+stack_hi)(CX), SP
|
2012-01-08 17:23:07 -07:00
|
|
|
POPL 0x14(FS)
|
2011-02-14 10:15:13 -07:00
|
|
|
POPL DI
|
|
|
|
POPL SI
|
|
|
|
POPL BX
|
|
|
|
POPL BP
|
2011-09-17 01:57:59 -06:00
|
|
|
RET
|
2011-02-14 10:15:13 -07:00
|
|
|
|
2014-09-24 17:04:06 -06:00
|
|
|
GLOBL runtime·cbctxts(SB), NOPTR, $4
|
2013-06-24 01:17:45 -06:00
|
|
|
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·callbackasm1+0(SB),NOSPLIT,$0
|
2013-06-24 01:17:45 -06:00
|
|
|
MOVL 0(SP), AX // will use to find our callback context
|
|
|
|
|
|
|
|
// remove return address from stack, we are not returning there
|
|
|
|
ADDL $4, SP
|
|
|
|
|
|
|
|
// address to callback parameters into CX
|
|
|
|
LEAL 4(SP), CX
|
2011-01-21 19:55:53 -07:00
|
|
|
|
2011-02-01 09:49:24 -07:00
|
|
|
// save registers as required for windows callback
|
|
|
|
PUSHL DI
|
|
|
|
PUSHL SI
|
|
|
|
PUSHL BP
|
|
|
|
PUSHL BX
|
2011-08-10 01:17:28 -06:00
|
|
|
|
2013-06-24 01:17:45 -06:00
|
|
|
// determine index into runtime·cbctxts table
|
|
|
|
SUBL $runtime·callbackasm(SB), AX
|
|
|
|
MOVL $0, DX
|
|
|
|
MOVL $5, BX // divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
|
2015-02-16 22:48:31 -07:00
|
|
|
DIVL BX
|
2011-02-01 09:49:24 -07:00
|
|
|
|
2013-06-24 01:17:45 -06:00
|
|
|
// find correspondent runtime·cbctxts table entry
|
|
|
|
MOVL runtime·cbctxts(SB), BX
|
|
|
|
MOVL -4(BX)(AX*4), BX
|
2011-01-21 19:55:53 -07:00
|
|
|
|
2013-06-24 01:17:45 -06:00
|
|
|
// extract callback context
|
2014-11-18 17:55:15 -07:00
|
|
|
MOVL wincallbackcontext_gobody(BX), AX
|
|
|
|
MOVL wincallbackcontext_argsize(BX), DX
|
2011-01-21 19:55:53 -07:00
|
|
|
|
2013-06-24 01:17:45 -06:00
|
|
|
// preserve whatever's at the memory location that
|
|
|
|
// the callback will use to store the return value
|
|
|
|
PUSHL 0(CX)(DX*1)
|
|
|
|
|
|
|
|
// extend argsize by size of return value
|
|
|
|
ADDL $4, DX
|
|
|
|
|
|
|
|
// remember how to restore stack on return
|
2014-11-18 17:55:15 -07:00
|
|
|
MOVL wincallbackcontext_restorestack(BX), BX
|
2013-06-24 01:17:45 -06:00
|
|
|
PUSHL BX
|
|
|
|
|
|
|
|
// call target Go function
|
|
|
|
PUSHL DX // argsize (including return value)
|
|
|
|
PUSHL CX // callback parameters
|
|
|
|
PUSHL AX // address of target Go function
|
|
|
|
CLD
|
|
|
|
CALL runtime·cgocallback_gofunc(SB)
|
2011-02-10 05:02:27 -07:00
|
|
|
POPL AX
|
2011-02-01 09:49:24 -07:00
|
|
|
POPL CX
|
|
|
|
POPL DX
|
2011-08-10 01:17:28 -06:00
|
|
|
|
2013-06-24 01:17:45 -06:00
|
|
|
// how to restore stack on return
|
|
|
|
POPL BX
|
|
|
|
|
|
|
|
// return value into AX (as per Windows spec)
|
|
|
|
// and restore previously preserved value
|
|
|
|
MOVL -4(CX)(DX*1), AX
|
|
|
|
POPL -4(CX)(DX*1)
|
|
|
|
|
|
|
|
MOVL BX, CX // cannot use BX anymore
|
|
|
|
|
2011-08-10 01:17:28 -06:00
|
|
|
// restore registers as required for windows callback
|
2011-02-01 09:49:24 -07:00
|
|
|
POPL BX
|
|
|
|
POPL BP
|
|
|
|
POPL SI
|
|
|
|
POPL DI
|
2011-08-10 01:17:28 -06:00
|
|
|
|
2013-06-24 01:17:45 -06:00
|
|
|
// remove callback parameters before return (as per Windows spec)
|
|
|
|
POPL DX
|
|
|
|
ADDL CX, SP
|
|
|
|
PUSHL DX
|
|
|
|
|
2011-01-21 19:55:53 -07:00
|
|
|
CLD
|
|
|
|
|
2011-02-01 09:49:24 -07:00
|
|
|
RET
|
2011-01-21 19:55:53 -07:00
|
|
|
|
2010-09-11 19:45:16 -06:00
|
|
|
// void tstart(M *newm);
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·tstart(SB),NOSPLIT,$0
|
2016-09-29 22:34:44 -06:00
|
|
|
MOVL newm+0(FP), CX // m
|
2010-09-11 19:45:16 -06:00
|
|
|
MOVL m_g0(CX), DX // g
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2010-09-11 19:45:16 -06:00
|
|
|
// Layout new m scheduler stack on os stack.
|
|
|
|
MOVL SP, AX
|
2014-09-09 12:02:37 -06:00
|
|
|
MOVL AX, (g_stack+stack_hi)(DX)
|
2011-01-24 23:56:33 -07:00
|
|
|
SUBL $(64*1024), AX // stack size
|
2014-09-09 12:02:37 -06:00
|
|
|
MOVL AX, (g_stack+stack_lo)(DX)
|
2014-11-18 17:55:15 -07:00
|
|
|
ADDL $const__StackGuard, AX
|
2015-01-05 09:29:21 -07:00
|
|
|
MOVL AX, g_stackguard0(DX)
|
|
|
|
MOVL AX, g_stackguard1(DX)
|
2010-09-11 19:45:16 -06:00
|
|
|
|
|
|
|
// Set up tls.
|
2010-01-06 18:58:55 -07:00
|
|
|
LEAL m_tls(CX), SI
|
2012-01-08 17:23:07 -07:00
|
|
|
MOVL SI, 0x14(FS)
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVL CX, g_m(DX)
|
2010-01-06 18:58:55 -07:00
|
|
|
MOVL DX, g(SI)
|
|
|
|
|
2010-09-11 19:45:16 -06:00
|
|
|
// Someday the convention will be D is always cleared.
|
|
|
|
CLD
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2011-01-20 07:21:04 -07:00
|
|
|
CALL runtime·stackcheck(SB) // clobbers AX,CX
|
2013-03-01 09:44:43 -07:00
|
|
|
CALL runtime·mstart(SB)
|
2010-09-11 19:45:16 -06:00
|
|
|
|
|
|
|
RET
|
|
|
|
|
|
|
|
// uint32 tstart_stdcall(M *newm);
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
|
2016-09-29 22:34:44 -06:00
|
|
|
MOVL newm+0(FP), BX
|
2010-09-11 19:45:16 -06:00
|
|
|
|
|
|
|
PUSHL BX
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
CALL runtime·tstart(SB)
|
2010-09-11 19:45:16 -06:00
|
|
|
POPL BX
|
|
|
|
|
|
|
|
// Adjust stack for stdcall to return properly.
|
|
|
|
MOVL (SP), AX // save return address
|
|
|
|
ADDL $4, SP // remove single parameter
|
|
|
|
MOVL AX, (SP) // restore return address
|
|
|
|
|
|
|
|
XORL AX, AX // return 0 == success
|
|
|
|
|
2010-01-06 18:58:55 -07:00
|
|
|
RET
|
|
|
|
|
|
|
|
// setldt(int entry, int address, int limit)
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·setldt(SB),NOSPLIT,$0
|
2010-01-06 18:58:55 -07:00
|
|
|
MOVL address+4(FP), CX
|
2012-01-08 17:23:07 -07:00
|
|
|
MOVL CX, 0x14(FS)
|
2010-01-06 18:58:55 -07:00
|
|
|
RET
|
2012-05-29 23:10:54 -06:00
|
|
|
|
2016-03-29 23:33:52 -06:00
|
|
|
// onosstack calls fn on OS stack.
|
|
|
|
// func onosstack(fn unsafe.Pointer, arg uint32)
|
|
|
|
TEXT runtime·onosstack(SB),NOSPLIT,$0
|
|
|
|
MOVL fn+0(FP), AX // to hide from 8l
|
|
|
|
MOVL arg+4(FP), BX
|
2013-07-15 20:36:05 -06:00
|
|
|
|
|
|
|
// Execute call on m->g0 stack, in case we are not actually
|
|
|
|
// calling a system call wrapper, like when running under WINE.
|
|
|
|
get_tls(CX)
|
|
|
|
CMPL CX, $0
|
|
|
|
JNE 3(PC)
|
|
|
|
// Not a Go-managed thread. Do not switch stack.
|
2013-03-07 07:18:48 -07:00
|
|
|
CALL AX
|
|
|
|
RET
|
|
|
|
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVL g(CX), BP
|
|
|
|
MOVL g_m(BP), BP
|
2014-02-12 11:31:36 -07:00
|
|
|
|
|
|
|
// leave pc/sp for cpu profiler
|
|
|
|
MOVL (SP), SI
|
|
|
|
MOVL SI, m_libcallpc(BP)
|
2014-02-13 22:20:51 -07:00
|
|
|
MOVL g(CX), SI
|
|
|
|
MOVL SI, m_libcallg(BP)
|
|
|
|
// sp must be the last, because once async cpu profiler finds
|
|
|
|
// all three values to be non-zero, it will use them
|
cmd/cc, runtime: convert C compilers to use Go calling convention
To date, the C compilers and Go compilers differed only in how
values were returned from functions. This made it difficult to call
Go from C or C from Go if return values were involved. It also made
assembly called from Go and assembly called from C different.
This CL changes the C compiler to use the Go conventions, passing
results on the stack, after the arguments.
[Exception: this does not apply to C ... functions, because you can't
know where on the stack the arguments end.]
By doing this, the CL makes it possible to rewrite C functions into Go
one at a time, without worrying about which languages call that
function or which languages it calls.
This CL also updates all the assembly files in package runtime to use
the new conventions. Argument references of the form 40(SP) have
been rewritten to the form name+10(FP) instead, and there are now
Go func prototypes for every assembly function called from C or Go.
This means that 'go vet runtime' checks effectively every assembly
function, and go vet's output was used to automate the bulk of the
conversion.
Some functions, like seek and nsec on Plan 9, needed to be rewritten.
Many assembly routines called from C were reading arguments
incorrectly, using MOVL instead of MOVQ or vice versa, especially on
the less used systems like openbsd.
These were found by go vet and have been corrected too.
If we're lucky, this may reduce flakiness on those systems.
Tested on:
darwin/386
darwin/amd64
linux/arm
linux/386
linux/amd64
If this breaks another system, the bug is almost certainly in the
sys_$GOOS_$GOARCH.s file, since the rest of the CL is tested
by the combination of the above systems.
LGTM=dvyukov, iant
R=golang-codereviews, 0intro, dave, alex.brainman, dvyukov, iant
CC=golang-codereviews, josharian, r
https://golang.org/cl/135830043
2014-08-27 09:32:17 -06:00
|
|
|
LEAL usec+0(FP), SI
|
2014-02-12 11:31:36 -07:00
|
|
|
MOVL SI, m_libcallsp(BP)
|
|
|
|
|
2013-07-15 20:36:05 -06:00
|
|
|
MOVL m_g0(BP), SI
|
|
|
|
CMPL g(CX), SI
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
JNE switch
|
2013-07-15 20:36:05 -06:00
|
|
|
// executing on m->g0 already
|
|
|
|
CALL AX
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
JMP ret
|
2013-07-15 20:36:05 -06:00
|
|
|
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
switch:
|
2013-07-15 20:36:05 -06:00
|
|
|
// Switch to m->g0 stack and back.
|
|
|
|
MOVL (g_sched+gobuf_sp)(SI), SI
|
|
|
|
MOVL SP, -4(SI)
|
|
|
|
LEAL -4(SI), SP
|
|
|
|
CALL AX
|
|
|
|
MOVL 0(SP), SP
|
2014-02-12 11:31:36 -07:00
|
|
|
|
[dev.power64] cmd/5a, cmd/6a, cmd/8a, cmd/9a: make labels function-scoped
I removed support for jumping between functions years ago,
as part of doing the instruction layout for each function separately.
Given that, it makes sense to treat labels as function-scoped.
This lets each function have its own 'loop' label, for example.
Makes the assembly much cleaner and removes the last
reason anyone would reach for the 123(PC) form instead.
Note that this is on the dev.power64 branch, but it changes all
the assemblers. The change will ship in Go 1.5 (perhaps after
being ported into the new assembler).
Came up as part of CL 167730043.
LGTM=r
R=r
CC=austin, dave, golang-codereviews, minux
https://golang.org/cl/159670043
2014-10-28 19:50:16 -06:00
|
|
|
ret:
|
2014-02-12 11:31:36 -07:00
|
|
|
get_tls(CX)
|
all: remove 'extern register M *m' from runtime
The runtime has historically held two dedicated values g (current goroutine)
and m (current thread) in 'extern register' slots (TLS on x86, real registers
backed by TLS on ARM).
This CL removes the extern register m; code now uses g->m.
On ARM, this frees up the register that formerly held m (R9).
This is important for NaCl, because NaCl ARM code cannot use R9 at all.
The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected:
BenchmarkBinaryTree17 5491374955 5471024381 -0.37%
BenchmarkFannkuch11 4357101311 4275174828 -1.88%
BenchmarkGobDecode 11029957 11364184 +3.03%
BenchmarkGobEncode 6852205 6784822 -0.98%
BenchmarkGzip 650795967 650152275 -0.10%
BenchmarkGunzip 140962363 141041670 +0.06%
BenchmarkHTTPClientServer 71581 73081 +2.10%
BenchmarkJSONEncode 31928079 31913356 -0.05%
BenchmarkJSONDecode 117470065 113689916 -3.22%
BenchmarkMandelbrot200 6008923 5998712 -0.17%
BenchmarkGoParse 6310917 6327487 +0.26%
BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17%
BenchmarkRegexpMatchHard_1K 168977 169244 +0.16%
BenchmarkRevcomp 935294971 914060918 -2.27%
BenchmarkTemplate 145917123 148186096 +1.55%
Minux previous reported larger variations, but these were caused by
run-to-run noise, not repeatable slowdowns.
Actual code changes by Minux.
I only did the docs and the benchmarking.
LGTM=dvyukov, iant, minux
R=minux, josharian, iant, dave, bradfitz, dvyukov
CC=golang-codereviews
https://golang.org/cl/109050043
2014-06-26 09:54:39 -06:00
|
|
|
MOVL g(CX), BP
|
|
|
|
MOVL g_m(BP), BP
|
2014-02-12 11:31:36 -07:00
|
|
|
MOVL $0, m_libcallsp(BP)
|
2013-07-15 20:36:05 -06:00
|
|
|
RET
|
|
|
|
|
|
|
|
// Runs on OS stack. duration (in 100ns units) is in BX.
|
2013-08-07 13:20:05 -06:00
|
|
|
TEXT runtime·usleep2(SB),NOSPLIT,$20
|
2013-07-15 20:36:05 -06:00
|
|
|
// Want negative 100ns units.
|
2013-03-07 07:18:48 -07:00
|
|
|
NEGL BX
|
|
|
|
MOVL $-1, hi-4(SP)
|
|
|
|
MOVL BX, lo-8(SP)
|
|
|
|
LEAL lo-8(SP), BX
|
|
|
|
MOVL BX, ptime-12(SP)
|
|
|
|
MOVL $0, alertable-16(SP)
|
|
|
|
MOVL $-1, handle-20(SP)
|
|
|
|
MOVL SP, BP
|
2014-11-18 17:55:15 -07:00
|
|
|
MOVL runtime·_NtWaitForSingleObject(SB), AX
|
2013-03-07 07:18:48 -07:00
|
|
|
CALL AX
|
|
|
|
MOVL BP, SP
|
|
|
|
RET
|
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
2014-09-07 21:40:59 -06:00
|
|
|
|
2016-03-29 23:33:52 -06:00
|
|
|
// Runs on OS stack.
|
|
|
|
TEXT runtime·switchtothread(SB),NOSPLIT,$0
|
|
|
|
MOVL SP, BP
|
|
|
|
MOVL runtime·_SwitchToThread(SB), AX
|
|
|
|
CALL AX
|
|
|
|
MOVL BP, SP
|
|
|
|
RET
|
|
|
|
|
2017-02-03 17:26:13 -07:00
|
|
|
// See http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
|
|
|
|
// Must read hi1, then lo, then hi2. The snapshot is valid if hi1 == hi2.
|
|
|
|
#define _INTERRUPT_TIME 0x7ffe0008
|
|
|
|
#define _SYSTEM_TIME 0x7ffe0014
|
|
|
|
#define time_lo 0
|
|
|
|
#define time_hi1 4
|
|
|
|
#define time_hi2 8
|
|
|
|
|
|
|
|
TEXT runtime·nanotime(SB),NOSPLIT,$0-8
|
2017-04-20 07:51:36 -06:00
|
|
|
CMPB runtime·useQPCTime(SB), $0
|
|
|
|
JNE useQPC
|
2017-02-03 17:26:13 -07:00
|
|
|
loop:
|
|
|
|
MOVL (_INTERRUPT_TIME+time_hi1), AX
|
|
|
|
MOVL (_INTERRUPT_TIME+time_lo), CX
|
|
|
|
MOVL (_INTERRUPT_TIME+time_hi2), DI
|
|
|
|
CMPL AX, DI
|
|
|
|
JNE loop
|
|
|
|
|
|
|
|
// wintime = DI:CX, multiply by 100
|
|
|
|
MOVL $100, AX
|
|
|
|
MULL CX
|
|
|
|
IMULL $100, DI
|
|
|
|
ADDL DI, DX
|
|
|
|
// wintime*100 = DX:AX, subtract startNano and return
|
|
|
|
SUBL runtime·startNano+0(SB), AX
|
2017-02-20 23:54:39 -07:00
|
|
|
SBBL runtime·startNano+4(SB), DX
|
|
|
|
MOVL AX, ret_lo+0(FP)
|
|
|
|
MOVL DX, ret_hi+4(FP)
|
2017-02-03 17:26:13 -07:00
|
|
|
RET
|
2017-04-20 07:51:36 -06:00
|
|
|
useQPC:
|
|
|
|
JMP runtime·nanotimeQPC(SB)
|
|
|
|
RET
|
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
2014-09-07 21:40:59 -06:00
|
|
|
|
2017-02-03 17:26:13 -07:00
|
|
|
TEXT time·now(SB),NOSPLIT,$0-20
|
2017-04-20 07:51:36 -06:00
|
|
|
CMPB runtime·useQPCTime(SB), $0
|
|
|
|
JNE useQPC
|
2017-02-03 17:26:13 -07:00
|
|
|
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
|
|
|
|
// subtract startNano and save for return
|
|
|
|
SUBL runtime·startNano+0(SB), AX
|
2017-04-20 07:51:36 -06:00
|
|
|
SBBL runtime·startNano+4(SB), DX
|
2017-02-03 17:26:13 -07:00
|
|
|
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.)
|
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
2014-09-07 21:40:59 -06:00
|
|
|
MOVL $1000000000, CX
|
|
|
|
DIVL CX
|
2017-02-03 17:26:13 -07:00
|
|
|
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
|
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
2014-09-07 21:40:59 -06:00
|
|
|
MOVL AX, sec+0(FP)
|
2017-02-03 17:26:13 -07:00
|
|
|
MOVL DX, sec+4(FP)
|
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
2014-09-07 21:40:59 -06:00
|
|
|
RET
|
2017-04-20 07:51:36 -06:00
|
|
|
useQPC:
|
|
|
|
JMP runtime·nowQPC(SB)
|
|
|
|
RET
|