/[cmucl]/src/lisp/amd64-assem.S
ViewVC logotype

Contents of /src/lisp/amd64-assem.S

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations)
Mon Nov 2 15:05:07 2009 UTC (4 years, 5 months ago) by rtoy
Branch: MAIN
CVS Tags: sparc-tramp-assem-base, post-merge-intl-branch, intl-branch-working-2010-02-19-1000, release-20b-pre1, release-20b-pre2, sparc-tramp-assem-2010-07-19, intl-2-branch-base, GIT-CONVERSION, cross-sol-x86-merged, intl-branch-working-2010-02-11-1000, RELEASE_20b, cross-sol-x86-base, snapshot-2010-12, snapshot-2010-11, snapshot-2011-09, snapshot-2011-06, snapshot-2011-07, snapshot-2011-04, snapshot-2011-02, snapshot-2011-03, snapshot-2011-01, pre-merge-intl-branch, snapshot-2010-05, snapshot-2010-04, snapshot-2010-07, snapshot-2010-06, snapshot-2010-01, snapshot-2010-03, snapshot-2010-02, snapshot-2010-08, cross-sol-x86-2010-12-20, intl-branch-2010-03-18-1300, snapshot-2009-12, cross-sparc-branch-base, intl-branch-base, HEAD
Branch point for: cross-sparc-branch, RELEASE-20B-BRANCH, sparc-tramp-assem-branch, intl-branch, cross-sol-x86-branch, intl-2-branch
Changes since 1.11: +1 -1 lines
Revert previous changes.  They were supposed to go on
amd64-dd-branch.
1 ### amd64-assem.S -*- Mode: Asm; -*-
2 /**
3 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/amd64-assem.S,v 1.12 2009/11/02 15:05:07 rtoy Rel $
4 *
5 * Authors: Paul F. Werkowski <pw@snoopy.mv.com>
6 * Douglas T. Crosher
7 * Cheuksan Edward Wang
8 *
9 * This code was written to support the port of CMU Common Lisp
10 * to the AMD64 ISA and the Linux operating system. The
11 * author has placed this code in the public domain September 1996.
12 *
13 */
14
15
16 #include "x86-validate.h"
17
18 #define LANGUAGE_ASSEMBLY
19 #include "internals.h"
20 #include "lispregs.h"
21
22 #if defined __FreeBSD__
23 #include <osreldate.h>
24 #endif
25
26 /* Minimize conditionalization for different OS naming schemes */
27 #if defined (__linux__) || (__FreeBSD_version >= 300000) || defined (__NetBSD__)
28 #define GNAME(var) var
29 #else
30 #define GNAME(var) _##var
31 #endif
32
33 /* Get the right type of alignment. Linux wants alignment in bytes. */
34 #if defined (__linux__) || (__FreeBSD_version >= 300000)
35 #define align_4byte 4
36 #define align_8byte 8
37 #define align_16byte 16
38 #else
39 #define align_4byte 2
40 #define align_8byte 3
41 #define align_16byte 4
42 #endif
43
44 .text
45 .global GNAME(foreign_function_call_active)
46
47
48 /*
49 * The C function will preserve rbx, r12-15, and rbp across its
50 * function call - rbx is used to save the return lisp address.
51 *
52 * Return values are in rax, or st(0) for
53 * floats.
54 *
55 * It should work for lisp calls C calls lisp calls C ..
56 */
57 .text
58 .align align_16byte,0x90
59 .global GNAME(call_into_c)
60 .type GNAME(call_into_c),@function
61 GNAME(call_into_c):
62 movl $1,GNAME(foreign_function_call_active)
63
64 /* Save the return lisp address in rbx */
65 popq %rbx
66
67 /* Setup the NPX for C */
68 fstp %st(0)
69 fstp %st(0)
70 fstp %st(0)
71 fstp %st(0)
72 fstp %st(0)
73 fstp %st(0)
74 fstp %st(0)
75 fstp %st(0)
76
77 call *%rax # normal callout using Lisp stack
78
79 movq %rax,%rcx # remember integer return value
80
81 /* Check for a return FP value */
82 fxam
83 fnstsw %eax
84 andl $0x4500,%eax
85 cmpl $0x4100,%eax
86 jne Lfp_rtn_value
87
88 /* The return value is in eax, or eax,edx? */
89 /* Setup the NPX stack for lisp */
90 fldz # insure no regs are empty
91 fldz
92 fldz
93 fldz
94 fldz
95 fldz
96 fldz
97 fldz
98
99 /* Restore the return value */
100 movq %rcx,%rax # maybe return value
101
102 movl $0,GNAME(foreign_function_call_active)
103 /* Return */
104 jmp *%rbx
105
106 Lfp_rtn_value:
107 /* The return result is in st(0) */
108 /* Setup the NPX stack for lisp, placing the result in st(0) */
109 fldz # insure no regs are empty
110 fldz
111 fldz
112 fldz
113 fldz
114 fldz
115 fldz
116 fxch %st(7) # move the result back to st(0)
117
118 /* Don't need to restore eax as the result is in st(0) */
119
120 movl $0,GNAME(foreign_function_call_active)
121 /* Return */
122 jmp *%ebx
123
124 .size GNAME(call_into_c), . - GNAME(call_into_c)
125
126
127
128 .text
129 .global GNAME(call_into_lisp)
130 .type GNAME(call_into_lisp),@function
131
132 /* The C conventions require that rbx, r12-r15, and rbp be preserved
133 across function calls. */
134 /* The *alien-stack* pointer is setup on the first call_into_lisp when
135 the stack changes. */
136
137 .align align_16byte,0x90
138 GNAME(call_into_lisp):
139 pushq %rbp # save old frame pointer
140 movq %rsp,%rbp # establish new frame
141
142 /* Save the NPX state */
143 fwait # Catch any pending NPX exceptions.
144 subq $108,%rsp # Make room for the NPX state.
145 fnsave (%rsp) # Resets NPX
146
147 movl (%rsp),%eax # Load NPX control word
148 andl $0xfffff3ff,%eax # Set rounding mode to nearest
149 #ifdef type_LongFloat
150 orl $0x00000300,%eax # Set precision to 64 bits
151 #else
152 orl $0x00000200,%eax # Set precision to 53 bits
153 #endif
154 pushq %rax
155 fldcw (%rsp) # Recover modes
156 popq %rax
157
158 fldz # insure no FP regs are empty
159 fldz
160 fldz
161 fldz
162 fldz
163 fldz
164 fldz
165 fldz
166
167 /* Save C regs: rbx r12-15 */
168 pushq %rbx
169 pushq %r12
170 pushq %r13
171 pushq %r14
172 pushq %r15
173
174 /* clear descriptor regs */
175 xorq %rax,%rax # lexenv
176 xorq %rbx,%rbx # available
177 xorq %rcx,%rcx # arg count
178
179 /* no longer in function call */
180 movl $0, GNAME(foreign_function_call_active)
181
182 movq %rsp,%rbx # remember current stack
183 cmpq $CONTROL_STACK_START,%rsp
184 jbe ChangeToLispStack
185 cmpq $CONTROL_STACK_END,%rsp
186 jbe OnLispStack
187 ChangeToLispStack:
188 /* Setup the *alien-stack* pointer */
189 movq %rsp,ALIEN_STACK + SYMBOL_VALUE_OFFSET
190 movq $CONTROL_STACK_END,%rsp # New stack
191 OnLispStack:
192 pushq %rbx # save entry stack on (maybe) new stack
193
194 /* establish lisp args */
195 movq %rdi,%rax # lexenv? (C arg 1)
196 xorq %rdi,%rdi # clear second arg (lisp)
197
198 movq %rsi,%rbx # address of arg vec (C arg 2)
199 xorq %rsi,%rsi # clear third arg (lisp)
200
201 movq %rdx,%rcx # num args (C arg 3)
202 xorq %rdx,%rdx # clear first arg (lisp)
203
204 shlq $2,%rcx # make into fixnum
205 cmpq $0,%rcx
206 je Ldone
207 movq (%rbx),%rdx # arg0
208 cmpq $4,%rcx
209 je Ldone
210 movq 8(%rbx),%rdi # arg1
211 cmpq $8,%rcx
212 je Ldone
213 movq 16(%rbx),%rsi # arg2
214 Ldone:
215 /* Registers rax (lexenv), rcx (num args), rdx (arg 0),rdi (arg 1),rsi (arg 2) now live */
216
217 /* Allocate new frame */
218 mov %rsp,%rbx # current sp marks start of new frame
219 push %rbp # fp in save location S0
220 sub $16,%rsp # Ensure 3 slots are allocated, one above.
221 mov %rbx,%rbp # switch to new frame
222
223 /* Indirect the closure */
224 call *CLOSURE_FUNCTION_OFFSET(%rax)
225
226 /* Multi-value return - blow off any extra values */
227 mov %rbx, %rsp
228 /* Single value return */
229
230 /* Restore the stack, in case there was a stack change. */
231 popq %rsp # c-sp
232
233 /* Restore C regs: rbx esi edi */
234 popq %r15
235 popq %r14
236 popq %r13
237 popq %r12
238 popq %rbx
239
240 /* Restore the NPX state */
241 frstor (%rsp)
242 addq $108, %rsp
243
244 popq %rbp # c-fp
245 movq %rdx,%rax # c-val
246 ret
247 .size GNAME(call_into_lisp), . - GNAME(call_into_lisp)
248
249 /* Support for saving and restoring the NPX state from C. */
250 .text
251 .global GNAME(fpu_save)
252 .type GNAME(fpu_save),@function
253 .align 2,0x90
254 GNAME(fpu_save):
255 fnsave (%rdi) # Save the NPX state - Resets NPX
256 ret
257 .size GNAME(fpu_save),.-GNAME(fpu_save)
258
259 .global GNAME(fpu_restore)
260 .type GNAME(fpu_restore),@function
261 .align 2,0x90
262 GNAME(fpu_restore):
263 frstor (%rdi) # Restore the NPX state.
264 ret
265 .size GNAME(fpu_restore),.-GNAME(fpu_restore)
266
267
268 /*
269 * The undefined-function trampoline.
270 */
271 .text
272 .align align_4byte,0x90
273 .global GNAME(undefined_tramp)
274 .type GNAME(undefined_tramp),@function
275 GNAME(undefined_tramp):
276 int3
277 .byte trap_Error
278 /* Number of argument bytes */
279 .byte 2
280 .byte UNDEFINED_SYMBOL_ERROR
281 /* SC_OFFSET(sc_DescriptorReg,reg_RAX) */
282 .byte SC_OFFSET(sc_DescriptorReg,0)
283 ret
284 .size GNAME(undefined_tramp), .-GNAME(undefined_tramp)
285
286 /*
287 * The closure trampoline.
288 */
289 .text
290 .align align_4byte,0x90
291 .global GNAME(closure_tramp)
292 .type GNAME(closure_tramp),@function
293 GNAME(closure_tramp):
294 movq FDEFN_FUNCTION_OFFSET(%rax),%rax
295 jmp *CLOSURE_FUNCTION_OFFSET(%rax)
296 .size GNAME(closure_tramp), .-GNAME(closure_tramp)
297
298 /*
299 * Function-end breakpoint magic.
300 */
301 .text
302 .global GNAME(function_end_breakpoint_guts)
303 .align align_4byte
304 GNAME(function_end_breakpoint_guts):
305 /* Multiple Value return */
306 jmp multiple_value_return
307 /* Single value return: The eventual return will now use the
308 multiple values return convention but with a return values
309 count of one. */
310 movl %esp,%ebx # Setup ebx - the ofp.
311 subl $4,%esp # Allocate one stack slot for the return value
312 movl $4,%ecx # Setup ecx for one return value.
313 movl $NIL,%edi # Default second value
314 movl $NIL,%esi # Default third value
315
316 multiple_value_return:
317
318 .global GNAME(function_end_breakpoint_trap)
319 GNAME(function_end_breakpoint_trap):
320 int3
321 .byte trap_FunctionEndBreakpoint
322 hlt # Should never return here.
323
324 .global GNAME(function_end_breakpoint_end)
325 GNAME(function_end_breakpoint_end):
326
327
328 .global GNAME(do_pending_interrupt)
329 .type GNAME(do_pending_interrupt),@function
330 .align align_4byte,0x90
331 GNAME(do_pending_interrupt):
332 int3
333 .byte trap_PendingInterrupt
334 ret
335 .size GNAME(do_pending_interrupt),.-GNAME(do_pending_interrupt)
336
337 #ifdef trap_DynamicSpaceOverflowError
338 .global GNAME(do_dynamic_space_overflow_error)
339 .type GNAME(do_dynamic_space_overflow_error),@function
340 .align align_4byte,0x90
341 GNAME(do_dynamic_space_overflow_error):
342 int3
343 .byte trap_DynamicSpaceOverflowError
344 ret
345 .size GNAME(do_dynamic_space_overflow_error),.-GNAME(do_dynamic_space_overflow_error)
346 #endif
347
348 #ifdef trap_DynamicSpaceOverflowWarning
349 .global GNAME(do_dynamic_space_overflow_warning)
350 .type GNAME(do_dynamic_space_overflow_warning),@function
351 .align align_4byte,0x90
352 GNAME(do_dynamic_space_overflow_warning):
353 int3
354 .byte trap_DynamicSpaceOverflowWarning
355 ret
356 .size GNAME(do_dynamic_space_overflow_warning),.-GNAME(do_dynamic_space_overflow_warning)
357 #endif
358
359
360 /*
361 Allocate bytes and return the start of the allocated space
362 in the specified destination register.
363
364 In the general case the size will be in the destination register.
365
366 All registers must be preserved except the destination.
367 The C conventions will preserve rbx, r12-r15, and rbp.
368 Linkage table will trash r11.
369 So only rax, rdi, rsi, rdx, rcx, and r8-r10 need special care here. */
370
371 .globl GNAME(alloc_to_rax)
372 .type GNAME(alloc_to_rax),@function
373 .align align_4byte,0x90
374 GNAME(alloc_to_rax):
375 pushq %rcx # Save rcx, rdx, rdi, rsi, r8-r10 as C could destroy them.
376 pushq %rdx
377 pushq %rdi
378 pushq %rsi
379 pushq %r8
380 pushq %r9
381 pushq %r10
382 movq %rax, %rdi # Pass arg 1
383 call GNAME(alloc) # return value is in %rax
384 popq %r10
385 popq %r9
386 popq %r8
387 popq %rsi
388 popq %rdi
389 popq %rdx # Restore rcx and rdx.
390 popq %rcx
391 ret
392 .size GNAME(alloc_to_rax),.-GNAME(alloc_to_rax)
393
394 .globl GNAME(alloc_to_rcx)
395 .type GNAME(alloc_to_rcx),@function
396 .align align_4byte,0x90
397 GNAME(alloc_to_rcx):
398 pushq %rax # Save rax, rdi, rsi, rdx, and r8-r10 as C could destroy them.
399 pushq %rdi
400 pushq %rsi
401 pushq %rdx
402 pushq %r8
403 pushq %r9
404 pushq %r10
405 movq %rcx, %rdi # Pass the size
406 call GNAME(alloc)
407 movq %rax, %rcx # setup the destination.
408 popq %r10
409 popq %r9
410 popq %r8
411 popq %rdx # Restore
412 popq %rsi
413 popq %rdi
414 popq %rax
415 ret
416 .size GNAME(alloc_to_rcx),.-GNAME(alloc_to_rcx)
417
418 .globl GNAME(alloc_to_rdx)
419 .type GNAME(alloc_to_rdx),@function
420 .align align_4byte,0x90
421 GNAME(alloc_to_rdx):
422 pushq %rax # Save rax, rcx, rdi, rsi, r8-r10 as C could destroy them.
423 pushq %rcx
424 pushq %rdi
425 pushq %rsi
426 pushq %r8
427 pushq %r9
428 pushq %r10
429 mov %rdx, %rdi # move the size to arg 1
430 call GNAME(alloc)
431 movq %rax, %rdx # setup the destination.
432 popq %r10
433 popq %r9
434 popq %r8
435 popq %rsi
436 popq %rdi # Restore rdi, rax, and rcx.
437 popq %rcx
438 popq %rax
439 ret
440 .size GNAME(alloc_to_rdx),.-GNAME(alloc_to_rdx)
441
442 .globl GNAME(alloc_to_rbx)
443 .type GNAME(alloc_to_rbx),@function
444 .align align_4byte,0x90
445 GNAME(alloc_to_rbx):
446 pushq %rax # Save rax, rcx, rdx, rdi, rsi, r8-r10 as C could destroy them.
447 pushq %rcx
448 pushq %rdx
449 pushq %rdi
450 pushq %rsi
451 pushq %r8
452 pushq %r9
453 pushq %r10
454 movq %rbx, %rdi # Pass the size
455 call GNAME(alloc)
456 movq %rax, %rbx # setup the destination.
457 popq %r10
458 popq %r9
459 popq %r8
460 popq %rsi
461 popq %rdi
462 popq %rdx # Restore rax, rcx, rdx, rdi, rsi, r8-r10.
463 popq %rcx
464 popq %rax
465 ret
466 .size GNAME(alloc_to_rbx),.-GNAME(alloc_to_rbx)
467
468 .globl GNAME(alloc_to_rsi)
469 .type GNAME(alloc_to_rsi),@function
470 .align align_4byte,0x90
471 GNAME(alloc_to_rsi):
472 pushq %rax # Save rax, rcx, rdx, rdi, r8-r10 as C could destroy them.
473 pushq %rcx
474 pushq %rdx
475 pushq %rdi
476 pushq %r8
477 pushq %r9
478 pushq %r10
479 mov %rsi, %rdi # move the size to arg 1
480 call GNAME(alloc)
481 movq %rax,%rsi # setup the destination.
482 popq %r10
483 popq %r9
484 popq %r8
485 popq %rdi # Restore rdi, rax, rcx and rdx.
486 popq %rdx
487 popq %rcx
488 popq %rax
489 ret
490 .size GNAME(alloc_to_rsi),.-GNAME(alloc_to_rsi)
491
492 .globl GNAME(alloc_to_rdi)
493 .type GNAME(alloc_to_rdi),@function
494 .align align_4byte,0x90
495 GNAME(alloc_to_rdi):
496 pushq %rax # Save rax, rcx, rdx, rsi, r8-r10 as C could destroy them.
497 pushq %rcx
498 pushq %rdx
499 pushq %rsi
500 pushq %r8
501 pushq %r9
502 pushq %r10
503 call GNAME(alloc)
504 movq %rax, %rdi # setup the destination.
505 popq %r10
506 popq %r9
507 popq %r8
508 popq %rsi
509 popq %rdx # Restore rax, rcx and rdx.
510 popq %rcx
511 popq %rax
512 ret
513 .size GNAME(alloc_to_rdi),.-GNAME(alloc_to_rdi)
514
515 .globl GNAME(alloc_to_r8)
516 .type GNAME(alloc_to_r8),@function
517 .align align_4byte,0x90
518 GNAME(alloc_to_r8):
519 pushq %rax # Save rax, rcx, rdx, rdi, rsi, r9, r10 as C could destroy them.
520 pushq %rcx
521 pushq %rdx
522 pushq %rdi
523 pushq %rsi
524 pushq %r9
525 pushq %r10
526 movq %r8, %rdi # Pass the size
527 call GNAME(alloc)
528 movq %rax, %r8 # setup the destination.
529 popq %r10
530 popq %r9
531 popq %rsi
532 popq %rdi
533 popq %rdx # Restore rax, rcx and rdx.
534 popq %rcx
535 popq %rax
536 ret
537 .size GNAME(alloc_to_r8),.-GNAME(alloc_to_r8)
538
539 .globl GNAME(alloc_to_r9)
540 .type GNAME(alloc_to_r9),@function
541 .align align_4byte,0x90
542 GNAME(alloc_to_r9):
543 pushq %rax # Save rax, rcx, rdx, rdi, rsi, r8, r10 as C could destroy them.
544 pushq %rcx
545 pushq %rdx
546 pushq %rdi
547 pushq %rsi
548 pushq %r8
549 pushq %r10
550 movq %r9, %rdi # Pass the size
551 call GNAME(alloc)
552 movq %rax, %r9 # setup the destination.
553 popq %r10
554 popq %r8
555 popq %rsi
556 popq %rdi
557 popq %rdx # Restore rax, rcx and rdx.
558 popq %rcx
559 popq %rax
560 ret
561 .size GNAME(alloc_to_r9),.-GNAME(alloc_to_r9)
562
563 .globl GNAME(alloc_to_r10)
564 .type GNAME(alloc_to_r10),@function
565 .align align_4byte,0x90
566 GNAME(alloc_to_r10):
567 pushq %rax # Save rax, rcx, rdx, rdi, rsi, r8-r9 as C could destroy them.
568 pushq %rcx
569 pushq %rdx
570 pushq %rdi
571 pushq %rsi
572 pushq %r8
573 pushq %r9
574 movq %r10, %rdi # Pass the size
575 call GNAME(alloc)
576 movq %rax, %r10 # setup the destination.
577 popq %r9
578 popq %r8
579 popq %rsi
580 popq %rdi
581 popq %rdx # Restore rax, rcx and rdx.
582 popq %rcx
583 popq %rax
584 ret
585 .size GNAME(alloc_to_r10),.-GNAME(alloc_to_r10)
586
587 .globl GNAME(alloc_to_r12)
588 .type GNAME(alloc_to_r12),@function
589 .align align_4byte,0x90
590 GNAME(alloc_to_r12):
591 pushq %rax # Save rax, rcx, rdx, rdi, rsi, r8-r10 as C could destroy them.
592 pushq %rcx
593 pushq %rdx
594 pushq %rdi
595 pushq %rsi
596 pushq %r8
597 pushq %r9
598 pushq %r10
599 movq %r12, %rdi # Pass the size
600 call GNAME(alloc)
601 movq %rax, %r12 # setup the destination.
602 popq %r10
603 popq %r9
604 popq %r8
605 popq %rsi
606 popq %rdi
607 popq %rdx # Restore rax, rcx and rdx.
608 popq %rcx
609 popq %rax
610 ret
611 .size GNAME(alloc_to_r12),.-GNAME(alloc_to_r12)
612
613 .globl GNAME(alloc_to_r13)
614 .type GNAME(alloc_to_r13),@function
615 .align align_4byte,0x90
616 GNAME(alloc_to_r13):
617 pushq %rax # Save rax, rcx, rdx, rdi, rsi, r8-r10 as C could destroy them.
618 pushq %rcx
619 pushq %rdx
620 pushq %rdi
621 pushq %rsi
622 pushq %r8
623 pushq %r9
624 pushq %r10
625 movq %r13, %rdi # Pass the size
626 call GNAME(alloc)
627 movq %rax, %r13 # setup the destination.
628 popq %r10
629 popq %r9
630 popq %r8
631 popq %rsi
632 popq %rdi
633 popq %rdx # Restore rax, rcx and rdx.
634 popq %rcx
635 popq %rax
636 ret
637 .size GNAME(alloc_to_r13),.-GNAME(alloc_to_r13)
638
639
640 #ifdef GENCGC
641
642 /* Called from lisp when an inline allocation overflows.
643 Every register except the result needs to be preserved.
644 We depend on C to preserve rbx, r12-r15, and rbp.
645 Linkage table will trash r11.
646 But where necessary must save rax, rcx, rdx, rdi, rsi, r8-r10. */
647
648 /* This routine handles an overflow with rax=crfp+size. So the
649 size=rax-crfp. */
650 .align align_4byte
651 .globl GNAME(alloc_overflow_rax)
652 .type GNAME(alloc_overflow_rax),@function
653 GNAME(alloc_overflow_rax):
654 pushq %rcx # Save rcx
655 pushq %rdx # Save rdx
656 pushq %rdi
657 pushq %rsi
658 pushq %r8
659 pushq %r9
660 pushq %r10
661 /* Calculate the size for the allocation. */
662 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%rax
663 movq %rax, %rdi # Pass arg 1
664 call GNAME(alloc)
665 popq %r10
666 popq %r9
667 popq %r8
668 popq %rsi
669 popq %rdi
670 popq %rdx # Restore rdx.
671 popq %rcx # Restore rcx.
672 addq $13,(%rsp) # Adjust the return address to skip the next inst.
673 ret
674 .size GNAME(alloc_overflow_rax),.-GNAME(alloc_overflow_rax)
675
676 /* This routine handles an overflow with rcx=crfp+size. So the
677 size=rcx-crfp. */
678 .align align_4byte
679 .globl GNAME(alloc_overflow_rcx)
680 .type GNAME(alloc_overflow_rcx),@function
681 GNAME(alloc_overflow_rcx):
682 pushq %rax # Save rax
683 pushq %rdx # Save rdx
684 pushq %rdi
685 pushq %rsi
686 pushq %r8
687 pushq %r9
688 pushq %r10
689 /* Calculate the size for the allocation. */
690 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%rcx
691 movq %rcx, %rdi # Pass arg1
692 call GNAME(alloc)
693 movq %rax, %rcx # setup the destination.
694 popq %r10
695 popq %r9
696 popq %r8
697 popq %rsi
698 popq %rdi
699 popq %rdx # Restore rdx.
700 popq %rax # Restore rax.
701 addq $13,(%rsp) # Adjust the return address to skip the next 2 inst.
702 ret
703 .size GNAME(alloc_overflow_rcx),.-GNAME(alloc_overflow_rcx)
704
705 /* This routine handles an overflow with rdx=crfp+size. So the
706 size=rdx-crfp. */
707 .align align_4byte
708 .globl GNAME(alloc_overflow_rdx)
709 .type GNAME(alloc_overflow_rdx),@function
710 GNAME(alloc_overflow_rdx):
711 pushq %rax # Save rax
712 pushq %rcx # Save rcx
713 pushq %rdi
714 pushq %rsi
715 pushq %r8
716 pushq %r9
717 pushq %r10
718 /* Calculate the size for the allocation. */
719 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%rdx
720 movq %rdx, %rdi # Move the size
721 call GNAME(alloc)
722 movq %rax,%rdx # setup the destination.
723 popq %r10
724 popq %r9
725 popq %r8
726 popq %rsi
727 popq %rdi
728 popq %rcx # Restore rcx.
729 popq %rax # Restore rax.
730 addq $13,(%rsp) # Adjust the return address to skip the next 2 inst.
731 # The next 2 instructions sets the CRFP.
732 ret
733 .size GNAME(alloc_overflow_rdx),.-GNAME(alloc_overflow_rdx)
734
735 /* This routine handles an overflow with rbx=crfp+size. So the
736 size=rbx-crfp. */
737 .align align_4byte
738 .globl GNAME(alloc_overflow_rbx)
739 .type GNAME(alloc_overflow_rbx),@function
740 GNAME(alloc_overflow_rbx):
741 pushq %rax # Save rax
742 pushq %rcx # Save rcx
743 pushq %rdx # Save rdx
744 pushq %rdi
745 pushq %rsi
746 pushq %r8
747 pushq %r9
748 pushq %r10
749 /* Calculate the size for the allocation. */
750 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%rbx
751 movq %rbx, %rdi # Pass arg 1
752 call GNAME(alloc)
753 movq %rax,%rbx # setup the destination.
754 popq %r10
755 popq %r9
756 popq %r8
757 popq %rsi
758 popq %rdi
759 popq %rdx # Restore rdx.
760 popq %rcx # Restore rcx.
761 popq %rax # Restore rax.
762 addq $13,(%rsp) # Adjust the return address to skip the next 2 inst.
763 ret
764 .size GNAME(alloc_overflow_rbx),.-GNAME(alloc_overflow_rbx)
765
766 /* This routine handles an overflow with rsi=crfp+size. So the
767 size=rsi-crfp. */
768 .align align_4byte
769 .globl GNAME(alloc_overflow_rsi)
770 .type GNAME(alloc_overflow_rsi),@function
771 GNAME(alloc_overflow_rsi):
772 pushq %rax # Save rax
773 pushq %rcx # Save rcx
774 pushq %rdx # Save rdx
775 pushq %rdi
776 pushq %r8
777 pushq %r9
778 pushq %r10
779 /* Calculate the size for the allocation. */
780 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%rsi
781 movq %rsi, %rdi # Pass arg 1
782 call GNAME(alloc)
783 movq %rax, %rsi # setup the destination.
784 popq %r10
785 popq %r9
786 popq %r8
787 popq %rdi
788 popq %rdx # Restore rdx.
789 popq %rcx # Restore rcx.
790 popq %rax # Restore rax.
791 addq $13,(%rsp) # Adjust the return address to skip the next 2 inst.
792 ret
793 .size GNAME(alloc_overflow_rsi),.-GNAME(alloc_overflow_rsi)
794
795 /* This routine handles an overflow with rdi=crfp+size. So the
796 size=rdi-crfp. */
797 .align align_4byte
798 .globl GNAME(alloc_overflow_rdi)
799 .type GNAME(alloc_overflow_rdi),@function
800 GNAME(alloc_overflow_rdi):
801 pushq %rax # Save rax
802 pushq %rcx # Save rcx
803 pushq %rdx # Save rdx
804 pushq %rsi
805 pushq %r8
806 pushq %r9
807 pushq %r10
808 /* Calculate the size for the allocation. */
809 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%rdi
810 call GNAME(alloc)
811 movq %rax,%rdi # setup the destination.
812 popq %r10
813 popq %r9
814 popq %r8
815 popq %rsi
816 popq %rdx # Restore rdx.
817 popq %rcx # Restore rcx.
818 popq %rax # Restore rax.
819 addl $13,(%rsp) # Adjust the return address to skip the next inst.
820 ret
821 .size GNAME(alloc_overflow_rdi),.-GNAME(alloc_overflow_rdi)
822
823 /* This routine handles an overflow with r8=crfp+size. So the
824 size=r8-crfp. */
825 .align align_4byte
826 .globl GNAME(alloc_overflow_r8)
827 .type GNAME(alloc_overflow_r8),@function
828 GNAME(alloc_overflow_r8):
829 pushq %rax # Save rax
830 pushq %rcx # Save rcx
831 pushq %rdx # Save rdx
832 pushq %rdi
833 pushq %rsi
834 pushq %r9
835 pushq %r10
836 /* Calculate the size for the allocation. */
837 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%r8
838 movq %r8, %rdi # Pass arg 1
839 call GNAME(alloc)
840 movq %rax,%r8 # setup the destination.
841 popq %r10
842 popq %r9
843 popq %rsi
844 popq %rdi
845 popq %rdx # Restore rdx.
846 popq %rcx # Restore rcx.
847 popq %rax # Restore rax.
848 addl $13,(%rsp) # Adjust the return address to skip the next inst.
849 ret
850 .size GNAME(alloc_overflow_r8),.-GNAME(alloc_overflow_r8)
851
852 /* This routine handles an overflow with r9=crfp+size. So the
853 size=r9-crfp. */
854 .align align_4byte
855 .globl GNAME(alloc_overflow_r9)
856 .type GNAME(alloc_overflow_r9),@function
857 GNAME(alloc_overflow_r9):
858 pushq %rax # Save rax
859 pushq %rcx # Save rcx
860 pushq %rdx # Save rdx
861 pushq %rdi
862 pushq %rsi
863 pushq %r8
864 pushq %r10
865 /* Calculate the size for the allocation. */
866 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%r9
867 movq %r9, %rdi # Pass arg 1
868 call GNAME(alloc)
869 movq %rax,%r9 # setup the destination.
870 popq %r10
871 popq %r8
872 popq %rsi
873 popq %rdi
874 popq %rdx # Restore rdx.
875 popq %rcx # Restore rcx.
876 popq %rax # Restore rax.
877 addl $13,(%rsp) # Adjust the return address to skip the next inst.
878 ret
879 .size GNAME(alloc_overflow_r9),.-GNAME(alloc_overflow_r9)
880
881 /* This routine handles an overflow with r10=crfp+size. So the
882 size=r10-crfp. */
883 .align align_4byte
884 .globl GNAME(alloc_overflow_r10)
885 .type GNAME(alloc_overflow_r10),@function
886 GNAME(alloc_overflow_r10):
887 pushq %rax # Save rax
888 pushq %rcx # Save rcx
889 pushq %rdx # Save rdx
890 pushq %rdi
891 pushq %rsi
892 pushq %r8
893 pushq %r9
894 /* Calculate the size for the allocation. */
895 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%r10
896 movq %r10, %rdi # Pass arg 1
897 call GNAME(alloc)
898 movq %rax,%r10 # setup the destination.
899 popq %r9
900 popq %r8
901 popq %rsi
902 popq %rdi
903 popq %rdx # Restore rdx.
904 popq %rcx # Restore rcx.
905 popq %rax # Restore rax.
906 addl $13,(%rsp) # Adjust the return address to skip the next inst.
907 ret
908 .size GNAME(alloc_overflow_r10),.-GNAME(alloc_overflow_r10)
909
910 /* r11 is used by linkage table */
911
912 /* This routine handles an overflow with r12=crfp+size. So the
913 size=r12-crfp. */
914 .align align_4byte
915 .globl GNAME(alloc_overflow_r12)
916 .type GNAME(alloc_overflow_r12),@function
917 GNAME(alloc_overflow_r12):
918 pushq %rax # Save rax
919 pushq %rcx # Save rcx
920 pushq %rdx # Save rdx
921 pushq %rdi
922 pushq %rsi
923 pushq %r8
924 pushq %r9
925 pushq %r10
926 /* Calculate the size for the allocation. */
927 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%r12
928 movq %r12, %rdi # Pass arg 1
929 call GNAME(alloc)
930 movq %rax,%r12 # setup the destination.
931 popq %r10
932 popq %r9
933 popq %r8
934 popq %rsi
935 popq %rdi
936 popq %rdx # Restore rdx.
937 popq %rcx # Restore rcx.
938 popq %rax # Restore rax.
939 addl $13,(%rsp) # Adjust the return address to skip the next inst.
940 ret
941 .size GNAME(alloc_overflow_r12),.-GNAME(alloc_overflow_r12)
942
943 /* This routine handles an overflow with r13=crfp+size. So the
944 size=r13-crfp. */
945 .align align_4byte
946 .globl GNAME(alloc_overflow_r13)
947 .type GNAME(alloc_overflow_r13),@function
948 GNAME(alloc_overflow_r13):
949 pushq %rax # Save rax
950 pushq %rcx # Save rcx
951 pushq %rdx # Save rdx
952 pushq %rdi
953 pushq %rsi
954 pushq %r8
955 pushq %r9
956 pushq %r10
957 /* Calculate the size for the allocation. */
958 subq CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%r13
959 movq %r13, %rdi # Pass arg 1
960 call GNAME(alloc)
961 movq %rax,%r13 # setup the destination.
962 popq %r10
963 popq %r9
964 popq %r8
965 popq %rsi
966 popq %rdi
967 popq %rdx # Restore rdx.
968 popq %rcx # Restore rcx.
969 popq %rax # Restore rax.
970 addl $13,(%rsp) # Adjust the return address to skip the next inst.
971 ret
972 .size GNAME(alloc_overflow_r13),.-GNAME(alloc_overflow_r13)
973
974 #endif
975
976 #ifdef LINKAGE_TABLE
977
978 /* Call into C code to resolve a linkage entry. The initial code in the
979 * linkage entry has done a call to here; pass that return entry along as a
980 * parameter.
981 *
982 * We could be called from raw Lisp code or from a foreign call site, so we
983 * have to save all the registers...
984 */
985 .align align_4byte
986 .globl GNAME(resolve_linkage_tramp)
987 .type GNAME(resolve_linkage_tramp),@function
988 GNAME(resolve_linkage_tramp):
989 pushq %rbp # save old frame pointer
990 movq %rsp,%rbp # establish new frame
991 pushq %rax
992 # rbx is callee saved
993 pushq %rcx
994 pushq %rdx
995 pushq %rdi
996 pushq %rsi
997 pushq %r8
998 pushq %r9
999 pushq %r10
1000 pushq %r11
1001 # r12-15 is callee saved
1002
1003 /* calling location (plus offset) was on top of stack */
1004 movq 8(%rbp), %rdi # arg 1 for C function
1005 call GNAME(lazy_resolve_linkage)
1006 /* real address of target is in %rax. Replace return address on stack
1007 * with it. That way we can get out of here without trashing any
1008 * registers!
1009 */
1010 movq %rax,8(%rbp)
1011 popq %r11
1012 popq %r10
1013 popq %r9
1014 popq %r8
1015 popq %rsi
1016 popq %rdi
1017 popq %rdx
1018 popq %rcx
1019 popq %rax
1020 popq %rbp
1021 ret # jump to the real target
1022 .size GNAME(resolve_linkage_tramp),.-GNAME(resolve_linkage_tramp)
1023
1024 /*
1025 * The C-callable undefined-foreign-symbol trapping function.
1026 */
1027 .text
1028 .align align_4byte,0x90
1029 .global GNAME(undefined_foreign_symbol_trap)
1030 .type GNAME(undefined_foreign_symbol_trap),@function
1031 GNAME(undefined_foreign_symbol_trap):
1032 /* C Calling Convention, move one arg to RAX */
1033 pushq %rbp
1034 movq %rsp,%rbp
1035 movq %rdi,%rax
1036
1037 /* Now trap to Lisp */
1038 int3
1039 .byte trap_Error
1040 /* Number of argument bytes */
1041 .byte 2
1042 .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
1043 /* SC_OFFSET(sc_DescriptorReg,reg_RAX) */
1044 .byte SC_OFFSET(sc_DescriptorReg,0)
1045
1046 /* C Calling Convention */
1047 /* Doesn't matter here, but could if we'd use trap_Cerror */
1048 leave
1049 ret
1050 .size GNAME(undefined_foreign_symbol_trap), .-GNAME(undefined_foreign_symbol_trap)
1051 .end
1052
1053 #endif /* LINKAGE_TABLE */

  ViewVC Help
Powered by ViewVC 1.1.5