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

View as plain text