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