Text file
src/runtime/sys_solaris_amd64.s
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
305
View as plain text