Home | History | Annotate | Download | only in runtime
      1 // Copyright 2015 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 // +build linux
      6 // +build mips64 mips64le
      7 
      8 //
      9 // System calls and other sys.stuff for mips64, Linux
     10 //
     11 
     12 #include "go_asm.h"
     13 #include "go_tls.h"
     14 #include "textflag.h"
     15 
     16 #define SYS_exit		5058
     17 #define SYS_read		5000
     18 #define SYS_write		5001
     19 #define SYS_open		5002
     20 #define SYS_close		5003
     21 #define SYS_getpid		5038
     22 #define SYS_kill		5060
     23 #define SYS_fcntl		5080
     24 #define SYS_gettimeofday	5094
     25 #define SYS_mmap		5009
     26 #define SYS_munmap		5011
     27 #define SYS_setitimer		5036
     28 #define SYS_clone		5055
     29 #define SYS_newselect		5022
     30 #define SYS_sched_yield		5023
     31 #define SYS_rt_sigreturn	5211
     32 #define SYS_rt_sigaction	5013
     33 #define SYS_rt_sigprocmask	5014
     34 #define SYS_sigaltstack		5129
     35 #define SYS_getrlimit		5095
     36 #define SYS_madvise		5027
     37 #define SYS_mincore		5026
     38 #define SYS_gettid		5178
     39 #define SYS_tkill		5192
     40 #define SYS_futex		5194
     41 #define SYS_sched_getaffinity	5196
     42 #define SYS_exit_group		5205
     43 #define SYS_epoll_create	5207
     44 #define SYS_epoll_ctl		5208
     45 #define SYS_epoll_wait		5209
     46 #define SYS_clock_gettime	5222
     47 #define SYS_epoll_create1	5285
     48 #define SYS_brk			5012
     49 
     50 TEXT runtimeexit(SB),NOSPLIT,$-8-4
     51 	MOVW	code+0(FP), R4
     52 	MOVV	$SYS_exit_group, R2
     53 	SYSCALL
     54 	RET
     55 
     56 // func exitThread(wait *uint32)
     57 TEXT runtimeexitThread(SB),NOSPLIT,$-8-8
     58 	MOVV	wait+0(FP), R1
     59 	// We're done using the stack.
     60 	MOVW	$0, R2
     61 	SYNC
     62 	MOVW	R2, (R1)
     63 	SYNC
     64 	MOVW	$0, R4	// exit code
     65 	MOVV	$SYS_exit, R2
     66 	SYSCALL
     67 	JMP	0(PC)
     68 
     69 TEXT runtimeopen(SB),NOSPLIT,$-8-20
     70 	MOVV	name+0(FP), R4
     71 	MOVW	mode+8(FP), R5
     72 	MOVW	perm+12(FP), R6
     73 	MOVV	$SYS_open, R2
     74 	SYSCALL
     75 	BEQ	R7, 2(PC)
     76 	MOVW	$-1, R2
     77 	MOVW	R2, ret+16(FP)
     78 	RET
     79 
     80 TEXT runtimeclosefd(SB),NOSPLIT,$-8-12
     81 	MOVW	fd+0(FP), R4
     82 	MOVV	$SYS_close, R2
     83 	SYSCALL
     84 	BEQ	R7, 2(PC)
     85 	MOVW	$-1, R2
     86 	MOVW	R2, ret+8(FP)
     87 	RET
     88 
     89 TEXT runtimewrite(SB),NOSPLIT,$-8-28
     90 	MOVV	fd+0(FP), R4
     91 	MOVV	p+8(FP), R5
     92 	MOVW	n+16(FP), R6
     93 	MOVV	$SYS_write, R2
     94 	SYSCALL
     95 	BEQ	R7, 2(PC)
     96 	MOVW	$-1, R2
     97 	MOVW	R2, ret+24(FP)
     98 	RET
     99 
    100 TEXT runtimeread(SB),NOSPLIT,$-8-28
    101 	MOVW	fd+0(FP), R4
    102 	MOVV	p+8(FP), R5
    103 	MOVW	n+16(FP), R6
    104 	MOVV	$SYS_read, R2
    105 	SYSCALL
    106 	BEQ	R7, 2(PC)
    107 	MOVW	$-1, R2
    108 	MOVW	R2, ret+24(FP)
    109 	RET
    110 
    111 TEXT runtimegetrlimit(SB),NOSPLIT,$-8-20
    112 	MOVW	kind+0(FP), R4	// _RLIMIT_AS = 6 on linux/mips
    113 	MOVV	limit+8(FP), R5
    114 	MOVV	$SYS_getrlimit, R2
    115 	SYSCALL
    116 	MOVW	R2, ret+16(FP)
    117 	RET
    118 
    119 TEXT runtimeusleep(SB),NOSPLIT,$16-4
    120 	MOVWU	usec+0(FP), R3
    121 	MOVV	R3, R5
    122 	MOVW	$1000000, R4
    123 	DIVVU	R4, R3
    124 	MOVV	LO, R3
    125 	MOVV	R3, 8(R29)
    126 	MULVU	R3, R4
    127 	MOVV	LO, R4
    128 	SUBVU	R4, R5
    129 	MOVV	R5, 16(R29)
    130 
    131 	// select(0, 0, 0, 0, &tv)
    132 	MOVW	$0, R4
    133 	MOVW	$0, R5
    134 	MOVW	$0, R6
    135 	MOVW	$0, R7
    136 	ADDV	$8, R29, R8
    137 	MOVV	$SYS_newselect, R2
    138 	SYSCALL
    139 	RET
    140 
    141 TEXT runtimegettid(SB),NOSPLIT,$0-4
    142 	MOVV	$SYS_gettid, R2
    143 	SYSCALL
    144 	MOVW	R2, ret+0(FP)
    145 	RET
    146 
    147 TEXT runtimeraise(SB),NOSPLIT,$-8
    148 	MOVV	$SYS_gettid, R2
    149 	SYSCALL
    150 	MOVW	R2, R4	// arg 1 tid
    151 	MOVW	sig+0(FP), R5	// arg 2
    152 	MOVV	$SYS_tkill, R2
    153 	SYSCALL
    154 	RET
    155 
    156 TEXT runtimeraiseproc(SB),NOSPLIT,$-8
    157 	MOVV	$SYS_getpid, R2
    158 	SYSCALL
    159 	MOVW	R2, R4	// arg 1 pid
    160 	MOVW	sig+0(FP), R5	// arg 2
    161 	MOVV	$SYS_kill, R2
    162 	SYSCALL
    163 	RET
    164 
    165 TEXT runtimesetitimer(SB),NOSPLIT,$-8-24
    166 	MOVW	mode+0(FP), R4
    167 	MOVV	new+8(FP), R5
    168 	MOVV	old+16(FP), R6
    169 	MOVV	$SYS_setitimer, R2
    170 	SYSCALL
    171 	RET
    172 
    173 TEXT runtimemincore(SB),NOSPLIT,$-8-28
    174 	MOVV	addr+0(FP), R4
    175 	MOVV	n+8(FP), R5
    176 	MOVV	dst+16(FP), R6
    177 	MOVV	$SYS_mincore, R2
    178 	SYSCALL
    179 	SUBVU	R2, R0, R2	// caller expects negative errno
    180 	MOVW	R2, ret+24(FP)
    181 	RET
    182 
    183 // func walltime() (sec int64, nsec int32)
    184 TEXT runtimewalltime(SB),NOSPLIT,$16
    185 	MOVW	$0, R4 // CLOCK_REALTIME
    186 	MOVV	$0(R29), R5
    187 	MOVV	$SYS_clock_gettime, R2
    188 	SYSCALL
    189 	MOVV	0(R29), R3	// sec
    190 	MOVV	8(R29), R5	// nsec
    191 	MOVV	R3, sec+0(FP)
    192 	MOVW	R5, nsec+8(FP)
    193 	RET
    194 
    195 TEXT runtimenanotime(SB),NOSPLIT,$16
    196 	MOVW	$1, R4 // CLOCK_MONOTONIC
    197 	MOVV	$0(R29), R5
    198 	MOVV	$SYS_clock_gettime, R2
    199 	SYSCALL
    200 	MOVV	0(R29), R3	// sec
    201 	MOVV	8(R29), R5	// nsec
    202 	// sec is in R3, nsec in R5
    203 	// return nsec in R3
    204 	MOVV	$1000000000, R4
    205 	MULVU	R4, R3
    206 	MOVV	LO, R3
    207 	ADDVU	R5, R3
    208 	MOVV	R3, ret+0(FP)
    209 	RET
    210 
    211 TEXT runtimertsigprocmask(SB),NOSPLIT,$-8-28
    212 	MOVW	how+0(FP), R4
    213 	MOVV	new+8(FP), R5
    214 	MOVV	old+16(FP), R6
    215 	MOVW	size+24(FP), R7
    216 	MOVV	$SYS_rt_sigprocmask, R2
    217 	SYSCALL
    218 	BEQ	R7, 2(PC)
    219 	MOVV	R0, 0xf1(R0)	// crash
    220 	RET
    221 
    222 TEXT runtimert_sigaction(SB),NOSPLIT,$-8-36
    223 	MOVV	sig+0(FP), R4
    224 	MOVV	new+8(FP), R5
    225 	MOVV	old+16(FP), R6
    226 	MOVV	size+24(FP), R7
    227 	MOVV	$SYS_rt_sigaction, R2
    228 	SYSCALL
    229 	MOVW	R2, ret+32(FP)
    230 	RET
    231 
    232 TEXT runtimesigfwd(SB),NOSPLIT,$0-32
    233 	MOVW	sig+8(FP), R4
    234 	MOVV	info+16(FP), R5
    235 	MOVV	ctx+24(FP), R6
    236 	MOVV	fn+0(FP), R25
    237 	JAL	(R25)
    238 	RET
    239 
    240 TEXT runtimesigtramp(SB),NOSPLIT,$64
    241 	// initialize REGSB = PC&0xffffffff00000000
    242 	BGEZAL	R0, 1(PC)
    243 	SRLV	$32, R31, RSB
    244 	SLLV	$32, RSB
    245 
    246 	// this might be called in external code context,
    247 	// where g is not set.
    248 	MOVB	runtimeiscgo(SB), R1
    249 	BEQ	R1, 2(PC)
    250 	JAL	runtimeload_g(SB)
    251 
    252 	MOVW	R4, 8(R29)
    253 	MOVV	R5, 16(R29)
    254 	MOVV	R6, 24(R29)
    255 	MOVV	$runtimesigtrampgo(SB), R1
    256 	JAL	(R1)
    257 	RET
    258 
    259 TEXT runtimecgoSigtramp(SB),NOSPLIT,$0
    260 	JMP	runtimesigtramp(SB)
    261 
    262 TEXT runtimemmap(SB),NOSPLIT,$-8
    263 	MOVV	addr+0(FP), R4
    264 	MOVV	n+8(FP), R5
    265 	MOVW	prot+16(FP), R6
    266 	MOVW	flags+20(FP), R7
    267 	MOVW	fd+24(FP), R8
    268 	MOVW	off+28(FP), R9
    269 
    270 	MOVV	$SYS_mmap, R2
    271 	SYSCALL
    272 	BEQ	R7, ok
    273 	MOVV	$0, p+32(FP)
    274 	MOVV	R2, err+40(FP)
    275 	RET
    276 ok:
    277 	MOVV	R2, p+32(FP)
    278 	MOVV	$0, err+40(FP)
    279 	RET
    280 
    281 TEXT runtimemunmap(SB),NOSPLIT,$-8
    282 	MOVV	addr+0(FP), R4
    283 	MOVV	n+8(FP), R5
    284 	MOVV	$SYS_munmap, R2
    285 	SYSCALL
    286 	BEQ	R7, 2(PC)
    287 	MOVV	R0, 0xf3(R0)	// crash
    288 	RET
    289 
    290 TEXT runtimemadvise(SB),NOSPLIT,$-8
    291 	MOVV	addr+0(FP), R4
    292 	MOVV	n+8(FP), R5
    293 	MOVW	flags+16(FP), R6
    294 	MOVV	$SYS_madvise, R2
    295 	SYSCALL
    296 	// ignore failure - maybe pages are locked
    297 	RET
    298 
    299 // int64 futex(int32 *uaddr, int32 op, int32 val,
    300 //	struct timespec *timeout, int32 *uaddr2, int32 val2);
    301 TEXT runtimefutex(SB),NOSPLIT,$-8
    302 	MOVV	addr+0(FP), R4
    303 	MOVW	op+8(FP), R5
    304 	MOVW	val+12(FP), R6
    305 	MOVV	ts+16(FP), R7
    306 	MOVV	addr2+24(FP), R8
    307 	MOVW	val3+32(FP), R9
    308 	MOVV	$SYS_futex, R2
    309 	SYSCALL
    310 	MOVW	R2, ret+40(FP)
    311 	RET
    312 
    313 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
    314 TEXT runtimeclone(SB),NOSPLIT,$-8
    315 	MOVW	flags+0(FP), R4
    316 	MOVV	stk+8(FP), R5
    317 
    318 	// Copy mp, gp, fn off parent stack for use by child.
    319 	// Careful: Linux system call clobbers ???.
    320 	MOVV	mp+16(FP), R16
    321 	MOVV	gp+24(FP), R17
    322 	MOVV	fn+32(FP), R18
    323 
    324 	MOVV	R16, -8(R5)
    325 	MOVV	R17, -16(R5)
    326 	MOVV	R18, -24(R5)
    327 	MOVV	$1234, R16
    328 	MOVV	R16, -32(R5)
    329 
    330 	MOVV	$SYS_clone, R2
    331 	SYSCALL
    332 
    333 	// In parent, return.
    334 	BEQ	R2, 3(PC)
    335 	MOVW	R2, ret+40(FP)
    336 	RET
    337 
    338 	// In child, on new stack.
    339 	MOVV	-32(R29), R16
    340 	MOVV	$1234, R1
    341 	BEQ	R16, R1, 2(PC)
    342 	MOVV	R0, 0(R0)
    343 
    344 	// Initialize m->procid to Linux tid
    345 	MOVV	$SYS_gettid, R2
    346 	SYSCALL
    347 
    348 	MOVV	-24(R29), R18		// fn
    349 	MOVV	-16(R29), R17		// g
    350 	MOVV	-8(R29), R16		// m
    351 
    352 	BEQ	R16, nog
    353 	BEQ	R17, nog
    354 
    355 	MOVV	R2, m_procid(R16)
    356 
    357 	// TODO: setup TLS.
    358 
    359 	// In child, set up new stack
    360 	MOVV	R16, g_m(R17)
    361 	MOVV	R17, g
    362 	//CALL	runtimestackcheck(SB)
    363 
    364 nog:
    365 	// Call fn
    366 	JAL	(R18)
    367 
    368 	// It shouldn't return.	 If it does, exit that thread.
    369 	MOVW	$111, R4
    370 	MOVV	$SYS_exit, R2
    371 	SYSCALL
    372 	JMP	-3(PC)	// keep exiting
    373 
    374 TEXT runtimesigaltstack(SB),NOSPLIT,$-8
    375 	MOVV	new+0(FP), R4
    376 	MOVV	old+8(FP), R5
    377 	MOVV	$SYS_sigaltstack, R2
    378 	SYSCALL
    379 	BEQ	R7, 2(PC)
    380 	MOVV	R0, 0xf1(R0)	// crash
    381 	RET
    382 
    383 TEXT runtimeosyield(SB),NOSPLIT,$-8
    384 	MOVV	$SYS_sched_yield, R2
    385 	SYSCALL
    386 	RET
    387 
    388 TEXT runtimesched_getaffinity(SB),NOSPLIT,$-8
    389 	MOVV	pid+0(FP), R4
    390 	MOVV	len+8(FP), R5
    391 	MOVV	buf+16(FP), R6
    392 	MOVV	$SYS_sched_getaffinity, R2
    393 	SYSCALL
    394 	MOVW	R2, ret+24(FP)
    395 	RET
    396 
    397 // int32 runtimeepollcreate(int32 size);
    398 TEXT runtimeepollcreate(SB),NOSPLIT,$-8
    399 	MOVW    size+0(FP), R4
    400 	MOVV	$SYS_epoll_create, R2
    401 	SYSCALL
    402 	MOVW	R2, ret+8(FP)
    403 	RET
    404 
    405 // int32 runtimeepollcreate1(int32 flags);
    406 TEXT runtimeepollcreate1(SB),NOSPLIT,$-8
    407 	MOVW	flags+0(FP), R4
    408 	MOVV	$SYS_epoll_create1, R2
    409 	SYSCALL
    410 	MOVW	R2, ret+8(FP)
    411 	RET
    412 
    413 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
    414 TEXT runtimeepollctl(SB),NOSPLIT,$-8
    415 	MOVW	epfd+0(FP), R4
    416 	MOVW	op+4(FP), R5
    417 	MOVW	fd+8(FP), R6
    418 	MOVV	ev+16(FP), R7
    419 	MOVV	$SYS_epoll_ctl, R2
    420 	SYSCALL
    421 	MOVW	R2, ret+24(FP)
    422 	RET
    423 
    424 // int32 runtimeepollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
    425 TEXT runtimeepollwait(SB),NOSPLIT,$-8
    426 	MOVW	epfd+0(FP), R4
    427 	MOVV	ev+8(FP), R5
    428 	MOVW	nev+16(FP), R6
    429 	MOVW	timeout+20(FP), R7
    430 	MOVV	$SYS_epoll_wait, R2
    431 	SYSCALL
    432 	MOVW	R2, ret+24(FP)
    433 	RET
    434 
    435 // void runtimecloseonexec(int32 fd);
    436 TEXT runtimecloseonexec(SB),NOSPLIT,$-8
    437 	MOVW    fd+0(FP), R4  // fd
    438 	MOVV    $2, R5  // F_SETFD
    439 	MOVV    $1, R6  // FD_CLOEXEC
    440 	MOVV	$SYS_fcntl, R2
    441 	SYSCALL
    442 	RET
    443 
    444 // func sbrk0() uintptr
    445 TEXT runtimesbrk0(SB),NOSPLIT,$-8-8
    446 	// Implemented as brk(NULL).
    447 	MOVV	$0, R4
    448 	MOVV	$SYS_brk, R2
    449 	SYSCALL
    450 	MOVV	R2, ret+0(FP)
    451 	RET
    452