github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/runtime/asm_arm.s (about)

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