Text file src/runtime/sys_aix_ppc64.s

     1  // Copyright 2018 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  //
     6  // System calls and other sys.stuff for ppc64, Aix
     7  //
     8  
     9  #include "go_asm.h"
    10  #include "go_tls.h"
    11  #include "textflag.h"
    12  #include "asm_ppc64x.h"
    13  
    14  // This function calls a C function with the function descriptor in R12
    15  TEXT callCfunction<>(SB),	NOSPLIT|NOFRAME,$0
    16  	MOVD	0(R12), R12
    17  	MOVD	R2, 40(R1)
    18  	MOVD	0(R12), R0
    19  	MOVD	8(R12), R2
    20  	MOVD	R0, CTR
    21  	BR	(CTR)
    22  
    23  
    24  // asmsyscall6 calls a library function with a function descriptor
    25  // stored in libcall_fn and store the results in libcall structure
    26  // Up to 6 arguments can be passed to this C function
    27  // Called by runtime.asmcgocall
    28  // It reserves a stack of 288 bytes for the C function. It must
    29  // follow AIX convention, thus the first local variable must
    30  // be stored at the offset 112, after the linker area (48 bytes)
    31  // and the argument area (64).
    32  // The AIX convention is described here:
    33  // https://www.ibm.com/docs/en/aix/7.2?topic=overview-runtime-process-stack
    34  // NOT USING GO CALLING CONVENTION
    35  // runtime.asmsyscall6 is a function descriptor to the real asmsyscall6.
    36  DATA	runtime·asmsyscall6+0(SB)/8, $asmsyscall6<>(SB)
    37  DATA	runtime·asmsyscall6+8(SB)/8, $TOC(SB)
    38  DATA	runtime·asmsyscall6+16(SB)/8, $0
    39  GLOBL	runtime·asmsyscall6(SB), NOPTR, $24
    40  
    41  TEXT asmsyscall6<>(SB),NOSPLIT,$256
    42  	// Save libcall for later
    43  	MOVD	R3, 112(R1)
    44  	MOVD	libcall_fn(R3), R12
    45  	MOVD	libcall_args(R3), R9
    46  	MOVD	0(R9), R3
    47  	MOVD	8(R9), R4
    48  	MOVD	16(R9), R5
    49  	MOVD	24(R9), R6
    50  	MOVD	32(R9), R7
    51  	MOVD	40(R9), R8
    52  	BL	callCfunction<>(SB)
    53  
    54  	// Restore R0 and TOC
    55  	XOR	R0, R0
    56  	MOVD	40(R1), R2
    57  
    58  	// Store result in libcall
    59  	MOVD	112(R1), R5
    60  	MOVD	R3, (libcall_r1)(R5)
    61  	MOVD	$-1, R6
    62  	CMP	R6, R3
    63  	BNE	skiperrno
    64  
    65  	// Save errno in libcall
    66  	BL	runtime·load_g(SB)
    67  	MOVD	g_m(g), R4
    68  	MOVD	(m_mOS + mOS_perrno)(R4), R9
    69  	MOVW	0(R9), R9
    70  	MOVD	R9, (libcall_err)(R5)
    71  	RET
    72  skiperrno:
    73  	// Reset errno if no error has been returned
    74  	MOVD	R0, (libcall_err)(R5)
    75  	RET
    76  
    77  
    78  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
    79  	MOVW	sig+8(FP), R3
    80  	MOVD	info+16(FP), R4
    81  	MOVD	ctx+24(FP), R5
    82  	MOVD	fn+0(FP), R12
    83  	// fn is a function descriptor
    84  	// R2 must be saved on restore
    85  	MOVD	0(R12), R0
    86  	MOVD	R2, 40(R1)
    87  	MOVD	8(R12), R2
    88  	MOVD	R0, CTR
    89  	BL	(CTR)
    90  	MOVD	40(R1), R2
    91  	BL	runtime·reginit(SB)
    92  	RET
    93  
    94  
    95  // runtime.sigtramp is a function descriptor to the real sigtramp.
    96  DATA	runtime·sigtramp+0(SB)/8, $sigtramp<>(SB)
    97  DATA	runtime·sigtramp+8(SB)/8, $TOC(SB)
    98  DATA	runtime·sigtramp+16(SB)/8, $0
    99  GLOBL	runtime·sigtramp(SB), NOPTR, $24
   100  
   101  // This function must not have any frame as we want to control how
   102  // every registers are used.
   103  // TODO(aix): Implement SetCgoTraceback handler.
   104  TEXT sigtramp<>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
   105  	MOVD	LR, R0
   106  	MOVD	R0, 16(R1)
   107  	// initialize essential registers (just in case)
   108  	BL	runtime·reginit(SB)
   109  
   110  	// Note that we are executing on altsigstack here, so we have
   111  	// more stack available than NOSPLIT would have us believe.
   112  	// To defeat the linker, we make our own stack frame with
   113  	// more space.
   114  	SUB	$144+FIXED_FRAME, R1
   115  
   116  	// Save registers
   117  	MOVD	R31, 56(R1)
   118  	MOVD	g, 64(R1)
   119  	MOVD	R29, 72(R1)
   120  	MOVD	R14, 80(R1)
   121  	MOVD	R15, 88(R1)
   122  
   123  	BL	runtime·load_g(SB)
   124  
   125  	CMP	$0, g
   126  	BEQ	sigtramp // g == nil
   127  	MOVD	g_m(g), R6
   128  	CMP	$0, R6
   129  	BEQ	sigtramp	// g.m == nil
   130  
   131  	// Save m->libcall. We need to do this because we
   132  	// might get interrupted by a signal in runtime·asmcgocall.
   133  	MOVD	(m_mOS+mOS_libcall+libcall_fn)(R6), R7
   134  	MOVD	R7, 96(R1)
   135  	MOVD	(m_mOS+mOS_libcall+libcall_args)(R6), R7
   136  	MOVD	R7, 104(R1)
   137  	MOVD	(m_mOS+mOS_libcall+libcall_n)(R6), R7
   138  	MOVD	R7, 112(R1)
   139  	MOVD	(m_mOS+mOS_libcall+libcall_r1)(R6), R7
   140  	MOVD	R7, 120(R1)
   141  	MOVD	(m_mOS+mOS_libcall+libcall_r2)(R6), R7
   142  	MOVD	R7, 128(R1)
   143  
   144  	// save errno, it might be EINTR; stuff we do here might reset it.
   145  	MOVD	(m_mOS+mOS_perrno)(R6), R8
   146  	MOVD	0(R8), R8
   147  	MOVD	R8, 136(R1)
   148  
   149  sigtramp:
   150  	MOVW	R3, FIXED_FRAME+0(R1)
   151  	MOVD	R4, FIXED_FRAME+8(R1)
   152  	MOVD	R5, FIXED_FRAME+16(R1)
   153  	MOVD	$runtime·sigtrampgo(SB), R12
   154  	MOVD	R12, CTR
   155  	BL	(CTR)
   156  
   157  	CMP	$0, g
   158  	BEQ	exit // g == nil
   159  	MOVD	g_m(g), R6
   160  	CMP	$0, R6
   161  	BEQ	exit	// g.m == nil
   162  
   163  	// restore libcall
   164  	MOVD	96(R1), R7
   165  	MOVD	R7, (m_mOS+mOS_libcall+libcall_fn)(R6)
   166  	MOVD	104(R1), R7
   167  	MOVD	R7, (m_mOS+mOS_libcall+libcall_args)(R6)
   168  	MOVD	112(R1), R7
   169  	MOVD	R7, (m_mOS+mOS_libcall+libcall_n)(R6)
   170  	MOVD	120(R1), R7
   171  	MOVD	R7, (m_mOS+mOS_libcall+libcall_r1)(R6)
   172  	MOVD	128(R1), R7
   173  	MOVD	R7, (m_mOS+mOS_libcall+libcall_r2)(R6)
   174  
   175  	// restore errno
   176  	MOVD	(m_mOS+mOS_perrno)(R6), R7
   177  	MOVD	136(R1), R8
   178  	MOVD	R8, 0(R7)
   179  
   180  exit:
   181  	// restore registers
   182  	MOVD	56(R1),R31
   183  	MOVD	64(R1),g
   184  	MOVD	72(R1),R29
   185  	MOVD	80(R1), R14
   186  	MOVD	88(R1), R15
   187  
   188  	// Don't use RET because we need to restore R31 !
   189  	ADD $144+FIXED_FRAME, R1
   190  	MOVD	16(R1), R0
   191  	MOVD	R0, LR
   192  	BR (LR)
   193  
   194  // runtime.tstart is a function descriptor to the real tstart.
   195  DATA	runtime·tstart+0(SB)/8, $tstart<>(SB)
   196  DATA	runtime·tstart+8(SB)/8, $TOC(SB)
   197  DATA	runtime·tstart+16(SB)/8, $0
   198  GLOBL	runtime·tstart(SB), NOPTR, $24
   199  
   200  // runtime.rt0LibGoDesc is a function descriptor to rt0_lib_go,
   201  // used by libInit to create a new thread on AIX where
   202  // pthread_create expects a function descriptor, not a raw
   203  // code address.
   204  DATA	runtime·rt0LibGoDesc+0(SB)/8, $runtime·rt0_lib_go(SB)
   205  DATA	runtime·rt0LibGoDesc+8(SB)/8, $TOC(SB)
   206  DATA	runtime·rt0LibGoDesc+16(SB)/8, $0
   207  GLOBL	runtime·rt0LibGoDesc(SB), NOPTR, $24
   208  
   209  TEXT tstart<>(SB),NOSPLIT,$0
   210  	XOR	 R0, R0 // reset R0
   211  
   212  	// set g
   213  	MOVD	m_g0(R3), g
   214  	BL	runtime·save_g(SB)
   215  	MOVD	R3, g_m(g)
   216  
   217  	// Layout new m scheduler stack on os stack.
   218  	MOVD	R1, R3
   219  	MOVD	R3, (g_stack+stack_hi)(g)
   220  	SUB	$(const_threadStackSize), R3		// stack size
   221  	MOVD	R3, (g_stack+stack_lo)(g)
   222  	ADD	$const_stackGuard, R3
   223  	MOVD	R3, g_stackguard0(g)
   224  	MOVD	R3, g_stackguard1(g)
   225  
   226  	BL	runtime·mstart(SB)
   227  
   228  	MOVD R0, R3
   229  	RET
   230  
   231  
   232  #define CSYSCALL()			\
   233  	MOVD	0(R12), R12		\
   234  	MOVD	R2, 40(R1)		\
   235  	MOVD	0(R12), R0		\
   236  	MOVD	8(R12), R2		\
   237  	MOVD	R0, CTR			\
   238  	BL	(CTR)			\
   239  	MOVD	40(R1), R2		\
   240  	BL runtime·reginit(SB)
   241  
   242  
   243  // Runs on OS stack, called from runtime·osyield.
   244  TEXT runtime·osyield1(SB),NOSPLIT,$0
   245  	MOVD	$libc_sched_yield(SB), R12
   246  	CSYSCALL()
   247  	RET
   248  
   249  
   250  // Runs on OS stack, called from runtime·sigprocmask.
   251  TEXT runtime·sigprocmask1(SB),NOSPLIT,$0-24
   252  	MOVD	how+0(FP), R3
   253  	MOVD	new+8(FP), R4
   254  	MOVD	old+16(FP), R5
   255  	MOVD	$libpthread_sigthreadmask(SB), R12
   256  	CSYSCALL()
   257  	RET
   258  
   259  // Runs on OS stack, called from runtime·usleep.
   260  TEXT runtime·usleep1(SB),NOSPLIT,$0-4
   261  	MOVW	us+0(FP), R3
   262  	MOVD	$libc_usleep(SB), R12
   263  	CSYSCALL()
   264  	RET
   265  
   266  // Runs on OS stack, called from runtime·exit.
   267  TEXT runtime·exit1(SB),NOSPLIT,$0-4
   268  	MOVW	code+0(FP), R3
   269  	MOVD	$libc_exit(SB), R12
   270  	CSYSCALL()
   271  	RET
   272  
   273  // Runs on OS stack, called from runtime·write1.
   274  TEXT runtime·write2(SB),NOSPLIT,$0-28
   275  	MOVD	fd+0(FP), R3
   276  	MOVD	p+8(FP), R4
   277  	MOVW	n+16(FP), R5
   278  	MOVD	$libc_write(SB), R12
   279  	CSYSCALL()
   280  	MOVW	R3, ret+24(FP)
   281  	RET
   282  
   283  // Runs on OS stack, called from runtime·pthread_attr_init.
   284  TEXT runtime·pthread_attr_init1(SB),NOSPLIT,$0-12
   285  	MOVD	attr+0(FP), R3
   286  	MOVD	$libpthread_attr_init(SB), R12
   287  	CSYSCALL()
   288  	MOVW	R3, ret+8(FP)
   289  	RET
   290  
   291  // Runs on OS stack, called from runtime·pthread_attr_setstacksize.
   292  TEXT runtime·pthread_attr_setstacksize1(SB),NOSPLIT,$0-20
   293  	MOVD	attr+0(FP), R3
   294  	MOVD	size+8(FP), R4
   295  	MOVD	$libpthread_attr_setstacksize(SB), R12
   296  	CSYSCALL()
   297  	MOVW	R3, ret+16(FP)
   298  	RET
   299  
   300  // Runs on OS stack, called from runtime·pthread_setdetachstate.
   301  TEXT runtime·pthread_attr_setdetachstate1(SB),NOSPLIT,$0-20
   302  	MOVD	attr+0(FP), R3
   303  	MOVW	state+8(FP), R4
   304  	MOVD	$libpthread_attr_setdetachstate(SB), R12
   305  	CSYSCALL()
   306  	MOVW	R3, ret+16(FP)
   307  	RET
   308  
   309  // Runs on OS stack, called from runtime·pthread_create.
   310  TEXT runtime·pthread_create1(SB),NOSPLIT,$0-36
   311  	MOVD	tid+0(FP), R3
   312  	MOVD	attr+8(FP), R4
   313  	MOVD	fn+16(FP), R5
   314  	MOVD	arg+24(FP), R6
   315  	MOVD	$libpthread_create(SB), R12
   316  	CSYSCALL()
   317  	MOVW	R3, ret+32(FP)
   318  	RET
   319  
   320  // Runs on OS stack, called from runtime·sigaction.
   321  TEXT runtime·sigaction1(SB),NOSPLIT,$0-24
   322  	MOVD	sig+0(FP), R3
   323  	MOVD	new+8(FP), R4
   324  	MOVD	old+16(FP), R5
   325  	MOVD	$libc_sigaction(SB), R12
   326  	CSYSCALL()
   327  	RET
   328  

View as plain text