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