Text file src/runtime/asm_arm.s

     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 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)
    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·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
    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  #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  
   186  DATA	runtime·mainPC+0(SB)/4,$runtime·main(SB)
   187  GLOBL	runtime·mainPC(SB),RODATA,$4
   188  
   189  TEXT 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  
   199  TEXT 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  
   209  TEXT 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
   219  TEXT 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  
   225  TEXT 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.
   244  TEXT 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()).
   274  TEXT 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())
   280  TEXT 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  
   302  switch:
   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  
   328  noswitch:
   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())
   337  TEXT 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.
   372  TEXT 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  
   414  TEXT 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  
   437  TEXT ·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)			\
   470  TEXT 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.
   503  TEXT 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  
   513  CALLFN(·call16, 16)
   514  CALLFN(·call32, 32)
   515  CALLFN(·call64, 64)
   516  CALLFN(·call128, 128)
   517  CALLFN(·call256, 256)
   518  CALLFN(·call512, 512)
   519  CALLFN(·call1024, 1024)
   520  CALLFN(·call2048, 2048)
   521  CALLFN(·call4096, 4096)
   522  CALLFN(·call8192, 8192)
   523  CALLFN(·call16384, 16384)
   524  CALLFN(·call32768, 32768)
   525  CALLFN(·call65536, 65536)
   526  CALLFN(·call131072, 131072)
   527  CALLFN(·call262144, 262144)
   528  CALLFN(·call524288, 524288)
   529  CALLFN(·call1048576, 1048576)
   530  CALLFN(·call2097152, 2097152)
   531  CALLFN(·call4194304, 4194304)
   532  CALLFN(·call8388608, 8388608)
   533  CALLFN(·call16777216, 16777216)
   534  CALLFN(·call33554432, 33554432)
   535  CALLFN(·call67108864, 67108864)
   536  CALLFN(·call134217728, 134217728)
   537  CALLFN(·call268435456, 268435456)
   538  CALLFN(·call536870912, 536870912)
   539  CALLFN(·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.
   546  TEXT 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).
   564  TEXT ·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.
   580  TEXT ·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  
   629  nosave:
   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.
   655  TEXT	·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  
   667  loadg:
   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  
   690  needm:
   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  
   710  havem:
   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  
   783  dropm:
   784  	MOVW	$runtime·dropm(SB), R0
   785  	BL	(R0)
   786  
   787  done:
   788  	// Done!
   789  	RET
   790  
   791  // void setg(G*); set g. for use by needm.
   792  TEXT runtime·setg(SB),NOSPLIT|NOFRAME,$0-4
   793  	MOVW	gg+0(FP), R0
   794  	B	setg<>(SB)
   795  
   796  TEXT 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  
   816  TEXT runtime·emptyfunc(SB),0,$0-0
   817  	RET
   818  
   819  TEXT 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  //
   832  TEXT 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
   840  TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-16
   841  	JMP	runtime·memhashFallback(SB)
   842  TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-12
   843  	JMP	runtime·strhashFallback(SB)
   844  TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-12
   845  	JMP	runtime·memhash32Fallback(SB)
   846  TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-12
   847  	JMP	runtime·memhash64Fallback(SB)
   848  
   849  TEXT runtime·return0(SB),NOSPLIT,$0
   850  	MOVW	$0, R0
   851  	RET
   852  
   853  TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0
   854  	MOVW	cycles+0(FP), R1
   855  	MOVW	$0, R0
   856  yieldloop:
   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.
   866  TEXT _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.
   883  TEXT 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.
   890  TEXT 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
   898  TEXT 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.
   911  TEXT 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  
   921  TEXT ·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).
   935  TEXT gcWriteBarrier<>(SB),NOSPLIT|NOFRAME,$0
   936  	// Save the registers clobbered by the fast path.
   937  	MOVM.DB.W	[R0,R1], (R13)
   938  retry:
   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  
   956  flush:
   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  
   976  TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   977  	MOVW	$4, R8
   978  	JMP	gcWriteBarrier<>(SB)
   979  TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   980  	MOVW	$8, R8
   981  	JMP	gcWriteBarrier<>(SB)
   982  TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   983  	MOVW	$12, R8
   984  	JMP	gcWriteBarrier<>(SB)
   985  TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   986  	MOVW	$16, R8
   987  	JMP	gcWriteBarrier<>(SB)
   988  TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   989  	MOVW	$20, R8
   990  	JMP	gcWriteBarrier<>(SB)
   991  TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   992  	MOVW	$24, R8
   993  	JMP	gcWriteBarrier<>(SB)
   994  TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   995  	MOVW	$28, R8
   996  	JMP	gcWriteBarrier<>(SB)
   997  TEXT 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.
  1006  TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
  1007  	MOVW	R0, x+0(FP)
  1008  	MOVW	R1, y+4(FP)
  1009  	JMP	runtime·goPanicIndex(SB)
  1010  TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
  1011  	MOVW	R0, x+0(FP)
  1012  	MOVW	R1, y+4(FP)
  1013  	JMP	runtime·goPanicIndexU(SB)
  1014  TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
  1015  	MOVW	R1, x+0(FP)
  1016  	MOVW	R2, y+4(FP)
  1017  	JMP	runtime·goPanicSliceAlen(SB)
  1018  TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
  1019  	MOVW	R1, x+0(FP)
  1020  	MOVW	R2, y+4(FP)
  1021  	JMP	runtime·goPanicSliceAlenU(SB)
  1022  TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
  1023  	MOVW	R1, x+0(FP)
  1024  	MOVW	R2, y+4(FP)
  1025  	JMP	runtime·goPanicSliceAcap(SB)
  1026  TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
  1027  	MOVW	R1, x+0(FP)
  1028  	MOVW	R2, y+4(FP)
  1029  	JMP	runtime·goPanicSliceAcapU(SB)
  1030  TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
  1031  	MOVW	R0, x+0(FP)
  1032  	MOVW	R1, y+4(FP)
  1033  	JMP	runtime·goPanicSliceB(SB)
  1034  TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
  1035  	MOVW	R0, x+0(FP)
  1036  	MOVW	R1, y+4(FP)
  1037  	JMP	runtime·goPanicSliceBU(SB)
  1038  TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
  1039  	MOVW	R2, x+0(FP)
  1040  	MOVW	R3, y+4(FP)
  1041  	JMP	runtime·goPanicSlice3Alen(SB)
  1042  TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
  1043  	MOVW	R2, x+0(FP)
  1044  	MOVW	R3, y+4(FP)
  1045  	JMP	runtime·goPanicSlice3AlenU(SB)
  1046  TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
  1047  	MOVW	R2, x+0(FP)
  1048  	MOVW	R3, y+4(FP)
  1049  	JMP	runtime·goPanicSlice3Acap(SB)
  1050  TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
  1051  	MOVW	R2, x+0(FP)
  1052  	MOVW	R3, y+4(FP)
  1053  	JMP	runtime·goPanicSlice3AcapU(SB)
  1054  TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
  1055  	MOVW	R1, x+0(FP)
  1056  	MOVW	R2, y+4(FP)
  1057  	JMP	runtime·goPanicSlice3B(SB)
  1058  TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
  1059  	MOVW	R1, x+0(FP)
  1060  	MOVW	R2, y+4(FP)
  1061  	JMP	runtime·goPanicSlice3BU(SB)
  1062  TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
  1063  	MOVW	R0, x+0(FP)
  1064  	MOVW	R1, y+4(FP)
  1065  	JMP	runtime·goPanicSlice3C(SB)
  1066  TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
  1067  	MOVW	R0, x+0(FP)
  1068  	MOVW	R1, y+4(FP)
  1069  	JMP	runtime·goPanicSlice3CU(SB)
  1070  TEXT 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.
  1076  TEXT 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)
  1081  TEXT 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)
  1086  TEXT 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)
  1091  TEXT 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)
  1096  TEXT 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)
  1101  TEXT 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)
  1106  TEXT 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)
  1111  TEXT 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)
  1116  TEXT 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)
  1121  TEXT 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)
  1126  TEXT 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)
  1131  TEXT 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)
  1136  TEXT 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)
  1141  TEXT 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)
  1146  TEXT 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)
  1151  TEXT 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)
  1156  

View as plain text