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

View as plain text