github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/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(argtype *_type, 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 reflect·call(SB), NOSPLIT, $0-0
   337  	B	·reflectcall(SB)
   338  
   339  TEXT ·reflectcall(SB),NOSPLIT,$-4-20
   340  	MOVW	argsize+12(FP), R0
   341  	DISPATCH(runtime·call16, 16)
   342  	DISPATCH(runtime·call32, 32)
   343  	DISPATCH(runtime·call64, 64)
   344  	DISPATCH(runtime·call128, 128)
   345  	DISPATCH(runtime·call256, 256)
   346  	DISPATCH(runtime·call512, 512)
   347  	DISPATCH(runtime·call1024, 1024)
   348  	DISPATCH(runtime·call2048, 2048)
   349  	DISPATCH(runtime·call4096, 4096)
   350  	DISPATCH(runtime·call8192, 8192)
   351  	DISPATCH(runtime·call16384, 16384)
   352  	DISPATCH(runtime·call32768, 32768)
   353  	DISPATCH(runtime·call65536, 65536)
   354  	DISPATCH(runtime·call131072, 131072)
   355  	DISPATCH(runtime·call262144, 262144)
   356  	DISPATCH(runtime·call524288, 524288)
   357  	DISPATCH(runtime·call1048576, 1048576)
   358  	DISPATCH(runtime·call2097152, 2097152)
   359  	DISPATCH(runtime·call4194304, 4194304)
   360  	DISPATCH(runtime·call8388608, 8388608)
   361  	DISPATCH(runtime·call16777216, 16777216)
   362  	DISPATCH(runtime·call33554432, 33554432)
   363  	DISPATCH(runtime·call67108864, 67108864)
   364  	DISPATCH(runtime·call134217728, 134217728)
   365  	DISPATCH(runtime·call268435456, 268435456)
   366  	DISPATCH(runtime·call536870912, 536870912)
   367  	DISPATCH(runtime·call1073741824, 1073741824)
   368  	MOVW	$runtime·badreflectcall(SB), R1
   369  	B	(R1)
   370  
   371  #define CALLFN(NAME,MAXSIZE)			\
   372  TEXT NAME(SB), WRAPPER, $MAXSIZE-20;		\
   373  	NO_LOCAL_POINTERS;			\
   374  	/* copy arguments to stack */		\
   375  	MOVW	argptr+8(FP), R0;		\
   376  	MOVW	argsize+12(FP), R2;		\
   377  	ADD	$4, SP, R1;			\
   378  	CMP	$0, R2;				\
   379  	B.EQ	5(PC);				\
   380  	MOVBU.P	1(R0), R5;			\
   381  	MOVBU.P R5, 1(R1);			\
   382  	SUB	$1, R2, R2;			\
   383  	B	-5(PC);				\
   384  	/* call function */			\
   385  	MOVW	f+4(FP), R7;			\
   386  	MOVW	(R7), R0;			\
   387  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   388  	BL	(R0);				\
   389  	/* copy return values back */		\
   390  	MOVW	argptr+8(FP), R0;		\
   391  	MOVW	argsize+12(FP), R2;		\
   392  	MOVW	retoffset+16(FP), R3;		\
   393  	ADD	$4, SP, R1;			\
   394  	ADD	R3, R1;				\
   395  	ADD	R3, R0;				\
   396  	SUB	R3, R2;				\
   397  loop:						\
   398  	CMP	$0, R2;				\
   399  	B.EQ	end;				\
   400  	MOVBU.P	1(R1), R5;			\
   401  	MOVBU.P R5, 1(R0);			\
   402  	SUB	$1, R2, R2;			\
   403  	B	loop;				\
   404  end:						\
   405  	/* execute write barrier updates */	\
   406  	MOVW	argtype+0(FP), R1;		\
   407  	MOVW	argptr+8(FP), R0;		\
   408  	MOVW	argsize+12(FP), R2;		\
   409  	MOVW	retoffset+16(FP), R3;		\
   410  	MOVW	R1, 4(R13);			\
   411  	MOVW	R0, 8(R13);			\
   412  	MOVW	R2, 12(R13);			\
   413  	MOVW	R3, 16(R13);			\
   414  	BL	runtime·callwritebarrier(SB);	\
   415  	RET	
   416  
   417  CALLFN(·call16, 16)
   418  CALLFN(·call32, 32)
   419  CALLFN(·call64, 64)
   420  CALLFN(·call128, 128)
   421  CALLFN(·call256, 256)
   422  CALLFN(·call512, 512)
   423  CALLFN(·call1024, 1024)
   424  CALLFN(·call2048, 2048)
   425  CALLFN(·call4096, 4096)
   426  CALLFN(·call8192, 8192)
   427  CALLFN(·call16384, 16384)
   428  CALLFN(·call32768, 32768)
   429  CALLFN(·call65536, 65536)
   430  CALLFN(·call131072, 131072)
   431  CALLFN(·call262144, 262144)
   432  CALLFN(·call524288, 524288)
   433  CALLFN(·call1048576, 1048576)
   434  CALLFN(·call2097152, 2097152)
   435  CALLFN(·call4194304, 4194304)
   436  CALLFN(·call8388608, 8388608)
   437  CALLFN(·call16777216, 16777216)
   438  CALLFN(·call33554432, 33554432)
   439  CALLFN(·call67108864, 67108864)
   440  CALLFN(·call134217728, 134217728)
   441  CALLFN(·call268435456, 268435456)
   442  CALLFN(·call536870912, 536870912)
   443  CALLFN(·call1073741824, 1073741824)
   444  
   445  // void jmpdefer(fn, sp);
   446  // called from deferreturn.
   447  // 1. grab stored LR for caller
   448  // 2. sub 4 bytes to get back to BL deferreturn
   449  // 3. B to fn
   450  // TODO(rsc): Push things on stack and then use pop
   451  // to load all registers simultaneously, so that a profiling
   452  // interrupt can never see mismatched SP/LR/PC.
   453  // (And double-check that pop is atomic in that way.)
   454  TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
   455  	MOVW	0(SP), LR
   456  	MOVW	$-4(LR), LR	// BL deferreturn
   457  	MOVW	fv+0(FP), R7
   458  	MOVW	argp+4(FP), SP
   459  	MOVW	$-4(SP), SP	// SP is 4 below argp, due to saved LR
   460  	MOVW	0(R7), R1
   461  	B	(R1)
   462  
   463  // Save state of caller into g->sched. Smashes R11.
   464  TEXT gosave<>(SB),NOSPLIT,$0
   465  	MOVW	LR, (g_sched+gobuf_pc)(g)
   466  	MOVW	R13, (g_sched+gobuf_sp)(g)
   467  	MOVW	$0, R11
   468  	MOVW	R11, (g_sched+gobuf_lr)(g)
   469  	MOVW	R11, (g_sched+gobuf_ret)(g)
   470  	MOVW	R11, (g_sched+gobuf_ctxt)(g)
   471  	RET
   472  
   473  // asmcgocall(void(*fn)(void*), void *arg)
   474  // Call fn(arg) on the scheduler stack,
   475  // aligned appropriately for the gcc ABI.
   476  // See cgocall.c for more details.
   477  TEXT	·asmcgocall(SB),NOSPLIT,$0-8
   478  	MOVW	fn+0(FP), R1
   479  	MOVW	arg+4(FP), R0
   480  	BL	asmcgocall<>(SB)
   481  	RET
   482  
   483  TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12
   484  	MOVW	fn+0(FP), R1
   485  	MOVW	arg+4(FP), R0
   486  	BL	asmcgocall<>(SB)
   487  	MOVW	R0, ret+8(FP)
   488  	RET
   489  
   490  TEXT asmcgocall<>(SB),NOSPLIT,$0-0
   491  	// fn in R1, arg in R0.
   492  	MOVW	R13, R2
   493  	MOVW	g, R4
   494  
   495  	// Figure out if we need to switch to m->g0 stack.
   496  	// We get called to create new OS threads too, and those
   497  	// come in on the m->g0 stack already.
   498  	MOVW	g_m(g), R8
   499  	MOVW	m_g0(R8), R3
   500  	CMP	R3, g
   501  	BEQ	g0
   502  	BL	gosave<>(SB)
   503  	MOVW	R0, R5
   504  	MOVW	R3, R0
   505  	BL	setg<>(SB)
   506  	MOVW	R5, R0
   507  	MOVW	(g_sched+gobuf_sp)(g), R13
   508  
   509  	// Now on a scheduling stack (a pthread-created stack).
   510  g0:
   511  	SUB	$24, R13
   512  	BIC	$0x7, R13	// alignment for gcc ABI
   513  	MOVW	R4, 20(R13) // save old g
   514  	MOVW	(g_stack+stack_hi)(R4), R4
   515  	SUB	R2, R4
   516  	MOVW	R4, 16(R13)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
   517  	BL	(R1)
   518  
   519  	// Restore registers, g, stack pointer.
   520  	MOVW	R0, R5
   521  	MOVW	20(R13), R0
   522  	BL	setg<>(SB)
   523  	MOVW	(g_stack+stack_hi)(g), R1
   524  	MOVW	16(R13), R2
   525  	SUB	R2, R1
   526  	MOVW	R5, R0
   527  	MOVW	R1, R13
   528  	RET
   529  
   530  // cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
   531  // Turn the fn into a Go func (by taking its address) and call
   532  // cgocallback_gofunc.
   533  TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
   534  	MOVW	$fn+0(FP), R0
   535  	MOVW	R0, 4(R13)
   536  	MOVW	frame+4(FP), R0
   537  	MOVW	R0, 8(R13)
   538  	MOVW	framesize+8(FP), R0
   539  	MOVW	R0, 12(R13)
   540  	MOVW	$runtime·cgocallback_gofunc(SB), R0
   541  	BL	(R0)
   542  	RET
   543  
   544  // cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize)
   545  // See cgocall.c for more details.
   546  TEXT	·cgocallback_gofunc(SB),NOSPLIT,$8-12
   547  	NO_LOCAL_POINTERS
   548  	
   549  	// Load m and g from thread-local storage.
   550  	MOVB	runtime·iscgo(SB), R0
   551  	CMP	$0, R0
   552  	BL.NE	runtime·load_g(SB)
   553  
   554  	// If g is nil, Go did not create the current thread.
   555  	// Call needm to obtain one for temporary use.
   556  	// In this case, we're running on the thread stack, so there's
   557  	// lots of space, but the linker doesn't know. Hide the call from
   558  	// the linker analysis by using an indirect call.
   559  	CMP	$0, g
   560  	B.NE	havem
   561  	MOVW	g, savedm-4(SP) // g is zero, so is m.
   562  	MOVW	$runtime·needm(SB), R0
   563  	BL	(R0)
   564  
   565  	// Set m->sched.sp = SP, so that if a panic happens
   566  	// during the function we are about to execute, it will
   567  	// have a valid SP to run on the g0 stack.
   568  	// The next few lines (after the havem label)
   569  	// will save this SP onto the stack and then write
   570  	// the same SP back to m->sched.sp. That seems redundant,
   571  	// but if an unrecovered panic happens, unwindm will
   572  	// restore the g->sched.sp from the stack location
   573  	// and then systemstack will try to use it. If we don't set it here,
   574  	// that restored SP will be uninitialized (typically 0) and
   575  	// will not be usable.
   576  	MOVW	g_m(g), R8
   577  	MOVW	m_g0(R8), R3
   578  	MOVW	R13, (g_sched+gobuf_sp)(R3)
   579  
   580  havem:
   581  	MOVW	g_m(g), R8
   582  	MOVW	R8, savedm-4(SP)
   583  	// Now there's a valid m, and we're running on its m->g0.
   584  	// Save current m->g0->sched.sp on stack and then set it to SP.
   585  	// Save current sp in m->g0->sched.sp in preparation for
   586  	// switch back to m->curg stack.
   587  	// NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP).
   588  	MOVW	m_g0(R8), R3
   589  	MOVW	(g_sched+gobuf_sp)(R3), R4
   590  	MOVW	R4, savedsp-8(SP)
   591  	MOVW	R13, (g_sched+gobuf_sp)(R3)
   592  
   593  	// Switch to m->curg stack and call runtime.cgocallbackg.
   594  	// Because we are taking over the execution of m->curg
   595  	// but *not* resuming what had been running, we need to
   596  	// save that information (m->curg->sched) so we can restore it.
   597  	// We can restore m->curg->sched.sp easily, because calling
   598  	// runtime.cgocallbackg leaves SP unchanged upon return.
   599  	// To save m->curg->sched.pc, we push it onto the stack.
   600  	// This has the added benefit that it looks to the traceback
   601  	// routine like cgocallbackg is going to return to that
   602  	// PC (because the frame we allocate below has the same
   603  	// size as cgocallback_gofunc's frame declared above)
   604  	// so that the traceback will seamlessly trace back into
   605  	// the earlier calls.
   606  	//
   607  	// In the new goroutine, -8(SP) and -4(SP) are unused.
   608  	MOVW	m_curg(R8), R0
   609  	BL	setg<>(SB)
   610  	MOVW	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
   611  	MOVW	(g_sched+gobuf_pc)(g), R5
   612  	MOVW	R5, -12(R4)
   613  	MOVW	$-12(R4), R13
   614  	BL	runtime·cgocallbackg(SB)
   615  
   616  	// Restore g->sched (== m->curg->sched) from saved values.
   617  	MOVW	0(R13), R5
   618  	MOVW	R5, (g_sched+gobuf_pc)(g)
   619  	MOVW	$12(R13), R4
   620  	MOVW	R4, (g_sched+gobuf_sp)(g)
   621  
   622  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   623  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   624  	// so we do not have to restore it.)
   625  	MOVW	g_m(g), R8
   626  	MOVW	m_g0(R8), R0
   627  	BL	setg<>(SB)
   628  	MOVW	(g_sched+gobuf_sp)(g), R13
   629  	MOVW	savedsp-8(SP), R4
   630  	MOVW	R4, (g_sched+gobuf_sp)(g)
   631  
   632  	// If the m on entry was nil, we called needm above to borrow an m
   633  	// for the duration of the call. Since the call is over, return it with dropm.
   634  	MOVW	savedm-4(SP), R6
   635  	CMP	$0, R6
   636  	B.NE	3(PC)
   637  	MOVW	$runtime·dropm(SB), R0
   638  	BL	(R0)
   639  
   640  	// Done!
   641  	RET
   642  
   643  // void setg(G*); set g. for use by needm.
   644  TEXT runtime·setg(SB),NOSPLIT,$-4-4
   645  	MOVW	gg+0(FP), R0
   646  	B	setg<>(SB)
   647  
   648  TEXT setg<>(SB),NOSPLIT,$-4-0
   649  	MOVW	R0, g
   650  
   651  	// Save g to thread-local storage.
   652  	MOVB	runtime·iscgo(SB), R0
   653  	CMP	$0, R0
   654  	B.EQ	2(PC)
   655  	B	runtime·save_g(SB)
   656  
   657  	MOVW	g, R0
   658  	RET
   659  
   660  TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
   661  	MOVW	0(SP), R0
   662  	MOVW	R0, ret+4(FP)
   663  	RET
   664  
   665  TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-4-8
   666  	MOVW	R14, ret+4(FP)
   667  	RET
   668  
   669  TEXT runtime·setcallerpc(SB),NOSPLIT,$-4-8
   670  	MOVW	pc+4(FP), R0
   671  	MOVW	R0, 0(SP)
   672  	RET
   673  
   674  TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
   675  	MOVW	0(FP), R0
   676  	MOVW	$-4(R0), R0
   677  	MOVW	R0, ret+4(FP)
   678  	RET
   679  
   680  // func gogetcallersp(p unsafe.Pointer) uintptr
   681  TEXT runtime·gogetcallersp(SB),NOSPLIT,$-4-8
   682  	MOVW	0(FP), R0
   683  	MOVW	$-4(R0), R0
   684  	MOVW	R0, ret+4(FP)
   685  	RET
   686  
   687  TEXT runtime·emptyfunc(SB),0,$0-0
   688  	RET
   689  
   690  TEXT runtime·abort(SB),NOSPLIT,$-4-0
   691  	MOVW	$0, R0
   692  	MOVW	(R0), R1
   693  
   694  // bool armcas(int32 *val, int32 old, int32 new)
   695  // Atomically:
   696  //	if(*val == old){
   697  //		*val = new;
   698  //		return 1;
   699  //	}else
   700  //		return 0;
   701  //
   702  // To implement runtime·cas in sys_$GOOS_arm.s
   703  // using the native instructions, use:
   704  //
   705  //	TEXT runtime·cas(SB),NOSPLIT,$0
   706  //		B	runtime·armcas(SB)
   707  //
   708  TEXT runtime·armcas(SB),NOSPLIT,$0-13
   709  	MOVW	valptr+0(FP), R1
   710  	MOVW	old+4(FP), R2
   711  	MOVW	new+8(FP), R3
   712  casl:
   713  	LDREX	(R1), R0
   714  	CMP	R0, R2
   715  	BNE	casfail
   716  	STREX	R3, (R1), R0
   717  	CMP	$0, R0
   718  	BNE	casl
   719  	MOVW	$1, R0
   720  	MOVB	R0, ret+12(FP)
   721  	RET
   722  casfail:
   723  	MOVW	$0, R0
   724  	MOVB	R0, ret+12(FP)
   725  	RET
   726  
   727  TEXT runtime·casuintptr(SB),NOSPLIT,$0-13
   728  	B	runtime·cas(SB)
   729  
   730  TEXT runtime·atomicloaduintptr(SB),NOSPLIT,$0-8
   731  	B	runtime·atomicload(SB)
   732  
   733  TEXT runtime·atomicloaduint(SB),NOSPLIT,$0-8
   734  	B	runtime·atomicload(SB)
   735  
   736  TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
   737  	B	runtime·atomicstore(SB)
   738  
   739  // AES hashing not implemented for ARM
   740  TEXT runtime·aeshash(SB),NOSPLIT,$-4-0
   741  	MOVW	$0, R0
   742  	MOVW	(R0), R1
   743  TEXT runtime·aeshash32(SB),NOSPLIT,$-4-0
   744  	MOVW	$0, R0
   745  	MOVW	(R0), R1
   746  TEXT runtime·aeshash64(SB),NOSPLIT,$-4-0
   747  	MOVW	$0, R0
   748  	MOVW	(R0), R1
   749  TEXT runtime·aeshashstr(SB),NOSPLIT,$-4-0
   750  	MOVW	$0, R0
   751  	MOVW	(R0), R1
   752  
   753  // memhash_varlen(p unsafe.Pointer, h seed) uintptr
   754  // redirects to memhash(p, h, size) using the size
   755  // stored in the closure.
   756  TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
   757  	GO_ARGS
   758  	NO_LOCAL_POINTERS
   759  	MOVW	p+0(FP), R0
   760  	MOVW	h+4(FP), R1
   761  	MOVW	4(R7), R2
   762  	MOVW	R0, 4(R13)
   763  	MOVW	R1, 8(R13)
   764  	MOVW	R2, 12(R13)
   765  	BL	runtime·memhash(SB)
   766  	MOVW	16(R13), R0
   767  	MOVW	R0, ret+8(FP)
   768  	RET
   769  
   770  TEXT runtime·memeq(SB),NOSPLIT,$-4-13
   771  	MOVW	a+0(FP), R1
   772  	MOVW	b+4(FP), R2
   773  	MOVW	size+8(FP), R3
   774  	ADD	R1, R3, R6
   775  	MOVW	$1, R0
   776  	MOVB	R0, ret+12(FP)
   777  loop:
   778  	CMP	R1, R6
   779  	RET.EQ
   780  	MOVBU.P	1(R1), R4
   781  	MOVBU.P	1(R2), R5
   782  	CMP	R4, R5
   783  	BEQ	loop
   784  
   785  	MOVW	$0, R0
   786  	MOVB	R0, ret+12(FP)
   787  	RET
   788  
   789  // memequal_varlen(a, b unsafe.Pointer) bool
   790  TEXT runtime·memequal_varlen(SB),NOSPLIT,$16-9
   791  	MOVW	a+0(FP), R0
   792  	MOVW	b+4(FP), R1
   793  	CMP	R0, R1
   794  	BEQ	eq
   795  	MOVW	4(R7), R2    // compiler stores size at offset 4 in the closure
   796  	MOVW	R0, 4(R13)
   797  	MOVW	R1, 8(R13)
   798  	MOVW	R2, 12(R13)
   799  	BL	runtime·memeq(SB)
   800  	MOVB	16(R13), R0
   801  	MOVB	R0, ret+8(FP)
   802  	RET
   803  eq:
   804  	MOVW	$1, R0
   805  	MOVB	R0, ret+8(FP)
   806  	RET
   807  
   808  // eqstring tests whether two strings are equal.
   809  // See runtime_test.go:eqstring_generic for
   810  // equivalent Go code.
   811  TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
   812  	MOVW	s1len+4(FP), R0
   813  	MOVW	s2len+12(FP), R1
   814  	MOVW	$0, R7
   815  	CMP	R0, R1
   816  	MOVB.NE R7, v+16(FP)
   817  	RET.NE
   818  	MOVW	s1str+0(FP), R2
   819  	MOVW	s2str+8(FP), R3
   820  	MOVW	$1, R8
   821  	MOVB	R8, v+16(FP)
   822  	CMP	R2, R3
   823  	RET.EQ
   824  	ADD	R2, R0, R6
   825  loop:
   826  	CMP	R2, R6
   827  	RET.EQ
   828  	MOVBU.P	1(R2), R4
   829  	MOVBU.P	1(R3), R5
   830  	CMP	R4, R5
   831  	BEQ	loop
   832  	MOVB	R7, v+16(FP)
   833  	RET
   834  
   835  // void setg_gcc(G*); set g called from gcc.
   836  TEXT setg_gcc<>(SB),NOSPLIT,$0
   837  	MOVW	R0, g
   838  	B		runtime·save_g(SB)
   839  
   840  // TODO: share code with memeq?
   841  TEXT bytes·Equal(SB),NOSPLIT,$0
   842  	MOVW	a_len+4(FP), R1
   843  	MOVW	b_len+16(FP), R3
   844  	
   845  	CMP	R1, R3		// unequal lengths are not equal
   846  	B.NE	notequal
   847  
   848  	MOVW	a+0(FP), R0
   849  	MOVW	b+12(FP), R2
   850  	ADD	R0, R1		// end
   851  
   852  loop:
   853  	CMP	R0, R1
   854  	B.EQ	equal		// reached the end
   855  	MOVBU.P	1(R0), R4
   856  	MOVBU.P	1(R2), R5
   857  	CMP	R4, R5
   858  	B.EQ	loop
   859  
   860  notequal:
   861  	MOVW	$0, R0
   862  	MOVBU	R0, ret+24(FP)
   863  	RET
   864  
   865  equal:
   866  	MOVW	$1, R0
   867  	MOVBU	R0, ret+24(FP)
   868  	RET
   869  
   870  TEXT bytes·IndexByte(SB),NOSPLIT,$0
   871  	MOVW	s+0(FP), R0
   872  	MOVW	s_len+4(FP), R1
   873  	MOVBU	c+12(FP), R2	// byte to find
   874  	MOVW	R0, R4		// store base for later
   875  	ADD	R0, R1		// end 
   876  
   877  _loop:
   878  	CMP	R0, R1
   879  	B.EQ	_notfound
   880  	MOVBU.P	1(R0), R3
   881  	CMP	R2, R3
   882  	B.NE	_loop
   883  
   884  	SUB	$1, R0		// R0 will be one beyond the position we want
   885  	SUB	R4, R0		// remove base
   886  	MOVW    R0, ret+16(FP) 
   887  	RET
   888  
   889  _notfound:
   890  	MOVW	$-1, R0
   891  	MOVW	R0, ret+16(FP)
   892  	RET
   893  
   894  TEXT strings·IndexByte(SB),NOSPLIT,$0
   895  	MOVW	s+0(FP), R0
   896  	MOVW	s_len+4(FP), R1
   897  	MOVBU	c+8(FP), R2	// byte to find
   898  	MOVW	R0, R4		// store base for later
   899  	ADD	R0, R1		// end 
   900  
   901  _sib_loop:
   902  	CMP	R0, R1
   903  	B.EQ	_sib_notfound
   904  	MOVBU.P	1(R0), R3
   905  	CMP	R2, R3
   906  	B.NE	_sib_loop
   907  
   908  	SUB	$1, R0		// R0 will be one beyond the position we want
   909  	SUB	R4, R0		// remove base
   910  	MOVW	R0, ret+12(FP) 
   911  	RET
   912  
   913  _sib_notfound:
   914  	MOVW	$-1, R0
   915  	MOVW	R0, ret+12(FP)
   916  	RET
   917  
   918  // A Duff's device for zeroing memory.
   919  // The compiler jumps to computed addresses within
   920  // this routine to zero chunks of memory.  Do not
   921  // change this code without also changing the code
   922  // in ../../cmd/5g/ggen.c:clearfat.
   923  // R0: zero
   924  // R1: ptr to memory to be zeroed
   925  // R1 is updated as a side effect.
   926  TEXT runtime·duffzero(SB),NOSPLIT,$0-0
   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  	MOVW.P	R0, 4(R1)
  1014  	MOVW.P	R0, 4(R1)
  1015  	MOVW.P	R0, 4(R1)
  1016  	MOVW.P	R0, 4(R1)
  1017  	MOVW.P	R0, 4(R1)
  1018  	MOVW.P	R0, 4(R1)
  1019  	MOVW.P	R0, 4(R1)
  1020  	MOVW.P	R0, 4(R1)
  1021  	MOVW.P	R0, 4(R1)
  1022  	MOVW.P	R0, 4(R1)
  1023  	MOVW.P	R0, 4(R1)
  1024  	MOVW.P	R0, 4(R1)
  1025  	MOVW.P	R0, 4(R1)
  1026  	MOVW.P	R0, 4(R1)
  1027  	MOVW.P	R0, 4(R1)
  1028  	MOVW.P	R0, 4(R1)
  1029  	MOVW.P	R0, 4(R1)
  1030  	MOVW.P	R0, 4(R1)
  1031  	MOVW.P	R0, 4(R1)
  1032  	MOVW.P	R0, 4(R1)
  1033  	MOVW.P	R0, 4(R1)
  1034  	MOVW.P	R0, 4(R1)
  1035  	MOVW.P	R0, 4(R1)
  1036  	MOVW.P	R0, 4(R1)
  1037  	MOVW.P	R0, 4(R1)
  1038  	MOVW.P	R0, 4(R1)
  1039  	MOVW.P	R0, 4(R1)
  1040  	MOVW.P	R0, 4(R1)
  1041  	MOVW.P	R0, 4(R1)
  1042  	MOVW.P	R0, 4(R1)
  1043  	MOVW.P	R0, 4(R1)
  1044  	MOVW.P	R0, 4(R1)
  1045  	MOVW.P	R0, 4(R1)
  1046  	MOVW.P	R0, 4(R1)
  1047  	MOVW.P	R0, 4(R1)
  1048  	MOVW.P	R0, 4(R1)
  1049  	MOVW.P	R0, 4(R1)
  1050  	MOVW.P	R0, 4(R1)
  1051  	MOVW.P	R0, 4(R1)
  1052  	MOVW.P	R0, 4(R1)
  1053  	MOVW.P	R0, 4(R1)
  1054  	MOVW.P	R0, 4(R1)
  1055  	RET
  1056  
  1057  // A Duff's device for copying memory.
  1058  // The compiler jumps to computed addresses within
  1059  // this routine to copy chunks of memory.  Source
  1060  // and destination must not overlap.  Do not
  1061  // change this code without also changing the code
  1062  // in ../../cmd/5g/cgen.c:sgen.
  1063  // R0: scratch space
  1064  // R1: ptr to source memory
  1065  // R2: ptr to destination memory
  1066  // R1 and R2 are updated as a side effect
  1067  TEXT runtime·duffcopy(SB),NOSPLIT,$0-0
  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  	MOVW.P	4(R1), R0
  1283  	MOVW.P	R0, 4(R2)
  1284  	MOVW.P	4(R1), R0
  1285  	MOVW.P	R0, 4(R2)
  1286  	MOVW.P	4(R1), R0
  1287  	MOVW.P	R0, 4(R2)
  1288  	MOVW.P	4(R1), R0
  1289  	MOVW.P	R0, 4(R2)
  1290  	MOVW.P	4(R1), R0
  1291  	MOVW.P	R0, 4(R2)
  1292  	MOVW.P	4(R1), R0
  1293  	MOVW.P	R0, 4(R2)
  1294  	MOVW.P	4(R1), R0
  1295  	MOVW.P	R0, 4(R2)
  1296  	MOVW.P	4(R1), R0
  1297  	MOVW.P	R0, 4(R2)
  1298  	MOVW.P	4(R1), R0
  1299  	MOVW.P	R0, 4(R2)
  1300  	MOVW.P	4(R1), R0
  1301  	MOVW.P	R0, 4(R2)
  1302  	MOVW.P	4(R1), R0
  1303  	MOVW.P	R0, 4(R2)
  1304  	MOVW.P	4(R1), R0
  1305  	MOVW.P	R0, 4(R2)
  1306  	MOVW.P	4(R1), R0
  1307  	MOVW.P	R0, 4(R2)
  1308  	MOVW.P	4(R1), R0
  1309  	MOVW.P	R0, 4(R2)
  1310  	MOVW.P	4(R1), R0
  1311  	MOVW.P	R0, 4(R2)
  1312  	MOVW.P	4(R1), R0
  1313  	MOVW.P	R0, 4(R2)
  1314  	MOVW.P	4(R1), R0
  1315  	MOVW.P	R0, 4(R2)
  1316  	MOVW.P	4(R1), R0
  1317  	MOVW.P	R0, 4(R2)
  1318  	MOVW.P	4(R1), R0
  1319  	MOVW.P	R0, 4(R2)
  1320  	MOVW.P	4(R1), R0
  1321  	MOVW.P	R0, 4(R2)
  1322  	MOVW.P	4(R1), R0
  1323  	MOVW.P	R0, 4(R2)
  1324  	RET
  1325  
  1326  TEXT runtime·fastrand1(SB),NOSPLIT,$-4-4
  1327  	MOVW	g_m(g), R1
  1328  	MOVW	m_fastrand(R1), R0
  1329  	ADD.S	R0, R0
  1330  	EOR.MI	$0x88888eef, R0
  1331  	MOVW	R0, m_fastrand(R1)
  1332  	MOVW	R0, ret+0(FP)
  1333  	RET
  1334  
  1335  TEXT runtime·return0(SB),NOSPLIT,$0
  1336  	MOVW	$0, R0
  1337  	RET
  1338  
  1339  TEXT runtime·procyield(SB),NOSPLIT,$-4
  1340  	MOVW	cycles+0(FP), R1
  1341  	MOVW	$0, R0
  1342  yieldloop:
  1343  	CMP	R0, R1
  1344  	B.NE	2(PC)
  1345  	RET
  1346  	SUB	$1, R1
  1347  	B yieldloop
  1348  
  1349  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
  1350  // Must obey the gcc calling convention.
  1351  TEXT _cgo_topofstack(SB),NOSPLIT,$8
  1352  	// R11 and g register are clobbered by load_g.  They are
  1353  	// callee-save in the gcc calling convention, so save them here.
  1354  	MOVW	R11, saveR11-4(SP)
  1355  	MOVW	g, saveG-8(SP)
  1356  	
  1357  	BL	runtime·load_g(SB)
  1358  	MOVW	g_m(g), R0
  1359  	MOVW	m_curg(R0), R0
  1360  	MOVW	(g_stack+stack_hi)(R0), R0
  1361  	
  1362  	MOVW	saveG-8(SP), g
  1363  	MOVW	saveR11-4(SP), R11
  1364  	RET
  1365  
  1366  // The top-most function running on a goroutine
  1367  // returns to goexit+PCQuantum.
  1368  TEXT runtime·goexit(SB),NOSPLIT,$-4-0
  1369  	MOVW	R0, R0	// NOP
  1370  	BL	runtime·goexit1(SB)	// does not return
  1371  
  1372  TEXT runtime·getg(SB),NOSPLIT,$-4-4
  1373  	MOVW	g, ret+0(FP)
  1374  	RET
  1375  
  1376  TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
  1377  	RET
  1378  
  1379  TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
  1380  	RET
  1381  
  1382  TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
  1383  	RET
  1384  
  1385  TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
  1386  	RET