github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/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 "zasm_GOOS_GOARCH.h"
     6  #include "funcdata.h"
     7  #include "textflag.h"
     8  
     9  // using frame size $-4 means do not save LR on stack.
    10  TEXT runtime·rt0_go(SB),NOSPLIT,$-4
    11  	MOVW	$0xcafebabe, R12
    12  
    13  	// copy arguments forward on an even stack
    14  	// use R13 instead of SP to avoid linker rewriting the offsets
    15  	MOVW	0(R13), R0		// argc
    16  	MOVW	4(R13), R1		// argv
    17  	SUB	$64, R13		// plenty of scratch
    18  	AND	$~7, R13
    19  	MOVW	R0, 60(R13)		// save argc, argv away
    20  	MOVW	R1, 64(R13)
    21  
    22  	// set up g register
    23  	// g is R10
    24  	MOVW	$runtime·g0(SB), g
    25  	MOVW	$runtime·m0(SB), R8
    26  
    27  	// save m->g0 = g0
    28  	MOVW	g, m_g0(R8)
    29  	// save g->m = m0
    30  	MOVW	R8, g_m(g)
    31  
    32  	// create istack out of the OS stack
    33  	MOVW	$(-8192+104)(R13), R0
    34  	MOVW	R0, g_stackguard0(g)
    35  	MOVW	R0, g_stackguard1(g)
    36  	MOVW	R0, (g_stack+stack_lo)(g)
    37  	MOVW	R13, (g_stack+stack_hi)(g)
    38  
    39  	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
    40  
    41  #ifndef GOOS_nacl
    42  	// if there is an _cgo_init, call it.
    43  	MOVW	_cgo_init(SB), R4
    44  	CMP	$0, R4
    45  	B.EQ	nocgo
    46  	MRC     15, 0, R0, C13, C0, 3 	// load TLS base pointer
    47  	MOVW 	R0, R3 			// arg 3: TLS base pointer
    48  	MOVW 	$runtime·tlsg(SB), R2 	// arg 2: tlsg
    49  	MOVW	$setg_gcc<>(SB), R1 	// arg 1: setg
    50  	MOVW	g, R0 			// arg 0: G
    51  	BL	(R4) // will clobber R0-R3
    52  #endif
    53  
    54  nocgo:
    55  	// update stackguard after _cgo_init
    56  	MOVW	(g_stack+stack_lo)(g), R0
    57  	ADD	$const_StackGuard, R0
    58  	MOVW	R0, g_stackguard0(g)
    59  	MOVW	R0, g_stackguard1(g)
    60  
    61  	BL	runtime·checkgoarm(SB)
    62  	BL	runtime·check(SB)
    63  
    64  	// saved argc, argv
    65  	MOVW	60(R13), R0
    66  	MOVW	R0, 4(R13)
    67  	MOVW	64(R13), R1
    68  	MOVW	R1, 8(R13)
    69  	BL	runtime·args(SB)
    70  	BL	runtime·osinit(SB)
    71  	BL	runtime·schedinit(SB)
    72  
    73  	// create a new goroutine to start program
    74  	MOVW	$runtime·main·f(SB), R0
    75  	MOVW.W	R0, -4(R13)
    76  	MOVW	$8, R0
    77  	MOVW.W	R0, -4(R13)
    78  	MOVW	$0, R0
    79  	MOVW.W	R0, -4(R13)	// push $0 as guard
    80  	BL	runtime·newproc(SB)
    81  	MOVW	$12(R13), R13	// pop args and LR
    82  
    83  	// start this M
    84  	BL	runtime·mstart(SB)
    85  
    86  	MOVW	$1234, R0
    87  	MOVW	$1000, R1
    88  	MOVW	R0, (R1)	// fail hard
    89  
    90  DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
    91  GLOBL	runtime·main·f(SB),RODATA,$4
    92  
    93  TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
    94  	// gdb won't skip this breakpoint instruction automatically,
    95  	// so you must manually "set $pc+=4" to skip it and continue.
    96  #ifdef GOOS_nacl
    97  	WORD	$0xe125be7f	// BKPT 0x5bef, NACL_INSTR_ARM_BREAKPOINT
    98  #else
    99  	WORD	$0xe7f001f0	// undefined instruction that gdb understands is a software breakpoint
   100  #endif
   101  	RET
   102  
   103  TEXT runtime·asminit(SB),NOSPLIT,$0-0
   104  	// disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
   105  	MOVB	runtime·goarm(SB), R11
   106  	CMP	$5, R11
   107  	BLE	4(PC)
   108  	WORD	$0xeef1ba10	// vmrs r11, fpscr
   109  	BIC	$(1<<24), R11
   110  	WORD	$0xeee1ba10	// vmsr fpscr, r11
   111  	RET
   112  
   113  /*
   114   *  go-routine
   115   */
   116  
   117  // void gosave(Gobuf*)
   118  // save state in Gobuf; setjmp
   119  TEXT runtime·gosave(SB),NOSPLIT,$-4-4
   120  	MOVW	0(FP), R0		// gobuf
   121  	MOVW	SP, gobuf_sp(R0)
   122  	MOVW	LR, gobuf_pc(R0)
   123  	MOVW	g, gobuf_g(R0)
   124  	MOVW	$0, R11
   125  	MOVW	R11, gobuf_lr(R0)
   126  	MOVW	R11, gobuf_ret(R0)
   127  	MOVW	R11, gobuf_ctxt(R0)
   128  	RET
   129  
   130  // void gogo(Gobuf*)
   131  // restore state from Gobuf; longjmp
   132  TEXT runtime·gogo(SB),NOSPLIT,$-4-4
   133  	MOVW	0(FP), R1		// gobuf
   134  	MOVW	gobuf_g(R1), R0
   135  	BL	setg<>(SB)
   136  
   137  	// NOTE: We updated g above, and we are about to update SP.
   138  	// Until LR and PC are also updated, the g/SP/LR/PC quadruple
   139  	// are out of sync and must not be used as the basis of a traceback.
   140  	// Sigprof skips the traceback when SP is not within g's bounds,
   141  	// and when the PC is inside this function, runtime.gogo.
   142  	// Since we are about to update SP, until we complete runtime.gogo
   143  	// we must not leave this function. In particular, no calls
   144  	// after this point: it must be straight-line code until the
   145  	// final B instruction.
   146  	// See large comment in sigprof for more details.
   147  	MOVW	gobuf_sp(R1), SP	// restore SP
   148  	MOVW	gobuf_lr(R1), LR
   149  	MOVW	gobuf_ret(R1), R0
   150  	MOVW	gobuf_ctxt(R1), R7
   151  	MOVW	$0, R11
   152  	MOVW	R11, gobuf_sp(R1)	// clear to help garbage collector
   153  	MOVW	R11, gobuf_ret(R1)
   154  	MOVW	R11, gobuf_lr(R1)
   155  	MOVW	R11, gobuf_ctxt(R1)
   156  	MOVW	gobuf_pc(R1), R11
   157  	CMP	R11, R11 // set condition codes for == test, needed by stack split
   158  	B	(R11)
   159  
   160  // func mcall(fn func(*g))
   161  // Switch to m->g0's stack, call fn(g).
   162  // Fn must never return.  It should gogo(&g->sched)
   163  // to keep running g.
   164  TEXT runtime·mcall(SB),NOSPLIT,$-4-4
   165  	// Save caller state in g->sched.
   166  	MOVW	SP, (g_sched+gobuf_sp)(g)
   167  	MOVW	LR, (g_sched+gobuf_pc)(g)
   168  	MOVW	$0, R11
   169  	MOVW	R11, (g_sched+gobuf_lr)(g)
   170  	MOVW	g, (g_sched+gobuf_g)(g)
   171  
   172  	// Switch to m->g0 & its stack, call fn.
   173  	MOVW	g, R1
   174  	MOVW	g_m(g), R8
   175  	MOVW	m_g0(R8), R0
   176  	BL	setg<>(SB)
   177  	CMP	g, R1
   178  	B.NE	2(PC)
   179  	B	runtime·badmcall(SB)
   180  	MOVB	runtime·iscgo(SB), R11
   181  	CMP	$0, R11
   182  	BL.NE	runtime·save_g(SB)
   183  	MOVW	fn+0(FP), R0
   184  	MOVW	(g_sched+gobuf_sp)(g), SP
   185  	SUB	$8, SP
   186  	MOVW	R1, 4(SP)
   187  	MOVW	R0, R7
   188  	MOVW	0(R0), R0
   189  	BL	(R0)
   190  	B	runtime·badmcall2(SB)
   191  	RET
   192  
   193  // switchtoM is a dummy routine that onM leaves at the bottom
   194  // of the G stack.  We need to distinguish the routine that
   195  // lives at the bottom of the G stack from the one that lives
   196  // at the top of the M stack because the one at the top of
   197  // the M stack terminates the stack walk (see topofstack()).
   198  TEXT runtime·switchtoM(SB),NOSPLIT,$0-0
   199  	MOVW	$0, R0
   200  	BL	(R0) // clobber lr to ensure push {lr} is kept
   201  	RET
   202  
   203  // func onM_signalok(fn func())
   204  TEXT runtime·onM_signalok(SB), NOSPLIT, $-4-4
   205  	MOVW	g_m(g), R1
   206  	MOVW	m_gsignal(R1), R2
   207  	CMP	g, R2
   208  	B.EQ	ongsignal
   209  	B	runtime·onM(SB)
   210  
   211  ongsignal:
   212  	MOVW	fn+0(FP), R0
   213  	MOVW	R0, R7
   214  	MOVW	0(R0), R0
   215  	BL	(R0)
   216  	RET
   217  
   218  // func onM(fn func())
   219  TEXT runtime·onM(SB),NOSPLIT,$0-4
   220  	MOVW	fn+0(FP), R0	// R0 = fn
   221  	MOVW	g_m(g), R1	// R1 = m
   222  
   223  	MOVW	m_g0(R1), R2	// R2 = g0
   224  	CMP	g, R2
   225  	B.EQ	onm
   226  
   227  	MOVW	m_curg(R1), R3
   228  	CMP	g, R3
   229  	B.EQ	oncurg
   230  
   231  	// Not g0, not curg. Must be gsignal, but that's not allowed.
   232  	// Hide call from linker nosplit analysis.
   233  	MOVW	$runtime·badonm(SB), R0
   234  	BL	(R0)
   235  
   236  oncurg:
   237  	// save our state in g->sched.  Pretend to
   238  	// be switchtoM if the G stack is scanned.
   239  	MOVW	$runtime·switchtoM(SB), R3
   240  	ADD	$4, R3, R3 // get past push {lr}
   241  	MOVW	R3, (g_sched+gobuf_pc)(g)
   242  	MOVW	SP, (g_sched+gobuf_sp)(g)
   243  	MOVW	LR, (g_sched+gobuf_lr)(g)
   244  	MOVW	g, (g_sched+gobuf_g)(g)
   245  
   246  	// switch to g0
   247  	MOVW	R0, R5
   248  	MOVW	R2, R0
   249  	BL	setg<>(SB)
   250  	MOVW	R5, R0
   251  	MOVW	(g_sched+gobuf_sp)(R2), R3
   252  	// make it look like mstart called onM on g0, to stop traceback
   253  	SUB	$4, R3, R3
   254  	MOVW	$runtime·mstart(SB), R4
   255  	MOVW	R4, 0(R3)
   256  	MOVW	R3, SP
   257  
   258  	// call target function
   259  	MOVW	R0, R7
   260  	MOVW	0(R0), R0
   261  	BL	(R0)
   262  
   263  	// switch back to g
   264  	MOVW	g_m(g), R1
   265  	MOVW	m_curg(R1), R0
   266  	BL	setg<>(SB)
   267  	MOVW	(g_sched+gobuf_sp)(g), SP
   268  	MOVW	$0, R3
   269  	MOVW	R3, (g_sched+gobuf_sp)(g)
   270  	RET
   271  
   272  onm:
   273  	MOVW	R0, R7
   274  	MOVW	0(R0), R0
   275  	BL	(R0)
   276  	RET
   277  
   278  /*
   279   * support for morestack
   280   */
   281  
   282  // Called during function prolog when more stack is needed.
   283  // R1 frame size
   284  // R2 arg size
   285  // R3 prolog's LR
   286  // NB. we do not save R0 because we've forced 5c to pass all arguments
   287  // on the stack.
   288  // using frame size $-4 means do not save LR on stack.
   289  //
   290  // The traceback routines see morestack on a g0 as being
   291  // the top of a stack (for example, morestack calling newstack
   292  // calling the scheduler calling newm calling gc), so we must
   293  // record an argument size. For that purpose, it has no arguments.
   294  TEXT runtime·morestack(SB),NOSPLIT,$-4-0
   295  	// Cannot grow scheduler stack (m->g0).
   296  	MOVW	g_m(g), R8
   297  	MOVW	m_g0(R8), R4
   298  	CMP	g, R4
   299  	BL.EQ	runtime·abort(SB)
   300  
   301  	// Cannot grow signal stack (m->gsignal).
   302  	MOVW	m_gsignal(R8), R4
   303  	CMP	g, R4
   304  	BL.EQ	runtime·abort(SB)
   305  
   306  	// Called from f.
   307  	// Set g->sched to context in f.
   308  	MOVW	R7, (g_sched+gobuf_ctxt)(g)
   309  	MOVW	SP, (g_sched+gobuf_sp)(g)
   310  	MOVW	LR, (g_sched+gobuf_pc)(g)
   311  	MOVW	R3, (g_sched+gobuf_lr)(g)
   312  
   313  	// Called from f.
   314  	// Set m->morebuf to f's caller.
   315  	MOVW	R3, (m_morebuf+gobuf_pc)(R8)	// f's caller's PC
   316  	MOVW	SP, (m_morebuf+gobuf_sp)(R8)	// f's caller's SP
   317  	MOVW	$4(SP), R3			// f's argument pointer
   318  	MOVW	g, (m_morebuf+gobuf_g)(R8)
   319  
   320  	// Call newstack on m->g0's stack.
   321  	MOVW	m_g0(R8), R0
   322  	BL	setg<>(SB)
   323  	MOVW	(g_sched+gobuf_sp)(g), SP
   324  	BL	runtime·newstack(SB)
   325  
   326  	// Not reached, but make sure the return PC from the call to newstack
   327  	// is still in this function, and not the beginning of the next.
   328  	RET
   329  
   330  TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-4-0
   331  	MOVW	$0, R7
   332  	B runtime·morestack(SB)
   333  
   334  // reflectcall: call a function with the given argument list
   335  // func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
   336  // we don't have variable-sized frames, so we use a small number
   337  // of constant-sized-frame functions to encode a few bits of size in the pc.
   338  // Caution: ugly multiline assembly macros in your future!
   339  
   340  #define DISPATCH(NAME,MAXSIZE)		\
   341  	CMP	$MAXSIZE, R0;		\
   342  	B.HI	3(PC);			\
   343  	MOVW	$NAME(SB), R1;		\
   344  	B	(R1)
   345  
   346  TEXT ·reflectcall(SB),NOSPLIT,$-4-16
   347  	MOVW	argsize+8(FP), R0
   348  	DISPATCH(runtime·call16, 16)
   349  	DISPATCH(runtime·call32, 32)
   350  	DISPATCH(runtime·call64, 64)
   351  	DISPATCH(runtime·call128, 128)
   352  	DISPATCH(runtime·call256, 256)
   353  	DISPATCH(runtime·call512, 512)
   354  	DISPATCH(runtime·call1024, 1024)
   355  	DISPATCH(runtime·call2048, 2048)
   356  	DISPATCH(runtime·call4096, 4096)
   357  	DISPATCH(runtime·call8192, 8192)
   358  	DISPATCH(runtime·call16384, 16384)
   359  	DISPATCH(runtime·call32768, 32768)
   360  	DISPATCH(runtime·call65536, 65536)
   361  	DISPATCH(runtime·call131072, 131072)
   362  	DISPATCH(runtime·call262144, 262144)
   363  	DISPATCH(runtime·call524288, 524288)
   364  	DISPATCH(runtime·call1048576, 1048576)
   365  	DISPATCH(runtime·call2097152, 2097152)
   366  	DISPATCH(runtime·call4194304, 4194304)
   367  	DISPATCH(runtime·call8388608, 8388608)
   368  	DISPATCH(runtime·call16777216, 16777216)
   369  	DISPATCH(runtime·call33554432, 33554432)
   370  	DISPATCH(runtime·call67108864, 67108864)
   371  	DISPATCH(runtime·call134217728, 134217728)
   372  	DISPATCH(runtime·call268435456, 268435456)
   373  	DISPATCH(runtime·call536870912, 536870912)
   374  	DISPATCH(runtime·call1073741824, 1073741824)
   375  	MOVW	$runtime·badreflectcall(SB), R1
   376  	B	(R1)
   377  
   378  #define CALLFN(NAME,MAXSIZE)			\
   379  TEXT NAME(SB), WRAPPER, $MAXSIZE-16;		\
   380  	NO_LOCAL_POINTERS;			\
   381  	/* copy arguments to stack */		\
   382  	MOVW	argptr+4(FP), R0;		\
   383  	MOVW	argsize+8(FP), R2;		\
   384  	ADD	$4, SP, R1;			\
   385  	CMP	$0, R2;				\
   386  	B.EQ	5(PC);				\
   387  	MOVBU.P	1(R0), R5;			\
   388  	MOVBU.P R5, 1(R1);			\
   389  	SUB	$1, R2, R2;			\
   390  	B	-5(PC);				\
   391  	/* call function */			\
   392  	MOVW	f+0(FP), R7;			\
   393  	MOVW	(R7), R0;			\
   394  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   395  	BL	(R0);				\
   396  	/* copy return values back */		\
   397  	MOVW	argptr+4(FP), R0;		\
   398  	MOVW	argsize+8(FP), R2;		\
   399  	MOVW	retoffset+12(FP), R3;		\
   400  	ADD	$4, SP, R1;			\
   401  	ADD	R3, R1;				\
   402  	ADD	R3, R0;				\
   403  	SUB	R3, R2;				\
   404  	CMP	$0, R2;				\
   405  	RET.EQ	;				\
   406  	MOVBU.P	1(R1), R5;			\
   407  	MOVBU.P R5, 1(R0);			\
   408  	SUB	$1, R2, R2;			\
   409  	B	-5(PC)				\
   410  
   411  CALLFN(·call16, 16)
   412  CALLFN(·call32, 32)
   413  CALLFN(·call64, 64)
   414  CALLFN(·call128, 128)
   415  CALLFN(·call256, 256)
   416  CALLFN(·call512, 512)
   417  CALLFN(·call1024, 1024)
   418  CALLFN(·call2048, 2048)
   419  CALLFN(·call4096, 4096)
   420  CALLFN(·call8192, 8192)
   421  CALLFN(·call16384, 16384)
   422  CALLFN(·call32768, 32768)
   423  CALLFN(·call65536, 65536)
   424  CALLFN(·call131072, 131072)
   425  CALLFN(·call262144, 262144)
   426  CALLFN(·call524288, 524288)
   427  CALLFN(·call1048576, 1048576)
   428  CALLFN(·call2097152, 2097152)
   429  CALLFN(·call4194304, 4194304)
   430  CALLFN(·call8388608, 8388608)
   431  CALLFN(·call16777216, 16777216)
   432  CALLFN(·call33554432, 33554432)
   433  CALLFN(·call67108864, 67108864)
   434  CALLFN(·call134217728, 134217728)
   435  CALLFN(·call268435456, 268435456)
   436  CALLFN(·call536870912, 536870912)
   437  CALLFN(·call1073741824, 1073741824)
   438  
   439  // void jmpdefer(fn, sp);
   440  // called from deferreturn.
   441  // 1. grab stored LR for caller
   442  // 2. sub 4 bytes to get back to BL deferreturn
   443  // 3. B to fn
   444  // TODO(rsc): Push things on stack and then use pop
   445  // to load all registers simultaneously, so that a profiling
   446  // interrupt can never see mismatched SP/LR/PC.
   447  // (And double-check that pop is atomic in that way.)
   448  TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
   449  	MOVW	0(SP), LR
   450  	MOVW	$-4(LR), LR	// BL deferreturn
   451  	MOVW	fv+0(FP), R7
   452  	MOVW	argp+4(FP), SP
   453  	MOVW	$-4(SP), SP	// SP is 4 below argp, due to saved LR
   454  	MOVW	0(R7), R1
   455  	B	(R1)
   456  
   457  // Save state of caller into g->sched. Smashes R11.
   458  TEXT gosave<>(SB),NOSPLIT,$0
   459  	MOVW	LR, (g_sched+gobuf_pc)(g)
   460  	MOVW	R13, (g_sched+gobuf_sp)(g)
   461  	MOVW	$0, R11
   462  	MOVW	R11, (g_sched+gobuf_lr)(g)
   463  	MOVW	R11, (g_sched+gobuf_ret)(g)
   464  	MOVW	R11, (g_sched+gobuf_ctxt)(g)
   465  	RET
   466  
   467  // asmcgocall(void(*fn)(void*), void *arg)
   468  // Call fn(arg) on the scheduler stack,
   469  // aligned appropriately for the gcc ABI.
   470  // See cgocall.c for more details.
   471  TEXT	·asmcgocall(SB),NOSPLIT,$0-8
   472  	MOVW	fn+0(FP), R1
   473  	MOVW	arg+4(FP), R0
   474  	BL	asmcgocall<>(SB)
   475  	RET
   476  
   477  TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12
   478  	MOVW	fn+0(FP), R1
   479  	MOVW	arg+4(FP), R0
   480  	BL	asmcgocall<>(SB)
   481  	MOVW	R0, ret+8(FP)
   482  	RET
   483  
   484  TEXT asmcgocall<>(SB),NOSPLIT,$0-0
   485  	// fn in R1, arg in R0.
   486  	MOVW	R13, R2
   487  	MOVW	g, R4
   488  
   489  	// Figure out if we need to switch to m->g0 stack.
   490  	// We get called to create new OS threads too, and those
   491  	// come in on the m->g0 stack already.
   492  	MOVW	g_m(g), R8
   493  	MOVW	m_g0(R8), R3
   494  	CMP	R3, g
   495  	BEQ	asmcgocall_g0
   496  	BL	gosave<>(SB)
   497  	MOVW	R0, R5
   498  	MOVW	R3, R0
   499  	BL	setg<>(SB)
   500  	MOVW	R5, R0
   501  	MOVW	(g_sched+gobuf_sp)(g), R13
   502  
   503  	// Now on a scheduling stack (a pthread-created stack).
   504  asmcgocall_g0:
   505  	SUB	$24, R13
   506  	BIC	$0x7, R13	// alignment for gcc ABI
   507  	MOVW	R4, 20(R13) // save old g
   508  	MOVW	(g_stack+stack_hi)(R4), R4
   509  	SUB	R2, R4
   510  	MOVW	R4, 16(R13)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
   511  	BL	(R1)
   512  
   513  	// Restore registers, g, stack pointer.
   514  	MOVW	R0, R5
   515  	MOVW	20(R13), R0
   516  	BL	setg<>(SB)
   517  	MOVW	(g_stack+stack_hi)(g), R1
   518  	MOVW	16(R13), R2
   519  	SUB	R2, R1
   520  	MOVW	R5, R0
   521  	MOVW	R1, R13
   522  	RET
   523  
   524  // cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
   525  // Turn the fn into a Go func (by taking its address) and call
   526  // cgocallback_gofunc.
   527  TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
   528  	MOVW	$fn+0(FP), R0
   529  	MOVW	R0, 4(R13)
   530  	MOVW	frame+4(FP), R0
   531  	MOVW	R0, 8(R13)
   532  	MOVW	framesize+8(FP), R0
   533  	MOVW	R0, 12(R13)
   534  	MOVW	$runtime·cgocallback_gofunc(SB), R0
   535  	BL	(R0)
   536  	RET
   537  
   538  // cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize)
   539  // See cgocall.c for more details.
   540  TEXT	·cgocallback_gofunc(SB),NOSPLIT,$8-12
   541  	NO_LOCAL_POINTERS
   542  	
   543  	// Load m and g from thread-local storage.
   544  	MOVB	runtime·iscgo(SB), R0
   545  	CMP	$0, R0
   546  	BL.NE	runtime·load_g(SB)
   547  
   548  	// If g is nil, Go did not create the current thread.
   549  	// Call needm to obtain one for temporary use.
   550  	// In this case, we're running on the thread stack, so there's
   551  	// lots of space, but the linker doesn't know. Hide the call from
   552  	// the linker analysis by using an indirect call.
   553  	CMP	$0, g
   554  	B.NE	havem
   555  	MOVW	g, savedm-4(SP) // g is zero, so is m.
   556  	MOVW	$runtime·needm(SB), R0
   557  	BL	(R0)
   558  
   559  	// Set m->sched.sp = SP, so that if a panic happens
   560  	// during the function we are about to execute, it will
   561  	// have a valid SP to run on the g0 stack.
   562  	// The next few lines (after the havem label)
   563  	// will save this SP onto the stack and then write
   564  	// the same SP back to m->sched.sp. That seems redundant,
   565  	// but if an unrecovered panic happens, unwindm will
   566  	// restore the g->sched.sp from the stack location
   567  	// and then onM will try to use it. If we don't set it here,
   568  	// that restored SP will be uninitialized (typically 0) and
   569  	// will not be usable.
   570  	MOVW	g_m(g), R8
   571  	MOVW	m_g0(R8), R3
   572  	MOVW	R13, (g_sched+gobuf_sp)(R3)
   573  
   574  havem:
   575  	MOVW	g_m(g), R8
   576  	MOVW	R8, savedm-4(SP)
   577  	// Now there's a valid m, and we're running on its m->g0.
   578  	// Save current m->g0->sched.sp on stack and then set it to SP.
   579  	// Save current sp in m->g0->sched.sp in preparation for
   580  	// switch back to m->curg stack.
   581  	// NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP).
   582  	MOVW	m_g0(R8), R3
   583  	MOVW	(g_sched+gobuf_sp)(R3), R4
   584  	MOVW	R4, savedsp-8(SP)
   585  	MOVW	R13, (g_sched+gobuf_sp)(R3)
   586  
   587  	// Switch to m->curg stack and call runtime.cgocallbackg.
   588  	// Because we are taking over the execution of m->curg
   589  	// but *not* resuming what had been running, we need to
   590  	// save that information (m->curg->sched) so we can restore it.
   591  	// We can restore m->curg->sched.sp easily, because calling
   592  	// runtime.cgocallbackg leaves SP unchanged upon return.
   593  	// To save m->curg->sched.pc, we push it onto the stack.
   594  	// This has the added benefit that it looks to the traceback
   595  	// routine like cgocallbackg is going to return to that
   596  	// PC (because the frame we allocate below has the same
   597  	// size as cgocallback_gofunc's frame declared above)
   598  	// so that the traceback will seamlessly trace back into
   599  	// the earlier calls.
   600  	//
   601  	// In the new goroutine, -8(SP) and -4(SP) are unused.
   602  	MOVW	m_curg(R8), R0
   603  	BL	setg<>(SB)
   604  	MOVW	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
   605  	MOVW	(g_sched+gobuf_pc)(g), R5
   606  	MOVW	R5, -12(R4)
   607  	MOVW	$-12(R4), R13
   608  	BL	runtime·cgocallbackg(SB)
   609  
   610  	// Restore g->sched (== m->curg->sched) from saved values.
   611  	MOVW	0(R13), R5
   612  	MOVW	R5, (g_sched+gobuf_pc)(g)
   613  	MOVW	$12(R13), R4
   614  	MOVW	R4, (g_sched+gobuf_sp)(g)
   615  
   616  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   617  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   618  	// so we do not have to restore it.)
   619  	MOVW	g_m(g), R8
   620  	MOVW	m_g0(R8), R0
   621  	BL	setg<>(SB)
   622  	MOVW	(g_sched+gobuf_sp)(g), R13
   623  	MOVW	savedsp-8(SP), R4
   624  	MOVW	R4, (g_sched+gobuf_sp)(g)
   625  
   626  	// If the m on entry was nil, we called needm above to borrow an m
   627  	// for the duration of the call. Since the call is over, return it with dropm.
   628  	MOVW	savedm-4(SP), R6
   629  	CMP	$0, R6
   630  	B.NE	3(PC)
   631  	MOVW	$runtime·dropm(SB), R0
   632  	BL	(R0)
   633  
   634  	// Done!
   635  	RET
   636  
   637  // void setg(G*); set g. for use by needm.
   638  TEXT runtime·setg(SB),NOSPLIT,$-4-4
   639  	MOVW	gg+0(FP), R0
   640  	B	setg<>(SB)
   641  
   642  TEXT setg<>(SB),NOSPLIT,$-4-0
   643  	MOVW	R0, g
   644  
   645  	// Save g to thread-local storage.
   646  	MOVB	runtime·iscgo(SB), R0
   647  	CMP	$0, R0
   648  	B.EQ	2(PC)
   649  	B	runtime·save_g(SB)
   650  
   651  	MOVW	g, R0
   652  	RET
   653  
   654  TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
   655  	MOVW	0(SP), R0
   656  	MOVW	R0, ret+4(FP)
   657  	RET
   658  
   659  TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-4-8
   660  	MOVW	R14, ret+4(FP)
   661  	RET
   662  
   663  TEXT runtime·setcallerpc(SB),NOSPLIT,$-4-8
   664  	MOVW	pc+4(FP), R0
   665  	MOVW	R0, 0(SP)
   666  	RET
   667  
   668  TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
   669  	MOVW	0(FP), R0
   670  	MOVW	$-4(R0), R0
   671  	MOVW	R0, ret+4(FP)
   672  	RET
   673  
   674  // func gogetcallersp(p unsafe.Pointer) uintptr
   675  TEXT runtime·gogetcallersp(SB),NOSPLIT,$-4-8
   676  	MOVW	0(FP), R0
   677  	MOVW	$-4(R0), R0
   678  	MOVW	R0, ret+4(FP)
   679  	RET
   680  
   681  TEXT runtime·emptyfunc(SB),0,$0-0
   682  	RET
   683  
   684  TEXT runtime·abort(SB),NOSPLIT,$-4-0
   685  	MOVW	$0, R0
   686  	MOVW	(R0), R1
   687  
   688  // bool armcas(int32 *val, int32 old, int32 new)
   689  // Atomically:
   690  //	if(*val == old){
   691  //		*val = new;
   692  //		return 1;
   693  //	}else
   694  //		return 0;
   695  //
   696  // To implement runtime·cas in sys_$GOOS_arm.s
   697  // using the native instructions, use:
   698  //
   699  //	TEXT runtime·cas(SB),NOSPLIT,$0
   700  //		B	runtime·armcas(SB)
   701  //
   702  TEXT runtime·armcas(SB),NOSPLIT,$0-13
   703  	MOVW	valptr+0(FP), R1
   704  	MOVW	old+4(FP), R2
   705  	MOVW	new+8(FP), R3
   706  casl:
   707  	LDREX	(R1), R0
   708  	CMP	R0, R2
   709  	BNE	casfail
   710  	STREX	R3, (R1), R0
   711  	CMP	$0, R0
   712  	BNE	casl
   713  	MOVW	$1, R0
   714  	MOVB	R0, ret+12(FP)
   715  	RET
   716  casfail:
   717  	MOVW	$0, R0
   718  	MOVB	R0, ret+12(FP)
   719  	RET
   720  
   721  TEXT runtime·casuintptr(SB),NOSPLIT,$0-13
   722  	B	runtime·cas(SB)
   723  
   724  TEXT runtime·atomicloaduintptr(SB),NOSPLIT,$0-8
   725  	B	runtime·atomicload(SB)
   726  
   727  TEXT runtime·atomicloaduint(SB),NOSPLIT,$0-8
   728  	B	runtime·atomicload(SB)
   729  
   730  TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
   731  	B	runtime·atomicstore(SB)
   732  
   733  // AES hashing not implemented for ARM
   734  TEXT runtime·aeshash(SB),NOSPLIT,$-4-0
   735  	MOVW	$0, R0
   736  	MOVW	(R0), R1
   737  TEXT runtime·aeshash32(SB),NOSPLIT,$-4-0
   738  	MOVW	$0, R0
   739  	MOVW	(R0), R1
   740  TEXT runtime·aeshash64(SB),NOSPLIT,$-4-0
   741  	MOVW	$0, R0
   742  	MOVW	(R0), R1
   743  TEXT runtime·aeshashstr(SB),NOSPLIT,$-4-0
   744  	MOVW	$0, R0
   745  	MOVW	(R0), R1
   746  
   747  TEXT runtime·memeq(SB),NOSPLIT,$-4-13
   748  	MOVW	a+0(FP), R1
   749  	MOVW	b+4(FP), R2
   750  	MOVW	size+8(FP), R3
   751  	ADD	R1, R3, R6
   752  	MOVW	$1, R0
   753  	MOVB	R0, ret+12(FP)
   754  _next2:
   755  	CMP	R1, R6
   756  	RET.EQ
   757  	MOVBU.P	1(R1), R4
   758  	MOVBU.P	1(R2), R5
   759  	CMP	R4, R5
   760  	BEQ	_next2
   761  
   762  	MOVW	$0, R0
   763  	MOVB	R0, ret+12(FP)
   764  	RET
   765  
   766  // eqstring tests whether two strings are equal.
   767  // See runtime_test.go:eqstring_generic for
   768  // equivalent Go code.
   769  TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
   770  	MOVW	s1len+4(FP), R0
   771  	MOVW	s2len+12(FP), R1
   772  	MOVW	$0, R7
   773  	CMP	R0, R1
   774  	MOVB.NE R7, v+16(FP)
   775  	RET.NE
   776  	MOVW	s1str+0(FP), R2
   777  	MOVW	s2str+8(FP), R3
   778  	MOVW	$1, R8
   779  	MOVB	R8, v+16(FP)
   780  	CMP	R2, R3
   781  	RET.EQ
   782  	ADD	R2, R0, R6
   783  _eqnext:
   784  	CMP	R2, R6
   785  	RET.EQ
   786  	MOVBU.P	1(R2), R4
   787  	MOVBU.P	1(R3), R5
   788  	CMP	R4, R5
   789  	BEQ	_eqnext
   790  	MOVB	R7, v+16(FP)
   791  	RET
   792  
   793  // void setg_gcc(G*); set g called from gcc.
   794  TEXT setg_gcc<>(SB),NOSPLIT,$0
   795  	MOVW	R0, g
   796  	B		runtime·save_g(SB)
   797  
   798  // TODO: share code with memeq?
   799  TEXT bytes·Equal(SB),NOSPLIT,$0
   800  	MOVW	a_len+4(FP), R1
   801  	MOVW	b_len+16(FP), R3
   802  	
   803  	CMP	R1, R3		// unequal lengths are not equal
   804  	B.NE	_notequal
   805  
   806  	MOVW	a+0(FP), R0
   807  	MOVW	b+12(FP), R2
   808  	ADD	R0, R1		// end
   809  
   810  _byteseq_next:
   811  	CMP	R0, R1
   812  	B.EQ	_equal		// reached the end
   813  	MOVBU.P	1(R0), R4
   814  	MOVBU.P	1(R2), R5
   815  	CMP	R4, R5
   816  	B.EQ	_byteseq_next
   817  
   818  _notequal:
   819  	MOVW	$0, R0
   820  	MOVBU	R0, ret+24(FP)
   821  	RET
   822  
   823  _equal:
   824  	MOVW	$1, R0
   825  	MOVBU	R0, ret+24(FP)
   826  	RET
   827  
   828  TEXT bytes·IndexByte(SB),NOSPLIT,$0
   829  	MOVW	s+0(FP), R0
   830  	MOVW	s_len+4(FP), R1
   831  	MOVBU	c+12(FP), R2	// byte to find
   832  	MOVW	R0, R4		// store base for later
   833  	ADD	R0, R1		// end 
   834  
   835  _loop:
   836  	CMP	R0, R1
   837  	B.EQ	_notfound
   838  	MOVBU.P	1(R0), R3
   839  	CMP	R2, R3
   840  	B.NE	_loop
   841  
   842  	SUB	$1, R0		// R0 will be one beyond the position we want
   843  	SUB	R4, R0		// remove base
   844  	MOVW    R0, ret+16(FP) 
   845  	RET
   846  
   847  _notfound:
   848  	MOVW	$-1, R0
   849  	MOVW	R0, ret+16(FP)
   850  	RET
   851  
   852  TEXT strings·IndexByte(SB),NOSPLIT,$0
   853  	MOVW	s+0(FP), R0
   854  	MOVW	s_len+4(FP), R1
   855  	MOVBU	c+8(FP), R2	// byte to find
   856  	MOVW	R0, R4		// store base for later
   857  	ADD	R0, R1		// end 
   858  
   859  _sib_loop:
   860  	CMP	R0, R1
   861  	B.EQ	_sib_notfound
   862  	MOVBU.P	1(R0), R3
   863  	CMP	R2, R3
   864  	B.NE	_sib_loop
   865  
   866  	SUB	$1, R0		// R0 will be one beyond the position we want
   867  	SUB	R4, R0		// remove base
   868  	MOVW	R0, ret+12(FP) 
   869  	RET
   870  
   871  _sib_notfound:
   872  	MOVW	$-1, R0
   873  	MOVW	R0, ret+12(FP)
   874  	RET
   875  
   876  // A Duff's device for zeroing memory.
   877  // The compiler jumps to computed addresses within
   878  // this routine to zero chunks of memory.  Do not
   879  // change this code without also changing the code
   880  // in ../../cmd/5g/ggen.c:clearfat.
   881  // R0: zero
   882  // R1: ptr to memory to be zeroed
   883  // R1 is updated as a side effect.
   884  TEXT runtime·duffzero(SB),NOSPLIT,$0-0
   885  	MOVW.P	R0, 4(R1)
   886  	MOVW.P	R0, 4(R1)
   887  	MOVW.P	R0, 4(R1)
   888  	MOVW.P	R0, 4(R1)
   889  	MOVW.P	R0, 4(R1)
   890  	MOVW.P	R0, 4(R1)
   891  	MOVW.P	R0, 4(R1)
   892  	MOVW.P	R0, 4(R1)
   893  	MOVW.P	R0, 4(R1)
   894  	MOVW.P	R0, 4(R1)
   895  	MOVW.P	R0, 4(R1)
   896  	MOVW.P	R0, 4(R1)
   897  	MOVW.P	R0, 4(R1)
   898  	MOVW.P	R0, 4(R1)
   899  	MOVW.P	R0, 4(R1)
   900  	MOVW.P	R0, 4(R1)
   901  	MOVW.P	R0, 4(R1)
   902  	MOVW.P	R0, 4(R1)
   903  	MOVW.P	R0, 4(R1)
   904  	MOVW.P	R0, 4(R1)
   905  	MOVW.P	R0, 4(R1)
   906  	MOVW.P	R0, 4(R1)
   907  	MOVW.P	R0, 4(R1)
   908  	MOVW.P	R0, 4(R1)
   909  	MOVW.P	R0, 4(R1)
   910  	MOVW.P	R0, 4(R1)
   911  	MOVW.P	R0, 4(R1)
   912  	MOVW.P	R0, 4(R1)
   913  	MOVW.P	R0, 4(R1)
   914  	MOVW.P	R0, 4(R1)
   915  	MOVW.P	R0, 4(R1)
   916  	MOVW.P	R0, 4(R1)
   917  	MOVW.P	R0, 4(R1)
   918  	MOVW.P	R0, 4(R1)
   919  	MOVW.P	R0, 4(R1)
   920  	MOVW.P	R0, 4(R1)
   921  	MOVW.P	R0, 4(R1)
   922  	MOVW.P	R0, 4(R1)
   923  	MOVW.P	R0, 4(R1)
   924  	MOVW.P	R0, 4(R1)
   925  	MOVW.P	R0, 4(R1)
   926  	MOVW.P	R0, 4(R1)
   927  	MOVW.P	R0, 4(R1)
   928  	MOVW.P	R0, 4(R1)
   929  	MOVW.P	R0, 4(R1)
   930  	MOVW.P	R0, 4(R1)
   931  	MOVW.P	R0, 4(R1)
   932  	MOVW.P	R0, 4(R1)
   933  	MOVW.P	R0, 4(R1)
   934  	MOVW.P	R0, 4(R1)
   935  	MOVW.P	R0, 4(R1)
   936  	MOVW.P	R0, 4(R1)
   937  	MOVW.P	R0, 4(R1)
   938  	MOVW.P	R0, 4(R1)
   939  	MOVW.P	R0, 4(R1)
   940  	MOVW.P	R0, 4(R1)
   941  	MOVW.P	R0, 4(R1)
   942  	MOVW.P	R0, 4(R1)
   943  	MOVW.P	R0, 4(R1)
   944  	MOVW.P	R0, 4(R1)
   945  	MOVW.P	R0, 4(R1)
   946  	MOVW.P	R0, 4(R1)
   947  	MOVW.P	R0, 4(R1)
   948  	MOVW.P	R0, 4(R1)
   949  	MOVW.P	R0, 4(R1)
   950  	MOVW.P	R0, 4(R1)
   951  	MOVW.P	R0, 4(R1)
   952  	MOVW.P	R0, 4(R1)
   953  	MOVW.P	R0, 4(R1)
   954  	MOVW.P	R0, 4(R1)
   955  	MOVW.P	R0, 4(R1)
   956  	MOVW.P	R0, 4(R1)
   957  	MOVW.P	R0, 4(R1)
   958  	MOVW.P	R0, 4(R1)
   959  	MOVW.P	R0, 4(R1)
   960  	MOVW.P	R0, 4(R1)
   961  	MOVW.P	R0, 4(R1)
   962  	MOVW.P	R0, 4(R1)
   963  	MOVW.P	R0, 4(R1)
   964  	MOVW.P	R0, 4(R1)
   965  	MOVW.P	R0, 4(R1)
   966  	MOVW.P	R0, 4(R1)
   967  	MOVW.P	R0, 4(R1)
   968  	MOVW.P	R0, 4(R1)
   969  	MOVW.P	R0, 4(R1)
   970  	MOVW.P	R0, 4(R1)
   971  	MOVW.P	R0, 4(R1)
   972  	MOVW.P	R0, 4(R1)
   973  	MOVW.P	R0, 4(R1)
   974  	MOVW.P	R0, 4(R1)
   975  	MOVW.P	R0, 4(R1)
   976  	MOVW.P	R0, 4(R1)
   977  	MOVW.P	R0, 4(R1)
   978  	MOVW.P	R0, 4(R1)
   979  	MOVW.P	R0, 4(R1)
   980  	MOVW.P	R0, 4(R1)
   981  	MOVW.P	R0, 4(R1)
   982  	MOVW.P	R0, 4(R1)
   983  	MOVW.P	R0, 4(R1)
   984  	MOVW.P	R0, 4(R1)
   985  	MOVW.P	R0, 4(R1)
   986  	MOVW.P	R0, 4(R1)
   987  	MOVW.P	R0, 4(R1)
   988  	MOVW.P	R0, 4(R1)
   989  	MOVW.P	R0, 4(R1)
   990  	MOVW.P	R0, 4(R1)
   991  	MOVW.P	R0, 4(R1)
   992  	MOVW.P	R0, 4(R1)
   993  	MOVW.P	R0, 4(R1)
   994  	MOVW.P	R0, 4(R1)
   995  	MOVW.P	R0, 4(R1)
   996  	MOVW.P	R0, 4(R1)
   997  	MOVW.P	R0, 4(R1)
   998  	MOVW.P	R0, 4(R1)
   999  	MOVW.P	R0, 4(R1)
  1000  	MOVW.P	R0, 4(R1)
  1001  	MOVW.P	R0, 4(R1)
  1002  	MOVW.P	R0, 4(R1)
  1003  	MOVW.P	R0, 4(R1)
  1004  	MOVW.P	R0, 4(R1)
  1005  	MOVW.P	R0, 4(R1)
  1006  	MOVW.P	R0, 4(R1)
  1007  	MOVW.P	R0, 4(R1)
  1008  	MOVW.P	R0, 4(R1)
  1009  	MOVW.P	R0, 4(R1)
  1010  	MOVW.P	R0, 4(R1)
  1011  	MOVW.P	R0, 4(R1)
  1012  	MOVW.P	R0, 4(R1)
  1013  	RET
  1014  
  1015  // A Duff's device for copying memory.
  1016  // The compiler jumps to computed addresses within
  1017  // this routine to copy chunks of memory.  Source
  1018  // and destination must not overlap.  Do not
  1019  // change this code without also changing the code
  1020  // in ../../cmd/5g/cgen.c:sgen.
  1021  // R0: scratch space
  1022  // R1: ptr to source memory
  1023  // R2: ptr to destination memory
  1024  // R1 and R2 are updated as a side effect
  1025  TEXT runtime·duffcopy(SB),NOSPLIT,$0-0
  1026  	MOVW.P	4(R1), R0
  1027  	MOVW.P	R0, 4(R2)
  1028  	MOVW.P	4(R1), R0
  1029  	MOVW.P	R0, 4(R2)
  1030  	MOVW.P	4(R1), R0
  1031  	MOVW.P	R0, 4(R2)
  1032  	MOVW.P	4(R1), R0
  1033  	MOVW.P	R0, 4(R2)
  1034  	MOVW.P	4(R1), R0
  1035  	MOVW.P	R0, 4(R2)
  1036  	MOVW.P	4(R1), R0
  1037  	MOVW.P	R0, 4(R2)
  1038  	MOVW.P	4(R1), R0
  1039  	MOVW.P	R0, 4(R2)
  1040  	MOVW.P	4(R1), R0
  1041  	MOVW.P	R0, 4(R2)
  1042  	MOVW.P	4(R1), R0
  1043  	MOVW.P	R0, 4(R2)
  1044  	MOVW.P	4(R1), R0
  1045  	MOVW.P	R0, 4(R2)
  1046  	MOVW.P	4(R1), R0
  1047  	MOVW.P	R0, 4(R2)
  1048  	MOVW.P	4(R1), R0
  1049  	MOVW.P	R0, 4(R2)
  1050  	MOVW.P	4(R1), R0
  1051  	MOVW.P	R0, 4(R2)
  1052  	MOVW.P	4(R1), R0
  1053  	MOVW.P	R0, 4(R2)
  1054  	MOVW.P	4(R1), R0
  1055  	MOVW.P	R0, 4(R2)
  1056  	MOVW.P	4(R1), R0
  1057  	MOVW.P	R0, 4(R2)
  1058  	MOVW.P	4(R1), R0
  1059  	MOVW.P	R0, 4(R2)
  1060  	MOVW.P	4(R1), R0
  1061  	MOVW.P	R0, 4(R2)
  1062  	MOVW.P	4(R1), R0
  1063  	MOVW.P	R0, 4(R2)
  1064  	MOVW.P	4(R1), R0
  1065  	MOVW.P	R0, 4(R2)
  1066  	MOVW.P	4(R1), R0
  1067  	MOVW.P	R0, 4(R2)
  1068  	MOVW.P	4(R1), R0
  1069  	MOVW.P	R0, 4(R2)
  1070  	MOVW.P	4(R1), R0
  1071  	MOVW.P	R0, 4(R2)
  1072  	MOVW.P	4(R1), R0
  1073  	MOVW.P	R0, 4(R2)
  1074  	MOVW.P	4(R1), R0
  1075  	MOVW.P	R0, 4(R2)
  1076  	MOVW.P	4(R1), R0
  1077  	MOVW.P	R0, 4(R2)
  1078  	MOVW.P	4(R1), R0
  1079  	MOVW.P	R0, 4(R2)
  1080  	MOVW.P	4(R1), R0
  1081  	MOVW.P	R0, 4(R2)
  1082  	MOVW.P	4(R1), R0
  1083  	MOVW.P	R0, 4(R2)
  1084  	MOVW.P	4(R1), R0
  1085  	MOVW.P	R0, 4(R2)
  1086  	MOVW.P	4(R1), R0
  1087  	MOVW.P	R0, 4(R2)
  1088  	MOVW.P	4(R1), R0
  1089  	MOVW.P	R0, 4(R2)
  1090  	MOVW.P	4(R1), R0
  1091  	MOVW.P	R0, 4(R2)
  1092  	MOVW.P	4(R1), R0
  1093  	MOVW.P	R0, 4(R2)
  1094  	MOVW.P	4(R1), R0
  1095  	MOVW.P	R0, 4(R2)
  1096  	MOVW.P	4(R1), R0
  1097  	MOVW.P	R0, 4(R2)
  1098  	MOVW.P	4(R1), R0
  1099  	MOVW.P	R0, 4(R2)
  1100  	MOVW.P	4(R1), R0
  1101  	MOVW.P	R0, 4(R2)
  1102  	MOVW.P	4(R1), R0
  1103  	MOVW.P	R0, 4(R2)
  1104  	MOVW.P	4(R1), R0
  1105  	MOVW.P	R0, 4(R2)
  1106  	MOVW.P	4(R1), R0
  1107  	MOVW.P	R0, 4(R2)
  1108  	MOVW.P	4(R1), R0
  1109  	MOVW.P	R0, 4(R2)
  1110  	MOVW.P	4(R1), R0
  1111  	MOVW.P	R0, 4(R2)
  1112  	MOVW.P	4(R1), R0
  1113  	MOVW.P	R0, 4(R2)
  1114  	MOVW.P	4(R1), R0
  1115  	MOVW.P	R0, 4(R2)
  1116  	MOVW.P	4(R1), R0
  1117  	MOVW.P	R0, 4(R2)
  1118  	MOVW.P	4(R1), R0
  1119  	MOVW.P	R0, 4(R2)
  1120  	MOVW.P	4(R1), R0
  1121  	MOVW.P	R0, 4(R2)
  1122  	MOVW.P	4(R1), R0
  1123  	MOVW.P	R0, 4(R2)
  1124  	MOVW.P	4(R1), R0
  1125  	MOVW.P	R0, 4(R2)
  1126  	MOVW.P	4(R1), R0
  1127  	MOVW.P	R0, 4(R2)
  1128  	MOVW.P	4(R1), R0
  1129  	MOVW.P	R0, 4(R2)
  1130  	MOVW.P	4(R1), R0
  1131  	MOVW.P	R0, 4(R2)
  1132  	MOVW.P	4(R1), R0
  1133  	MOVW.P	R0, 4(R2)
  1134  	MOVW.P	4(R1), R0
  1135  	MOVW.P	R0, 4(R2)
  1136  	MOVW.P	4(R1), R0
  1137  	MOVW.P	R0, 4(R2)
  1138  	MOVW.P	4(R1), R0
  1139  	MOVW.P	R0, 4(R2)
  1140  	MOVW.P	4(R1), R0
  1141  	MOVW.P	R0, 4(R2)
  1142  	MOVW.P	4(R1), R0
  1143  	MOVW.P	R0, 4(R2)
  1144  	MOVW.P	4(R1), R0
  1145  	MOVW.P	R0, 4(R2)
  1146  	MOVW.P	4(R1), R0
  1147  	MOVW.P	R0, 4(R2)
  1148  	MOVW.P	4(R1), R0
  1149  	MOVW.P	R0, 4(R2)
  1150  	MOVW.P	4(R1), R0
  1151  	MOVW.P	R0, 4(R2)
  1152  	MOVW.P	4(R1), R0
  1153  	MOVW.P	R0, 4(R2)
  1154  	MOVW.P	4(R1), R0
  1155  	MOVW.P	R0, 4(R2)
  1156  	MOVW.P	4(R1), R0
  1157  	MOVW.P	R0, 4(R2)
  1158  	MOVW.P	4(R1), R0
  1159  	MOVW.P	R0, 4(R2)
  1160  	MOVW.P	4(R1), R0
  1161  	MOVW.P	R0, 4(R2)
  1162  	MOVW.P	4(R1), R0
  1163  	MOVW.P	R0, 4(R2)
  1164  	MOVW.P	4(R1), R0
  1165  	MOVW.P	R0, 4(R2)
  1166  	MOVW.P	4(R1), R0
  1167  	MOVW.P	R0, 4(R2)
  1168  	MOVW.P	4(R1), R0
  1169  	MOVW.P	R0, 4(R2)
  1170  	MOVW.P	4(R1), R0
  1171  	MOVW.P	R0, 4(R2)
  1172  	MOVW.P	4(R1), R0
  1173  	MOVW.P	R0, 4(R2)
  1174  	MOVW.P	4(R1), R0
  1175  	MOVW.P	R0, 4(R2)
  1176  	MOVW.P	4(R1), R0
  1177  	MOVW.P	R0, 4(R2)
  1178  	MOVW.P	4(R1), R0
  1179  	MOVW.P	R0, 4(R2)
  1180  	MOVW.P	4(R1), R0
  1181  	MOVW.P	R0, 4(R2)
  1182  	MOVW.P	4(R1), R0
  1183  	MOVW.P	R0, 4(R2)
  1184  	MOVW.P	4(R1), R0
  1185  	MOVW.P	R0, 4(R2)
  1186  	MOVW.P	4(R1), R0
  1187  	MOVW.P	R0, 4(R2)
  1188  	MOVW.P	4(R1), R0
  1189  	MOVW.P	R0, 4(R2)
  1190  	MOVW.P	4(R1), R0
  1191  	MOVW.P	R0, 4(R2)
  1192  	MOVW.P	4(R1), R0
  1193  	MOVW.P	R0, 4(R2)
  1194  	MOVW.P	4(R1), R0
  1195  	MOVW.P	R0, 4(R2)
  1196  	MOVW.P	4(R1), R0
  1197  	MOVW.P	R0, 4(R2)
  1198  	MOVW.P	4(R1), R0
  1199  	MOVW.P	R0, 4(R2)
  1200  	MOVW.P	4(R1), R0
  1201  	MOVW.P	R0, 4(R2)
  1202  	MOVW.P	4(R1), R0
  1203  	MOVW.P	R0, 4(R2)
  1204  	MOVW.P	4(R1), R0
  1205  	MOVW.P	R0, 4(R2)
  1206  	MOVW.P	4(R1), R0
  1207  	MOVW.P	R0, 4(R2)
  1208  	MOVW.P	4(R1), R0
  1209  	MOVW.P	R0, 4(R2)
  1210  	MOVW.P	4(R1), R0
  1211  	MOVW.P	R0, 4(R2)
  1212  	MOVW.P	4(R1), R0
  1213  	MOVW.P	R0, 4(R2)
  1214  	MOVW.P	4(R1), R0
  1215  	MOVW.P	R0, 4(R2)
  1216  	MOVW.P	4(R1), R0
  1217  	MOVW.P	R0, 4(R2)
  1218  	MOVW.P	4(R1), R0
  1219  	MOVW.P	R0, 4(R2)
  1220  	MOVW.P	4(R1), R0
  1221  	MOVW.P	R0, 4(R2)
  1222  	MOVW.P	4(R1), R0
  1223  	MOVW.P	R0, 4(R2)
  1224  	MOVW.P	4(R1), R0
  1225  	MOVW.P	R0, 4(R2)
  1226  	MOVW.P	4(R1), R0
  1227  	MOVW.P	R0, 4(R2)
  1228  	MOVW.P	4(R1), R0
  1229  	MOVW.P	R0, 4(R2)
  1230  	MOVW.P	4(R1), R0
  1231  	MOVW.P	R0, 4(R2)
  1232  	MOVW.P	4(R1), R0
  1233  	MOVW.P	R0, 4(R2)
  1234  	MOVW.P	4(R1), R0
  1235  	MOVW.P	R0, 4(R2)
  1236  	MOVW.P	4(R1), R0
  1237  	MOVW.P	R0, 4(R2)
  1238  	MOVW.P	4(R1), R0
  1239  	MOVW.P	R0, 4(R2)
  1240  	MOVW.P	4(R1), R0
  1241  	MOVW.P	R0, 4(R2)
  1242  	MOVW.P	4(R1), R0
  1243  	MOVW.P	R0, 4(R2)
  1244  	MOVW.P	4(R1), R0
  1245  	MOVW.P	R0, 4(R2)
  1246  	MOVW.P	4(R1), R0
  1247  	MOVW.P	R0, 4(R2)
  1248  	MOVW.P	4(R1), R0
  1249  	MOVW.P	R0, 4(R2)
  1250  	MOVW.P	4(R1), R0
  1251  	MOVW.P	R0, 4(R2)
  1252  	MOVW.P	4(R1), R0
  1253  	MOVW.P	R0, 4(R2)
  1254  	MOVW.P	4(R1), R0
  1255  	MOVW.P	R0, 4(R2)
  1256  	MOVW.P	4(R1), R0
  1257  	MOVW.P	R0, 4(R2)
  1258  	MOVW.P	4(R1), R0
  1259  	MOVW.P	R0, 4(R2)
  1260  	MOVW.P	4(R1), R0
  1261  	MOVW.P	R0, 4(R2)
  1262  	MOVW.P	4(R1), R0
  1263  	MOVW.P	R0, 4(R2)
  1264  	MOVW.P	4(R1), R0
  1265  	MOVW.P	R0, 4(R2)
  1266  	MOVW.P	4(R1), R0
  1267  	MOVW.P	R0, 4(R2)
  1268  	MOVW.P	4(R1), R0
  1269  	MOVW.P	R0, 4(R2)
  1270  	MOVW.P	4(R1), R0
  1271  	MOVW.P	R0, 4(R2)
  1272  	MOVW.P	4(R1), R0
  1273  	MOVW.P	R0, 4(R2)
  1274  	MOVW.P	4(R1), R0
  1275  	MOVW.P	R0, 4(R2)
  1276  	MOVW.P	4(R1), R0
  1277  	MOVW.P	R0, 4(R2)
  1278  	MOVW.P	4(R1), R0
  1279  	MOVW.P	R0, 4(R2)
  1280  	MOVW.P	4(R1), R0
  1281  	MOVW.P	R0, 4(R2)
  1282  	RET
  1283  
  1284  TEXT runtime·fastrand1(SB),NOSPLIT,$-4-4
  1285  	MOVW	g_m(g), R1
  1286  	MOVW	m_fastrand(R1), R0
  1287  	ADD.S	R0, R0
  1288  	EOR.MI	$0x88888eef, R0
  1289  	MOVW	R0, m_fastrand(R1)
  1290  	MOVW	R0, ret+0(FP)
  1291  	RET
  1292  
  1293  TEXT runtime·return0(SB),NOSPLIT,$0
  1294  	MOVW	$0, R0
  1295  	RET
  1296  
  1297  TEXT runtime·procyield(SB),NOSPLIT,$-4
  1298  	MOVW	cycles+0(FP), R1
  1299  	MOVW	$0, R0
  1300  yieldloop:
  1301  	CMP	R0, R1
  1302  	B.NE	2(PC)
  1303  	RET
  1304  	SUB	$1, R1
  1305  	B yieldloop
  1306  
  1307  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
  1308  // Must obey the gcc calling convention.
  1309  TEXT _cgo_topofstack(SB),NOSPLIT,$8
  1310  	// R11 and g register are clobbered by load_g.  They are
  1311  	// callee-save in the gcc calling convention, so save them here.
  1312  	MOVW	R11, saveR11-4(SP)
  1313  	MOVW	g, saveG-8(SP)
  1314  	
  1315  	BL	runtime·load_g(SB)
  1316  	MOVW	g_m(g), R0
  1317  	MOVW	m_curg(R0), R0
  1318  	MOVW	(g_stack+stack_hi)(R0), R0
  1319  	
  1320  	MOVW	saveG-8(SP), g
  1321  	MOVW	saveR11-4(SP), R11
  1322  	RET
  1323  
  1324  // The top-most function running on a goroutine
  1325  // returns to goexit+PCQuantum.
  1326  TEXT runtime·goexit(SB),NOSPLIT,$-4-0
  1327  	MOVW	R0, R0	// NOP
  1328  	BL	runtime·goexit1(SB)	// does not return