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  #include "cgo/abi_ppc64x.h"
    16  
    17  #define SYS_exit		  1
    18  #define SYS_read		  3
    19  #define SYS_write		  4
    20  #define SYS_open		  5
    21  #define SYS_close		  6
    22  #define SYS_getpid		 20
    23  #define SYS_kill		 37
    24  #define SYS_brk			 45
    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_timer_create	240
    42  #define SYS_timer_settime	241
    43  #define SYS_timer_delete	244
    44  #define SYS_clock_gettime	246
    45  #define SYS_tgkill		250
    46  #define SYS_pipe2		317
    47  
    48  TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
    49  	MOVW	code+0(FP), R3
    50  	SYSCALL	$SYS_exit_group
    51  	RET
    52  
    53  // func exitThread(wait *atomic.Uint32)
    54  TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
    55  	MOVD	wait+0(FP), R1
    56  	// We're done using the stack.
    57  	MOVW	$0, R2
    58  	SYNC
    59  	MOVW	R2, (R1)
    60  	MOVW	$0, R3	// exit code
    61  	SYSCALL	$SYS_exit
    62  	JMP	0(PC)
    63  
    64  TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
    65  	MOVD	name+0(FP), R3
    66  	MOVW	mode+8(FP), R4
    67  	MOVW	perm+12(FP), R5
    68  	SYSCALL	$SYS_open
    69  	BVC	2(PC)
    70  	MOVW	$-1, R3
    71  	MOVW	R3, ret+16(FP)
    72  	RET
    73  
    74  TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
    75  	MOVW	fd+0(FP), R3
    76  	SYSCALL	$SYS_close
    77  	BVC	2(PC)
    78  	MOVW	$-1, R3
    79  	MOVW	R3, ret+8(FP)
    80  	RET
    81  
    82  TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
    83  	MOVD	fd+0(FP), R3
    84  	MOVD	p+8(FP), R4
    85  	MOVW	n+16(FP), R5
    86  	SYSCALL	$SYS_write
    87  	BVC	2(PC)
    88  	NEG	R3	// caller expects negative errno
    89  	MOVW	R3, ret+24(FP)
    90  	RET
    91  
    92  TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
    93  	MOVW	fd+0(FP), R3
    94  	MOVD	p+8(FP), R4
    95  	MOVW	n+16(FP), R5
    96  	SYSCALL	$SYS_read
    97  	BVC	2(PC)
    98  	NEG	R3	// caller expects negative errno
    99  	MOVW	R3, ret+24(FP)
   100  	RET
   101  
   102  // func pipe2(flags int32) (r, w int32, errno int32)
   103  TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
   104  	ADD	$FIXED_FRAME+8, R1, R3
   105  	MOVW	flags+0(FP), R4
   106  	SYSCALL	$SYS_pipe2
   107  	MOVW	R3, errno+16(FP)
   108  	RET
   109  
   110  // func usleep(usec uint32)
   111  TEXT runtime·usleep(SB),NOSPLIT,$16-4
   112  	MOVW	usec+0(FP), R3
   113  
   114  	// Use magic constant 0x8637bd06 and shift right 51
   115  	// to perform usec/1000000.
   116  	MOVD	$0x8637bd06, R4
   117  	MULLD	R3, R4, R4	// Convert usec to S.
   118  	SRD	$51, R4, R4
   119  	MOVD	R4, 8(R1)	// Store to tv_sec
   120  
   121  	MOVD	$1000000, R5
   122  	MULLW	R4, R5, R5	// Convert tv_sec back into uS
   123  	SUB	R5, R3, R5	// Compute remainder uS.
   124  	MULLD	$1000, R5, R5	// Convert to nsec
   125  	MOVD	R5, 16(R1)	// Store to tv_nsec
   126  
   127  	// nanosleep(&ts, 0)
   128  	ADD	$8, R1, R3
   129  	MOVW	$0, R4
   130  	SYSCALL	$SYS_nanosleep
   131  	RET
   132  
   133  TEXT runtime·gettid(SB),NOSPLIT,$0-4
   134  	SYSCALL	$SYS_gettid
   135  	MOVW	R3, ret+0(FP)
   136  	RET
   137  
   138  TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
   139  	SYSCALL	$SYS_getpid
   140  	MOVW	R3, R14
   141  	SYSCALL	$SYS_gettid
   142  	MOVW	R3, R4	// arg 2 tid
   143  	MOVW	R14, R3	// arg 1 pid
   144  	MOVW	sig+0(FP), R5	// arg 3
   145  	SYSCALL	$SYS_tgkill
   146  	RET
   147  
   148  TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
   149  	SYSCALL	$SYS_getpid
   150  	MOVW	R3, R3	// arg 1 pid
   151  	MOVW	sig+0(FP), R4	// arg 2
   152  	SYSCALL	$SYS_kill
   153  	RET
   154  
   155  TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
   156  	SYSCALL $SYS_getpid
   157  	MOVD	R3, ret+0(FP)
   158  	RET
   159  
   160  TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
   161  	MOVD	tgid+0(FP), R3
   162  	MOVD	tid+8(FP), R4
   163  	MOVD	sig+16(FP), R5
   164  	SYSCALL $SYS_tgkill
   165  	RET
   166  
   167  TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
   168  	MOVW	mode+0(FP), R3
   169  	MOVD	new+8(FP), R4
   170  	MOVD	old+16(FP), R5
   171  	SYSCALL	$SYS_setitimer
   172  	RET
   173  
   174  TEXT runtime·timer_create(SB),NOSPLIT,$0-28
   175  	MOVW	clockid+0(FP), R3
   176  	MOVD	sevp+8(FP), R4
   177  	MOVD	timerid+16(FP), R5
   178  	SYSCALL	$SYS_timer_create
   179  	MOVW	R3, ret+24(FP)
   180  	RET
   181  
   182  TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
   183  	MOVW	timerid+0(FP), R3
   184  	MOVW	flags+4(FP), R4
   185  	MOVD	new+8(FP), R5
   186  	MOVD	old+16(FP), R6
   187  	SYSCALL	$SYS_timer_settime
   188  	MOVW	R3, ret+24(FP)
   189  	RET
   190  
   191  TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
   192  	MOVW	timerid+0(FP), R3
   193  	SYSCALL	$SYS_timer_delete
   194  	MOVW	R3, ret+8(FP)
   195  	RET
   196  
   197  TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
   198  	MOVD	addr+0(FP), R3
   199  	MOVD	n+8(FP), R4
   200  	MOVD	dst+16(FP), R5
   201  	SYSCALL	$SYS_mincore
   202  	NEG	R3		// caller expects negative errno
   203  	MOVW	R3, ret+24(FP)
   204  	RET
   205  
   206  // func walltime() (sec int64, nsec int32)
   207  TEXT runtime·walltime(SB),NOSPLIT,$16-12
   208  	MOVD	R1, R15		// R15 is unchanged by C code
   209  	MOVD	g_m(g), R21	// R21 = m
   210  
   211  	MOVD	$0, R3		// CLOCK_REALTIME
   212  
   213  	MOVD	runtime·vdsoClockgettimeSym(SB), R12	// Check for VDSO availability
   214  	CMP	R12, $0
   215  	BEQ	fallback
   216  
   217  	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   218  	// Save the old values on stack and restore them on exit,
   219  	// so this function is reentrant.
   220  	MOVD	m_vdsoPC(R21), R4
   221  	MOVD	m_vdsoSP(R21), R5
   222  	MOVD	R4, 32(R1)
   223  	MOVD	R5, 40(R1)
   224  
   225  	MOVD	LR, R14
   226  	MOVD	$ret-FIXED_FRAME(FP), R5 // caller's SP
   227  	MOVD	R14, m_vdsoPC(R21)
   228  	MOVD	R5, m_vdsoSP(R21)
   229  
   230  	MOVD	m_curg(R21), R6
   231  	CMP	g, R6
   232  	BNE	noswitch
   233  
   234  	MOVD	m_g0(R21), R7
   235  	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
   236  
   237  noswitch:
   238  	SUB	$16, R1                 // Space for results
   239  	RLDICR	$0, R1, $59, R1         // Align for C code
   240  	MOVD	R12, CTR
   241  	MOVD	R1, R4
   242  
   243  	// Store g on gsignal's stack, so if we receive a signal
   244  	// during VDSO code we can find the g.
   245  	// If we don't have a signal stack, we won't receive signal,
   246  	// so don't bother saving g.
   247  	// When using cgo, we already saved g on TLS, also don't save
   248  	// g here.
   249  	// Also don't save g if we are already on the signal stack.
   250  	// We won't get a nested signal.
   251  	MOVBZ	runtime·iscgo(SB), R22
   252  	CMP	R22, $0
   253  	BNE	nosaveg
   254  	MOVD	m_gsignal(R21), R22	// g.m.gsignal
   255  	CMP	R22, $0
   256  	BEQ	nosaveg
   257  
   258  	CMP	g, R22
   259  	BEQ	nosaveg
   260  	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   261  	MOVD	g, (R22)
   262  
   263  	BL	(CTR)	// Call from VDSO
   264  
   265  	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
   266  
   267  	JMP	finish
   268  
   269  nosaveg:
   270  	BL	(CTR)	// Call from VDSO
   271  
   272  finish:
   273  	MOVD	$0, R0		// Restore R0
   274  	MOVD	0(R1), R3	// sec
   275  	MOVD	8(R1), R5	// nsec
   276  	MOVD	R15, R1		// Restore SP
   277  
   278  	// Restore vdsoPC, vdsoSP
   279  	// We don't worry about being signaled between the two stores.
   280  	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   281  	// and no one will care about vdsoPC. If we are in a signal handler,
   282  	// we cannot receive another signal.
   283  	MOVD	40(R1), R6
   284  	MOVD	R6, m_vdsoSP(R21)
   285  	MOVD	32(R1), R6
   286  	MOVD	R6, m_vdsoPC(R21)
   287  
   288  return:
   289  	MOVD	R3, sec+0(FP)
   290  	MOVW	R5, nsec+8(FP)
   291  	RET
   292  
   293  	// Syscall fallback
   294  fallback:
   295  	ADD	$32, R1, R4
   296  	SYSCALL $SYS_clock_gettime
   297  	MOVD	32(R1), R3
   298  	MOVD	40(R1), R5
   299  	JMP	return
   300  
   301  TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
   302  	MOVD	$1, R3		// CLOCK_MONOTONIC
   303  
   304  	MOVD	R1, R15		// R15 is unchanged by C code
   305  	MOVD	g_m(g), R21	// R21 = m
   306  
   307  	MOVD	runtime·vdsoClockgettimeSym(SB), R12	// Check for VDSO availability
   308  	CMP	R12, $0
   309  	BEQ	fallback
   310  
   311  	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   312  	// Save the old values on stack and restore them on exit,
   313  	// so this function is reentrant.
   314  	MOVD	m_vdsoPC(R21), R4
   315  	MOVD	m_vdsoSP(R21), R5
   316  	MOVD	R4, 32(R1)
   317  	MOVD	R5, 40(R1)
   318  
   319  	MOVD	LR, R14				// R14 is unchanged by C code
   320  	MOVD	$ret-FIXED_FRAME(FP), R5	// caller's SP
   321  	MOVD	R14, m_vdsoPC(R21)
   322  	MOVD	R5, m_vdsoSP(R21)
   323  
   324  	MOVD	m_curg(R21), R6
   325  	CMP	g, R6
   326  	BNE	noswitch
   327  
   328  	MOVD	m_g0(R21), R7
   329  	MOVD	(g_sched+gobuf_sp)(R7), R1	// Set SP to g0 stack
   330  
   331  noswitch:
   332  	SUB	$16, R1			// Space for results
   333  	RLDICR	$0, R1, $59, R1		// Align for C code
   334  	MOVD	R12, CTR
   335  	MOVD	R1, R4
   336  
   337  	// Store g on gsignal's stack, so if we receive a signal
   338  	// during VDSO code we can find the g.
   339  	// If we don't have a signal stack, we won't receive signal,
   340  	// so don't bother saving g.
   341  	// When using cgo, we already saved g on TLS, also don't save
   342  	// g here.
   343  	// Also don't save g if we are already on the signal stack.
   344  	// We won't get a nested signal.
   345  	MOVBZ	runtime·iscgo(SB), R22
   346  	CMP	R22, $0
   347  	BNE	nosaveg
   348  	MOVD	m_gsignal(R21), R22	// g.m.gsignal
   349  	CMP	R22, $0
   350  	BEQ	nosaveg
   351  
   352  	CMP	g, R22
   353  	BEQ	nosaveg
   354  	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   355  	MOVD	g, (R22)
   356  
   357  	BL	(CTR)	// Call from VDSO
   358  
   359  	MOVD	$0, (R22)	// clear g slot, R22 is unchanged by C code
   360  
   361  	JMP	finish
   362  
   363  nosaveg:
   364  	BL	(CTR)	// Call from VDSO
   365  
   366  finish:
   367  	MOVD	$0, R0			// Restore R0
   368  	MOVD	0(R1), R3		// sec
   369  	MOVD	8(R1), R5		// nsec
   370  	MOVD	R15, R1			// Restore SP
   371  
   372  	// Restore vdsoPC, vdsoSP
   373  	// We don't worry about being signaled between the two stores.
   374  	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   375  	// and no one will care about vdsoPC. If we are in a signal handler,
   376  	// we cannot receive another signal.
   377  	MOVD	40(R1), R6
   378  	MOVD	R6, m_vdsoSP(R21)
   379  	MOVD	32(R1), R6
   380  	MOVD	R6, m_vdsoPC(R21)
   381  
   382  return:
   383  	// sec is in R3, nsec in R5
   384  	// return nsec in R3
   385  	MOVD	$1000000000, R4
   386  	MULLD	R4, R3
   387  	ADD	R5, R3
   388  	MOVD	R3, ret+0(FP)
   389  	RET
   390  
   391  	// Syscall fallback
   392  fallback:
   393  	ADD	$32, R1, R4
   394  	SYSCALL $SYS_clock_gettime
   395  	MOVD	32(R1), R3
   396  	MOVD	40(R1), R5
   397  	JMP	return
   398  
   399  TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
   400  	MOVW	how+0(FP), R3
   401  	MOVD	new+8(FP), R4
   402  	MOVD	old+16(FP), R5
   403  	MOVW	size+24(FP), R6
   404  	SYSCALL	$SYS_rt_sigprocmask
   405  	BVC	2(PC)
   406  	MOVD	R0, 0xf0(R0)	// crash
   407  	RET
   408  
   409  TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
   410  	MOVD	sig+0(FP), R3
   411  	MOVD	new+8(FP), R4
   412  	MOVD	old+16(FP), R5
   413  	MOVD	size+24(FP), R6
   414  	SYSCALL	$SYS_rt_sigaction
   415  	BVC	2(PC)
   416  	NEG	R3	// caller expects negative errno
   417  	MOVW	R3, ret+32(FP)
   418  	RET
   419  
   420  #ifdef GOARCH_ppc64le
   421  // Call the function stored in _cgo_sigaction using the GCC calling convention.
   422  TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
   423  	MOVD    sig+0(FP), R3
   424  	MOVD    new+8(FP), R4
   425  	MOVD    old+16(FP), R5
   426  	MOVD     _cgo_sigaction(SB), R12
   427  	MOVD    R12, CTR                // R12 should contain the function address
   428  	MOVD    R1, R15                 // Save R1
   429  	MOVD    R2, 24(R1)              // Save R2
   430  	SUB     $48, R1                 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved.
   431  	RLDICR  $0, R1, $59, R1         // Align to 16 bytes for C code
   432  	BL      (CTR)
   433  	XOR     R0, R0, R0              // Clear R0 as Go expects
   434  	MOVD    R15, R1                 // Restore R1
   435  	MOVD    24(R1), R2              // Restore R2
   436  	MOVW    R3, ret+24(FP)          // Return result
   437  	RET
   438  #endif
   439  
   440  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   441  	MOVW	sig+8(FP), R3
   442  	MOVD	info+16(FP), R4
   443  	MOVD	ctx+24(FP), R5
   444  	MOVD	fn+0(FP), R12
   445  	MOVD	R12, CTR
   446  	BL	(CTR)
   447  	MOVD	24(R1), R2
   448  	RET
   449  
   450  #ifdef GO_PPC64X_HAS_FUNCDESC
   451  DEFINE_PPC64X_FUNCDESC(runtime·sigtramp, sigtramp<>)
   452  // cgo isn't supported on ppc64, but we need to supply a cgoSigTramp function.
   453  DEFINE_PPC64X_FUNCDESC(runtime·cgoSigtramp, sigtramp<>)
   454  TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
   455  #else
   456  // ppc64le doesn't need function descriptors
   457  // Save callee-save registers in the case of signal forwarding.
   458  // Same as on ARM64 https://golang.org/issue/31827 .
   459  //
   460  // Note, it is assumed this is always called indirectly (e.g via
   461  // a function pointer) as R2 may not be preserved when calling this
   462  // function. In those cases, the caller preserves their R2.
   463  TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0
   464  #endif
   465  	// This is called with ELF calling conventions. Convert to Go.
   466  	// Allocate space for argument storage to call runtime.sigtrampgo.
   467  	STACK_AND_SAVE_HOST_TO_GO_ABI(32)
   468  
   469  	// this might be called in external code context,
   470  	// where g is not set.
   471  	MOVBZ	runtime·iscgo(SB), R6
   472  	CMP	R6, $0
   473  	BEQ	2(PC)
   474  	BL	runtime·load_g(SB)
   475  
   476  	// R3,R4,R5 already hold the arguments. Forward them on.
   477  	// TODO: Indirectly call runtime.sigtrampgo to avoid the linker's static NOSPLIT stack
   478  	// overflow detection. It thinks this might be called on a small Go stack, but this is only
   479  	// called from a larger pthread or sigaltstack stack. Can the checker be improved to not
   480  	// flag a direct call here?
   481  	MOVD	$runtime·sigtrampgo<ABIInternal>(SB), R12
   482  	MOVD	R12, CTR
   483  	BL	(CTR)
   484  	// Restore R2 (TOC pointer) in the event it might be used later in this function.
   485  	// If this was not compiled as shared code, R2 is undefined, reloading it is harmless.
   486  	MOVD	24(R1), R2
   487  
   488  	UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
   489  	RET
   490  
   491  #ifdef GOARCH_ppc64le
   492  TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
   493  	// The stack unwinder, presumably written in C, may not be able to
   494  	// handle Go frame correctly. So, this function is NOFRAME, and we
   495  	// save/restore LR manually, and obey ELFv2 calling conventions.
   496  	MOVD	LR, R10
   497  
   498  	// We're coming from C code, initialize R0
   499  	MOVD	$0, R0
   500  
   501  	// If no traceback function, do usual sigtramp.
   502  	MOVD	runtime·cgoTraceback(SB), R6
   503  	CMP	$0, R6
   504  	BEQ	sigtramp
   505  
   506  	// If no traceback support function, which means that
   507  	// runtime/cgo was not linked in, do usual sigtramp.
   508  	MOVD	_cgo_callers(SB), R6
   509  	CMP	$0, R6
   510  	BEQ	sigtramp
   511  
   512  	// Inspect the g in TLS without clobbering R30/R31 via runtime.load_g.
   513  	MOVD	runtime·tls_g(SB), R9
   514  	MOVD	0(R9), R9
   515  
   516  	// Figure out if we are currently in a cgo call.
   517  	// If not, just do usual sigtramp.
   518  	// compared to ARM64 and others.
   519  	CMP	$0, R9
   520  	BEQ	sigtrampnog // g == nil
   521  
   522  	// g is not nil. Check further.
   523  	MOVD	g_m(R9), R6
   524  	CMP	$0, R6
   525  	BEQ	sigtramp    // g.m == nil
   526  	MOVW	m_ncgo(R6), R7
   527  	CMPW	$0, R7
   528  	BEQ	sigtramp    // g.m.ncgo = 0
   529  	MOVD	m_curg(R6), R7
   530  	CMP	$0, R7
   531  	BEQ	sigtramp    // g.m.curg == nil
   532  	MOVD	g_syscallsp(R7), R7
   533  	CMP	$0, R7
   534  	BEQ	sigtramp    // g.m.curg.syscallsp == 0
   535  	MOVD	m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention.
   536  	CMP	$0, R7
   537  	BEQ	sigtramp    // g.m.cgoCallers == nil
   538  	MOVW	m_cgoCallersUse(R6), R8
   539  	CMPW	$0, R8
   540  	BNE	sigtramp    // g.m.cgoCallersUse != 0
   541  
   542  	// Jump to a function in runtime/cgo.
   543  	// That function, written in C, will call the user's traceback
   544  	// function with proper unwind info, and will then call back here.
   545  	// The first three arguments, and the fifth, are already in registers.
   546  	// Set the two remaining arguments now.
   547  	MOVD	runtime·cgoTraceback(SB), R6
   548  	MOVD	$runtime·sigtramp(SB), R8
   549  	MOVD	_cgo_callers(SB), R12
   550  	MOVD	R12, CTR
   551  	MOVD	R10, LR // restore LR
   552  	JMP	(CTR)
   553  
   554  sigtramp:
   555  	MOVD	R10, LR // restore LR
   556  	JMP	runtime·sigtramp(SB)
   557  
   558  sigtrampnog:
   559  	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   560  	// stack trace.
   561  	CMPW	R3, $27 // 27 == SIGPROF
   562  	BNE	sigtramp
   563  
   564  	// Lock sigprofCallersUse (cas from 0 to 1).
   565  	MOVW	$1, R7
   566  	MOVD	$runtime·sigprofCallersUse(SB), R8
   567  	SYNC
   568  	LWAR    (R8), R6
   569  	CMPW    $0, R6
   570  	BNE     sigtramp
   571  	STWCCC  R7, (R8)
   572  	BNE     -4(PC)
   573  	ISYNC
   574  
   575  	// Jump to the traceback function in runtime/cgo.
   576  	// It will call back to sigprofNonGo, which will ignore the
   577  	// arguments passed in registers.
   578  	// First three arguments to traceback function are in registers already.
   579  	MOVD	runtime·cgoTraceback(SB), R6
   580  	MOVD	$runtime·sigprofCallers(SB), R7
   581  	MOVD	$runtime·sigprofNonGoWrapper<>(SB), R8
   582  	MOVD	_cgo_callers(SB), R12
   583  	MOVD	R12, CTR
   584  	MOVD	R10, LR // restore LR
   585  	JMP	(CTR)
   586  #endif
   587  
   588  // Used by cgoSigtramp to inspect without clobbering R30/R31 via runtime.load_g.
   589  GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
   590  
   591  TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
   592  	// This is called from C code. Callee save registers must be saved.
   593  	// R3,R4,R5 hold arguments, and allocate argument space to call sigprofNonGo.
   594  	STACK_AND_SAVE_HOST_TO_GO_ABI(32)
   595  
   596  	CALL	runtime·sigprofNonGo<ABIInternal>(SB)
   597  
   598  	UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32)
   599  	RET
   600  
   601  TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
   602  	MOVD	addr+0(FP), R3
   603  	MOVD	n+8(FP), R4
   604  	MOVW	prot+16(FP), R5
   605  	MOVW	flags+20(FP), R6
   606  	MOVW	fd+24(FP), R7
   607  	MOVW	off+28(FP), R8
   608  
   609  	SYSCALL	$SYS_mmap
   610  	BVC	ok
   611  	MOVD	$0, p+32(FP)
   612  	MOVD	R3, err+40(FP)
   613  	RET
   614  ok:
   615  	MOVD	R3, p+32(FP)
   616  	MOVD	$0, err+40(FP)
   617  	RET
   618  
   619  TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
   620  	MOVD	addr+0(FP), R3
   621  	MOVD	n+8(FP), R4
   622  	SYSCALL	$SYS_munmap
   623  	BVC	2(PC)
   624  	MOVD	R0, 0xf0(R0)
   625  	RET
   626  
   627  TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
   628  	MOVD	addr+0(FP), R3
   629  	MOVD	n+8(FP), R4
   630  	MOVW	flags+16(FP), R5
   631  	SYSCALL	$SYS_madvise
   632  	MOVW	R3, ret+24(FP)
   633  	RET
   634  
   635  // int64 futex(int32 *uaddr, int32 op, int32 val,
   636  //	struct timespec *timeout, int32 *uaddr2, int32 val2);
   637  TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
   638  	MOVD	addr+0(FP), R3
   639  	MOVW	op+8(FP), R4
   640  	MOVW	val+12(FP), R5
   641  	MOVD	ts+16(FP), R6
   642  	MOVD	addr2+24(FP), R7
   643  	MOVW	val3+32(FP), R8
   644  	SYSCALL	$SYS_futex
   645  	BVC	2(PC)
   646  	NEG	R3	// caller expects negative errno
   647  	MOVW	R3, ret+40(FP)
   648  	RET
   649  
   650  // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
   651  TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
   652  	MOVW	flags+0(FP), R3
   653  	MOVD	stk+8(FP), R4
   654  
   655  	// Copy mp, gp, fn off parent stack for use by child.
   656  	// Careful: Linux system call clobbers ???.
   657  	MOVD	mp+16(FP), R7
   658  	MOVD	gp+24(FP), R8
   659  	MOVD	fn+32(FP), R12
   660  
   661  	MOVD	R7, -8(R4)
   662  	MOVD	R8, -16(R4)
   663  	MOVD	R12, -24(R4)
   664  	MOVD	$1234, R7
   665  	MOVD	R7, -32(R4)
   666  
   667  	SYSCALL $SYS_clone
   668  	BVC	2(PC)
   669  	NEG	R3	// caller expects negative errno
   670  
   671  	// In parent, return.
   672  	CMP	R3, $0
   673  	BEQ	3(PC)
   674  	MOVW	R3, ret+40(FP)
   675  	RET
   676  
   677  	// In child, on new stack.
   678  	// initialize essential registers
   679  	BL	runtime·reginit(SB)
   680  	MOVD	-32(R1), R7
   681  	CMP	R7, $1234
   682  	BEQ	2(PC)
   683  	MOVD	R0, 0(R0)
   684  
   685  	// Initialize m->procid to Linux tid
   686  	SYSCALL $SYS_gettid
   687  
   688  	MOVD	-24(R1), R12       // fn
   689  	MOVD	-16(R1), R8        // g
   690  	MOVD	-8(R1), R7         // m
   691  
   692  	CMP	R7, $0
   693  	BEQ	nog
   694  	CMP	R8, $0
   695  	BEQ	nog
   696  
   697  	MOVD	R3, m_procid(R7)
   698  
   699  	// TODO: setup TLS.
   700  
   701  	// In child, set up new stack
   702  	MOVD	R7, g_m(R8)
   703  	MOVD	R8, g
   704  	//CALL	runtime·stackcheck(SB)
   705  
   706  nog:
   707  	// Call fn
   708  	MOVD	R12, CTR
   709  	BL	(CTR)
   710  
   711  	// It shouldn't return.	 If it does, exit that thread.
   712  	MOVW	$111, R3
   713  	SYSCALL	$SYS_exit
   714  	BR	-2(PC)	// keep exiting
   715  
   716  TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
   717  	MOVD	new+0(FP), R3
   718  	MOVD	old+8(FP), R4
   719  	SYSCALL	$SYS_sigaltstack
   720  	BVC	2(PC)
   721  	MOVD	R0, 0xf0(R0)  // crash
   722  	RET
   723  
   724  TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
   725  	SYSCALL	$SYS_sched_yield
   726  	RET
   727  
   728  TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
   729  	MOVD	pid+0(FP), R3
   730  	MOVD	len+8(FP), R4
   731  	MOVD	buf+16(FP), R5
   732  	SYSCALL	$SYS_sched_getaffinity
   733  	BVC	2(PC)
   734  	NEG	R3	// caller expects negative errno
   735  	MOVW	R3, ret+24(FP)
   736  	RET
   737  
   738  // func sbrk0() uintptr
   739  TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
   740  	// Implemented as brk(NULL).
   741  	MOVD	$0, R3
   742  	SYSCALL	$SYS_brk
   743  	MOVD	R3, ret+0(FP)
   744  	RET
   745  
   746  TEXT runtime·access(SB),$0-20
   747  	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   748  	MOVW	R0, ret+16(FP) // for vet
   749  	RET
   750  
   751  TEXT runtime·connect(SB),$0-28
   752  	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   753  	MOVW	R0, ret+24(FP) // for vet
   754  	RET
   755  
   756  TEXT runtime·socket(SB),$0-20
   757  	MOVD	R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   758  	MOVW	R0, ret+16(FP) // for vet
   759  	RET
   760  

View as plain text