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,$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
309
View as plain text