...

Text file src/runtime/asm_386.s

Documentation: runtime

     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#include "go_asm.h"
     6#include "go_tls.h"
     7#include "funcdata.h"
     8#include "textflag.h"
     9
    10// _rt0_386 is common startup code for most 386 systems when using
    11// internal linking. This is the entry point for the program from the
    12// kernel for an ordinary -buildmode=exe program. The stack holds the
    13// number of arguments and the C-style argv.
    14TEXT _rt0_386(SB),NOSPLIT,$8
    15	MOVL	8(SP), AX	// argc
    16	LEAL	12(SP), BX	// argv
    17	MOVL	AX, 0(SP)
    18	MOVL	BX, 4(SP)
    19	JMP	runtime·rt0_go(SB)
    20
    21// _rt0_386_lib is common startup code for most 386 systems when
    22// using -buildmode=c-archive or -buildmode=c-shared. The linker will
    23// arrange to invoke this function as a global constructor (for
    24// c-archive) or when the shared library is loaded (for c-shared).
    25// We expect argc and argv to be passed on the stack following the
    26// usual C ABI.
    27TEXT _rt0_386_lib(SB),NOSPLIT,$0
    28	PUSHL	BP
    29	MOVL	SP, BP
    30	PUSHL	BX
    31	PUSHL	SI
    32	PUSHL	DI
    33
    34	MOVL	8(BP), AX
    35	MOVL	AX, _rt0_386_lib_argc<>(SB)
    36	MOVL	12(BP), AX
    37	MOVL	AX, _rt0_386_lib_argv<>(SB)
    38
    39	// Synchronous initialization.
    40	CALL	runtime·libpreinit(SB)
    41
    42	SUBL	$8, SP
    43
    44	// Create a new thread to do the runtime initialization.
    45	MOVL	_cgo_sys_thread_create(SB), AX
    46	TESTL	AX, AX
    47	JZ	nocgo
    48
    49	// Align stack to call C function.
    50	// We moved SP to BP above, but BP was clobbered by the libpreinit call.
    51	MOVL	SP, BP
    52	ANDL	$~15, SP
    53
    54	MOVL	$_rt0_386_lib_go(SB), BX
    55	MOVL	BX, 0(SP)
    56	MOVL	$0, 4(SP)
    57
    58	CALL	AX
    59
    60	MOVL	BP, SP
    61
    62	JMP	restore
    63
    64nocgo:
    65	MOVL	$0x800000, 0(SP)                    // stacksize = 8192KB
    66	MOVL	$_rt0_386_lib_go(SB), AX
    67	MOVL	AX, 4(SP)                           // fn
    68	CALL	runtime·newosproc0(SB)
    69
    70restore:
    71	ADDL	$8, SP
    72	POPL	DI
    73	POPL	SI
    74	POPL	BX
    75	POPL	BP
    76	RET
    77
    78// _rt0_386_lib_go initializes the Go runtime.
    79// This is started in a separate thread by _rt0_386_lib.
    80TEXT _rt0_386_lib_go(SB),NOSPLIT,$8
    81	MOVL	_rt0_386_lib_argc<>(SB), AX
    82	MOVL	AX, 0(SP)
    83	MOVL	_rt0_386_lib_argv<>(SB), AX
    84	MOVL	AX, 4(SP)
    85	JMP	runtime·rt0_go(SB)
    86
    87DATA _rt0_386_lib_argc<>(SB)/4, $0
    88GLOBL _rt0_386_lib_argc<>(SB),NOPTR, $4
    89DATA _rt0_386_lib_argv<>(SB)/4, $0
    90GLOBL _rt0_386_lib_argv<>(SB),NOPTR, $4
    91
    92TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
    93	// Copy arguments forward on an even stack.
    94	// Users of this function jump to it, they don't call it.
    95	MOVL	0(SP), AX
    96	MOVL	4(SP), BX
    97	SUBL	$128, SP		// plenty of scratch
    98	ANDL	$~15, SP
    99	MOVL	AX, 120(SP)		// save argc, argv away
   100	MOVL	BX, 124(SP)
   101
   102	// set default stack bounds.
   103	// _cgo_init may update stackguard.
   104	MOVL	$runtime·g0(SB), BP
   105	LEAL	(-64*1024+104)(SP), BX
   106	MOVL	BX, g_stackguard0(BP)
   107	MOVL	BX, g_stackguard1(BP)
   108	MOVL	BX, (g_stack+stack_lo)(BP)
   109	MOVL	SP, (g_stack+stack_hi)(BP)
   110
   111	// find out information about the processor we're on
   112	// first see if CPUID instruction is supported.
   113	PUSHFL
   114	PUSHFL
   115	XORL	$(1<<21), 0(SP) // flip ID bit
   116	POPFL
   117	PUSHFL
   118	POPL	AX
   119	XORL	0(SP), AX
   120	POPFL	// restore EFLAGS
   121	TESTL	$(1<<21), AX
   122	JNE 	has_cpuid
   123
   124bad_proc: // show that the program requires MMX.
   125	MOVL	$2, 0(SP)
   126	MOVL	$bad_proc_msg<>(SB), 4(SP)
   127	MOVL	$0x3d, 8(SP)
   128	CALL	runtime·write(SB)
   129	MOVL	$1, 0(SP)
   130	CALL	runtime·exit(SB)
   131	CALL	runtime·abort(SB)
   132
   133has_cpuid:
   134	MOVL	$0, AX
   135	CPUID
   136	MOVL	AX, SI
   137	CMPL	AX, $0
   138	JE	nocpuinfo
   139
   140	CMPL	BX, $0x756E6547  // "Genu"
   141	JNE	notintel
   142	CMPL	DX, $0x49656E69  // "ineI"
   143	JNE	notintel
   144	CMPL	CX, $0x6C65746E  // "ntel"
   145	JNE	notintel
   146	MOVB	$1, runtime·isIntel(SB)
   147notintel:
   148
   149	// Load EAX=1 cpuid flags
   150	MOVL	$1, AX
   151	CPUID
   152	MOVL	CX, DI // Move to global variable clobbers CX when generating PIC
   153	MOVL	AX, runtime·processorVersionInfo(SB)
   154
   155	// Check for MMX support
   156	TESTL	$(1<<23), DX // MMX
   157	JZ	bad_proc
   158
   159nocpuinfo:
   160	// if there is an _cgo_init, call it to let it
   161	// initialize and to set up GS.  if not,
   162	// we set up GS ourselves.
   163	MOVL	_cgo_init(SB), AX
   164	TESTL	AX, AX
   165	JZ	needtls
   166#ifdef GOOS_android
   167	// arg 4: TLS base, stored in slot 0 (Android's TLS_SLOT_SELF).
   168	// Compensate for tls_g (+8).
   169	MOVL	-8(TLS), BX
   170	MOVL	BX, 12(SP)
   171	MOVL	$runtime·tls_g(SB), 8(SP)	// arg 3: &tls_g
   172#else
   173	MOVL	$0, BX
   174	MOVL	BX, 12(SP)	// arg 4: not used when using platform's TLS
   175#ifdef GOOS_windows
   176	MOVL	$runtime·tls_g(SB), 8(SP)	// arg 3: &tls_g
   177#else
   178	MOVL	BX, 8(SP)	// arg 3: not used when using platform's TLS
   179#endif
   180#endif
   181	MOVL	$setg_gcc<>(SB), BX
   182	MOVL	BX, 4(SP)	// arg 2: setg_gcc
   183	MOVL	BP, 0(SP)	// arg 1: g0
   184	CALL	AX
   185
   186	// update stackguard after _cgo_init
   187	MOVL	$runtime·g0(SB), CX
   188	MOVL	(g_stack+stack_lo)(CX), AX
   189	ADDL	$const_stackGuard, AX
   190	MOVL	AX, g_stackguard0(CX)
   191	MOVL	AX, g_stackguard1(CX)
   192
   193#ifndef GOOS_windows
   194	// skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
   195	JMP ok
   196#endif
   197needtls:
   198#ifdef GOOS_openbsd
   199	// skip runtime·ldt0setup(SB) and tls test on OpenBSD in all cases
   200	JMP	ok
   201#endif
   202#ifdef GOOS_plan9
   203	// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
   204	JMP	ok
   205#endif
   206
   207	// set up %gs
   208	CALL	ldt0setup<>(SB)
   209
   210	// store through it, to make sure it works
   211	get_tls(BX)
   212	MOVL	$0x123, g(BX)
   213	MOVL	runtime·m0+m_tls(SB), AX
   214	CMPL	AX, $0x123
   215	JEQ	ok
   216	MOVL	AX, 0	// abort
   217ok:
   218	// set up m and g "registers"
   219	get_tls(BX)
   220	LEAL	runtime·g0(SB), DX
   221	MOVL	DX, g(BX)
   222	LEAL	runtime·m0(SB), AX
   223
   224	// save m->g0 = g0
   225	MOVL	DX, m_g0(AX)
   226	// save g0->m = m0
   227	MOVL	AX, g_m(DX)
   228
   229	CALL	runtime·emptyfunc(SB)	// fault if stack check is wrong
   230
   231	// convention is D is always cleared
   232	CLD
   233
   234	CALL	runtime·check(SB)
   235
   236	// saved argc, argv
   237	MOVL	120(SP), AX
   238	MOVL	AX, 0(SP)
   239	MOVL	124(SP), AX
   240	MOVL	AX, 4(SP)
   241	CALL	runtime·args(SB)
   242	CALL	runtime·osinit(SB)
   243	CALL	runtime·schedinit(SB)
   244
   245	// create a new goroutine to start program
   246	PUSHL	$runtime·mainPC(SB)	// entry
   247	CALL	runtime·newproc(SB)
   248	POPL	AX
   249
   250	// start this M
   251	CALL	runtime·mstart(SB)
   252
   253	CALL	runtime·abort(SB)
   254	RET
   255
   256DATA	bad_proc_msg<>+0x00(SB)/61, $"This program can only be run on processors with MMX support.\n"
   257GLOBL	bad_proc_msg<>(SB), RODATA, $61
   258
   259DATA	runtime·mainPC+0(SB)/4,$runtime·main(SB)
   260GLOBL	runtime·mainPC(SB),RODATA,$4
   261
   262TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
   263	INT $3
   264	RET
   265
   266TEXT runtime·asminit(SB),NOSPLIT,$0-0
   267	// Linux and MinGW start the FPU in extended double precision.
   268	// Other operating systems use double precision.
   269	// Change to double precision to match them,
   270	// and to match other hardware that only has double.
   271	FLDCW	runtime·controlWord64(SB)
   272	RET
   273
   274TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
   275	CALL	runtime·mstart0(SB)
   276	RET // not reached
   277
   278/*
   279 *  go-routine
   280 */
   281
   282// void gogo(Gobuf*)
   283// restore state from Gobuf; longjmp
   284TEXT runtime·gogo(SB), NOSPLIT, $0-4
   285	MOVL	buf+0(FP), BX		// gobuf
   286	MOVL	gobuf_g(BX), DX
   287	MOVL	0(DX), CX		// make sure g != nil
   288	JMP	gogo<>(SB)
   289
   290TEXT gogo<>(SB), NOSPLIT, $0
   291	get_tls(CX)
   292	MOVL	DX, g(CX)
   293	MOVL	gobuf_sp(BX), SP	// restore SP
   294	MOVL	gobuf_ret(BX), AX
   295	MOVL	gobuf_ctxt(BX), DX
   296	MOVL	$0, gobuf_sp(BX)	// clear to help garbage collector
   297	MOVL	$0, gobuf_ret(BX)
   298	MOVL	$0, gobuf_ctxt(BX)
   299	MOVL	gobuf_pc(BX), BX
   300	JMP	BX
   301
   302// func mcall(fn func(*g))
   303// Switch to m->g0's stack, call fn(g).
   304// Fn must never return. It should gogo(&g->sched)
   305// to keep running g.
   306TEXT runtime·mcall(SB), NOSPLIT, $0-4
   307	MOVL	fn+0(FP), DI
   308
   309	get_tls(DX)
   310	MOVL	g(DX), AX	// save state in g->sched
   311	MOVL	0(SP), BX	// caller's PC
   312	MOVL	BX, (g_sched+gobuf_pc)(AX)
   313	LEAL	fn+0(FP), BX	// caller's SP
   314	MOVL	BX, (g_sched+gobuf_sp)(AX)
   315
   316	// switch to m->g0 & its stack, call fn
   317	MOVL	g(DX), BX
   318	MOVL	g_m(BX), BX
   319	MOVL	m_g0(BX), SI
   320	CMPL	SI, AX	// if g == m->g0 call badmcall
   321	JNE	3(PC)
   322	MOVL	$runtime·badmcall(SB), AX
   323	JMP	AX
   324	MOVL	SI, g(DX)	// g = m->g0
   325	MOVL	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
   326	PUSHL	AX
   327	MOVL	DI, DX
   328	MOVL	0(DI), DI
   329	CALL	DI
   330	POPL	AX
   331	MOVL	$runtime·badmcall2(SB), AX
   332	JMP	AX
   333	RET
   334
   335// systemstack_switch is a dummy routine that systemstack leaves at the bottom
   336// of the G stack. We need to distinguish the routine that
   337// lives at the bottom of the G stack from the one that lives
   338// at the top of the system stack because the one at the top of
   339// the system stack terminates the stack walk (see topofstack()).
   340TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   341	RET
   342
   343// func systemstack(fn func())
   344TEXT runtime·systemstack(SB), NOSPLIT, $0-4
   345	MOVL	fn+0(FP), DI	// DI = fn
   346	get_tls(CX)
   347	MOVL	g(CX), AX	// AX = g
   348	MOVL	g_m(AX), BX	// BX = m
   349
   350	CMPL	AX, m_gsignal(BX)
   351	JEQ	noswitch
   352
   353	MOVL	m_g0(BX), DX	// DX = g0
   354	CMPL	AX, DX
   355	JEQ	noswitch
   356
   357	CMPL	AX, m_curg(BX)
   358	JNE	bad
   359
   360	// switch stacks
   361	// save our state in g->sched. Pretend to
   362	// be systemstack_switch if the G stack is scanned.
   363	CALL	gosave_systemstack_switch<>(SB)
   364
   365	// switch to g0
   366	get_tls(CX)
   367	MOVL	DX, g(CX)
   368	MOVL	(g_sched+gobuf_sp)(DX), BX
   369	MOVL	BX, SP
   370
   371	// call target function
   372	MOVL	DI, DX
   373	MOVL	0(DI), DI
   374	CALL	DI
   375
   376	// switch back to g
   377	get_tls(CX)
   378	MOVL	g(CX), AX
   379	MOVL	g_m(AX), BX
   380	MOVL	m_curg(BX), AX
   381	MOVL	AX, g(CX)
   382	MOVL	(g_sched+gobuf_sp)(AX), SP
   383	MOVL	$0, (g_sched+gobuf_sp)(AX)
   384	RET
   385
   386noswitch:
   387	// already on system stack; tail call the function
   388	// Using a tail call here cleans up tracebacks since we won't stop
   389	// at an intermediate systemstack.
   390	MOVL	DI, DX
   391	MOVL	0(DI), DI
   392	JMP	DI
   393
   394bad:
   395	// Bad: g is not gsignal, not g0, not curg. What is it?
   396	// Hide call from linker nosplit analysis.
   397	MOVL	$runtime·badsystemstack(SB), AX
   398	CALL	AX
   399	INT	$3
   400
   401// func switchToCrashStack0(fn func())
   402TEXT runtime·switchToCrashStack0(SB), NOSPLIT, $0-4
   403	MOVL 	fn+0(FP), AX
   404
   405	get_tls(CX)
   406	MOVL	g(CX), BX	// BX = g
   407	MOVL	g_m(BX), DX	// DX = curm
   408
   409	// set g to gcrash
   410	LEAL	runtime·gcrash(SB), BX // g = &gcrash
   411	MOVL	DX, g_m(BX)            // g.m = curm
   412	MOVL	BX, m_g0(DX)           // curm.g0 = g
   413	get_tls(CX)
   414	MOVL	BX, g(CX)
   415
   416	// switch to crashstack
   417	MOVL	(g_stack+stack_hi)(BX), DX
   418	SUBL	$(4*8), DX
   419	MOVL	DX, SP
   420
   421	// call target function
   422	MOVL	AX, DX
   423	MOVL	0(AX), AX
   424	CALL	AX
   425
   426	// should never return
   427	CALL	runtime·abort(SB)
   428	UNDEF
   429
   430/*
   431 * support for morestack
   432 */
   433
   434// Called during function prolog when more stack is needed.
   435//
   436// The traceback routines see morestack on a g0 as being
   437// the top of a stack (for example, morestack calling newstack
   438// calling the scheduler calling newm calling gc), so we must
   439// record an argument size. For that purpose, it has no arguments.
   440TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   441	// Cannot grow scheduler stack (m->g0).
   442	get_tls(CX)
   443	MOVL	g(CX), DI
   444	MOVL	g_m(DI), BX
   445
   446	// Set g->sched to context in f.
   447	MOVL	0(SP), AX	// f's PC
   448	MOVL	AX, (g_sched+gobuf_pc)(DI)
   449	LEAL	4(SP), AX	// f's SP
   450	MOVL	AX, (g_sched+gobuf_sp)(DI)
   451	MOVL	DX, (g_sched+gobuf_ctxt)(DI)
   452
   453	MOVL	m_g0(BX), SI
   454	CMPL	g(CX), SI
   455	JNE	3(PC)
   456	CALL	runtime·badmorestackg0(SB)
   457	CALL	runtime·abort(SB)
   458
   459	// Cannot grow signal stack.
   460	MOVL	m_gsignal(BX), SI
   461	CMPL	g(CX), SI
   462	JNE	3(PC)
   463	CALL	runtime·badmorestackgsignal(SB)
   464	CALL	runtime·abort(SB)
   465
   466	// Called from f.
   467	// Set m->morebuf to f's caller.
   468	NOP	SP	// tell vet SP changed - stop checking offsets
   469	MOVL	4(SP), DI	// f's caller's PC
   470	MOVL	DI, (m_morebuf+gobuf_pc)(BX)
   471	LEAL	8(SP), CX	// f's caller's SP
   472	MOVL	CX, (m_morebuf+gobuf_sp)(BX)
   473	get_tls(CX)
   474	MOVL	g(CX), SI
   475	MOVL	SI, (m_morebuf+gobuf_g)(BX)
   476
   477	// Call newstack on m->g0's stack.
   478	MOVL	m_g0(BX), BP
   479	MOVL	BP, g(CX)
   480	MOVL	(g_sched+gobuf_sp)(BP), AX
   481	MOVL	-4(AX), BX	// fault if CALL would, before smashing SP
   482	MOVL	AX, SP
   483	CALL	runtime·newstack(SB)
   484	CALL	runtime·abort(SB)	// crash if newstack returns
   485	RET
   486
   487TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
   488	MOVL	$0, DX
   489	JMP runtime·morestack(SB)
   490
   491// reflectcall: call a function with the given argument list
   492// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
   493// we don't have variable-sized frames, so we use a small number
   494// of constant-sized-frame functions to encode a few bits of size in the pc.
   495// Caution: ugly multiline assembly macros in your future!
   496
   497#define DISPATCH(NAME,MAXSIZE)		\
   498	CMPL	CX, $MAXSIZE;		\
   499	JA	3(PC);			\
   500	MOVL	$NAME(SB), AX;		\
   501	JMP	AX
   502// Note: can't just "JMP NAME(SB)" - bad inlining results.
   503
   504TEXT ·reflectcall(SB), NOSPLIT, $0-28
   505	MOVL	frameSize+20(FP), CX
   506	DISPATCH(runtime·call16, 16)
   507	DISPATCH(runtime·call32, 32)
   508	DISPATCH(runtime·call64, 64)
   509	DISPATCH(runtime·call128, 128)
   510	DISPATCH(runtime·call256, 256)
   511	DISPATCH(runtime·call512, 512)
   512	DISPATCH(runtime·call1024, 1024)
   513	DISPATCH(runtime·call2048, 2048)
   514	DISPATCH(runtime·call4096, 4096)
   515	DISPATCH(runtime·call8192, 8192)
   516	DISPATCH(runtime·call16384, 16384)
   517	DISPATCH(runtime·call32768, 32768)
   518	DISPATCH(runtime·call65536, 65536)
   519	DISPATCH(runtime·call131072, 131072)
   520	DISPATCH(runtime·call262144, 262144)
   521	DISPATCH(runtime·call524288, 524288)
   522	DISPATCH(runtime·call1048576, 1048576)
   523	DISPATCH(runtime·call2097152, 2097152)
   524	DISPATCH(runtime·call4194304, 4194304)
   525	DISPATCH(runtime·call8388608, 8388608)
   526	DISPATCH(runtime·call16777216, 16777216)
   527	DISPATCH(runtime·call33554432, 33554432)
   528	DISPATCH(runtime·call67108864, 67108864)
   529	DISPATCH(runtime·call134217728, 134217728)
   530	DISPATCH(runtime·call268435456, 268435456)
   531	DISPATCH(runtime·call536870912, 536870912)
   532	DISPATCH(runtime·call1073741824, 1073741824)
   533	MOVL	$runtime·badreflectcall(SB), AX
   534	JMP	AX
   535
   536#define CALLFN(NAME,MAXSIZE)			\
   537TEXT NAME(SB), WRAPPER, $MAXSIZE-28;		\
   538	NO_LOCAL_POINTERS;			\
   539	/* copy arguments to stack */		\
   540	MOVL	stackArgs+8(FP), SI;		\
   541	MOVL	stackArgsSize+12(FP), CX;		\
   542	MOVL	SP, DI;				\
   543	REP;MOVSB;				\
   544	/* call function */			\
   545	MOVL	f+4(FP), DX;			\
   546	MOVL	(DX), AX; 			\
   547	PCDATA  $PCDATA_StackMapIndex, $0;	\
   548	CALL	AX;				\
   549	/* copy return values back */		\
   550	MOVL	stackArgsType+0(FP), DX;		\
   551	MOVL	stackArgs+8(FP), DI;		\
   552	MOVL	stackArgsSize+12(FP), CX;		\
   553	MOVL	stackRetOffset+16(FP), BX;		\
   554	MOVL	SP, SI;				\
   555	ADDL	BX, DI;				\
   556	ADDL	BX, SI;				\
   557	SUBL	BX, CX;				\
   558	CALL	callRet<>(SB);			\
   559	RET
   560
   561// callRet copies return values back at the end of call*. This is a
   562// separate function so it can allocate stack space for the arguments
   563// to reflectcallmove. It does not follow the Go ABI; it expects its
   564// arguments in registers.
   565TEXT callRet<>(SB), NOSPLIT, $20-0
   566	MOVL	DX, 0(SP)
   567	MOVL	DI, 4(SP)
   568	MOVL	SI, 8(SP)
   569	MOVL	CX, 12(SP)
   570	MOVL	$0, 16(SP)
   571	CALL	runtime·reflectcallmove(SB)
   572	RET
   573
   574CALLFN(·call16, 16)
   575CALLFN(·call32, 32)
   576CALLFN(·call64, 64)
   577CALLFN(·call128, 128)
   578CALLFN(·call256, 256)
   579CALLFN(·call512, 512)
   580CALLFN(·call1024, 1024)
   581CALLFN(·call2048, 2048)
   582CALLFN(·call4096, 4096)
   583CALLFN(·call8192, 8192)
   584CALLFN(·call16384, 16384)
   585CALLFN(·call32768, 32768)
   586CALLFN(·call65536, 65536)
   587CALLFN(·call131072, 131072)
   588CALLFN(·call262144, 262144)
   589CALLFN(·call524288, 524288)
   590CALLFN(·call1048576, 1048576)
   591CALLFN(·call2097152, 2097152)
   592CALLFN(·call4194304, 4194304)
   593CALLFN(·call8388608, 8388608)
   594CALLFN(·call16777216, 16777216)
   595CALLFN(·call33554432, 33554432)
   596CALLFN(·call67108864, 67108864)
   597CALLFN(·call134217728, 134217728)
   598CALLFN(·call268435456, 268435456)
   599CALLFN(·call536870912, 536870912)
   600CALLFN(·call1073741824, 1073741824)
   601
   602TEXT runtime·procyield(SB),NOSPLIT,$0-0
   603	MOVL	cycles+0(FP), AX
   604again:
   605	PAUSE
   606	SUBL	$1, AX
   607	JNZ	again
   608	RET
   609
   610TEXT ·publicationBarrier(SB),NOSPLIT,$0-0
   611	// Stores are already ordered on x86, so this is just a
   612	// compile barrier.
   613	RET
   614
   615// Save state of caller into g->sched,
   616// but using fake PC from systemstack_switch.
   617// Must only be called from functions with no locals ($0)
   618// or else unwinding from systemstack_switch is incorrect.
   619TEXT gosave_systemstack_switch<>(SB),NOSPLIT,$0
   620	PUSHL	AX
   621	PUSHL	BX
   622	get_tls(BX)
   623	MOVL	g(BX), BX
   624	LEAL	arg+0(FP), AX
   625	MOVL	AX, (g_sched+gobuf_sp)(BX)
   626	MOVL	$runtime·systemstack_switch(SB), AX
   627	MOVL	AX, (g_sched+gobuf_pc)(BX)
   628	MOVL	$0, (g_sched+gobuf_ret)(BX)
   629	// Assert ctxt is zero. See func save.
   630	MOVL	(g_sched+gobuf_ctxt)(BX), AX
   631	TESTL	AX, AX
   632	JZ	2(PC)
   633	CALL	runtime·abort(SB)
   634	POPL	BX
   635	POPL	AX
   636	RET
   637
   638// func asmcgocall_no_g(fn, arg unsafe.Pointer)
   639// Call fn(arg) aligned appropriately for the gcc ABI.
   640// Called on a system stack, and there may be no g yet (during needm).
   641TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-8
   642	MOVL	fn+0(FP), AX
   643	MOVL	arg+4(FP), BX
   644	MOVL	SP, DX
   645	SUBL	$32, SP
   646	ANDL	$~15, SP	// alignment, perhaps unnecessary
   647	MOVL	DX, 8(SP)	// save old SP
   648	MOVL	BX, 0(SP)	// first argument in x86-32 ABI
   649	CALL	AX
   650	MOVL	8(SP), DX
   651	MOVL	DX, SP
   652	RET
   653
   654// func asmcgocall(fn, arg unsafe.Pointer) int32
   655// Call fn(arg) on the scheduler stack,
   656// aligned appropriately for the gcc ABI.
   657// See cgocall.go for more details.
   658TEXT ·asmcgocall(SB),NOSPLIT,$0-12
   659	MOVL	fn+0(FP), AX
   660	MOVL	arg+4(FP), BX
   661
   662	MOVL	SP, DX
   663
   664	// Figure out if we need to switch to m->g0 stack.
   665	// We get called to create new OS threads too, and those
   666	// come in on the m->g0 stack already. Or we might already
   667	// be on the m->gsignal stack.
   668	get_tls(CX)
   669	MOVL	g(CX), DI
   670	CMPL	DI, $0
   671	JEQ	nosave	// Don't even have a G yet.
   672	MOVL	g_m(DI), BP
   673	CMPL	DI, m_gsignal(BP)
   674	JEQ	noswitch
   675	MOVL	m_g0(BP), SI
   676	CMPL	DI, SI
   677	JEQ	noswitch
   678	CALL	gosave_systemstack_switch<>(SB)
   679	get_tls(CX)
   680	MOVL	SI, g(CX)
   681	MOVL	(g_sched+gobuf_sp)(SI), SP
   682
   683noswitch:
   684	// Now on a scheduling stack (a pthread-created stack).
   685	SUBL	$32, SP
   686	ANDL	$~15, SP	// alignment, perhaps unnecessary
   687	MOVL	DI, 8(SP)	// save g
   688	MOVL	(g_stack+stack_hi)(DI), DI
   689	SUBL	DX, DI
   690	MOVL	DI, 4(SP)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
   691	MOVL	BX, 0(SP)	// first argument in x86-32 ABI
   692	CALL	AX
   693
   694	// Restore registers, g, stack pointer.
   695	get_tls(CX)
   696	MOVL	8(SP), DI
   697	MOVL	(g_stack+stack_hi)(DI), SI
   698	SUBL	4(SP), SI
   699	MOVL	DI, g(CX)
   700	MOVL	SI, SP
   701
   702	MOVL	AX, ret+8(FP)
   703	RET
   704nosave:
   705	// Now on a scheduling stack (a pthread-created stack).
   706	SUBL	$32, SP
   707	ANDL	$~15, SP	// alignment, perhaps unnecessary
   708	MOVL	DX, 4(SP)	// save original stack pointer
   709	MOVL	BX, 0(SP)	// first argument in x86-32 ABI
   710	CALL	AX
   711
   712	MOVL	4(SP), CX	// restore original stack pointer
   713	MOVL	CX, SP
   714	MOVL	AX, ret+8(FP)
   715	RET
   716
   717// cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   718// See cgocall.go for more details.
   719TEXT ·cgocallback(SB),NOSPLIT,$12-12  // Frame size must match commented places below
   720	NO_LOCAL_POINTERS
   721
   722	// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
   723	// It is used to dropm while thread is exiting.
   724	MOVL	fn+0(FP), AX
   725	CMPL	AX, $0
   726	JNE	loadg
   727	// Restore the g from frame.
   728	get_tls(CX)
   729	MOVL	frame+4(FP), BX
   730	MOVL	BX, g(CX)
   731	JMP	dropm
   732
   733loadg:
   734	// If g is nil, Go did not create the current thread,
   735	// or if this thread never called into Go on pthread platforms.
   736	// Call needm to obtain one for temporary use.
   737	// In this case, we're running on the thread stack, so there's
   738	// lots of space, but the linker doesn't know. Hide the call from
   739	// the linker analysis by using an indirect call through AX.
   740	get_tls(CX)
   741#ifdef GOOS_windows
   742	MOVL	$0, BP
   743	CMPL	CX, $0
   744	JEQ	2(PC) // TODO
   745#endif
   746	MOVL	g(CX), BP
   747	CMPL	BP, $0
   748	JEQ	needm
   749	MOVL	g_m(BP), BP
   750	MOVL	BP, savedm-4(SP) // saved copy of oldm
   751	JMP	havem
   752needm:
   753	MOVL	$runtime·needAndBindM(SB), AX
   754	CALL	AX
   755	MOVL	$0, savedm-4(SP)
   756	get_tls(CX)
   757	MOVL	g(CX), BP
   758	MOVL	g_m(BP), BP
   759
   760	// Set m->sched.sp = SP, so that if a panic happens
   761	// during the function we are about to execute, it will
   762	// have a valid SP to run on the g0 stack.
   763	// The next few lines (after the havem label)
   764	// will save this SP onto the stack and then write
   765	// the same SP back to m->sched.sp. That seems redundant,
   766	// but if an unrecovered panic happens, unwindm will
   767	// restore the g->sched.sp from the stack location
   768	// and then systemstack will try to use it. If we don't set it here,
   769	// that restored SP will be uninitialized (typically 0) and
   770	// will not be usable.
   771	MOVL	m_g0(BP), SI
   772	MOVL	SP, (g_sched+gobuf_sp)(SI)
   773
   774havem:
   775	// Now there's a valid m, and we're running on its m->g0.
   776	// Save current m->g0->sched.sp on stack and then set it to SP.
   777	// Save current sp in m->g0->sched.sp in preparation for
   778	// switch back to m->curg stack.
   779	// NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
   780	MOVL	m_g0(BP), SI
   781	MOVL	(g_sched+gobuf_sp)(SI), AX
   782	MOVL	AX, 0(SP)
   783	MOVL	SP, (g_sched+gobuf_sp)(SI)
   784
   785	// Switch to m->curg stack and call runtime.cgocallbackg.
   786	// Because we are taking over the execution of m->curg
   787	// but *not* resuming what had been running, we need to
   788	// save that information (m->curg->sched) so we can restore it.
   789	// We can restore m->curg->sched.sp easily, because calling
   790	// runtime.cgocallbackg leaves SP unchanged upon return.
   791	// To save m->curg->sched.pc, we push it onto the curg stack and
   792	// open a frame the same size as cgocallback's g0 frame.
   793	// Once we switch to the curg stack, the pushed PC will appear
   794	// to be the return PC of cgocallback, so that the traceback
   795	// will seamlessly trace back into the earlier calls.
   796	MOVL	m_curg(BP), SI
   797	MOVL	SI, g(CX)
   798	MOVL	(g_sched+gobuf_sp)(SI), DI // prepare stack as DI
   799	MOVL	(g_sched+gobuf_pc)(SI), BP
   800	MOVL	BP, -4(DI)  // "push" return PC on the g stack
   801	// Gather our arguments into registers.
   802	MOVL	fn+0(FP), AX
   803	MOVL	frame+4(FP), BX
   804	MOVL	ctxt+8(FP), CX
   805	LEAL	-(4+12)(DI), SP  // Must match declared frame size
   806	MOVL	AX, 0(SP)
   807	MOVL	BX, 4(SP)
   808	MOVL	CX, 8(SP)
   809	CALL	runtime·cgocallbackg(SB)
   810
   811	// Restore g->sched (== m->curg->sched) from saved values.
   812	get_tls(CX)
   813	MOVL	g(CX), SI
   814	MOVL	12(SP), BP  // Must match declared frame size
   815	MOVL	BP, (g_sched+gobuf_pc)(SI)
   816	LEAL	(12+4)(SP), DI  // Must match declared frame size
   817	MOVL	DI, (g_sched+gobuf_sp)(SI)
   818
   819	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   820	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   821	// so we do not have to restore it.)
   822	MOVL	g(CX), BP
   823	MOVL	g_m(BP), BP
   824	MOVL	m_g0(BP), SI
   825	MOVL	SI, g(CX)
   826	MOVL	(g_sched+gobuf_sp)(SI), SP
   827	MOVL	0(SP), AX
   828	MOVL	AX, (g_sched+gobuf_sp)(SI)
   829
   830	// If the m on entry was nil, we called needm above to borrow an m,
   831	// 1. for the duration of the call on non-pthread platforms,
   832	// 2. or the duration of the C thread alive on pthread platforms.
   833	// If the m on entry wasn't nil,
   834	// 1. the thread might be a Go thread,
   835	// 2. or it wasn't the first call from a C thread on pthread platforms,
   836	//    since then we skip dropm to reuse the m in the first call.
   837	MOVL	savedm-4(SP), DX
   838	CMPL	DX, $0
   839	JNE	droppedm
   840
   841	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   842	MOVL	_cgo_pthread_key_created(SB), DX
   843	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   844	CMPL	DX, $0
   845	JEQ	dropm
   846	CMPL	(DX), $0
   847	JNE	droppedm
   848
   849dropm:
   850	MOVL	$runtime·dropm(SB), AX
   851	CALL	AX
   852droppedm:
   853
   854	// Done!
   855	RET
   856
   857// void setg(G*); set g. for use by needm.
   858TEXT runtime·setg(SB), NOSPLIT, $0-4
   859	MOVL	gg+0(FP), BX
   860#ifdef GOOS_windows
   861	MOVL	runtime·tls_g(SB), CX
   862	CMPL	BX, $0
   863	JNE	settls
   864	MOVL	$0, 0(CX)(FS)
   865	RET
   866settls:
   867	MOVL	g_m(BX), AX
   868	LEAL	m_tls(AX), AX
   869	MOVL	AX, 0(CX)(FS)
   870#endif
   871	get_tls(CX)
   872	MOVL	BX, g(CX)
   873	RET
   874
   875// void setg_gcc(G*); set g. for use by gcc
   876TEXT setg_gcc<>(SB), NOSPLIT, $0
   877	get_tls(AX)
   878	MOVL	gg+0(FP), DX
   879	MOVL	DX, g(AX)
   880	RET
   881
   882TEXT runtime·abort(SB),NOSPLIT,$0-0
   883	INT	$3
   884loop:
   885	JMP	loop
   886
   887// check that SP is in range [g->stack.lo, g->stack.hi)
   888TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
   889	get_tls(CX)
   890	MOVL	g(CX), AX
   891	CMPL	(g_stack+stack_hi)(AX), SP
   892	JHI	2(PC)
   893	CALL	runtime·abort(SB)
   894	CMPL	SP, (g_stack+stack_lo)(AX)
   895	JHI	2(PC)
   896	CALL	runtime·abort(SB)
   897	RET
   898
   899// func cputicks() int64
   900TEXT runtime·cputicks(SB),NOSPLIT,$0-8
   901	// LFENCE/MFENCE instruction support is dependent on SSE2.
   902	// When no SSE2 support is present do not enforce any serialization
   903	// since using CPUID to serialize the instruction stream is
   904	// very costly.
   905#ifdef GO386_softfloat
   906	JMP	rdtsc  // no fence instructions available
   907#endif
   908	CMPB	internal∕cpu·X86+const_offsetX86HasRDTSCP(SB), $1
   909	JNE	fences
   910	// Instruction stream serializing RDTSCP is supported.
   911	// RDTSCP is supported by Intel Nehalem (2008) and
   912	// AMD K8 Rev. F (2006) and newer.
   913	RDTSCP
   914done:
   915	MOVL	AX, ret_lo+0(FP)
   916	MOVL	DX, ret_hi+4(FP)
   917	RET
   918fences:
   919	// MFENCE is instruction stream serializing and flushes the
   920	// store buffers on AMD. The serialization semantics of LFENCE on AMD
   921	// are dependent on MSR C001_1029 and CPU generation.
   922	// LFENCE on Intel does wait for all previous instructions to have executed.
   923	// Intel recommends MFENCE;LFENCE in its manuals before RDTSC to have all
   924	// previous instructions executed and all previous loads and stores to globally visible.
   925	// Using MFENCE;LFENCE here aligns the serializing properties without
   926	// runtime detection of CPU manufacturer.
   927	MFENCE
   928	LFENCE
   929rdtsc:
   930	RDTSC
   931	JMP done
   932
   933TEXT ldt0setup<>(SB),NOSPLIT,$16-0
   934#ifdef GOOS_windows
   935	CALL	runtime·wintls(SB)
   936#endif
   937	// set up ldt 7 to point at m0.tls
   938	// ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go.
   939	// the entry number is just a hint.  setldt will set up GS with what it used.
   940	MOVL	$7, 0(SP)
   941	LEAL	runtime·m0+m_tls(SB), AX
   942	MOVL	AX, 4(SP)
   943	MOVL	$32, 8(SP)	// sizeof(tls array)
   944	CALL	runtime·setldt(SB)
   945	RET
   946
   947TEXT runtime·emptyfunc(SB),0,$0-0
   948	RET
   949
   950// hash function using AES hardware instructions
   951TEXT runtime·memhash(SB),NOSPLIT,$0-16
   952	CMPB	runtime·useAeshash(SB), $0
   953	JEQ	noaes
   954	MOVL	p+0(FP), AX	// ptr to data
   955	MOVL	s+8(FP), BX	// size
   956	LEAL	ret+12(FP), DX
   957	JMP	aeshashbody<>(SB)
   958noaes:
   959	JMP	runtime·memhashFallback(SB)
   960
   961TEXT runtime·strhash(SB),NOSPLIT,$0-12
   962	CMPB	runtime·useAeshash(SB), $0
   963	JEQ	noaes
   964	MOVL	p+0(FP), AX	// ptr to string object
   965	MOVL	4(AX), BX	// length of string
   966	MOVL	(AX), AX	// string data
   967	LEAL	ret+8(FP), DX
   968	JMP	aeshashbody<>(SB)
   969noaes:
   970	JMP	runtime·strhashFallback(SB)
   971
   972// AX: data
   973// BX: length
   974// DX: address to put return value
   975TEXT aeshashbody<>(SB),NOSPLIT,$0-0
   976	MOVL	h+4(FP), X0	            // 32 bits of per-table hash seed
   977	PINSRW	$4, BX, X0	            // 16 bits of length
   978	PSHUFHW	$0, X0, X0	            // replace size with its low 2 bytes repeated 4 times
   979	MOVO	X0, X1                      // save unscrambled seed
   980	PXOR	runtime·aeskeysched(SB), X0 // xor in per-process seed
   981	AESENC	X0, X0                      // scramble seed
   982
   983	CMPL	BX, $16
   984	JB	aes0to15
   985	JE	aes16
   986	CMPL	BX, $32
   987	JBE	aes17to32
   988	CMPL	BX, $64
   989	JBE	aes33to64
   990	JMP	aes65plus
   991
   992aes0to15:
   993	TESTL	BX, BX
   994	JE	aes0
   995
   996	ADDL	$16, AX
   997	TESTW	$0xff0, AX
   998	JE	endofpage
   999
  1000	// 16 bytes loaded at this address won't cross
  1001	// a page boundary, so we can load it directly.
  1002	MOVOU	-16(AX), X1
  1003	ADDL	BX, BX
  1004	PAND	masks<>(SB)(BX*8), X1
  1005
  1006final1:
  1007	PXOR	X0, X1	// xor data with seed
  1008	AESENC	X1, X1  // scramble combo 3 times
  1009	AESENC	X1, X1
  1010	AESENC	X1, X1
  1011	MOVL	X1, (DX)
  1012	RET
  1013
  1014endofpage:
  1015	// address ends in 1111xxxx. Might be up against
  1016	// a page boundary, so load ending at last byte.
  1017	// Then shift bytes down using pshufb.
  1018	MOVOU	-32(AX)(BX*1), X1
  1019	ADDL	BX, BX
  1020	PSHUFB	shifts<>(SB)(BX*8), X1
  1021	JMP	final1
  1022
  1023aes0:
  1024	// Return scrambled input seed
  1025	AESENC	X0, X0
  1026	MOVL	X0, (DX)
  1027	RET
  1028
  1029aes16:
  1030	MOVOU	(AX), X1
  1031	JMP	final1
  1032
  1033aes17to32:
  1034	// make second starting seed
  1035	PXOR	runtime·aeskeysched+16(SB), X1
  1036	AESENC	X1, X1
  1037
  1038	// load data to be hashed
  1039	MOVOU	(AX), X2
  1040	MOVOU	-16(AX)(BX*1), X3
  1041
  1042	// xor with seed
  1043	PXOR	X0, X2
  1044	PXOR	X1, X3
  1045
  1046	// scramble 3 times
  1047	AESENC	X2, X2
  1048	AESENC	X3, X3
  1049	AESENC	X2, X2
  1050	AESENC	X3, X3
  1051	AESENC	X2, X2
  1052	AESENC	X3, X3
  1053
  1054	// combine results
  1055	PXOR	X3, X2
  1056	MOVL	X2, (DX)
  1057	RET
  1058
  1059aes33to64:
  1060	// make 3 more starting seeds
  1061	MOVO	X1, X2
  1062	MOVO	X1, X3
  1063	PXOR	runtime·aeskeysched+16(SB), X1
  1064	PXOR	runtime·aeskeysched+32(SB), X2
  1065	PXOR	runtime·aeskeysched+48(SB), X3
  1066	AESENC	X1, X1
  1067	AESENC	X2, X2
  1068	AESENC	X3, X3
  1069
  1070	MOVOU	(AX), X4
  1071	MOVOU	16(AX), X5
  1072	MOVOU	-32(AX)(BX*1), X6
  1073	MOVOU	-16(AX)(BX*1), X7
  1074
  1075	PXOR	X0, X4
  1076	PXOR	X1, X5
  1077	PXOR	X2, X6
  1078	PXOR	X3, X7
  1079
  1080	AESENC	X4, X4
  1081	AESENC	X5, X5
  1082	AESENC	X6, X6
  1083	AESENC	X7, X7
  1084
  1085	AESENC	X4, X4
  1086	AESENC	X5, X5
  1087	AESENC	X6, X6
  1088	AESENC	X7, X7
  1089
  1090	AESENC	X4, X4
  1091	AESENC	X5, X5
  1092	AESENC	X6, X6
  1093	AESENC	X7, X7
  1094
  1095	PXOR	X6, X4
  1096	PXOR	X7, X5
  1097	PXOR	X5, X4
  1098	MOVL	X4, (DX)
  1099	RET
  1100
  1101aes65plus:
  1102	// make 3 more starting seeds
  1103	MOVO	X1, X2
  1104	MOVO	X1, X3
  1105	PXOR	runtime·aeskeysched+16(SB), X1
  1106	PXOR	runtime·aeskeysched+32(SB), X2
  1107	PXOR	runtime·aeskeysched+48(SB), X3
  1108	AESENC	X1, X1
  1109	AESENC	X2, X2
  1110	AESENC	X3, X3
  1111
  1112	// start with last (possibly overlapping) block
  1113	MOVOU	-64(AX)(BX*1), X4
  1114	MOVOU	-48(AX)(BX*1), X5
  1115	MOVOU	-32(AX)(BX*1), X6
  1116	MOVOU	-16(AX)(BX*1), X7
  1117
  1118	// scramble state once
  1119	AESENC	X0, X4
  1120	AESENC	X1, X5
  1121	AESENC	X2, X6
  1122	AESENC	X3, X7
  1123
  1124	// compute number of remaining 64-byte blocks
  1125	DECL	BX
  1126	SHRL	$6, BX
  1127
  1128aesloop:
  1129	// scramble state, xor in a block
  1130	MOVOU	(AX), X0
  1131	MOVOU	16(AX), X1
  1132	MOVOU	32(AX), X2
  1133	MOVOU	48(AX), X3
  1134	AESENC	X0, X4
  1135	AESENC	X1, X5
  1136	AESENC	X2, X6
  1137	AESENC	X3, X7
  1138
  1139	// scramble state
  1140	AESENC	X4, X4
  1141	AESENC	X5, X5
  1142	AESENC	X6, X6
  1143	AESENC	X7, X7
  1144
  1145	ADDL	$64, AX
  1146	DECL	BX
  1147	JNE	aesloop
  1148
  1149	// 3 more scrambles to finish
  1150	AESENC	X4, X4
  1151	AESENC	X5, X5
  1152	AESENC	X6, X6
  1153	AESENC	X7, X7
  1154
  1155	AESENC	X4, X4
  1156	AESENC	X5, X5
  1157	AESENC	X6, X6
  1158	AESENC	X7, X7
  1159
  1160	AESENC	X4, X4
  1161	AESENC	X5, X5
  1162	AESENC	X6, X6
  1163	AESENC	X7, X7
  1164
  1165	PXOR	X6, X4
  1166	PXOR	X7, X5
  1167	PXOR	X5, X4
  1168	MOVL	X4, (DX)
  1169	RET
  1170
  1171TEXT runtime·memhash32(SB),NOSPLIT,$0-12
  1172	CMPB	runtime·useAeshash(SB), $0
  1173	JEQ	noaes
  1174	MOVL	p+0(FP), AX	// ptr to data
  1175	MOVL	h+4(FP), X0	// seed
  1176	PINSRD	$1, (AX), X0	// data
  1177	AESENC	runtime·aeskeysched+0(SB), X0
  1178	AESENC	runtime·aeskeysched+16(SB), X0
  1179	AESENC	runtime·aeskeysched+32(SB), X0
  1180	MOVL	X0, ret+8(FP)
  1181	RET
  1182noaes:
  1183	JMP	runtime·memhash32Fallback(SB)
  1184
  1185TEXT runtime·memhash64(SB),NOSPLIT,$0-12
  1186	CMPB	runtime·useAeshash(SB), $0
  1187	JEQ	noaes
  1188	MOVL	p+0(FP), AX	// ptr to data
  1189	MOVQ	(AX), X0	// data
  1190	PINSRD	$2, h+4(FP), X0	// seed
  1191	AESENC	runtime·aeskeysched+0(SB), X0
  1192	AESENC	runtime·aeskeysched+16(SB), X0
  1193	AESENC	runtime·aeskeysched+32(SB), X0
  1194	MOVL	X0, ret+8(FP)
  1195	RET
  1196noaes:
  1197	JMP	runtime·memhash64Fallback(SB)
  1198
  1199// simple mask to get rid of data in the high part of the register.
  1200DATA masks<>+0x00(SB)/4, $0x00000000
  1201DATA masks<>+0x04(SB)/4, $0x00000000
  1202DATA masks<>+0x08(SB)/4, $0x00000000
  1203DATA masks<>+0x0c(SB)/4, $0x00000000
  1204
  1205DATA masks<>+0x10(SB)/4, $0x000000ff
  1206DATA masks<>+0x14(SB)/4, $0x00000000
  1207DATA masks<>+0x18(SB)/4, $0x00000000
  1208DATA masks<>+0x1c(SB)/4, $0x00000000
  1209
  1210DATA masks<>+0x20(SB)/4, $0x0000ffff
  1211DATA masks<>+0x24(SB)/4, $0x00000000
  1212DATA masks<>+0x28(SB)/4, $0x00000000
  1213DATA masks<>+0x2c(SB)/4, $0x00000000
  1214
  1215DATA masks<>+0x30(SB)/4, $0x00ffffff
  1216DATA masks<>+0x34(SB)/4, $0x00000000
  1217DATA masks<>+0x38(SB)/4, $0x00000000
  1218DATA masks<>+0x3c(SB)/4, $0x00000000
  1219
  1220DATA masks<>+0x40(SB)/4, $0xffffffff
  1221DATA masks<>+0x44(SB)/4, $0x00000000
  1222DATA masks<>+0x48(SB)/4, $0x00000000
  1223DATA masks<>+0x4c(SB)/4, $0x00000000
  1224
  1225DATA masks<>+0x50(SB)/4, $0xffffffff
  1226DATA masks<>+0x54(SB)/4, $0x000000ff
  1227DATA masks<>+0x58(SB)/4, $0x00000000
  1228DATA masks<>+0x5c(SB)/4, $0x00000000
  1229
  1230DATA masks<>+0x60(SB)/4, $0xffffffff
  1231DATA masks<>+0x64(SB)/4, $0x0000ffff
  1232DATA masks<>+0x68(SB)/4, $0x00000000
  1233DATA masks<>+0x6c(SB)/4, $0x00000000
  1234
  1235DATA masks<>+0x70(SB)/4, $0xffffffff
  1236DATA masks<>+0x74(SB)/4, $0x00ffffff
  1237DATA masks<>+0x78(SB)/4, $0x00000000
  1238DATA masks<>+0x7c(SB)/4, $0x00000000
  1239
  1240DATA masks<>+0x80(SB)/4, $0xffffffff
  1241DATA masks<>+0x84(SB)/4, $0xffffffff
  1242DATA masks<>+0x88(SB)/4, $0x00000000
  1243DATA masks<>+0x8c(SB)/4, $0x00000000
  1244
  1245DATA masks<>+0x90(SB)/4, $0xffffffff
  1246DATA masks<>+0x94(SB)/4, $0xffffffff
  1247DATA masks<>+0x98(SB)/4, $0x000000ff
  1248DATA masks<>+0x9c(SB)/4, $0x00000000
  1249
  1250DATA masks<>+0xa0(SB)/4, $0xffffffff
  1251DATA masks<>+0xa4(SB)/4, $0xffffffff
  1252DATA masks<>+0xa8(SB)/4, $0x0000ffff
  1253DATA masks<>+0xac(SB)/4, $0x00000000
  1254
  1255DATA masks<>+0xb0(SB)/4, $0xffffffff
  1256DATA masks<>+0xb4(SB)/4, $0xffffffff
  1257DATA masks<>+0xb8(SB)/4, $0x00ffffff
  1258DATA masks<>+0xbc(SB)/4, $0x00000000
  1259
  1260DATA masks<>+0xc0(SB)/4, $0xffffffff
  1261DATA masks<>+0xc4(SB)/4, $0xffffffff
  1262DATA masks<>+0xc8(SB)/4, $0xffffffff
  1263DATA masks<>+0xcc(SB)/4, $0x00000000
  1264
  1265DATA masks<>+0xd0(SB)/4, $0xffffffff
  1266DATA masks<>+0xd4(SB)/4, $0xffffffff
  1267DATA masks<>+0xd8(SB)/4, $0xffffffff
  1268DATA masks<>+0xdc(SB)/4, $0x000000ff
  1269
  1270DATA masks<>+0xe0(SB)/4, $0xffffffff
  1271DATA masks<>+0xe4(SB)/4, $0xffffffff
  1272DATA masks<>+0xe8(SB)/4, $0xffffffff
  1273DATA masks<>+0xec(SB)/4, $0x0000ffff
  1274
  1275DATA masks<>+0xf0(SB)/4, $0xffffffff
  1276DATA masks<>+0xf4(SB)/4, $0xffffffff
  1277DATA masks<>+0xf8(SB)/4, $0xffffffff
  1278DATA masks<>+0xfc(SB)/4, $0x00ffffff
  1279
  1280GLOBL masks<>(SB),RODATA,$256
  1281
  1282// these are arguments to pshufb. They move data down from
  1283// the high bytes of the register to the low bytes of the register.
  1284// index is how many bytes to move.
  1285DATA shifts<>+0x00(SB)/4, $0x00000000
  1286DATA shifts<>+0x04(SB)/4, $0x00000000
  1287DATA shifts<>+0x08(SB)/4, $0x00000000
  1288DATA shifts<>+0x0c(SB)/4, $0x00000000
  1289
  1290DATA shifts<>+0x10(SB)/4, $0xffffff0f
  1291DATA shifts<>+0x14(SB)/4, $0xffffffff
  1292DATA shifts<>+0x18(SB)/4, $0xffffffff
  1293DATA shifts<>+0x1c(SB)/4, $0xffffffff
  1294
  1295DATA shifts<>+0x20(SB)/4, $0xffff0f0e
  1296DATA shifts<>+0x24(SB)/4, $0xffffffff
  1297DATA shifts<>+0x28(SB)/4, $0xffffffff
  1298DATA shifts<>+0x2c(SB)/4, $0xffffffff
  1299
  1300DATA shifts<>+0x30(SB)/4, $0xff0f0e0d
  1301DATA shifts<>+0x34(SB)/4, $0xffffffff
  1302DATA shifts<>+0x38(SB)/4, $0xffffffff
  1303DATA shifts<>+0x3c(SB)/4, $0xffffffff
  1304
  1305DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c
  1306DATA shifts<>+0x44(SB)/4, $0xffffffff
  1307DATA shifts<>+0x48(SB)/4, $0xffffffff
  1308DATA shifts<>+0x4c(SB)/4, $0xffffffff
  1309
  1310DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b
  1311DATA shifts<>+0x54(SB)/4, $0xffffff0f
  1312DATA shifts<>+0x58(SB)/4, $0xffffffff
  1313DATA shifts<>+0x5c(SB)/4, $0xffffffff
  1314
  1315DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a
  1316DATA shifts<>+0x64(SB)/4, $0xffff0f0e
  1317DATA shifts<>+0x68(SB)/4, $0xffffffff
  1318DATA shifts<>+0x6c(SB)/4, $0xffffffff
  1319
  1320DATA shifts<>+0x70(SB)/4, $0x0c0b0a09
  1321DATA shifts<>+0x74(SB)/4, $0xff0f0e0d
  1322DATA shifts<>+0x78(SB)/4, $0xffffffff
  1323DATA shifts<>+0x7c(SB)/4, $0xffffffff
  1324
  1325DATA shifts<>+0x80(SB)/4, $0x0b0a0908
  1326DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c
  1327DATA shifts<>+0x88(SB)/4, $0xffffffff
  1328DATA shifts<>+0x8c(SB)/4, $0xffffffff
  1329
  1330DATA shifts<>+0x90(SB)/4, $0x0a090807
  1331DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b
  1332DATA shifts<>+0x98(SB)/4, $0xffffff0f
  1333DATA shifts<>+0x9c(SB)/4, $0xffffffff
  1334
  1335DATA shifts<>+0xa0(SB)/4, $0x09080706
  1336DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a
  1337DATA shifts<>+0xa8(SB)/4, $0xffff0f0e
  1338DATA shifts<>+0xac(SB)/4, $0xffffffff
  1339
  1340DATA shifts<>+0xb0(SB)/4, $0x08070605
  1341DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09
  1342DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d
  1343DATA shifts<>+0xbc(SB)/4, $0xffffffff
  1344
  1345DATA shifts<>+0xc0(SB)/4, $0x07060504
  1346DATA shifts<>+0xc4(SB)/4, $0x0b0a0908
  1347DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c
  1348DATA shifts<>+0xcc(SB)/4, $0xffffffff
  1349
  1350DATA shifts<>+0xd0(SB)/4, $0x06050403
  1351DATA shifts<>+0xd4(SB)/4, $0x0a090807
  1352DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b
  1353DATA shifts<>+0xdc(SB)/4, $0xffffff0f
  1354
  1355DATA shifts<>+0xe0(SB)/4, $0x05040302
  1356DATA shifts<>+0xe4(SB)/4, $0x09080706
  1357DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a
  1358DATA shifts<>+0xec(SB)/4, $0xffff0f0e
  1359
  1360DATA shifts<>+0xf0(SB)/4, $0x04030201
  1361DATA shifts<>+0xf4(SB)/4, $0x08070605
  1362DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09
  1363DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d
  1364
  1365GLOBL shifts<>(SB),RODATA,$256
  1366
  1367TEXT ·checkASM(SB),NOSPLIT,$0-1
  1368	// check that masks<>(SB) and shifts<>(SB) are aligned to 16-byte
  1369	MOVL	$masks<>(SB), AX
  1370	MOVL	$shifts<>(SB), BX
  1371	ORL	BX, AX
  1372	TESTL	$15, AX
  1373	SETEQ	ret+0(FP)
  1374	RET
  1375
  1376TEXT runtime·return0(SB), NOSPLIT, $0
  1377	MOVL	$0, AX
  1378	RET
  1379
  1380// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
  1381// Must obey the gcc calling convention.
  1382TEXT _cgo_topofstack(SB),NOSPLIT,$0
  1383	get_tls(CX)
  1384	MOVL	g(CX), AX
  1385	MOVL	g_m(AX), AX
  1386	MOVL	m_curg(AX), AX
  1387	MOVL	(g_stack+stack_hi)(AX), AX
  1388	RET
  1389
  1390// The top-most function running on a goroutine
  1391// returns to goexit+PCQuantum.
  1392TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME,$0-0
  1393	BYTE	$0x90	// NOP
  1394	CALL	runtime·goexit1(SB)	// does not return
  1395	// traceback from goexit1 must hit code range of goexit
  1396	BYTE	$0x90	// NOP
  1397
  1398// Add a module's moduledata to the linked list of moduledata objects. This
  1399// is called from .init_array by a function generated in the linker and so
  1400// follows the platform ABI wrt register preservation -- it only touches AX,
  1401// CX (implicitly) and DX, but it does not follow the ABI wrt arguments:
  1402// instead the pointer to the moduledata is passed in AX.
  1403TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
  1404	MOVL	runtime·lastmoduledatap(SB), DX
  1405	MOVL	AX, moduledata_next(DX)
  1406	MOVL	AX, runtime·lastmoduledatap(SB)
  1407	RET
  1408
  1409TEXT runtime·uint32tofloat64(SB),NOSPLIT,$8-12
  1410	MOVL	a+0(FP), AX
  1411	MOVL	AX, 0(SP)
  1412	MOVL	$0, 4(SP)
  1413	FMOVV	0(SP), F0
  1414	FMOVDP	F0, ret+4(FP)
  1415	RET
  1416
  1417TEXT runtime·float64touint32(SB),NOSPLIT,$12-12
  1418	FMOVD	a+0(FP), F0
  1419	FSTCW	0(SP)
  1420	FLDCW	runtime·controlWord64trunc(SB)
  1421	FMOVVP	F0, 4(SP)
  1422	FLDCW	0(SP)
  1423	MOVL	4(SP), AX
  1424	MOVL	AX, ret+8(FP)
  1425	RET
  1426
  1427// gcWriteBarrier informs the GC about heap pointer writes.
  1428//
  1429// gcWriteBarrier returns space in a write barrier buffer which
  1430// should be filled in by the caller.
  1431// gcWriteBarrier does NOT follow the Go ABI. It accepts the
  1432// number of bytes of buffer needed in DI, and returns a pointer
  1433// to the buffer space in DI.
  1434// It clobbers FLAGS. It does not clobber any general-purpose registers,
  1435// but may clobber others (e.g., SSE registers).
  1436// Typical use would be, when doing *(CX+88) = AX
  1437//     CMPL    $0, runtime.writeBarrier(SB)
  1438//     JEQ     dowrite
  1439//     CALL    runtime.gcBatchBarrier2(SB)
  1440//     MOVL    AX, (DI)
  1441//     MOVL    88(CX), DX
  1442//     MOVL    DX, 4(DI)
  1443// dowrite:
  1444//     MOVL    AX, 88(CX)
  1445TEXT gcWriteBarrier<>(SB),NOSPLIT,$28
  1446	// Save the registers clobbered by the fast path. This is slightly
  1447	// faster than having the caller spill these.
  1448	MOVL	CX, 20(SP)
  1449	MOVL	BX, 24(SP)
  1450retry:
  1451	// TODO: Consider passing g.m.p in as an argument so they can be shared
  1452	// across a sequence of write barriers.
  1453	get_tls(BX)
  1454	MOVL	g(BX), BX
  1455	MOVL	g_m(BX), BX
  1456	MOVL	m_p(BX), BX
  1457	// Get current buffer write position.
  1458	MOVL	(p_wbBuf+wbBuf_next)(BX), CX	// original next position
  1459	ADDL	DI, CX				// new next position
  1460	// Is the buffer full?
  1461	CMPL	CX, (p_wbBuf+wbBuf_end)(BX)
  1462	JA	flush
  1463	// Commit to the larger buffer.
  1464	MOVL	CX, (p_wbBuf+wbBuf_next)(BX)
  1465	// Make return value (the original next position)
  1466	SUBL	DI, CX
  1467	MOVL	CX, DI
  1468	// Restore registers.
  1469	MOVL	20(SP), CX
  1470	MOVL	24(SP), BX
  1471	RET
  1472
  1473flush:
  1474	// Save all general purpose registers since these could be
  1475	// clobbered by wbBufFlush and were not saved by the caller.
  1476	MOVL	DI, 0(SP)
  1477	MOVL	AX, 4(SP)
  1478	// BX already saved
  1479	// CX already saved
  1480	MOVL	DX, 8(SP)
  1481	MOVL	BP, 12(SP)
  1482	MOVL	SI, 16(SP)
  1483	// DI already saved
  1484
  1485	CALL	runtime·wbBufFlush(SB)
  1486
  1487	MOVL	0(SP), DI
  1488	MOVL	4(SP), AX
  1489	MOVL	8(SP), DX
  1490	MOVL	12(SP), BP
  1491	MOVL	16(SP), SI
  1492	JMP	retry
  1493
  1494TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
  1495	MOVL	$4, DI
  1496	JMP	gcWriteBarrier<>(SB)
  1497TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
  1498	MOVL	$8, DI
  1499	JMP	gcWriteBarrier<>(SB)
  1500TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
  1501	MOVL	$12, DI
  1502	JMP	gcWriteBarrier<>(SB)
  1503TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
  1504	MOVL	$16, DI
  1505	JMP	gcWriteBarrier<>(SB)
  1506TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
  1507	MOVL	$20, DI
  1508	JMP	gcWriteBarrier<>(SB)
  1509TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
  1510	MOVL	$24, DI
  1511	JMP	gcWriteBarrier<>(SB)
  1512TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
  1513	MOVL	$28, DI
  1514	JMP	gcWriteBarrier<>(SB)
  1515TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
  1516	MOVL	$32, DI
  1517	JMP	gcWriteBarrier<>(SB)
  1518
  1519// Note: these functions use a special calling convention to save generated code space.
  1520// Arguments are passed in registers, but the space for those arguments are allocated
  1521// in the caller's stack frame. These stubs write the args into that stack space and
  1522// then tail call to the corresponding runtime handler.
  1523// The tail call makes these stubs disappear in backtraces.
  1524TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
  1525	MOVL	AX, x+0(FP)
  1526	MOVL	CX, y+4(FP)
  1527	JMP	runtime·goPanicIndex(SB)
  1528TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
  1529	MOVL	AX, x+0(FP)
  1530	MOVL	CX, y+4(FP)
  1531	JMP	runtime·goPanicIndexU(SB)
  1532TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
  1533	MOVL	CX, x+0(FP)
  1534	MOVL	DX, y+4(FP)
  1535	JMP	runtime·goPanicSliceAlen(SB)
  1536TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
  1537	MOVL	CX, x+0(FP)
  1538	MOVL	DX, y+4(FP)
  1539	JMP	runtime·goPanicSliceAlenU(SB)
  1540TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
  1541	MOVL	CX, x+0(FP)
  1542	MOVL	DX, y+4(FP)
  1543	JMP	runtime·goPanicSliceAcap(SB)
  1544TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
  1545	MOVL	CX, x+0(FP)
  1546	MOVL	DX, y+4(FP)
  1547	JMP	runtime·goPanicSliceAcapU(SB)
  1548TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
  1549	MOVL	AX, x+0(FP)
  1550	MOVL	CX, y+4(FP)
  1551	JMP	runtime·goPanicSliceB(SB)
  1552TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
  1553	MOVL	AX, x+0(FP)
  1554	MOVL	CX, y+4(FP)
  1555	JMP	runtime·goPanicSliceBU(SB)
  1556TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
  1557	MOVL	DX, x+0(FP)
  1558	MOVL	BX, y+4(FP)
  1559	JMP	runtime·goPanicSlice3Alen(SB)
  1560TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
  1561	MOVL	DX, x+0(FP)
  1562	MOVL	BX, y+4(FP)
  1563	JMP	runtime·goPanicSlice3AlenU(SB)
  1564TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
  1565	MOVL	DX, x+0(FP)
  1566	MOVL	BX, y+4(FP)
  1567	JMP	runtime·goPanicSlice3Acap(SB)
  1568TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
  1569	MOVL	DX, x+0(FP)
  1570	MOVL	BX, y+4(FP)
  1571	JMP	runtime·goPanicSlice3AcapU(SB)
  1572TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
  1573	MOVL	CX, x+0(FP)
  1574	MOVL	DX, y+4(FP)
  1575	JMP	runtime·goPanicSlice3B(SB)
  1576TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
  1577	MOVL	CX, x+0(FP)
  1578	MOVL	DX, y+4(FP)
  1579	JMP	runtime·goPanicSlice3BU(SB)
  1580TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
  1581	MOVL	AX, x+0(FP)
  1582	MOVL	CX, y+4(FP)
  1583	JMP	runtime·goPanicSlice3C(SB)
  1584TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
  1585	MOVL	AX, x+0(FP)
  1586	MOVL	CX, y+4(FP)
  1587	JMP	runtime·goPanicSlice3CU(SB)
  1588TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
  1589	MOVL	DX, x+0(FP)
  1590	MOVL	BX, y+4(FP)
  1591	JMP	runtime·goPanicSliceConvert(SB)
  1592
  1593// Extended versions for 64-bit indexes.
  1594TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
  1595	MOVL	SI, hi+0(FP)
  1596	MOVL	AX, lo+4(FP)
  1597	MOVL	CX, y+8(FP)
  1598	JMP	runtime·goPanicExtendIndex(SB)
  1599TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
  1600	MOVL	SI, hi+0(FP)
  1601	MOVL	AX, lo+4(FP)
  1602	MOVL	CX, y+8(FP)
  1603	JMP	runtime·goPanicExtendIndexU(SB)
  1604TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
  1605	MOVL	SI, hi+0(FP)
  1606	MOVL	CX, lo+4(FP)
  1607	MOVL	DX, y+8(FP)
  1608	JMP	runtime·goPanicExtendSliceAlen(SB)
  1609TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
  1610	MOVL	SI, hi+0(FP)
  1611	MOVL	CX, lo+4(FP)
  1612	MOVL	DX, y+8(FP)
  1613	JMP	runtime·goPanicExtendSliceAlenU(SB)
  1614TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
  1615	MOVL	SI, hi+0(FP)
  1616	MOVL	CX, lo+4(FP)
  1617	MOVL	DX, y+8(FP)
  1618	JMP	runtime·goPanicExtendSliceAcap(SB)
  1619TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
  1620	MOVL	SI, hi+0(FP)
  1621	MOVL	CX, lo+4(FP)
  1622	MOVL	DX, y+8(FP)
  1623	JMP	runtime·goPanicExtendSliceAcapU(SB)
  1624TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
  1625	MOVL	SI, hi+0(FP)
  1626	MOVL	AX, lo+4(FP)
  1627	MOVL	CX, y+8(FP)
  1628	JMP	runtime·goPanicExtendSliceB(SB)
  1629TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
  1630	MOVL	SI, hi+0(FP)
  1631	MOVL	AX, lo+4(FP)
  1632	MOVL	CX, y+8(FP)
  1633	JMP	runtime·goPanicExtendSliceBU(SB)
  1634TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
  1635	MOVL	SI, hi+0(FP)
  1636	MOVL	DX, lo+4(FP)
  1637	MOVL	BX, y+8(FP)
  1638	JMP	runtime·goPanicExtendSlice3Alen(SB)
  1639TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
  1640	MOVL	SI, hi+0(FP)
  1641	MOVL	DX, lo+4(FP)
  1642	MOVL	BX, y+8(FP)
  1643	JMP	runtime·goPanicExtendSlice3AlenU(SB)
  1644TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
  1645	MOVL	SI, hi+0(FP)
  1646	MOVL	DX, lo+4(FP)
  1647	MOVL	BX, y+8(FP)
  1648	JMP	runtime·goPanicExtendSlice3Acap(SB)
  1649TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
  1650	MOVL	SI, hi+0(FP)
  1651	MOVL	DX, lo+4(FP)
  1652	MOVL	BX, y+8(FP)
  1653	JMP	runtime·goPanicExtendSlice3AcapU(SB)
  1654TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
  1655	MOVL	SI, hi+0(FP)
  1656	MOVL	CX, lo+4(FP)
  1657	MOVL	DX, y+8(FP)
  1658	JMP	runtime·goPanicExtendSlice3B(SB)
  1659TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
  1660	MOVL	SI, hi+0(FP)
  1661	MOVL	CX, lo+4(FP)
  1662	MOVL	DX, y+8(FP)
  1663	JMP	runtime·goPanicExtendSlice3BU(SB)
  1664TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
  1665	MOVL	SI, hi+0(FP)
  1666	MOVL	AX, lo+4(FP)
  1667	MOVL	CX, y+8(FP)
  1668	JMP	runtime·goPanicExtendSlice3C(SB)
  1669TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
  1670	MOVL	SI, hi+0(FP)
  1671	MOVL	AX, lo+4(FP)
  1672	MOVL	CX, y+8(FP)
  1673	JMP	runtime·goPanicExtendSlice3CU(SB)
  1674
  1675#ifdef GOOS_android
  1676// Use the free TLS_SLOT_APP slot #2 on Android Q.
  1677// Earlier androids are set up in gcc_android.c.
  1678DATA runtime·tls_g+0(SB)/4, $8
  1679GLOBL runtime·tls_g+0(SB), NOPTR, $4
  1680#endif
  1681#ifdef GOOS_windows
  1682GLOBL runtime·tls_g+0(SB), NOPTR, $4
  1683#endif

View as plain text