github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 // Call a library function with SysV calling conventions. 33 // The called function can take a maximum of 6 INTEGER class arguments, 34 // see 35 // Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell 36 // System V Application Binary Interface 37 // AMD64 Architecture Processor Supplement 38 // section 3.2.3. 39 // 40 // Called by runtime·asmcgocall or runtime·cgocall. 41 // NOT USING GO CALLING CONVENTION. 42 TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0 43 // asmcgocall will put first argument into DI. 44 PUSHQ DI // save for later 45 MOVQ libcall_fn(DI), AX 46 MOVQ libcall_args(DI), R11 47 MOVQ libcall_n(DI), R10 48 49 get_tls(CX) 50 MOVQ g(CX), BX 51 CMPQ BX, $0 52 JEQ skiperrno1 53 MOVQ g_m(BX), BX 54 MOVQ (m_mOS+mOS_perrno)(BX), DX 55 CMPQ DX, $0 56 JEQ skiperrno1 57 MOVL $0, 0(DX) 58 59 skiperrno1: 60 CMPQ R11, $0 61 JEQ skipargs 62 // Load 6 args into correspondent registers. 63 MOVQ 0(R11), DI 64 MOVQ 8(R11), SI 65 MOVQ 16(R11), DX 66 MOVQ 24(R11), CX 67 MOVQ 32(R11), R8 68 MOVQ 40(R11), R9 69 skipargs: 70 71 // Call SysV function 72 CALL AX 73 74 // Return result 75 POPQ DI 76 MOVQ AX, libcall_r1(DI) 77 MOVQ DX, libcall_r2(DI) 78 79 get_tls(CX) 80 MOVQ g(CX), BX 81 CMPQ BX, $0 82 JEQ skiperrno2 83 MOVQ g_m(BX), BX 84 MOVQ (m_mOS+mOS_perrno)(BX), AX 85 CMPQ AX, $0 86 JEQ skiperrno2 87 MOVL 0(AX), AX 88 MOVQ AX, libcall_err(DI) 89 90 skiperrno2: 91 RET 92 93 // uint32 tstart_sysvicall(M *newm); 94 TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0 95 // DI contains first arg newm 96 MOVQ m_g0(DI), DX // g 97 98 // Make TLS entries point at g and m. 99 get_tls(BX) 100 MOVQ DX, g(BX) 101 MOVQ DI, g_m(DX) 102 103 // Layout new m scheduler stack on os stack. 104 MOVQ SP, AX 105 MOVQ AX, (g_stack+stack_hi)(DX) 106 SUBQ $(0x100000), AX // stack size 107 MOVQ AX, (g_stack+stack_lo)(DX) 108 ADDQ $const_stackGuard, AX 109 MOVQ AX, g_stackguard0(DX) 110 MOVQ AX, g_stackguard1(DX) 111 112 // Someday the convention will be D is always cleared. 113 CLD 114 115 CALL runtime·stackcheck(SB) // clobbers AX,CX 116 CALL runtime·mstart(SB) 117 118 XORL AX, AX // return 0 == success 119 MOVL AX, ret+8(FP) 120 RET 121 122 // Careful, this is called by __sighndlr, a libc function. We must preserve 123 // registers as per AMD 64 ABI. 124 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0 125 // Note that we are executing on altsigstack here, so we have 126 // more stack available than NOSPLIT would have us believe. 127 // To defeat the linker, we make our own stack frame with 128 // more space: 129 SUBQ $168, SP 130 // save registers 131 MOVQ BX, 24(SP) 132 MOVQ BP, 32(SP) 133 MOVQ R12, 40(SP) 134 MOVQ R13, 48(SP) 135 MOVQ R14, 56(SP) 136 MOVQ R15, 64(SP) 137 138 get_tls(BX) 139 // check that g exists 140 MOVQ g(BX), R10 141 CMPQ R10, $0 142 JNE allgood 143 MOVQ SI, 72(SP) 144 MOVQ DX, 80(SP) 145 LEAQ 72(SP), AX 146 MOVQ DI, 0(SP) 147 MOVQ AX, 8(SP) 148 MOVQ $runtime·badsignal(SB), AX 149 CALL AX 150 JMP exit 151 152 allgood: 153 // Save m->libcall and m->scratch. We need to do this because we 154 // might get interrupted by a signal in runtime·asmcgocall. 155 156 // save m->libcall 157 MOVQ g_m(R10), BP 158 LEAQ m_libcall(BP), R11 159 MOVQ libcall_fn(R11), R10 160 MOVQ R10, 72(SP) 161 MOVQ libcall_args(R11), R10 162 MOVQ R10, 80(SP) 163 MOVQ libcall_n(R11), R10 164 MOVQ R10, 88(SP) 165 MOVQ libcall_r1(R11), R10 166 MOVQ R10, 152(SP) 167 MOVQ libcall_r2(R11), R10 168 MOVQ R10, 160(SP) 169 170 // save m->scratch 171 LEAQ (m_mOS+mOS_scratch)(BP), R11 172 MOVQ 0(R11), R10 173 MOVQ R10, 96(SP) 174 MOVQ 8(R11), R10 175 MOVQ R10, 104(SP) 176 MOVQ 16(R11), R10 177 MOVQ R10, 112(SP) 178 MOVQ 24(R11), R10 179 MOVQ R10, 120(SP) 180 MOVQ 32(R11), R10 181 MOVQ R10, 128(SP) 182 MOVQ 40(R11), R10 183 MOVQ R10, 136(SP) 184 185 // save errno, it might be EINTR; stuff we do here might reset it. 186 MOVQ (m_mOS+mOS_perrno)(BP), R10 187 MOVL 0(R10), R10 188 MOVQ R10, 144(SP) 189 190 // prepare call 191 MOVQ DI, 0(SP) 192 MOVQ SI, 8(SP) 193 MOVQ DX, 16(SP) 194 CALL runtime·sigtrampgo(SB) 195 196 get_tls(BX) 197 MOVQ g(BX), BP 198 MOVQ g_m(BP), BP 199 // restore libcall 200 LEAQ m_libcall(BP), R11 201 MOVQ 72(SP), R10 202 MOVQ R10, libcall_fn(R11) 203 MOVQ 80(SP), R10 204 MOVQ R10, libcall_args(R11) 205 MOVQ 88(SP), R10 206 MOVQ R10, libcall_n(R11) 207 MOVQ 152(SP), R10 208 MOVQ R10, libcall_r1(R11) 209 MOVQ 160(SP), R10 210 MOVQ R10, libcall_r2(R11) 211 212 // restore scratch 213 LEAQ (m_mOS+mOS_scratch)(BP), R11 214 MOVQ 96(SP), R10 215 MOVQ R10, 0(R11) 216 MOVQ 104(SP), R10 217 MOVQ R10, 8(R11) 218 MOVQ 112(SP), R10 219 MOVQ R10, 16(R11) 220 MOVQ 120(SP), R10 221 MOVQ R10, 24(R11) 222 MOVQ 128(SP), R10 223 MOVQ R10, 32(R11) 224 MOVQ 136(SP), R10 225 MOVQ R10, 40(R11) 226 227 // restore errno 228 MOVQ (m_mOS+mOS_perrno)(BP), R11 229 MOVQ 144(SP), R10 230 MOVL R10, 0(R11) 231 232 exit: 233 // restore registers 234 MOVQ 24(SP), BX 235 MOVQ 32(SP), BP 236 MOVQ 40(SP), R12 237 MOVQ 48(SP), R13 238 MOVQ 56(SP), R14 239 MOVQ 64(SP), R15 240 ADDQ $168, SP 241 RET 242 243 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 244 MOVQ fn+0(FP), AX 245 MOVL sig+8(FP), DI 246 MOVQ info+16(FP), SI 247 MOVQ ctx+24(FP), DX 248 MOVQ SP, BX // callee-saved 249 ANDQ $~15, SP // alignment for x86_64 ABI 250 CALL AX 251 MOVQ BX, SP 252 RET 253 254 // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack, 255 // can also be called in cgo callback path without a g->m. 256 TEXT runtime·usleep1(SB),NOSPLIT,$0 257 MOVL usec+0(FP), DI 258 MOVQ $usleep2<>(SB), AX // to hide from 6l 259 260 // Execute call on m->g0. 261 get_tls(R15) 262 CMPQ R15, $0 263 JE noswitch 264 265 MOVQ g(R15), R13 266 CMPQ R13, $0 267 JE noswitch 268 MOVQ g_m(R13), R13 269 CMPQ R13, $0 270 JE noswitch 271 // TODO(aram): do something about the cpu profiler here. 272 273 MOVQ m_g0(R13), R14 274 CMPQ g(R15), R14 275 JNE switch 276 // executing on m->g0 already 277 CALL AX 278 RET 279 280 switch: 281 // Switch to m->g0 stack and back. 282 MOVQ (g_sched+gobuf_sp)(R14), R14 283 MOVQ SP, -8(R14) 284 LEAQ -8(R14), SP 285 CALL AX 286 MOVQ 0(SP), SP 287 RET 288 289 noswitch: 290 // Not a Go-managed thread. Do not switch stack. 291 CALL AX 292 RET 293 294 // Runs on OS stack. duration (in µs units) is in DI. 295 TEXT usleep2<>(SB),NOSPLIT,$0 296 LEAQ libc_usleep(SB), AX 297 CALL AX 298 RET 299 300 // Runs on OS stack, called from runtime·osyield. 301 TEXT runtime·osyield1(SB),NOSPLIT,$0 302 LEAQ libc_sched_yield(SB), AX 303 CALL AX 304 RET