...

Text file src/runtime/asm_arm.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_arm is common startup code for most ARM 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_arm(SB),NOSPLIT|NOFRAME,$0
    15	MOVW	(R13), R0	// argc
    16	MOVW	$4(R13), R1		// argv
    17	B	runtime·rt0_go(SB)
    18
    19// main is common startup code for most ARM systems when using
    20// external linking. The C startup code will call the symbol "main"
    21// passing argc and argv in the usual C ABI registers R0 and R1.
    22TEXT main(SB),NOSPLIT|NOFRAME,$0
    23	B	runtime·rt0_go(SB)
    24
    25// _rt0_arm_lib is common startup code for most ARM systems when
    26// using -buildmode=c-archive or -buildmode=c-shared. The linker will
    27// arrange to invoke this function as a global constructor (for
    28// c-archive) or when the shared library is loaded (for c-shared).
    29// We expect argc and argv to be passed in the usual C ABI registers
    30// R0 and R1.
    31TEXT _rt0_arm_lib(SB),NOSPLIT,$104
    32	// Preserve callee-save registers. Raspberry Pi's dlopen(), for example,
    33	// actually cares that R11 is preserved.
    34	MOVW	R4, 12(R13)
    35	MOVW	R5, 16(R13)
    36	MOVW	R6, 20(R13)
    37	MOVW	R7, 24(R13)
    38	MOVW	R8, 28(R13)
    39	MOVW	g, 32(R13)
    40	MOVW	R11, 36(R13)
    41
    42	// Skip floating point registers on goarmsoftfp != 0.
    43	MOVB    runtime·goarmsoftfp(SB), R11
    44	CMP	$0, R11
    45	BNE     skipfpsave
    46	MOVD	F8, (40+8*0)(R13)
    47	MOVD	F9, (40+8*1)(R13)
    48	MOVD	F10, (40+8*2)(R13)
    49	MOVD	F11, (40+8*3)(R13)
    50	MOVD	F12, (40+8*4)(R13)
    51	MOVD	F13, (40+8*5)(R13)
    52	MOVD	F14, (40+8*6)(R13)
    53	MOVD	F15, (40+8*7)(R13)
    54skipfpsave:
    55	// Save argc/argv.
    56	MOVW	R0, _rt0_arm_lib_argc<>(SB)
    57	MOVW	R1, _rt0_arm_lib_argv<>(SB)
    58
    59	MOVW	$0, g // Initialize g.
    60
    61	// Synchronous initialization.
    62	CALL	runtime·libpreinit(SB)
    63
    64	// Create a new thread to do the runtime initialization.
    65	MOVW	_cgo_sys_thread_create(SB), R2
    66	CMP	$0, R2
    67	BEQ	nocgo
    68	MOVW	$_rt0_arm_lib_go<>(SB), R0
    69	MOVW	$0, R1
    70	BL	(R2)
    71	B	rr
    72nocgo:
    73	MOVW	$0x800000, R0                     // stacksize = 8192KB
    74	MOVW	$_rt0_arm_lib_go<>(SB), R1  // fn
    75	MOVW	R0, 4(R13)
    76	MOVW	R1, 8(R13)
    77	BL	runtime·newosproc0(SB)
    78rr:
    79	// Restore callee-save registers and return.
    80	MOVB    runtime·goarmsoftfp(SB), R11
    81	CMP     $0, R11
    82	BNE     skipfprest
    83	MOVD	(40+8*0)(R13), F8
    84	MOVD	(40+8*1)(R13), F9
    85	MOVD	(40+8*2)(R13), F10
    86	MOVD	(40+8*3)(R13), F11
    87	MOVD	(40+8*4)(R13), F12
    88	MOVD	(40+8*5)(R13), F13
    89	MOVD	(40+8*6)(R13), F14
    90	MOVD	(40+8*7)(R13), F15
    91skipfprest:
    92	MOVW	12(R13), R4
    93	MOVW	16(R13), R5
    94	MOVW	20(R13), R6
    95	MOVW	24(R13), R7
    96	MOVW	28(R13), R8
    97	MOVW	32(R13), g
    98	MOVW	36(R13), R11
    99	RET
   100
   101// _rt0_arm_lib_go initializes the Go runtime.
   102// This is started in a separate thread by _rt0_arm_lib.
   103TEXT _rt0_arm_lib_go<>(SB),NOSPLIT,$8
   104	MOVW	_rt0_arm_lib_argc<>(SB), R0
   105	MOVW	_rt0_arm_lib_argv<>(SB), R1
   106	B	runtime·rt0_go(SB)
   107
   108DATA _rt0_arm_lib_argc<>(SB)/4,$0
   109GLOBL _rt0_arm_lib_argc<>(SB),NOPTR,$4
   110DATA _rt0_arm_lib_argv<>(SB)/4,$0
   111GLOBL _rt0_arm_lib_argv<>(SB),NOPTR,$4
   112
   113// using NOFRAME means do not save LR on stack.
   114// argc is in R0, argv is in R1.
   115TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
   116	MOVW	$0xcafebabe, R12
   117
   118	// copy arguments forward on an even stack
   119	// use R13 instead of SP to avoid linker rewriting the offsets
   120	SUB	$64, R13		// plenty of scratch
   121	AND	$~7, R13
   122	MOVW	R0, 60(R13)		// save argc, argv away
   123	MOVW	R1, 64(R13)
   124
   125	// set up g register
   126	// g is R10
   127	MOVW	$runtime·g0(SB), g
   128	MOVW	$runtime·m0(SB), R8
   129
   130	// save m->g0 = g0
   131	MOVW	g, m_g0(R8)
   132	// save g->m = m0
   133	MOVW	R8, g_m(g)
   134
   135	// create istack out of the OS stack
   136	// (1MB of system stack is available on iOS and Android)
   137	MOVW	$(-64*1024+104)(R13), R0
   138	MOVW	R0, g_stackguard0(g)
   139	MOVW	R0, g_stackguard1(g)
   140	MOVW	R0, (g_stack+stack_lo)(g)
   141	MOVW	R13, (g_stack+stack_hi)(g)
   142
   143	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
   144
   145#ifdef GOOS_openbsd
   146	// Save g to TLS so that it is available from signal trampoline.
   147	BL	runtime·save_g(SB)
   148#endif
   149
   150	BL	runtime·_initcgo(SB)	// will clobber R0-R3
   151
   152	// update stackguard after _cgo_init
   153	MOVW	(g_stack+stack_lo)(g), R0
   154	ADD	$const_stackGuard, R0
   155	MOVW	R0, g_stackguard0(g)
   156	MOVW	R0, g_stackguard1(g)
   157
   158	BL	runtime·check(SB)
   159
   160	// saved argc, argv
   161	MOVW	60(R13), R0
   162	MOVW	R0, 4(R13)
   163	MOVW	64(R13), R1
   164	MOVW	R1, 8(R13)
   165	BL	runtime·args(SB)
   166	BL	runtime·checkgoarm(SB)
   167	BL	runtime·osinit(SB)
   168	BL	runtime·schedinit(SB)
   169
   170	// create a new goroutine to start program
   171	SUB	$8, R13
   172	MOVW	$runtime·mainPC(SB), R0
   173	MOVW	R0, 4(R13)	// arg 1: fn
   174	MOVW	$0, R0
   175	MOVW	R0, 0(R13)	// dummy LR
   176	BL	runtime·newproc(SB)
   177	ADD	$8, R13	// pop args and LR
   178
   179	// start this M
   180	BL	runtime·mstart(SB)
   181
   182	MOVW	$1234, R0
   183	MOVW	$1000, R1
   184	MOVW	R0, (R1)	// fail hard
   185
   186DATA	runtime·mainPC+0(SB)/4,$runtime·main(SB)
   187GLOBL	runtime·mainPC(SB),RODATA,$4
   188
   189TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
   190	// gdb won't skip this breakpoint instruction automatically,
   191	// so you must manually "set $pc+=4" to skip it and continue.
   192#ifdef GOOS_plan9
   193	WORD	$0xD1200070	// undefined instruction used as armv5 breakpoint in Plan 9
   194#else
   195	WORD	$0xe7f001f0	// undefined instruction that gdb understands is a software breakpoint
   196#endif
   197	RET
   198
   199TEXT runtime·asminit(SB),NOSPLIT,$0-0
   200	// disable runfast (flush-to-zero) mode of vfp if runtime.goarmsoftfp == 0
   201	MOVB	runtime·goarmsoftfp(SB), R11
   202	CMP	$0, R11
   203	BNE	4(PC)
   204	WORD	$0xeef1ba10	// vmrs r11, fpscr
   205	BIC	$(1<<24), R11
   206	WORD	$0xeee1ba10	// vmsr fpscr, r11
   207	RET
   208
   209TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
   210	BL	runtime·mstart0(SB)
   211	RET // not reached
   212
   213/*
   214 *  go-routine
   215 */
   216
   217// void gogo(Gobuf*)
   218// restore state from Gobuf; longjmp
   219TEXT runtime·gogo(SB),NOSPLIT|NOFRAME,$0-4
   220	MOVW	buf+0(FP), R1
   221	MOVW	gobuf_g(R1), R0
   222	MOVW	0(R0), R2	// make sure g != nil
   223	B	gogo<>(SB)
   224
   225TEXT gogo<>(SB),NOSPLIT|NOFRAME,$0
   226	BL	setg<>(SB)
   227	MOVW	gobuf_sp(R1), R13	// restore SP==R13
   228	MOVW	gobuf_lr(R1), LR
   229	MOVW	gobuf_ret(R1), R0
   230	MOVW	gobuf_ctxt(R1), R7
   231	MOVW	$0, R11
   232	MOVW	R11, gobuf_sp(R1)	// clear to help garbage collector
   233	MOVW	R11, gobuf_ret(R1)
   234	MOVW	R11, gobuf_lr(R1)
   235	MOVW	R11, gobuf_ctxt(R1)
   236	MOVW	gobuf_pc(R1), R11
   237	CMP	R11, R11 // set condition codes for == test, needed by stack split
   238	B	(R11)
   239
   240// func mcall(fn func(*g))
   241// Switch to m->g0's stack, call fn(g).
   242// Fn must never return. It should gogo(&g->sched)
   243// to keep running g.
   244TEXT runtime·mcall(SB),NOSPLIT|NOFRAME,$0-4
   245	// Save caller state in g->sched.
   246	MOVW	R13, (g_sched+gobuf_sp)(g)
   247	MOVW	LR, (g_sched+gobuf_pc)(g)
   248	MOVW	$0, R11
   249	MOVW	R11, (g_sched+gobuf_lr)(g)
   250
   251	// Switch to m->g0 & its stack, call fn.
   252	MOVW	g, R1
   253	MOVW	g_m(g), R8
   254	MOVW	m_g0(R8), R0
   255	BL	setg<>(SB)
   256	CMP	g, R1
   257	B.NE	2(PC)
   258	B	runtime·badmcall(SB)
   259	MOVW	fn+0(FP), R0
   260	MOVW	(g_sched+gobuf_sp)(g), R13
   261	SUB	$8, R13
   262	MOVW	R1, 4(R13)
   263	MOVW	R0, R7
   264	MOVW	0(R0), R0
   265	BL	(R0)
   266	B	runtime·badmcall2(SB)
   267	RET
   268
   269// systemstack_switch is a dummy routine that systemstack leaves at the bottom
   270// of the G stack. We need to distinguish the routine that
   271// lives at the bottom of the G stack from the one that lives
   272// at the top of the system stack because the one at the top of
   273// the system stack terminates the stack walk (see topofstack()).
   274TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0
   275	MOVW	$0, R0
   276	BL	(R0) // clobber lr to ensure push {lr} is kept
   277	RET
   278
   279// func systemstack(fn func())
   280TEXT runtime·systemstack(SB),NOSPLIT,$0-4
   281	MOVW	fn+0(FP), R0	// R0 = fn
   282	MOVW	g_m(g), R1	// R1 = m
   283
   284	MOVW	m_gsignal(R1), R2	// R2 = gsignal
   285	CMP	g, R2
   286	B.EQ	noswitch
   287
   288	MOVW	m_g0(R1), R2	// R2 = g0
   289	CMP	g, R2
   290	B.EQ	noswitch
   291
   292	MOVW	m_curg(R1), R3
   293	CMP	g, R3
   294	B.EQ	switch
   295
   296	// Bad: g is not gsignal, not g0, not curg. What is it?
   297	// Hide call from linker nosplit analysis.
   298	MOVW	$runtime·badsystemstack(SB), R0
   299	BL	(R0)
   300	B	runtime·abort(SB)
   301
   302switch:
   303	// save our state in g->sched. Pretend to
   304	// be systemstack_switch if the G stack is scanned.
   305	BL	gosave_systemstack_switch<>(SB)
   306
   307	// switch to g0
   308	MOVW	R0, R5
   309	MOVW	R2, R0
   310	BL	setg<>(SB)
   311	MOVW	R5, R0
   312	MOVW	(g_sched+gobuf_sp)(R2), R13
   313
   314	// call target function
   315	MOVW	R0, R7
   316	MOVW	0(R0), R0
   317	BL	(R0)
   318
   319	// switch back to g
   320	MOVW	g_m(g), R1
   321	MOVW	m_curg(R1), R0
   322	BL	setg<>(SB)
   323	MOVW	(g_sched+gobuf_sp)(g), R13
   324	MOVW	$0, R3
   325	MOVW	R3, (g_sched+gobuf_sp)(g)
   326	RET
   327
   328noswitch:
   329	// Using a tail call here cleans up tracebacks since we won't stop
   330	// at an intermediate systemstack.
   331	MOVW	R0, R7
   332	MOVW	0(R0), R0
   333	MOVW.P	4(R13), R14	// restore LR
   334	B	(R0)
   335
   336// func switchToCrashStack0(fn func())
   337TEXT runtime·switchToCrashStack0(SB), NOSPLIT, $0-4
   338	MOVW	fn+0(FP), R7 // context register
   339	MOVW	g_m(g), R1 // curm
   340
   341	// set g to gcrash
   342	MOVW	$runtime·gcrash(SB), R0
   343	BL	setg<>(SB)	// g = &gcrash
   344	MOVW	R1, g_m(g)	// g.m = curm
   345	MOVW	g, m_g0(R1)	// curm.g0 = g
   346
   347	// switch to crashstack
   348	MOVW	(g_stack+stack_hi)(g), R1
   349	SUB	$(4*8), R1
   350	MOVW	R1, R13
   351
   352	// call target function
   353	MOVW	0(R7), R0
   354	BL	(R0)
   355
   356	// should never return
   357	CALL	runtime·abort(SB)
   358	UNDEF
   359
   360/*
   361 * support for morestack
   362 */
   363
   364// Called during function prolog when more stack is needed.
   365// R3 prolog's LR
   366// using NOFRAME means do not save LR on stack.
   367//
   368// The traceback routines see morestack on a g0 as being
   369// the top of a stack (for example, morestack calling newstack
   370// calling the scheduler calling newm calling gc), so we must
   371// record an argument size. For that purpose, it has no arguments.
   372TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   373	// Cannot grow scheduler stack (m->g0).
   374	MOVW	g_m(g), R8
   375	MOVW	m_g0(R8), R4
   376
   377	// Called from f.
   378	// Set g->sched to context in f.
   379	MOVW	R13, (g_sched+gobuf_sp)(g)
   380	MOVW	LR, (g_sched+gobuf_pc)(g)
   381	MOVW	R3, (g_sched+gobuf_lr)(g)
   382	MOVW	R7, (g_sched+gobuf_ctxt)(g)
   383
   384	CMP	g, R4
   385	BNE	3(PC)
   386	BL	runtime·badmorestackg0(SB)
   387	B	runtime·abort(SB)
   388
   389	// Cannot grow signal stack (m->gsignal).
   390	MOVW	m_gsignal(R8), R4
   391	CMP	g, R4
   392	BNE	3(PC)
   393	BL	runtime·badmorestackgsignal(SB)
   394	B	runtime·abort(SB)
   395
   396	// Called from f.
   397	// Set m->morebuf to f's caller.
   398	MOVW	R3, (m_morebuf+gobuf_pc)(R8)	// f's caller's PC
   399	MOVW	R13, (m_morebuf+gobuf_sp)(R8)	// f's caller's SP
   400	MOVW	g, (m_morebuf+gobuf_g)(R8)
   401
   402	// Call newstack on m->g0's stack.
   403	MOVW	m_g0(R8), R0
   404	BL	setg<>(SB)
   405	MOVW	(g_sched+gobuf_sp)(g), R13
   406	MOVW	$0, R0
   407	MOVW.W  R0, -4(R13)	// create a call frame on g0 (saved LR)
   408	BL	runtime·newstack(SB)
   409
   410	// Not reached, but make sure the return PC from the call to newstack
   411	// is still in this function, and not the beginning of the next.
   412	RET
   413
   414TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   415	// Force SPWRITE. This function doesn't actually write SP,
   416	// but it is called with a special calling convention where
   417	// the caller doesn't save LR on stack but passes it as a
   418	// register (R3), and the unwinder currently doesn't understand.
   419	// Make it SPWRITE to stop unwinding. (See issue 54332)
   420	MOVW	R13, R13
   421
   422	MOVW	$0, R7
   423	B runtime·morestack(SB)
   424
   425// reflectcall: call a function with the given argument list
   426// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
   427// we don't have variable-sized frames, so we use a small number
   428// of constant-sized-frame functions to encode a few bits of size in the pc.
   429// Caution: ugly multiline assembly macros in your future!
   430
   431#define DISPATCH(NAME,MAXSIZE)		\
   432	CMP	$MAXSIZE, R0;		\
   433	B.HI	3(PC);			\
   434	MOVW	$NAME(SB), R1;		\
   435	B	(R1)
   436
   437TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-28
   438	MOVW	frameSize+20(FP), R0
   439	DISPATCH(runtime·call16, 16)
   440	DISPATCH(runtime·call32, 32)
   441	DISPATCH(runtime·call64, 64)
   442	DISPATCH(runtime·call128, 128)
   443	DISPATCH(runtime·call256, 256)
   444	DISPATCH(runtime·call512, 512)
   445	DISPATCH(runtime·call1024, 1024)
   446	DISPATCH(runtime·call2048, 2048)
   447	DISPATCH(runtime·call4096, 4096)
   448	DISPATCH(runtime·call8192, 8192)
   449	DISPATCH(runtime·call16384, 16384)
   450	DISPATCH(runtime·call32768, 32768)
   451	DISPATCH(runtime·call65536, 65536)
   452	DISPATCH(runtime·call131072, 131072)
   453	DISPATCH(runtime·call262144, 262144)
   454	DISPATCH(runtime·call524288, 524288)
   455	DISPATCH(runtime·call1048576, 1048576)
   456	DISPATCH(runtime·call2097152, 2097152)
   457	DISPATCH(runtime·call4194304, 4194304)
   458	DISPATCH(runtime·call8388608, 8388608)
   459	DISPATCH(runtime·call16777216, 16777216)
   460	DISPATCH(runtime·call33554432, 33554432)
   461	DISPATCH(runtime·call67108864, 67108864)
   462	DISPATCH(runtime·call134217728, 134217728)
   463	DISPATCH(runtime·call268435456, 268435456)
   464	DISPATCH(runtime·call536870912, 536870912)
   465	DISPATCH(runtime·call1073741824, 1073741824)
   466	MOVW	$runtime·badreflectcall(SB), R1
   467	B	(R1)
   468
   469#define CALLFN(NAME,MAXSIZE)			\
   470TEXT NAME(SB), WRAPPER, $MAXSIZE-28;		\
   471	NO_LOCAL_POINTERS;			\
   472	/* copy arguments to stack */		\
   473	MOVW	stackArgs+8(FP), R0;		\
   474	MOVW	stackArgsSize+12(FP), R2;		\
   475	ADD	$4, R13, R1;			\
   476	CMP	$0, R2;				\
   477	B.EQ	5(PC);				\
   478	MOVBU.P	1(R0), R5;			\
   479	MOVBU.P R5, 1(R1);			\
   480	SUB	$1, R2, R2;			\
   481	B	-5(PC);				\
   482	/* call function */			\
   483	MOVW	f+4(FP), R7;			\
   484	MOVW	(R7), R0;			\
   485	PCDATA  $PCDATA_StackMapIndex, $0;	\
   486	BL	(R0);				\
   487	/* copy return values back */		\
   488	MOVW	stackArgsType+0(FP), R4;		\
   489	MOVW	stackArgs+8(FP), R0;		\
   490	MOVW	stackArgsSize+12(FP), R2;		\
   491	MOVW	stackArgsRetOffset+16(FP), R3;		\
   492	ADD	$4, R13, R1;			\
   493	ADD	R3, R1;				\
   494	ADD	R3, R0;				\
   495	SUB	R3, R2;				\
   496	BL	callRet<>(SB);			\
   497	RET
   498
   499// callRet copies return values back at the end of call*. This is a
   500// separate function so it can allocate stack space for the arguments
   501// to reflectcallmove. It does not follow the Go ABI; it expects its
   502// arguments in registers.
   503TEXT callRet<>(SB), NOSPLIT, $20-0
   504	MOVW	R4, 4(R13)
   505	MOVW	R0, 8(R13)
   506	MOVW	R1, 12(R13)
   507	MOVW	R2, 16(R13)
   508	MOVW	$0, R7
   509	MOVW	R7, 20(R13)
   510	BL	runtime·reflectcallmove(SB)
   511	RET
   512
   513CALLFN(·call16, 16)
   514CALLFN(·call32, 32)
   515CALLFN(·call64, 64)
   516CALLFN(·call128, 128)
   517CALLFN(·call256, 256)
   518CALLFN(·call512, 512)
   519CALLFN(·call1024, 1024)
   520CALLFN(·call2048, 2048)
   521CALLFN(·call4096, 4096)
   522CALLFN(·call8192, 8192)
   523CALLFN(·call16384, 16384)
   524CALLFN(·call32768, 32768)
   525CALLFN(·call65536, 65536)
   526CALLFN(·call131072, 131072)
   527CALLFN(·call262144, 262144)
   528CALLFN(·call524288, 524288)
   529CALLFN(·call1048576, 1048576)
   530CALLFN(·call2097152, 2097152)
   531CALLFN(·call4194304, 4194304)
   532CALLFN(·call8388608, 8388608)
   533CALLFN(·call16777216, 16777216)
   534CALLFN(·call33554432, 33554432)
   535CALLFN(·call67108864, 67108864)
   536CALLFN(·call134217728, 134217728)
   537CALLFN(·call268435456, 268435456)
   538CALLFN(·call536870912, 536870912)
   539CALLFN(·call1073741824, 1073741824)
   540
   541// Save state of caller into g->sched,
   542// but using fake PC from systemstack_switch.
   543// Must only be called from functions with no locals ($0)
   544// or else unwinding from systemstack_switch is incorrect.
   545// Smashes R11.
   546TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
   547	MOVW	$runtime·systemstack_switch(SB), R11
   548	ADD	$4, R11 // get past push {lr}
   549	MOVW	R11, (g_sched+gobuf_pc)(g)
   550	MOVW	R13, (g_sched+gobuf_sp)(g)
   551	MOVW	$0, R11
   552	MOVW	R11, (g_sched+gobuf_lr)(g)
   553	MOVW	R11, (g_sched+gobuf_ret)(g)
   554	// Assert ctxt is zero. See func save.
   555	MOVW	(g_sched+gobuf_ctxt)(g), R11
   556	TST	R11, R11
   557	B.EQ	2(PC)
   558	BL	runtime·abort(SB)
   559	RET
   560
   561// func asmcgocall_no_g(fn, arg unsafe.Pointer)
   562// Call fn(arg) aligned appropriately for the gcc ABI.
   563// Called on a system stack, and there may be no g yet (during needm).
   564TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-8
   565	MOVW	fn+0(FP), R1
   566	MOVW	arg+4(FP), R0
   567	MOVW	R13, R2
   568	SUB	$32, R13
   569	BIC	$0x7, R13	// alignment for gcc ABI
   570	MOVW	R2, 8(R13)
   571	BL	(R1)
   572	MOVW	8(R13), R2
   573	MOVW	R2, R13
   574	RET
   575
   576// func asmcgocall(fn, arg unsafe.Pointer) int32
   577// Call fn(arg) on the scheduler stack,
   578// aligned appropriately for the gcc ABI.
   579// See cgocall.go for more details.
   580TEXT ·asmcgocall(SB),NOSPLIT,$0-12
   581	MOVW	fn+0(FP), R1
   582	MOVW	arg+4(FP), R0
   583
   584	MOVW	R13, R2
   585	CMP	$0, g
   586	BEQ nosave
   587	MOVW	g, R4
   588
   589	// Figure out if we need to switch to m->g0 stack.
   590	// We get called to create new OS threads too, and those
   591	// come in on the m->g0 stack already. Or we might already
   592	// be on the m->gsignal stack.
   593	MOVW	g_m(g), R8
   594	MOVW	m_gsignal(R8), R3
   595	CMP	R3, g
   596	BEQ	nosave
   597	MOVW	m_g0(R8), R3
   598	CMP	R3, g
   599	BEQ	nosave
   600	BL	gosave_systemstack_switch<>(SB)
   601	MOVW	R0, R5
   602	MOVW	R3, R0
   603	BL	setg<>(SB)
   604	MOVW	R5, R0
   605	MOVW	(g_sched+gobuf_sp)(g), R13
   606
   607	// Now on a scheduling stack (a pthread-created stack).
   608	SUB	$24, R13
   609	BIC	$0x7, R13	// alignment for gcc ABI
   610	MOVW	R4, 20(R13) // save old g
   611	MOVW	(g_stack+stack_hi)(R4), R4
   612	SUB	R2, R4
   613	MOVW	R4, 16(R13)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
   614	BL	(R1)
   615
   616	// Restore registers, g, stack pointer.
   617	MOVW	R0, R5
   618	MOVW	20(R13), R0
   619	BL	setg<>(SB)
   620	MOVW	(g_stack+stack_hi)(g), R1
   621	MOVW	16(R13), R2
   622	SUB	R2, R1
   623	MOVW	R5, R0
   624	MOVW	R1, R13
   625
   626	MOVW	R0, ret+8(FP)
   627	RET
   628
   629nosave:
   630	// Running on a system stack, perhaps even without a g.
   631	// Having no g can happen during thread creation or thread teardown
   632	// (see needm/dropm on Solaris, for example).
   633	// This code is like the above sequence but without saving/restoring g
   634	// and without worrying about the stack moving out from under us
   635	// (because we're on a system stack, not a goroutine stack).
   636	// The above code could be used directly if already on a system stack,
   637	// but then the only path through this code would be a rare case on Solaris.
   638	// Using this code for all "already on system stack" calls exercises it more,
   639	// which should help keep it correct.
   640	SUB	$24, R13
   641	BIC	$0x7, R13	// alignment for gcc ABI
   642	// save null g in case someone looks during debugging.
   643	MOVW	$0, R4
   644	MOVW	R4, 20(R13)
   645	MOVW	R2, 16(R13)	// Save old stack pointer.
   646	BL	(R1)
   647	// Restore stack pointer.
   648	MOVW	16(R13), R2
   649	MOVW	R2, R13
   650	MOVW	R0, ret+8(FP)
   651	RET
   652
   653// cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   654// See cgocall.go for more details.
   655TEXT	·cgocallback(SB),NOSPLIT,$12-12
   656	NO_LOCAL_POINTERS
   657
   658	// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
   659	// It is used to dropm while thread is exiting.
   660	MOVW	fn+0(FP), R1
   661	CMP	$0, R1
   662	B.NE	loadg
   663	// Restore the g from frame.
   664	MOVW	frame+4(FP), g
   665	B	dropm
   666
   667loadg:
   668	// Load m and g from thread-local storage.
   669#ifdef GOOS_openbsd
   670	BL	runtime·load_g(SB)
   671#else
   672	MOVB	runtime·iscgo(SB), R0
   673	CMP	$0, R0
   674	BL.NE	runtime·load_g(SB)
   675#endif
   676
   677	// If g is nil, Go did not create the current thread,
   678	// or if this thread never called into Go on pthread platforms.
   679	// Call needm to obtain one for temporary use.
   680	// In this case, we're running on the thread stack, so there's
   681	// lots of space, but the linker doesn't know. Hide the call from
   682	// the linker analysis by using an indirect call.
   683	CMP	$0, g
   684	B.EQ	needm
   685
   686	MOVW	g_m(g), R8
   687	MOVW	R8, savedm-4(SP)
   688	B	havem
   689
   690needm:
   691	MOVW	g, savedm-4(SP) // g is zero, so is m.
   692	MOVW	$runtime·needAndBindM(SB), R0
   693	BL	(R0)
   694
   695	// Set m->g0->sched.sp = SP, so that if a panic happens
   696	// during the function we are about to execute, it will
   697	// have a valid SP to run on the g0 stack.
   698	// The next few lines (after the havem label)
   699	// will save this SP onto the stack and then write
   700	// the same SP back to m->sched.sp. That seems redundant,
   701	// but if an unrecovered panic happens, unwindm will
   702	// restore the g->sched.sp from the stack location
   703	// and then systemstack will try to use it. If we don't set it here,
   704	// that restored SP will be uninitialized (typically 0) and
   705	// will not be usable.
   706	MOVW	g_m(g), R8
   707	MOVW	m_g0(R8), R3
   708	MOVW	R13, (g_sched+gobuf_sp)(R3)
   709
   710havem:
   711	// Now there's a valid m, and we're running on its m->g0.
   712	// Save current m->g0->sched.sp on stack and then set it to SP.
   713	// Save current sp in m->g0->sched.sp in preparation for
   714	// switch back to m->curg stack.
   715	// NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-12(SP).
   716	MOVW	m_g0(R8), R3
   717	MOVW	(g_sched+gobuf_sp)(R3), R4
   718	MOVW	R4, savedsp-12(SP)	// must match frame size
   719	MOVW	R13, (g_sched+gobuf_sp)(R3)
   720
   721	// Switch to m->curg stack and call runtime.cgocallbackg.
   722	// Because we are taking over the execution of m->curg
   723	// but *not* resuming what had been running, we need to
   724	// save that information (m->curg->sched) so we can restore it.
   725	// We can restore m->curg->sched.sp easily, because calling
   726	// runtime.cgocallbackg leaves SP unchanged upon return.
   727	// To save m->curg->sched.pc, we push it onto the curg stack and
   728	// open a frame the same size as cgocallback's g0 frame.
   729	// Once we switch to the curg stack, the pushed PC will appear
   730	// to be the return PC of cgocallback, so that the traceback
   731	// will seamlessly trace back into the earlier calls.
   732	MOVW	m_curg(R8), R0
   733	BL	setg<>(SB)
   734	MOVW	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
   735	MOVW	(g_sched+gobuf_pc)(g), R5
   736	MOVW	R5, -(12+4)(R4)	// "saved LR"; must match frame size
   737	// Gather our arguments into registers.
   738	MOVW	fn+0(FP), R1
   739	MOVW	frame+4(FP), R2
   740	MOVW	ctxt+8(FP), R3
   741	MOVW	$-(12+4)(R4), R13	// switch stack; must match frame size
   742	MOVW	R1, 4(R13)
   743	MOVW	R2, 8(R13)
   744	MOVW	R3, 12(R13)
   745	BL	runtime·cgocallbackg(SB)
   746
   747	// Restore g->sched (== m->curg->sched) from saved values.
   748	MOVW	0(R13), R5
   749	MOVW	R5, (g_sched+gobuf_pc)(g)
   750	MOVW	$(12+4)(R13), R4	// must match frame size
   751	MOVW	R4, (g_sched+gobuf_sp)(g)
   752
   753	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   754	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   755	// so we do not have to restore it.)
   756	MOVW	g_m(g), R8
   757	MOVW	m_g0(R8), R0
   758	BL	setg<>(SB)
   759	MOVW	(g_sched+gobuf_sp)(g), R13
   760	MOVW	savedsp-12(SP), R4	// must match frame size
   761	MOVW	R4, (g_sched+gobuf_sp)(g)
   762
   763	// If the m on entry was nil, we called needm above to borrow an m,
   764	// 1. for the duration of the call on non-pthread platforms,
   765	// 2. or the duration of the C thread alive on pthread platforms.
   766	// If the m on entry wasn't nil,
   767	// 1. the thread might be a Go thread,
   768	// 2. or it wasn't the first call from a C thread on pthread platforms,
   769	//    since then we skip dropm to reuse the m in the first call.
   770	MOVW	savedm-4(SP), R6
   771	CMP	$0, R6
   772	B.NE	done
   773
   774	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   775	MOVW	_cgo_pthread_key_created(SB), R6
   776	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   777	CMP	$0, R6
   778	B.EQ	dropm
   779	MOVW	(R6), R6
   780	CMP	$0, R6
   781	B.NE	done
   782
   783dropm:
   784	MOVW	$runtime·dropm(SB), R0
   785	BL	(R0)
   786
   787done:
   788	// Done!
   789	RET
   790
   791// void setg(G*); set g. for use by needm.
   792TEXT runtime·setg(SB),NOSPLIT|NOFRAME,$0-4
   793	MOVW	gg+0(FP), R0
   794	B	setg<>(SB)
   795
   796TEXT setg<>(SB),NOSPLIT|NOFRAME,$0-0
   797	MOVW	R0, g
   798
   799	// Save g to thread-local storage.
   800#ifdef GOOS_windows
   801	B	runtime·save_g(SB)
   802#else
   803#ifdef GOOS_openbsd
   804	B	runtime·save_g(SB)
   805#else
   806	MOVB	runtime·iscgo(SB), R0
   807	CMP	$0, R0
   808	B.EQ	2(PC)
   809	B	runtime·save_g(SB)
   810
   811	MOVW	g, R0
   812	RET
   813#endif
   814#endif
   815
   816TEXT runtime·emptyfunc(SB),0,$0-0
   817	RET
   818
   819TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   820	MOVW	$0, R0
   821	MOVW	(R0), R1
   822
   823// armPublicationBarrier is a native store/store barrier for ARMv7+.
   824// On earlier ARM revisions, armPublicationBarrier is a no-op.
   825// This will not work on SMP ARMv6 machines, if any are in use.
   826// To implement publicationBarrier in sys_$GOOS_arm.s using the native
   827// instructions, use:
   828//
   829//	TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
   830//		B	runtime·armPublicationBarrier(SB)
   831//
   832TEXT runtime·armPublicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
   833	MOVB	runtime·goarm(SB), R11
   834	CMP	$7, R11
   835	BLT	2(PC)
   836	DMB	MB_ST
   837	RET
   838
   839// AES hashing not implemented for ARM
   840TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-16
   841	JMP	runtime·memhashFallback(SB)
   842TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-12
   843	JMP	runtime·strhashFallback(SB)
   844TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-12
   845	JMP	runtime·memhash32Fallback(SB)
   846TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-12
   847	JMP	runtime·memhash64Fallback(SB)
   848
   849TEXT runtime·return0(SB),NOSPLIT,$0
   850	MOVW	$0, R0
   851	RET
   852
   853TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0
   854	MOVW	cycles+0(FP), R1
   855	MOVW	$0, R0
   856yieldloop:
   857	WORD	$0xe320f001	// YIELD (NOP pre-ARMv6K)
   858	CMP	R0, R1
   859	B.NE	2(PC)
   860	RET
   861	SUB	$1, R1
   862	B yieldloop
   863
   864// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   865// Must obey the gcc calling convention.
   866TEXT _cgo_topofstack(SB),NOSPLIT,$8
   867	// R11 and g register are clobbered by load_g. They are
   868	// callee-save in the gcc calling convention, so save them here.
   869	MOVW	R11, saveR11-4(SP)
   870	MOVW	g, saveG-8(SP)
   871
   872	BL	runtime·load_g(SB)
   873	MOVW	g_m(g), R0
   874	MOVW	m_curg(R0), R0
   875	MOVW	(g_stack+stack_hi)(R0), R0
   876
   877	MOVW	saveG-8(SP), g
   878	MOVW	saveR11-4(SP), R11
   879	RET
   880
   881// The top-most function running on a goroutine
   882// returns to goexit+PCQuantum.
   883TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   884	MOVW	R0, R0	// NOP
   885	BL	runtime·goexit1(SB)	// does not return
   886	// traceback from goexit1 must hit code range of goexit
   887	MOVW	R0, R0	// NOP
   888
   889// x -> x/1000000, x%1000000, called from Go with args, results on stack.
   890TEXT runtime·usplit(SB),NOSPLIT,$0-12
   891	MOVW	x+0(FP), R0
   892	CALL	runtime·usplitR0(SB)
   893	MOVW	R0, q+4(FP)
   894	MOVW	R1, r+8(FP)
   895	RET
   896
   897// R0, R1 = R0/1000000, R0%1000000
   898TEXT runtime·usplitR0(SB),NOSPLIT,$0
   899	// magic multiply to avoid software divide without available m.
   900	// see output of go tool compile -S for x/1000000.
   901	MOVW	R0, R3
   902	MOVW	$1125899907, R1
   903	MULLU	R1, R0, (R0, R1)
   904	MOVW	R0>>18, R0
   905	MOVW	$1000000, R1
   906	MULU	R0, R1
   907	SUB	R1, R3, R1
   908	RET
   909
   910// This is called from .init_array and follows the platform, not Go, ABI.
   911TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
   912	MOVW	R9, saver9-4(SP) // The access to global variables below implicitly uses R9, which is callee-save
   913	MOVW	R11, saver11-8(SP) // Likewise, R11 is the temp register, but callee-save in C ABI
   914	MOVW	runtime·lastmoduledatap(SB), R1
   915	MOVW	R0, moduledata_next(R1)
   916	MOVW	R0, runtime·lastmoduledatap(SB)
   917	MOVW	saver11-8(SP), R11
   918	MOVW	saver9-4(SP), R9
   919	RET
   920
   921TEXT ·checkASM(SB),NOSPLIT,$0-1
   922	MOVW	$1, R3
   923	MOVB	R3, ret+0(FP)
   924	RET
   925
   926// gcWriteBarrier informs the GC about heap pointer writes.
   927//
   928// gcWriteBarrier does NOT follow the Go ABI. It accepts the
   929// number of bytes of buffer needed in R8, and returns a pointer
   930// to the buffer space in R8.
   931// It clobbers condition codes.
   932// It does not clobber any other general-purpose registers,
   933// but may clobber others (e.g., floating point registers).
   934// The act of CALLing gcWriteBarrier will clobber R14 (LR).
   935TEXT gcWriteBarrier<>(SB),NOSPLIT|NOFRAME,$0
   936	// Save the registers clobbered by the fast path.
   937	MOVM.DB.W	[R0,R1], (R13)
   938retry:
   939	MOVW	g_m(g), R0
   940	MOVW	m_p(R0), R0
   941	MOVW	(p_wbBuf+wbBuf_next)(R0), R1
   942	MOVW	(p_wbBuf+wbBuf_end)(R0), R11
   943	// Increment wbBuf.next position.
   944	ADD	R8, R1
   945	// Is the buffer full?
   946	CMP	R11, R1
   947	BHI	flush
   948	// Commit to the larger buffer.
   949	MOVW	R1, (p_wbBuf+wbBuf_next)(R0)
   950	// Make return value (the original next position)
   951	SUB	R8, R1, R8
   952	// Restore registers.
   953	MOVM.IA.W	(R13), [R0,R1]
   954	RET
   955
   956flush:
   957	// Save all general purpose registers since these could be
   958	// clobbered by wbBufFlush and were not saved by the caller.
   959	//
   960	// R0 and R1 were saved at entry.
   961	// R10 is g, so preserved.
   962	// R11 is linker temp, so no need to save.
   963	// R13 is stack pointer.
   964	// R15 is PC.
   965	MOVM.DB.W	[R2-R9,R12], (R13)
   966	// Save R14 (LR) because the fast path above doesn't save it,
   967	// but needs it to RET.
   968	MOVM.DB.W	[R14], (R13)
   969
   970	CALL	runtime·wbBufFlush(SB)
   971
   972	MOVM.IA.W	(R13), [R14]
   973	MOVM.IA.W	(R13), [R2-R9,R12]
   974	JMP	retry
   975
   976TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   977	MOVW	$4, R8
   978	JMP	gcWriteBarrier<>(SB)
   979TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   980	MOVW	$8, R8
   981	JMP	gcWriteBarrier<>(SB)
   982TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   983	MOVW	$12, R8
   984	JMP	gcWriteBarrier<>(SB)
   985TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   986	MOVW	$16, R8
   987	JMP	gcWriteBarrier<>(SB)
   988TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   989	MOVW	$20, R8
   990	JMP	gcWriteBarrier<>(SB)
   991TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   992	MOVW	$24, R8
   993	JMP	gcWriteBarrier<>(SB)
   994TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   995	MOVW	$28, R8
   996	JMP	gcWriteBarrier<>(SB)
   997TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   998	MOVW	$32, R8
   999	JMP	gcWriteBarrier<>(SB)
  1000
  1001// Note: these functions use a special calling convention to save generated code space.
  1002// Arguments are passed in registers, but the space for those arguments are allocated
  1003// in the caller's stack frame. These stubs write the args into that stack space and
  1004// then tail call to the corresponding runtime handler.
  1005// The tail call makes these stubs disappear in backtraces.
  1006TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
  1007	MOVW	R0, x+0(FP)
  1008	MOVW	R1, y+4(FP)
  1009	JMP	runtime·goPanicIndex(SB)
  1010TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
  1011	MOVW	R0, x+0(FP)
  1012	MOVW	R1, y+4(FP)
  1013	JMP	runtime·goPanicIndexU(SB)
  1014TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
  1015	MOVW	R1, x+0(FP)
  1016	MOVW	R2, y+4(FP)
  1017	JMP	runtime·goPanicSliceAlen(SB)
  1018TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
  1019	MOVW	R1, x+0(FP)
  1020	MOVW	R2, y+4(FP)
  1021	JMP	runtime·goPanicSliceAlenU(SB)
  1022TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
  1023	MOVW	R1, x+0(FP)
  1024	MOVW	R2, y+4(FP)
  1025	JMP	runtime·goPanicSliceAcap(SB)
  1026TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
  1027	MOVW	R1, x+0(FP)
  1028	MOVW	R2, y+4(FP)
  1029	JMP	runtime·goPanicSliceAcapU(SB)
  1030TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
  1031	MOVW	R0, x+0(FP)
  1032	MOVW	R1, y+4(FP)
  1033	JMP	runtime·goPanicSliceB(SB)
  1034TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
  1035	MOVW	R0, x+0(FP)
  1036	MOVW	R1, y+4(FP)
  1037	JMP	runtime·goPanicSliceBU(SB)
  1038TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
  1039	MOVW	R2, x+0(FP)
  1040	MOVW	R3, y+4(FP)
  1041	JMP	runtime·goPanicSlice3Alen(SB)
  1042TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
  1043	MOVW	R2, x+0(FP)
  1044	MOVW	R3, y+4(FP)
  1045	JMP	runtime·goPanicSlice3AlenU(SB)
  1046TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
  1047	MOVW	R2, x+0(FP)
  1048	MOVW	R3, y+4(FP)
  1049	JMP	runtime·goPanicSlice3Acap(SB)
  1050TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
  1051	MOVW	R2, x+0(FP)
  1052	MOVW	R3, y+4(FP)
  1053	JMP	runtime·goPanicSlice3AcapU(SB)
  1054TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
  1055	MOVW	R1, x+0(FP)
  1056	MOVW	R2, y+4(FP)
  1057	JMP	runtime·goPanicSlice3B(SB)
  1058TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
  1059	MOVW	R1, x+0(FP)
  1060	MOVW	R2, y+4(FP)
  1061	JMP	runtime·goPanicSlice3BU(SB)
  1062TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
  1063	MOVW	R0, x+0(FP)
  1064	MOVW	R1, y+4(FP)
  1065	JMP	runtime·goPanicSlice3C(SB)
  1066TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
  1067	MOVW	R0, x+0(FP)
  1068	MOVW	R1, y+4(FP)
  1069	JMP	runtime·goPanicSlice3CU(SB)
  1070TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
  1071	MOVW	R2, x+0(FP)
  1072	MOVW	R3, y+4(FP)
  1073	JMP	runtime·goPanicSliceConvert(SB)
  1074
  1075// Extended versions for 64-bit indexes.
  1076TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
  1077	MOVW	R4, hi+0(FP)
  1078	MOVW	R0, lo+4(FP)
  1079	MOVW	R1, y+8(FP)
  1080	JMP	runtime·goPanicExtendIndex(SB)
  1081TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
  1082	MOVW	R4, hi+0(FP)
  1083	MOVW	R0, lo+4(FP)
  1084	MOVW	R1, y+8(FP)
  1085	JMP	runtime·goPanicExtendIndexU(SB)
  1086TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
  1087	MOVW	R4, hi+0(FP)
  1088	MOVW	R1, lo+4(FP)
  1089	MOVW	R2, y+8(FP)
  1090	JMP	runtime·goPanicExtendSliceAlen(SB)
  1091TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
  1092	MOVW	R4, hi+0(FP)
  1093	MOVW	R1, lo+4(FP)
  1094	MOVW	R2, y+8(FP)
  1095	JMP	runtime·goPanicExtendSliceAlenU(SB)
  1096TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
  1097	MOVW	R4, hi+0(FP)
  1098	MOVW	R1, lo+4(FP)
  1099	MOVW	R2, y+8(FP)
  1100	JMP	runtime·goPanicExtendSliceAcap(SB)
  1101TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
  1102	MOVW	R4, hi+0(FP)
  1103	MOVW	R1, lo+4(FP)
  1104	MOVW	R2, y+8(FP)
  1105	JMP	runtime·goPanicExtendSliceAcapU(SB)
  1106TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
  1107	MOVW	R4, hi+0(FP)
  1108	MOVW	R0, lo+4(FP)
  1109	MOVW	R1, y+8(FP)
  1110	JMP	runtime·goPanicExtendSliceB(SB)
  1111TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
  1112	MOVW	R4, hi+0(FP)
  1113	MOVW	R0, lo+4(FP)
  1114	MOVW	R1, y+8(FP)
  1115	JMP	runtime·goPanicExtendSliceBU(SB)
  1116TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
  1117	MOVW	R4, hi+0(FP)
  1118	MOVW	R2, lo+4(FP)
  1119	MOVW	R3, y+8(FP)
  1120	JMP	runtime·goPanicExtendSlice3Alen(SB)
  1121TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
  1122	MOVW	R4, hi+0(FP)
  1123	MOVW	R2, lo+4(FP)
  1124	MOVW	R3, y+8(FP)
  1125	JMP	runtime·goPanicExtendSlice3AlenU(SB)
  1126TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
  1127	MOVW	R4, hi+0(FP)
  1128	MOVW	R2, lo+4(FP)
  1129	MOVW	R3, y+8(FP)
  1130	JMP	runtime·goPanicExtendSlice3Acap(SB)
  1131TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
  1132	MOVW	R4, hi+0(FP)
  1133	MOVW	R2, lo+4(FP)
  1134	MOVW	R3, y+8(FP)
  1135	JMP	runtime·goPanicExtendSlice3AcapU(SB)
  1136TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
  1137	MOVW	R4, hi+0(FP)
  1138	MOVW	R1, lo+4(FP)
  1139	MOVW	R2, y+8(FP)
  1140	JMP	runtime·goPanicExtendSlice3B(SB)
  1141TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
  1142	MOVW	R4, hi+0(FP)
  1143	MOVW	R1, lo+4(FP)
  1144	MOVW	R2, y+8(FP)
  1145	JMP	runtime·goPanicExtendSlice3BU(SB)
  1146TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
  1147	MOVW	R4, hi+0(FP)
  1148	MOVW	R0, lo+4(FP)
  1149	MOVW	R1, y+8(FP)
  1150	JMP	runtime·goPanicExtendSlice3C(SB)
  1151TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
  1152	MOVW	R4, hi+0(FP)
  1153	MOVW	R0, lo+4(FP)
  1154	MOVW	R1, y+8(FP)
  1155	JMP	runtime·goPanicExtendSlice3CU(SB)

View as plain text