github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/src/runtime/sys_solaris_amd64.s (about) 1 // Copyright 2014 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 AMD64, SunOS 6 // /usr/include/sys/syscall.h for syscall numbers. 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 // This is needed by asm_amd64.s 14 TEXT runtime·settls(SB),NOSPLIT,$8 15 RET 16 17 // void libc_miniterrno(void *(*___errno)(void)); 18 // 19 // Set the TLS errno pointer in M. 20 // 21 // Called using runtime·asmcgocall from os_solaris.c:/minit. 22 // NOT USING GO CALLING CONVENTION. 23 TEXT runtime·miniterrno(SB),NOSPLIT,$0 24 // asmcgocall will put first argument into DI. 25 CALL DI // SysV ABI so returns in AX 26 get_tls(CX) 27 MOVQ g(CX), BX 28 MOVQ g_m(BX), BX 29 MOVQ AX, (m_mOS+mOS_perrno)(BX) 30 RET 31 32 // int64 runtime·nanotime1(void); 33 // 34 // clock_gettime(3c) wrapper because Timespec is too large for 35 // runtime·nanotime stack. 36 // 37 // Called using runtime·sysvicall6 from os_solaris.c:/nanotime. 38 // NOT USING GO CALLING CONVENTION. 39 TEXT runtime·nanotime1(SB),NOSPLIT,$0 40 // need space for the timespec argument. 41 SUBQ $64, SP // 16 bytes will do, but who knows in the future? 42 MOVQ $3, DI // CLOCK_REALTIME from <sys/time_impl.h> 43 MOVQ SP, SI 44 LEAQ libc_clock_gettime(SB), AX 45 CALL AX 46 MOVQ (SP), AX // tv_sec from struct timespec 47 IMULQ $1000000000, AX // multiply into nanoseconds 48 ADDQ 8(SP), AX // tv_nsec, offset should be stable. 49 ADDQ $64, SP 50 RET 51 52 // pipe(3c) wrapper that returns fds in AX, DX. 53 // NOT USING GO CALLING CONVENTION. 54 TEXT runtime·pipe1(SB),NOSPLIT,$0 55 SUBQ $16, SP // 8 bytes will do, but stack has to be 16-byte alligned 56 MOVQ SP, DI 57 LEAQ libc_pipe(SB), AX 58 CALL AX 59 MOVL 0(SP), AX 60 MOVL 4(SP), DX 61 ADDQ $16, SP 62 RET 63 64 // Call a library function with SysV calling conventions. 65 // The called function can take a maximum of 6 INTEGER class arguments, 66 // see 67 // Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell 68 // System V Application Binary Interface 69 // AMD64 Architecture Processor Supplement 70 // section 3.2.3. 71 // 72 // Called by runtime·asmcgocall or runtime·cgocall. 73 // NOT USING GO CALLING CONVENTION. 74 TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0 75 // asmcgocall will put first argument into DI. 76 PUSHQ DI // save for later 77 MOVQ libcall_fn(DI), AX 78 MOVQ libcall_args(DI), R11 79 MOVQ libcall_n(DI), R10 80 81 get_tls(CX) 82 MOVQ g(CX), BX 83 CMPQ BX, $0 84 JEQ skiperrno1 85 MOVQ g_m(BX), BX 86 MOVQ (m_mOS+mOS_perrno)(BX), DX 87 CMPQ DX, $0 88 JEQ skiperrno1 89 MOVL $0, 0(DX) 90 91 skiperrno1: 92 CMPQ R11, $0 93 JEQ skipargs 94 // Load 6 args into correspondent registers. 95 MOVQ 0(R11), DI 96 MOVQ 8(R11), SI 97 MOVQ 16(R11), DX 98 MOVQ 24(R11), CX 99 MOVQ 32(R11), R8 100 MOVQ 40(R11), R9 101 skipargs: 102 103 // Call SysV function 104 CALL AX 105 106 // Return result 107 POPQ DI 108 MOVQ AX, libcall_r1(DI) 109 MOVQ DX, libcall_r2(DI) 110 111 get_tls(CX) 112 MOVQ g(CX), BX 113 CMPQ BX, $0 114 JEQ skiperrno2 115 MOVQ g_m(BX), BX 116 MOVQ (m_mOS+mOS_perrno)(BX), AX 117 CMPQ AX, $0 118 JEQ skiperrno2 119 MOVL 0(AX), AX 120 MOVQ AX, libcall_err(DI) 121 122 skiperrno2: 123 RET 124 125 // uint32 tstart_sysvicall(M *newm); 126 TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0 127 // DI contains first arg newm 128 MOVQ m_g0(DI), DX // g 129 130 // Make TLS entries point at g and m. 131 get_tls(BX) 132 MOVQ DX, g(BX) 133 MOVQ DI, g_m(DX) 134 135 // Layout new m scheduler stack on os stack. 136 MOVQ SP, AX 137 MOVQ AX, (g_stack+stack_hi)(DX) 138 SUBQ $(0x100000), AX // stack size 139 MOVQ AX, (g_stack+stack_lo)(DX) 140 ADDQ $const__StackGuard, AX 141 MOVQ AX, g_stackguard0(DX) 142 MOVQ AX, g_stackguard1(DX) 143 144 // Someday the convention will be D is always cleared. 145 CLD 146 147 CALL runtime·stackcheck(SB) // clobbers AX,CX 148 CALL runtime·mstart(SB) 149 150 XORL AX, AX // return 0 == success 151 MOVL AX, ret+8(FP) 152 RET 153 154 // Careful, this is called by __sighndlr, a libc function. We must preserve 155 // registers as per AMD 64 ABI. 156 TEXT runtime·sigtramp(SB),NOSPLIT,$0 157 // Note that we are executing on altsigstack here, so we have 158 // more stack available than NOSPLIT would have us believe. 159 // To defeat the linker, we make our own stack frame with 160 // more space: 161 SUBQ $184, SP 162 163 // save registers 164 MOVQ BX, 32(SP) 165 MOVQ BP, 40(SP) 166 MOVQ R12, 48(SP) 167 MOVQ R13, 56(SP) 168 MOVQ R14, 64(SP) 169 MOVQ R15, 72(SP) 170 171 get_tls(BX) 172 // check that g exists 173 MOVQ g(BX), R10 174 CMPQ R10, $0 175 JNE allgood 176 MOVQ DI, 0(SP) 177 MOVQ $runtime·badsignal(SB), AX 178 CALL AX 179 JMP exit 180 181 allgood: 182 // save g 183 MOVQ R10, 80(SP) 184 185 // Save m->libcall and m->scratch. We need to do this because we 186 // might get interrupted by a signal in runtime·asmcgocall. 187 188 // save m->libcall 189 MOVQ g_m(R10), BP 190 LEAQ m_libcall(BP), R11 191 MOVQ libcall_fn(R11), R10 192 MOVQ R10, 88(SP) 193 MOVQ libcall_args(R11), R10 194 MOVQ R10, 96(SP) 195 MOVQ libcall_n(R11), R10 196 MOVQ R10, 104(SP) 197 MOVQ libcall_r1(R11), R10 198 MOVQ R10, 168(SP) 199 MOVQ libcall_r2(R11), R10 200 MOVQ R10, 176(SP) 201 202 // save m->scratch 203 LEAQ (m_mOS+mOS_scratch)(BP), R11 204 MOVQ 0(R11), R10 205 MOVQ R10, 112(SP) 206 MOVQ 8(R11), R10 207 MOVQ R10, 120(SP) 208 MOVQ 16(R11), R10 209 MOVQ R10, 128(SP) 210 MOVQ 24(R11), R10 211 MOVQ R10, 136(SP) 212 MOVQ 32(R11), R10 213 MOVQ R10, 144(SP) 214 MOVQ 40(R11), R10 215 MOVQ R10, 152(SP) 216 217 // save errno, it might be EINTR; stuff we do here might reset it. 218 MOVQ (m_mOS+mOS_perrno)(BP), R10 219 MOVL 0(R10), R10 220 MOVQ R10, 160(SP) 221 222 MOVQ g(BX), R10 223 // g = m->gsignal 224 MOVQ m_gsignal(BP), BP 225 MOVQ BP, g(BX) 226 227 // prepare call 228 MOVQ DI, 0(SP) 229 MOVQ SI, 8(SP) 230 MOVQ DX, 16(SP) 231 MOVQ R10, 24(SP) 232 CALL runtime·sighandler(SB) 233 234 get_tls(BX) 235 MOVQ g(BX), BP 236 MOVQ g_m(BP), BP 237 // restore libcall 238 LEAQ m_libcall(BP), R11 239 MOVQ 88(SP), R10 240 MOVQ R10, libcall_fn(R11) 241 MOVQ 96(SP), R10 242 MOVQ R10, libcall_args(R11) 243 MOVQ 104(SP), R10 244 MOVQ R10, libcall_n(R11) 245 MOVQ 168(SP), R10 246 MOVQ R10, libcall_r1(R11) 247 MOVQ 176(SP), R10 248 MOVQ R10, libcall_r2(R11) 249 250 // restore scratch 251 LEAQ (m_mOS+mOS_scratch)(BP), R11 252 MOVQ 112(SP), R10 253 MOVQ R10, 0(R11) 254 MOVQ 120(SP), R10 255 MOVQ R10, 8(R11) 256 MOVQ 128(SP), R10 257 MOVQ R10, 16(R11) 258 MOVQ 136(SP), R10 259 MOVQ R10, 24(R11) 260 MOVQ 144(SP), R10 261 MOVQ R10, 32(R11) 262 MOVQ 152(SP), R10 263 MOVQ R10, 40(R11) 264 265 // restore errno 266 MOVQ (m_mOS+mOS_perrno)(BP), R11 267 MOVQ 160(SP), R10 268 MOVL R10, 0(R11) 269 270 // restore g 271 MOVQ 80(SP), R10 272 MOVQ R10, g(BX) 273 274 exit: 275 // restore registers 276 MOVQ 32(SP), BX 277 MOVQ 40(SP), BP 278 MOVQ 48(SP), R12 279 MOVQ 56(SP), R13 280 MOVQ 64(SP), R14 281 MOVQ 72(SP), R15 282 283 ADDQ $184, SP 284 RET 285 286 // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack, 287 // can also be called in cgo callback path without a g->m. 288 TEXT runtime·usleep1(SB),NOSPLIT,$0 289 MOVL usec+0(FP), DI 290 MOVQ $runtime·usleep2(SB), AX // to hide from 6l 291 292 // Execute call on m->g0. 293 get_tls(R15) 294 CMPQ R15, $0 295 JE noswitch 296 297 MOVQ g(R15), R13 298 CMPQ R13, $0 299 JE noswitch 300 MOVQ g_m(R13), R13 301 CMPQ R13, $0 302 JE noswitch 303 // TODO(aram): do something about the cpu profiler here. 304 305 MOVQ m_g0(R13), R14 306 CMPQ g(R15), R14 307 JNE switch 308 // executing on m->g0 already 309 CALL AX 310 RET 311 312 switch: 313 // Switch to m->g0 stack and back. 314 MOVQ (g_sched+gobuf_sp)(R14), R14 315 MOVQ SP, -8(R14) 316 LEAQ -8(R14), SP 317 CALL AX 318 MOVQ 0(SP), SP 319 RET 320 321 noswitch: 322 // Not a Go-managed thread. Do not switch stack. 323 CALL AX 324 RET 325 326 // Runs on OS stack. duration (in µs units) is in DI. 327 TEXT runtime·usleep2(SB),NOSPLIT,$0 328 LEAQ libc_usleep(SB), AX 329 CALL AX 330 RET 331 332 // Runs on OS stack, called from runtime·osyield. 333 TEXT runtime·osyield1(SB),NOSPLIT,$0 334 LEAQ libc_sched_yield(SB), AX 335 CALL AX 336 RET 337 338 // func now() (sec int64, nsec int32) 339 TEXT time·now(SB),NOSPLIT,$8-12 340 CALL runtime·nanotime(SB) 341 MOVQ 0(SP), AX 342 343 // generated code for 344 // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 } 345 // adapted to reduce duplication 346 MOVQ AX, CX 347 MOVQ $1360296554856532783, AX 348 MULQ CX 349 ADDQ CX, DX 350 RCRQ $1, DX 351 SHRQ $29, DX 352 MOVQ DX, sec+0(FP) 353 IMULQ $1000000000, DX 354 SUBQ DX, CX 355 MOVL CX, nsec+8(FP) 356 RET