github.com/lzhfromustc/gofuzz@v0.0.0-20211116160056-151b3108bbd1/runtime/asm_arm64.s (about)

     1  // Copyright 2015 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 "tls_arm64.h"
     8  #include "funcdata.h"
     9  #include "textflag.h"
    10  
    11  TEXT runtime·rt0_go(SB),NOSPLIT,$0
    12  	// SP = stack; R0 = argc; R1 = argv
    13  
    14  	SUB	$32, RSP
    15  	MOVW	R0, 8(RSP) // argc
    16  	MOVD	R1, 16(RSP) // argv
    17  
    18  #ifdef TLS_darwin
    19  	// Initialize TLS.
    20  	MOVD	ZR, g // clear g, make sure it's not junk.
    21  	SUB	$32, RSP
    22  	MRS_TPIDR_R0
    23  	AND	$~7, R0
    24  	MOVD	R0, 16(RSP)             // arg2: TLS base
    25  	MOVD	$runtime·tls_g(SB), R2
    26  	MOVD	R2, 8(RSP)              // arg1: &tlsg
    27  	BL	·tlsinit(SB)
    28  	ADD	$32, RSP
    29  #endif
    30  
    31  	// create istack out of the given (operating system) stack.
    32  	// _cgo_init may update stackguard.
    33  	MOVD	$runtime·g0(SB), g
    34  	MOVD	RSP, R7
    35  	MOVD	$(-64*1024)(R7), R0
    36  	MOVD	R0, g_stackguard0(g)
    37  	MOVD	R0, g_stackguard1(g)
    38  	MOVD	R0, (g_stack+stack_lo)(g)
    39  	MOVD	R7, (g_stack+stack_hi)(g)
    40  
    41  	// if there is a _cgo_init, call it using the gcc ABI.
    42  	MOVD	_cgo_init(SB), R12
    43  	CBZ	R12, nocgo
    44  
    45  #ifdef GOOS_android
    46  	MRS_TPIDR_R0			// load TLS base pointer
    47  	MOVD	R0, R3			// arg 3: TLS base pointer
    48  	MOVD	$runtime·tls_g(SB), R2 	// arg 2: &tls_g
    49  #else
    50  	MOVD	$0, R2		        // arg 2: not used when using platform's TLS
    51  #endif
    52  	MOVD	$setg_gcc<>(SB), R1	// arg 1: setg
    53  	MOVD	g, R0			// arg 0: G
    54  	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
    55  	BL	(R12)
    56  	ADD	$16, RSP
    57  
    58  nocgo:
    59  	BL	runtime·save_g(SB)
    60  	// update stackguard after _cgo_init
    61  	MOVD	(g_stack+stack_lo)(g), R0
    62  	ADD	$const__StackGuard, R0
    63  	MOVD	R0, g_stackguard0(g)
    64  	MOVD	R0, g_stackguard1(g)
    65  
    66  	// set the per-goroutine and per-mach "registers"
    67  	MOVD	$runtime·m0(SB), R0
    68  
    69  	// save m->g0 = g0
    70  	MOVD	g, m_g0(R0)
    71  	// save m0 to g0->m
    72  	MOVD	R0, g_m(g)
    73  
    74  	BL	runtime·check(SB)
    75  
    76  	MOVW	8(RSP), R0	// copy argc
    77  	MOVW	R0, -8(RSP)
    78  	MOVD	16(RSP), R0		// copy argv
    79  	MOVD	R0, 0(RSP)
    80  	BL	runtime·args(SB)
    81  	BL	runtime·osinit(SB)
    82  	BL	runtime·schedinit(SB)
    83  
    84  	// create a new goroutine to start program
    85  	MOVD	$runtime·mainPC(SB), R0		// entry
    86  	MOVD	RSP, R7
    87  	MOVD.W	$0, -8(R7)
    88  	MOVD.W	R0, -8(R7)
    89  	MOVD.W	$0, -8(R7)
    90  	MOVD.W	$0, -8(R7)
    91  	MOVD	R7, RSP
    92  	BL	runtime·newproc(SB)
    93  	ADD	$32, RSP
    94  
    95  	// start this M
    96  	BL	runtime·mstart(SB)
    97  
    98  	MOVD	$0, R0
    99  	MOVD	R0, (R0)	// boom
   100  	UNDEF
   101  
   102  DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
   103  GLOBL	runtime·mainPC(SB),RODATA,$8
   104  
   105  TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
   106  	BRK
   107  	RET
   108  
   109  TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
   110  	RET
   111  
   112  /*
   113   *  go-routine
   114   */
   115  
   116  // void gosave(Gobuf*)
   117  // save state in Gobuf; setjmp
   118  TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
   119  	MOVD	buf+0(FP), R3
   120  	MOVD	RSP, R0
   121  	MOVD	R0, gobuf_sp(R3)
   122  	MOVD	R29, gobuf_bp(R3)
   123  	MOVD	LR, gobuf_pc(R3)
   124  	MOVD	g, gobuf_g(R3)
   125  	MOVD	ZR, gobuf_lr(R3)
   126  	MOVD	ZR, gobuf_ret(R3)
   127  	// Assert ctxt is zero. See func save.
   128  	MOVD	gobuf_ctxt(R3), R0
   129  	CBZ	R0, 2(PC)
   130  	CALL	runtime·badctxt(SB)
   131  	RET
   132  
   133  // void gogo(Gobuf*)
   134  // restore state from Gobuf; longjmp
   135  TEXT runtime·gogo(SB), NOSPLIT, $24-8
   136  	MOVD	buf+0(FP), R5
   137  	MOVD	gobuf_g(R5), g
   138  	BL	runtime·save_g(SB)
   139  
   140  	MOVD	0(g), R4	// make sure g is not nil
   141  	MOVD	gobuf_sp(R5), R0
   142  	MOVD	R0, RSP
   143  	MOVD	gobuf_bp(R5), R29
   144  	MOVD	gobuf_lr(R5), LR
   145  	MOVD	gobuf_ret(R5), R0
   146  	MOVD	gobuf_ctxt(R5), R26
   147  	MOVD	$0, gobuf_sp(R5)
   148  	MOVD	$0, gobuf_bp(R5)
   149  	MOVD	$0, gobuf_ret(R5)
   150  	MOVD	$0, gobuf_lr(R5)
   151  	MOVD	$0, gobuf_ctxt(R5)
   152  	CMP	ZR, ZR // set condition codes for == test, needed by stack split
   153  	MOVD	gobuf_pc(R5), R6
   154  	B	(R6)
   155  
   156  // void mcall(fn func(*g))
   157  // Switch to m->g0's stack, call fn(g).
   158  // Fn must never return. It should gogo(&g->sched)
   159  // to keep running g.
   160  TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8
   161  	// Save caller state in g->sched
   162  	MOVD	RSP, R0
   163  	MOVD	R0, (g_sched+gobuf_sp)(g)
   164  	MOVD	R29, (g_sched+gobuf_bp)(g)
   165  	MOVD	LR, (g_sched+gobuf_pc)(g)
   166  	MOVD	$0, (g_sched+gobuf_lr)(g)
   167  	MOVD	g, (g_sched+gobuf_g)(g)
   168  
   169  	// Switch to m->g0 & its stack, call fn.
   170  	MOVD	g, R3
   171  	MOVD	g_m(g), R8
   172  	MOVD	m_g0(R8), g
   173  	BL	runtime·save_g(SB)
   174  	CMP	g, R3
   175  	BNE	2(PC)
   176  	B	runtime·badmcall(SB)
   177  	MOVD	fn+0(FP), R26			// context
   178  	MOVD	0(R26), R4			// code pointer
   179  	MOVD	(g_sched+gobuf_sp)(g), R0
   180  	MOVD	R0, RSP	// sp = m->g0->sched.sp
   181  	MOVD	(g_sched+gobuf_bp)(g), R29
   182  	MOVD	R3, -8(RSP)
   183  	MOVD	$0, -16(RSP)
   184  	SUB	$16, RSP
   185  	BL	(R4)
   186  	B	runtime·badmcall2(SB)
   187  
   188  // systemstack_switch is a dummy routine that systemstack leaves at the bottom
   189  // of the G stack. We need to distinguish the routine that
   190  // lives at the bottom of the G stack from the one that lives
   191  // at the top of the system stack because the one at the top of
   192  // the system stack terminates the stack walk (see topofstack()).
   193  TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   194  	UNDEF
   195  	BL	(LR)	// make sure this function is not leaf
   196  	RET
   197  
   198  // func systemstack(fn func())
   199  TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   200  	MOVD	fn+0(FP), R3	// R3 = fn
   201  	MOVD	R3, R26		// context
   202  	MOVD	g_m(g), R4	// R4 = m
   203  
   204  	MOVD	m_gsignal(R4), R5	// R5 = gsignal
   205  	CMP	g, R5
   206  	BEQ	noswitch
   207  
   208  	MOVD	m_g0(R4), R5	// R5 = g0
   209  	CMP	g, R5
   210  	BEQ	noswitch
   211  
   212  	MOVD	m_curg(R4), R6
   213  	CMP	g, R6
   214  	BEQ	switch
   215  
   216  	// Bad: g is not gsignal, not g0, not curg. What is it?
   217  	// Hide call from linker nosplit analysis.
   218  	MOVD	$runtime·badsystemstack(SB), R3
   219  	BL	(R3)
   220  	B	runtime·abort(SB)
   221  
   222  switch:
   223  	// save our state in g->sched. Pretend to
   224  	// be systemstack_switch if the G stack is scanned.
   225  	MOVD	$runtime·systemstack_switch(SB), R6
   226  	ADD	$8, R6	// get past prologue
   227  	MOVD	R6, (g_sched+gobuf_pc)(g)
   228  	MOVD	RSP, R0
   229  	MOVD	R0, (g_sched+gobuf_sp)(g)
   230  	MOVD	R29, (g_sched+gobuf_bp)(g)
   231  	MOVD	$0, (g_sched+gobuf_lr)(g)
   232  	MOVD	g, (g_sched+gobuf_g)(g)
   233  
   234  	// switch to g0
   235  	MOVD	R5, g
   236  	BL	runtime·save_g(SB)
   237  	MOVD	(g_sched+gobuf_sp)(g), R3
   238  	// make it look like mstart called systemstack on g0, to stop traceback
   239  	SUB	$16, R3
   240  	AND	$~15, R3
   241  	MOVD	$runtime·mstart(SB), R4
   242  	MOVD	R4, 0(R3)
   243  	MOVD	R3, RSP
   244  	MOVD	(g_sched+gobuf_bp)(g), R29
   245  
   246  	// call target function
   247  	MOVD	0(R26), R3	// code pointer
   248  	BL	(R3)
   249  
   250  	// switch back to g
   251  	MOVD	g_m(g), R3
   252  	MOVD	m_curg(R3), g
   253  	BL	runtime·save_g(SB)
   254  	MOVD	(g_sched+gobuf_sp)(g), R0
   255  	MOVD	R0, RSP
   256  	MOVD	(g_sched+gobuf_bp)(g), R29
   257  	MOVD	$0, (g_sched+gobuf_sp)(g)
   258  	MOVD	$0, (g_sched+gobuf_bp)(g)
   259  	RET
   260  
   261  noswitch:
   262  	// already on m stack, just call directly
   263  	// Using a tail call here cleans up tracebacks since we won't stop
   264  	// at an intermediate systemstack.
   265  	MOVD	0(R26), R3	// code pointer
   266  	MOVD.P	16(RSP), R30	// restore LR
   267  	SUB	$8, RSP, R29	// restore FP
   268  	B	(R3)
   269  
   270  /*
   271   * support for morestack
   272   */
   273  
   274  // Called during function prolog when more stack is needed.
   275  // Caller has already loaded:
   276  // R3 prolog's LR (R30)
   277  //
   278  // The traceback routines see morestack on a g0 as being
   279  // the top of a stack (for example, morestack calling newstack
   280  // calling the scheduler calling newm calling gc), so we must
   281  // record an argument size. For that purpose, it has no arguments.
   282  TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   283  	// Cannot grow scheduler stack (m->g0).
   284  	MOVD	g_m(g), R8
   285  	MOVD	m_g0(R8), R4
   286  	CMP	g, R4
   287  	BNE	3(PC)
   288  	BL	runtime·badmorestackg0(SB)
   289  	B	runtime·abort(SB)
   290  
   291  	// Cannot grow signal stack (m->gsignal).
   292  	MOVD	m_gsignal(R8), R4
   293  	CMP	g, R4
   294  	BNE	3(PC)
   295  	BL	runtime·badmorestackgsignal(SB)
   296  	B	runtime·abort(SB)
   297  
   298  	// Called from f.
   299  	// Set g->sched to context in f
   300  	MOVD	RSP, R0
   301  	MOVD	R0, (g_sched+gobuf_sp)(g)
   302  	MOVD	R29, (g_sched+gobuf_bp)(g)
   303  	MOVD	LR, (g_sched+gobuf_pc)(g)
   304  	MOVD	R3, (g_sched+gobuf_lr)(g)
   305  	MOVD	R26, (g_sched+gobuf_ctxt)(g)
   306  
   307  	// Called from f.
   308  	// Set m->morebuf to f's callers.
   309  	MOVD	R3, (m_morebuf+gobuf_pc)(R8)	// f's caller's PC
   310  	MOVD	RSP, R0
   311  	MOVD	R0, (m_morebuf+gobuf_sp)(R8)	// f's caller's RSP
   312  	MOVD	g, (m_morebuf+gobuf_g)(R8)
   313  
   314  	// Call newstack on m->g0's stack.
   315  	MOVD	m_g0(R8), g
   316  	BL	runtime·save_g(SB)
   317  	MOVD	(g_sched+gobuf_sp)(g), R0
   318  	MOVD	R0, RSP
   319  	MOVD	(g_sched+gobuf_bp)(g), R29
   320  	MOVD.W	$0, -16(RSP)	// create a call frame on g0 (saved LR; keep 16-aligned)
   321  	BL	runtime·newstack(SB)
   322  
   323  	// Not reached, but make sure the return PC from the call to newstack
   324  	// is still in this function, and not the beginning of the next.
   325  	UNDEF
   326  
   327  TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   328  	MOVW	$0, R26
   329  	B runtime·morestack(SB)
   330  
   331  // reflectcall: call a function with the given argument list
   332  // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
   333  // we don't have variable-sized frames, so we use a small number
   334  // of constant-sized-frame functions to encode a few bits of size in the pc.
   335  // Caution: ugly multiline assembly macros in your future!
   336  
   337  #define DISPATCH(NAME,MAXSIZE)		\
   338  	MOVD	$MAXSIZE, R27;		\
   339  	CMP	R27, R16;		\
   340  	BGT	3(PC);			\
   341  	MOVD	$NAME(SB), R27;	\
   342  	B	(R27)
   343  // Note: can't just "B NAME(SB)" - bad inlining results.
   344  
   345  TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
   346  	MOVWU argsize+24(FP), R16
   347  	DISPATCH(runtime·call16, 16)
   348  	DISPATCH(runtime·call32, 32)
   349  	DISPATCH(runtime·call64, 64)
   350  	DISPATCH(runtime·call128, 128)
   351  	DISPATCH(runtime·call256, 256)
   352  	DISPATCH(runtime·call512, 512)
   353  	DISPATCH(runtime·call1024, 1024)
   354  	DISPATCH(runtime·call2048, 2048)
   355  	DISPATCH(runtime·call4096, 4096)
   356  	DISPATCH(runtime·call8192, 8192)
   357  	DISPATCH(runtime·call16384, 16384)
   358  	DISPATCH(runtime·call32768, 32768)
   359  	DISPATCH(runtime·call65536, 65536)
   360  	DISPATCH(runtime·call131072, 131072)
   361  	DISPATCH(runtime·call262144, 262144)
   362  	DISPATCH(runtime·call524288, 524288)
   363  	DISPATCH(runtime·call1048576, 1048576)
   364  	DISPATCH(runtime·call2097152, 2097152)
   365  	DISPATCH(runtime·call4194304, 4194304)
   366  	DISPATCH(runtime·call8388608, 8388608)
   367  	DISPATCH(runtime·call16777216, 16777216)
   368  	DISPATCH(runtime·call33554432, 33554432)
   369  	DISPATCH(runtime·call67108864, 67108864)
   370  	DISPATCH(runtime·call134217728, 134217728)
   371  	DISPATCH(runtime·call268435456, 268435456)
   372  	DISPATCH(runtime·call536870912, 536870912)
   373  	DISPATCH(runtime·call1073741824, 1073741824)
   374  	MOVD	$runtime·badreflectcall(SB), R0
   375  	B	(R0)
   376  
   377  #define CALLFN(NAME,MAXSIZE)			\
   378  TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
   379  	NO_LOCAL_POINTERS;			\
   380  	/* copy arguments to stack */		\
   381  	MOVD	arg+16(FP), R3;			\
   382  	MOVWU	argsize+24(FP), R4;		\
   383  	ADD	$8, RSP, R5;			\
   384  	BIC	$0xf, R4, R6;			\
   385  	CBZ	R6, 6(PC);			\
   386  	/* if R6=(argsize&~15) != 0 */		\
   387  	ADD	R6, R5, R6;			\
   388  	/* copy 16 bytes a time */		\
   389  	LDP.P	16(R3), (R7, R8);		\
   390  	STP.P	(R7, R8), 16(R5);		\
   391  	CMP	R5, R6;				\
   392  	BNE	-3(PC);				\
   393  	AND	$0xf, R4, R6;			\
   394  	CBZ	R6, 6(PC);			\
   395  	/* if R6=(argsize&15) != 0 */		\
   396  	ADD	R6, R5, R6;			\
   397  	/* copy 1 byte a time for the rest */	\
   398  	MOVBU.P	1(R3), R7;			\
   399  	MOVBU.P	R7, 1(R5);			\
   400  	CMP	R5, R6;				\
   401  	BNE	-3(PC);				\
   402  	/* call function */			\
   403  	MOVD	f+8(FP), R26;			\
   404  	MOVD	(R26), R0;			\
   405  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   406  	BL	(R0);				\
   407  	/* copy return values back */		\
   408  	MOVD	argtype+0(FP), R7;		\
   409  	MOVD	arg+16(FP), R3;			\
   410  	MOVWU	n+24(FP), R4;			\
   411  	MOVWU	retoffset+28(FP), R6;		\
   412  	ADD	$8, RSP, R5;			\
   413  	ADD	R6, R5; 			\
   414  	ADD	R6, R3;				\
   415  	SUB	R6, R4;				\
   416  	BL	callRet<>(SB);			\
   417  	RET
   418  
   419  // callRet copies return values back at the end of call*. This is a
   420  // separate function so it can allocate stack space for the arguments
   421  // to reflectcallmove. It does not follow the Go ABI; it expects its
   422  // arguments in registers.
   423  TEXT callRet<>(SB), NOSPLIT, $40-0
   424  	MOVD	R7, 8(RSP)
   425  	MOVD	R3, 16(RSP)
   426  	MOVD	R5, 24(RSP)
   427  	MOVD	R4, 32(RSP)
   428  	BL	runtime·reflectcallmove(SB)
   429  	RET
   430  
   431  CALLFN(·call16, 16)
   432  CALLFN(·call32, 32)
   433  CALLFN(·call64, 64)
   434  CALLFN(·call128, 128)
   435  CALLFN(·call256, 256)
   436  CALLFN(·call512, 512)
   437  CALLFN(·call1024, 1024)
   438  CALLFN(·call2048, 2048)
   439  CALLFN(·call4096, 4096)
   440  CALLFN(·call8192, 8192)
   441  CALLFN(·call16384, 16384)
   442  CALLFN(·call32768, 32768)
   443  CALLFN(·call65536, 65536)
   444  CALLFN(·call131072, 131072)
   445  CALLFN(·call262144, 262144)
   446  CALLFN(·call524288, 524288)
   447  CALLFN(·call1048576, 1048576)
   448  CALLFN(·call2097152, 2097152)
   449  CALLFN(·call4194304, 4194304)
   450  CALLFN(·call8388608, 8388608)
   451  CALLFN(·call16777216, 16777216)
   452  CALLFN(·call33554432, 33554432)
   453  CALLFN(·call67108864, 67108864)
   454  CALLFN(·call134217728, 134217728)
   455  CALLFN(·call268435456, 268435456)
   456  CALLFN(·call536870912, 536870912)
   457  CALLFN(·call1073741824, 1073741824)
   458  
   459  // func memhash32(p unsafe.Pointer, h uintptr) uintptr
   460  TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
   461  	MOVB	runtime·useAeshash(SB), R0
   462  	CBZ	R0, noaes
   463  	MOVD	p+0(FP), R0
   464  	MOVD	h+8(FP), R1
   465  	MOVD	$ret+16(FP), R2
   466  	MOVD	$runtime·aeskeysched+0(SB), R3
   467  
   468  	VEOR	V0.B16, V0.B16, V0.B16
   469  	VLD1	(R3), [V2.B16]
   470  	VLD1	(R0), V0.S[1]
   471  	VMOV	R1, V0.S[0]
   472  
   473  	AESE	V2.B16, V0.B16
   474  	AESMC	V0.B16, V0.B16
   475  	AESE	V2.B16, V0.B16
   476  	AESMC	V0.B16, V0.B16
   477  	AESE	V2.B16, V0.B16
   478  
   479  	VST1	[V0.D1], (R2)
   480  	RET
   481  noaes:
   482  	B	runtime·memhash32Fallback(SB)
   483  
   484  // func memhash64(p unsafe.Pointer, h uintptr) uintptr
   485  TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
   486  	MOVB	runtime·useAeshash(SB), R0
   487  	CBZ	R0, noaes
   488  	MOVD	p+0(FP), R0
   489  	MOVD	h+8(FP), R1
   490  	MOVD	$ret+16(FP), R2
   491  	MOVD	$runtime·aeskeysched+0(SB), R3
   492  
   493  	VEOR	V0.B16, V0.B16, V0.B16
   494  	VLD1	(R3), [V2.B16]
   495  	VLD1	(R0), V0.D[1]
   496  	VMOV	R1, V0.D[0]
   497  
   498  	AESE	V2.B16, V0.B16
   499  	AESMC	V0.B16, V0.B16
   500  	AESE	V2.B16, V0.B16
   501  	AESMC	V0.B16, V0.B16
   502  	AESE	V2.B16, V0.B16
   503  
   504  	VST1	[V0.D1], (R2)
   505  	RET
   506  noaes:
   507  	B	runtime·memhash64Fallback(SB)
   508  
   509  // func memhash(p unsafe.Pointer, h, size uintptr) uintptr
   510  TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
   511  	MOVB	runtime·useAeshash(SB), R0
   512  	CBZ	R0, noaes
   513  	MOVD	p+0(FP), R0
   514  	MOVD	s+16(FP), R1
   515  	MOVD	h+8(FP), R3
   516  	MOVD	$ret+24(FP), R2
   517  	B	aeshashbody<>(SB)
   518  noaes:
   519  	B	runtime·memhashFallback(SB)
   520  
   521  // func strhash(p unsafe.Pointer, h uintptr) uintptr
   522  TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
   523  	MOVB	runtime·useAeshash(SB), R0
   524  	CBZ	R0, noaes
   525  	MOVD	p+0(FP), R10 // string pointer
   526  	LDP	(R10), (R0, R1) //string data/ length
   527  	MOVD	h+8(FP), R3
   528  	MOVD	$ret+16(FP), R2 // return adddress
   529  	B	aeshashbody<>(SB)
   530  noaes:
   531  	B	runtime·strhashFallback(SB)
   532  
   533  // R0: data
   534  // R1: length
   535  // R2: address to put return value
   536  // R3: seed data
   537  TEXT aeshashbody<>(SB),NOSPLIT|NOFRAME,$0
   538  	VEOR	V30.B16, V30.B16, V30.B16
   539  	VMOV	R3, V30.D[0]
   540  	VMOV	R1, V30.D[1] // load length into seed
   541  
   542  	MOVD	$runtime·aeskeysched+0(SB), R4
   543  	VLD1.P	16(R4), [V0.B16]
   544  	AESE	V30.B16, V0.B16
   545  	AESMC	V0.B16, V0.B16
   546  	CMP	$16, R1
   547  	BLO	aes0to15
   548  	BEQ	aes16
   549  	CMP	$32, R1
   550  	BLS	aes17to32
   551  	CMP	$64, R1
   552  	BLS	aes33to64
   553  	CMP	$128, R1
   554  	BLS	aes65to128
   555  	B	aes129plus
   556  
   557  aes0to15:
   558  	CBZ	R1, aes0
   559  	VEOR	V2.B16, V2.B16, V2.B16
   560  	TBZ	$3, R1, less_than_8
   561  	VLD1.P	8(R0), V2.D[0]
   562  
   563  less_than_8:
   564  	TBZ	$2, R1, less_than_4
   565  	VLD1.P	4(R0), V2.S[2]
   566  
   567  less_than_4:
   568  	TBZ	$1, R1, less_than_2
   569  	VLD1.P	2(R0), V2.H[6]
   570  
   571  less_than_2:
   572  	TBZ	$0, R1, done
   573  	VLD1	(R0), V2.B[14]
   574  done:
   575  	AESE	V0.B16, V2.B16
   576  	AESMC	V2.B16, V2.B16
   577  	AESE	V0.B16, V2.B16
   578  	AESMC	V2.B16, V2.B16
   579  	AESE	V0.B16, V2.B16
   580  
   581  	VST1	[V2.D1], (R2)
   582  	RET
   583  aes0:
   584  	VST1	[V0.D1], (R2)
   585  	RET
   586  aes16:
   587  	VLD1	(R0), [V2.B16]
   588  	B	done
   589  
   590  aes17to32:
   591  	// make second seed
   592  	VLD1	(R4), [V1.B16]
   593  	AESE	V30.B16, V1.B16
   594  	AESMC	V1.B16, V1.B16
   595  	SUB	$16, R1, R10
   596  	VLD1.P	(R0)(R10), [V2.B16]
   597  	VLD1	(R0), [V3.B16]
   598  
   599  	AESE	V0.B16, V2.B16
   600  	AESMC	V2.B16, V2.B16
   601  	AESE	V1.B16, V3.B16
   602  	AESMC	V3.B16, V3.B16
   603  
   604  	AESE	V0.B16, V2.B16
   605  	AESMC	V2.B16, V2.B16
   606  	AESE	V1.B16, V3.B16
   607  	AESMC	V3.B16, V3.B16
   608  
   609  	AESE	V0.B16, V2.B16
   610  	AESE	V1.B16, V3.B16
   611  
   612  	VEOR	V3.B16, V2.B16, V2.B16
   613  	VST1	[V2.D1], (R2)
   614  	RET
   615  
   616  aes33to64:
   617  	VLD1	(R4), [V1.B16, V2.B16, V3.B16]
   618  	AESE	V30.B16, V1.B16
   619  	AESMC	V1.B16, V1.B16
   620  	AESE	V30.B16, V2.B16
   621  	AESMC	V2.B16, V2.B16
   622  	AESE	V30.B16, V3.B16
   623  	AESMC	V3.B16, V3.B16
   624  	SUB	$32, R1, R10
   625  
   626  	VLD1.P	(R0)(R10), [V4.B16, V5.B16]
   627  	VLD1	(R0), [V6.B16, V7.B16]
   628  
   629  	AESE	V0.B16, V4.B16
   630  	AESMC	V4.B16, V4.B16
   631  	AESE	V1.B16, V5.B16
   632  	AESMC	V5.B16, V5.B16
   633  	AESE	V2.B16, V6.B16
   634  	AESMC	V6.B16, V6.B16
   635  	AESE	V3.B16, V7.B16
   636  	AESMC	V7.B16, V7.B16
   637  
   638  	AESE	V0.B16, V4.B16
   639  	AESMC	V4.B16, V4.B16
   640  	AESE	V1.B16, V5.B16
   641  	AESMC	V5.B16, V5.B16
   642  	AESE	V2.B16, V6.B16
   643  	AESMC	V6.B16, V6.B16
   644  	AESE	V3.B16, V7.B16
   645  	AESMC	V7.B16, V7.B16
   646  
   647  	AESE	V0.B16, V4.B16
   648  	AESE	V1.B16, V5.B16
   649  	AESE	V2.B16, V6.B16
   650  	AESE	V3.B16, V7.B16
   651  
   652  	VEOR	V6.B16, V4.B16, V4.B16
   653  	VEOR	V7.B16, V5.B16, V5.B16
   654  	VEOR	V5.B16, V4.B16, V4.B16
   655  
   656  	VST1	[V4.D1], (R2)
   657  	RET
   658  
   659  aes65to128:
   660  	VLD1.P	64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
   661  	VLD1	(R4), [V5.B16, V6.B16, V7.B16]
   662  	AESE	V30.B16, V1.B16
   663  	AESMC	V1.B16, V1.B16
   664  	AESE	V30.B16, V2.B16
   665  	AESMC	V2.B16, V2.B16
   666  	AESE	V30.B16, V3.B16
   667  	AESMC	V3.B16, V3.B16
   668  	AESE	V30.B16, V4.B16
   669  	AESMC	V4.B16, V4.B16
   670  	AESE	V30.B16, V5.B16
   671  	AESMC	V5.B16, V5.B16
   672  	AESE	V30.B16, V6.B16
   673  	AESMC	V6.B16, V6.B16
   674  	AESE	V30.B16, V7.B16
   675  	AESMC	V7.B16, V7.B16
   676  
   677  	SUB	$64, R1, R10
   678  	VLD1.P	(R0)(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
   679  	VLD1	(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
   680  	AESE	V0.B16,	 V8.B16
   681  	AESMC	V8.B16,  V8.B16
   682  	AESE	V1.B16,	 V9.B16
   683  	AESMC	V9.B16,  V9.B16
   684  	AESE	V2.B16, V10.B16
   685  	AESMC	V10.B16,  V10.B16
   686  	AESE	V3.B16, V11.B16
   687  	AESMC	V11.B16,  V11.B16
   688  	AESE	V4.B16, V12.B16
   689  	AESMC	V12.B16,  V12.B16
   690  	AESE	V5.B16, V13.B16
   691  	AESMC	V13.B16,  V13.B16
   692  	AESE	V6.B16, V14.B16
   693  	AESMC	V14.B16,  V14.B16
   694  	AESE	V7.B16, V15.B16
   695  	AESMC	V15.B16,  V15.B16
   696  
   697  	AESE	V0.B16,	 V8.B16
   698  	AESMC	V8.B16,  V8.B16
   699  	AESE	V1.B16,	 V9.B16
   700  	AESMC	V9.B16,  V9.B16
   701  	AESE	V2.B16, V10.B16
   702  	AESMC	V10.B16,  V10.B16
   703  	AESE	V3.B16, V11.B16
   704  	AESMC	V11.B16,  V11.B16
   705  	AESE	V4.B16, V12.B16
   706  	AESMC	V12.B16,  V12.B16
   707  	AESE	V5.B16, V13.B16
   708  	AESMC	V13.B16,  V13.B16
   709  	AESE	V6.B16, V14.B16
   710  	AESMC	V14.B16,  V14.B16
   711  	AESE	V7.B16, V15.B16
   712  	AESMC	V15.B16,  V15.B16
   713  
   714  	AESE	V0.B16,	 V8.B16
   715  	AESE	V1.B16,	 V9.B16
   716  	AESE	V2.B16, V10.B16
   717  	AESE	V3.B16, V11.B16
   718  	AESE	V4.B16, V12.B16
   719  	AESE	V5.B16, V13.B16
   720  	AESE	V6.B16, V14.B16
   721  	AESE	V7.B16, V15.B16
   722  
   723  	VEOR	V12.B16, V8.B16, V8.B16
   724  	VEOR	V13.B16, V9.B16, V9.B16
   725  	VEOR	V14.B16, V10.B16, V10.B16
   726  	VEOR	V15.B16, V11.B16, V11.B16
   727  	VEOR	V10.B16, V8.B16, V8.B16
   728  	VEOR	V11.B16, V9.B16, V9.B16
   729  	VEOR	V9.B16, V8.B16, V8.B16
   730  
   731  	VST1	[V8.D1], (R2)
   732  	RET
   733  
   734  aes129plus:
   735  	PRFM (R0), PLDL1KEEP
   736  	VLD1.P	64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
   737  	VLD1	(R4), [V5.B16, V6.B16, V7.B16]
   738  	AESE	V30.B16, V1.B16
   739  	AESMC	V1.B16, V1.B16
   740  	AESE	V30.B16, V2.B16
   741  	AESMC	V2.B16, V2.B16
   742  	AESE	V30.B16, V3.B16
   743  	AESMC	V3.B16, V3.B16
   744  	AESE	V30.B16, V4.B16
   745  	AESMC	V4.B16, V4.B16
   746  	AESE	V30.B16, V5.B16
   747  	AESMC	V5.B16, V5.B16
   748  	AESE	V30.B16, V6.B16
   749  	AESMC	V6.B16, V6.B16
   750  	AESE	V30.B16, V7.B16
   751  	AESMC	V7.B16, V7.B16
   752  	ADD	R0, R1, R10
   753  	SUB	$128, R10, R10
   754  	VLD1.P	64(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
   755  	VLD1	(R10), [V12.B16, V13.B16, V14.B16, V15.B16]
   756  	SUB	$1, R1, R1
   757  	LSR	$7, R1, R1
   758  
   759  aesloop:
   760  	AESE	V8.B16,	 V0.B16
   761  	AESMC	V0.B16,  V0.B16
   762  	AESE	V9.B16,	 V1.B16
   763  	AESMC	V1.B16,  V1.B16
   764  	AESE	V10.B16, V2.B16
   765  	AESMC	V2.B16,  V2.B16
   766  	AESE	V11.B16, V3.B16
   767  	AESMC	V3.B16,  V3.B16
   768  	AESE	V12.B16, V4.B16
   769  	AESMC	V4.B16,  V4.B16
   770  	AESE	V13.B16, V5.B16
   771  	AESMC	V5.B16,  V5.B16
   772  	AESE	V14.B16, V6.B16
   773  	AESMC	V6.B16,  V6.B16
   774  	AESE	V15.B16, V7.B16
   775  	AESMC	V7.B16,  V7.B16
   776  
   777  	VLD1.P	64(R0), [V8.B16, V9.B16, V10.B16, V11.B16]
   778  	AESE	V8.B16,	 V0.B16
   779  	AESMC	V0.B16,  V0.B16
   780  	AESE	V9.B16,	 V1.B16
   781  	AESMC	V1.B16,  V1.B16
   782  	AESE	V10.B16, V2.B16
   783  	AESMC	V2.B16,  V2.B16
   784  	AESE	V11.B16, V3.B16
   785  	AESMC	V3.B16,  V3.B16
   786  
   787  	VLD1.P	64(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
   788  	AESE	V12.B16, V4.B16
   789  	AESMC	V4.B16,  V4.B16
   790  	AESE	V13.B16, V5.B16
   791  	AESMC	V5.B16,  V5.B16
   792  	AESE	V14.B16, V6.B16
   793  	AESMC	V6.B16,  V6.B16
   794  	AESE	V15.B16, V7.B16
   795  	AESMC	V7.B16,  V7.B16
   796  	SUB	$1, R1, R1
   797  	CBNZ	R1, aesloop
   798  
   799  	AESE	V8.B16,	 V0.B16
   800  	AESMC	V0.B16,  V0.B16
   801  	AESE	V9.B16,	 V1.B16
   802  	AESMC	V1.B16,  V1.B16
   803  	AESE	V10.B16, V2.B16
   804  	AESMC	V2.B16,  V2.B16
   805  	AESE	V11.B16, V3.B16
   806  	AESMC	V3.B16,  V3.B16
   807  	AESE	V12.B16, V4.B16
   808  	AESMC	V4.B16,  V4.B16
   809  	AESE	V13.B16, V5.B16
   810  	AESMC	V5.B16,  V5.B16
   811  	AESE	V14.B16, V6.B16
   812  	AESMC	V6.B16,  V6.B16
   813  	AESE	V15.B16, V7.B16
   814  	AESMC	V7.B16,  V7.B16
   815  
   816  	AESE	V8.B16,	 V0.B16
   817  	AESMC	V0.B16,  V0.B16
   818  	AESE	V9.B16,	 V1.B16
   819  	AESMC	V1.B16,  V1.B16
   820  	AESE	V10.B16, V2.B16
   821  	AESMC	V2.B16,  V2.B16
   822  	AESE	V11.B16, V3.B16
   823  	AESMC	V3.B16,  V3.B16
   824  	AESE	V12.B16, V4.B16
   825  	AESMC	V4.B16,  V4.B16
   826  	AESE	V13.B16, V5.B16
   827  	AESMC	V5.B16,  V5.B16
   828  	AESE	V14.B16, V6.B16
   829  	AESMC	V6.B16,  V6.B16
   830  	AESE	V15.B16, V7.B16
   831  	AESMC	V7.B16,  V7.B16
   832  
   833  	AESE	V8.B16,	 V0.B16
   834  	AESE	V9.B16,	 V1.B16
   835  	AESE	V10.B16, V2.B16
   836  	AESE	V11.B16, V3.B16
   837  	AESE	V12.B16, V4.B16
   838  	AESE	V13.B16, V5.B16
   839  	AESE	V14.B16, V6.B16
   840  	AESE	V15.B16, V7.B16
   841  
   842  	VEOR	V0.B16, V1.B16, V0.B16
   843  	VEOR	V2.B16, V3.B16, V2.B16
   844  	VEOR	V4.B16, V5.B16, V4.B16
   845  	VEOR	V6.B16, V7.B16, V6.B16
   846  	VEOR	V0.B16, V2.B16, V0.B16
   847  	VEOR	V4.B16, V6.B16, V4.B16
   848  	VEOR	V4.B16, V0.B16, V0.B16
   849  
   850  	VST1	[V0.D1], (R2)
   851  	RET
   852  
   853  TEXT runtime·procyield(SB),NOSPLIT,$0-0
   854  	MOVWU	cycles+0(FP), R0
   855  again:
   856  	YIELD
   857  	SUBW	$1, R0
   858  	CBNZ	R0, again
   859  	RET
   860  
   861  // void jmpdefer(fv, sp);
   862  // called from deferreturn.
   863  // 1. grab stored LR for caller
   864  // 2. sub 4 bytes to get back to BL deferreturn
   865  // 3. BR to fn
   866  TEXT runtime·jmpdefer(SB), NOSPLIT|NOFRAME, $0-16
   867  	MOVD	0(RSP), R0
   868  	SUB	$4, R0
   869  	MOVD	R0, LR
   870  
   871  	MOVD	fv+0(FP), R26
   872  	MOVD	argp+8(FP), R0
   873  	MOVD	R0, RSP
   874  	SUB	$8, RSP
   875  	MOVD	0(R26), R3
   876  	B	(R3)
   877  
   878  // Save state of caller into g->sched. Smashes R0.
   879  TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
   880  	MOVD	LR, (g_sched+gobuf_pc)(g)
   881  	MOVD	RSP, R0
   882  	MOVD	R0, (g_sched+gobuf_sp)(g)
   883  	MOVD	R29, (g_sched+gobuf_bp)(g)
   884  	MOVD	$0, (g_sched+gobuf_lr)(g)
   885  	MOVD	$0, (g_sched+gobuf_ret)(g)
   886  	// Assert ctxt is zero. See func save.
   887  	MOVD	(g_sched+gobuf_ctxt)(g), R0
   888  	CBZ	R0, 2(PC)
   889  	CALL	runtime·badctxt(SB)
   890  	RET
   891  
   892  // func asmcgocall(fn, arg unsafe.Pointer) int32
   893  // Call fn(arg) on the scheduler stack,
   894  // aligned appropriately for the gcc ABI.
   895  // See cgocall.go for more details.
   896  TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   897  	MOVD	fn+0(FP), R1
   898  	MOVD	arg+8(FP), R0
   899  
   900  	MOVD	RSP, R2		// save original stack pointer
   901  	CBZ	g, nosave
   902  	MOVD	g, R4
   903  
   904  	// Figure out if we need to switch to m->g0 stack.
   905  	// We get called to create new OS threads too, and those
   906  	// come in on the m->g0 stack already.
   907  	MOVD	g_m(g), R8
   908  	MOVD	m_gsignal(R8), R3
   909  	CMP	R3, g
   910  	BEQ	nosave
   911  	MOVD	m_g0(R8), R3
   912  	CMP	R3, g
   913  	BEQ	nosave
   914  
   915  	// Switch to system stack.
   916  	MOVD	R0, R9	// gosave<> and save_g might clobber R0
   917  	BL	gosave<>(SB)
   918  	MOVD	R3, g
   919  	BL	runtime·save_g(SB)
   920  	MOVD	(g_sched+gobuf_sp)(g), R0
   921  	MOVD	R0, RSP
   922  	MOVD	(g_sched+gobuf_bp)(g), R29
   923  	MOVD	R9, R0
   924  
   925  	// Now on a scheduling stack (a pthread-created stack).
   926  	// Save room for two of our pointers /*, plus 32 bytes of callee
   927  	// save area that lives on the caller stack. */
   928  	MOVD	RSP, R13
   929  	SUB	$16, R13
   930  	MOVD	R13, RSP
   931  	MOVD	R4, 0(RSP)	// save old g on stack
   932  	MOVD	(g_stack+stack_hi)(R4), R4
   933  	SUB	R2, R4
   934  	MOVD	R4, 8(RSP)	// save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   935  	BL	(R1)
   936  	MOVD	R0, R9
   937  
   938  	// Restore g, stack pointer. R0 is errno, so don't touch it
   939  	MOVD	0(RSP), g
   940  	BL	runtime·save_g(SB)
   941  	MOVD	(g_stack+stack_hi)(g), R5
   942  	MOVD	8(RSP), R6
   943  	SUB	R6, R5
   944  	MOVD	R9, R0
   945  	MOVD	R5, RSP
   946  
   947  	MOVW	R0, ret+16(FP)
   948  	RET
   949  
   950  nosave:
   951  	// Running on a system stack, perhaps even without a g.
   952  	// Having no g can happen during thread creation or thread teardown
   953  	// (see needm/dropm on Solaris, for example).
   954  	// This code is like the above sequence but without saving/restoring g
   955  	// and without worrying about the stack moving out from under us
   956  	// (because we're on a system stack, not a goroutine stack).
   957  	// The above code could be used directly if already on a system stack,
   958  	// but then the only path through this code would be a rare case on Solaris.
   959  	// Using this code for all "already on system stack" calls exercises it more,
   960  	// which should help keep it correct.
   961  	MOVD	RSP, R13
   962  	SUB	$16, R13
   963  	MOVD	R13, RSP
   964  	MOVD	$0, R4
   965  	MOVD	R4, 0(RSP)	// Where above code stores g, in case someone looks during debugging.
   966  	MOVD	R2, 8(RSP)	// Save original stack pointer.
   967  	BL	(R1)
   968  	// Restore stack pointer.
   969  	MOVD	8(RSP), R2
   970  	MOVD	R2, RSP	
   971  	MOVD	R0, ret+16(FP)
   972  	RET
   973  
   974  // cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   975  // See cgocall.go for more details.
   976  TEXT ·cgocallback(SB),NOSPLIT,$24-24
   977  	NO_LOCAL_POINTERS
   978  
   979  	// Load g from thread-local storage.
   980  	BL	runtime·load_g(SB)
   981  
   982  	// If g is nil, Go did not create the current thread.
   983  	// Call needm to obtain one for temporary use.
   984  	// In this case, we're running on the thread stack, so there's
   985  	// lots of space, but the linker doesn't know. Hide the call from
   986  	// the linker analysis by using an indirect call.
   987  	CBZ	g, needm
   988  
   989  	MOVD	g_m(g), R8
   990  	MOVD	R8, savedm-8(SP)
   991  	B	havem
   992  
   993  needm:
   994  	MOVD	g, savedm-8(SP) // g is zero, so is m.
   995  	MOVD	$runtime·needm(SB), R0
   996  	BL	(R0)
   997  
   998  	// Set m->g0->sched.sp = SP, so that if a panic happens
   999  	// during the function we are about to execute, it will
  1000  	// have a valid SP to run on the g0 stack.
  1001  	// The next few lines (after the havem label)
  1002  	// will save this SP onto the stack and then write
  1003  	// the same SP back to m->sched.sp. That seems redundant,
  1004  	// but if an unrecovered panic happens, unwindm will
  1005  	// restore the g->sched.sp from the stack location
  1006  	// and then systemstack will try to use it. If we don't set it here,
  1007  	// that restored SP will be uninitialized (typically 0) and
  1008  	// will not be usable.
  1009  	MOVD	g_m(g), R8
  1010  	MOVD	m_g0(R8), R3
  1011  	MOVD	RSP, R0
  1012  	MOVD	R0, (g_sched+gobuf_sp)(R3)
  1013  	MOVD	R29, (g_sched+gobuf_bp)(R3)
  1014  
  1015  havem:
  1016  	// Now there's a valid m, and we're running on its m->g0.
  1017  	// Save current m->g0->sched.sp on stack and then set it to SP.
  1018  	// Save current sp in m->g0->sched.sp in preparation for
  1019  	// switch back to m->curg stack.
  1020  	// NOTE: unwindm knows that the saved g->sched.sp is at 16(RSP) aka savedsp-16(SP).
  1021  	// Beware that the frame size is actually 32+16.
  1022  	MOVD	m_g0(R8), R3
  1023  	MOVD	(g_sched+gobuf_sp)(R3), R4
  1024  	MOVD	R4, savedsp-16(SP)
  1025  	MOVD	RSP, R0
  1026  	MOVD	R0, (g_sched+gobuf_sp)(R3)
  1027  
  1028  	// Switch to m->curg stack and call runtime.cgocallbackg.
  1029  	// Because we are taking over the execution of m->curg
  1030  	// but *not* resuming what had been running, we need to
  1031  	// save that information (m->curg->sched) so we can restore it.
  1032  	// We can restore m->curg->sched.sp easily, because calling
  1033  	// runtime.cgocallbackg leaves SP unchanged upon return.
  1034  	// To save m->curg->sched.pc, we push it onto the curg stack and
  1035  	// open a frame the same size as cgocallback's g0 frame.
  1036  	// Once we switch to the curg stack, the pushed PC will appear
  1037  	// to be the return PC of cgocallback, so that the traceback
  1038  	// will seamlessly trace back into the earlier calls.
  1039  	MOVD	m_curg(R8), g
  1040  	BL	runtime·save_g(SB)
  1041  	MOVD	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
  1042  	MOVD	(g_sched+gobuf_pc)(g), R5
  1043  	MOVD	R5, -48(R4)
  1044  	MOVD	(g_sched+gobuf_bp)(g), R5
  1045  	MOVD	R5, -56(R4)
  1046  	// Gather our arguments into registers.
  1047  	MOVD	fn+0(FP), R1
  1048  	MOVD	frame+8(FP), R2
  1049  	MOVD	ctxt+16(FP), R3
  1050  	MOVD	$-48(R4), R0 // maintain 16-byte SP alignment
  1051  	MOVD	R0, RSP	// switch stack
  1052  	MOVD	R1, 8(RSP)
  1053  	MOVD	R2, 16(RSP)
  1054  	MOVD	R3, 24(RSP)
  1055  	BL	runtime·cgocallbackg(SB)
  1056  
  1057  	// Restore g->sched (== m->curg->sched) from saved values.
  1058  	MOVD	0(RSP), R5
  1059  	MOVD	R5, (g_sched+gobuf_pc)(g)
  1060  	MOVD	RSP, R4
  1061  	ADD	$48, R4, R4
  1062  	MOVD	R4, (g_sched+gobuf_sp)(g)
  1063  
  1064  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
  1065  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
  1066  	// so we do not have to restore it.)
  1067  	MOVD	g_m(g), R8
  1068  	MOVD	m_g0(R8), g
  1069  	BL	runtime·save_g(SB)
  1070  	MOVD	(g_sched+gobuf_sp)(g), R0
  1071  	MOVD	R0, RSP
  1072  	MOVD	savedsp-16(SP), R4
  1073  	MOVD	R4, (g_sched+gobuf_sp)(g)
  1074  
  1075  	// If the m on entry was nil, we called needm above to borrow an m
  1076  	// for the duration of the call. Since the call is over, return it with dropm.
  1077  	MOVD	savedm-8(SP), R6
  1078  	CBNZ	R6, droppedm
  1079  	MOVD	$runtime·dropm(SB), R0
  1080  	BL	(R0)
  1081  droppedm:
  1082  
  1083  	// Done!
  1084  	RET
  1085  
  1086  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
  1087  // Must obey the gcc calling convention.
  1088  TEXT _cgo_topofstack(SB),NOSPLIT,$24
  1089  	// g (R28) and REGTMP (R27)  might be clobbered by load_g. They
  1090  	// are callee-save in the gcc calling convention, so save them.
  1091  	MOVD	R27, savedR27-8(SP)
  1092  	MOVD	g, saveG-16(SP)
  1093  
  1094  	BL	runtime·load_g(SB)
  1095  	MOVD	g_m(g), R0
  1096  	MOVD	m_curg(R0), R0
  1097  	MOVD	(g_stack+stack_hi)(R0), R0
  1098  
  1099  	MOVD	saveG-16(SP), g
  1100  	MOVD	savedR28-8(SP), R27
  1101  	RET
  1102  
  1103  // void setg(G*); set g. for use by needm.
  1104  TEXT runtime·setg(SB), NOSPLIT, $0-8
  1105  	MOVD	gg+0(FP), g
  1106  	// This only happens if iscgo, so jump straight to save_g
  1107  	BL	runtime·save_g(SB)
  1108  	RET
  1109  
  1110  // void setg_gcc(G*); set g called from gcc
  1111  TEXT setg_gcc<>(SB),NOSPLIT,$8
  1112  	MOVD	R0, g
  1113  	MOVD	R27, savedR27-8(SP)
  1114  	BL	runtime·save_g(SB)
  1115  	MOVD	savedR27-8(SP), R27
  1116  	RET
  1117  
  1118  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
  1119  	MOVD	ZR, R0
  1120  	MOVD	(R0), R0
  1121  	UNDEF
  1122  
  1123  TEXT runtime·return0(SB), NOSPLIT, $0
  1124  	MOVW	$0, R0
  1125  	RET
  1126  
  1127  // The top-most function running on a goroutine
  1128  // returns to goexit+PCQuantum.
  1129  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
  1130  	MOVD	R0, R0	// NOP
  1131  	BL	runtime·goexit1(SB)	// does not return
  1132  
  1133  // This is called from .init_array and follows the platform, not Go, ABI.
  1134  TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
  1135  	SUB	$0x10, RSP
  1136  	MOVD	R27, 8(RSP) // The access to global variables below implicitly uses R27, which is callee-save
  1137  	MOVD	runtime·lastmoduledatap(SB), R1
  1138  	MOVD	R0, moduledata_next(R1)
  1139  	MOVD	R0, runtime·lastmoduledatap(SB)
  1140  	MOVD	8(RSP), R27
  1141  	ADD	$0x10, RSP
  1142  	RET
  1143  
  1144  TEXT ·checkASM(SB),NOSPLIT,$0-1
  1145  	MOVW	$1, R3
  1146  	MOVB	R3, ret+0(FP)
  1147  	RET
  1148  
  1149  // gcWriteBarrier performs a heap pointer write and informs the GC.
  1150  //
  1151  // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
  1152  // - R2 is the destination of the write
  1153  // - R3 is the value being written at R2
  1154  // It clobbers condition codes.
  1155  // It does not clobber any general-purpose registers,
  1156  // but may clobber others (e.g., floating point registers)
  1157  // The act of CALLing gcWriteBarrier will clobber R30 (LR).
  1158  TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216
  1159  	// Save the registers clobbered by the fast path.
  1160  	MOVD	R0, 200(RSP)
  1161  	MOVD	R1, 208(RSP)
  1162  	MOVD	g_m(g), R0
  1163  	MOVD	m_p(R0), R0
  1164  	MOVD	(p_wbBuf+wbBuf_next)(R0), R1
  1165  	// Increment wbBuf.next position.
  1166  	ADD	$16, R1
  1167  	MOVD	R1, (p_wbBuf+wbBuf_next)(R0)
  1168  	MOVD	(p_wbBuf+wbBuf_end)(R0), R0
  1169  	CMP	R1, R0
  1170  	// Record the write.
  1171  	MOVD	R3, -16(R1)	// Record value
  1172  	MOVD	(R2), R0	// TODO: This turns bad writes into bad reads.
  1173  	MOVD	R0, -8(R1)	// Record *slot
  1174  	// Is the buffer full? (flags set in CMP above)
  1175  	BEQ	flush
  1176  ret:
  1177  	MOVD	200(RSP), R0
  1178  	MOVD	208(RSP), R1
  1179  	// Do the write.
  1180  	MOVD	R3, (R2)
  1181  	RET
  1182  
  1183  flush:
  1184  	// Save all general purpose registers since these could be
  1185  	// clobbered by wbBufFlush and were not saved by the caller.
  1186  	MOVD	R2, 8(RSP)	// Also first argument to wbBufFlush
  1187  	MOVD	R3, 16(RSP)	// Also second argument to wbBufFlush
  1188  	// R0 already saved
  1189  	// R1 already saved
  1190  	MOVD	R4, 24(RSP)
  1191  	MOVD	R5, 32(RSP)
  1192  	MOVD	R6, 40(RSP)
  1193  	MOVD	R7, 48(RSP)
  1194  	MOVD	R8, 56(RSP)
  1195  	MOVD	R9, 64(RSP)
  1196  	MOVD	R10, 72(RSP)
  1197  	MOVD	R11, 80(RSP)
  1198  	MOVD	R12, 88(RSP)
  1199  	MOVD	R13, 96(RSP)
  1200  	MOVD	R14, 104(RSP)
  1201  	MOVD	R15, 112(RSP)
  1202  	MOVD	R16, 120(RSP)
  1203  	MOVD	R17, 128(RSP)
  1204  	// R18 is unused.
  1205  	MOVD	R19, 136(RSP)
  1206  	MOVD	R20, 144(RSP)
  1207  	MOVD	R21, 152(RSP)
  1208  	MOVD	R22, 160(RSP)
  1209  	MOVD	R23, 168(RSP)
  1210  	MOVD	R24, 176(RSP)
  1211  	MOVD	R25, 184(RSP)
  1212  	MOVD	R26, 192(RSP)
  1213  	// R27 is temp register.
  1214  	// R28 is g.
  1215  	// R29 is frame pointer (unused).
  1216  	// R30 is LR, which was saved by the prologue.
  1217  	// R31 is SP.
  1218  
  1219  	// This takes arguments R2 and R3.
  1220  	CALL	runtime·wbBufFlush(SB)
  1221  
  1222  	MOVD	8(RSP), R2
  1223  	MOVD	16(RSP), R3
  1224  	MOVD	24(RSP), R4
  1225  	MOVD	32(RSP), R5
  1226  	MOVD	40(RSP), R6
  1227  	MOVD	48(RSP), R7
  1228  	MOVD	56(RSP), R8
  1229  	MOVD	64(RSP), R9
  1230  	MOVD	72(RSP), R10
  1231  	MOVD	80(RSP), R11
  1232  	MOVD	88(RSP), R12
  1233  	MOVD	96(RSP), R13
  1234  	MOVD	104(RSP), R14
  1235  	MOVD	112(RSP), R15
  1236  	MOVD	120(RSP), R16
  1237  	MOVD	128(RSP), R17
  1238  	MOVD	136(RSP), R19
  1239  	MOVD	144(RSP), R20
  1240  	MOVD	152(RSP), R21
  1241  	MOVD	160(RSP), R22
  1242  	MOVD	168(RSP), R23
  1243  	MOVD	176(RSP), R24
  1244  	MOVD	184(RSP), R25
  1245  	MOVD	192(RSP), R26
  1246  	JMP	ret
  1247  
  1248  // Note: these functions use a special calling convention to save generated code space.
  1249  // Arguments are passed in registers, but the space for those arguments are allocated
  1250  // in the caller's stack frame. These stubs write the args into that stack space and
  1251  // then tail call to the corresponding runtime handler.
  1252  // The tail call makes these stubs disappear in backtraces.
  1253  TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
  1254  	MOVD	R0, x+0(FP)
  1255  	MOVD	R1, y+8(FP)
  1256  	JMP	runtime·goPanicIndex(SB)
  1257  TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
  1258  	MOVD	R0, x+0(FP)
  1259  	MOVD	R1, y+8(FP)
  1260  	JMP	runtime·goPanicIndexU(SB)
  1261  TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
  1262  	MOVD	R1, x+0(FP)
  1263  	MOVD	R2, y+8(FP)
  1264  	JMP	runtime·goPanicSliceAlen(SB)
  1265  TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
  1266  	MOVD	R1, x+0(FP)
  1267  	MOVD	R2, y+8(FP)
  1268  	JMP	runtime·goPanicSliceAlenU(SB)
  1269  TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
  1270  	MOVD	R1, x+0(FP)
  1271  	MOVD	R2, y+8(FP)
  1272  	JMP	runtime·goPanicSliceAcap(SB)
  1273  TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
  1274  	MOVD	R1, x+0(FP)
  1275  	MOVD	R2, y+8(FP)
  1276  	JMP	runtime·goPanicSliceAcapU(SB)
  1277  TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
  1278  	MOVD	R0, x+0(FP)
  1279  	MOVD	R1, y+8(FP)
  1280  	JMP	runtime·goPanicSliceB(SB)
  1281  TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
  1282  	MOVD	R0, x+0(FP)
  1283  	MOVD	R1, y+8(FP)
  1284  	JMP	runtime·goPanicSliceBU(SB)
  1285  TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
  1286  	MOVD	R2, x+0(FP)
  1287  	MOVD	R3, y+8(FP)
  1288  	JMP	runtime·goPanicSlice3Alen(SB)
  1289  TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
  1290  	MOVD	R2, x+0(FP)
  1291  	MOVD	R3, y+8(FP)
  1292  	JMP	runtime·goPanicSlice3AlenU(SB)
  1293  TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
  1294  	MOVD	R2, x+0(FP)
  1295  	MOVD	R3, y+8(FP)
  1296  	JMP	runtime·goPanicSlice3Acap(SB)
  1297  TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
  1298  	MOVD	R2, x+0(FP)
  1299  	MOVD	R3, y+8(FP)
  1300  	JMP	runtime·goPanicSlice3AcapU(SB)
  1301  TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
  1302  	MOVD	R1, x+0(FP)
  1303  	MOVD	R2, y+8(FP)
  1304  	JMP	runtime·goPanicSlice3B(SB)
  1305  TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
  1306  	MOVD	R1, x+0(FP)
  1307  	MOVD	R2, y+8(FP)
  1308  	JMP	runtime·goPanicSlice3BU(SB)
  1309  TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
  1310  	MOVD	R0, x+0(FP)
  1311  	MOVD	R1, y+8(FP)
  1312  	JMP	runtime·goPanicSlice3C(SB)
  1313  TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
  1314  	MOVD	R0, x+0(FP)
  1315  	MOVD	R1, y+8(FP)
  1316  	JMP	runtime·goPanicSlice3CU(SB)