Text file src/runtime/asm_ppc64x.s

     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  //go: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  #include "cgo/abi_ppc64x.h"
    13  
    14  // This is called using the host ABI. argc and argv arguments
    15  // should be in R3 and R4 respectively.
    16  TEXT _rt0_ppc64x_lib(SB),NOSPLIT|NOFRAME,$0
    17  	// Start with standard C stack frame layout and linkage, allocate
    18  	// 16 bytes of argument space, save callee-save regs, and set R0 to $0.
    19  	// Allocate an extra 16 bytes to account for the larger fixed frame size
    20  	// of aix/elfv1 (48 vs 32) to ensure 16 bytes of parameter save space.
    21  	STACK_AND_SAVE_HOST_TO_GO_ABI(32)
    22  	// The above will not preserve R2 (TOC). Save it in case Go is
    23  	// compiled without a TOC pointer (e.g -buildmode=default).
    24  	MOVD	R2, 24(R1)
    25  
    26  	MOVD	R3, _rt0_ppc64x_lib_argc<>(SB)
    27  	MOVD	R4, _rt0_ppc64x_lib_argv<>(SB)
    28  
    29  	// Synchronous initialization.
    30  	MOVD	$runtime·reginit(SB), R12
    31  	MOVD	R12, CTR
    32  	BL	(CTR)
    33  
    34  	// Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go
    35  	MOVD	R0, g
    36  
    37  #ifdef GOOS_aix
    38  	// See runtime/cgo/gcc_aix_ppc64.c
    39  	MOVBZ	runtime·isarchive(SB), R3	// Check buildmode = c-archive
    40  	CMP		$0, R3
    41  	BEQ		skipInit
    42  #endif
    43  
    44  	MOVD	$runtime·libInit(SB), R12
    45  	MOVD	R12, CTR
    46  	BL	(CTR)
    47  
    48  skipInit:
    49  	// Restore and return to ELFv2 caller.
    50  	UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
    51  	RET
    52  
    53  TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0
    54  	MOVD	_rt0_ppc64x_lib_argc<>(SB), R3
    55  	MOVD	_rt0_ppc64x_lib_argv<>(SB), R4
    56  	MOVD	$runtime·rt0_go(SB), R12
    57  	MOVD	R12, CTR
    58  	BR	(CTR)
    59  
    60  DATA _rt0_ppc64x_lib_argc<>(SB)/8, $0
    61  GLOBL _rt0_ppc64x_lib_argc<>(SB),NOPTR, $8
    62  DATA _rt0_ppc64x_lib_argv<>(SB)/8, $0
    63  GLOBL _rt0_ppc64x_lib_argv<>(SB),NOPTR, $8
    64  
    65  
    66  #ifdef GOOS_aix
    67  #define cgoCalleeStackSize 48
    68  #else
    69  #define cgoCalleeStackSize 32
    70  #endif
    71  
    72  TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
    73  	// R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer
    74  
    75  	// initialize essential registers
    76  	BL	runtime·reginit(SB)
    77  
    78  	SUB	$(FIXED_FRAME+16), R1
    79  	MOVD	R2, 24(R1)		// stash the TOC pointer away again now we've created a new frame
    80  	MOVW	R3, FIXED_FRAME+0(R1)	// argc
    81  	MOVD	R4, FIXED_FRAME+8(R1)	// argv
    82  
    83  	// create istack out of the given (operating system) stack.
    84  	// _cgo_init may update stackguard.
    85  	MOVD	$runtime·g0(SB), g
    86  	BL	runtime·save_g(SB)
    87  	MOVD	$(-64*1024), R31
    88  	ADD	R31, R1, R3
    89  	MOVD	R3, g_stackguard0(g)
    90  	MOVD	R3, g_stackguard1(g)
    91  	MOVD	R3, (g_stack+stack_lo)(g)
    92  	MOVD	R1, (g_stack+stack_hi)(g)
    93  
    94  	// If there is a _cgo_init, call it using the gcc ABI.
    95  	MOVD	_cgo_init(SB), R12
    96  	CMP	R12, $0
    97  	BEQ	nocgo
    98  
    99  #ifdef GO_PPC64X_HAS_FUNCDESC
   100  	// Load the real entry address from the first slot of the function descriptor.
   101  	MOVD	8(R12), R2
   102  	MOVD	(R12), R12
   103  #endif
   104  	MOVD	R12, CTR		// r12 = "global function entry point"
   105  	MOVD	R13, R5			// arg 2: TLS base pointer
   106  	MOVD	$setg_gcc<>(SB), R4 	// arg 1: setg
   107  	MOVD	g, R3			// arg 0: G
   108  	// C functions expect 32 (48 for AIX) bytes of space on caller
   109  	// stack frame and a 16-byte aligned R1
   110  	MOVD	R1, R14			// save current stack
   111  	SUB	$cgoCalleeStackSize, R1	// reserve the callee area
   112  	RLDCR	$0, R1, $~15, R1	// 16-byte align
   113  	BL	(CTR)			// may clobber R0, R3-R12
   114  	MOVD	R14, R1			// restore stack
   115  #ifndef GOOS_aix
   116  	MOVD	24(R1), R2
   117  #endif
   118  	XOR	R0, R0			// fix R0
   119  
   120  nocgo:
   121  	// update stackguard after _cgo_init
   122  	MOVD	(g_stack+stack_lo)(g), R3
   123  	ADD	$const_stackGuard, R3
   124  	MOVD	R3, g_stackguard0(g)
   125  	MOVD	R3, g_stackguard1(g)
   126  
   127  	// set the per-goroutine and per-mach "registers"
   128  	MOVD	$runtime·m0(SB), R3
   129  
   130  	// save m->g0 = g0
   131  	MOVD	g, m_g0(R3)
   132  	// save m0 to g0->m
   133  	MOVD	R3, g_m(g)
   134  
   135  	BL	runtime·check(SB)
   136  
   137  	// args are already prepared
   138  	BL	runtime·args(SB)
   139  	BL	runtime·osinit(SB)
   140  	BL	runtime·schedinit(SB)
   141  
   142  	// create a new goroutine to start program
   143  	MOVD	$runtime·mainPC(SB), R3		// entry
   144  	MOVDU	R3, -8(R1)
   145  	MOVDU	R0, -8(R1)
   146  	MOVDU	R0, -8(R1)
   147  	MOVDU	R0, -8(R1)
   148  	MOVDU	R0, -8(R1)
   149  	BL	runtime·newproc(SB)
   150  	ADD	$(8+FIXED_FRAME), R1
   151  
   152  	// start this M
   153  	BL	runtime·mstart(SB)
   154  	// Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
   155  	// intended to be called by debuggers.
   156  #ifdef GOOS_linux
   157  	MOVD	$runtime·debugPinnerV1<ABIInternal>(SB), R31
   158  	MOVD	$runtime·debugCallV2<ABIInternal>(SB), R31
   159  #endif
   160  	MOVD	R0, 0(R0)
   161  	RET
   162  
   163  DATA	runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
   164  GLOBL	runtime·mainPC(SB),RODATA,$8
   165  
   166  TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
   167  	TW	$31, R0, R0
   168  	RET
   169  
   170  TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
   171  	RET
   172  
   173  // Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall1
   174  TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
   175  	// crosscall1 and crosscall2 need to reginit, but can't
   176  	// get at the 'runtime.reginit' symbol.
   177  	BR	runtime·reginit(SB)
   178  
   179  TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0
   180  	// set R0 to zero, it's expected by the toolchain
   181  	XOR R0, R0
   182  	RET
   183  
   184  TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
   185  	BL	runtime·mstart0(SB)
   186  	RET // not reached
   187  
   188  /*
   189   *  go-routine
   190   */
   191  
   192  // void gogo(Gobuf*)
   193  // restore state from Gobuf; longjmp
   194  TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
   195  	MOVD	buf+0(FP), R5
   196  	MOVD	gobuf_g(R5), R6
   197  	MOVD	0(R6), R4	// make sure g != nil
   198  	BR	gogo<>(SB)
   199  
   200  TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
   201  	MOVD	R6, g
   202  	BL	runtime·save_g(SB)
   203  
   204  	MOVD	gobuf_sp(R5), R1
   205  	MOVD	gobuf_lr(R5), R31
   206  #ifndef GOOS_aix
   207  	MOVD	24(R1), R2	// restore R2
   208  #endif
   209  	MOVD	R31, LR
   210  	MOVD	gobuf_ctxt(R5), R11
   211  	MOVD	R0, gobuf_sp(R5)
   212  	MOVD	R0, gobuf_lr(R5)
   213  	MOVD	R0, gobuf_ctxt(R5)
   214  	CMP	R0, R0 // set condition codes for == test, needed by stack split
   215  	MOVD	gobuf_pc(R5), R12
   216  	MOVD	R12, CTR
   217  	BR	(CTR)
   218  
   219  // void mcall(fn func(*g))
   220  // Switch to m->g0's stack, call fn(g).
   221  // Fn must never return. It should gogo(&g->sched)
   222  // to keep running g.
   223  TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
   224  	// Save caller state in g->sched
   225  	// R11 should be safe across save_g??
   226  	MOVD	R3, R11
   227  	MOVD	R1, (g_sched+gobuf_sp)(g)
   228  	MOVD	LR, R31
   229  	MOVD	R31, (g_sched+gobuf_pc)(g)
   230  	MOVD	R0, (g_sched+gobuf_lr)(g)
   231  
   232  	// Switch to m->g0 & its stack, call fn.
   233  	MOVD	g, R3
   234  	MOVD	g_m(g), R8
   235  	MOVD	m_g0(R8), g
   236  	BL	runtime·save_g(SB)
   237  	CMP	g, R3
   238  	BNE	2(PC)
   239  	BR	runtime·badmcall(SB)
   240  	MOVD	0(R11), R12			// code pointer
   241  	MOVD	R12, CTR
   242  	MOVD	(g_sched+gobuf_sp)(g), R1	// sp = m->g0->sched.sp
   243  	// Don't need to do anything special for regabiargs here
   244  	// R3 is g; stack is set anyway
   245  	MOVDU	R3, -8(R1)
   246  	MOVDU	R0, -8(R1)
   247  	MOVDU	R0, -8(R1)
   248  	MOVDU	R0, -8(R1)
   249  	MOVDU	R0, -8(R1)
   250  	BL	(CTR)
   251  	MOVD	24(R1), R2
   252  	BR	runtime·badmcall2(SB)
   253  
   254  // systemstack_switch is a dummy routine that systemstack leaves at the bottom
   255  // of the G stack. We need to distinguish the routine that
   256  // lives at the bottom of the G stack from the one that lives
   257  // at the top of the system stack because the one at the top of
   258  // the system stack terminates the stack walk (see topofstack()).
   259  TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   260  	// We have several undefs here so that 16 bytes past
   261  	// $runtime·systemstack_switch lies within them whether or not the
   262  	// instructions that derive r2 from r12 are there.
   263  	UNDEF
   264  	UNDEF
   265  	UNDEF
   266  	BL	(LR)	// make sure this function is not leaf
   267  	RET
   268  
   269  // func systemstack(fn func())
   270  TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   271  	MOVD	fn+0(FP), R3	// R3 = fn
   272  	MOVD	R3, R11		// context
   273  	MOVD	g_m(g), R4	// R4 = m
   274  
   275  	MOVD	m_gsignal(R4), R5	// R5 = gsignal
   276  	CMP	g, R5
   277  	BEQ	noswitch
   278  
   279  	MOVD	m_g0(R4), R5	// R5 = g0
   280  	CMP	g, R5
   281  	BEQ	noswitch
   282  
   283  	MOVD	m_curg(R4), R6
   284  	CMP	g, R6
   285  	BEQ	switch
   286  
   287  	// Bad: g is not gsignal, not g0, not curg. What is it?
   288  	// Hide call from linker nosplit analysis.
   289  	MOVD	$runtime·badsystemstack(SB), R12
   290  	MOVD	R12, CTR
   291  	BL	(CTR)
   292  	BL	runtime·abort(SB)
   293  
   294  switch:
   295  	// save our state in g->sched. Pretend to
   296  	// be systemstack_switch if the G stack is scanned.
   297  	BL	gosave_systemstack_switch<>(SB)
   298  
   299  	// switch to g0
   300  	MOVD	R5, g
   301  	BL	runtime·save_g(SB)
   302  	MOVD	(g_sched+gobuf_sp)(g), R1
   303  
   304  	// call target function
   305  	MOVD	0(R11), R12	// code pointer
   306  	MOVD	R12, CTR
   307  	BL	(CTR)
   308  
   309  	// restore TOC pointer. It seems unlikely that we will use systemstack
   310  	// to call a function defined in another module, but the results of
   311  	// doing so would be so confusing that it's worth doing this.
   312  	MOVD	g_m(g), R3
   313  	MOVD	m_curg(R3), g
   314  	MOVD	(g_sched+gobuf_sp)(g), R3
   315  #ifndef GOOS_aix
   316  	MOVD	24(R3), R2
   317  #endif
   318  	// switch back to g
   319  	MOVD	g_m(g), R3
   320  	MOVD	m_curg(R3), g
   321  	BL	runtime·save_g(SB)
   322  	MOVD	(g_sched+gobuf_sp)(g), R1
   323  	MOVD	R0, (g_sched+gobuf_sp)(g)
   324  	RET
   325  
   326  noswitch:
   327  	// already on m stack, just call directly
   328  	// On other arches we do a tail call here, but it appears to be
   329  	// impossible to tail call a function pointer in shared mode on
   330  	// ppc64 because the caller is responsible for restoring the TOC.
   331  	MOVD	0(R11), R12	// code pointer
   332  	MOVD	R12, CTR
   333  	BL	(CTR)
   334  #ifndef GOOS_aix
   335  	MOVD	24(R1), R2
   336  #endif
   337  	RET
   338  
   339  // func switchToCrashStack0(fn func())
   340  TEXT runtime·switchToCrashStack0<ABIInternal>(SB), NOSPLIT, $0-8
   341  	MOVD	R3, R11				// context register
   342  	MOVD	g_m(g), R3			// curm
   343  
   344  	// set g to gcrash
   345  	MOVD	$runtime·gcrash(SB), g	// g = &gcrash
   346  	CALL	runtime·save_g(SB)	// clobbers R31
   347  	MOVD	R3, g_m(g)			// g.m = curm
   348  	MOVD	g, m_g0(R3)			// curm.g0 = g
   349  
   350  	// switch to crashstack
   351  	MOVD	(g_stack+stack_hi)(g), R3
   352  	SUB	$(4*8), R3
   353  	MOVD	R3, R1
   354  
   355  	// call target function
   356  	MOVD	0(R11), R12			// code pointer
   357  	MOVD	R12, CTR
   358  	BL	(CTR)
   359  
   360  	// should never return
   361  	CALL	runtime·abort(SB)
   362  	UNDEF
   363  
   364  /*
   365   * support for morestack
   366   */
   367  
   368  // Called during function prolog when more stack is needed.
   369  // Caller has already loaded:
   370  // R3: framesize, R4: argsize, R5: LR
   371  //
   372  // The traceback routines see morestack on a g0 as being
   373  // the top of a stack (for example, morestack calling newstack
   374  // calling the scheduler calling newm calling gc), so we must
   375  // record an argument size. For that purpose, it has no arguments.
   376  TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   377  	// Called from f.
   378  	// Set g->sched to context in f.
   379  	MOVD	R1, (g_sched+gobuf_sp)(g)
   380  	MOVD	LR, R8
   381  	MOVD	R8, (g_sched+gobuf_pc)(g)
   382  	MOVD	R5, (g_sched+gobuf_lr)(g)
   383  	MOVD	R11, (g_sched+gobuf_ctxt)(g)
   384  
   385  	// Cannot grow scheduler stack (m->g0).
   386  	MOVD	g_m(g), R7
   387  	MOVD	m_g0(R7), R8
   388  	CMP	g, R8
   389  	BNE	3(PC)
   390  	BL	runtime·badmorestackg0(SB)
   391  	BL	runtime·abort(SB)
   392  
   393  	// Cannot grow signal stack (m->gsignal).
   394  	MOVD	m_gsignal(R7), R8
   395  	CMP	g, R8
   396  	BNE	3(PC)
   397  	BL	runtime·badmorestackgsignal(SB)
   398  	BL	runtime·abort(SB)
   399  
   400  	// Called from f.
   401  	// Set m->morebuf to f's caller.
   402  	MOVD	R5, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   403  	MOVD	R1, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   404  	MOVD	g, (m_morebuf+gobuf_g)(R7)
   405  
   406  	// Call newstack on m->g0's stack.
   407  	MOVD	m_g0(R7), g
   408  	BL	runtime·save_g(SB)
   409  	MOVD	(g_sched+gobuf_sp)(g), R1
   410  	MOVDU   R0, -(FIXED_FRAME+0)(R1)	// create a call frame on g0
   411  	BL	runtime·newstack(SB)
   412  
   413  	// Not reached, but make sure the return PC from the call to newstack
   414  	// is still in this function, and not the beginning of the next.
   415  	UNDEF
   416  
   417  TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   418  	// Force SPWRITE. This function doesn't actually write SP,
   419  	// but it is called with a special calling convention where
   420  	// the caller doesn't save LR on stack but passes it as a
   421  	// register (R5), and the unwinder currently doesn't understand.
   422  	// Make it SPWRITE to stop unwinding. (See issue 54332)
   423  	// Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction
   424  	// has a special affect on Power8,9,10 by lowering the thread
   425  	// priority and causing a slowdown in execution time
   426  
   427  	OR	R0, R1
   428  	MOVD	R0, R11
   429  	BR	runtime·morestack(SB)
   430  
   431  // reflectcall: call a function with the given argument list
   432  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
   433  // we don't have variable-sized frames, so we use a small number
   434  // of constant-sized-frame functions to encode a few bits of size in the pc.
   435  // Caution: ugly multiline assembly macros in your future!
   436  
   437  #define DISPATCH(NAME,MAXSIZE)		\
   438  	MOVD	$MAXSIZE, R31;		\
   439  	CMP	R3, R31;		\
   440  	BGT	4(PC);			\
   441  	MOVD	$NAME(SB), R12;		\
   442  	MOVD	R12, CTR;		\
   443  	BR	(CTR)
   444  // Note: can't just "BR NAME(SB)" - bad inlining results.
   445  
   446  TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
   447  	MOVWZ	frameSize+32(FP), R3
   448  	DISPATCH(runtime·call16, 16)
   449  	DISPATCH(runtime·call32, 32)
   450  	DISPATCH(runtime·call64, 64)
   451  	DISPATCH(runtime·call128, 128)
   452  	DISPATCH(runtime·call256, 256)
   453  	DISPATCH(runtime·call512, 512)
   454  	DISPATCH(runtime·call1024, 1024)
   455  	DISPATCH(runtime·call2048, 2048)
   456  	DISPATCH(runtime·call4096, 4096)
   457  	DISPATCH(runtime·call8192, 8192)
   458  	DISPATCH(runtime·call16384, 16384)
   459  	DISPATCH(runtime·call32768, 32768)
   460  	DISPATCH(runtime·call65536, 65536)
   461  	DISPATCH(runtime·call131072, 131072)
   462  	DISPATCH(runtime·call262144, 262144)
   463  	DISPATCH(runtime·call524288, 524288)
   464  	DISPATCH(runtime·call1048576, 1048576)
   465  	DISPATCH(runtime·call2097152, 2097152)
   466  	DISPATCH(runtime·call4194304, 4194304)
   467  	DISPATCH(runtime·call8388608, 8388608)
   468  	DISPATCH(runtime·call16777216, 16777216)
   469  	DISPATCH(runtime·call33554432, 33554432)
   470  	DISPATCH(runtime·call67108864, 67108864)
   471  	DISPATCH(runtime·call134217728, 134217728)
   472  	DISPATCH(runtime·call268435456, 268435456)
   473  	DISPATCH(runtime·call536870912, 536870912)
   474  	DISPATCH(runtime·call1073741824, 1073741824)
   475  	MOVD	$runtime·badreflectcall(SB), R12
   476  	MOVD	R12, CTR
   477  	BR	(CTR)
   478  
   479  #define CALLFN(NAME,MAXSIZE)			\
   480  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   481  	NO_LOCAL_POINTERS;			\
   482  	/* copy arguments to stack */		\
   483  	MOVD	stackArgs+16(FP), R3;			\
   484  	MOVWZ	stackArgsSize+24(FP), R4;			\
   485  	MOVD    R1, R5;				\
   486  	CMP	R4, $8;				\
   487  	BLT	tailsetup;			\
   488  	/* copy 8 at a time if possible */	\
   489  	ADD	$(FIXED_FRAME-8), R5;			\
   490  	SUB	$8, R3;				\
   491  top: \
   492  	MOVDU	8(R3), R7;			\
   493  	MOVDU	R7, 8(R5);			\
   494  	SUB	$8, R4;				\
   495  	CMP	R4, $8;				\
   496  	BGE	top;				\
   497  	/* handle remaining bytes */	\
   498  	CMP	$0, R4;			\
   499  	BEQ	callfn;			\
   500  	ADD	$7, R3;			\
   501  	ADD	$7, R5;			\
   502  	BR	tail;			\
   503  tailsetup: \
   504  	CMP	$0, R4;			\
   505  	BEQ	callfn;			\
   506  	ADD     $(FIXED_FRAME-1), R5;	\
   507  	SUB     $1, R3;			\
   508  tail: \
   509  	MOVBU	1(R3), R6;		\
   510  	MOVBU	R6, 1(R5);		\
   511  	SUB	$1, R4;			\
   512  	CMP	$0, R4;			\
   513  	BGT	tail;			\
   514  callfn: \
   515  	/* call function */			\
   516  	MOVD	f+8(FP), R11;			\
   517  #ifdef GOOS_aix				\
   518  	/* AIX won't trigger a SIGSEGV if R11 = nil */	\
   519  	/* So it manually triggers it */	\
   520  	CMP	R11, $0				\
   521  	BNE	2(PC)				\
   522  	MOVD	R0, 0(R0)			\
   523  #endif						\
   524  	MOVD    regArgs+40(FP), R20;    \
   525  	BL      runtime·unspillArgs(SB);        \
   526  	MOVD	(R11), R12;			\
   527  	MOVD	R12, CTR;			\
   528  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   529  	BL	(CTR);				\
   530  #ifndef GOOS_aix				\
   531  	MOVD	24(R1), R2;			\
   532  #endif						\
   533  	/* copy return values back */		\
   534  	MOVD	regArgs+40(FP), R20;		\
   535  	BL	runtime·spillArgs(SB);			\
   536  	MOVD	stackArgsType+0(FP), R7;		\
   537  	MOVD	stackArgs+16(FP), R3;			\
   538  	MOVWZ	stackArgsSize+24(FP), R4;			\
   539  	MOVWZ	stackRetOffset+28(FP), R6;		\
   540  	ADD	$FIXED_FRAME, R1, R5;		\
   541  	ADD	R6, R5; 			\
   542  	ADD	R6, R3;				\
   543  	SUB	R6, R4;				\
   544  	BL	callRet<>(SB);			\
   545  	RET
   546  
   547  // callRet copies return values back at the end of call*. This is a
   548  // separate function so it can allocate stack space for the arguments
   549  // to reflectcallmove. It does not follow the Go ABI; it expects its
   550  // arguments in registers.
   551  TEXT callRet<>(SB), NOSPLIT, $40-0
   552  	NO_LOCAL_POINTERS
   553  	MOVD	R7, FIXED_FRAME+0(R1)
   554  	MOVD	R3, FIXED_FRAME+8(R1)
   555  	MOVD	R5, FIXED_FRAME+16(R1)
   556  	MOVD	R4, FIXED_FRAME+24(R1)
   557  	MOVD	R20, FIXED_FRAME+32(R1)
   558  	BL	runtime·reflectcallmove(SB)
   559  	RET
   560  
   561  CALLFN(·call16, 16)
   562  CALLFN(·call32, 32)
   563  CALLFN(·call64, 64)
   564  CALLFN(·call128, 128)
   565  CALLFN(·call256, 256)
   566  CALLFN(·call512, 512)
   567  CALLFN(·call1024, 1024)
   568  CALLFN(·call2048, 2048)
   569  CALLFN(·call4096, 4096)
   570  CALLFN(·call8192, 8192)
   571  CALLFN(·call16384, 16384)
   572  CALLFN(·call32768, 32768)
   573  CALLFN(·call65536, 65536)
   574  CALLFN(·call131072, 131072)
   575  CALLFN(·call262144, 262144)
   576  CALLFN(·call524288, 524288)
   577  CALLFN(·call1048576, 1048576)
   578  CALLFN(·call2097152, 2097152)
   579  CALLFN(·call4194304, 4194304)
   580  CALLFN(·call8388608, 8388608)
   581  CALLFN(·call16777216, 16777216)
   582  CALLFN(·call33554432, 33554432)
   583  CALLFN(·call67108864, 67108864)
   584  CALLFN(·call134217728, 134217728)
   585  CALLFN(·call268435456, 268435456)
   586  CALLFN(·call536870912, 536870912)
   587  CALLFN(·call1073741824, 1073741824)
   588  
   589  TEXT runtime·procyieldAsm(SB),NOSPLIT|NOFRAME,$0-4
   590  	MOVW	cycles+0(FP), R7
   591  	CMP	$0, R7
   592  	BEQ	done
   593  	// POWER does not have a pause/yield instruction equivalent.
   594  	// Instead, we can lower the program priority by setting the
   595  	// Program Priority Register prior to the wait loop and set it
   596  	// back to default afterwards. On Linux, the default priority is
   597  	// medium-low. For details, see page 837 of the ISA 3.0.
   598  	OR	R1, R1, R1	// Set PPR priority to low
   599  again:
   600  	SUB	$1, R7
   601  	CMP	$0, R7
   602  	BNE	again
   603  	OR	R6, R6, R6	// Set PPR priority back to medium-low
   604  done:
   605  	RET
   606  
   607  // Save state of caller into g->sched,
   608  // but using fake PC from systemstack_switch.
   609  // Must only be called from functions with no locals ($0)
   610  // or else unwinding from systemstack_switch is incorrect.
   611  // Smashes R31.
   612  TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
   613  	MOVD	$runtime·systemstack_switch(SB), R31
   614  	ADD     $16, R31 // get past prologue (including r2-setting instructions when they're there)
   615  	MOVD	R31, (g_sched+gobuf_pc)(g)
   616  	MOVD	R1, (g_sched+gobuf_sp)(g)
   617  	MOVD	R0, (g_sched+gobuf_lr)(g)
   618  	// Assert ctxt is zero. See func save.
   619  	MOVD	(g_sched+gobuf_ctxt)(g), R31
   620  	CMP	R31, $0
   621  	BEQ	2(PC)
   622  	BL	runtime·abort(SB)
   623  	RET
   624  
   625  #ifdef GOOS_aix
   626  #define asmcgocallSaveOffset cgoCalleeStackSize + 8
   627  #else
   628  #define asmcgocallSaveOffset cgoCalleeStackSize
   629  #endif
   630  
   631  // func asmcgocall_no_g(fn, arg unsafe.Pointer)
   632  // Call fn(arg) aligned appropriately for the gcc ABI.
   633  // Called on a system stack, and there may be no g yet (during needm).
   634  TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
   635  	MOVD	fn+0(FP), R3
   636  	MOVD	arg+8(FP), R4
   637  
   638  	MOVD	R1, R15
   639  	SUB	$(asmcgocallSaveOffset+8), R1
   640  	RLDCR	$0, R1, $~15, R1	// 16-byte alignment for gcc ABI
   641  	MOVD	R15, asmcgocallSaveOffset(R1)
   642  
   643  	MOVD	R0, 0(R1)	// clear back chain pointer (TODO can we give it real back trace information?)
   644  
   645  	// This is a "global call", so put the global entry point in r12
   646  	MOVD	R3, R12
   647  
   648  #ifdef GO_PPC64X_HAS_FUNCDESC
   649  	// Load the real entry address from the first slot of the function descriptor.
   650  	MOVD	8(R12), R2
   651  	MOVD	(R12), R12
   652  #endif
   653  	MOVD	R12, CTR
   654  	MOVD	R4, R3		// arg in r3
   655  	BL	(CTR)
   656  
   657  	// C code can clobber R0, so set it back to 0. F27-F31 are
   658  	// callee save, so we don't need to recover those.
   659  	XOR	R0, R0
   660  
   661  	MOVD	asmcgocallSaveOffset(R1), R1	// Restore stack pointer.
   662  #ifndef GOOS_aix
   663  	MOVD	24(R1), R2
   664  #endif
   665  
   666  	RET
   667  
   668  // func asmcgocall(fn, arg unsafe.Pointer) int32
   669  // Call fn(arg) on the scheduler stack,
   670  // aligned appropriately for the gcc ABI.
   671  // See cgocall.go for more details.
   672  TEXT ·asmcgocall<ABIInternal>(SB),NOSPLIT,$0-20
   673  	// R3 = fn
   674  	// R4 = arg
   675  
   676  	MOVD	R1, R7		// save original stack pointer
   677  	CMP	$0, g
   678  	BEQ	nosave
   679  	MOVD	g, R5
   680  
   681  	// Figure out if we need to switch to m->g0 stack.
   682  	// We get called to create new OS threads too, and those
   683  	// come in on the m->g0 stack already. Or we might already
   684  	// be on the m->gsignal stack.
   685  	MOVD	g_m(g), R8
   686  	MOVD	m_gsignal(R8), R6
   687  	CMP	R6, g
   688  	BEQ	nosave
   689  	MOVD	m_g0(R8), R6
   690  	CMP	R6, g
   691  	BEQ	nosave
   692  
   693  	BL	gosave_systemstack_switch<>(SB)
   694  	MOVD	R6, g
   695  	BL	runtime·save_g(SB)
   696  	MOVD	(g_sched+gobuf_sp)(g), R1
   697  
   698  	// Now on a scheduling stack (a pthread-created stack).
   699  #ifdef GOOS_aix
   700  	// Create a fake LR to improve backtrace.
   701  	MOVD	$runtime·asmcgocall(SB), R6
   702  	MOVD	R6, 16(R1)
   703  	// AIX also saves one argument on the stack.
   704  	SUB	$8, R1
   705  #endif
   706  	// Save room for two of our pointers, plus the callee
   707  	// save area that lives on the caller stack.
   708  	// Do arithmetics in R10 to hide from the assembler
   709  	// counting it as SP delta, which is irrelevant as we are
   710  	// on the system stack.
   711  	SUB	$(asmcgocallSaveOffset+16), R1, R10
   712  	RLDCR	$0, R10, $~15, R1	// 16-byte alignment for gcc ABI
   713  	MOVD	R5, (asmcgocallSaveOffset+8)(R1)	// save old g on stack
   714  	MOVD	(g_stack+stack_hi)(R5), R5
   715  	SUB	R7, R5
   716  	MOVD	R5, asmcgocallSaveOffset(R1)    // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   717  #ifdef GOOS_aix
   718  	MOVD	R7, 0(R1)	// Save frame pointer to allow manual backtrace with gdb
   719  #else
   720  	MOVD	R0, 0(R1)	// clear back chain pointer (TODO can we give it real back trace information?)
   721  #endif
   722  	// This is a "global call", so put the global entry point in r12
   723  	MOVD	R3, R12
   724  
   725  #ifdef GO_PPC64X_HAS_FUNCDESC
   726  	// Load the real entry address from the first slot of the function descriptor.
   727  	MOVD	8(R12), R2
   728  	MOVD	(R12), R12
   729  #endif
   730  	MOVD	R12, CTR
   731  	MOVD	R4, R3		// arg in r3
   732  	BL	(CTR)
   733  
   734  	// Reinitialise zero value register.
   735  	XOR	R0, R0
   736  
   737  	// Restore g, stack pointer, toc pointer.
   738  	// R3 is errno, so don't touch it
   739  	MOVD	(asmcgocallSaveOffset+8)(R1), g
   740  	MOVD	(g_stack+stack_hi)(g), R5
   741  	MOVD	asmcgocallSaveOffset(R1), R6
   742  	SUB	R6, R5
   743  #ifndef GOOS_aix
   744  	MOVD	24(R5), R2
   745  #endif
   746  	MOVD	R5, R1
   747  	BL	runtime·save_g(SB)
   748  
   749  	// ret = R3
   750  	RET
   751  
   752  nosave:
   753  	// Running on a system stack, perhaps even without a g.
   754  	// Having no g can happen during thread creation or thread teardown.
   755  	// This code is like the above sequence but without saving/restoring g
   756  	// and without worrying about the stack moving out from under us
   757  	// (because we're on a system stack, not a goroutine stack).
   758  
   759  	SUB	$(asmcgocallSaveOffset+8), R1, R10
   760  	RLDCR	$0, R10, $~15, R1		// 16-byte alignment for gcc ABI
   761  	MOVD	R7, asmcgocallSaveOffset(R1)	// Save original stack pointer.
   762  
   763  	MOVD	R3, R12		// fn
   764  #ifdef GO_PPC64X_HAS_FUNCDESC
   765  	// Load the real entry address from the first slot of the function descriptor.
   766  	MOVD	8(R12), R2
   767  	MOVD	(R12), R12
   768  #endif
   769  	MOVD	R12, CTR
   770  	MOVD	R4, R3		// arg
   771  	BL	(CTR)
   772  
   773  	// Reinitialise zero value register.
   774  	XOR	R0, R0
   775  
   776  	MOVD	asmcgocallSaveOffset(R1), R1	// Restore stack pointer.
   777  #ifndef GOOS_aix
   778  	MOVD	24(R1), R2
   779  #endif
   780  	// ret = R3
   781  	RET
   782  
   783  // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   784  // See cgocall.go for more details.
   785  TEXT ·cgocallback(SB),NOSPLIT,$24-24
   786  	NO_LOCAL_POINTERS
   787  
   788  	// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
   789  	// It is used to dropm while thread is exiting.
   790  	MOVD	fn+0(FP), R5
   791  	CMP	R5, $0
   792  	BNE	loadg
   793  	// Restore the g from frame.
   794  	MOVD	frame+8(FP), g
   795  	BR	dropm
   796  
   797  loadg:
   798  	// Load m and g from thread-local storage.
   799  #ifndef GOOS_openbsd
   800  	MOVBZ	runtime·iscgo(SB), R3
   801  	CMP	R3, $0
   802  	BEQ	nocgo
   803  #endif
   804  	BL	runtime·load_g(SB)
   805  nocgo:
   806  
   807  	// If g is nil, Go did not create the current thread,
   808  	// or if this thread never called into Go on pthread platforms.
   809  	// Call needm to obtain one for temporary use.
   810  	// In this case, we're running on the thread stack, so there's
   811  	// lots of space, but the linker doesn't know. Hide the call from
   812  	// the linker analysis by using an indirect call.
   813  	CMP	g, $0
   814  	BEQ	needm
   815  
   816  	MOVD	g_m(g), R8
   817  	MOVD	R8, savedm-8(SP)
   818  	BR	havem
   819  
   820  needm:
   821  	MOVD	g, savedm-8(SP) // g is zero, so is m.
   822  	MOVD	$runtime·needAndBindM(SB), R12
   823  	MOVD	R12, CTR
   824  	BL	(CTR)
   825  
   826  	// Set m->sched.sp = SP, so that if a panic happens
   827  	// during the function we are about to execute, it will
   828  	// have a valid SP to run on the g0 stack.
   829  	// The next few lines (after the havem label)
   830  	// will save this SP onto the stack and then write
   831  	// the same SP back to m->sched.sp. That seems redundant,
   832  	// but if an unrecovered panic happens, unwindm will
   833  	// restore the g->sched.sp from the stack location
   834  	// and then systemstack will try to use it. If we don't set it here,
   835  	// that restored SP will be uninitialized (typically 0) and
   836  	// will not be usable.
   837  	MOVD	g_m(g), R8
   838  	MOVD	m_g0(R8), R3
   839  	MOVD	R1, (g_sched+gobuf_sp)(R3)
   840  
   841  havem:
   842  	// Now there's a valid m, and we're running on its m->g0.
   843  	// Save current m->g0->sched.sp on stack and then set it to SP.
   844  	// Save current sp in m->g0->sched.sp in preparation for
   845  	// switch back to m->curg stack.
   846  	// NOTE: unwindm knows that the saved g->sched.sp is at 8(R1) aka savedsp-16(SP).
   847  	MOVD	m_g0(R8), R3
   848  	MOVD	(g_sched+gobuf_sp)(R3), R4
   849  	MOVD	R4, savedsp-24(SP)      // must match frame size
   850  	MOVD	R1, (g_sched+gobuf_sp)(R3)
   851  
   852  	// Switch to m->curg stack and call runtime.cgocallbackg.
   853  	// Because we are taking over the execution of m->curg
   854  	// but *not* resuming what had been running, we need to
   855  	// save that information (m->curg->sched) so we can restore it.
   856  	// We can restore m->curg->sched.sp easily, because calling
   857  	// runtime.cgocallbackg leaves SP unchanged upon return.
   858  	// To save m->curg->sched.pc, we push it onto the curg stack and
   859  	// open a frame the same size as cgocallback's g0 frame.
   860  	// Once we switch to the curg stack, the pushed PC will appear
   861  	// to be the return PC of cgocallback, so that the traceback
   862  	// will seamlessly trace back into the earlier calls.
   863  	MOVD	m_curg(R8), g
   864  	BL	runtime·save_g(SB)
   865  	MOVD	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
   866  	MOVD	(g_sched+gobuf_pc)(g), R5
   867  	MOVD	R5, -(24+FIXED_FRAME)(R4)       // "saved LR"; must match frame size
   868  	// Gather our arguments into registers.
   869  	MOVD	fn+0(FP), R5
   870  	MOVD	frame+8(FP), R6
   871  	MOVD	ctxt+16(FP), R7
   872  	MOVD	$-(24+FIXED_FRAME)(R4), R1      // switch stack; must match frame size
   873  	MOVD    R5, FIXED_FRAME+0(R1)
   874  	MOVD    R6, FIXED_FRAME+8(R1)
   875  	MOVD    R7, FIXED_FRAME+16(R1)
   876  
   877  	MOVD	$runtime·cgocallbackg(SB), R12
   878  	MOVD	R12, CTR
   879  	CALL	(CTR) // indirect call to bypass nosplit check. We're on a different stack now.
   880  
   881  	// Restore g->sched (== m->curg->sched) from saved values.
   882  	MOVD	0(R1), R5
   883  	MOVD	R5, (g_sched+gobuf_pc)(g)
   884  	MOVD	$(24+FIXED_FRAME)(R1), R4       // must match frame size
   885  	MOVD	R4, (g_sched+gobuf_sp)(g)
   886  
   887  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   888  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   889  	// so we do not have to restore it.)
   890  	MOVD	g_m(g), R8
   891  	MOVD	m_g0(R8), g
   892  	BL	runtime·save_g(SB)
   893  	MOVD	(g_sched+gobuf_sp)(g), R1
   894  	MOVD	savedsp-24(SP), R4      // must match frame size
   895  	MOVD	R4, (g_sched+gobuf_sp)(g)
   896  
   897  	// If the m on entry was nil, we called needm above to borrow an m,
   898  	// 1. for the duration of the call on non-pthread platforms,
   899  	// 2. or the duration of the C thread alive on pthread platforms.
   900  	// If the m on entry wasn't nil,
   901  	// 1. the thread might be a Go thread,
   902  	// 2. or it wasn't the first call from a C thread on pthread platforms,
   903  	//    since then we skip dropm to reuse the m in the first call.
   904  	MOVD	savedm-8(SP), R6
   905  	CMP	R6, $0
   906  	BNE	droppedm
   907  
   908  	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   909  	MOVD	_cgo_pthread_key_created(SB), R6
   910  	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   911  	CMP	R6, $0
   912  	BEQ	dropm
   913  	MOVD	(R6), R6
   914  	CMP	R6, $0
   915  	BNE	droppedm
   916  
   917  dropm:
   918  	MOVD	$runtime·dropm(SB), R12
   919  	MOVD	R12, CTR
   920  	BL	(CTR)
   921  droppedm:
   922  
   923  	// Done!
   924  	RET
   925  
   926  // void setg(G*); set g. for use by needm.
   927  TEXT runtime·setg(SB), NOSPLIT, $0-8
   928  	MOVD	gg+0(FP), g
   929  	// This only happens if iscgo, so jump straight to save_g
   930  	BL	runtime·save_g(SB)
   931  	RET
   932  
   933  #ifdef GO_PPC64X_HAS_FUNCDESC
   934  DEFINE_PPC64X_FUNCDESC(setg_gcc<>, _setg_gcc<>)
   935  TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
   936  #else
   937  TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0
   938  #endif
   939  	// The standard prologue clobbers R31, which is callee-save in
   940  	// the C ABI, so we have to use $-8-0 and save LR ourselves.
   941  	MOVD	LR, R4
   942  	// Also save g and R31, since they're callee-save in C ABI
   943  	MOVD	R31, R5
   944  	MOVD	g, R6
   945  
   946  	MOVD	R3, g
   947  	BL	runtime·save_g(SB)
   948  
   949  	MOVD	R6, g
   950  	MOVD	R5, R31
   951  	MOVD	R4, LR
   952  	RET
   953  
   954  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   955  	MOVW	(R0), R0
   956  	UNDEF
   957  
   958  #define	TBR	268
   959  
   960  // int64 runtime·cputicks(void)
   961  TEXT runtime·cputicks(SB),NOSPLIT,$0-8
   962  	MOVD	SPR(TBR), R3
   963  	MOVD	R3, ret+0(FP)
   964  	RET
   965  
   966  // spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
   967  TEXT runtime·spillArgs(SB),NOSPLIT,$0-0
   968  	MOVD    R3, 0(R20)
   969  	MOVD    R4, 8(R20)
   970  	MOVD    R5, 16(R20)
   971  	MOVD    R6, 24(R20)
   972  	MOVD    R7, 32(R20)
   973  	MOVD    R8, 40(R20)
   974  	MOVD    R9, 48(R20)
   975  	MOVD    R10, 56(R20)
   976  	MOVD	R14, 64(R20)
   977  	MOVD	R15, 72(R20)
   978  	MOVD	R16, 80(R20)
   979  	MOVD	R17, 88(R20)
   980  	FMOVD	F1, 96(R20)
   981  	FMOVD	F2, 104(R20)
   982  	FMOVD   F3, 112(R20)
   983  	FMOVD   F4, 120(R20)
   984  	FMOVD   F5, 128(R20)
   985  	FMOVD   F6, 136(R20)
   986  	FMOVD   F7, 144(R20)
   987  	FMOVD   F8, 152(R20)
   988  	FMOVD   F9, 160(R20)
   989  	FMOVD   F10, 168(R20)
   990  	FMOVD   F11, 176(R20)
   991  	FMOVD   F12, 184(R20)
   992  	RET
   993  
   994  // unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
   995  TEXT runtime·unspillArgs(SB),NOSPLIT,$0-0
   996  	MOVD    0(R20), R3
   997  	MOVD    8(R20), R4
   998  	MOVD    16(R20), R5
   999  	MOVD    24(R20), R6
  1000  	MOVD    32(R20), R7
  1001  	MOVD    40(R20), R8
  1002  	MOVD    48(R20), R9
  1003  	MOVD    56(R20), R10
  1004  	MOVD    64(R20), R14
  1005  	MOVD    72(R20), R15
  1006  	MOVD    80(R20), R16
  1007  	MOVD    88(R20), R17
  1008  	FMOVD   96(R20), F1
  1009  	FMOVD   104(R20), F2
  1010  	FMOVD   112(R20), F3
  1011  	FMOVD   120(R20), F4
  1012  	FMOVD   128(R20), F5
  1013  	FMOVD   136(R20), F6
  1014  	FMOVD   144(R20), F7
  1015  	FMOVD   152(R20), F8
  1016  	FMOVD   160(R20), F9
  1017  	FMOVD	168(R20), F10
  1018  	FMOVD	176(R20), F11
  1019  	FMOVD	184(R20), F12
  1020  	RET
  1021  
  1022  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
  1023  // Must obey the gcc calling convention.
  1024  #ifdef GOOS_aix
  1025  // On AIX, _cgo_topofstack is defined in runtime/cgo, because it must
  1026  // be a longcall in order to prevent trampolines from ld.
  1027  TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
  1028  #else
  1029  TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
  1030  #endif
  1031  	// g (R30) and R31 are callee-save in the C ABI, so save them
  1032  	MOVD	g, R4
  1033  	MOVD	R31, R5
  1034  	MOVD	LR, R6
  1035  
  1036  	BL	runtime·load_g(SB)	// clobbers g (R30), R31
  1037  	MOVD	g_m(g), R3
  1038  	MOVD	m_curg(R3), R3
  1039  	MOVD	(g_stack+stack_hi)(R3), R3
  1040  
  1041  	MOVD	R4, g
  1042  	MOVD	R5, R31
  1043  	MOVD	R6, LR
  1044  	RET
  1045  
  1046  // The top-most function running on a goroutine
  1047  // returns to goexit+PCQuantum.
  1048  //
  1049  // When dynamically linking Go, it can be returned to from a function
  1050  // implemented in a different module and so needs to reload the TOC pointer
  1051  // from the stack (although this function declares that it does not set up x-a
  1052  // frame, newproc1 does in fact allocate one for goexit and saves the TOC
  1053  // pointer in the correct place).
  1054  // goexit+_PCQuantum is halfway through the usual global entry point prologue
  1055  // that derives r2 from r12 which is a bit silly, but not harmful.
  1056  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
  1057  	MOVD	24(R1), R2
  1058  	BL	runtime·goexit1(SB)	// does not return
  1059  	// traceback from goexit1 must hit code range of goexit
  1060  	MOVD	R0, R0	// NOP
  1061  
  1062  // prepGoExitFrame saves the current TOC pointer (i.e. the TOC pointer for the
  1063  // module containing runtime) to the frame that goexit will execute in when
  1064  // the goroutine exits. It's implemented in assembly mainly because that's the
  1065  // easiest way to get access to R2.
  1066  TEXT runtime·prepGoExitFrame(SB),NOSPLIT,$0-8
  1067  	MOVD    sp+0(FP), R3
  1068  	MOVD    R2, 24(R3)
  1069  	RET
  1070  
  1071  TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0
  1072  	ADD	$-8, R1
  1073  	MOVD	R31, 0(R1)
  1074  	MOVD	runtime·lastmoduledatap(SB), R4
  1075  	MOVD	R3, moduledata_next(R4)
  1076  	MOVD	R3, runtime·lastmoduledatap(SB)
  1077  	MOVD	0(R1), R31
  1078  	ADD	$8, R1
  1079  	RET
  1080  
  1081  // gcWriteBarrier informs the GC about heap pointer writes.
  1082  //
  1083  // gcWriteBarrier does NOT follow the Go ABI. It accepts the
  1084  // number of bytes of buffer needed in R29, and returns a pointer
  1085  // to the buffer space in R29.
  1086  // It clobbers condition codes.
  1087  // It does not clobber R0 through R17 (except special registers),
  1088  // but may clobber any other register, *including* R31.
  1089  TEXT gcWriteBarrier<>(SB),NOSPLIT,$120
  1090  	// The standard prologue clobbers R31.
  1091  	// We use R18, R19, and R31 as scratch registers.
  1092  retry:
  1093  	MOVD	g_m(g), R18
  1094  	MOVD	m_p(R18), R18
  1095  	MOVD	(p_wbBuf+wbBuf_next)(R18), R19
  1096  	MOVD	(p_wbBuf+wbBuf_end)(R18), R31
  1097  	// Increment wbBuf.next position.
  1098  	ADD	R29, R19
  1099  	// Is the buffer full?
  1100  	CMPU	R31, R19
  1101  	BLT	flush
  1102  	// Commit to the larger buffer.
  1103  	MOVD	R19, (p_wbBuf+wbBuf_next)(R18)
  1104  	// Make return value (the original next position)
  1105  	SUB	R29, R19, R29
  1106  	RET
  1107  
  1108  flush:
  1109  	// Save registers R0 through R15 since these were not saved by the caller.
  1110  	// We don't save all registers on ppc64 because it takes too much space.
  1111  	MOVD	R20, (FIXED_FRAME+0)(R1)
  1112  	MOVD	R21, (FIXED_FRAME+8)(R1)
  1113  	// R0 is always 0, so no need to spill.
  1114  	// R1 is SP.
  1115  	// R2 is SB.
  1116  	MOVD	R3, (FIXED_FRAME+16)(R1)
  1117  	MOVD	R4, (FIXED_FRAME+24)(R1)
  1118  	MOVD	R5, (FIXED_FRAME+32)(R1)
  1119  	MOVD	R6, (FIXED_FRAME+40)(R1)
  1120  	MOVD	R7, (FIXED_FRAME+48)(R1)
  1121  	MOVD	R8, (FIXED_FRAME+56)(R1)
  1122  	MOVD	R9, (FIXED_FRAME+64)(R1)
  1123  	MOVD	R10, (FIXED_FRAME+72)(R1)
  1124  	// R11, R12 may be clobbered by external-linker-inserted trampoline
  1125  	// R13 is REGTLS
  1126  	MOVD	R14, (FIXED_FRAME+80)(R1)
  1127  	MOVD	R15, (FIXED_FRAME+88)(R1)
  1128  	MOVD	R16, (FIXED_FRAME+96)(R1)
  1129  	MOVD	R17, (FIXED_FRAME+104)(R1)
  1130  	MOVD	R29, (FIXED_FRAME+112)(R1)
  1131  
  1132  	CALL	runtime·wbBufFlush(SB)
  1133  
  1134  	MOVD	(FIXED_FRAME+0)(R1), R20
  1135  	MOVD	(FIXED_FRAME+8)(R1), R21
  1136  	MOVD	(FIXED_FRAME+16)(R1), R3
  1137  	MOVD	(FIXED_FRAME+24)(R1), R4
  1138  	MOVD	(FIXED_FRAME+32)(R1), R5
  1139  	MOVD	(FIXED_FRAME+40)(R1), R6
  1140  	MOVD	(FIXED_FRAME+48)(R1), R7
  1141  	MOVD	(FIXED_FRAME+56)(R1), R8
  1142  	MOVD	(FIXED_FRAME+64)(R1), R9
  1143  	MOVD	(FIXED_FRAME+72)(R1), R10
  1144  	MOVD	(FIXED_FRAME+80)(R1), R14
  1145  	MOVD	(FIXED_FRAME+88)(R1), R15
  1146  	MOVD	(FIXED_FRAME+96)(R1), R16
  1147  	MOVD	(FIXED_FRAME+104)(R1), R17
  1148  	MOVD	(FIXED_FRAME+112)(R1), R29
  1149  	JMP	retry
  1150  
  1151  TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
  1152  	MOVD	$8, R29
  1153  	JMP	gcWriteBarrier<>(SB)
  1154  TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
  1155  	MOVD	$16, R29
  1156  	JMP	gcWriteBarrier<>(SB)
  1157  TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
  1158  	MOVD	$24, R29
  1159  	JMP	gcWriteBarrier<>(SB)
  1160  TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
  1161  	MOVD	$32, R29
  1162  	JMP	gcWriteBarrier<>(SB)
  1163  TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
  1164  	MOVD	$40, R29
  1165  	JMP	gcWriteBarrier<>(SB)
  1166  TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
  1167  	MOVD	$48, R29
  1168  	JMP	gcWriteBarrier<>(SB)
  1169  TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
  1170  	MOVD	$56, R29
  1171  	JMP	gcWriteBarrier<>(SB)
  1172  TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
  1173  	MOVD	$64, R29
  1174  	JMP	gcWriteBarrier<>(SB)
  1175  
  1176  DATA	debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
  1177  GLOBL	debugCallFrameTooLarge<>(SB), RODATA, $20	// Size duplicated below
  1178  
  1179  // debugCallV2 is the entry point for debugger-injected function
  1180  // calls on running goroutines. It informs the runtime that a
  1181  // debug call has been injected and creates a call frame for the
  1182  // debugger to fill in.
  1183  //
  1184  // To inject a function call, a debugger should:
  1185  // 1. Check that the goroutine is in state _Grunning and that
  1186  //    there are at least 320 bytes free on the stack.
  1187  // 2. Set SP as SP-32.
  1188  // 3. Store the current LR in (SP) (using the SP after step 2).
  1189  // 4. Store the current PC in the LR register.
  1190  // 5. Write the desired argument frame size at SP-32
  1191  // 6. Save all machine registers (including flags and floating point registers)
  1192  //    so they can be restored later by the debugger.
  1193  // 7. Set the PC to debugCallV2 and resume execution.
  1194  //
  1195  // If the goroutine is in state _Grunnable, then it's not generally
  1196  // safe to inject a call because it may return out via other runtime
  1197  // operations. Instead, the debugger should unwind the stack to find
  1198  // the return to non-runtime code, add a temporary breakpoint there,
  1199  // and inject the call once that breakpoint is hit.
  1200  //
  1201  // If the goroutine is in any other state, it's not safe to inject a call.
  1202  //
  1203  // This function communicates back to the debugger by setting R20 and
  1204  // invoking TW to raise a breakpoint signal. Note that the signal PC of
  1205  // the signal triggered by the TW instruction is the PC where the signal
  1206  // is trapped, not the next PC, so to resume execution, the debugger needs
  1207  // to set the signal PC to PC+4. See the comments in the implementation for
  1208  // the protocol the debugger is expected to follow. InjectDebugCall in the
  1209  // runtime tests demonstrates this protocol.
  1210  // The debugger must ensure that any pointers passed to the function
  1211  // obey escape analysis requirements. Specifically, it must not pass
  1212  // a stack pointer to an escaping argument. debugCallV2 cannot check
  1213  // this invariant.
  1214  //
  1215  // This is ABIInternal because Go code injects its PC directly into new
  1216  // goroutine stacks.
  1217  #ifdef GOOS_linux
  1218  TEXT runtime·debugCallV2<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-0
  1219  	// save scratch register R31 first
  1220  	MOVD	R31, -184(R1)
  1221  	MOVD	0(R1), R31
  1222  	// save caller LR
  1223  	MOVD	R31, -304(R1)
  1224  	MOVD	-32(R1), R31
  1225  	// save argument frame size
  1226  	MOVD	R31, -192(R1)
  1227  	MOVD	LR, R31
  1228  	MOVD	R31, -320(R1)
  1229  	ADD	$-320, R1
  1230  	// save all registers that can contain pointers
  1231  	// and the CR register
  1232  	MOVW	CR, R31
  1233  	MOVD	R31, 8(R1)
  1234  	MOVD	R2, 24(R1)
  1235  	MOVD	R3, 56(R1)
  1236  	MOVD	R4, 64(R1)
  1237  	MOVD	R5, 72(R1)
  1238  	MOVD	R6, 80(R1)
  1239  	MOVD	R7, 88(R1)
  1240  	MOVD	R8, 96(R1)
  1241  	MOVD	R9, 104(R1)
  1242  	MOVD	R10, 112(R1)
  1243  	MOVD	R11, 120(R1)
  1244  	MOVD	R12, 144(R1)
  1245  	MOVD	R13, 152(R1)
  1246  	MOVD	R14, 160(R1)
  1247  	MOVD	R15, 168(R1)
  1248  	MOVD	R16, 176(R1)
  1249  	MOVD	R17, 184(R1)
  1250  	MOVD	R18, 192(R1)
  1251  	MOVD	R19, 200(R1)
  1252  	MOVD	R20, 208(R1)
  1253  	MOVD	R21, 216(R1)
  1254  	MOVD	R22, 224(R1)
  1255  	MOVD	R23, 232(R1)
  1256  	MOVD	R24, 240(R1)
  1257  	MOVD	R25, 248(R1)
  1258  	MOVD	R26, 256(R1)
  1259  	MOVD	R27, 264(R1)
  1260  	MOVD	R28, 272(R1)
  1261  	MOVD	R29, 280(R1)
  1262  	MOVD	g, 288(R1)
  1263  	MOVD	LR, R31
  1264  	MOVD	R31, 32(R1)
  1265  	CALL	runtime·debugCallCheck(SB)
  1266  	MOVD	40(R1), R22
  1267  	XOR	R0, R0
  1268  	CMP	R22, $0
  1269  	BEQ	good
  1270  	MOVD	48(R1), R22
  1271  	MOVD	$8, R20
  1272  	TW	$31, R0, R0
  1273  
  1274  	BR	restore
  1275  
  1276  good:
  1277  #define DEBUG_CALL_DISPATCH(NAME,MAXSIZE)	\
  1278  	MOVD	$MAXSIZE, R23;			\
  1279  	CMP	R26, R23;			\
  1280  	BGT	5(PC);				\
  1281  	MOVD	$NAME(SB), R26;			\
  1282  	MOVD	R26, 32(R1);			\
  1283  	CALL	runtime·debugCallWrap(SB);	\
  1284  	BR	restore
  1285  
  1286  	// the argument frame size
  1287  	MOVD	128(R1), R26
  1288  
  1289  	DEBUG_CALL_DISPATCH(debugCall32<>, 32)
  1290  	DEBUG_CALL_DISPATCH(debugCall64<>, 64)
  1291  	DEBUG_CALL_DISPATCH(debugCall128<>, 128)
  1292  	DEBUG_CALL_DISPATCH(debugCall256<>, 256)
  1293  	DEBUG_CALL_DISPATCH(debugCall512<>, 512)
  1294  	DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
  1295  	DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
  1296  	DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
  1297  	DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
  1298  	DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
  1299  	DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
  1300  	DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
  1301  	// The frame size is too large. Report the error.
  1302  	MOVD	$debugCallFrameTooLarge<>(SB), R22
  1303  	MOVD	R22, 32(R1)
  1304  	MOVD	$20, R22
  1305  	// length of debugCallFrameTooLarge string
  1306  	MOVD	R22, 40(R1)
  1307  	MOVD	$8, R20
  1308  	TW	$31, R0, R0
  1309  	BR	restore
  1310  restore:
  1311  	MOVD	$16, R20
  1312  	TW	$31, R0, R0
  1313  	// restore all registers that can contain
  1314  	// pointers including CR
  1315  	MOVD	8(R1), R31
  1316  	MOVW	R31, CR
  1317  	MOVD	24(R1), R2
  1318  	MOVD	56(R1), R3
  1319  	MOVD	64(R1), R4
  1320  	MOVD	72(R1), R5
  1321  	MOVD	80(R1), R6
  1322  	MOVD	88(R1), R7
  1323  	MOVD	96(R1), R8
  1324  	MOVD	104(R1), R9
  1325  	MOVD	112(R1), R10
  1326  	MOVD	120(R1), R11
  1327  	MOVD	144(R1), R12
  1328  	MOVD	152(R1), R13
  1329  	MOVD	160(R1), R14
  1330  	MOVD	168(R1), R15
  1331  	MOVD	176(R1), R16
  1332  	MOVD	184(R1), R17
  1333  	MOVD	192(R1), R18
  1334  	MOVD	200(R1), R19
  1335  	MOVD	208(R1), R20
  1336  	MOVD	216(R1), R21
  1337  	MOVD	224(R1), R22
  1338  	MOVD	232(R1), R23
  1339  	MOVD	240(R1), R24
  1340  	MOVD	248(R1), R25
  1341  	MOVD	256(R1), R26
  1342  	MOVD	264(R1), R27
  1343  	MOVD	272(R1), R28
  1344  	MOVD	280(R1), R29
  1345  	MOVD	288(R1), g
  1346  	MOVD	16(R1), R31
  1347  	// restore old LR
  1348  	MOVD	R31, LR
  1349  	// restore caller PC
  1350  	MOVD	0(R1), CTR
  1351  	MOVD	136(R1), R31
  1352  	// Add 32 bytes more to compensate for SP change in saveSigContext
  1353  	ADD	$352, R1
  1354  	JMP	(CTR)
  1355  #endif
  1356  #define DEBUG_CALL_FN(NAME,MAXSIZE)	\
  1357  TEXT NAME(SB),WRAPPER,$MAXSIZE-0;	\
  1358  	NO_LOCAL_POINTERS;		\
  1359  	MOVD	$0, R20;		\
  1360  	TW	$31, R0, R0		\
  1361  	MOVD	$1, R20;		\
  1362  	TW	$31, R0, R0		\
  1363  	RET
  1364  DEBUG_CALL_FN(debugCall32<>, 32)
  1365  DEBUG_CALL_FN(debugCall64<>, 64)
  1366  DEBUG_CALL_FN(debugCall128<>, 128)
  1367  DEBUG_CALL_FN(debugCall256<>, 256)
  1368  DEBUG_CALL_FN(debugCall512<>, 512)
  1369  DEBUG_CALL_FN(debugCall1024<>, 1024)
  1370  DEBUG_CALL_FN(debugCall2048<>, 2048)
  1371  DEBUG_CALL_FN(debugCall4096<>, 4096)
  1372  DEBUG_CALL_FN(debugCall8192<>, 8192)
  1373  DEBUG_CALL_FN(debugCall16384<>, 16384)
  1374  DEBUG_CALL_FN(debugCall32768<>, 32768)
  1375  DEBUG_CALL_FN(debugCall65536<>, 65536)
  1376  
  1377  #ifdef GOOS_linux
  1378  // func debugCallPanicked(val interface{})
  1379  TEXT runtime·debugCallPanicked(SB),NOSPLIT,$32-16
  1380  	// Copy the panic value to the top of stack at SP+32.
  1381  	MOVD	val_type+0(FP), R31
  1382  	MOVD	R31, 32(R1)
  1383  	MOVD	val_data+8(FP), R31
  1384  	MOVD	R31, 40(R1)
  1385  	MOVD	$2, R20
  1386  	TW	$31, R0, R0
  1387  	RET
  1388  #endif
  1389  
  1390  TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$88-0
  1391  	// Note: frame size is 16 bytes larger than necessary
  1392  	// in order to pacify vet. Vet doesn't understand ppc64
  1393  	// layout properly.
  1394  	NO_LOCAL_POINTERS
  1395  	// Save all 7 int registers that could have an index in them.
  1396  	// They may be pointers, but if so they are dead.
  1397  	// Skip R0 aka ZERO, R1 aka SP, R2 aka SB
  1398  	MOVD	R3, 48(R1)
  1399  	MOVD	R4, 56(R1)
  1400  	MOVD	R5, 64(R1)
  1401  	MOVD	R6, 72(R1)
  1402  	MOVD	R7, 80(R1)
  1403  	MOVD	R8, 88(R1)
  1404  	MOVD	R9, 96(R1)
  1405  	// Note: we only save 7 registers to keep under nosplit stack limit
  1406  	// Also, R11 is clobbered in dynamic linking situations
  1407  
  1408  	MOVD	LR, R3		// PC immediately after call to panicBounds
  1409  	ADD	$48, R1, R4	// pointer to save area
  1410  	CALL	runtime·panicBounds64<ABIInternal>(SB)
  1411  	RET
  1412  
  1413  // These functions are used when internal linking cgo with external
  1414  // objects compiled with the -Os on gcc. They reduce prologue/epilogue
  1415  // size by deferring preservation of callee-save registers to a shared
  1416  // function. These are defined in PPC64 ELFv2 2.3.3 (but also present
  1417  // in ELFv1)
  1418  //
  1419  // These appear unused, but the linker will redirect calls to functions
  1420  // like _savegpr0_14 or _restgpr1_14 to runtime.elf_savegpr0 or
  1421  // runtime.elf_restgpr1 with an appropriate offset based on the number
  1422  // register operations required when linking external objects which
  1423  // make these calls. For GPR/FPR saves, the minimum register value is
  1424  // 14, for VR it is 20.
  1425  //
  1426  // These are only used when linking such cgo code internally. Note, R12
  1427  // and R0 may be used in different ways than regular ELF compliant
  1428  // functions.
  1429  TEXT runtime·elf_savegpr0(SB),NOSPLIT|NOFRAME,$0
  1430  	// R0 holds the LR of the caller's caller, R1 holds save location
  1431  	MOVD	R14, -144(R1)
  1432  	MOVD	R15, -136(R1)
  1433  	MOVD	R16, -128(R1)
  1434  	MOVD	R17, -120(R1)
  1435  	MOVD	R18, -112(R1)
  1436  	MOVD	R19, -104(R1)
  1437  	MOVD	R20, -96(R1)
  1438  	MOVD	R21, -88(R1)
  1439  	MOVD	R22, -80(R1)
  1440  	MOVD	R23, -72(R1)
  1441  	MOVD	R24, -64(R1)
  1442  	MOVD	R25, -56(R1)
  1443  	MOVD	R26, -48(R1)
  1444  	MOVD	R27, -40(R1)
  1445  	MOVD	R28, -32(R1)
  1446  	MOVD	R29, -24(R1)
  1447  	MOVD	g, -16(R1)
  1448  	MOVD	R31, -8(R1)
  1449  	MOVD	R0, 16(R1)
  1450  	RET
  1451  TEXT runtime·elf_restgpr0(SB),NOSPLIT|NOFRAME,$0
  1452  	// R1 holds save location. This returns to the LR saved on stack (bypassing the caller)
  1453  	MOVD	-144(R1), R14
  1454  	MOVD	-136(R1), R15
  1455  	MOVD	-128(R1), R16
  1456  	MOVD	-120(R1), R17
  1457  	MOVD	-112(R1), R18
  1458  	MOVD	-104(R1), R19
  1459  	MOVD	-96(R1), R20
  1460  	MOVD	-88(R1), R21
  1461  	MOVD	-80(R1), R22
  1462  	MOVD	-72(R1), R23
  1463  	MOVD	-64(R1), R24
  1464  	MOVD	-56(R1), R25
  1465  	MOVD	-48(R1), R26
  1466  	MOVD	-40(R1), R27
  1467  	MOVD	-32(R1), R28
  1468  	MOVD	-24(R1), R29
  1469  	MOVD	-16(R1), g
  1470  	MOVD	-8(R1), R31
  1471  	MOVD	16(R1), R0	// Load and return to saved LR
  1472  	MOVD	R0, LR
  1473  	RET
  1474  TEXT runtime·elf_savegpr1(SB),NOSPLIT|NOFRAME,$0
  1475  	// R12 holds the save location
  1476  	MOVD	R14, -144(R12)
  1477  	MOVD	R15, -136(R12)
  1478  	MOVD	R16, -128(R12)
  1479  	MOVD	R17, -120(R12)
  1480  	MOVD	R18, -112(R12)
  1481  	MOVD	R19, -104(R12)
  1482  	MOVD	R20, -96(R12)
  1483  	MOVD	R21, -88(R12)
  1484  	MOVD	R22, -80(R12)
  1485  	MOVD	R23, -72(R12)
  1486  	MOVD	R24, -64(R12)
  1487  	MOVD	R25, -56(R12)
  1488  	MOVD	R26, -48(R12)
  1489  	MOVD	R27, -40(R12)
  1490  	MOVD	R28, -32(R12)
  1491  	MOVD	R29, -24(R12)
  1492  	MOVD	g, -16(R12)
  1493  	MOVD	R31, -8(R12)
  1494  	RET
  1495  TEXT runtime·elf_restgpr1(SB),NOSPLIT|NOFRAME,$0
  1496  	// R12 holds the save location
  1497  	MOVD	-144(R12), R14
  1498  	MOVD	-136(R12), R15
  1499  	MOVD	-128(R12), R16
  1500  	MOVD	-120(R12), R17
  1501  	MOVD	-112(R12), R18
  1502  	MOVD	-104(R12), R19
  1503  	MOVD	-96(R12), R20
  1504  	MOVD	-88(R12), R21
  1505  	MOVD	-80(R12), R22
  1506  	MOVD	-72(R12), R23
  1507  	MOVD	-64(R12), R24
  1508  	MOVD	-56(R12), R25
  1509  	MOVD	-48(R12), R26
  1510  	MOVD	-40(R12), R27
  1511  	MOVD	-32(R12), R28
  1512  	MOVD	-24(R12), R29
  1513  	MOVD	-16(R12), g
  1514  	MOVD	-8(R12), R31
  1515  	RET
  1516  TEXT runtime·elf_savefpr(SB),NOSPLIT|NOFRAME,$0
  1517  	// R0 holds the LR of the caller's caller, R1 holds save location
  1518  	FMOVD	F14, -144(R1)
  1519  	FMOVD	F15, -136(R1)
  1520  	FMOVD	F16, -128(R1)
  1521  	FMOVD	F17, -120(R1)
  1522  	FMOVD	F18, -112(R1)
  1523  	FMOVD	F19, -104(R1)
  1524  	FMOVD	F20, -96(R1)
  1525  	FMOVD	F21, -88(R1)
  1526  	FMOVD	F22, -80(R1)
  1527  	FMOVD	F23, -72(R1)
  1528  	FMOVD	F24, -64(R1)
  1529  	FMOVD	F25, -56(R1)
  1530  	FMOVD	F26, -48(R1)
  1531  	FMOVD	F27, -40(R1)
  1532  	FMOVD	F28, -32(R1)
  1533  	FMOVD	F29, -24(R1)
  1534  	FMOVD	F30, -16(R1)
  1535  	FMOVD	F31, -8(R1)
  1536  	MOVD	R0, 16(R1)
  1537  	RET
  1538  TEXT runtime·elf_restfpr(SB),NOSPLIT|NOFRAME,$0
  1539  	// R1 holds save location. This returns to the LR saved on stack (bypassing the caller)
  1540  	FMOVD	-144(R1), F14
  1541  	FMOVD	-136(R1), F15
  1542  	FMOVD	-128(R1), F16
  1543  	FMOVD	-120(R1), F17
  1544  	FMOVD	-112(R1), F18
  1545  	FMOVD	-104(R1), F19
  1546  	FMOVD	-96(R1), F20
  1547  	FMOVD	-88(R1), F21
  1548  	FMOVD	-80(R1), F22
  1549  	FMOVD	-72(R1), F23
  1550  	FMOVD	-64(R1), F24
  1551  	FMOVD	-56(R1), F25
  1552  	FMOVD	-48(R1), F26
  1553  	FMOVD	-40(R1), F27
  1554  	FMOVD	-32(R1), F28
  1555  	FMOVD	-24(R1), F29
  1556  	FMOVD	-16(R1), F30
  1557  	FMOVD	-8(R1), F31
  1558  	MOVD	16(R1), R0	// Load and return to saved LR
  1559  	MOVD	R0, LR
  1560  	RET
  1561  TEXT runtime·elf_savevr(SB),NOSPLIT|NOFRAME,$0
  1562  	// R0 holds the save location, R12 is clobbered
  1563  	MOVD	$-192, R12
  1564  	STVX	V20, (R0+R12)
  1565  	MOVD	$-176, R12
  1566  	STVX	V21, (R0+R12)
  1567  	MOVD	$-160, R12
  1568  	STVX	V22, (R0+R12)
  1569  	MOVD	$-144, R12
  1570  	STVX	V23, (R0+R12)
  1571  	MOVD	$-128, R12
  1572  	STVX	V24, (R0+R12)
  1573  	MOVD	$-112, R12
  1574  	STVX	V25, (R0+R12)
  1575  	MOVD	$-96, R12
  1576  	STVX	V26, (R0+R12)
  1577  	MOVD	$-80, R12
  1578  	STVX	V27, (R0+R12)
  1579  	MOVD	$-64, R12
  1580  	STVX	V28, (R0+R12)
  1581  	MOVD	$-48, R12
  1582  	STVX	V29, (R0+R12)
  1583  	MOVD	$-32, R12
  1584  	STVX	V30, (R0+R12)
  1585  	MOVD	$-16, R12
  1586  	STVX	V31, (R0+R12)
  1587  	RET
  1588  TEXT runtime·elf_restvr(SB),NOSPLIT|NOFRAME,$0
  1589  	// R0 holds the save location, R12 is clobbered
  1590  	MOVD	$-192, R12
  1591  	LVX	(R0+R12), V20
  1592  	MOVD	$-176, R12
  1593  	LVX	(R0+R12), V21
  1594  	MOVD	$-160, R12
  1595  	LVX	(R0+R12), V22
  1596  	MOVD	$-144, R12
  1597  	LVX	(R0+R12), V23
  1598  	MOVD	$-128, R12
  1599  	LVX	(R0+R12), V24
  1600  	MOVD	$-112, R12
  1601  	LVX	(R0+R12), V25
  1602  	MOVD	$-96, R12
  1603  	LVX	(R0+R12), V26
  1604  	MOVD	$-80, R12
  1605  	LVX	(R0+R12), V27
  1606  	MOVD	$-64, R12
  1607  	LVX	(R0+R12), V28
  1608  	MOVD	$-48, R12
  1609  	LVX	(R0+R12), V29
  1610  	MOVD	$-32, R12
  1611  	LVX	(R0+R12), V30
  1612  	MOVD	$-16, R12
  1613  	LVX	(R0+R12), V31
  1614  	RET
  1615  

View as plain text