...

Text file src/runtime/sys_linux_s390x.s

     1	// Copyright 2016 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	// System calls and other system stuff for Linux s390x; see
     6	// /usr/include/asm/unistd.h for the syscall number definitions.
     7	
     8	#include "go_asm.h"
     9	#include "go_tls.h"
    10	#include "textflag.h"
    11	
    12	#define SYS_exit                  1
    13	#define SYS_read                  3
    14	#define SYS_write                 4
    15	#define SYS_open                  5
    16	#define SYS_close                 6
    17	#define SYS_getpid               20
    18	#define SYS_kill                 37
    19	#define SYS_brk			 45
    20	#define SYS_fcntl                55
    21	#define SYS_mmap                 90
    22	#define SYS_munmap               91
    23	#define SYS_setitimer           104
    24	#define SYS_clone               120
    25	#define SYS_sched_yield         158
    26	#define SYS_nanosleep           162
    27	#define SYS_rt_sigreturn        173
    28	#define SYS_rt_sigaction        174
    29	#define SYS_rt_sigprocmask      175
    30	#define SYS_sigaltstack         186
    31	#define SYS_madvise             219
    32	#define SYS_mincore             218
    33	#define SYS_gettid              236
    34	#define SYS_futex               238
    35	#define SYS_sched_getaffinity   240
    36	#define SYS_tgkill              241
    37	#define SYS_exit_group          248
    38	#define SYS_epoll_create        249
    39	#define SYS_epoll_ctl           250
    40	#define SYS_epoll_wait          251
    41	#define SYS_clock_gettime       260
    42	#define SYS_epoll_create1       327
    43	
    44	TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
    45		MOVW	code+0(FP), R2
    46		MOVW	$SYS_exit_group, R1
    47		SYSCALL
    48		RET
    49	
    50	// func exitThread(wait *uint32)
    51	TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
    52		MOVD	wait+0(FP), R1
    53		// We're done using the stack.
    54		MOVW	$0, R2
    55		MOVW	R2, (R1)
    56		MOVW	$0, R2	// exit code
    57		MOVW	$SYS_exit, R1
    58		SYSCALL
    59		JMP	0(PC)
    60	
    61	TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
    62		MOVD	name+0(FP), R2
    63		MOVW	mode+8(FP), R3
    64		MOVW	perm+12(FP), R4
    65		MOVW	$SYS_open, R1
    66		SYSCALL
    67		MOVD	$-4095, R3
    68		CMPUBLT	R2, R3, 2(PC)
    69		MOVW	$-1, R2
    70		MOVW	R2, ret+16(FP)
    71		RET
    72	
    73	TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
    74		MOVW	fd+0(FP), R2
    75		MOVW	$SYS_close, R1
    76		SYSCALL
    77		MOVD	$-4095, R3
    78		CMPUBLT	R2, R3, 2(PC)
    79		MOVW	$-1, R2
    80		MOVW	R2, ret+8(FP)
    81		RET
    82	
    83	TEXT runtime·write(SB),NOSPLIT|NOFRAME,$0-28
    84		MOVD	fd+0(FP), R2
    85		MOVD	p+8(FP), R3
    86		MOVW	n+16(FP), R4
    87		MOVW	$SYS_write, R1
    88		SYSCALL
    89		MOVD	$-4095, R3
    90		CMPUBLT	R2, R3, 2(PC)
    91		MOVW	$-1, R2
    92		MOVW	R2, ret+24(FP)
    93		RET
    94	
    95	TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
    96		MOVW	fd+0(FP), R2
    97		MOVD	p+8(FP), R3
    98		MOVW	n+16(FP), R4
    99		MOVW	$SYS_read, R1
   100		SYSCALL
   101		MOVD	$-4095, R3
   102		CMPUBLT	R2, R3, 2(PC)
   103		MOVW	$-1, R2
   104		MOVW	R2, ret+24(FP)
   105		RET
   106	
   107	TEXT runtime·usleep(SB),NOSPLIT,$16-4
   108		MOVW	usec+0(FP), R2
   109		MOVD	R2, R4
   110		MOVW	$1000000, R3
   111		DIVD	R3, R2
   112		MOVD	R2, 8(R15)
   113		MOVW	$1000, R3
   114		MULLD	R2, R3
   115		SUB	R3, R4
   116		MOVD	R4, 16(R15)
   117	
   118		// nanosleep(&ts, 0)
   119		ADD	$8, R15, R2
   120		MOVW	$0, R3
   121		MOVW	$SYS_nanosleep, R1
   122		SYSCALL
   123		RET
   124	
   125	TEXT runtime·gettid(SB),NOSPLIT,$0-4
   126		MOVW	$SYS_gettid, R1
   127		SYSCALL
   128		MOVW	R2, ret+0(FP)
   129		RET
   130	
   131	TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
   132		MOVW	$SYS_getpid, R1
   133		SYSCALL
   134		MOVW	R2, R10
   135		MOVW	$SYS_gettid, R1
   136		SYSCALL
   137		MOVW	R2, R3	// arg 2 tid
   138		MOVW	R10, R2	// arg 1 pid
   139		MOVW	sig+0(FP), R4	// arg 2
   140		MOVW	$SYS_tgkill, R1
   141		SYSCALL
   142		RET
   143	
   144	TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
   145		MOVW	$SYS_getpid, R1
   146		SYSCALL
   147		MOVW	R2, R2	// arg 1 pid
   148		MOVW	sig+0(FP), R3	// arg 2
   149		MOVW	$SYS_kill, R1
   150		SYSCALL
   151		RET
   152	
   153	TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
   154		MOVW	mode+0(FP), R2
   155		MOVD	new+8(FP), R3
   156		MOVD	old+16(FP), R4
   157		MOVW	$SYS_setitimer, R1
   158		SYSCALL
   159		RET
   160	
   161	TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
   162		MOVD	addr+0(FP), R2
   163		MOVD	n+8(FP), R3
   164		MOVD	dst+16(FP), R4
   165		MOVW	$SYS_mincore, R1
   166		SYSCALL
   167		MOVW	R2, ret+24(FP)
   168		RET
   169	
   170	// func walltime() (sec int64, nsec int32)
   171	TEXT runtime·walltime(SB),NOSPLIT,$16
   172		MOVW	$0, R2 // CLOCK_REALTIME
   173		MOVD	$tp-16(SP), R3
   174		MOVW	$SYS_clock_gettime, R1
   175		SYSCALL
   176		LMG	tp-16(SP), R2, R3
   177		// sec is in R2, nsec in R3
   178		MOVD	R2, sec+0(FP)
   179		MOVW	R3, nsec+8(FP)
   180		RET
   181	
   182	TEXT runtime·nanotime(SB),NOSPLIT,$16
   183		MOVW	$1, R2 // CLOCK_MONOTONIC
   184		MOVD	$tp-16(SP), R3
   185		MOVW	$SYS_clock_gettime, R1
   186		SYSCALL
   187		LMG	tp-16(SP), R2, R3
   188		// sec is in R2, nsec in R3
   189		// return nsec in R2
   190		MULLD	$1000000000, R2
   191		ADD	R3, R2
   192		MOVD	R2, ret+0(FP)
   193		RET
   194	
   195	TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
   196		MOVW	how+0(FP), R2
   197		MOVD	new+8(FP), R3
   198		MOVD	old+16(FP), R4
   199		MOVW	size+24(FP), R5
   200		MOVW	$SYS_rt_sigprocmask, R1
   201		SYSCALL
   202		MOVD	$-4095, R3
   203		CMPUBLT	R2, R3, 2(PC)
   204		MOVD	R0, 0(R0) // crash
   205		RET
   206	
   207	TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
   208		MOVD	sig+0(FP), R2
   209		MOVD	new+8(FP), R3
   210		MOVD	old+16(FP), R4
   211		MOVD	size+24(FP), R5
   212		MOVW	$SYS_rt_sigaction, R1
   213		SYSCALL
   214		MOVW	R2, ret+32(FP)
   215		RET
   216	
   217	TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   218		MOVW	sig+8(FP), R2
   219		MOVD	info+16(FP), R3
   220		MOVD	ctx+24(FP), R4
   221		MOVD	fn+0(FP), R5
   222		BL	R5
   223		RET
   224	
   225	TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
   226		RET
   227	
   228	TEXT runtime·sigtramp(SB),NOSPLIT,$64
   229		// initialize essential registers (just in case)
   230		XOR	R0, R0
   231	
   232		// this might be called in external code context,
   233		// where g is not set.
   234		MOVB	runtime·iscgo(SB), R6
   235		CMPBEQ	R6, $0, 2(PC)
   236		BL	runtime·load_g(SB)
   237	
   238		MOVW	R2, 8(R15)
   239		MOVD	R3, 16(R15)
   240		MOVD	R4, 24(R15)
   241		MOVD	$runtime·sigtrampgo(SB), R5
   242		BL	R5
   243		RET
   244	
   245	TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   246		BR	runtime·sigtramp(SB)
   247	
   248	// func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
   249	TEXT runtime·mmap(SB),NOSPLIT,$48-48
   250		MOVD	addr+0(FP), R2
   251		MOVD	n+8(FP), R3
   252		MOVW	prot+16(FP), R4
   253		MOVW	flags+20(FP), R5
   254		MOVW	fd+24(FP), R6
   255		MOVWZ	off+28(FP), R7
   256	
   257		// s390x uses old_mmap, so the arguments need to be placed into
   258		// a struct and a pointer to the struct passed to mmap.
   259		MOVD	R2, addr-48(SP)
   260		MOVD	R3, n-40(SP)
   261		MOVD	R4, prot-32(SP)
   262		MOVD	R5, flags-24(SP)
   263		MOVD	R6, fd-16(SP)
   264		MOVD	R7, off-8(SP)
   265	
   266		MOVD	$addr-48(SP), R2
   267		MOVW	$SYS_mmap, R1
   268		SYSCALL
   269		MOVD	$-4095, R3
   270		CMPUBLT	R2, R3, ok
   271		NEG	R2
   272		MOVD	$0, p+32(FP)
   273		MOVD	R2, err+40(FP)
   274		RET
   275	ok:
   276		MOVD	R2, p+32(FP)
   277		MOVD	$0, err+40(FP)
   278		RET
   279	
   280	TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
   281		MOVD	addr+0(FP), R2
   282		MOVD	n+8(FP), R3
   283		MOVW	$SYS_munmap, R1
   284		SYSCALL
   285		MOVD	$-4095, R3
   286		CMPUBLT	R2, R3, 2(PC)
   287		MOVD	R0, 0(R0) // crash
   288		RET
   289	
   290	TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
   291		MOVD	addr+0(FP), R2
   292		MOVD	n+8(FP), R3
   293		MOVW	flags+16(FP), R4
   294		MOVW	$SYS_madvise, R1
   295		SYSCALL
   296		MOVW	R2, ret+24(FP)
   297		RET
   298	
   299	// int64 futex(int32 *uaddr, int32 op, int32 val,
   300	//	struct timespec *timeout, int32 *uaddr2, int32 val2);
   301	TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
   302		MOVD	addr+0(FP), R2
   303		MOVW	op+8(FP), R3
   304		MOVW	val+12(FP), R4
   305		MOVD	ts+16(FP), R5
   306		MOVD	addr2+24(FP), R6
   307		MOVW	val3+32(FP),  R7
   308		MOVW	$SYS_futex, R1
   309		SYSCALL
   310		MOVW	R2, ret+40(FP)
   311		RET
   312	
   313	// int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
   314	TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
   315		MOVW	flags+0(FP), R3
   316		MOVD	stk+8(FP), R2
   317	
   318		// Copy mp, gp, fn off parent stack for use by child.
   319		// Careful: Linux system call clobbers ???.
   320		MOVD	mp+16(FP), R7
   321		MOVD	gp+24(FP), R8
   322		MOVD	fn+32(FP), R9
   323	
   324		MOVD	R7, -8(R2)
   325		MOVD	R8, -16(R2)
   326		MOVD	R9, -24(R2)
   327		MOVD	$1234, R7
   328		MOVD	R7, -32(R2)
   329	
   330		SYSCALL $SYS_clone
   331	
   332		// In parent, return.
   333		CMPBEQ	R2, $0, 3(PC)
   334		MOVW	R2, ret+40(FP)
   335		RET
   336	
   337		// In child, on new stack.
   338		// initialize essential registers
   339		XOR	R0, R0
   340		MOVD	-32(R15), R7
   341		CMP	R7, $1234
   342		BEQ	2(PC)
   343		MOVD	R0, 0(R0)
   344	
   345		// Initialize m->procid to Linux tid
   346		SYSCALL $SYS_gettid
   347	
   348		MOVD	-24(R15), R9        // fn
   349		MOVD	-16(R15), R8        // g
   350		MOVD	-8(R15), R7         // m
   351	
   352		CMPBEQ	R7, $0, nog
   353		CMP	R8, $0
   354		BEQ	nog
   355	
   356		MOVD	R2, m_procid(R7)
   357	
   358		// In child, set up new stack
   359		MOVD	R7, g_m(R8)
   360		MOVD	R8, g
   361		//CALL	runtime·stackcheck(SB)
   362	
   363	nog:
   364		// Call fn
   365		BL	R9
   366	
   367		// It shouldn't return.	 If it does, exit that thread.
   368		MOVW	$111, R2
   369		MOVW	$SYS_exit, R1
   370		SYSCALL
   371		BR	-2(PC)	// keep exiting
   372	
   373	TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
   374		MOVD	new+0(FP), R2
   375		MOVD	old+8(FP), R3
   376		MOVW	$SYS_sigaltstack, R1
   377		SYSCALL
   378		MOVD	$-4095, R3
   379		CMPUBLT	R2, R3, 2(PC)
   380		MOVD	R0, 0(R0) // crash
   381		RET
   382	
   383	TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
   384		MOVW	$SYS_sched_yield, R1
   385		SYSCALL
   386		RET
   387	
   388	TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
   389		MOVD	pid+0(FP), R2
   390		MOVD	len+8(FP), R3
   391		MOVD	buf+16(FP), R4
   392		MOVW	$SYS_sched_getaffinity, R1
   393		SYSCALL
   394		MOVW	R2, ret+24(FP)
   395		RET
   396	
   397	// int32 runtime·epollcreate(int32 size);
   398	TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
   399		MOVW    size+0(FP), R2
   400		MOVW	$SYS_epoll_create, R1
   401		SYSCALL
   402		MOVW	R2, ret+8(FP)
   403		RET
   404	
   405	// int32 runtime·epollcreate1(int32 flags);
   406	TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
   407		MOVW	flags+0(FP), R2
   408		MOVW	$SYS_epoll_create1, R1
   409		SYSCALL
   410		MOVW	R2, ret+8(FP)
   411		RET
   412	
   413	// func epollctl(epfd, op, fd int32, ev *epollEvent) int
   414	TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
   415		MOVW	epfd+0(FP), R2
   416		MOVW	op+4(FP), R3
   417		MOVW	fd+8(FP), R4
   418		MOVD	ev+16(FP), R5
   419		MOVW	$SYS_epoll_ctl, R1
   420		SYSCALL
   421		MOVW	R2, ret+24(FP)
   422		RET
   423	
   424	// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
   425	TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
   426		MOVW	epfd+0(FP), R2
   427		MOVD	ev+8(FP), R3
   428		MOVW	nev+16(FP), R4
   429		MOVW	timeout+20(FP), R5
   430		MOVW	$SYS_epoll_wait, R1
   431		SYSCALL
   432		MOVW	R2, ret+24(FP)
   433		RET
   434	
   435	// void runtime·closeonexec(int32 fd);
   436	TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
   437		MOVW    fd+0(FP), R2  // fd
   438		MOVD    $2, R3  // F_SETFD
   439		MOVD    $1, R4  // FD_CLOEXEC
   440		MOVW	$SYS_fcntl, R1
   441		SYSCALL
   442		RET
   443	
   444	// func sbrk0() uintptr
   445	TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8
   446		// Implemented as brk(NULL).
   447		MOVD	$0, R2
   448		MOVW	$SYS_brk, R1
   449		SYSCALL
   450		MOVD	R2, ret+0(FP)
   451		RET
   452	
   453	TEXT runtime·access(SB),$0-20
   454		MOVD	$0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   455		MOVW	R0, ret+16(FP)
   456		RET
   457	
   458	TEXT runtime·connect(SB),$0-28
   459		MOVD	$0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   460		MOVW	R0, ret+24(FP)
   461		RET
   462	
   463	TEXT runtime·socket(SB),$0-20
   464		MOVD	$0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
   465		MOVW	R0, ret+16(FP)
   466		RET

View as plain text