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