github.com/stingnevermore/go@v0.0.0-20180120041312-3810f5bfed72/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 aligned 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 SI, 80(SP) 177 MOVQ DX, 88(SP) 178 LEAQ 80(SP), AX 179 MOVQ DI, 0(SP) 180 MOVQ AX, 8(SP) 181 MOVQ $runtime·badsignal(SB), AX 182 CALL AX 183 JMP exit 184 185 allgood: 186 // Save m->libcall and m->scratch. We need to do this because we 187 // might get interrupted by a signal in runtime·asmcgocall. 188 189 // save m->libcall 190 MOVQ g_m(R10), BP 191 LEAQ m_libcall(BP), R11 192 MOVQ libcall_fn(R11), R10 193 MOVQ R10, 88(SP) 194 MOVQ libcall_args(R11), R10 195 MOVQ R10, 96(SP) 196 MOVQ libcall_n(R11), R10 197 MOVQ R10, 104(SP) 198 MOVQ libcall_r1(R11), R10 199 MOVQ R10, 168(SP) 200 MOVQ libcall_r2(R11), R10 201 MOVQ R10, 176(SP) 202 203 // save m->scratch 204 LEAQ (m_mOS+mOS_scratch)(BP), R11 205 MOVQ 0(R11), R10 206 MOVQ R10, 112(SP) 207 MOVQ 8(R11), R10 208 MOVQ R10, 120(SP) 209 MOVQ 16(R11), R10 210 MOVQ R10, 128(SP) 211 MOVQ 24(R11), R10 212 MOVQ R10, 136(SP) 213 MOVQ 32(R11), R10 214 MOVQ R10, 144(SP) 215 MOVQ 40(R11), R10 216 MOVQ R10, 152(SP) 217 218 // save errno, it might be EINTR; stuff we do here might reset it. 219 MOVQ (m_mOS+mOS_perrno)(BP), R10 220 MOVL 0(R10), R10 221 MOVQ R10, 160(SP) 222 223 // prepare call 224 MOVQ DI, 0(SP) 225 MOVQ SI, 8(SP) 226 MOVQ DX, 16(SP) 227 CALL runtime·sigtrampgo(SB) 228 229 get_tls(BX) 230 MOVQ g(BX), BP 231 MOVQ g_m(BP), BP 232 // restore libcall 233 LEAQ m_libcall(BP), R11 234 MOVQ 88(SP), R10 235 MOVQ R10, libcall_fn(R11) 236 MOVQ 96(SP), R10 237 MOVQ R10, libcall_args(R11) 238 MOVQ 104(SP), R10 239 MOVQ R10, libcall_n(R11) 240 MOVQ 168(SP), R10 241 MOVQ R10, libcall_r1(R11) 242 MOVQ 176(SP), R10 243 MOVQ R10, libcall_r2(R11) 244 245 // restore scratch 246 LEAQ (m_mOS+mOS_scratch)(BP), R11 247 MOVQ 112(SP), R10 248 MOVQ R10, 0(R11) 249 MOVQ 120(SP), R10 250 MOVQ R10, 8(R11) 251 MOVQ 128(SP), R10 252 MOVQ R10, 16(R11) 253 MOVQ 136(SP), R10 254 MOVQ R10, 24(R11) 255 MOVQ 144(SP), R10 256 MOVQ R10, 32(R11) 257 MOVQ 152(SP), R10 258 MOVQ R10, 40(R11) 259 260 // restore errno 261 MOVQ (m_mOS+mOS_perrno)(BP), R11 262 MOVQ 160(SP), R10 263 MOVL R10, 0(R11) 264 265 exit: 266 // restore registers 267 MOVQ 32(SP), BX 268 MOVQ 40(SP), BP 269 MOVQ 48(SP), R12 270 MOVQ 56(SP), R13 271 MOVQ 64(SP), R14 272 MOVQ 72(SP), R15 273 274 ADDQ $184, SP 275 RET 276 277 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 278 MOVQ fn+0(FP), AX 279 MOVL sig+8(FP), DI 280 MOVQ info+16(FP), SI 281 MOVQ ctx+24(FP), DX 282 PUSHQ BP 283 MOVQ SP, BP 284 ANDQ $~15, SP // alignment for x86_64 ABI 285 CALL AX 286 MOVQ BP, SP 287 POPQ BP 288 RET 289 290 // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack, 291 // can also be called in cgo callback path without a g->m. 292 TEXT runtime·usleep1(SB),NOSPLIT,$0 293 MOVL usec+0(FP), DI 294 MOVQ $runtime·usleep2(SB), AX // to hide from 6l 295 296 // Execute call on m->g0. 297 get_tls(R15) 298 CMPQ R15, $0 299 JE noswitch 300 301 MOVQ g(R15), R13 302 CMPQ R13, $0 303 JE noswitch 304 MOVQ g_m(R13), R13 305 CMPQ R13, $0 306 JE noswitch 307 // TODO(aram): do something about the cpu profiler here. 308 309 MOVQ m_g0(R13), R14 310 CMPQ g(R15), R14 311 JNE switch 312 // executing on m->g0 already 313 CALL AX 314 RET 315 316 switch: 317 // Switch to m->g0 stack and back. 318 MOVQ (g_sched+gobuf_sp)(R14), R14 319 MOVQ SP, -8(R14) 320 LEAQ -8(R14), SP 321 CALL AX 322 MOVQ 0(SP), SP 323 RET 324 325 noswitch: 326 // Not a Go-managed thread. Do not switch stack. 327 CALL AX 328 RET 329 330 // Runs on OS stack. duration (in µs units) is in DI. 331 TEXT runtime·usleep2(SB),NOSPLIT,$0 332 LEAQ libc_usleep(SB), AX 333 CALL AX 334 RET 335 336 // Runs on OS stack, called from runtime·osyield. 337 TEXT runtime·osyield1(SB),NOSPLIT,$0 338 LEAQ libc_sched_yield(SB), AX 339 CALL AX 340 RET 341 342 // func walltime() (sec int64, nsec int32) 343 TEXT runtime·walltime(SB),NOSPLIT,$8-12 344 CALL runtime·nanotime(SB) 345 MOVQ 0(SP), AX 346 347 // generated code for 348 // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 } 349 // adapted to reduce duplication 350 MOVQ AX, CX 351 MOVQ $1360296554856532783, AX 352 MULQ CX 353 ADDQ CX, DX 354 RCRQ $1, DX 355 SHRQ $29, DX 356 MOVQ DX, sec+0(FP) 357 IMULQ $1000000000, DX 358 SUBQ DX, CX 359 MOVL CX, nsec+8(FP) 360 RET