Text file
src/runtime/sys_netbsd_386.s
1 // Copyright 2009 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 sys.stuff for 386, NetBSD
6 // /usr/src/sys/kern/syscalls.master for syscall numbers.
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 #define CLOCK_REALTIME 0
14 #define CLOCK_MONOTONIC 3
15 #define FD_CLOEXEC 1
16 #define F_SETFD 2
17
18 #define SYS_exit 1
19 #define SYS_read 3
20 #define SYS_write 4
21 #define SYS_open 5
22 #define SYS_close 6
23 #define SYS_getpid 20
24 #define SYS_kill 37
25 #define SYS_munmap 73
26 #define SYS_madvise 75
27 #define SYS_fcntl 92
28 #define SYS_mmap 197
29 #define SYS___sysctl 202
30 #define SYS___sigaltstack14 281
31 #define SYS___sigprocmask14 293
32 #define SYS_getcontext 307
33 #define SYS_setcontext 308
34 #define SYS__lwp_create 309
35 #define SYS__lwp_exit 310
36 #define SYS__lwp_self 311
37 #define SYS__lwp_setprivate 317
38 #define SYS__lwp_kill 318
39 #define SYS__lwp_unpark 321
40 #define SYS___sigaction_sigtramp 340
41 #define SYS_kqueue 344
42 #define SYS_sched_yield 350
43 #define SYS___setitimer50 425
44 #define SYS___clock_gettime50 427
45 #define SYS___nanosleep50 430
46 #define SYS___kevent50 435
47 #define SYS____lwp_park60 478
48
49 // Exit the entire program (like C exit)
50 TEXT runtime·exit(SB),NOSPLIT,$-4
51 MOVL $SYS_exit, AX
52 INT $0x80
53 MOVL $0xf1, 0xf1 // crash
54 RET
55
56 // func exitThread(wait *uint32)
57 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
58 MOVL wait+0(FP), AX
59 // We're done using the stack.
60 MOVL $0, (AX)
61 MOVL $SYS__lwp_exit, AX
62 INT $0x80
63 MOVL $0xf1, 0xf1 // crash
64 JMP 0(PC)
65
66 TEXT runtime·open(SB),NOSPLIT,$-4
67 MOVL $SYS_open, AX
68 INT $0x80
69 JAE 2(PC)
70 MOVL $-1, AX
71 MOVL AX, ret+12(FP)
72 RET
73
74 TEXT runtime·closefd(SB),NOSPLIT,$-4
75 MOVL $SYS_close, AX
76 INT $0x80
77 JAE 2(PC)
78 MOVL $-1, AX
79 MOVL AX, ret+4(FP)
80 RET
81
82 TEXT runtime·read(SB),NOSPLIT,$-4
83 MOVL $SYS_read, AX
84 INT $0x80
85 JAE 2(PC)
86 NEGL AX // caller expects negative errno
87 MOVL AX, ret+12(FP)
88 RET
89
90 // func pipe() (r, w int32, errno int32)
91 TEXT runtime·pipe(SB),NOSPLIT,$0-12
92 MOVL $42, AX
93 INT $0x80
94 JCC pipeok
95 MOVL $-1, r+0(FP)
96 MOVL $-1, w+4(FP)
97 MOVL AX, errno+8(FP)
98 RET
99 pipeok:
100 MOVL AX, r+0(FP)
101 MOVL DX, w+4(FP)
102 MOVL $0, errno+8(FP)
103 RET
104
105 // func pipe2(flags int32) (r, w int32, errno int32)
106 TEXT runtime·pipe2(SB),NOSPLIT,$12-16
107 MOVL $453, AX
108 LEAL r+4(FP), BX
109 MOVL BX, 4(SP)
110 MOVL flags+0(FP), BX
111 MOVL BX, 8(SP)
112 INT $0x80
113 MOVL AX, errno+12(FP)
114 RET
115
116 TEXT runtime·write1(SB),NOSPLIT,$-4
117 MOVL $SYS_write, AX
118 INT $0x80
119 JAE 2(PC)
120 NEGL AX // caller expects negative errno
121 MOVL AX, ret+12(FP)
122 RET
123
124 TEXT runtime·usleep(SB),NOSPLIT,$24
125 MOVL $0, DX
126 MOVL usec+0(FP), AX
127 MOVL $1000000, CX
128 DIVL CX
129 MOVL AX, 12(SP) // tv_sec - l32
130 MOVL $0, 16(SP) // tv_sec - h32
131 MOVL $1000, AX
132 MULL DX
133 MOVL AX, 20(SP) // tv_nsec
134
135 MOVL $0, 0(SP)
136 LEAL 12(SP), AX
137 MOVL AX, 4(SP) // arg 1 - rqtp
138 MOVL $0, 8(SP) // arg 2 - rmtp
139 MOVL $SYS___nanosleep50, AX
140 INT $0x80
141 RET
142
143 TEXT runtime·lwp_kill(SB),NOSPLIT,$12-8
144 MOVL $0, 0(SP)
145 MOVL tid+0(FP), AX
146 MOVL AX, 4(SP) // arg 1 - target
147 MOVL sig+4(FP), AX
148 MOVL AX, 8(SP) // arg 2 - signo
149 MOVL $SYS__lwp_kill, AX
150 INT $0x80
151 RET
152
153 TEXT runtime·raiseproc(SB),NOSPLIT,$12
154 MOVL $SYS_getpid, AX
155 INT $0x80
156 MOVL $0, 0(SP)
157 MOVL AX, 4(SP) // arg 1 - pid
158 MOVL sig+0(FP), AX
159 MOVL AX, 8(SP) // arg 2 - signo
160 MOVL $SYS_kill, AX
161 INT $0x80
162 RET
163
164 TEXT runtime·mmap(SB),NOSPLIT,$36
165 LEAL addr+0(FP), SI
166 LEAL 4(SP), DI
167 CLD
168 MOVSL // arg 1 - addr
169 MOVSL // arg 2 - len
170 MOVSL // arg 3 - prot
171 MOVSL // arg 4 - flags
172 MOVSL // arg 5 - fd
173 MOVL $0, AX
174 STOSL // arg 6 - pad
175 MOVSL // arg 7 - offset
176 MOVL $0, AX // top 32 bits of file offset
177 STOSL
178 MOVL $SYS_mmap, AX
179 INT $0x80
180 JAE ok
181 MOVL $0, p+24(FP)
182 MOVL AX, err+28(FP)
183 RET
184 ok:
185 MOVL AX, p+24(FP)
186 MOVL $0, err+28(FP)
187 RET
188
189 TEXT runtime·munmap(SB),NOSPLIT,$-4
190 MOVL $SYS_munmap, AX
191 INT $0x80
192 JAE 2(PC)
193 MOVL $0xf1, 0xf1 // crash
194 RET
195
196 TEXT runtime·madvise(SB),NOSPLIT,$-4
197 MOVL $SYS_madvise, AX
198 INT $0x80
199 JAE 2(PC)
200 MOVL $-1, AX
201 MOVL AX, ret+12(FP)
202 RET
203
204 TEXT runtime·setitimer(SB),NOSPLIT,$-4
205 MOVL $SYS___setitimer50, AX
206 INT $0x80
207 RET
208
209 // func walltime() (sec int64, nsec int32)
210 TEXT runtime·walltime(SB), NOSPLIT, $32
211 LEAL 12(SP), BX
212 MOVL $CLOCK_REALTIME, 4(SP) // arg 1 - clock_id
213 MOVL BX, 8(SP) // arg 2 - tp
214 MOVL $SYS___clock_gettime50, AX
215 INT $0x80
216
217 MOVL 12(SP), AX // sec - l32
218 MOVL AX, sec_lo+0(FP)
219 MOVL 16(SP), AX // sec - h32
220 MOVL AX, sec_hi+4(FP)
221
222 MOVL 20(SP), BX // nsec
223 MOVL BX, nsec+8(FP)
224 RET
225
226 // int64 nanotime1(void) so really
227 // void nanotime1(int64 *nsec)
228 TEXT runtime·nanotime1(SB),NOSPLIT,$32
229 LEAL 12(SP), BX
230 MOVL $CLOCK_MONOTONIC, 4(SP) // arg 1 - clock_id
231 MOVL BX, 8(SP) // arg 2 - tp
232 MOVL $SYS___clock_gettime50, AX
233 INT $0x80
234
235 MOVL 16(SP), CX // sec - h32
236 IMULL $1000000000, CX
237
238 MOVL 12(SP), AX // sec - l32
239 MOVL $1000000000, BX
240 MULL BX // result in dx:ax
241
242 MOVL 20(SP), BX // nsec
243 ADDL BX, AX
244 ADCL CX, DX // add high bits with carry
245
246 MOVL AX, ret_lo+0(FP)
247 MOVL DX, ret_hi+4(FP)
248 RET
249
250 TEXT runtime·getcontext(SB),NOSPLIT,$-4
251 MOVL $SYS_getcontext, AX
252 INT $0x80
253 JAE 2(PC)
254 MOVL $0xf1, 0xf1 // crash
255 RET
256
257 TEXT runtime·sigprocmask(SB),NOSPLIT,$-4
258 MOVL $SYS___sigprocmask14, AX
259 INT $0x80
260 JAE 2(PC)
261 MOVL $0xf1, 0xf1 // crash
262 RET
263
264 TEXT sigreturn_tramp<>(SB),NOSPLIT,$0
265 LEAL 140(SP), AX // Load address of ucontext
266 MOVL AX, 4(SP)
267 MOVL $SYS_setcontext, AX
268 INT $0x80
269 MOVL $-1, 4(SP) // Something failed...
270 MOVL $SYS_exit, AX
271 INT $0x80
272
273 TEXT runtime·sigaction(SB),NOSPLIT,$24
274 LEAL sig+0(FP), SI
275 LEAL 4(SP), DI
276 CLD
277 MOVSL // arg 1 - sig
278 MOVSL // arg 2 - act
279 MOVSL // arg 3 - oact
280 LEAL sigreturn_tramp<>(SB), AX
281 STOSL // arg 4 - tramp
282 MOVL $2, AX
283 STOSL // arg 5 - vers
284 MOVL $SYS___sigaction_sigtramp, AX
285 INT $0x80
286 JAE 2(PC)
287 MOVL $0xf1, 0xf1 // crash
288 RET
289
290 TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
291 MOVL fn+0(FP), AX
292 MOVL sig+4(FP), BX
293 MOVL info+8(FP), CX
294 MOVL ctx+12(FP), DX
295 MOVL SP, SI
296 SUBL $32, SP
297 ANDL $-15, SP // align stack: handler might be a C function
298 MOVL BX, 0(SP)
299 MOVL CX, 4(SP)
300 MOVL DX, 8(SP)
301 MOVL SI, 12(SP) // save SI: handler might be a Go function
302 CALL AX
303 MOVL 12(SP), AX
304 MOVL AX, SP
305 RET
306
307 // Called by OS using C ABI.
308 TEXT runtime·sigtramp(SB),NOSPLIT,$28
309 NOP SP // tell vet SP changed - stop checking offsets
310 // Save callee-saved C registers, since the caller may be a C signal handler.
311 MOVL BX, bx-4(SP)
312 MOVL BP, bp-8(SP)
313 MOVL SI, si-12(SP)
314 MOVL DI, di-16(SP)
315 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
316 // modify them.
317
318 MOVL 32(SP), BX // signo
319 MOVL BX, 0(SP)
320 MOVL 36(SP), BX // info
321 MOVL BX, 4(SP)
322 MOVL 40(SP), BX // context
323 MOVL BX, 8(SP)
324 CALL runtime·sigtrampgo(SB)
325
326 MOVL di-16(SP), DI
327 MOVL si-12(SP), SI
328 MOVL bp-8(SP), BP
329 MOVL bx-4(SP), BX
330 RET
331
332 // int32 lwp_create(void *context, uintptr flags, void *lwpid);
333 TEXT runtime·lwp_create(SB),NOSPLIT,$16
334 MOVL $0, 0(SP)
335 MOVL ctxt+0(FP), AX
336 MOVL AX, 4(SP) // arg 1 - context
337 MOVL flags+4(FP), AX
338 MOVL AX, 8(SP) // arg 2 - flags
339 MOVL lwpid+8(FP), AX
340 MOVL AX, 12(SP) // arg 3 - lwpid
341 MOVL $SYS__lwp_create, AX
342 INT $0x80
343 JCC 2(PC)
344 NEGL AX
345 MOVL AX, ret+12(FP)
346 RET
347
348 TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
349
350 // Set FS to point at m->tls
351 LEAL m_tls(BX), BP
352 PUSHAL // save registers
353 PUSHL BP
354 CALL lwp_setprivate<>(SB)
355 POPL AX
356 POPAL
357
358 // Now segment is established. Initialize m, g.
359 get_tls(AX)
360 MOVL DX, g(AX)
361 MOVL BX, g_m(DX)
362
363 CALL runtime·stackcheck(SB) // smashes AX, CX
364 MOVL 0(DX), DX // paranoia; check they are not nil
365 MOVL 0(BX), BX
366
367 // more paranoia; check that stack splitting code works
368 PUSHAL
369 CALL runtime·emptyfunc(SB)
370 POPAL
371
372 // Call fn
373 CALL SI
374
375 // fn should never return
376 MOVL $0x1234, 0x1005
377 RET
378
379 TEXT ·netbsdMstart(SB),NOSPLIT|TOPFRAME,$0
380 CALL ·netbsdMstart0(SB)
381 RET // not reached
382
383 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
384 MOVL $SYS___sigaltstack14, AX
385 MOVL new+0(FP), BX
386 MOVL old+4(FP), CX
387 INT $0x80
388 CMPL AX, $0xfffff001
389 JLS 2(PC)
390 INT $3
391 RET
392
393 TEXT runtime·setldt(SB),NOSPLIT,$8
394 // Under NetBSD we set the GS base instead of messing with the LDT.
395 MOVL base+4(FP), AX
396 MOVL AX, 0(SP)
397 CALL lwp_setprivate<>(SB)
398 RET
399
400 TEXT lwp_setprivate<>(SB),NOSPLIT,$16
401 // adjust for ELF: wants to use -4(GS) for g
402 MOVL base+0(FP), CX
403 ADDL $4, CX
404 MOVL $0, 0(SP) // syscall gap
405 MOVL CX, 4(SP) // arg 1 - ptr
406 MOVL $SYS__lwp_setprivate, AX
407 INT $0x80
408 JCC 2(PC)
409 MOVL $0xf1, 0xf1 // crash
410 RET
411
412 TEXT runtime·osyield(SB),NOSPLIT,$-4
413 MOVL $SYS_sched_yield, AX
414 INT $0x80
415 RET
416
417 TEXT runtime·lwp_park(SB),NOSPLIT,$-4
418 MOVL $SYS____lwp_park60, AX
419 INT $0x80
420 MOVL AX, ret+24(FP)
421 RET
422
423 TEXT runtime·lwp_unpark(SB),NOSPLIT,$-4
424 MOVL $SYS__lwp_unpark, AX
425 INT $0x80
426 MOVL AX, ret+8(FP)
427 RET
428
429 TEXT runtime·lwp_self(SB),NOSPLIT,$-4
430 MOVL $SYS__lwp_self, AX
431 INT $0x80
432 MOVL AX, ret+0(FP)
433 RET
434
435 TEXT runtime·sysctl(SB),NOSPLIT,$28
436 LEAL mib+0(FP), SI
437 LEAL 4(SP), DI
438 CLD
439 MOVSL // arg 1 - name
440 MOVSL // arg 2 - namelen
441 MOVSL // arg 3 - oldp
442 MOVSL // arg 4 - oldlenp
443 MOVSL // arg 5 - newp
444 MOVSL // arg 6 - newlen
445 MOVL $SYS___sysctl, AX
446 INT $0x80
447 JAE 4(PC)
448 NEGL AX
449 MOVL AX, ret+24(FP)
450 RET
451 MOVL $0, AX
452 MOVL AX, ret+24(FP)
453 RET
454
455 GLOBL runtime·tlsoffset(SB),NOPTR,$4
456
457 // int32 runtime·kqueue(void)
458 TEXT runtime·kqueue(SB),NOSPLIT,$0
459 MOVL $SYS_kqueue, AX
460 INT $0x80
461 JAE 2(PC)
462 NEGL AX
463 MOVL AX, ret+0(FP)
464 RET
465
466 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
467 TEXT runtime·kevent(SB),NOSPLIT,$0
468 MOVL $SYS___kevent50, AX
469 INT $0x80
470 JAE 2(PC)
471 NEGL AX
472 MOVL AX, ret+24(FP)
473 RET
474
475 // int32 runtime·closeonexec(int32 fd)
476 TEXT runtime·closeonexec(SB),NOSPLIT,$32
477 MOVL $SYS_fcntl, AX
478 // 0(SP) is where the caller PC would be; kernel skips it
479 MOVL fd+0(FP), BX
480 MOVL BX, 4(SP) // fd
481 MOVL $F_SETFD, 8(SP)
482 MOVL $FD_CLOEXEC, 12(SP)
483 INT $0x80
484 JAE 2(PC)
485 NEGL AX
486 RET
487
488 // func runtime·setNonblock(fd int32)
489 TEXT runtime·setNonblock(SB),NOSPLIT,$16-4
490 MOVL $92, AX // fcntl
491 MOVL fd+0(FP), BX // fd
492 MOVL BX, 4(SP)
493 MOVL $3, 8(SP) // F_GETFL
494 MOVL $0, 12(SP)
495 INT $0x80
496 MOVL fd+0(FP), BX // fd
497 MOVL BX, 4(SP)
498 MOVL $4, 8(SP) // F_SETFL
499 ORL $4, AX // O_NONBLOCK
500 MOVL AX, 12(SP)
501 MOVL $92, AX // fcntl
502 INT $0x80
503 RET
504
View as plain text