github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/sys_linux_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  //go:build linux && (ppc64 || ppc64le)
     6  // +build linux
     7  // +build ppc64 ppc64le
     8  
     9  //
    10  // System calls and other sys.stuff for ppc64, Linux
    11  //
    12  
    13  #include "go_asm.h"
    14  #include "go_tls.h"
    15  #include "textflag.h"
    16  #include "asm_ppc64x.h"
    17  
    18  #define SYS_exit		  1
    19  #define SYS_read		  3
    20  #define SYS_write		  4
    21  #define SYS_open		  5
    22  #define SYS_close		  6
    23  #define SYS_getpid		 20
    24  #define SYS_kill		 37
    25  #define SYS_pipe		 42
    26  #define SYS_brk			 45
    27  #define SYS_fcntl		 55
    28  #define SYS_mmap		 90
    29  #define SYS_munmap		 91
    30  #define SYS_setitimer		104
    31  #define SYS_clone		120
    32  #define SYS_sched_yield		158
    33  #define SYS_nanosleep		162
    34  #define SYS_rt_sigreturn	172
    35  #define SYS_rt_sigaction	173
    36  #define SYS_rt_sigprocmask	174
    37  #define SYS_sigaltstack		185
    38  #define SYS_madvise		205
    39  #define SYS_mincore		206
    40  #define SYS_gettid		207
    41  #define SYS_futex		221
    42  #define SYS_sched_getaffinity	223
    43  #define SYS_exit_group		234
    44  #define SYS_epoll_create	236
    45  #define SYS_epoll_ctl		237
    46  #define SYS_epoll_wait		238
    47  #define SYS_clock_gettime	246
    48  #define SYS_tgkill		250
    49  #define SYS_epoll_create1	315
    50  #define SYS_pipe2		317
    51  
    52  TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
    53  	MOVW	code+0(FP), R3
    54  	SYSCALL	$SYS_exit_group
    55  	RET
    56  
    57  // func exitThread(wait *uint32)
    58  TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
    59  	MOVD	wait+0(FP), R1
    60  	// We're done using the stack.
    61  	MOVW	$0, R2
    62  	SYNC
    63  	MOVW	R2, (R1)
    64  	MOVW	$0, R3	// exit code
    65  	SYSCALL	$SYS_exit
    66  	JMP	0(PC)
    67  
    68  TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
    69  	MOVD	name+0(FP), R3
    70  	MOVW	mode+8(FP), R4
    71  	MOVW	perm+12(FP), R5
    72  	SYSCALL	$SYS_open
    73  	BVC	2(PC)
    74  	MOVW	$-1, R3
    75  	MOVW	R3, ret+16(FP)
    76  	RET
    77  
    78  TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
    79  	MOVW	fd+0(FP), R3
    80  	SYSCALL	$SYS_close
    81  	BVC	2(PC)
    82  	MOVW	$-1, R3
    83  	MOVW	R3, ret+8(FP)
    84  	RET
    85  
    86  TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
    87  	MOVD	fd+0(FP), R3
    88  	MOVD	p+8(FP), R4
    89  	MOVW	n+16(FP), R5
    90  	SYSCALL	$SYS_write
    91  	BVC	2(PC)
    92  	NEG	R3	// caller expects negative errno
    93  	MOVW	R3, ret+24(FP)
    94  	RET
    95  
    96  TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
    97  	MOVW	fd+0(FP), R3
    98  	MOVD	p+8(FP), R4
    99  	MOVW	n+16(FP), R5
   100  	SYSCALL	$SYS_read
   101  	BVC	2(PC)
   102  	NEG	R3	// caller expects negative errno
   103  	MOVW	R3, ret+24(FP)
   104  	RET
   105  
   106  // func pipe() (r, w int32, errno int32)
   107  TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
   108  	ADD	$FIXED_FRAME, R1, R3
   109  	SYSCALL	$SYS_pipe
   110  	MOVW	R3, errno+8(FP)
   111  	RET
   112  
   113  // func pipe2(flags int32) (r, w int32, errno int32)
   114  TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
   115  	ADD	$FIXED_FRAME+8, R1, R3
   116  	MOVW	flags+0(FP), R4
   117  	SYSCALL	$SYS_pipe2
   118  	MOVW	R3, errno+16(FP)
   119  	RET
   120  
   121  TEXT runtime·usleep(SB),NOSPLIT,$16-4
   122  	MOVW	usec+0(FP), R3
   123  	MOVD	R3, R5
   124  	MOVW	$1000000, R4
   125  	DIVD	R4, R3
   126  	MOVD	R3, 8(R1)
   127  	MOVW	$1000, R4
   128  	MULLD	R3, R4
   129  	SUB	R4, R5
   130  	MOVD	R5, 16(R1)
   131  
   132  	// nanosleep(&ts, 0)
   133  	ADD	$8, R1, R3
   134  	MOVW	$0, R4
   135  	SYSCALL	$SYS_nanosleep
   136  	RET
   137  
   138  TEXT runtime·gettid(SB),NOSPLIT,$0-4
   139  	SYSCALL	$SYS_gettid
   140  	MOVW	R3, ret+0(FP)
   141  	RET
   142  
   143  TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
   144  	SYSCALL	$SYS_getpid
   145  	MOVW	R3, R14
   146  	SYSCALL	$SYS_gettid
   147  	MOVW	R3, R4	// arg 2 tid
   148  	MOVW	R14, R3	// arg 1 pid
   149  	MOVW	sig+0(FP), R5	// arg 3
   150  	SYSCALL	$SYS_tgkill
   151  	RET
   152  
   153  TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
   154  	SYSCALL	$SYS_getpid
   155  	MOVW	R3, R3	// arg 1 pid
   156  	MOVW	sig+0(FP), R4	// arg 2
   157  	SYSCALL	$SYS_kill
   158  	RET
   159  
   160  TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
   161  	SYSCALL $SYS_getpid
   162  	MOVD	R3, ret+0(FP)
   163  	RET
   164  
   165  TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
   166  	MOVD	tgid+0(FP), R3
   167  	MOVD	tid+8(FP), R4
   168  	MOVD	sig+16(FP), R5
   169  	SYSCALL $SYS_tgkill
   170  	RET
   171  
   172  TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
   173  	MOVW	mode+0(FP), R3
   174  	MOVD	new+8(FP), R4
   175  	MOVD	old+16(FP), R5
   176  	SYSCALL	$SYS_setitimer
   177  	RET
   178  
   179  TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
   180  	MOVD	addr+0(FP), R3
   181  	MOVD	n+8(FP), R4
   182  	MOVD	dst+16(FP), R5
   183  	SYSCALL	$SYS_mincore
   184  	NEG	R3		// caller expects negative errno
   185  	MOVW	R3, ret+24(FP)
   186  	RET
   187  
   188  // func walltime() (sec int64, nsec int32)
   189  TEXT runtime·walltime(SB),NOSPLIT,$16-12
   190  	MOVD	R1, R15		// R15 is unchanged by C code
   191  	MOVD	g_m(g), R21	// R21 = m
   192  
   193  	MOVD	$0, R3		// CLOCK_REALTIME
   194  
   195  	MOVD	runtime·vdsoClockgettimeSym(SB), R12	// Check for VDSO availability
   196  	CMP	R12, R0
   197  	BEQ	fallback
   198  
   199  	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   200  	// Save the old values on stack and restore them on exit,
   201  	// so this function is reentrant.
   202  	MOVD	m_vdsoPC(R21), R4
   203  	MOVD	m_vdsoSP(R21), R5
   204  	MOVD	R4, 32(R1)
   205  	MOVD	R5, 40(R1)
   206  
   207  	MOVD	LR, R14
   208  	MOVD	$ret-FIXED_FRAME(FP), R5 // caller's SP
   209  	MOVD	R14, m_vdsoPC(R21)
   210  	MOVD	R5, m_vdsoSP(R21)
   211  
   212  	MOVD	m_curg(R21), R6
   213  	CMP	g, R6
   214  	BNE	noswitch
   215  
   216  	MOVD	m_g0(R21), R7
   217  	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
   218  
   219  noswitch:
   220  	SUB	$16, R1                 // Space for results
   221  	RLDICR	$0, R1, $59, R1         // Align for C code
   222  	MOVD	R12, CTR
   223  	MOVD	R1, R4
   224  
   225  	// Store g on gsignal's stack, so if we receive a signal
   226  	// during VDSO code we can find the g.
   227  	// If we don't have a signal stack, we won't receive signal,
   228  	// so don't bother saving g.
   229  	// When using cgo, we already saved g on TLS, also don't save
   230  	// g here.
   231  	// Also don't save g if we are already on the signal stack.
   232  	// We won't get a nested signal.
   233  	MOVBZ	runtime·iscgo(SB), R22
   234  	CMP	R22, $0
   235  	BNE	nosaveg
   236  	MOVD	m_gsignal(R21), R22	// g.m.gsignal
   237  	CMP	R22, $0
   238  	BEQ	nosaveg
   239  
   240  	CMP	g, R22
   241  	BEQ	nosaveg
   242  	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   243  	MOVD	g, (R22)
   244  
   245  	BL	(CTR)	// Call from VDSO
   246  
   247  	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
   248  
   249  	JMP	finish
   250  
   251  nosaveg:
   252  	BL	(CTR)	// Call from VDSO
   253  
   254  finish:
   255  	MOVD	$0, R0		// Restore R0
   256  	MOVD	0(R1), R3	// sec
   257  	MOVD	8(R1), R5	// nsec
   258  	MOVD	R15, R1		// Restore SP
   259  
   260  	// Restore vdsoPC, vdsoSP
   261  	// We don't worry about being signaled between the two stores.
   262  	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   263  	// and no one will care about vdsoPC. If we are in a signal handler,
   264  	// we cannot receive another signal.
   265  	MOVD	40(R1), R6
   266  	MOVD	R6, m_vdsoSP(R21)
   267  	MOVD	32(R1), R6
   268  	MOVD	R6, m_vdsoPC(R21)
   269  
   270  return:
   271  	MOVD	R3, sec+0(FP)
   272  	MOVW	R5, nsec+8(FP)
   273  	RET
   274  
   275  	// Syscall fallback
   276  fallback:
   277  	ADD	$32, R1, R4
   278  	SYSCALL $SYS_clock_gettime
   279  	MOVD	32(R1), R3
   280  	MOVD	40(R1), R5
   281  	JMP	return
   282  
   283  TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
   284  	MOVD	$1, R3		// CLOCK_MONOTONIC
   285  
   286  	MOVD	R1, R15		// R15 is unchanged by C code
   287  	MOVD	g_m(g), R21	// R21 = m
   288  
   289  	MOVD	runtime·vdsoClockgettimeSym(SB), R12	// Check for VDSO availability
   290  	CMP	R12, R0
   291  	BEQ	fallback
   292  
   293  	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   294  	// Save the old values on stack and restore them on exit,
   295  	// so this function is reentrant.
   296  	MOVD	m_vdsoPC(R21), R4
   297  	MOVD	m_vdsoSP(R21), R5
   298  	MOVD	R4, 32(R1)
   299  	MOVD	R5, 40(R1)
   300  
   301  	MOVD	LR, R14				// R14 is unchanged by C code
   302  	MOVD	$ret-FIXED_FRAME(FP), R5	// caller's SP
   303  	MOVD	R14, m_vdsoPC(R21)
   304  	MOVD	R5, m_vdsoSP(R21)
   305  
   306  	MOVD	m_curg(R21), R6
   307  	CMP	g, R6
   308  	BNE	noswitch
   309  
   310  	MOVD	m_g0(R21), R7
   311  	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
   312  
   313  noswitch:
   314  	SUB	$16, R1			// Space for results
   315  	RLDICR	$0, R1, $59, R1		// Align for C code
   316  	MOVD	R12, CTR
   317  	MOVD	R1, R4
   318  
   319  	// Store g on gsignal's stack, so if we receive a signal
   320  	// during VDSO code we can find the g.
   321  	// If we don't have a signal stack, we won't receive signal,
   322  	// so don't bother saving g.
   323  	// When using cgo, we already saved g on TLS, also don't save
   324  	// g here.
   325  	// Also don't save g if we are already on the signal stack.
   326  	// We won't get a nested signal.
   327  	MOVBZ	runtime·iscgo(SB), R22
   328  	CMP	R22, $0
   329  	BNE	nosaveg
   330  	MOVD	m_gsignal(R21), R22	// g.m.gsignal
   331  	CMP	R22, $0
   332  	BEQ	nosaveg
   333  
   334  	CMP	g, R22
   335  	BEQ	nosaveg
   336  	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   337  	MOVD	g, (R22)
   338  
   339  	BL	(CTR)	// Call from VDSO
   340  
   341  	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
   342  
   343  	JMP	finish
   344  
   345  nosaveg:
   346  	BL	(CTR)	// Call from VDSO
   347  
   348  finish:
   349  	MOVD	$0, R0			// Restore R0
   350  	MOVD	0(R1), R3		// sec
   351  	MOVD	8(R1), R5		// nsec
   352  	MOVD	R15, R1			// Restore SP
   353  
   354  	// Restore vdsoPC, vdsoSP
   355  	// We don't worry about being signaled between the two stores.
   356  	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   357  	// and no one will care about vdsoPC. If we are in a signal handler,
   358  	// we cannot receive another signal.
   359  	MOVD	40(R1), R6
   360  	MOVD	R6, m_vdsoSP(R21)
   361  	MOVD	32(R1), R6
   362  	MOVD	R6, m_vdsoPC(R21)
   363  
   364  return:
   365  	// sec is in R3, nsec in R5
   366  	// return nsec in R3
   367  	MOVD	$1000000000, R4
   368  	MULLD	R4, R3
   369  	ADD	R5, R3
   370  	MOVD	R3, ret+0(FP)
   371  	RET
   372  
   373  	// Syscall fallback
   374  fallback:
   375  	ADD	$32, R1, R4
   376  	SYSCALL $SYS_clock_gettime
   377  	MOVD	32(R1), R3
   378  	MOVD	40(R1), R5
   379  	JMP	return
   380  
   381  TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
   382  	MOVW	how+0(FP), R3
   383  	MOVD	new+8(FP), R4
   384  	MOVD	old+16(FP), R5
   385  	MOVW	size+24(FP), R6
   386  	SYSCALL	$SYS_rt_sigprocmask
   387  	BVC	2(PC)
   388  	MOVD	R0, 0xf0(R0)	// crash
   389  	RET
   390  
   391  TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
   392  	MOVD	sig+0(FP), R3
   393  	MOVD	new+8(FP), R4
   394  	MOVD	old+16(FP), R5
   395  	MOVD	size+24(FP), R6
   396  	SYSCALL	$SYS_rt_sigaction
   397  	BVC	2(PC)
   398  	NEG	R3	// caller expects negative errno
   399  	MOVW	R3, ret+32(FP)
   400  	RET
   401  
   402  #ifdef GOARCH_ppc64le
   403  // Call the function stored in _cgo_sigaction using the GCC calling convention.
   404  TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
   405  	MOVD    sig+0(FP), R3
   406  	MOVD    new+8(FP), R4
   407  	MOVD    old+16(FP), R5
   408  	MOVD     _cgo_sigaction(SB), R12
   409  	MOVD    R12, CTR                // R12 should contain the function address
   410  	MOVD    R1, R15                 // Save R1
   411  	MOVD    R2, 24(R1)              // Save R2
   412  	SUB     $48, R1                 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved.
   413  	RLDICR  $0, R1, $59, R1         // Align to 16 bytes for C code
   414  	BL      (CTR)
   415  	XOR     R0, R0, R0              // Clear R0 as Go expects
   416  	MOVD    R15, R1                 // Restore R1
   417  	MOVD    24(R1), R2              // Restore R2
   418  	MOVW    R3, ret+24(FP)          // Return result
   419  	RET
   420  #endif
   421  
   422  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   423  	MOVW	sig+8(FP), R3
   424  	MOVD	info+16(FP), R4
   425  	MOVD	ctx+24(FP), R5
   426  	MOVD	fn+0(FP), R12
   427  	MOVD	R12, CTR
   428  	BL	(CTR)
   429  	MOVD	24(R1), R2
   430  	RET
   431  
   432  TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
   433  	RET
   434  
   435  #ifdef GOARCH_ppc64le
   436  // ppc64le doesn't need function descriptors
   437  // Save callee-save registers in the case of signal forwarding.
   438  // Same as on ARM64 https://golang.org/issue/31827 .
   439  TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
   440  #else
   441  // function descriptor for the real sigtramp
   442  TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
   443  	DWORD	$sigtramp<>(SB)
   444  	DWORD	$0
   445  	DWORD	$0
   446  TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0
   447  #endif
   448  	// Start with standard C stack frame layout and linkage.
   449  	MOVD    LR, R0
   450  	MOVD    R0, 16(R1) // Save LR in caller's frame.
   451  	MOVW    CR, R0     // Save CR in caller's frame
   452  	MOVD    R0, 8(R1)
   453  	// The stack must be acquired here and not
   454  	// in the automatic way based on stack size
   455  	// since that sequence clobbers R31 before it
   456  	// gets saved.
   457  	// We are being ultra safe here in saving the
   458  	// Vregs. The case where they might need to
   459  	// be saved is very unlikely.
   460  	MOVDU   R1, -544(R1)
   461  	MOVD    R14, 64(R1)
   462  	MOVD    R15, 72(R1)
   463  	MOVD    R16, 80(R1)
   464  	MOVD    R17, 88(R1)
   465  	MOVD    R18, 96(R1)
   466  	MOVD    R19, 104(R1)
   467  	MOVD    R20, 112(R1)
   468  	MOVD    R21, 120(R1)
   469  	MOVD    R22, 128(R1)
   470  	MOVD    R23, 136(R1)
   471  	MOVD    R24, 144(R1)
   472  	MOVD    R25, 152(R1)
   473  	MOVD    R26, 160(R1)
   474  	MOVD    R27, 168(R1)
   475  	MOVD    R28, 176(R1)
   476  	MOVD    R29, 184(R1)
   477  	MOVD    g, 192(R1) // R30
   478  	MOVD    R31, 200(R1)
   479  	FMOVD   F14, 208(R1)
   480  	FMOVD   F15, 216(R1)
   481  	FMOVD   F16, 224(R1)
   482  	FMOVD   F17, 232(R1)
   483  	FMOVD   F18, 240(R1)
   484  	FMOVD   F19, 248(R1)
   485  	FMOVD   F20, 256(R1)
   486  	FMOVD   F21, 264(R1)
   487  	FMOVD   F22, 272(R1)
   488  	FMOVD   F23, 280(R1)
   489  	FMOVD   F24, 288(R1)
   490  	FMOVD   F25, 296(R1)
   491  	FMOVD   F26, 304(R1)
   492  	FMOVD   F27, 312(R1)
   493  	FMOVD   F28, 320(R1)
   494  	FMOVD   F29, 328(R1)
   495  	FMOVD   F30, 336(R1)
   496  	FMOVD   F31, 344(R1)
   497  	// Save V regs
   498  	// STXVD2X and LXVD2X used since
   499  	// we aren't sure of alignment.
   500  	// Endianness doesn't matter
   501  	// if we are just loading and
   502  	// storing values.
   503  	MOVD	$352, R7 // V20
   504  	STXVD2X VS52, (R7)(R1)
   505  	ADD	$16, R7 // V21 368
   506  	STXVD2X VS53, (R7)(R1)
   507  	ADD	$16, R7 // V22 384
   508  	STXVD2X VS54, (R7)(R1)
   509  	ADD	$16, R7 // V23 400
   510  	STXVD2X VS55, (R7)(R1)
   511  	ADD	$16, R7 // V24 416
   512  	STXVD2X	VS56, (R7)(R1)
   513  	ADD	$16, R7 // V25 432
   514  	STXVD2X	VS57, (R7)(R1)
   515  	ADD	$16, R7 // V26 448
   516  	STXVD2X VS58, (R7)(R1)
   517  	ADD	$16, R7 // V27 464
   518  	STXVD2X VS59, (R7)(R1)
   519  	ADD	$16, R7 // V28 480
   520  	STXVD2X VS60, (R7)(R1)
   521  	ADD	$16, R7 // V29 496
   522  	STXVD2X VS61, (R7)(R1)
   523  	ADD	$16, R7 // V30 512
   524  	STXVD2X VS62, (R7)(R1)
   525  	ADD	$16, R7 // V31 528
   526  	STXVD2X VS63, (R7)(R1)
   527  
   528  	// initialize essential registers (just in case)
   529  	BL	runtime·reginit(SB)
   530  
   531  	// this might be called in external code context,
   532  	// where g is not set.
   533  	MOVBZ	runtime·iscgo(SB), R6
   534  	CMP	R6, $0
   535  	BEQ	2(PC)
   536  	BL	runtime·load_g(SB)
   537  
   538  	MOVW	R3, FIXED_FRAME+0(R1)
   539  	MOVD	R4, FIXED_FRAME+8(R1)
   540  	MOVD	R5, FIXED_FRAME+16(R1)
   541  	MOVD	$runtime·sigtrampgo(SB), R12
   542  	MOVD	R12, CTR
   543  	BL	(CTR)
   544  	MOVD	24(R1), R2 // Should this be here? Where is it saved?
   545  	// Starts at 64; FIXED_FRAME is 32
   546  	MOVD    64(R1), R14
   547  	MOVD    72(R1), R15
   548  	MOVD    80(R1), R16
   549  	MOVD    88(R1), R17
   550  	MOVD    96(R1), R18
   551  	MOVD    104(R1), R19
   552  	MOVD    112(R1), R20
   553  	MOVD    120(R1), R21
   554  	MOVD    128(R1), R22
   555  	MOVD    136(R1), R23
   556  	MOVD    144(R1), R24
   557  	MOVD    152(R1), R25
   558  	MOVD    160(R1), R26
   559  	MOVD    168(R1), R27
   560  	MOVD    176(R1), R28
   561  	MOVD    184(R1), R29
   562  	MOVD    192(R1), g // R30
   563  	MOVD    200(R1), R31
   564  	FMOVD   208(R1), F14
   565  	FMOVD   216(R1), F15
   566  	FMOVD   224(R1), F16
   567  	FMOVD   232(R1), F17
   568  	FMOVD   240(R1), F18
   569  	FMOVD   248(R1), F19
   570  	FMOVD   256(R1), F20
   571  	FMOVD   264(R1), F21
   572  	FMOVD   272(R1), F22
   573  	FMOVD   280(R1), F23
   574  	FMOVD   288(R1), F24
   575  	FMOVD   292(R1), F25
   576  	FMOVD   300(R1), F26
   577  	FMOVD   308(R1), F27
   578  	FMOVD   316(R1), F28
   579  	FMOVD   328(R1), F29
   580  	FMOVD   336(R1), F30
   581  	FMOVD   344(R1), F31
   582  	MOVD	$352, R7
   583  	LXVD2X	(R7)(R1), VS52
   584  	ADD	$16, R7 // 368 V21
   585  	LXVD2X	(R7)(R1), VS53
   586  	ADD	$16, R7 // 384 V22
   587  	LXVD2X	(R7)(R1), VS54
   588  	ADD	$16, R7 // 400 V23
   589  	LXVD2X	(R7)(R1), VS55
   590  	ADD	$16, R7 // 416 V24
   591  	LXVD2X	(R7)(R1), VS56
   592  	ADD	$16, R7 // 432 V25
   593  	LXVD2X	(R7)(R1), VS57
   594  	ADD	$16, R7 // 448 V26
   595  	LXVD2X	(R7)(R1), VS58
   596  	ADD	$16, R8 // 464 V27
   597  	LXVD2X	(R7)(R1), VS59
   598  	ADD	$16, R7 // 480 V28
   599  	LXVD2X	(R7)(R1), VS60
   600  	ADD	$16, R7 // 496 V29
   601  	LXVD2X	(R7)(R1), VS61
   602  	ADD	$16, R7 // 512 V30
   603  	LXVD2X	(R7)(R1), VS62
   604  	ADD	$16, R7 // 528 V31
   605  	LXVD2X	(R7)(R1), VS63
   606  	ADD	$544, R1
   607  	MOVD	8(R1), R0
   608  	MOVFL	R0, $0xff
   609  	MOVD	16(R1), R0
   610  	MOVD	R0, LR
   611  
   612  	RET
   613  
   614  #ifdef GOARCH_ppc64le
   615  // ppc64le doesn't need function descriptors
   616  TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
   617  	// The stack unwinder, presumably written in C, may not be able to
   618  	// handle Go frame correctly. So, this function is NOFRAME, and we
   619  	// save/restore LR manually.
   620  	MOVD	LR, R10
   621  
   622  	// We're coming from C code, initialize essential registers.
   623  	CALL	runtime·reginit(SB)
   624  
   625  	// If no traceback function, do usual sigtramp.
   626  	MOVD	runtime·cgoTraceback(SB), R6
   627  	CMP	$0, R6
   628  	BEQ	sigtramp
   629  
   630  	// If no traceback support function, which means that
   631  	// runtime/cgo was not linked in, do usual sigtramp.
   632  	MOVD	_cgo_callers(SB), R6
   633  	CMP	$0, R6
   634  	BEQ	sigtramp
   635  
   636  	// Set up g register.
   637  	CALL	runtime·load_g(SB)
   638  
   639  	// Figure out if we are currently in a cgo call.
   640  	// If not, just do usual sigtramp.
   641  	// compared to ARM64 and others.
   642  	CMP	$0, g
   643  	BEQ	sigtrampnog // g == nil
   644  	MOVD	g_m(g), R6
   645  	CMP	$0, R6
   646  	BEQ	sigtramp    // g.m == nil
   647  	MOVW	m_ncgo(R6), R7
   648  	CMPW	$0, R7
   649  	BEQ	sigtramp    // g.m.ncgo = 0
   650  	MOVD	m_curg(R6), R7
   651  	CMP	$0, R7
   652  	BEQ	sigtramp    // g.m.curg == nil
   653  	MOVD	g_syscallsp(R7), R7
   654  	CMP	$0, R7
   655  	BEQ	sigtramp    // g.m.curg.syscallsp == 0
   656  	MOVD	m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
   657  	CMP	$0, R7
   658  	BEQ	sigtramp    // g.m.cgoCallers == nil
   659  	MOVW	m_cgoCallersUse(R6), R8
   660  	CMPW	$0, R8
   661  	BNE	sigtramp    // g.m.cgoCallersUse != 0
   662  
   663  	// Jump to a function in runtime/cgo.
   664  	// That function, written in C, will call the user's traceback
   665  	// function with proper unwind info, and will then call back here.
   666  	// The first three arguments, and the fifth, are already in registers.
   667  	// Set the two remaining arguments now.
   668  	MOVD	runtime·cgoTraceback(SB), R6
   669  	MOVD	$runtime·sigtramp(SB), R8
   670  	MOVD	_cgo_callers(SB), R12
   671  	MOVD	R12, CTR
   672  	MOVD	R10, LR // restore LR
   673  	JMP	(CTR)
   674  
   675  sigtramp:
   676  	MOVD	R10, LR // restore LR
   677  	JMP	runtime·sigtramp(SB)
   678  
   679  sigtrampnog:
   680  	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   681  	// stack trace.
   682  	CMPW	R3, $27 // 27 == SIGPROF
   683  	BNE	sigtramp
   684  
   685  	// Lock sigprofCallersUse (cas from 0 to 1).
   686  	MOVW	$1, R7
   687  	MOVD	$runtime·sigprofCallersUse(SB), R8
   688  	SYNC
   689  	LWAR    (R8), R6
   690  	CMPW    $0, R6
   691  	BNE     sigtramp
   692  	STWCCC  R7, (R8)
   693  	BNE     -4(PC)
   694  	ISYNC
   695  
   696  	// Jump to the traceback function in runtime/cgo.
   697  	// It will call back to sigprofNonGo, which will ignore the
   698  	// arguments passed in registers.
   699  	// First three arguments to traceback function are in registers already.
   700  	MOVD	runtime·cgoTraceback(SB), R6
   701  	MOVD	$runtime·sigprofCallers(SB), R7
   702  	MOVD	$runtime·sigprofNonGoWrapper<>(SB), R8
   703  	MOVD	_cgo_callers(SB), R12
   704  	MOVD	R12, CTR
   705  	MOVD	R10, LR // restore LR
   706  	JMP	(CTR)
   707  #else
   708  // function descriptor for the real sigtramp
   709  TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
   710  	DWORD	$cgoSigtramp<>(SB)
   711  	DWORD	$0
   712  	DWORD	$0
   713  TEXT cgoSigtramp<>(SB),NOSPLIT,$0
   714  	JMP	sigtramp<>(SB)
   715  #endif
   716  
   717  TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
   718  	// We're coming from C code, set up essential register, then call sigprofNonGo.
   719  	CALL	runtime·reginit(SB)
   720  	CALL	runtime·sigprofNonGo(SB)
   721  	RET
   722  
   723  TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
   724  	MOVD	addr+0(FP), R3
   725  	MOVD	n+8(FP), R4
   726  	MOVW	prot+16(FP), R5
   727  	MOVW	flags+20(FP), R6
   728  	MOVW	fd+24(FP), R7
   729  	MOVW	off+28(FP), R8
   730  
   731  	SYSCALL	$SYS_mmap
   732  	BVC	ok
   733  	MOVD	$0, p+32(FP)
   734  	MOVD	R3, err+40(FP)
   735  	RET
   736  ok:
   737  	MOVD	R3, p+32(FP)
   738  	MOVD	$0, err+40(FP)
   739  	RET
   740  
   741  TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
   742  	MOVD	addr+0(FP), R3
   743  	MOVD	n+8(FP), R4
   744  	SYSCALL	$SYS_munmap
   745  	BVC	2(PC)
   746  	MOVD	R0, 0xf0(R0)
   747  	RET
   748  
   749  TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
   750  	MOVD	addr+0(FP), R3
   751  	MOVD	n+8(FP), R4
   752  	MOVW	flags+16(FP), R5
   753  	SYSCALL	$SYS_madvise
   754  	MOVW	R3, ret+24(FP)
   755  	RET
   756  
   757  // int64 futex(int32 *uaddr, int32 op, int32 val,
   758  //	struct timespec *timeout, int32 *uaddr2, int32 val2);
   759  TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
   760  	MOVD	addr+0(FP), R3
   761  	MOVW	op+8(FP), R4
   762  	MOVW	val+12(FP), R5
   763  	MOVD	ts+16(FP), R6
   764  	MOVD	addr2+24(FP), R7
   765  	MOVW	val3+32(FP), R8
   766  	SYSCALL	$SYS_futex
   767  	BVC	2(PC)
   768  	NEG	R3	// caller expects negative errno
   769  	MOVW	R3, ret+40(FP)
   770  	RET
   771  
   772  // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
   773  TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
   774  	MOVW	flags+0(FP), R3
   775  	MOVD	stk+8(FP), R4
   776  
   777  	// Copy mp, gp, fn off parent stack for use by child.
   778  	// Careful: Linux system call clobbers ???.
   779  	MOVD	mp+16(FP), R7
   780  	MOVD	gp+24(FP), R8
   781  	MOVD	fn+32(FP), R12
   782  
   783  	MOVD	R7, -8(R4)
   784  	MOVD	R8, -16(R4)
   785  	MOVD	R12, -24(R4)
   786  	MOVD	$1234, R7
   787  	MOVD	R7, -32(R4)
   788  
   789  	SYSCALL $SYS_clone
   790  	BVC	2(PC)
   791  	NEG	R3	// caller expects negative errno
   792  
   793  	// In parent, return.
   794  	CMP	R3, $0
   795  	BEQ	3(PC)
   796  	MOVW	R3, ret+40(FP)
   797  	RET
   798  
   799  	// In child, on new stack.
   800  	// initialize essential registers
   801  	BL	runtime·reginit(SB)
   802  	MOVD	-32(R1), R7
   803  	CMP	R7, $1234
   804  	BEQ	2(PC)
   805  	MOVD	R0, 0(R0)
   806  
   807  	// Initialize m->procid to Linux tid
   808  	SYSCALL $SYS_gettid
   809  
   810  	MOVD	-24(R1), R12       // fn
   811  	MOVD	-16(R1), R8        // g
   812  	MOVD	-8(R1), R7         // m
   813  
   814  	CMP	R7, $0
   815  	BEQ	nog
   816  	CMP	R8, $0
   817  	BEQ	nog
   818  
   819  	MOVD	R3, m_procid(R7)
   820  
   821  	// TODO: setup TLS.
   822  
   823  	// In child, set up new stack
   824  	MOVD	R7, g_m(R8)
   825  	MOVD	R8, g
   826  	//CALL	runtime·stackcheck(SB)
   827  
   828  nog:
   829  	// Call fn
   830  	MOVD	R12, CTR
   831  	BL	(CTR)
   832  
   833  	// It shouldn't return.	 If it does, exit that thread.
   834  	MOVW	$111, R3
   835  	SYSCALL	$SYS_exit
   836  	BR	-2(PC)	// keep exiting
   837  
   838  TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
   839  	MOVD	new+0(FP), R3
   840  	MOVD	old+8(FP), R4
   841  	SYSCALL	$SYS_sigaltstack
   842  	BVC	2(PC)
   843  	MOVD	R0, 0xf0(R0)  // crash
   844  	RET
   845  
   846  TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
   847  	SYSCALL	$SYS_sched_yield
   848  	RET
   849  
   850  TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
   851  	MOVD	pid+0(FP), R3
   852  	MOVD	len+8(FP), R4
   853  	MOVD	buf+16(FP), R5
   854  	SYSCALL	$SYS_sched_getaffinity
   855  	BVC	2(PC)
   856  	NEG	R3	// caller expects negative errno
   857  	MOVW	R3, ret+24(FP)
   858  	RET
   859  
   860  // int32 runtime·epollcreate(int32 size);
   861  TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
   862  	MOVW    size+0(FP), R3
   863  	SYSCALL	$SYS_epoll_create
   864  	BVC	2(PC)
   865  	NEG	R3	// caller expects negative errno
   866  	MOVW	R3, ret+8(FP)
   867  	RET
   868  
   869  // int32 runtime·epollcreate1(int32 flags);
   870  TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
   871  	MOVW	flags+0(FP), R3
   872  	SYSCALL	$SYS_epoll_create1
   873  	BVC	2(PC)
   874  	NEG	R3	// caller expects negative errno
   875  	MOVW	R3, ret+8(FP)
   876  	RET
   877  
   878  // func epollctl(epfd, op, fd int32, ev *epollEvent) int
   879  TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
   880  	MOVW	epfd+0(FP), R3
   881  	MOVW	op+4(FP), R4
   882  	MOVW	fd+8(FP), R5
   883  	MOVD	ev+16(FP), R6
   884  	SYSCALL	$SYS_epoll_ctl
   885  	NEG	R3	// caller expects negative errno
   886  	MOVW	R3, ret+24(FP)
   887  	RET
   888  
   889  // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
   890  TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
   891  	MOVW	epfd+0(FP), R3
   892  	MOVD	ev+8(FP), R4
   893  	MOVW	nev+16(FP), R5
   894  	MOVW	timeout+20(FP), R6
   895  	SYSCALL	$SYS_epoll_wait
   896  	BVC	2(PC)
   897  	NEG	R3	// caller expects negative errno
   898  	MOVW	R3, ret+24(FP)
   899  	RET
   900  
   901  // void runtime·closeonexec(int32 fd);
   902  TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
   903  	MOVW    fd+0(FP), R3  // fd
   904  	MOVD    $2, R4  // F_SETFD
   905  	MOVD    $1, R5  // FD_CLOEXEC
   906  	SYSCALL	$SYS_fcntl
   907  	RET
   908  
   909  // func runtime·setNonblock(int32 fd)
   910  TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
   911  	MOVW	fd+0(FP), R3 // fd
   912  	MOVD	$3, R4	// F_GETFL
   913  	MOVD	$0, R5
   914  	SYSCALL	$SYS_fcntl
   915  	OR	$0x800, R3, R5 // O_NONBLOCK
   916  	MOVW	fd+0(FP), R3 // fd
   917  	MOVD	$4, R4	// F_SETFL
   918  	SYSCALL	$SYS_fcntl
   919  	RET
   920  
   921  // func sbrk0() uintptr
   922  TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
   923  	// Implemented as brk(NULL).
   924  	MOVD	$0, R3
   925  	SYSCALL	$SYS_brk
   926  	MOVD	R3, ret+0(FP)
   927  	RET
   928  
   929  TEXT runtime·access(SB),$0-20
   930  	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   931  	MOVW	R0, ret+16(FP) // for vet
   932  	RET
   933  
   934  TEXT runtime·connect(SB),$0-28
   935  	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   936  	MOVW	R0, ret+24(FP) // for vet
   937  	RET
   938  
   939  TEXT runtime·socket(SB),$0-20
   940  	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   941  	MOVW	R0, ret+16(FP) // for vet
   942  	RET