...

Text file src/runtime/asm_arm64.s

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

View as plain text