github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/src/runtime/sys_openbsd_386.s (about) 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, OpenBSD 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_MONOTONIC $3 14 15 // Exit the entire program (like C exit) 16 TEXT runtime·exit(SB),NOSPLIT,$-4 17 MOVL $1, AX 18 INT $0x80 19 MOVL $0xf1, 0xf1 // crash 20 RET 21 22 TEXT runtime·exit1(SB),NOSPLIT,$8 23 MOVL $0, 0(SP) 24 MOVL $0, 4(SP) // arg 1 - notdead 25 MOVL $302, AX // sys___threxit 26 INT $0x80 27 JAE 2(PC) 28 MOVL $0xf1, 0xf1 // crash 29 RET 30 31 TEXT runtime·open(SB),NOSPLIT,$-4 32 MOVL $5, AX 33 INT $0x80 34 MOVL AX, ret+12(FP) 35 RET 36 37 TEXT runtime·close(SB),NOSPLIT,$-4 38 MOVL $6, AX 39 INT $0x80 40 MOVL AX, ret+4(FP) 41 RET 42 43 TEXT runtime·read(SB),NOSPLIT,$-4 44 MOVL $3, AX 45 INT $0x80 46 MOVL AX, ret+12(FP) 47 RET 48 49 TEXT runtime·write(SB),NOSPLIT,$-4 50 MOVL $4, AX // sys_write 51 INT $0x80 52 MOVL AX, ret+12(FP) 53 RET 54 55 TEXT runtime·usleep(SB),NOSPLIT,$24 56 MOVL $0, DX 57 MOVL usec+0(FP), AX 58 MOVL $1000000, CX 59 DIVL CX 60 MOVL AX, 12(SP) // tv_sec - l32 61 MOVL $0, 16(SP) // tv_sec - h32 62 MOVL $1000, AX 63 MULL DX 64 MOVL AX, 20(SP) // tv_nsec 65 66 MOVL $0, 0(SP) 67 LEAL 12(SP), AX 68 MOVL AX, 4(SP) // arg 1 - rqtp 69 MOVL $0, 8(SP) // arg 2 - rmtp 70 MOVL $91, AX // sys_nanosleep 71 INT $0x80 72 RET 73 74 TEXT runtime·raise(SB),NOSPLIT,$12 75 MOVL $299, AX // sys_getthrid 76 INT $0x80 77 MOVL $0, 0(SP) 78 MOVL AX, 4(SP) // arg 1 - pid 79 MOVL sig+0(FP), AX 80 MOVL AX, 8(SP) // arg 2 - signum 81 MOVL $37, AX // sys_kill 82 INT $0x80 83 RET 84 85 TEXT runtime·mmap(SB),NOSPLIT,$36 86 LEAL addr+0(FP), SI 87 LEAL 4(SP), DI 88 CLD 89 MOVSL // arg 1 - addr 90 MOVSL // arg 2 - len 91 MOVSL // arg 3 - prot 92 MOVSL // arg 4 - flags 93 MOVSL // arg 5 - fd 94 MOVL $0, AX 95 STOSL // arg 6 - pad 96 MOVSL // arg 7 - offset 97 MOVL $0, AX // top 32 bits of file offset 98 STOSL 99 MOVL $197, AX // sys_mmap 100 INT $0x80 101 MOVL AX, ret+24(FP) 102 RET 103 104 TEXT runtime·munmap(SB),NOSPLIT,$-4 105 MOVL $73, AX // sys_munmap 106 INT $0x80 107 JAE 2(PC) 108 MOVL $0xf1, 0xf1 // crash 109 RET 110 111 TEXT runtime·madvise(SB),NOSPLIT,$-4 112 MOVL $75, AX // sys_madvise 113 INT $0x80 114 JAE 2(PC) 115 MOVL $0xf1, 0xf1 // crash 116 RET 117 118 TEXT runtime·setitimer(SB),NOSPLIT,$-4 119 MOVL $69, AX 120 INT $0x80 121 RET 122 123 // func now() (sec int64, nsec int32) 124 TEXT time·now(SB), NOSPLIT, $32 125 LEAL 12(SP), BX 126 MOVL $0, 4(SP) // arg 1 - clock_id 127 MOVL BX, 8(SP) // arg 2 - tp 128 MOVL $87, AX // sys_clock_gettime 129 INT $0x80 130 131 MOVL 12(SP), AX // sec - l32 132 MOVL AX, sec+0(FP) 133 MOVL 16(SP), AX // sec - h32 134 MOVL AX, sec+4(FP) 135 136 MOVL 20(SP), BX // nsec 137 MOVL BX, nsec+8(FP) 138 RET 139 140 // int64 nanotime(void) so really 141 // void nanotime(int64 *nsec) 142 TEXT runtime·nanotime(SB),NOSPLIT,$32 143 LEAL 12(SP), BX 144 MOVL CLOCK_MONOTONIC, 4(SP) // arg 1 - clock_id 145 MOVL BX, 8(SP) // arg 2 - tp 146 MOVL $87, AX // sys_clock_gettime 147 INT $0x80 148 149 MOVL 16(SP), CX // sec - h32 150 IMULL $1000000000, CX 151 152 MOVL 12(SP), AX // sec - l32 153 MOVL $1000000000, BX 154 MULL BX // result in dx:ax 155 156 MOVL 20(SP), BX // nsec 157 ADDL BX, AX 158 ADCL CX, DX // add high bits with carry 159 160 MOVL AX, ret_lo+0(FP) 161 MOVL DX, ret_hi+4(FP) 162 RET 163 164 TEXT runtime·sigaction(SB),NOSPLIT,$-4 165 MOVL $46, AX // sys_sigaction 166 INT $0x80 167 JAE 2(PC) 168 MOVL $0xf1, 0xf1 // crash 169 RET 170 171 TEXT runtime·sigprocmask(SB),NOSPLIT,$-4 172 MOVL $48, AX // sys_sigprocmask 173 INT $0x80 174 JAE 2(PC) 175 MOVL $0xf1, 0xf1 // crash 176 MOVL AX, ret+8(FP) 177 RET 178 179 TEXT runtime·sigtramp(SB),NOSPLIT,$44 180 get_tls(CX) 181 182 // check that g exists 183 MOVL g(CX), DI 184 CMPL DI, $0 185 JNE 6(PC) 186 MOVL signo+0(FP), BX 187 MOVL BX, 0(SP) 188 MOVL $runtime·badsignal(SB), AX 189 CALL AX 190 JMP ret 191 192 // save g 193 MOVL DI, 20(SP) 194 195 // g = m->gsignal 196 MOVL g_m(DI), BX 197 MOVL m_gsignal(BX), BX 198 MOVL BX, g(CX) 199 200 // copy arguments for call to sighandler 201 MOVL signo+0(FP), BX 202 MOVL BX, 0(SP) 203 MOVL info+4(FP), BX 204 MOVL BX, 4(SP) 205 MOVL context+8(FP), BX 206 MOVL BX, 8(SP) 207 MOVL DI, 12(SP) 208 209 CALL runtime·sighandler(SB) 210 211 // restore g 212 get_tls(CX) 213 MOVL 20(SP), BX 214 MOVL BX, g(CX) 215 216 ret: 217 // call sigreturn 218 MOVL context+8(FP), AX 219 MOVL $0, 0(SP) // syscall gap 220 MOVL AX, 4(SP) // arg 1 - sigcontext 221 MOVL $103, AX // sys_sigreturn 222 INT $0x80 223 MOVL $0xf1, 0xf1 // crash 224 RET 225 226 // int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void)); 227 TEXT runtime·tfork(SB),NOSPLIT,$12 228 229 // Copy mp, gp and fn from the parent stack onto the child stack. 230 MOVL param+0(FP), AX 231 MOVL 8(AX), CX // tf_stack 232 SUBL $16, CX 233 MOVL CX, 8(AX) 234 MOVL mm+8(FP), SI 235 MOVL SI, 0(CX) 236 MOVL gg+12(FP), SI 237 MOVL SI, 4(CX) 238 MOVL fn+16(FP), SI 239 MOVL SI, 8(CX) 240 MOVL $1234, 12(CX) 241 242 MOVL $0, 0(SP) // syscall gap 243 MOVL param+0(FP), AX 244 MOVL AX, 4(SP) // arg 1 - param 245 MOVL psize+4(FP), AX 246 MOVL AX, 8(SP) // arg 2 - psize 247 MOVL $8, AX // sys___tfork 248 INT $0x80 249 250 // Return if tfork syscall failed. 251 JCC 4(PC) 252 NEGL AX 253 MOVL AX, ret+20(FP) 254 RET 255 256 // In parent, return. 257 CMPL AX, $0 258 JEQ 3(PC) 259 MOVL AX, ret+20(FP) 260 RET 261 262 // Paranoia: check that SP is as we expect. 263 MOVL 12(SP), BP 264 CMPL BP, $1234 265 JEQ 2(PC) 266 INT $3 267 268 // Reload registers. 269 MOVL 0(SP), BX // m 270 MOVL 4(SP), DX // g 271 MOVL 8(SP), SI // fn 272 273 // Set FS to point at m->tls. 274 LEAL m_tls(BX), BP 275 PUSHAL // save registers 276 PUSHL BP 277 CALL runtime·settls(SB) 278 POPL AX 279 POPAL 280 281 // Now segment is established. Initialize m, g. 282 get_tls(AX) 283 MOVL DX, g(AX) 284 MOVL BX, g_m(DX) 285 286 CALL runtime·stackcheck(SB) // smashes AX, CX 287 MOVL 0(DX), DX // paranoia; check they are not nil 288 MOVL 0(BX), BX 289 290 // More paranoia; check that stack splitting code works. 291 PUSHAL 292 CALL runtime·emptyfunc(SB) 293 POPAL 294 295 // Call fn. 296 CALL SI 297 298 CALL runtime·exit1(SB) 299 MOVL $0x1234, 0x1005 300 RET 301 302 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 303 MOVL $288, AX // sys_sigaltstack 304 MOVL new+4(SP), BX 305 MOVL old+8(SP), CX 306 INT $0x80 307 CMPL AX, $0xfffff001 308 JLS 2(PC) 309 INT $3 310 RET 311 312 TEXT runtime·setldt(SB),NOSPLIT,$4 313 // Under OpenBSD we set the GS base instead of messing with the LDT. 314 MOVL tls0+4(FP), AX 315 MOVL AX, 0(SP) 316 CALL runtime·settls(SB) 317 RET 318 319 TEXT runtime·settls(SB),NOSPLIT,$8 320 // adjust for ELF: wants to use -8(GS) and -4(GS) for g and m 321 MOVL tlsbase+0(FP), CX 322 ADDL $8, CX 323 MOVL $0, 0(SP) // syscall gap 324 MOVL CX, 4(SP) // arg 1 - tcb 325 MOVL $329, AX // sys___set_tcb 326 INT $0x80 327 JCC 2(PC) 328 MOVL $0xf1, 0xf1 // crash 329 RET 330 331 TEXT runtime·osyield(SB),NOSPLIT,$-4 332 MOVL $298, AX // sys_sched_yield 333 INT $0x80 334 RET 335 336 TEXT runtime·thrsleep(SB),NOSPLIT,$-4 337 MOVL $94, AX // sys___thrsleep 338 INT $0x80 339 MOVL AX, ret+20(FP) 340 RET 341 342 TEXT runtime·thrwakeup(SB),NOSPLIT,$-4 343 MOVL $301, AX // sys___thrwakeup 344 INT $0x80 345 MOVL AX, ret+8(FP) 346 RET 347 348 TEXT runtime·sysctl(SB),NOSPLIT,$28 349 LEAL mib+0(FP), SI 350 LEAL 4(SP), DI 351 CLD 352 MOVSL // arg 1 - name 353 MOVSL // arg 2 - namelen 354 MOVSL // arg 3 - oldp 355 MOVSL // arg 4 - oldlenp 356 MOVSL // arg 5 - newp 357 MOVSL // arg 6 - newlen 358 MOVL $202, AX // sys___sysctl 359 INT $0x80 360 JCC 4(PC) 361 NEGL AX 362 MOVL AX, ret+24(FP) 363 RET 364 MOVL $0, AX 365 MOVL AX, ret+24(FP) 366 RET 367 368 // int32 runtime·kqueue(void); 369 TEXT runtime·kqueue(SB),NOSPLIT,$0 370 MOVL $269, AX 371 INT $0x80 372 JAE 2(PC) 373 NEGL AX 374 MOVL AX, ret+0(FP) 375 RET 376 377 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 378 TEXT runtime·kevent(SB),NOSPLIT,$0 379 MOVL $72, AX // sys_kevent 380 INT $0x80 381 JAE 2(PC) 382 NEGL AX 383 MOVL AX, ret+24(FP) 384 RET 385 386 // int32 runtime·closeonexec(int32 fd); 387 TEXT runtime·closeonexec(SB),NOSPLIT,$32 388 MOVL $92, AX // sys_fcntl 389 // 0(SP) is where the caller PC would be; kernel skips it 390 MOVL fd+0(FP), BX 391 MOVL BX, 4(SP) // fd 392 MOVL $2, 8(SP) // F_SETFD 393 MOVL $1, 12(SP) // FD_CLOEXEC 394 INT $0x80 395 JAE 2(PC) 396 NEGL AX 397 RET 398 399 GLOBL runtime·tlsoffset(SB),NOPTR,$4