github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/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  
    12  TEXT runtime·rt0_go(SB),NOSPLIT,$0
    13  	// initialize essential registers
    14  	BL	runtime·reginit(SB)
    15  
    16  	SUB	$24, R1
    17  	MOVW	R3, 8(R1) // argc
    18  	MOVD	R4, 16(R1) // argv
    19  
    20  	// create istack out of the given (operating system) stack.
    21  	// _cgo_init may update stackguard.
    22  	MOVD	$runtime·g0(SB), g
    23  	MOVD	$(-64*1024), R31
    24  	ADD	R31, R1, R3
    25  	MOVD	R3, g_stackguard0(g)
    26  	MOVD	R3, g_stackguard1(g)
    27  	MOVD	R3, (g_stack+stack_lo)(g)
    28  	MOVD	R1, (g_stack+stack_hi)(g)
    29  
    30  	// TODO: if there is a _cgo_init, call it.
    31  	// TODO: add TLS
    32  
    33  	// set the per-goroutine and per-mach "registers"
    34  	MOVD	$runtime·m0(SB), R3
    35  
    36  	// save m->g0 = g0
    37  	MOVD	g, m_g0(R3)
    38  	// save m0 to g0->m
    39  	MOVD	R3, g_m(g)
    40  
    41  	BL	runtime·check(SB)
    42  
    43  	// args are already prepared
    44  	BL	runtime·args(SB)
    45  	BL	runtime·osinit(SB)
    46  	BL	runtime·schedinit(SB)
    47  
    48  	// create a new goroutine to start program
    49  	MOVD	$runtime·main·f(SB), R3		// entry
    50  	MOVDU	R3, -8(R1)
    51  	MOVDU	R0, -8(R1)
    52  	MOVDU	R0, -8(R1)
    53  	BL	runtime·newproc(SB)
    54  	ADD	$24, R1
    55  
    56  	// start this M
    57  	BL	runtime·mstart(SB)
    58  
    59  	MOVD	R0, 1(R0)
    60  	RETURN
    61  
    62  DATA	runtime·main·f+0(SB)/8,$runtime·main(SB)
    63  GLOBL	runtime·main·f(SB),RODATA,$8
    64  
    65  TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0
    66  	MOVD	R0, 2(R0) // TODO: TD
    67  	RETURN
    68  
    69  TEXT runtime·asminit(SB),NOSPLIT,$-8-0
    70  	RETURN
    71  
    72  TEXT runtime·reginit(SB),NOSPLIT,$-8-0
    73  	// set R0 to zero, it's expected by the toolchain
    74  	XOR R0, R0
    75  	// initialize essential FP registers
    76  	FMOVD	$4503601774854144.0, F27
    77  	FMOVD	$0.5, F29
    78  	FSUB	F29, F29, F28
    79  	FADD	F29, F29, F30
    80  	FADD	F30, F30, F31
    81  	RETURN
    82  
    83  /*
    84   *  go-routine
    85   */
    86  
    87  // void gosave(Gobuf*)
    88  // save state in Gobuf; setjmp
    89  TEXT runtime·gosave(SB), NOSPLIT, $-8-8
    90  	MOVD	buf+0(FP), R3
    91  	MOVD	R1, gobuf_sp(R3)
    92  	MOVD	LR, R31
    93  	MOVD	R31, gobuf_pc(R3)
    94  	MOVD	g, gobuf_g(R3)
    95  	MOVD	R0, gobuf_lr(R3)
    96  	MOVD	R0, gobuf_ret(R3)
    97  	MOVD	R0, gobuf_ctxt(R3)
    98  	RETURN
    99  
   100  // void gogo(Gobuf*)
   101  // restore state from Gobuf; longjmp
   102  TEXT runtime·gogo(SB), NOSPLIT, $-8-8
   103  	MOVD	buf+0(FP), R5
   104  	MOVD	gobuf_g(R5), g	// make sure g is not nil
   105  	MOVD	0(g), R4
   106  	MOVD	gobuf_sp(R5), R1
   107  	MOVD	gobuf_lr(R5), R31
   108  	MOVD	R31, LR
   109  	MOVD	gobuf_ret(R5), R3
   110  	MOVD	gobuf_ctxt(R5), R11
   111  	MOVD	R0, gobuf_sp(R5)
   112  	MOVD	R0, gobuf_ret(R5)
   113  	MOVD	R0, gobuf_lr(R5)
   114  	MOVD	R0, gobuf_ctxt(R5)
   115  	CMP	R0, R0 // set condition codes for == test, needed by stack split
   116  	MOVD	gobuf_pc(R5), R31
   117  	MOVD	R31, CTR
   118  	BR	(CTR)
   119  
   120  // void mcall(fn func(*g))
   121  // Switch to m->g0's stack, call fn(g).
   122  // Fn must never return.  It should gogo(&g->sched)
   123  // to keep running g.
   124  TEXT runtime·mcall(SB), NOSPLIT, $-8-8
   125  	// Save caller state in g->sched
   126  	MOVD	R1, (g_sched+gobuf_sp)(g)
   127  	MOVD	LR, R31
   128  	MOVD	R31, (g_sched+gobuf_pc)(g)
   129  	MOVD	R0, (g_sched+gobuf_lr)(g)
   130  	MOVD	g, (g_sched+gobuf_g)(g)
   131  
   132  	// Switch to m->g0 & its stack, call fn.
   133  	MOVD	g, R3
   134  	MOVD	g_m(g), R8
   135  	MOVD	m_g0(R8), g
   136  	CMP	g, R3
   137  	BNE	2(PC)
   138  	BR	runtime·badmcall(SB)
   139  	MOVD	fn+0(FP), R11			// context
   140  	MOVD	0(R11), R4			// code pointer
   141  	MOVD	R4, CTR
   142  	MOVD	(g_sched+gobuf_sp)(g), R1	// sp = m->g0->sched.sp
   143  	MOVDU	R3, -8(R1)
   144  	MOVDU	R0, -8(R1)
   145  	BL	(CTR)
   146  	BR	runtime·badmcall2(SB)
   147  
   148  // systemstack_switch is a dummy routine that systemstack leaves at the bottom
   149  // of the G stack.  We need to distinguish the routine that
   150  // lives at the bottom of the G stack from the one that lives
   151  // at the top of the system stack because the one at the top of
   152  // the system stack terminates the stack walk (see topofstack()).
   153  TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   154  	UNDEF
   155  	BL	(LR)	// make sure this function is not leaf
   156  	RETURN
   157  
   158  // func systemstack(fn func())
   159  TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   160  	MOVD	fn+0(FP), R3	// R3 = fn
   161  	MOVD	R3, R11		// context
   162  	MOVD	g_m(g), R4	// R4 = m
   163  
   164  	MOVD	m_gsignal(R4), R5	// R5 = gsignal
   165  	CMP	g, R5
   166  	BEQ	noswitch
   167  
   168  	MOVD	m_g0(R4), R5	// R5 = g0
   169  	CMP	g, R5
   170  	BEQ	noswitch
   171  
   172  	MOVD	m_curg(R4), R6
   173  	CMP	g, R6
   174  	BEQ	switch
   175  
   176  	// Bad: g is not gsignal, not g0, not curg. What is it?
   177  	// Hide call from linker nosplit analysis.
   178  	MOVD	$runtime·badsystemstack(SB), R3
   179  	MOVD	R3, CTR
   180  	BL	(CTR)
   181  
   182  switch:
   183  	// save our state in g->sched.  Pretend to
   184  	// be systemstack_switch if the G stack is scanned.
   185  	MOVD	$runtime·systemstack_switch(SB), R6
   186  	ADD	$8, R6	// get past prologue
   187  	MOVD	R6, (g_sched+gobuf_pc)(g)
   188  	MOVD	R1, (g_sched+gobuf_sp)(g)
   189  	MOVD	R0, (g_sched+gobuf_lr)(g)
   190  	MOVD	g, (g_sched+gobuf_g)(g)
   191  
   192  	// switch to g0
   193  	MOVD	R5, g
   194  	MOVD	(g_sched+gobuf_sp)(g), R3
   195  	// make it look like mstart called systemstack on g0, to stop traceback
   196  	SUB	$8, R3
   197  	MOVD	$runtime·mstart(SB), R4
   198  	MOVD	R4, 0(R3)
   199  	MOVD	R3, R1
   200  
   201  	// call target function
   202  	MOVD	0(R11), R3	// code pointer
   203  	MOVD	R3, CTR
   204  	BL	(CTR)
   205  
   206  	// switch back to g
   207  	MOVD	g_m(g), R3
   208  	MOVD	m_curg(R3), g
   209  	MOVD	(g_sched+gobuf_sp)(g), R1
   210  	MOVD	R0, (g_sched+gobuf_sp)(g)
   211  	RETURN
   212  
   213  noswitch:
   214  	// already on m stack, just call directly
   215  	MOVD	0(R11), R3	// code pointer
   216  	MOVD	R3, CTR
   217  	BL	(CTR)
   218  	RETURN
   219  
   220  /*
   221   * support for morestack
   222   */
   223  
   224  // Called during function prolog when more stack is needed.
   225  // Caller has already loaded:
   226  // R3: framesize, R4: argsize, R5: LR
   227  //
   228  // The traceback routines see morestack on a g0 as being
   229  // the top of a stack (for example, morestack calling newstack
   230  // calling the scheduler calling newm calling gc), so we must
   231  // record an argument size. For that purpose, it has no arguments.
   232  TEXT runtime·morestack(SB),NOSPLIT,$-8-0
   233  	// Cannot grow scheduler stack (m->g0).
   234  	MOVD	g_m(g), R7
   235  	MOVD	m_g0(R7), R8
   236  	CMP	g, R8
   237  	BNE	2(PC)
   238  	BL	runtime·abort(SB)
   239  
   240  	// Cannot grow signal stack (m->gsignal).
   241  	MOVD	m_gsignal(R7), R8
   242  	CMP	g, R8
   243  	BNE	2(PC)
   244  	BL	runtime·abort(SB)
   245  
   246  	// Called from f.
   247  	// Set g->sched to context in f.
   248  	MOVD	R11, (g_sched+gobuf_ctxt)(g)
   249  	MOVD	R1, (g_sched+gobuf_sp)(g)
   250  	MOVD	LR, R8
   251  	MOVD	R8, (g_sched+gobuf_pc)(g)
   252  	MOVD	R5, (g_sched+gobuf_lr)(g)
   253  
   254  	// Called from f.
   255  	// Set m->morebuf to f's caller.
   256  	MOVD	R5, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   257  	MOVD	R1, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   258  	MOVD	g, (m_morebuf+gobuf_g)(R7)
   259  
   260  	// Call newstack on m->g0's stack.
   261  	MOVD	m_g0(R7), g
   262  	MOVD	(g_sched+gobuf_sp)(g), R1
   263  	BL	runtime·newstack(SB)
   264  
   265  	// Not reached, but make sure the return PC from the call to newstack
   266  	// is still in this function, and not the beginning of the next.
   267  	UNDEF
   268  
   269  TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0
   270  	MOVD	R0, R11
   271  	BR	runtime·morestack(SB)
   272  
   273  // reflectcall: call a function with the given argument list
   274  // func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
   275  // we don't have variable-sized frames, so we use a small number
   276  // of constant-sized-frame functions to encode a few bits of size in the pc.
   277  // Caution: ugly multiline assembly macros in your future!
   278  
   279  #define DISPATCH(NAME,MAXSIZE)		\
   280  	MOVD	$MAXSIZE, R31;		\
   281  	CMP	R3, R31;		\
   282  	BGT	4(PC);			\
   283  	MOVD	$NAME(SB), R31;	\
   284  	MOVD	R31, CTR;		\
   285  	BR	(CTR)
   286  // Note: can't just "BR NAME(SB)" - bad inlining results.
   287  
   288  TEXT ·reflectcall(SB), NOSPLIT, $-8-24
   289  	MOVWZ n+16(FP), R3
   290  	DISPATCH(runtime·call16, 16)
   291  	DISPATCH(runtime·call32, 32)
   292  	DISPATCH(runtime·call64, 64)
   293  	DISPATCH(runtime·call128, 128)
   294  	DISPATCH(runtime·call256, 256)
   295  	DISPATCH(runtime·call512, 512)
   296  	DISPATCH(runtime·call1024, 1024)
   297  	DISPATCH(runtime·call2048, 2048)
   298  	DISPATCH(runtime·call4096, 4096)
   299  	DISPATCH(runtime·call8192, 8192)
   300  	DISPATCH(runtime·call16384, 16384)
   301  	DISPATCH(runtime·call32768, 32768)
   302  	DISPATCH(runtime·call65536, 65536)
   303  	DISPATCH(runtime·call131072, 131072)
   304  	DISPATCH(runtime·call262144, 262144)
   305  	DISPATCH(runtime·call524288, 524288)
   306  	DISPATCH(runtime·call1048576, 1048576)
   307  	DISPATCH(runtime·call2097152, 2097152)
   308  	DISPATCH(runtime·call4194304, 4194304)
   309  	DISPATCH(runtime·call8388608, 8388608)
   310  	DISPATCH(runtime·call16777216, 16777216)
   311  	DISPATCH(runtime·call33554432, 33554432)
   312  	DISPATCH(runtime·call67108864, 67108864)
   313  	DISPATCH(runtime·call134217728, 134217728)
   314  	DISPATCH(runtime·call268435456, 268435456)
   315  	DISPATCH(runtime·call536870912, 536870912)
   316  	DISPATCH(runtime·call1073741824, 1073741824)
   317  	MOVD	$runtime·badreflectcall(SB), R31
   318  	MOVD	R31, CTR
   319  	BR	(CTR)
   320  
   321  #define CALLFN(NAME,MAXSIZE)			\
   322  TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
   323  	NO_LOCAL_POINTERS;			\
   324  	/* copy arguments to stack */		\
   325  	MOVD	arg+8(FP), R3;			\
   326  	MOVWZ	n+16(FP), R4;			\
   327  	MOVD	R1, R5;				\
   328  	ADD	$(8-1), R5;			\
   329  	SUB	$1, R3;				\
   330  	ADD	R5, R4;				\
   331  	CMP	R5, R4;				\
   332  	BEQ	4(PC);				\
   333  	MOVBZU	1(R3), R6;			\
   334  	MOVBZU	R6, 1(R5);			\
   335  	BR	-4(PC);				\
   336  	/* call function */			\
   337  	MOVD	f+0(FP), R11;			\
   338  	MOVD	(R11), R31;			\
   339  	MOVD	R31, CTR;			\
   340  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   341  	BL	(CTR);				\
   342  	/* copy return values back */		\
   343  	MOVD	arg+8(FP), R3;			\
   344  	MOVWZ	n+16(FP), R4;			\
   345  	MOVWZ	retoffset+20(FP), R6;		\
   346  	MOVD	R1, R5;				\
   347  	ADD	R6, R5; 			\
   348  	ADD	R6, R3;				\
   349  	SUB	R6, R4;				\
   350  	ADD	$(8-1), R5;			\
   351  	SUB	$1, R3;				\
   352  	ADD	R5, R4;				\
   353  	CMP	R5, R4;				\
   354  	BEQ	4(PC);				\
   355  	MOVBZU	1(R5), R6;			\
   356  	MOVBZU	R6, 1(R3);			\
   357  	BR	-4(PC);				\
   358  	RETURN
   359  
   360  CALLFN(·call16, 16)
   361  CALLFN(·call32, 32)
   362  CALLFN(·call64, 64)
   363  CALLFN(·call128, 128)
   364  CALLFN(·call256, 256)
   365  CALLFN(·call512, 512)
   366  CALLFN(·call1024, 1024)
   367  CALLFN(·call2048, 2048)
   368  CALLFN(·call4096, 4096)
   369  CALLFN(·call8192, 8192)
   370  CALLFN(·call16384, 16384)
   371  CALLFN(·call32768, 32768)
   372  CALLFN(·call65536, 65536)
   373  CALLFN(·call131072, 131072)
   374  CALLFN(·call262144, 262144)
   375  CALLFN(·call524288, 524288)
   376  CALLFN(·call1048576, 1048576)
   377  CALLFN(·call2097152, 2097152)
   378  CALLFN(·call4194304, 4194304)
   379  CALLFN(·call8388608, 8388608)
   380  CALLFN(·call16777216, 16777216)
   381  CALLFN(·call33554432, 33554432)
   382  CALLFN(·call67108864, 67108864)
   383  CALLFN(·call134217728, 134217728)
   384  CALLFN(·call268435456, 268435456)
   385  CALLFN(·call536870912, 536870912)
   386  CALLFN(·call1073741824, 1073741824)
   387  
   388  // bool cas(uint32 *ptr, uint32 old, uint32 new)
   389  // Atomically:
   390  //	if(*val == old){
   391  //		*val = new;
   392  //		return 1;
   393  //	} else
   394  //		return 0;
   395  TEXT runtime·cas(SB), NOSPLIT, $0-17
   396  	MOVD	ptr+0(FP), R3
   397  	MOVWZ	old+8(FP), R4
   398  	MOVWZ	new+12(FP), R5
   399  cas_again:
   400  	SYNC
   401  	LWAR	(R3), R6
   402  	CMPW	R6, R4
   403  	BNE	cas_fail
   404  	STWCCC	R5, (R3)
   405  	BNE	cas_again
   406  	MOVD	$1, R3
   407  	SYNC
   408  	ISYNC
   409  	MOVB	R3, ret+16(FP)
   410  	RETURN
   411  cas_fail:
   412  	MOVD	$0, R3
   413  	BR	-5(PC)
   414  
   415  // bool	runtime·cas64(uint64 *ptr, uint64 old, uint64 new)
   416  // Atomically:
   417  //	if(*val == *old){
   418  //		*val = new;
   419  //		return 1;
   420  //	} else {
   421  //		return 0;
   422  //	}
   423  TEXT runtime·cas64(SB), NOSPLIT, $0-25
   424  	MOVD	ptr+0(FP), R3
   425  	MOVD	old+8(FP), R4
   426  	MOVD	new+16(FP), R5
   427  cas64_again:
   428  	SYNC
   429  	LDAR	(R3), R6
   430  	CMP	R6, R4
   431  	BNE	cas64_fail
   432  	STDCCC	R5, (R3)
   433  	BNE	cas64_again
   434  	MOVD	$1, R3
   435  	SYNC
   436  	ISYNC
   437  	MOVB	R3, ret+24(FP)
   438  	RETURN
   439  cas64_fail:
   440  	MOVD	$0, R3
   441  	BR	-5(PC)
   442  
   443  TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
   444  	BR	runtime·cas64(SB)
   445  
   446  TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $-8-16
   447  	BR	runtime·atomicload64(SB)
   448  
   449  TEXT runtime·atomicloaduint(SB), NOSPLIT, $-8-16
   450  	BR	runtime·atomicload64(SB)
   451  
   452  TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
   453  	BR	runtime·atomicstore64(SB)
   454  
   455  // bool casp(void **val, void *old, void *new)
   456  // Atomically:
   457  //	if(*val == old){
   458  //		*val = new;
   459  //		return 1;
   460  //	} else
   461  //		return 0;
   462  TEXT runtime·casp1(SB), NOSPLIT, $0-25
   463  	BR runtime·cas64(SB)
   464  
   465  // uint32 xadd(uint32 volatile *ptr, int32 delta)
   466  // Atomically:
   467  //	*val += delta;
   468  //	return *val;
   469  TEXT runtime·xadd(SB), NOSPLIT, $0-20
   470  	MOVD	ptr+0(FP), R4
   471  	MOVW	delta+8(FP), R5
   472  	SYNC
   473  	LWAR	(R4), R3
   474  	ADD	R5, R3
   475  	STWCCC	R3, (R4)
   476  	BNE	-4(PC)
   477  	SYNC
   478  	ISYNC
   479  	MOVW	R3, ret+16(FP)
   480  	RETURN
   481  
   482  TEXT runtime·xadd64(SB), NOSPLIT, $0-24
   483  	MOVD	ptr+0(FP), R4
   484  	MOVD	delta+8(FP), R5
   485  	SYNC
   486  	LDAR	(R4), R3
   487  	ADD	R5, R3
   488  	STDCCC	R3, (R4)
   489  	BNE	-4(PC)
   490  	SYNC
   491  	ISYNC
   492  	MOVD	R3, ret+16(FP)
   493  	RETURN
   494  
   495  TEXT runtime·xchg(SB), NOSPLIT, $0-20
   496  	MOVD	ptr+0(FP), R4
   497  	MOVW	new+8(FP), R5
   498  	SYNC
   499  	LWAR	(R4), R3
   500  	STWCCC	R5, (R4)
   501  	BNE	-3(PC)
   502  	SYNC
   503  	ISYNC
   504  	MOVW	R3, ret+16(FP)
   505  	RETURN
   506  
   507  TEXT runtime·xchg64(SB), NOSPLIT, $0-24
   508  	MOVD	ptr+0(FP), R4
   509  	MOVD	new+8(FP), R5
   510  	SYNC
   511  	LDAR	(R4), R3
   512  	STDCCC	R5, (R4)
   513  	BNE	-3(PC)
   514  	SYNC
   515  	ISYNC
   516  	MOVD	R3, ret+16(FP)
   517  	RETURN
   518  
   519  TEXT runtime·xchgp1(SB), NOSPLIT, $0-24
   520  	BR	runtime·xchg64(SB)
   521  
   522  TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
   523  	BR	runtime·xchg64(SB)
   524  
   525  TEXT runtime·procyield(SB),NOSPLIT,$0-0
   526  	RETURN
   527  
   528  TEXT runtime·atomicstorep1(SB), NOSPLIT, $0-16
   529  	BR	runtime·atomicstore64(SB)
   530  
   531  TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
   532  	MOVD	ptr+0(FP), R3
   533  	MOVW	val+8(FP), R4
   534  	SYNC
   535  	MOVW	R4, 0(R3)
   536  	RETURN
   537  
   538  TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
   539  	MOVD	ptr+0(FP), R3
   540  	MOVD	val+8(FP), R4
   541  	SYNC
   542  	MOVD	R4, 0(R3)
   543  	RETURN
   544  
   545  // void	runtime·atomicor8(byte volatile*, byte);
   546  TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
   547  	MOVD	ptr+0(FP), R3
   548  	MOVBZ	val+8(FP), R4
   549  	// Align ptr down to 4 bytes so we can use 32-bit load/store.
   550  	// R5 = (R3 << 0) & ~3
   551  	RLDCR	$0, R3, $~3, R5
   552  	// Compute val shift.
   553  #ifdef GOARCH_ppc64
   554  	// Big endian.  ptr = ptr ^ 3
   555  	XOR	$3, R3
   556  #endif
   557  	// R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
   558  	RLDC	$3, R3, $(3*8), R6
   559  	// Shift val for aligned ptr.  R4 = val << R6
   560  	SLD	R6, R4, R4
   561  
   562  atomicor8_again:
   563  	SYNC
   564  	LWAR	(R5), R6
   565  	OR	R4, R6
   566  	STWCCC	R6, (R5)
   567  	BNE	atomicor8_again
   568  	SYNC
   569  	ISYNC
   570  	RETURN
   571  
   572  // void jmpdefer(fv, sp);
   573  // called from deferreturn.
   574  // 1. grab stored LR for caller
   575  // 2. sub 4 bytes to get back to BL deferreturn
   576  // 3. BR to fn
   577  TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16
   578  	MOVD	0(R1), R31
   579  	SUB	$4, R31
   580  	MOVD	R31, LR
   581  
   582  	MOVD	fv+0(FP), R11
   583  	MOVD	argp+8(FP), R1
   584  	SUB	$8, R1
   585  	MOVD	0(R11), R3
   586  	MOVD	R3, CTR
   587  	BR	(CTR)
   588  
   589  // Save state of caller into g->sched. Smashes R31.
   590  TEXT gosave<>(SB),NOSPLIT,$-8
   591  	MOVD	LR, R31
   592  	MOVD	R31, (g_sched+gobuf_pc)(g)
   593  	MOVD	R1, (g_sched+gobuf_sp)(g)
   594  	MOVD	R0, (g_sched+gobuf_lr)(g)
   595  	MOVD	R0, (g_sched+gobuf_ret)(g)
   596  	MOVD	R0, (g_sched+gobuf_ctxt)(g)
   597  	RETURN
   598  
   599  // asmcgocall(void(*fn)(void*), void *arg)
   600  // Call fn(arg) on the scheduler stack,
   601  // aligned appropriately for the gcc ABI.
   602  // See cgocall.c for more details.
   603  TEXT ·asmcgocall(SB),NOSPLIT,$0-16
   604  	MOVD	R0, 21(R0)
   605  
   606  // cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
   607  // Turn the fn into a Go func (by taking its address) and call
   608  // cgocallback_gofunc.
   609  TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
   610  	MOVD	R0, 22(R0)
   611  
   612  // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
   613  // See cgocall.c for more details.
   614  TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24
   615  	MOVD	R0, 23(R0)
   616  
   617  // void setg(G*); set g. for use by needm.
   618  TEXT runtime·setg(SB), NOSPLIT, $0-8
   619  	MOVD	R0, 24(R0)
   620  
   621  // void setg_gcc(G*); set g called from gcc.
   622  TEXT setg_gcc<>(SB),NOSPLIT,$0
   623  	MOVD	R0, 25(R0)
   624  
   625  TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-16
   626  	MOVD	0(R1), R3
   627  	MOVD	R3, ret+8(FP)
   628  	RETURN
   629  
   630  TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-8-16
   631  	MOVD	0(R1), R3
   632  	MOVD	R3,ret+8(FP)
   633  	RETURN
   634  
   635  TEXT runtime·setcallerpc(SB),NOSPLIT,$-8-16
   636  	MOVD	pc+8(FP), R3
   637  	MOVD	R3, 0(R1)		// set calling pc
   638  	RETURN
   639  
   640  TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
   641  	MOVD	argp+0(FP), R3
   642  	SUB	$8, R3
   643  	MOVD	R3, ret+8(FP)
   644  	RETURN
   645  
   646  // func gogetcallersp(p unsafe.Pointer) uintptr
   647  TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
   648  	MOVD	sp+0(FP), R3
   649  	SUB	$8, R3
   650  	MOVD	R3,ret+8(FP)
   651  	RETURN
   652  
   653  TEXT runtime·abort(SB),NOSPLIT,$-8-0
   654  	MOVW	(R0), R0
   655  	UNDEF
   656  
   657  #define	TBRL	268
   658  #define	TBRU	269		/* Time base Upper/Lower */
   659  
   660  // int64 runtime·cputicks(void)
   661  TEXT runtime·cputicks(SB),NOSPLIT,$0-8
   662  	MOVW	SPR(TBRU), R4
   663  	MOVW	SPR(TBRL), R3
   664  	MOVW	SPR(TBRU), R5
   665  	CMPW	R4, R5
   666  	BNE	-4(PC)
   667  	SLD	$32, R5
   668  	OR	R5, R3
   669  	MOVD	R3, ret+0(FP)
   670  	RETURN
   671  
   672  // AES hashing not implemented for ppc64
   673  TEXT runtime·aeshash(SB),NOSPLIT,$-8-0
   674  	MOVW	(R0), R1
   675  TEXT runtime·aeshash32(SB),NOSPLIT,$-8-0
   676  	MOVW	(R0), R1
   677  TEXT runtime·aeshash64(SB),NOSPLIT,$-8-0
   678  	MOVW	(R0), R1
   679  TEXT runtime·aeshashstr(SB),NOSPLIT,$-8-0
   680  	MOVW	(R0), R1
   681  
   682  TEXT runtime·memeq(SB),NOSPLIT,$-8-25
   683  	MOVD	a+0(FP), R3
   684  	MOVD	b+8(FP), R4
   685  	MOVD	size+16(FP), R5
   686  	SUB	$1, R3
   687  	SUB	$1, R4
   688  	ADD	R3, R5, R8
   689  loop:
   690  	CMP	R3, R8
   691  	BNE	test
   692  	MOVD	$1, R3
   693  	MOVB	R3, ret+24(FP)
   694  	RETURN
   695  test:
   696  	MOVBZU	1(R3), R6
   697  	MOVBZU	1(R4), R7
   698  	CMP	R6, R7
   699  	BEQ	loop
   700  
   701  	MOVB	R0, ret+24(FP)
   702  	RETURN
   703  
   704  // eqstring tests whether two strings are equal.
   705  // See runtime_test.go:eqstring_generic for
   706  // equivalent Go code.
   707  TEXT runtime·eqstring(SB),NOSPLIT,$0-33
   708  	MOVD	s1len+8(FP), R4
   709  	MOVD	s2len+24(FP), R5
   710  	CMP	R4, R5
   711  	BNE	noteq
   712  
   713  	MOVD	s1str+0(FP), R3
   714  	MOVD	s2str+16(FP), R4
   715  	SUB	$1, R3
   716  	SUB	$1, R4
   717  	ADD	R3, R5, R8
   718  loop:
   719  	CMP	R3, R8
   720  	BNE	4(PC)
   721  	MOVD	$1, R3
   722  	MOVB	R3, ret+32(FP)
   723  	RETURN
   724  	MOVBZU	1(R3), R6
   725  	MOVBZU	1(R4), R7
   726  	CMP	R6, R7
   727  	BEQ	loop
   728  noteq:
   729  	MOVB	R0, ret+32(FP)
   730  	RETURN
   731  
   732  // TODO: share code with memeq?
   733  TEXT bytes·Equal(SB),NOSPLIT,$0-49
   734  	MOVD	a_len+8(FP), R3
   735  	MOVD	b_len+32(FP), R4
   736  
   737  	CMP	R3, R4		// unequal lengths are not equal
   738  	BNE	noteq
   739  
   740  	MOVD	a+0(FP), R5
   741  	MOVD	b+24(FP), R6
   742  	SUB	$1, R5
   743  	SUB	$1, R6
   744  	ADD	R5, R3		// end-1
   745  
   746  loop:
   747  	CMP	R5, R3
   748  	BEQ	equal		// reached the end
   749  	MOVBZU	1(R5), R4
   750  	MOVBZU	1(R6), R7
   751  	CMP	R4, R7
   752  	BEQ	loop
   753  
   754  noteq:
   755  	MOVBZ	R0, ret+48(FP)
   756  	RETURN
   757  
   758  equal:
   759  	MOVD	$1, R3
   760  	MOVBZ	R3, ret+48(FP)
   761  	RETURN
   762  
   763  TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
   764  	MOVD	s+0(FP), R3
   765  	MOVD	s_len+8(FP), R4
   766  	MOVBZ	c+24(FP), R5	// byte to find
   767  	MOVD	R3, R6		// store base for later
   768  	SUB	$1, R3
   769  	ADD	R3, R4		// end-1
   770  
   771  loop:
   772  	CMP	R3, R4
   773  	BEQ	notfound
   774  	MOVBZU	1(R3), R7
   775  	CMP	R7, R5
   776  	BNE	loop
   777  
   778  	SUB	R6, R3		// remove base
   779  	MOVD	R3, ret+32(FP)
   780  	RETURN
   781  
   782  notfound:
   783  	MOVD	$-1, R3
   784  	MOVD	R3, ret+32(FP)
   785  	RETURN
   786  
   787  TEXT strings·IndexByte(SB),NOSPLIT,$0
   788  	MOVD	p+0(FP), R3
   789  	MOVD	b_len+8(FP), R4
   790  	MOVBZ	c+16(FP), R5	// byte to find
   791  	MOVD	R3, R6		// store base for later
   792  	SUB	$1, R3
   793  	ADD	R3, R4		// end-1
   794  
   795  loop:
   796  	CMP	R3, R4
   797  	BEQ	notfound
   798  	MOVBZU	1(R3), R7
   799  	CMP	R7, R5
   800  	BNE	loop
   801  
   802  	SUB	R6, R3		// remove base
   803  	MOVD	R3, ret+24(FP)
   804  	RETURN
   805  
   806  notfound:
   807  	MOVD	$-1, R3
   808  	MOVD	R3, ret+24(FP)
   809  	RETURN
   810  
   811  
   812  // A Duff's device for zeroing memory.
   813  // The compiler jumps to computed addresses within
   814  // this routine to zero chunks of memory.  Do not
   815  // change this code without also changing the code
   816  // in ../../cmd/9g/ggen.c:/^clearfat.
   817  // R0: always zero
   818  // R3 (aka REGRT1): ptr to memory to be zeroed - 8
   819  // On return, R3 points to the last zeroed dword.
   820  TEXT runtime·duffzero(SB), NOSPLIT, $-8-0
   821  	MOVDU	R0, 8(R3)
   822  	MOVDU	R0, 8(R3)
   823  	MOVDU	R0, 8(R3)
   824  	MOVDU	R0, 8(R3)
   825  	MOVDU	R0, 8(R3)
   826  	MOVDU	R0, 8(R3)
   827  	MOVDU	R0, 8(R3)
   828  	MOVDU	R0, 8(R3)
   829  	MOVDU	R0, 8(R3)
   830  	MOVDU	R0, 8(R3)
   831  	MOVDU	R0, 8(R3)
   832  	MOVDU	R0, 8(R3)
   833  	MOVDU	R0, 8(R3)
   834  	MOVDU	R0, 8(R3)
   835  	MOVDU	R0, 8(R3)
   836  	MOVDU	R0, 8(R3)
   837  	MOVDU	R0, 8(R3)
   838  	MOVDU	R0, 8(R3)
   839  	MOVDU	R0, 8(R3)
   840  	MOVDU	R0, 8(R3)
   841  	MOVDU	R0, 8(R3)
   842  	MOVDU	R0, 8(R3)
   843  	MOVDU	R0, 8(R3)
   844  	MOVDU	R0, 8(R3)
   845  	MOVDU	R0, 8(R3)
   846  	MOVDU	R0, 8(R3)
   847  	MOVDU	R0, 8(R3)
   848  	MOVDU	R0, 8(R3)
   849  	MOVDU	R0, 8(R3)
   850  	MOVDU	R0, 8(R3)
   851  	MOVDU	R0, 8(R3)
   852  	MOVDU	R0, 8(R3)
   853  	MOVDU	R0, 8(R3)
   854  	MOVDU	R0, 8(R3)
   855  	MOVDU	R0, 8(R3)
   856  	MOVDU	R0, 8(R3)
   857  	MOVDU	R0, 8(R3)
   858  	MOVDU	R0, 8(R3)
   859  	MOVDU	R0, 8(R3)
   860  	MOVDU	R0, 8(R3)
   861  	MOVDU	R0, 8(R3)
   862  	MOVDU	R0, 8(R3)
   863  	MOVDU	R0, 8(R3)
   864  	MOVDU	R0, 8(R3)
   865  	MOVDU	R0, 8(R3)
   866  	MOVDU	R0, 8(R3)
   867  	MOVDU	R0, 8(R3)
   868  	MOVDU	R0, 8(R3)
   869  	MOVDU	R0, 8(R3)
   870  	MOVDU	R0, 8(R3)
   871  	MOVDU	R0, 8(R3)
   872  	MOVDU	R0, 8(R3)
   873  	MOVDU	R0, 8(R3)
   874  	MOVDU	R0, 8(R3)
   875  	MOVDU	R0, 8(R3)
   876  	MOVDU	R0, 8(R3)
   877  	MOVDU	R0, 8(R3)
   878  	MOVDU	R0, 8(R3)
   879  	MOVDU	R0, 8(R3)
   880  	MOVDU	R0, 8(R3)
   881  	MOVDU	R0, 8(R3)
   882  	MOVDU	R0, 8(R3)
   883  	MOVDU	R0, 8(R3)
   884  	MOVDU	R0, 8(R3)
   885  	MOVDU	R0, 8(R3)
   886  	MOVDU	R0, 8(R3)
   887  	MOVDU	R0, 8(R3)
   888  	MOVDU	R0, 8(R3)
   889  	MOVDU	R0, 8(R3)
   890  	MOVDU	R0, 8(R3)
   891  	MOVDU	R0, 8(R3)
   892  	MOVDU	R0, 8(R3)
   893  	MOVDU	R0, 8(R3)
   894  	MOVDU	R0, 8(R3)
   895  	MOVDU	R0, 8(R3)
   896  	MOVDU	R0, 8(R3)
   897  	MOVDU	R0, 8(R3)
   898  	MOVDU	R0, 8(R3)
   899  	MOVDU	R0, 8(R3)
   900  	MOVDU	R0, 8(R3)
   901  	MOVDU	R0, 8(R3)
   902  	MOVDU	R0, 8(R3)
   903  	MOVDU	R0, 8(R3)
   904  	MOVDU	R0, 8(R3)
   905  	MOVDU	R0, 8(R3)
   906  	MOVDU	R0, 8(R3)
   907  	MOVDU	R0, 8(R3)
   908  	MOVDU	R0, 8(R3)
   909  	MOVDU	R0, 8(R3)
   910  	MOVDU	R0, 8(R3)
   911  	MOVDU	R0, 8(R3)
   912  	MOVDU	R0, 8(R3)
   913  	MOVDU	R0, 8(R3)
   914  	MOVDU	R0, 8(R3)
   915  	MOVDU	R0, 8(R3)
   916  	MOVDU	R0, 8(R3)
   917  	MOVDU	R0, 8(R3)
   918  	MOVDU	R0, 8(R3)
   919  	MOVDU	R0, 8(R3)
   920  	MOVDU	R0, 8(R3)
   921  	MOVDU	R0, 8(R3)
   922  	MOVDU	R0, 8(R3)
   923  	MOVDU	R0, 8(R3)
   924  	MOVDU	R0, 8(R3)
   925  	MOVDU	R0, 8(R3)
   926  	MOVDU	R0, 8(R3)
   927  	MOVDU	R0, 8(R3)
   928  	MOVDU	R0, 8(R3)
   929  	MOVDU	R0, 8(R3)
   930  	MOVDU	R0, 8(R3)
   931  	MOVDU	R0, 8(R3)
   932  	MOVDU	R0, 8(R3)
   933  	MOVDU	R0, 8(R3)
   934  	MOVDU	R0, 8(R3)
   935  	MOVDU	R0, 8(R3)
   936  	MOVDU	R0, 8(R3)
   937  	MOVDU	R0, 8(R3)
   938  	MOVDU	R0, 8(R3)
   939  	MOVDU	R0, 8(R3)
   940  	MOVDU	R0, 8(R3)
   941  	MOVDU	R0, 8(R3)
   942  	MOVDU	R0, 8(R3)
   943  	MOVDU	R0, 8(R3)
   944  	MOVDU	R0, 8(R3)
   945  	MOVDU	R0, 8(R3)
   946  	MOVDU	R0, 8(R3)
   947  	MOVDU	R0, 8(R3)
   948  	MOVDU	R0, 8(R3)
   949  	RETURN
   950  
   951  TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
   952  	MOVD	g_m(g), R4
   953  	MOVWZ	m_fastrand(R4), R3
   954  	ADD	R3, R3
   955  	CMPW	R3, $0
   956  	BGE	2(PC)
   957  	XOR	$0x88888eef, R3
   958  	MOVW	R3, m_fastrand(R4)
   959  	MOVW	R3, ret+0(FP)
   960  	RETURN
   961  
   962  TEXT runtime·return0(SB), NOSPLIT, $0
   963  	MOVW	$0, R3
   964  	RETURN
   965  
   966  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   967  // Must obey the gcc calling convention.
   968  TEXT _cgo_topofstack(SB),NOSPLIT,$0
   969  	MOVD	R0, 26(R0)
   970  
   971  // The top-most function running on a goroutine
   972  // returns to goexit+PCQuantum.
   973  TEXT runtime·goexit(SB),NOSPLIT,$-8-0
   974  	MOVD	R0, R0	// NOP
   975  	BL	runtime·goexit1(SB)	// does not return
   976  
   977  TEXT runtime·getg(SB),NOSPLIT,$-8-8
   978  	MOVD	g, ret+0(FP)
   979  	RETURN
   980  
   981  TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
   982  	RETURN
   983  
   984  TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
   985  	RETURN
   986  
   987  TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
   988  	RETURN
   989  
   990  TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
   991  	RETURN