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_libcall+libcall_fn)(R6), R7
   134  	MOVD	R7, 96(R1)
   135  	MOVD	(m_libcall+libcall_args)(R6), R7
   136  	MOVD	R7, 104(R1)
   137  	MOVD	(m_libcall+libcall_n)(R6), R7
   138  	MOVD	R7, 112(R1)
   139  	MOVD	(m_libcall+libcall_r1)(R6), R7
   140  	MOVD	R7, 120(R1)
   141  	MOVD	(m_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_libcall+libcall_fn)(R6)
   166  	MOVD	104(R1), R7
   167  	MOVD	R7, (m_libcall+libcall_args)(R6)
   168  	MOVD	112(R1), R7
   169  	MOVD	R7, (m_libcall+libcall_n)(R6)
   170  	MOVD	120(R1), R7
   171  	MOVD	R7, (m_libcall+libcall_r1)(R6)
   172  	MOVD	128(R1), R7
   173  	MOVD	R7, (m_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  TEXT tstart<>(SB),NOSPLIT,$0
   201  	XOR	 R0, R0 // reset R0
   202  
   203  	// set g
   204  	MOVD	m_g0(R3), g
   205  	BL	runtime·save_g(SB)
   206  	MOVD	R3, g_m(g)
   207  
   208  	// Layout new m scheduler stack on os stack.
   209  	MOVD	R1, R3
   210  	MOVD	R3, (g_stack+stack_hi)(g)
   211  	SUB	$(const_threadStackSize), R3		// stack size
   212  	MOVD	R3, (g_stack+stack_lo)(g)
   213  	ADD	$const_stackGuard, R3
   214  	MOVD	R3, g_stackguard0(g)
   215  	MOVD	R3, g_stackguard1(g)
   216  
   217  	BL	runtime·mstart(SB)
   218  
   219  	MOVD R0, R3
   220  	RET
   221  
   222  
   223  #define CSYSCALL()			\
   224  	MOVD	0(R12), R12		\
   225  	MOVD	R2, 40(R1)		\
   226  	MOVD	0(R12), R0		\
   227  	MOVD	8(R12), R2		\
   228  	MOVD	R0, CTR			\
   229  	BL	(CTR)			\
   230  	MOVD	40(R1), R2		\
   231  	BL runtime·reginit(SB)
   232  
   233  
   234  // Runs on OS stack, called from runtime·osyield.
   235  TEXT runtime·osyield1(SB),NOSPLIT,$0
   236  	MOVD	$libc_sched_yield(SB), R12
   237  	CSYSCALL()
   238  	RET
   239  
   240  
   241  // Runs on OS stack, called from runtime·sigprocmask.
   242  TEXT runtime·sigprocmask1(SB),NOSPLIT,$0-24
   243  	MOVD	how+0(FP), R3
   244  	MOVD	new+8(FP), R4
   245  	MOVD	old+16(FP), R5
   246  	MOVD	$libpthread_sigthreadmask(SB), R12
   247  	CSYSCALL()
   248  	RET
   249  
   250  // Runs on OS stack, called from runtime·usleep.
   251  TEXT runtime·usleep1(SB),NOSPLIT,$0-4
   252  	MOVW	us+0(FP), R3
   253  	MOVD	$libc_usleep(SB), R12
   254  	CSYSCALL()
   255  	RET
   256  
   257  // Runs on OS stack, called from runtime·exit.
   258  TEXT runtime·exit1(SB),NOSPLIT,$0-4
   259  	MOVW	code+0(FP), R3
   260  	MOVD	$libc_exit(SB), R12
   261  	CSYSCALL()
   262  	RET
   263  
   264  // Runs on OS stack, called from runtime·write1.
   265  TEXT runtime·write2(SB),NOSPLIT,$0-28
   266  	MOVD	fd+0(FP), R3
   267  	MOVD	p+8(FP), R4
   268  	MOVW	n+16(FP), R5
   269  	MOVD	$libc_write(SB), R12
   270  	CSYSCALL()
   271  	MOVW	R3, ret+24(FP)
   272  	RET
   273  
   274  // Runs on OS stack, called from runtime·pthread_attr_init.
   275  TEXT runtime·pthread_attr_init1(SB),NOSPLIT,$0-12
   276  	MOVD	attr+0(FP), R3
   277  	MOVD	$libpthread_attr_init(SB), R12
   278  	CSYSCALL()
   279  	MOVW	R3, ret+8(FP)
   280  	RET
   281  
   282  // Runs on OS stack, called from runtime·pthread_attr_setstacksize.
   283  TEXT runtime·pthread_attr_setstacksize1(SB),NOSPLIT,$0-20
   284  	MOVD	attr+0(FP), R3
   285  	MOVD	size+8(FP), R4
   286  	MOVD	$libpthread_attr_setstacksize(SB), R12
   287  	CSYSCALL()
   288  	MOVW	R3, ret+16(FP)
   289  	RET
   290  
   291  // Runs on OS stack, called from runtime·pthread_setdetachstate.
   292  TEXT runtime·pthread_attr_setdetachstate1(SB),NOSPLIT,$0-20
   293  	MOVD	attr+0(FP), R3
   294  	MOVW	state+8(FP), R4
   295  	MOVD	$libpthread_attr_setdetachstate(SB), R12
   296  	CSYSCALL()
   297  	MOVW	R3, ret+16(FP)
   298  	RET
   299  
   300  // Runs on OS stack, called from runtime·pthread_create.
   301  TEXT runtime·pthread_create1(SB),NOSPLIT,$0-36
   302  	MOVD	tid+0(FP), R3
   303  	MOVD	attr+8(FP), R4
   304  	MOVD	fn+16(FP), R5
   305  	MOVD	arg+24(FP), R6
   306  	MOVD	$libpthread_create(SB), R12
   307  	CSYSCALL()
   308  	MOVW	R3, ret+32(FP)
   309  	RET
   310  
   311  // Runs on OS stack, called from runtime·sigaction.
   312  TEXT runtime·sigaction1(SB),NOSPLIT,$0-24
   313  	MOVD	sig+0(FP), R3
   314  	MOVD	new+8(FP), R4
   315  	MOVD	old+16(FP), R5
   316  	MOVD	$libc_sigaction(SB), R12
   317  	CSYSCALL()
   318  	RET
   319  

View as plain text