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

View as plain text