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

View as plain text