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