...

Text file src/runtime/sys_aix_ppc64.s

Documentation: runtime

     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
    15TEXT 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.
    36DATA	runtime·asmsyscall6+0(SB)/8, $asmsyscall6<>(SB)
    37DATA	runtime·asmsyscall6+8(SB)/8, $TOC(SB)
    38DATA	runtime·asmsyscall6+16(SB)/8, $0
    39GLOBL	runtime·asmsyscall6(SB), NOPTR, $24
    40
    41TEXT 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
    72skiperrno:
    73	// Reset errno if no error has been returned
    74	MOVD	R0, (libcall_err)(R5)
    75	RET
    76
    77
    78TEXT 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.
    96DATA	runtime·sigtramp+0(SB)/8, $sigtramp<>(SB)
    97DATA	runtime·sigtramp+8(SB)/8, $TOC(SB)
    98DATA	runtime·sigtramp+16(SB)/8, $0
    99GLOBL	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.
   104TEXT 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
   149sigtramp:
   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
   180exit:
   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.
   195DATA	runtime·tstart+0(SB)/8, $tstart<>(SB)
   196DATA	runtime·tstart+8(SB)/8, $TOC(SB)
   197DATA	runtime·tstart+16(SB)/8, $0
   198GLOBL	runtime·tstart(SB), NOPTR, $24
   199
   200TEXT 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.
   235TEXT 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.
   242TEXT 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.
   251TEXT 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.
   258TEXT 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.
   265TEXT 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.
   275TEXT 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.
   283TEXT 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.
   292TEXT 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.
   301TEXT 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.
   312TEXT 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

View as plain text