Black Lives Matter. Support the Equal Justice Initiative.

Text file src/runtime/sys_linux_ppc64x.s

Documentation: runtime

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

View as plain text