Text file src/runtime/sys_nacl_amd64p32.s
1 // Copyright 2013 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 #include "go_asm.h"
6 #include "go_tls.h"
7 #include "textflag.h"
8 #include "syscall_nacl.h"
9
10 #define NACL_SYSCALL(code) \
11 MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
12
13 TEXT runtime·settls(SB),NOSPLIT,$0
14 MOVL DI, TLS // really BP
15 RET
16
17 TEXT runtime·exit(SB),NOSPLIT,$0
18 MOVL code+0(FP), DI
19 NACL_SYSCALL(SYS_exit)
20 RET
21
22 // func exitThread(wait *uint32)
23 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
24 MOVL wait+0(FP), DI
25 // SYS_thread_exit will clear *wait when the stack is free.
26 NACL_SYSCALL(SYS_thread_exit)
27 JMP 0(PC)
28
29 TEXT runtime·open(SB),NOSPLIT,$0
30 MOVL name+0(FP), DI
31 MOVL mode+4(FP), SI
32 MOVL perm+8(FP), DX
33 NACL_SYSCALL(SYS_open)
34 MOVL AX, ret+16(FP)
35 RET
36
37 TEXT runtime·closefd(SB),NOSPLIT,$0
38 MOVL fd+0(FP), DI
39 NACL_SYSCALL(SYS_close)
40 MOVL AX, ret+8(FP)
41 RET
42
43 TEXT runtime·read(SB),NOSPLIT,$0
44 MOVL fd+0(FP), DI
45 MOVL p+4(FP), SI
46 MOVL n+8(FP), DX
47 NACL_SYSCALL(SYS_read)
48 MOVL AX, ret+16(FP)
49 RET
50
51 TEXT syscall·naclWrite(SB), NOSPLIT, $24-20
52 MOVL arg1+0(FP), DI
53 MOVL arg2+4(FP), SI
54 MOVL arg3+8(FP), DX
55 MOVL DI, 0(SP)
56 MOVL SI, 4(SP)
57 MOVL DX, 8(SP)
58 CALL runtime·write(SB)
59 MOVL 16(SP), AX
60 MOVL AX, ret+16(FP)
61 RET
62
63 TEXT runtime·write(SB),NOSPLIT,$16-20
64 // If using fake time and writing to stdout or stderr,
65 // emit playback header before actual data.
66 MOVQ runtime·faketime(SB), AX
67 CMPQ AX, $0
68 JEQ write
69 MOVL fd+0(FP), DI
70 CMPL DI, $1
71 JEQ playback
72 CMPL DI, $2
73 JEQ playback
74
75 write:
76 // Ordinary write.
77 MOVL fd+0(FP), DI
78 MOVL p+4(FP), SI
79 MOVL n+8(FP), DX
80 NACL_SYSCALL(SYS_write)
81 MOVL AX, ret+16(FP)
82 RET
83
84 // Write with playback header.
85 // First, lock to avoid interleaving writes.
86 playback:
87 MOVL $1, BX
88 XCHGL runtime·writelock(SB), BX
89 CMPL BX, $0
90 JNE playback
91
92 MOVQ runtime·lastfaketime(SB), CX
93 MOVL runtime·lastfaketimefd(SB), BX
94 CMPL DI, BX
95 JE samefd
96
97 // If the current fd doesn't match the fd of the previous write,
98 // ensure that the timestamp is strictly greater. That way, we can
99 // recover the original order even if we read the fds separately.
100 INCQ CX
101 MOVL DI, runtime·lastfaketimefd(SB)
102
103 samefd:
104 CMPQ AX, CX
105 CMOVQLT CX, AX
106 MOVQ AX, runtime·lastfaketime(SB)
107
108 // Playback header: 0 0 P B <8-byte time> <4-byte data length>
109 MOVL $(('B'<<24) | ('P'<<16)), 0(SP)
110 BSWAPQ AX
111 MOVQ AX, 4(SP)
112 MOVL n+8(FP), DX
113 BSWAPL DX
114 MOVL DX, 12(SP)
115 MOVL fd+0(FP), DI
116 MOVL SP, SI
117 MOVL $16, DX
118 NACL_SYSCALL(SYS_write)
119
120 // Write actual data.
121 MOVL fd+0(FP), DI
122 MOVL p+4(FP), SI
123 MOVL n+8(FP), DX
124 NACL_SYSCALL(SYS_write)
125
126 // Unlock.
127 MOVL $0, runtime·writelock(SB)
128
129 MOVL AX, ret+16(FP)
130 RET
131
132 TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
133 MOVL p+0(FP), DI
134 MOVL size+4(FP), SI
135 NACL_SYSCALL(SYS_exception_stack)
136 MOVL AX, ret+8(FP)
137 RET
138
139 TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
140 MOVL fn+0(FP), DI
141 MOVL arg+4(FP), SI
142 NACL_SYSCALL(SYS_exception_handler)
143 MOVL AX, ret+8(FP)
144 RET
145
146 TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
147 MOVL flag+0(FP), DI
148 NACL_SYSCALL(SYS_sem_create)
149 MOVL AX, ret+8(FP)
150 RET
151
152 TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
153 MOVL sem+0(FP), DI
154 NACL_SYSCALL(SYS_sem_wait)
155 MOVL AX, ret+8(FP)
156 RET
157
158 TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
159 MOVL sem+0(FP), DI
160 NACL_SYSCALL(SYS_sem_post)
161 MOVL AX, ret+8(FP)
162 RET
163
164 TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
165 MOVL flag+0(FP), DI
166 NACL_SYSCALL(SYS_mutex_create)
167 MOVL AX, ret+8(FP)
168 RET
169
170 TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
171 MOVL mutex+0(FP), DI
172 NACL_SYSCALL(SYS_mutex_lock)
173 MOVL AX, ret+8(FP)
174 RET
175
176 TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
177 MOVL mutex+0(FP), DI
178 NACL_SYSCALL(SYS_mutex_trylock)
179 MOVL AX, ret+8(FP)
180 RET
181
182 TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
183 MOVL mutex+0(FP), DI
184 NACL_SYSCALL(SYS_mutex_unlock)
185 MOVL AX, ret+8(FP)
186 RET
187
188 TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
189 MOVL flag+0(FP), DI
190 NACL_SYSCALL(SYS_cond_create)
191 MOVL AX, ret+8(FP)
192 RET
193
194 TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
195 MOVL cond+0(FP), DI
196 MOVL n+4(FP), SI
197 NACL_SYSCALL(SYS_cond_wait)
198 MOVL AX, ret+8(FP)
199 RET
200
201 TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
202 MOVL cond+0(FP), DI
203 NACL_SYSCALL(SYS_cond_signal)
204 MOVL AX, ret+8(FP)
205 RET
206
207 TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
208 MOVL cond+0(FP), DI
209 NACL_SYSCALL(SYS_cond_broadcast)
210 MOVL AX, ret+8(FP)
211 RET
212
213 TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
214 MOVL cond+0(FP), DI
215 MOVL lock+4(FP), SI
216 MOVL ts+8(FP), DX
217 NACL_SYSCALL(SYS_cond_timed_wait_abs)
218 MOVL AX, ret+16(FP)
219 RET
220
221 TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
222 MOVL fn+0(FP), DI
223 MOVL stk+4(FP), SI
224 MOVL tls+8(FP), DX
225 MOVL xx+12(FP), CX
226 NACL_SYSCALL(SYS_thread_create)
227 MOVL AX, ret+16(FP)
228 RET
229
230 TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
231 NACL_SYSCALL(SYS_tls_get)
232 SUBL $8, AX
233 MOVL AX, TLS
234 JMP runtime·mstart(SB)
235
236 TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
237 MOVL ts+0(FP), DI
238 MOVL extra+4(FP), SI
239 NACL_SYSCALL(SYS_nanosleep)
240 MOVL AX, ret+8(FP)
241 RET
242
243 TEXT runtime·osyield(SB),NOSPLIT,$0
244 NACL_SYSCALL(SYS_sched_yield)
245 RET
246
247 TEXT runtime·mmap(SB),NOSPLIT,$8
248 MOVL addr+0(FP), DI
249 MOVL n+4(FP), SI
250 MOVL prot+8(FP), DX
251 MOVL flags+12(FP), CX
252 MOVL fd+16(FP), R8
253 MOVL off+20(FP), AX
254 MOVQ AX, 0(SP)
255 MOVL SP, R9
256 NACL_SYSCALL(SYS_mmap)
257 CMPL AX, $-4095
258 JNA ok
259 NEGL AX
260 MOVL $0, p+24(FP)
261 MOVL AX, err+28(FP)
262 RET
263 ok:
264 MOVL AX, p+24(FP)
265 MOVL $0, err+28(FP)
266 RET
267
268 TEXT runtime·walltime(SB),NOSPLIT,$16
269 MOVQ runtime·faketime(SB), AX
270 CMPQ AX, $0
271 JEQ realtime
272 MOVQ $0, DX
273 MOVQ $1000000000, CX
274 DIVQ CX
275 MOVQ AX, sec+0(FP)
276 MOVL DX, nsec+8(FP)
277 RET
278 realtime:
279 MOVL $0, DI // real time clock
280 LEAL 0(SP), AX
281 MOVL AX, SI // timespec
282 NACL_SYSCALL(SYS_clock_gettime)
283 MOVL 0(SP), AX // low 32 sec
284 MOVL 4(SP), CX // high 32 sec
285 MOVL 8(SP), BX // nsec
286
287 // sec is in AX, nsec in BX
288 MOVL AX, sec_lo+0(FP)
289 MOVL CX, sec_hi+4(FP)
290 MOVL BX, nsec+8(FP)
291 RET
292
293 TEXT syscall·now(SB),NOSPLIT,$0
294 JMP runtime·walltime(SB)
295
296 TEXT runtime·nanotime(SB),NOSPLIT,$16
297 MOVQ runtime·faketime(SB), AX
298 CMPQ AX, $0
299 JEQ 3(PC)
300 MOVQ AX, ret+0(FP)
301 RET
302 MOVL $0, DI // real time clock
303 LEAL 0(SP), AX
304 MOVL AX, SI // timespec
305 NACL_SYSCALL(SYS_clock_gettime)
306 MOVQ 0(SP), AX // sec
307 MOVL 8(SP), DX // nsec
308
309 // sec is in AX, nsec in DX
310 // return nsec in AX
311 IMULQ $1000000000, AX
312 ADDQ DX, AX
313 MOVQ AX, ret+0(FP)
314 RET
315
316 TEXT runtime·sigtramp(SB),NOSPLIT,$80
317 // restore TLS register at time of execution,
318 // in case it's been smashed.
319 // the TLS register is really BP, but for consistency
320 // with non-NaCl systems it is referred to here as TLS.
321 // NOTE: Cannot use SYS_tls_get here (like we do in mstart_nacl),
322 // because the main thread never calls tls_set.
323 LEAL ctxt+0(FP), AX
324 MOVL (16*4+5*8)(AX), AX
325 MOVL AX, TLS
326
327 // check that g exists
328 get_tls(CX)
329 MOVL g(CX), DI
330
331 CMPL DI, $0
332 JEQ nog
333
334 // save g
335 MOVL DI, 20(SP)
336
337 // g = m->gsignal
338 MOVL g_m(DI), BX
339 MOVL m_gsignal(BX), BX
340 MOVL BX, g(CX)
341
342 //JMP debughandler
343
344 // copy arguments for sighandler
345 MOVL $11, 0(SP) // signal
346 MOVL $0, 4(SP) // siginfo
347 LEAL ctxt+0(FP), AX
348 MOVL AX, 8(SP) // context
349 MOVL DI, 12(SP) // g
350
351 CALL runtime·sighandler(SB)
352
353 // restore g
354 get_tls(CX)
355 MOVL 20(SP), BX
356 MOVL BX, g(CX)
357
358 // Enable exceptions again.
359 NACL_SYSCALL(SYS_exception_clear_flag)
360
361 // Restore registers as best we can. Impossible to do perfectly.
362 // See comment in sys_nacl_386.s for extended rationale.
363 LEAL ctxt+0(FP), SI
364 ADDL $64, SI
365 MOVQ 0(SI), AX
366 MOVQ 8(SI), CX
367 MOVQ 16(SI), DX
368 MOVQ 24(SI), BX
369 MOVL 32(SI), SP // MOVL for SP sandboxing
370 // 40(SI) is saved BP aka TLS, already restored above
371 // 48(SI) is saved SI, never to be seen again
372 MOVQ 56(SI), DI
373 MOVQ 64(SI), R8
374 MOVQ 72(SI), R9
375 MOVQ 80(SI), R10
376 MOVQ 88(SI), R11
377 MOVQ 96(SI), R12
378 MOVQ 104(SI), R13
379 MOVQ 112(SI), R14
380 // 120(SI) is R15, which is owned by Native Client and must not be modified
381 MOVQ 128(SI), SI // saved PC
382 // 136(SI) is saved EFLAGS, never to be seen again
383 JMP SI
384
385 //debughandler:
386 //// print basic information
387 //LEAL ctxt+0(FP), DI
388 //MOVL $runtime·sigtrampf(SB), AX
389 //MOVL AX, 0(SP)
390 //MOVQ (16*4+16*8)(DI), BX // rip
391 //MOVQ BX, 8(SP)
392 //MOVQ (16*4+0*8)(DI), BX // rax
393 //MOVQ BX, 16(SP)
394 //MOVQ (16*4+1*8)(DI), BX // rcx
395 //MOVQ BX, 24(SP)
396 //MOVQ (16*4+2*8)(DI), BX // rdx
397 //MOVQ BX, 32(SP)
398 //MOVQ (16*4+3*8)(DI), BX // rbx
399 //MOVQ BX, 40(SP)
400 //MOVQ (16*4+7*8)(DI), BX // rdi
401 //MOVQ BX, 48(SP)
402 //MOVQ (16*4+15*8)(DI), BX // r15
403 //MOVQ BX, 56(SP)
404 //MOVQ (16*4+4*8)(DI), BX // rsp
405 //MOVQ 0(BX), BX
406 //MOVQ BX, 64(SP)
407 //CALL runtime·printf(SB)
408 //
409 //LEAL ctxt+0(FP), DI
410 //MOVQ (16*4+16*8)(DI), BX // rip
411 //MOVL BX, 0(SP)
412 //MOVQ (16*4+4*8)(DI), BX // rsp
413 //MOVL BX, 4(SP)
414 //MOVL $0, 8(SP) // lr
415 //get_tls(CX)
416 //MOVL g(CX), BX
417 //MOVL BX, 12(SP) // gp
418 //CALL runtime·traceback(SB)
419
420 notls:
421 MOVL 0, AX
422 RET
423
424 nog:
425 MOVL 0, AX
426 RET
427
428 // cannot do real signal handling yet, because gsignal has not been allocated.
429 MOVL $1, DI; NACL_SYSCALL(SYS_exit)
430
431 // func getRandomData([]byte)
432 TEXT runtime·getRandomData(SB),NOSPLIT,$0-12
433 MOVL arg_base+0(FP), DI
434 MOVL arg_len+4(FP), SI
435 NACL_SYSCALL(SYS_get_random_bytes)
436 RET
437
438 TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
439 /*
440 MOVL di+0(FP), DI
441 LEAL 12(DI), BX
442 MOVL 8(DI), AX
443 ADDL 4(DI), AX
444 ADDL $2, AX
445 LEAL (BX)(AX*4), BX
446 MOVL BX, runtime·nacl_irt_query(SB)
447 auxloop:
448 MOVL 0(BX), DX
449 CMPL DX, $0
450 JNE 2(PC)
451 RET
452 CMPL DX, $32
453 JEQ auxfound
454 ADDL $8, BX
455 JMP auxloop
456 auxfound:
457 MOVL 4(BX), BX
458 MOVL BX, runtime·nacl_irt_query(SB)
459
460 LEAL runtime·nacl_irt_basic_v0_1_str(SB), DI
461 LEAL runtime·nacl_irt_basic_v0_1(SB), SI
462 MOVL runtime·nacl_irt_basic_v0_1_size(SB), DX
463 MOVL runtime·nacl_irt_query(SB), BX
464 CALL BX
465
466 LEAL runtime·nacl_irt_memory_v0_3_str(SB), DI
467 LEAL runtime·nacl_irt_memory_v0_3(SB), SI
468 MOVL runtime·nacl_irt_memory_v0_3_size(SB), DX
469 MOVL runtime·nacl_irt_query(SB), BX
470 CALL BX
471
472 LEAL runtime·nacl_irt_thread_v0_1_str(SB), DI
473 LEAL runtime·nacl_irt_thread_v0_1(SB), SI
474 MOVL runtime·nacl_irt_thread_v0_1_size(SB), DX
475 MOVL runtime·nacl_irt_query(SB), BX
476 CALL BX
477
478 // TODO: Once we have a NaCl SDK with futex syscall support,
479 // try switching to futex syscalls and here load the
480 // nacl-irt-futex-0.1 table.
481 */
482 RET
View as plain text