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