github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/runtime/asm_ppc64x.s (about)

     1  // Copyright 2014 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  // +build ppc64 ppc64le
     6  
     7  #include "go_asm.h"
     8  #include "go_tls.h"
     9  #include "funcdata.h"
    10  #include "textflag.h"
    11  #include "asm_ppc64x.h"
    12  
    13  #ifdef GOOS_aix
    14  #define cgoCalleeStackSize 48
    15  #else
    16  #define cgoCalleeStackSize 32
    17  #endif
    18  
    19  TEXT runtime·rt0_go(SB),NOSPLIT,$0
    20  	// R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer
    21  
    22  	// initialize essential registers
    23  	BL	runtime·reginit(SB)
    24  
    25  	SUB	$(FIXED_FRAME+16), R1
    26  	MOVD	R2, 24(R1)		// stash the TOC pointer away again now we've created a new frame
    27  	MOVW	R3, FIXED_FRAME+0(R1)	// argc
    28  	MOVD	R4, FIXED_FRAME+8(R1)	// argv
    29  
    30  	// create istack out of the given (operating system) stack.
    31  	// _cgo_init may update stackguard.
    32  	MOVD	$runtime·g0(SB), g
    33  	BL	runtime·save_g(SB)
    34  	MOVD	$(-64*1024), R31
    35  	ADD	R31, R1, R3
    36  	MOVD	R3, g_stackguard0(g)
    37  	MOVD	R3, g_stackguard1(g)
    38  	MOVD	R3, (g_stack+stack_lo)(g)
    39  	MOVD	R1, (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  	CMP	R0, R12
    44  	BEQ	nocgo
    45  #ifdef GOARCH_ppc64
    46  	// ppc64 use elf ABI v1. we must get the real entry address from
    47  	// first slot of the function descriptor before call.
    48  	MOVD	8(R12), R2
    49  	MOVD	(R12), R12
    50  #endif
    51  	MOVD	R12, CTR		// r12 = "global function entry point"
    52  	MOVD	R13, R5			// arg 2: TLS base pointer
    53  	MOVD	$setg_gcc<>(SB), R4 	// arg 1: setg
    54  	MOVD	g, R3			// arg 0: G
    55  	// C functions expect 32 (48 for AIX) bytes of space on caller
    56  	// stack frame and a 16-byte aligned R1
    57  	MOVD	R1, R14			// save current stack
    58  	SUB	$cgoCalleeStackSize, R1	// reserve the callee area
    59  	RLDCR	$0, R1, $~15, R1	// 16-byte align
    60  	BL	(CTR)			// may clobber R0, R3-R12
    61  	MOVD	R14, R1			// restore stack
    62  #ifndef GOOS_aix
    63  	MOVD	24(R1), R2
    64  #endif
    65  	XOR	R0, R0			// fix R0
    66  
    67  nocgo:
    68  	// update stackguard after _cgo_init
    69  	MOVD	(g_stack+stack_lo)(g), R3
    70  	ADD	$const__StackGuard, R3
    71  	MOVD	R3, g_stackguard0(g)
    72  	MOVD	R3, g_stackguard1(g)
    73  
    74  	// set the per-goroutine and per-mach "registers"
    75  	MOVD	$runtime·m0(SB), R3
    76  
    77  	// save m->g0 = g0
    78  	MOVD	g, m_g0(R3)
    79  	// save m0 to g0->m
    80  	MOVD	R3, g_m(g)
    81  
    82  	BL	runtime·check(SB)
    83  
    84  	// args are already prepared
    85  	BL	runtime·args(SB)
    86  	BL	runtime·osinit(SB)
    87  	BL	runtime·schedinit(SB)
    88  
    89  	// create a new goroutine to start program
    90  	MOVD	$runtime·mainPC(SB), R3		// entry
    91  	MOVDU	R3, -8(R1)
    92  	MOVDU	R0, -8(R1)
    93  	MOVDU	R0, -8(R1)
    94  	MOVDU	R0, -8(R1)
    95  	MOVDU	R0, -8(R1)
    96  	MOVDU	R0, -8(R1)
    97  	BL	runtime·newproc(SB)
    98  	ADD	$(16+FIXED_FRAME), R1
    99  
   100  	// start this M
   101  	BL	runtime·mstart(SB)
   102  
   103  	MOVD	R0, 0(R0)
   104  	RET
   105  
   106  DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
   107  GLOBL	runtime·mainPC(SB),RODATA,$8
   108  
   109  TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
   110  	MOVD	R0, 0(R0) // TODO: TD
   111  	RET
   112  
   113  TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
   114  	RET
   115  
   116  // Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall_ppc64
   117  TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
   118  	// crosscall_ppc64 and crosscall2 need to reginit, but can't
   119  	// get at the 'runtime.reginit' symbol.
   120  	BR	runtime·reginit(SB)
   121  
   122  TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0
   123  	// set R0 to zero, it's expected by the toolchain
   124  	XOR R0, R0
   125  	RET
   126  
   127  /*
   128   *  go-routine
   129   */
   130  
   131  // void gosave(Gobuf*)
   132  // save state in Gobuf; setjmp
   133  TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
   134  	MOVD	buf+0(FP), R3
   135  	MOVD	R1, gobuf_sp(R3)
   136  	MOVD	LR, R31
   137  	MOVD	R31, gobuf_pc(R3)
   138  	MOVD	g, gobuf_g(R3)
   139  	MOVD	R0, gobuf_lr(R3)
   140  	MOVD	R0, gobuf_ret(R3)
   141  	// Assert ctxt is zero. See func save.
   142  	MOVD	gobuf_ctxt(R3), R3
   143  	CMP	R0, R3
   144  	BEQ	2(PC)
   145  	BL	runtime·badctxt(SB)
   146  	RET
   147  
   148  // void gogo(Gobuf*)
   149  // restore state from Gobuf; longjmp
   150  TEXT runtime·gogo(SB), NOSPLIT, $16-8
   151  	MOVD	buf+0(FP), R5
   152  	MOVD	gobuf_g(R5), g	// make sure g is not nil
   153  	BL	runtime·save_g(SB)
   154  
   155  	MOVD	0(g), R4
   156  	MOVD	gobuf_sp(R5), R1
   157  	MOVD	gobuf_lr(R5), R31
   158  #ifndef GOOS_aix
   159  	MOVD	24(R1), R2	// restore R2
   160  #endif
   161  	MOVD	R31, LR
   162  	MOVD	gobuf_ret(R5), R3
   163  	MOVD	gobuf_ctxt(R5), R11
   164  	MOVD	R0, gobuf_sp(R5)
   165  	MOVD	R0, gobuf_ret(R5)
   166  	MOVD	R0, gobuf_lr(R5)
   167  	MOVD	R0, gobuf_ctxt(R5)
   168  	CMP	R0, R0 // set condition codes for == test, needed by stack split
   169  	MOVD	gobuf_pc(R5), R12
   170  	MOVD	R12, CTR
   171  	BR	(CTR)
   172  
   173  // void mcall(fn func(*g))
   174  // Switch to m->g0's stack, call fn(g).
   175  // Fn must never return. It should gogo(&g->sched)
   176  // to keep running g.
   177  TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8
   178  	// Save caller state in g->sched
   179  	MOVD	R1, (g_sched+gobuf_sp)(g)
   180  	MOVD	LR, R31
   181  	MOVD	R31, (g_sched+gobuf_pc)(g)
   182  	MOVD	R0, (g_sched+gobuf_lr)(g)
   183  	MOVD	g, (g_sched+gobuf_g)(g)
   184  
   185  	// Switch to m->g0 & its stack, call fn.
   186  	MOVD	g, R3
   187  	MOVD	g_m(g), R8
   188  	MOVD	m_g0(R8), g
   189  	BL	runtime·save_g(SB)
   190  	CMP	g, R3
   191  	BNE	2(PC)
   192  	BR	runtime·badmcall(SB)
   193  	MOVD	fn+0(FP), R11			// context
   194  	MOVD	0(R11), R12			// code pointer
   195  	MOVD	R12, CTR
   196  	MOVD	(g_sched+gobuf_sp)(g), R1	// sp = m->g0->sched.sp
   197  	MOVDU	R3, -8(R1)
   198  	MOVDU	R0, -8(R1)
   199  	MOVDU	R0, -8(R1)
   200  	MOVDU	R0, -8(R1)
   201  	MOVDU	R0, -8(R1)
   202  	BL	(CTR)
   203  	MOVD	24(R1), R2
   204  	BR	runtime·badmcall2(SB)
   205  
   206  // systemstack_switch is a dummy routine that systemstack leaves at the bottom
   207  // of the G stack. We need to distinguish the routine that
   208  // lives at the bottom of the G stack from the one that lives
   209  // at the top of the system stack because the one at the top of
   210  // the system stack terminates the stack walk (see topofstack()).
   211  TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   212  	// We have several undefs here so that 16 bytes past
   213  	// $runtime·systemstack_switch lies within them whether or not the
   214  	// instructions that derive r2 from r12 are there.
   215  	UNDEF
   216  	UNDEF
   217  	UNDEF
   218  	BL	(LR)	// make sure this function is not leaf
   219  	RET
   220  
   221  // func systemstack(fn func())
   222  TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   223  	MOVD	fn+0(FP), R3	// R3 = fn
   224  	MOVD	R3, R11		// context
   225  	MOVD	g_m(g), R4	// R4 = m
   226  
   227  	MOVD	m_gsignal(R4), R5	// R5 = gsignal
   228  	CMP	g, R5
   229  	BEQ	noswitch
   230  
   231  	MOVD	m_g0(R4), R5	// R5 = g0
   232  	CMP	g, R5
   233  	BEQ	noswitch
   234  
   235  	MOVD	m_curg(R4), R6
   236  	CMP	g, R6
   237  	BEQ	switch
   238  
   239  	// Bad: g is not gsignal, not g0, not curg. What is it?
   240  	// Hide call from linker nosplit analysis.
   241  	MOVD	$runtime·badsystemstack(SB), R12
   242  	MOVD	R12, CTR
   243  	BL	(CTR)
   244  	BL	runtime·abort(SB)
   245  
   246  switch:
   247  	// save our state in g->sched. Pretend to
   248  	// be systemstack_switch if the G stack is scanned.
   249  	MOVD	$runtime·systemstack_switch(SB), R6
   250  	ADD     $16, R6 // get past prologue (including r2-setting instructions when they're there)
   251  	MOVD	R6, (g_sched+gobuf_pc)(g)
   252  	MOVD	R1, (g_sched+gobuf_sp)(g)
   253  	MOVD	R0, (g_sched+gobuf_lr)(g)
   254  	MOVD	g, (g_sched+gobuf_g)(g)
   255  
   256  	// switch to g0
   257  	MOVD	R5, g
   258  	BL	runtime·save_g(SB)
   259  	MOVD	(g_sched+gobuf_sp)(g), R3
   260  	// make it look like mstart called systemstack on g0, to stop traceback
   261  	SUB	$FIXED_FRAME, R3
   262  	MOVD	$runtime·mstart(SB), R4
   263  	MOVD	R4, 0(R3)
   264  	MOVD	R3, R1
   265  
   266  	// call target function
   267  	MOVD	0(R11), R12	// code pointer
   268  	MOVD	R12, CTR
   269  	BL	(CTR)
   270  
   271  	// restore TOC pointer. It seems unlikely that we will use systemstack
   272  	// to call a function defined in another module, but the results of
   273  	// doing so would be so confusing that it's worth doing this.
   274  	MOVD	g_m(g), R3
   275  	MOVD	m_curg(R3), g
   276  	MOVD	(g_sched+gobuf_sp)(g), R3
   277  #ifndef GOOS_aix
   278  	MOVD	24(R3), R2
   279  #endif
   280  	// switch back to g
   281  	MOVD	g_m(g), R3
   282  	MOVD	m_curg(R3), g
   283  	BL	runtime·save_g(SB)
   284  	MOVD	(g_sched+gobuf_sp)(g), R1
   285  	MOVD	R0, (g_sched+gobuf_sp)(g)
   286  	RET
   287  
   288  noswitch:
   289  	// already on m stack, just call directly
   290  	// On other arches we do a tail call here, but it appears to be
   291  	// impossible to tail call a function pointer in shared mode on
   292  	// ppc64 because the caller is responsible for restoring the TOC.
   293  	MOVD	0(R11), R12	// code pointer
   294  	MOVD	R12, CTR
   295  	BL	(CTR)
   296  #ifndef GOOS_aix
   297  	MOVD	24(R1), R2
   298  #endif
   299  	RET
   300  
   301  /*
   302   * support for morestack
   303   */
   304  
   305  // Called during function prolog when more stack is needed.
   306  // Caller has already loaded:
   307  // R3: framesize, R4: argsize, R5: LR
   308  //
   309  // The traceback routines see morestack on a g0 as being
   310  // the top of a stack (for example, morestack calling newstack
   311  // calling the scheduler calling newm calling gc), so we must
   312  // record an argument size. For that purpose, it has no arguments.
   313  TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   314  	// Cannot grow scheduler stack (m->g0).
   315  	MOVD	g_m(g), R7
   316  	MOVD	m_g0(R7), R8
   317  	CMP	g, R8
   318  	BNE	3(PC)
   319  	BL	runtime·badmorestackg0(SB)
   320  	BL	runtime·abort(SB)
   321  
   322  	// Cannot grow signal stack (m->gsignal).
   323  	MOVD	m_gsignal(R7), R8
   324  	CMP	g, R8
   325  	BNE	3(PC)
   326  	BL	runtime·badmorestackgsignal(SB)
   327  	BL	runtime·abort(SB)
   328  
   329  	// Called from f.
   330  	// Set g->sched to context in f.
   331  	MOVD	R1, (g_sched+gobuf_sp)(g)
   332  	MOVD	LR, R8
   333  	MOVD	R8, (g_sched+gobuf_pc)(g)
   334  	MOVD	R5, (g_sched+gobuf_lr)(g)
   335  	MOVD	R11, (g_sched+gobuf_ctxt)(g)
   336  
   337  	// Called from f.
   338  	// Set m->morebuf to f's caller.
   339  	MOVD	R5, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   340  	MOVD	R1, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   341  	MOVD	g, (m_morebuf+gobuf_g)(R7)
   342  
   343  	// Call newstack on m->g0's stack.
   344  	MOVD	m_g0(R7), g
   345  	BL	runtime·save_g(SB)
   346  	MOVD	(g_sched+gobuf_sp)(g), R1
   347  	MOVDU   R0, -(FIXED_FRAME+0)(R1)	// create a call frame on g0
   348  	BL	runtime·newstack(SB)
   349  
   350  	// Not reached, but make sure the return PC from the call to newstack
   351  	// is still in this function, and not the beginning of the next.
   352  	UNDEF
   353  
   354  TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   355  	MOVD	R0, R11
   356  	BR	runtime·morestack(SB)
   357  
   358  // reflectcall: call a function with the given argument list
   359  // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
   360  // we don't have variable-sized frames, so we use a small number
   361  // of constant-sized-frame functions to encode a few bits of size in the pc.
   362  // Caution: ugly multiline assembly macros in your future!
   363  
   364  #define DISPATCH(NAME,MAXSIZE)		\
   365  	MOVD	$MAXSIZE, R31;		\
   366  	CMP	R3, R31;		\
   367  	BGT	4(PC);			\
   368  	MOVD	$NAME(SB), R12;		\
   369  	MOVD	R12, CTR;		\
   370  	BR	(CTR)
   371  // Note: can't just "BR NAME(SB)" - bad inlining results.
   372  
   373  TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
   374  	MOVWZ argsize+24(FP), R3
   375  	DISPATCH(runtime·call16, 16)
   376  	DISPATCH(runtime·call32, 32)
   377  	DISPATCH(runtime·call64, 64)
   378  	DISPATCH(runtime·call128, 128)
   379  	DISPATCH(runtime·call256, 256)
   380  	DISPATCH(runtime·call512, 512)
   381  	DISPATCH(runtime·call1024, 1024)
   382  	DISPATCH(runtime·call2048, 2048)
   383  	DISPATCH(runtime·call4096, 4096)
   384  	DISPATCH(runtime·call8192, 8192)
   385  	DISPATCH(runtime·call16384, 16384)
   386  	DISPATCH(runtime·call32768, 32768)
   387  	DISPATCH(runtime·call65536, 65536)
   388  	DISPATCH(runtime·call131072, 131072)
   389  	DISPATCH(runtime·call262144, 262144)
   390  	DISPATCH(runtime·call524288, 524288)
   391  	DISPATCH(runtime·call1048576, 1048576)
   392  	DISPATCH(runtime·call2097152, 2097152)
   393  	DISPATCH(runtime·call4194304, 4194304)
   394  	DISPATCH(runtime·call8388608, 8388608)
   395  	DISPATCH(runtime·call16777216, 16777216)
   396  	DISPATCH(runtime·call33554432, 33554432)
   397  	DISPATCH(runtime·call67108864, 67108864)
   398  	DISPATCH(runtime·call134217728, 134217728)
   399  	DISPATCH(runtime·call268435456, 268435456)
   400  	DISPATCH(runtime·call536870912, 536870912)
   401  	DISPATCH(runtime·call1073741824, 1073741824)
   402  	MOVD	$runtime·badreflectcall(SB), R12
   403  	MOVD	R12, CTR
   404  	BR	(CTR)
   405  
   406  #define CALLFN(NAME,MAXSIZE)			\
   407  TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
   408  	NO_LOCAL_POINTERS;			\
   409  	/* copy arguments to stack */		\
   410  	MOVD	arg+16(FP), R3;			\
   411  	MOVWZ	argsize+24(FP), R4;			\
   412  	MOVD    R1, R5;				\
   413  	CMP	R4, $8;				\
   414  	BLT	tailsetup;			\
   415  	/* copy 8 at a time if possible */	\
   416  	ADD	$(FIXED_FRAME-8), R5;			\
   417  	SUB	$8, R3;				\
   418  top: \
   419  	MOVDU	8(R3), R7;			\
   420  	MOVDU	R7, 8(R5);			\
   421  	SUB	$8, R4;				\
   422  	CMP	R4, $8;				\
   423  	BGE	top;				\
   424  	/* handle remaining bytes */	\
   425  	CMP	$0, R4;			\
   426  	BEQ	callfn;			\
   427  	ADD	$7, R3;			\
   428  	ADD	$7, R5;			\
   429  	BR	tail;			\
   430  tailsetup: \
   431  	CMP	$0, R4;			\
   432  	BEQ	callfn;			\
   433  	ADD     $(FIXED_FRAME-1), R5;	\
   434  	SUB     $1, R3;			\
   435  tail: \
   436  	MOVBU	1(R3), R6;		\
   437  	MOVBU	R6, 1(R5);		\
   438  	SUB	$1, R4;			\
   439  	CMP	$0, R4;			\
   440  	BGT	tail;			\
   441  callfn: \
   442  	/* call function */			\
   443  	MOVD	f+8(FP), R11;			\
   444  #ifdef GOOS_aix				\
   445  	/* AIX won't trigger a SIGSEGV if R11 = nil */	\
   446  	/* So it manually triggers it */	\
   447  	CMP	R0, R11				\
   448  	BNE	2(PC)				\
   449  	MOVD	R0, 0(R0)			\
   450  #endif						\
   451  	MOVD	(R11), R12;			\
   452  	MOVD	R12, CTR;			\
   453  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   454  	BL	(CTR);				\
   455  #ifndef GOOS_aix				\
   456  	MOVD	24(R1), R2;			\
   457  #endif						\
   458  	/* copy return values back */		\
   459  	MOVD	argtype+0(FP), R7;		\
   460  	MOVD	arg+16(FP), R3;			\
   461  	MOVWZ	n+24(FP), R4;			\
   462  	MOVWZ	retoffset+28(FP), R6;		\
   463  	ADD	$FIXED_FRAME, R1, R5;		\
   464  	ADD	R6, R5; 			\
   465  	ADD	R6, R3;				\
   466  	SUB	R6, R4;				\
   467  	BL	callRet<>(SB);			\
   468  	RET
   469  
   470  // callRet copies return values back at the end of call*. This is a
   471  // separate function so it can allocate stack space for the arguments
   472  // to reflectcallmove. It does not follow the Go ABI; it expects its
   473  // arguments in registers.
   474  TEXT callRet<>(SB), NOSPLIT, $32-0
   475  	MOVD	R7, FIXED_FRAME+0(R1)
   476  	MOVD	R3, FIXED_FRAME+8(R1)
   477  	MOVD	R5, FIXED_FRAME+16(R1)
   478  	MOVD	R4, FIXED_FRAME+24(R1)
   479  	BL	runtime·reflectcallmove(SB)
   480  	RET
   481  
   482  CALLFN(·call16, 16)
   483  CALLFN(·call32, 32)
   484  CALLFN(·call64, 64)
   485  CALLFN(·call128, 128)
   486  CALLFN(·call256, 256)
   487  CALLFN(·call512, 512)
   488  CALLFN(·call1024, 1024)
   489  CALLFN(·call2048, 2048)
   490  CALLFN(·call4096, 4096)
   491  CALLFN(·call8192, 8192)
   492  CALLFN(·call16384, 16384)
   493  CALLFN(·call32768, 32768)
   494  CALLFN(·call65536, 65536)
   495  CALLFN(·call131072, 131072)
   496  CALLFN(·call262144, 262144)
   497  CALLFN(·call524288, 524288)
   498  CALLFN(·call1048576, 1048576)
   499  CALLFN(·call2097152, 2097152)
   500  CALLFN(·call4194304, 4194304)
   501  CALLFN(·call8388608, 8388608)
   502  CALLFN(·call16777216, 16777216)
   503  CALLFN(·call33554432, 33554432)
   504  CALLFN(·call67108864, 67108864)
   505  CALLFN(·call134217728, 134217728)
   506  CALLFN(·call268435456, 268435456)
   507  CALLFN(·call536870912, 536870912)
   508  CALLFN(·call1073741824, 1073741824)
   509  
   510  TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0-4
   511  	MOVW	cycles+0(FP), R7
   512  	// POWER does not have a pause/yield instruction equivalent.
   513  	// Instead, we can lower the program priority by setting the
   514  	// Program Priority Register prior to the wait loop and set it
   515  	// back to default afterwards. On Linux, the default priority is
   516  	// medium-low. For details, see page 837 of the ISA 3.0.
   517  	OR	R1, R1, R1	// Set PPR priority to low
   518  again:
   519  	SUB	$1, R7
   520  	CMP	$0, R7
   521  	BNE	again
   522  	OR	R6, R6, R6	// Set PPR priority back to medium-low
   523  	RET
   524  
   525  // void jmpdefer(fv, sp);
   526  // called from deferreturn.
   527  // 1. grab stored LR for caller
   528  // 2. sub 8 bytes to get back to either nop or toc reload before deferreturn
   529  // 3. BR to fn
   530  // When dynamically linking Go, it is not sufficient to rewind to the BL
   531  // deferreturn -- we might be jumping between modules and so we need to reset
   532  // the TOC pointer in r2. To do this, codegen inserts MOVD 24(R1), R2 *before*
   533  // the BL deferreturn and jmpdefer rewinds to that.
   534  TEXT runtime·jmpdefer(SB), NOSPLIT|NOFRAME, $0-16
   535  	MOVD	0(R1), R31
   536  	SUB     $8, R31
   537  	MOVD	R31, LR
   538  
   539  	MOVD	fv+0(FP), R11
   540  	MOVD	argp+8(FP), R1
   541  	SUB	$FIXED_FRAME, R1
   542  #ifdef GOOS_aix
   543  	// AIX won't trigger a SIGSEGV if R11 = nil
   544  	// So it manually triggers it
   545  	CMP	R0, R11
   546  	BNE	2(PC)
   547  	MOVD	R0, 0(R0)
   548  #endif
   549  	MOVD	0(R11), R12
   550  	MOVD	R12, CTR
   551  	BR	(CTR)
   552  
   553  // Save state of caller into g->sched. Smashes R31.
   554  TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
   555  	MOVD	LR, R31
   556  	MOVD	R31, (g_sched+gobuf_pc)(g)
   557  	MOVD	R1, (g_sched+gobuf_sp)(g)
   558  	MOVD	R0, (g_sched+gobuf_lr)(g)
   559  	MOVD	R0, (g_sched+gobuf_ret)(g)
   560  	// Assert ctxt is zero. See func save.
   561  	MOVD	(g_sched+gobuf_ctxt)(g), R31
   562  	CMP	R0, R31
   563  	BEQ	2(PC)
   564  	BL	runtime·badctxt(SB)
   565  	RET
   566  
   567  #ifdef GOOS_aix
   568  #define asmcgocallSaveOffset cgoCalleeStackSize + 8
   569  #else
   570  #define asmcgocallSaveOffset cgoCalleeStackSize
   571  #endif
   572  
   573  // func asmcgocall(fn, arg unsafe.Pointer) int32
   574  // Call fn(arg) on the scheduler stack,
   575  // aligned appropriately for the gcc ABI.
   576  // See cgocall.go for more details.
   577  TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   578  	MOVD	fn+0(FP), R3
   579  	MOVD	arg+8(FP), R4
   580  
   581  	MOVD	R1, R7		// save original stack pointer
   582  	MOVD	g, R5
   583  
   584  	// Figure out if we need to switch to m->g0 stack.
   585  	// We get called to create new OS threads too, and those
   586  	// come in on the m->g0 stack already.
   587  	// Moreover, if it's called inside the signal handler, it must not switch
   588  	// to g0 as it can be in use by another syscall.
   589  	MOVD	g_m(g), R8
   590  	MOVD	m_gsignal(R8), R6
   591  	CMP	R6, g
   592  	BEQ	g0
   593  	MOVD	m_g0(R8), R6
   594  	CMP	R6, g
   595  	BEQ	g0
   596  	BL	gosave<>(SB)
   597  	MOVD	R6, g
   598  	BL	runtime·save_g(SB)
   599  	MOVD	(g_sched+gobuf_sp)(g), R1
   600  
   601  	// Now on a scheduling stack (a pthread-created stack).
   602  g0:
   603  #ifdef GOOS_aix
   604  	// Create a fake LR to improve backtrace.
   605  	MOVD	$runtime·asmcgocall(SB), R6
   606  	MOVD	R6, 16(R1)
   607  	// AIX also save one argument on the stack.
   608  	SUB $8, R1
   609  #endif
   610  	// Save room for two of our pointers, plus the callee
   611  	// save area that lives on the caller stack.
   612  	SUB	$(asmcgocallSaveOffset+16), R1
   613  	RLDCR	$0, R1, $~15, R1	// 16-byte alignment for gcc ABI
   614  	MOVD	R5, (asmcgocallSaveOffset+8)(R1)// save old g on stack
   615  	MOVD	(g_stack+stack_hi)(R5), R5
   616  	SUB	R7, R5
   617  	MOVD	R5, asmcgocallSaveOffset(R1)    // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   618  #ifdef GOOS_aix
   619  	MOVD	R7, 0(R1)	// Save frame pointer to allow manual backtrace with gdb
   620  #else
   621  	MOVD	R0, 0(R1)	// clear back chain pointer (TODO can we give it real back trace information?)
   622  #endif
   623  	// This is a "global call", so put the global entry point in r12
   624  	MOVD	R3, R12
   625  
   626  #ifdef GOARCH_ppc64
   627  	// ppc64 use elf ABI v1. we must get the real entry address from
   628  	// first slot of the function descriptor before call.
   629  	// Same for AIX.
   630  	MOVD	8(R12), R2
   631  	MOVD	(R12), R12
   632  #endif
   633  	MOVD	R12, CTR
   634  	MOVD	R4, R3		// arg in r3
   635  	BL	(CTR)
   636  	// C code can clobber R0, so set it back to 0. F27-F31 are
   637  	// callee save, so we don't need to recover those.
   638  	XOR	R0, R0
   639  	// Restore g, stack pointer, toc pointer.
   640  	// R3 is errno, so don't touch it
   641  	MOVD	(asmcgocallSaveOffset+8)(R1), g
   642  	MOVD	(g_stack+stack_hi)(g), R5
   643  	MOVD	asmcgocallSaveOffset(R1), R6
   644  	SUB	R6, R5
   645  #ifndef GOOS_aix
   646  	MOVD	24(R5), R2
   647  #endif
   648  	MOVD	R5, R1
   649  	BL	runtime·save_g(SB)
   650  
   651  	MOVW	R3, ret+16(FP)
   652  	RET
   653  
   654  // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   655  // See cgocall.go for more details.
   656  TEXT ·cgocallback(SB),NOSPLIT,$24-24
   657  	NO_LOCAL_POINTERS
   658  
   659  	// Load m and g from thread-local storage.
   660  	MOVBZ	runtime·iscgo(SB), R3
   661  	CMP	R3, $0
   662  	BEQ	nocgo
   663  	BL	runtime·load_g(SB)
   664  nocgo:
   665  
   666  	// If g is nil, Go did not create the current thread.
   667  	// Call needm to obtain one for temporary use.
   668  	// In this case, we're running on the thread stack, so there's
   669  	// lots of space, but the linker doesn't know. Hide the call from
   670  	// the linker analysis by using an indirect call.
   671  	CMP	g, $0
   672  	BEQ	needm
   673  
   674  	MOVD	g_m(g), R8
   675  	MOVD	R8, savedm-8(SP)
   676  	BR	havem
   677  
   678  needm:
   679  	MOVD	g, savedm-8(SP) // g is zero, so is m.
   680  	MOVD	$runtime·needm(SB), R12
   681  	MOVD	R12, CTR
   682  	BL	(CTR)
   683  
   684  	// Set m->sched.sp = SP, so that if a panic happens
   685  	// during the function we are about to execute, it will
   686  	// have a valid SP to run on the g0 stack.
   687  	// The next few lines (after the havem label)
   688  	// will save this SP onto the stack and then write
   689  	// the same SP back to m->sched.sp. That seems redundant,
   690  	// but if an unrecovered panic happens, unwindm will
   691  	// restore the g->sched.sp from the stack location
   692  	// and then systemstack will try to use it. If we don't set it here,
   693  	// that restored SP will be uninitialized (typically 0) and
   694  	// will not be usable.
   695  	MOVD	g_m(g), R8
   696  	MOVD	m_g0(R8), R3
   697  	MOVD	R1, (g_sched+gobuf_sp)(R3)
   698  
   699  havem:
   700  	// Now there's a valid m, and we're running on its m->g0.
   701  	// Save current m->g0->sched.sp on stack and then set it to SP.
   702  	// Save current sp in m->g0->sched.sp in preparation for
   703  	// switch back to m->curg stack.
   704  	// NOTE: unwindm knows that the saved g->sched.sp is at 8(R1) aka savedsp-16(SP).
   705  	MOVD	m_g0(R8), R3
   706  	MOVD	(g_sched+gobuf_sp)(R3), R4
   707  	MOVD	R4, savedsp-24(SP)      // must match frame size
   708  	MOVD	R1, (g_sched+gobuf_sp)(R3)
   709  
   710  	// Switch to m->curg stack and call runtime.cgocallbackg.
   711  	// Because we are taking over the execution of m->curg
   712  	// but *not* resuming what had been running, we need to
   713  	// save that information (m->curg->sched) so we can restore it.
   714  	// We can restore m->curg->sched.sp easily, because calling
   715  	// runtime.cgocallbackg leaves SP unchanged upon return.
   716  	// To save m->curg->sched.pc, we push it onto the curg stack and
   717  	// open a frame the same size as cgocallback's g0 frame.
   718  	// Once we switch to the curg stack, the pushed PC will appear
   719  	// to be the return PC of cgocallback, so that the traceback
   720  	// will seamlessly trace back into the earlier calls.
   721  	MOVD	m_curg(R8), g
   722  	BL	runtime·save_g(SB)
   723  	MOVD	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
   724  	MOVD	(g_sched+gobuf_pc)(g), R5
   725  	MOVD	R5, -(24+FIXED_FRAME)(R4)       // "saved LR"; must match frame size
   726  	// Gather our arguments into registers.
   727  	MOVD	fn+0(FP), R5
   728  	MOVD	frame+8(FP), R6
   729  	MOVD	ctxt+16(FP), R7
   730  	MOVD	$-(24+FIXED_FRAME)(R4), R1      // switch stack; must match frame size
   731  	MOVD    R5, FIXED_FRAME+0(R1)
   732  	MOVD    R6, FIXED_FRAME+8(R1)
   733  	MOVD    R7, FIXED_FRAME+16(R1)
   734  	BL	runtime·cgocallbackg(SB)
   735  
   736  	// Restore g->sched (== m->curg->sched) from saved values.
   737  	MOVD	0(R1), R5
   738  	MOVD	R5, (g_sched+gobuf_pc)(g)
   739  	MOVD	$(24+FIXED_FRAME)(R1), R4       // must match frame size
   740  	MOVD	R4, (g_sched+gobuf_sp)(g)
   741  
   742  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   743  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   744  	// so we do not have to restore it.)
   745  	MOVD	g_m(g), R8
   746  	MOVD	m_g0(R8), g
   747  	BL	runtime·save_g(SB)
   748  	MOVD	(g_sched+gobuf_sp)(g), R1
   749  	MOVD	savedsp-24(SP), R4      // must match frame size
   750  	MOVD	R4, (g_sched+gobuf_sp)(g)
   751  
   752  	// If the m on entry was nil, we called needm above to borrow an m
   753  	// for the duration of the call. Since the call is over, return it with dropm.
   754  	MOVD	savedm-8(SP), R6
   755  	CMP	R6, $0
   756  	BNE	droppedm
   757  	MOVD	$runtime·dropm(SB), R12
   758  	MOVD	R12, CTR
   759  	BL	(CTR)
   760  droppedm:
   761  
   762  	// Done!
   763  	RET
   764  
   765  // void setg(G*); set g. for use by needm.
   766  TEXT runtime·setg(SB), NOSPLIT, $0-8
   767  	MOVD	gg+0(FP), g
   768  	// This only happens if iscgo, so jump straight to save_g
   769  	BL	runtime·save_g(SB)
   770  	RET
   771  
   772  #ifdef GOARCH_ppc64
   773  #ifdef GOOS_aix
   774  DATA    setg_gcc<>+0(SB)/8, $_setg_gcc<>(SB)
   775  DATA    setg_gcc<>+8(SB)/8, $TOC(SB)
   776  DATA    setg_gcc<>+16(SB)/8, $0
   777  GLOBL   setg_gcc<>(SB), NOPTR, $24
   778  #else
   779  TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
   780  	DWORD	$_setg_gcc<>(SB)
   781  	DWORD	$0
   782  	DWORD	$0
   783  #endif
   784  #endif
   785  
   786  // void setg_gcc(G*); set g in C TLS.
   787  // Must obey the gcc calling convention.
   788  #ifdef GOARCH_ppc64le
   789  TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
   790  #else
   791  TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
   792  #endif
   793  	// The standard prologue clobbers R31, which is callee-save in
   794  	// the C ABI, so we have to use $-8-0 and save LR ourselves.
   795  	MOVD	LR, R4
   796  	// Also save g and R31, since they're callee-save in C ABI
   797  	MOVD	R31, R5
   798  	MOVD	g, R6
   799  
   800  	MOVD	R3, g
   801  	BL	runtime·save_g(SB)
   802  
   803  	MOVD	R6, g
   804  	MOVD	R5, R31
   805  	MOVD	R4, LR
   806  	RET
   807  
   808  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   809  	MOVW	(R0), R0
   810  	UNDEF
   811  
   812  #define	TBR	268
   813  
   814  // int64 runtime·cputicks(void)
   815  TEXT runtime·cputicks(SB),NOSPLIT,$0-8
   816  	MOVD	SPR(TBR), R3
   817  	MOVD	R3, ret+0(FP)
   818  	RET
   819  
   820  // AES hashing not implemented for ppc64
   821  TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
   822  	JMP	runtime·memhashFallback(SB)
   823  TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
   824  	JMP	runtime·strhashFallback(SB)
   825  TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
   826  	JMP	runtime·memhash32Fallback(SB)
   827  TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
   828  	JMP	runtime·memhash64Fallback(SB)
   829  
   830  TEXT runtime·return0(SB), NOSPLIT, $0
   831  	MOVW	$0, R3
   832  	RET
   833  
   834  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   835  // Must obey the gcc calling convention.
   836  #ifdef GOOS_aix
   837  // On AIX, _cgo_topofstack is defined in runtime/cgo, because it must
   838  // be a longcall in order to prevent trampolines from ld.
   839  TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
   840  #else
   841  TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
   842  #endif
   843  	// g (R30) and R31 are callee-save in the C ABI, so save them
   844  	MOVD	g, R4
   845  	MOVD	R31, R5
   846  	MOVD	LR, R6
   847  
   848  	BL	runtime·load_g(SB)	// clobbers g (R30), R31
   849  	MOVD	g_m(g), R3
   850  	MOVD	m_curg(R3), R3
   851  	MOVD	(g_stack+stack_hi)(R3), R3
   852  
   853  	MOVD	R4, g
   854  	MOVD	R5, R31
   855  	MOVD	R6, LR
   856  	RET
   857  
   858  // The top-most function running on a goroutine
   859  // returns to goexit+PCQuantum.
   860  //
   861  // When dynamically linking Go, it can be returned to from a function
   862  // implemented in a different module and so needs to reload the TOC pointer
   863  // from the stack (although this function declares that it does not set up x-a
   864  // frame, newproc1 does in fact allocate one for goexit and saves the TOC
   865  // pointer in the correct place).
   866  // goexit+_PCQuantum is halfway through the usual global entry point prologue
   867  // that derives r2 from r12 which is a bit silly, but not harmful.
   868  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   869  	MOVD	24(R1), R2
   870  	BL	runtime·goexit1(SB)	// does not return
   871  	// traceback from goexit1 must hit code range of goexit
   872  	MOVD	R0, R0	// NOP
   873  
   874  // prepGoExitFrame saves the current TOC pointer (i.e. the TOC pointer for the
   875  // module containing runtime) to the frame that goexit will execute in when
   876  // the goroutine exits. It's implemented in assembly mainly because that's the
   877  // easiest way to get access to R2.
   878  TEXT runtime·prepGoExitFrame(SB),NOSPLIT,$0-8
   879  	MOVD    sp+0(FP), R3
   880  	MOVD    R2, 24(R3)
   881  	RET
   882  
   883  TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0
   884  	ADD	$-8, R1
   885  	MOVD	R31, 0(R1)
   886  	MOVD	runtime·lastmoduledatap(SB), R4
   887  	MOVD	R3, moduledata_next(R4)
   888  	MOVD	R3, runtime·lastmoduledatap(SB)
   889  	MOVD	0(R1), R31
   890  	ADD	$8, R1
   891  	RET
   892  
   893  TEXT ·checkASM(SB),NOSPLIT,$0-1
   894  	MOVW	$1, R3
   895  	MOVB	R3, ret+0(FP)
   896  	RET
   897  
   898  // gcWriteBarrier performs a heap pointer write and informs the GC.
   899  //
   900  // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
   901  // - R20 is the destination of the write
   902  // - R21 is the value being written at R20.
   903  // It clobbers condition codes.
   904  // It does not clobber R0 through R17 (except special registers),
   905  // but may clobber any other register, *including* R31.
   906  TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$112
   907  	// The standard prologue clobbers R31.
   908  	// We use R18 and R19 as scratch registers.
   909  	MOVD	g_m(g), R18
   910  	MOVD	m_p(R18), R18
   911  	MOVD	(p_wbBuf+wbBuf_next)(R18), R19
   912  	// Increment wbBuf.next position.
   913  	ADD	$16, R19
   914  	MOVD	R19, (p_wbBuf+wbBuf_next)(R18)
   915  	MOVD	(p_wbBuf+wbBuf_end)(R18), R18
   916  	CMP	R18, R19
   917  	// Record the write.
   918  	MOVD	R21, -16(R19)	// Record value
   919  	MOVD	(R20), R18	// TODO: This turns bad writes into bad reads.
   920  	MOVD	R18, -8(R19)	// Record *slot
   921  	// Is the buffer full? (flags set in CMP above)
   922  	BEQ	flush
   923  ret:
   924  	// Do the write.
   925  	MOVD	R21, (R20)
   926  	RET
   927  
   928  flush:
   929  	// Save registers R0 through R15 since these were not saved by the caller.
   930  	// We don't save all registers on ppc64 because it takes too much space.
   931  	MOVD	R20, (FIXED_FRAME+0)(R1)	// Also first argument to wbBufFlush
   932  	MOVD	R21, (FIXED_FRAME+8)(R1)	// Also second argument to wbBufFlush
   933  	// R0 is always 0, so no need to spill.
   934  	// R1 is SP.
   935  	// R2 is SB.
   936  	MOVD	R3, (FIXED_FRAME+16)(R1)
   937  	MOVD	R4, (FIXED_FRAME+24)(R1)
   938  	MOVD	R5, (FIXED_FRAME+32)(R1)
   939  	MOVD	R6, (FIXED_FRAME+40)(R1)
   940  	MOVD	R7, (FIXED_FRAME+48)(R1)
   941  	MOVD	R8, (FIXED_FRAME+56)(R1)
   942  	MOVD	R9, (FIXED_FRAME+64)(R1)
   943  	MOVD	R10, (FIXED_FRAME+72)(R1)
   944  	// R11, R12 may be clobbered by external-linker-inserted trampoline
   945  	// R13 is REGTLS
   946  	MOVD	R14, (FIXED_FRAME+80)(R1)
   947  	MOVD	R15, (FIXED_FRAME+88)(R1)
   948  	MOVD	R16, (FIXED_FRAME+96)(R1)
   949  	MOVD	R17, (FIXED_FRAME+104)(R1)
   950  
   951  	// This takes arguments R20 and R21.
   952  	CALL	runtime·wbBufFlush(SB)
   953  
   954  	MOVD	(FIXED_FRAME+0)(R1), R20
   955  	MOVD	(FIXED_FRAME+8)(R1), R21
   956  	MOVD	(FIXED_FRAME+16)(R1), R3
   957  	MOVD	(FIXED_FRAME+24)(R1), R4
   958  	MOVD	(FIXED_FRAME+32)(R1), R5
   959  	MOVD	(FIXED_FRAME+40)(R1), R6
   960  	MOVD	(FIXED_FRAME+48)(R1), R7
   961  	MOVD	(FIXED_FRAME+56)(R1), R8
   962  	MOVD	(FIXED_FRAME+64)(R1), R9
   963  	MOVD	(FIXED_FRAME+72)(R1), R10
   964  	MOVD	(FIXED_FRAME+80)(R1), R14
   965  	MOVD	(FIXED_FRAME+88)(R1), R15
   966  	MOVD	(FIXED_FRAME+96)(R1), R16
   967  	MOVD	(FIXED_FRAME+104)(R1), R17
   968  	JMP	ret
   969  
   970  // Note: these functions use a special calling convention to save generated code space.
   971  // Arguments are passed in registers, but the space for those arguments are allocated
   972  // in the caller's stack frame. These stubs write the args into that stack space and
   973  // then tail call to the corresponding runtime handler.
   974  // The tail call makes these stubs disappear in backtraces.
   975  TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
   976  	MOVD	R3, x+0(FP)
   977  	MOVD	R4, y+8(FP)
   978  	JMP	runtime·goPanicIndex(SB)
   979  TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
   980  	MOVD	R3, x+0(FP)
   981  	MOVD	R4, y+8(FP)
   982  	JMP	runtime·goPanicIndexU(SB)
   983  TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
   984  	MOVD	R4, x+0(FP)
   985  	MOVD	R5, y+8(FP)
   986  	JMP	runtime·goPanicSliceAlen(SB)
   987  TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
   988  	MOVD	R4, x+0(FP)
   989  	MOVD	R5, y+8(FP)
   990  	JMP	runtime·goPanicSliceAlenU(SB)
   991  TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
   992  	MOVD	R4, x+0(FP)
   993  	MOVD	R5, y+8(FP)
   994  	JMP	runtime·goPanicSliceAcap(SB)
   995  TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
   996  	MOVD	R4, x+0(FP)
   997  	MOVD	R5, y+8(FP)
   998  	JMP	runtime·goPanicSliceAcapU(SB)
   999  TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
  1000  	MOVD	R3, x+0(FP)
  1001  	MOVD	R4, y+8(FP)
  1002  	JMP	runtime·goPanicSliceB(SB)
  1003  TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
  1004  	MOVD	R3, x+0(FP)
  1005  	MOVD	R4, y+8(FP)
  1006  	JMP	runtime·goPanicSliceBU(SB)
  1007  TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
  1008  	MOVD	R5, x+0(FP)
  1009  	MOVD	R6, y+8(FP)
  1010  	JMP	runtime·goPanicSlice3Alen(SB)
  1011  TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
  1012  	MOVD	R5, x+0(FP)
  1013  	MOVD	R6, y+8(FP)
  1014  	JMP	runtime·goPanicSlice3AlenU(SB)
  1015  TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
  1016  	MOVD	R5, x+0(FP)
  1017  	MOVD	R6, y+8(FP)
  1018  	JMP	runtime·goPanicSlice3Acap(SB)
  1019  TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
  1020  	MOVD	R5, x+0(FP)
  1021  	MOVD	R6, y+8(FP)
  1022  	JMP	runtime·goPanicSlice3AcapU(SB)
  1023  TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
  1024  	MOVD	R4, x+0(FP)
  1025  	MOVD	R5, y+8(FP)
  1026  	JMP	runtime·goPanicSlice3B(SB)
  1027  TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
  1028  	MOVD	R4, x+0(FP)
  1029  	MOVD	R5, y+8(FP)
  1030  	JMP	runtime·goPanicSlice3BU(SB)
  1031  TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
  1032  	MOVD	R3, x+0(FP)
  1033  	MOVD	R4, y+8(FP)
  1034  	JMP	runtime·goPanicSlice3C(SB)
  1035  TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
  1036  	MOVD	R3, x+0(FP)
  1037  	MOVD	R4, y+8(FP)
  1038  	JMP	runtime·goPanicSlice3CU(SB)