github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/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,$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 $184, SP 130 131 // save registers 132 MOVQ BX, 32(SP) 133 MOVQ BP, 40(SP) 134 MOVQ R12, 48(SP) 135 MOVQ R13, 56(SP) 136 MOVQ R14, 64(SP) 137 MOVQ R15, 72(SP) 138 139 get_tls(BX) 140 // check that g exists 141 MOVQ g(BX), R10 142 CMPQ R10, $0 143 JNE allgood 144 MOVQ SI, 80(SP) 145 MOVQ DX, 88(SP) 146 LEAQ 80(SP), AX 147 MOVQ DI, 0(SP) 148 MOVQ AX, 8(SP) 149 MOVQ $runtime·badsignal(SB), AX 150 CALL AX 151 JMP exit 152 153 allgood: 154 // Save m->libcall and m->scratch. We need to do this because we 155 // might get interrupted by a signal in runtime·asmcgocall. 156 157 // save m->libcall 158 MOVQ g_m(R10), BP 159 LEAQ m_libcall(BP), R11 160 MOVQ libcall_fn(R11), R10 161 MOVQ R10, 88(SP) 162 MOVQ libcall_args(R11), R10 163 MOVQ R10, 96(SP) 164 MOVQ libcall_n(R11), R10 165 MOVQ R10, 104(SP) 166 MOVQ libcall_r1(R11), R10 167 MOVQ R10, 168(SP) 168 MOVQ libcall_r2(R11), R10 169 MOVQ R10, 176(SP) 170 171 // save m->scratch 172 LEAQ (m_mOS+mOS_scratch)(BP), R11 173 MOVQ 0(R11), R10 174 MOVQ R10, 112(SP) 175 MOVQ 8(R11), R10 176 MOVQ R10, 120(SP) 177 MOVQ 16(R11), R10 178 MOVQ R10, 128(SP) 179 MOVQ 24(R11), R10 180 MOVQ R10, 136(SP) 181 MOVQ 32(R11), R10 182 MOVQ R10, 144(SP) 183 MOVQ 40(R11), R10 184 MOVQ R10, 152(SP) 185 186 // save errno, it might be EINTR; stuff we do here might reset it. 187 MOVQ (m_mOS+mOS_perrno)(BP), R10 188 MOVL 0(R10), R10 189 MOVQ R10, 160(SP) 190 191 // prepare call 192 MOVQ DI, 0(SP) 193 MOVQ SI, 8(SP) 194 MOVQ DX, 16(SP) 195 CALL runtime·sigtrampgo(SB) 196 197 get_tls(BX) 198 MOVQ g(BX), BP 199 MOVQ g_m(BP), BP 200 // restore libcall 201 LEAQ m_libcall(BP), R11 202 MOVQ 88(SP), R10 203 MOVQ R10, libcall_fn(R11) 204 MOVQ 96(SP), R10 205 MOVQ R10, libcall_args(R11) 206 MOVQ 104(SP), R10 207 MOVQ R10, libcall_n(R11) 208 MOVQ 168(SP), R10 209 MOVQ R10, libcall_r1(R11) 210 MOVQ 176(SP), R10 211 MOVQ R10, libcall_r2(R11) 212 213 // restore scratch 214 LEAQ (m_mOS+mOS_scratch)(BP), R11 215 MOVQ 112(SP), R10 216 MOVQ R10, 0(R11) 217 MOVQ 120(SP), R10 218 MOVQ R10, 8(R11) 219 MOVQ 128(SP), R10 220 MOVQ R10, 16(R11) 221 MOVQ 136(SP), R10 222 MOVQ R10, 24(R11) 223 MOVQ 144(SP), R10 224 MOVQ R10, 32(R11) 225 MOVQ 152(SP), R10 226 MOVQ R10, 40(R11) 227 228 // restore errno 229 MOVQ (m_mOS+mOS_perrno)(BP), R11 230 MOVQ 160(SP), R10 231 MOVL R10, 0(R11) 232 233 exit: 234 // restore registers 235 MOVQ 32(SP), BX 236 MOVQ 40(SP), BP 237 MOVQ 48(SP), R12 238 MOVQ 56(SP), R13 239 MOVQ 64(SP), R14 240 MOVQ 72(SP), R15 241 242 ADDQ $184, SP 243 RET 244 245 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 246 MOVQ fn+0(FP), AX 247 MOVL sig+8(FP), DI 248 MOVQ info+16(FP), SI 249 MOVQ ctx+24(FP), DX 250 PUSHQ BP 251 MOVQ SP, BP 252 ANDQ $~15, SP // alignment for x86_64 ABI 253 CALL AX 254 MOVQ BP, SP 255 POPQ BP 256 RET 257 258 // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack, 259 // can also be called in cgo callback path without a g->m. 260 TEXT runtime·usleep1(SB),NOSPLIT,$0 261 MOVL usec+0(FP), DI 262 MOVQ $usleep2<>(SB), AX // to hide from 6l 263 264 // Execute call on m->g0. 265 get_tls(R15) 266 CMPQ R15, $0 267 JE noswitch 268 269 MOVQ g(R15), R13 270 CMPQ R13, $0 271 JE noswitch 272 MOVQ g_m(R13), R13 273 CMPQ R13, $0 274 JE noswitch 275 // TODO(aram): do something about the cpu profiler here. 276 277 MOVQ m_g0(R13), R14 278 CMPQ g(R15), R14 279 JNE switch 280 // executing on m->g0 already 281 CALL AX 282 RET 283 284 switch: 285 // Switch to m->g0 stack and back. 286 MOVQ (g_sched+gobuf_sp)(R14), R14 287 MOVQ SP, -8(R14) 288 LEAQ -8(R14), SP 289 CALL AX 290 MOVQ 0(SP), SP 291 RET 292 293 noswitch: 294 // Not a Go-managed thread. Do not switch stack. 295 CALL AX 296 RET 297 298 // Runs on OS stack. duration (in µs units) is in DI. 299 TEXT usleep2<>(SB),NOSPLIT,$0 300 LEAQ libc_usleep(SB), AX 301 CALL AX 302 RET 303 304 // Runs on OS stack, called from runtime·osyield. 305 TEXT runtime·osyield1(SB),NOSPLIT,$0 306 LEAQ libc_sched_yield(SB), AX 307 CALL AX 308 RET