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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.35 - (show annotations)
Wed Dec 22 02:12:52 2010 UTC (3 years, 3 months ago) by rtoy
Branch: MAIN
CVS Tags: GIT-CONVERSION, cross-sol-x86-merged, snapshot-2011-09, snapshot-2011-06, snapshot-2011-07, snapshot-2011-04, snapshot-2011-02, snapshot-2011-03, snapshot-2011-01, HEAD
Changes since 1.34: +39 -22 lines
Merge changes from cross-sol-x86-2010-12-20 which adds support for
Solaris/x86.  There should be no functional changes for either other
x86 ports or for the sparc port.
1 /* ### x86-assem.S -*- Mode: Asm; -*- */
2 /**
3 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/x86-assem.S,v 1.35 2010/12/22 02:12:52 rtoy Exp $
4 *
5 * Authors: Paul F. Werkowski <pw@snoopy.mv.com>
6 * Douglas T. Crosher
7 *
8 * This code was written to support the port of CMU Common Lisp
9 * to the Intel X86 ISA and the FreeBSD operating system. The
10 * author has placed this code in the public domain September 1996.
11 *
12 */
13
14
15 #include "x86-validate.h"
16
17 #define LANGUAGE_ASSEMBLY
18 #include "internals.h"
19 #include "lispregs.h"
20
21 /* Minimize conditionalization for different OS naming schemes */
22 #ifdef DARWIN
23 #define GNAME(var) _##var
24 #define FUNCDEF(x) \
25 .text ; \
26 .align 2,0x90 ; \
27 .globl GNAME(x) ; \
28 GNAME(x): ;
29 #define ENDFUNC(x)
30 #elif defined(SOLARIS)
31 #define GNAME(var) var
32 #define FUNCDEF(x) \
33 .text ; \
34 .align 16,0x90 ; \
35 .globl GNAME(x) ; \
36 .type x,@function ; \
37 GNAME(x): ;
38 #define ENDFUNC(x) \
39 .size GNAME(x),.-GNAME(x)
40 #else
41 #define GNAME(var) var
42 #define FUNCDEF(x) \
43 .text ; \
44 .balign 4,0x90 ; \
45 .globl GNAME(x) ; \
46 .type x,@function ; \
47 GNAME(x): ;
48 #define ENDFUNC(x) \
49 .size GNAME(x),.-GNAME(x)
50 #endif
51
52 #ifdef SOLARIS
53 #define INT3 int $3
54
55 #else
56 #define INT3 int3
57 #endif
58
59 /* Get the right type of alignment. Linux wants alignment in bytes. */
60 #if defined (__linux__) || defined (__FreeBSD__)
61 #define align_16byte 16
62 #else
63 #define align_16byte 4
64 #endif
65
66 .text
67 .globl GNAME(foreign_function_call_active)
68
69
70 /*
71 * The C function will preserve ebx, esi, edi, and ebp across its
72 * function call - ebx is used to save the return lisp address.
73 *
74 * Return values are in eax and maybe edx for quads, or st(0) for
75 * floats.
76 *
77 * It should work for lisp calls C calls lisp calls C ..
78 */
79 FUNCDEF(call_into_c)
80 movl $1,GNAME(foreign_function_call_active)
81
82 /* Save the return lisp address in ebx */
83 popl %ebx
84
85 /* Setup the NPX for C */
86 fstp %st(0)
87 fstp %st(0)
88 fstp %st(0)
89 fstp %st(0)
90 fstp %st(0)
91 fstp %st(0)
92 fstp %st(0)
93 fstp %st(0)
94 call *%eax # normal callout using Lisp stack
95
96 movl %eax,%ecx # remember integer return value
97
98 /* Check for a return FP value */
99 fxam
100 fnstsw %ax
101 andl $0x4500,%eax
102 cmpl $0x4100,%eax
103 jne Lfp_rtn_value
104
105 /* The return value is in eax, or eax,edx? */
106 /* Setup the NPX stack for lisp */
107 fldz # insure no regs are empty
108 fldz
109 fldz
110 fldz
111 fldz
112 fldz
113 fldz
114 fldz
115 no_fldz:
116 /* Restore the return value */
117 movl %ecx,%eax # maybe return value
118
119 movl $0,GNAME(foreign_function_call_active)
120 /* Return */
121 jmp *%ebx
122
123 Lfp_rtn_value:
124 /* The return result is in st(0) */
125 /* Setup the NPX stack for lisp, placing the result in st(0) */
126 fldz # insure no regs are empty
127 fldz
128 fldz
129 fldz
130 fldz
131 fldz
132 fldz
133 fxch %st(7) # move the result back to st(0)
134
135 /* Don't need to restore eax as the result is in st(0) */
136
137 movl $0,GNAME(foreign_function_call_active)
138 /* Return */
139 jmp *%ebx
140 ENDFUNC(call_into_c)
141
142
143
144 /* The C conventions require that ebx, esi, edi, and ebp be preserved
145 across function calls. */
146 /* The *alien-stack* pointer is setup on the first call_into_lisp when
147 the stack changes. */
148 FUNCDEF(call_into_lisp)
149 pushl %ebp # save old frame pointer
150 movl %esp,%ebp # establish new frame
151
152 /* Save the NPX state */
153 fwait # Catch any pending NPX exceptions.
154 /* Save the SSE2 for X87 state */
155 mov GNAME(fpu_mode), %eax
156 cmp $2, %eax # SSE2 mode?
157 jne x87_save
158 movl %esp, %eax # Remember the current stack pointer
159 subl $512,%esp # Make room for the SSE state
160 andl $-16, %esp # fxsave needs 16-byte alignment
161 fxsave (%esp)
162 pushl %eax # Save the old stack pointer
163 fninit # Reset fpu, just in case
164 jmp npx_save_done
165
166 x87_save:
167 subl $108,%esp # Make room for the NPX state.
168 fnsave (%esp) # Resets NPX
169
170 movl (%esp),%eax # Load NPX control word
171 andl $0xfffff3ff,%eax # Set rounding mode to nearest
172 #ifdef type_LongFloat
173 orl $0x00000300,%eax # Set precision to 64 bits
174 #else
175 orl $0x00000200,%eax # Set precision to 53 bits
176 #endif
177 pushl %eax
178 fldcw (%esp) # Recover modes
179 popl %eax
180 npx_save_done:
181
182 fldz # insure no FP regs are empty
183 fldz
184 fldz
185 fldz
186 fldz
187 fldz
188 fldz
189 fldz
190
191 /* Save C regs: ebx esi edi */
192 pushl %ebx
193 pushl %esi
194 pushl %edi
195
196 /* clear descriptor regs */
197 xorl %eax,%eax # lexenv
198 xorl %ebx,%ebx # available
199 xorl %ecx,%ecx # arg count
200 xorl %edx,%edx # first arg
201 xorl %edi,%edi # second arg
202 xorl %esi,%esi # third arg
203
204 /* no longer in function call */
205 movl %eax, GNAME(foreign_function_call_active)
206
207 movl %esp,%ebx # remember current stack
208 cmpl $CONTROL_STACK_START,%esp
209 jbe ChangeToLispStack
210 cmpl $CONTROL_STACK_END,%esp
211 jbe OnLispStack
212 ChangeToLispStack:
213 /* Setup the *alien-stack* pointer */
214 movl %esp,ALIEN_STACK + SYMBOL_VALUE_OFFSET
215 movl $CONTROL_STACK_END,%esp # New stack
216 OnLispStack:
217 pushl %ebx # save entry stack on (maybe) new stack
218
219 /* establish lisp args */
220 movl 8(%ebp),%eax # lexenv?
221 movl 12(%ebp),%ebx # address of arg vec
222 movl 16(%ebp),%ecx # num args
223 shll $2,%ecx # make into fixnum
224 cmpl $0,%ecx
225 je Ldone
226 movl (%ebx),%edx # arg0
227 cmpl $4,%ecx
228 je Ldone
229 movl 4(%ebx),%edi # arg1
230 cmpl $8,%ecx
231 je Ldone
232 movl 8(%ebx),%esi # arg2
233 Ldone:
234 /* Registers eax, ecx, edx,edi,esi now live */
235
236 /* Allocate new frame */
237 mov %esp,%ebx # current sp marks start of new frame
238 push %ebp # fp in save location S0
239 sub $8,%esp # Ensure 3 slots are allocated, one above.
240 mov %ebx,%ebp # switch to new frame
241
242 /* Indirect the closure */
243 call *CLOSURE_FUNCTION_OFFSET(%eax)
244
245 /* Multi-value return - blow off any extra values */
246 mov %ebx, %esp
247 /* Single value return */
248
249 /* Restore the stack, in case there was a stack change. */
250 popl %esp # c-sp
251
252 /* Restore C regs: ebx esi edi */
253 popl %edi
254 popl %esi
255 popl %ebx
256
257 /* Restore the NPX state */
258 /* Restore SSE2 state? */
259 mov GNAME(fpu_mode), %eax
260 cmp $2, %eax # SSE2 mode?
261 jne x87_restore
262 popl %eax # Get the old stack pointer
263 fxrstor (%esp) # Restore the SSE state
264 movl %eax, %esp # Now really restore the old stack pointer
265 jmp npx_restore_done
266 x87_restore:
267 frstor (%esp)
268 addl $108, %esp
269 npx_restore_done:
270
271 popl %ebp # c-sp
272 movl %edx,%eax # c-val
273 ret
274 ENDFUNC(call_into_lisp)
275
276 /* Support for saving and restoring the NPX state from C. */
277 FUNCDEF(fpu_save)
278 movl 4(%esp),%eax
279 fnsave (%eax) # Save the NPX state - Resets NPX
280 ret
281 ENDFUNC(fpu_save)
282
283 FUNCDEF(fpu_restore)
284 movl 4(%esp),%eax
285 frstor (%eax) # Restore the NPX state.
286 ret
287 ENDFUNC(fpu_restore)
288
289 FUNCDEF(sse_save)
290 movl 4(%esp),%eax
291 addl $16, %eax # Make sure eax is on a 16-byte boundary
292 and $-16, %eax
293 fxsave (%eax)
294 ret
295 ENDFUNC(sse_save)
296
297 FUNCDEF(sse_restore)
298 movl 4(%esp),%eax
299 addl $16, %eax # Make sure eax is on a 16-byte boundary
300 and $-16, %eax
301 fxrstor (%eax)
302 ret
303 ENDFUNC(sse_restore)
304
305
306 #if 0
307 /*
308 * These are now implemented as Lisp assembly routines. We leave
309 * these here for the time being until we're sure the assembly
310 * routines are working as expected.
311 */
312
313 /*
314 * The undefined-function trampoline.
315 */
316 FUNCDEF(undefined_tramp)
317 INT3
318 .byte trap_Error
319 /* Number of argument bytes */
320 .byte 2
321 .byte UNDEFINED_SYMBOL_ERROR
322 /* SC_OFFSET(sc_DescriptorReg,reg_EAX) */
323 .byte SC_OFFSET(sc_DescriptorReg,0)
324 ret
325 ENDFUNC(undefined_tramp)
326
327 /*
328 * The closure trampoline.
329 */
330 FUNCDEF(closure_tramp)
331 movl FDEFN_FUNCTION_OFFSET(%eax),%eax
332 jmp *CLOSURE_FUNCTION_OFFSET(%eax)
333 ENDFUNC(closure_tramp)
334
335 #endif
336
337 /*
338 * Function-end breakpoint magic.
339 */
340 FUNCDEF(function_end_breakpoint_guts)
341 /* Multiple Value return
342 This MUST be a two-byte instruction. If it isn't tracing is
343 majorly broken. */
344 jmp 1f
345 /* Single value return: The eventual return will now use the
346 multiple values return convention but with a return values
347 count of one. */
348 movl %esp,%ebx # Setup ebx - the ofp.
349 subl $4,%esp # Allocate one stack slot for the return value
350 movl $4,%ecx # Setup ecx for one return value.
351 movl $NIL,%edi # Default second value
352 movl $NIL,%esi # Default third value
353
354 1:
355 multiple_value_return:
356
357 .globl GNAME(function_end_breakpoint_trap)
358 GNAME(function_end_breakpoint_trap):
359 INT3
360 .byte trap_FunctionEndBreakpoint
361 hlt # Should never return here.
362
363 .globl GNAME(function_end_breakpoint_end)
364 GNAME(function_end_breakpoint_end):
365
366
367 FUNCDEF(do_pending_interrupt)
368 INT3
369 .byte trap_PendingInterrupt
370 ret
371 ENDFUNC(do_pending_interrupt)
372
373 #ifdef trap_DynamicSpaceOverflowError
374 FUNCDEF(do_dynamic_space_overflow_error)
375 INT3
376 .byte trap_DynamicSpaceOverflowError
377 ret
378 ENDFUNC(do_dynamic_space_overflow_error)
379 #endif
380
381 #ifdef trap_DynamicSpaceOverflowWarning
382 FUNCDEF(do_dynamic_space_overflow_warning)
383 INT3
384 .byte trap_DynamicSpaceOverflowWarning
385 ret
386 ENDFUNC(do_dynamic_space_overflow_warning)
387 #endif
388
389
390 #ifdef WANT_CGC
391 /* A copy function optimized for the Pentium and works ok on
392 * 486 as well. This assumes (does not check) that the input
393 * byte count is a multiple of 8-bytes (one lisp object).
394 * This code takes advantage of pairing in the Pentium as well
395 * as the 128-bit cache line.
396 */
397 FUNCDEF(fastcopy16)
398 pushl %ebp
399 movl %esp,%ebp
400 movl 8(%ebp), %edx # dst
401 movl 12(%ebp),%eax # src
402 movl 16(%ebp),%ecx # bytes
403 pushl %ebx
404 pushl %esi
405 pushl %edi
406 movl %edx,%edi
407 movl %eax,%esi
408 sarl $3,%ecx # number 8-byte units
409 testl $1,%ecx # odd?
410 jz Lquad
411 movl (%esi),%eax
412 movl 4(%esi),%ebx
413 movl %eax,(%edi)
414 movl %ebx,4(%edi)
415 leal 8(%esi),%esi
416 leal 8(%edi),%edi
417 Lquad: sarl $1,%ecx # count 16-byte units
418 jz Lend
419 movl %ecx,%ebp # use ebp for loop counter
420 .align align_16byte,0x90
421 Ltop:
422 movl (%edi),%eax #prefetch! MAJOR Pentium win.
423 movl (%esi),%eax
424 movl 4(%esi),%ebx
425 movl 8(%esi),%ecx
426 movl 12(%esi),%edx
427 movl %eax, (%edi)
428 movl %ebx, 4(%edi)
429 movl %ecx, 8(%edi)
430 movl %edx,12(%edi)
431 leal 16(%esi),%esi
432 leal 16(%edi),%edi
433 decl %ebp
434 jnz Ltop # non-prefixed jump saves cycles
435 Lend:
436 popl %edi
437 popl %esi
438 popl %ebx
439 popl %ebp
440 ret
441 ENDFUNC(fastcopy16)
442 #endif
443
444
445 /*
446 Allocate bytes and return the start of the allocated space
447 in the specified destination register.
448
449 In the general case the size will be in the destination register.
450
451 All registers must be preserved except the destination.
452 The C conventions will preserve ebx, esi, edi, and ebp.
453 So only eax, ecx, and edx need special care here. */
454
455 FUNCDEF(alloc_to_eax)
456 pushl %ecx # Save ecx and edx as C could destroy them.
457 pushl %edx
458 pushl %eax # Push the size
459 call GNAME(alloc)
460 addl $4,%esp # pop the size arg.
461 popl %edx # Restore ecx and edx.
462 popl %ecx
463 ret
464 ENDFUNC(alloc_to_eax)
465
466 FUNCDEF(alloc_8_to_eax)
467 pushl %ecx # Save ecx and edx as C could destroy them.
468 pushl %edx
469 pushl $8 # Push the size
470 call GNAME(alloc)
471 addl $4,%esp # pop the size arg.
472 popl %edx # Restore ecx and edx.
473 popl %ecx
474 ret
475 ENDFUNC(alloc_8_to_eax)
476
477 FUNCDEF(alloc_16_to_eax)
478 pushl %ecx # Save ecx and edx as C could destroy them.
479 pushl %edx
480 pushl $16 # Push the size
481 call GNAME(alloc)
482 addl $4,%esp # pop the size arg.
483 popl %edx # Restore ecx and edx.
484 popl %ecx
485 ret
486 ENDFUNC(alloc_16_to_eax)
487
488 FUNCDEF(alloc_to_ecx)
489 pushl %eax # Save eax and edx as C could destroy them.
490 pushl %edx
491 pushl %ecx # Push the size
492 call GNAME(alloc)
493 addl $4,%esp # pop the size arg.
494 movl %eax,%ecx # setup the destination.
495 popl %edx # Restore eax and edx.
496 popl %eax
497 ret
498 ENDFUNC(alloc_to_ecx)
499
500 FUNCDEF(alloc_8_to_ecx)
501 pushl %eax # Save eax and edx as C could destroy them.
502 pushl %edx
503 pushl $8 # Push the size
504 call GNAME(alloc)
505 addl $4,%esp # pop the size arg.
506 movl %eax,%ecx # setup the destination.
507 popl %edx # Restore eax and edx.
508 popl %eax
509 ret
510 ENDFUNC(alloc_8_to_ecx)
511
512 FUNCDEF(alloc_16_to_ecx)
513 pushl %eax # Save eax and edx as C could destroy them.
514 pushl %edx
515 pushl $16 # Push the size
516 call GNAME(alloc)
517 addl $4,%esp # pop the size arg.
518 movl %eax,%ecx # setup the destination.
519 popl %edx # Restore eax and edx.
520 popl %eax
521 ret
522 ENDFUNC(alloc_16_to_ecx)
523
524 FUNCDEF(alloc_to_edx)
525 pushl %eax # Save eax and ecx as C could destroy them.
526 pushl %ecx
527 pushl %edx # Push the size
528 call GNAME(alloc)
529 addl $4,%esp # pop the size arg.
530 movl %eax,%edx # setup the destination.
531 popl %ecx # Restore eax and ecx.
532 popl %eax
533 ret
534 ENDFUNC(alloc_to_edx)
535
536 FUNCDEF(alloc_8_to_edx)
537 pushl %eax # Save eax and ecx as C could destroy them.
538 pushl %ecx
539 pushl $8 # Push the size
540 call GNAME(alloc)
541 addl $4,%esp # pop the size arg.
542 movl %eax,%edx # setup the destination.
543 popl %ecx # Restore eax and ecx.
544 popl %eax
545 ret
546 ENDFUNC(alloc_8_to_edx)
547
548 FUNCDEF(alloc_16_to_edx)
549 pushl %eax # Save eax and ecx as C could destroy them.
550 pushl %ecx
551 pushl $16 # Push the size
552 call GNAME(alloc)
553 addl $4,%esp # pop the size arg.
554 movl %eax,%edx # setup the destination.
555 popl %ecx # Restore eax and ecx.
556 popl %eax
557 ret
558 ENDFUNC(alloc_16_to_edx)
559
560 FUNCDEF(alloc_to_ebx)
561 pushl %eax # Save eax, ecx, and edx as C could destroy them.
562 pushl %ecx
563 pushl %edx
564 pushl %ebx # Push the size
565 call GNAME(alloc)
566 addl $4,%esp # pop the size arg.
567 movl %eax,%ebx # setup the destination.
568 popl %edx # Restore eax, ecx and edx.
569 popl %ecx
570 popl %eax
571 ret
572 ENDFUNC(alloc_to_ebx)
573
574 FUNCDEF(alloc_8_to_ebx)
575 pushl %eax # Save eax, ecx, and edx as C could destroy them.
576 pushl %ecx
577 pushl %edx
578 pushl $8 # Push the size
579 call GNAME(alloc)
580 addl $4,%esp # pop the size arg.
581 movl %eax,%ebx # setup the destination.
582 popl %edx # Restore eax, ecx and edx.
583 popl %ecx
584 popl %eax
585 ret
586 ENDFUNC(alloc_8_to_ebx)
587
588 FUNCDEF(alloc_16_to_ebx)
589 pushl %eax # Save eax, ecx, and edx as C could destroy them.
590 pushl %ecx
591 pushl %edx
592 pushl $16 # Push the size
593 call GNAME(alloc)
594 addl $4,%esp # pop the size arg.
595 movl %eax,%ebx # setup the destination.
596 popl %edx # Restore eax, ecx and edx.
597 popl %ecx
598 popl %eax
599 ret
600 ENDFUNC(alloc_16_to_ebx)
601
602 FUNCDEF(alloc_to_esi)
603 pushl %eax # Save eax, ecx, and edx as C could destroy them.
604 pushl %ecx
605 pushl %edx
606 pushl %esi # Push the size
607 call GNAME(alloc)
608 addl $4,%esp # pop the size arg.
609 movl %eax,%esi # setup the destination.
610 popl %edx # Restore eax, ecx and edx.
611 popl %ecx
612 popl %eax
613 ret
614 ENDFUNC(alloc_to_esi)
615
616 FUNCDEF(alloc_8_to_esi)
617 pushl %eax # Save eax, ecx, and edx as C could destroy them.
618 pushl %ecx
619 pushl %edx
620 pushl $8 # Push the size
621 call GNAME(alloc)
622 addl $4,%esp # pop the size arg.
623 movl %eax,%esi # setup the destination.
624 popl %edx # Restore eax, ecx and edx.
625 popl %ecx
626 popl %eax
627 ret
628 ENDFUNC(alloc_8_to_esi)
629
630 FUNCDEF(alloc_16_to_esi)
631 pushl %eax # Save eax, ecx, and edx as C could destroy them.
632 pushl %ecx
633 pushl %edx
634 pushl $16 # Push the size
635 call GNAME(alloc)
636 addl $4,%esp # pop the size arg.
637 movl %eax,%esi # setup the destination.
638 popl %edx # Restore eax, ecx and edx.
639 popl %ecx
640 popl %eax
641 ret
642 ENDFUNC(alloc_16_to_esi)
643
644 FUNCDEF(alloc_to_edi)
645 pushl %eax # Save eax, ecx, and edx as C could destroy them.
646 pushl %ecx
647 pushl %edx
648 pushl %edi # Push the size
649 call GNAME(alloc)
650 addl $4,%esp # pop the size arg.
651 movl %eax,%edi # setup the destination.
652 popl %edx # Restore eax, ecx and edx.
653 popl %ecx
654 popl %eax
655 ret
656 ENDFUNC(alloc_to_edi)
657
658 FUNCDEF(alloc_8_to_edi)
659 pushl %eax # Save eax, ecx, and edx as C could destroy them.
660 pushl %ecx
661 pushl %edx
662 pushl $8 # Push the size
663 call GNAME(alloc)
664 addl $4,%esp # pop the size arg.
665 movl %eax,%edi # setup the destination.
666 popl %edx # Restore eax, ecx and edx.
667 popl %ecx
668 popl %eax
669 ret
670 ENDFUNC(alloc_8_to_edi)
671
672 FUNCDEF(alloc_16_to_edi)
673 pushl %eax # Save eax, ecx, and edx as C could destroy them.
674 pushl %ecx
675 pushl %edx
676 pushl $16 # Push the size
677 call GNAME(alloc)
678 addl $4,%esp # pop the size arg.
679 movl %eax,%edi # setup the destination.
680 popl %edx # Restore eax, ecx and edx.
681 popl %ecx
682 popl %eax
683 ret
684 ENDFUNC(alloc_16_to_edi)
685
686
687 #ifdef GENCGC
688
689 /* Called from lisp when an inline allocation overflows.
690 Every register except the result needs to be preserved.
691 We depend on C to preserve ebx, esi, edi, and ebp.
692 But where necessary must save eax, ecx, edx. */
693
694 /* This routine handles an overflow with eax=crfp+size. So the
695 size=eax-crfp. */
696 FUNCDEF(alloc_overflow_eax)
697 pushl %ecx # Save ecx
698 pushl %edx # Save edx
699 /* Calculate the size for the allocation. */
700 subl CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%eax
701 pushl %eax # Push the size
702 call GNAME(alloc)
703 addl $4,%esp # pop the size arg.
704 popl %edx # Restore edx.
705 popl %ecx # Restore ecx.
706 addl $6,(%esp) # Adjust the return address to skip the next inst.
707 ret
708 ENDFUNC(alloc_overflow_eax)
709
710 /* This routine handles an overflow with ecx=crfp+size. So the
711 size=ecx-crfp. */
712 FUNCDEF(alloc_overflow_ecx)
713 pushl %eax # Save eax
714 pushl %edx # Save edx
715 /* Calculate the size for the allocation. */
716 subl CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%ecx
717 pushl %ecx # Push the size
718 call GNAME(alloc)
719 addl $4,%esp # pop the size arg.
720 movl %eax,%ecx # setup the destination.
721 popl %edx # Restore edx.
722 popl %eax # Restore eax.
723 addl $6,(%esp) # Adjust the return address to skip the next inst.
724 ret
725 ENDFUNC(alloc_overflow_ecx)
726
727 /* This routine handles an overflow with edx=crfp+size. So the
728 size=edx-crfp. */
729 FUNCDEF(alloc_overflow_edx)
730 pushl %eax # Save eax
731 pushl %ecx # Save ecx
732 /* Calculate the size for the allocation. */
733 subl CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%edx
734 pushl %edx # Push the size
735 call GNAME(alloc)
736 addl $4,%esp # pop the size arg.
737 movl %eax,%edx # setup the destination.
738 popl %ecx # Restore ecx.
739 popl %eax # Restore eax.
740 addl $6,(%esp) # Adjust the return address to skip the next inst.
741 ret
742 ENDFUNC(alloc_overflow_edx)
743
744 /* This routine handles an overflow with ebx=crfp+size. So the
745 size=ebx-crfp. */
746 FUNCDEF(alloc_overflow_ebx)
747 pushl %eax # Save eax
748 pushl %ecx # Save ecx
749 pushl %edx # Save edx
750 /* Calculate the size for the allocation. */
751 subl CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%ebx
752 pushl %ebx # Push the size
753 call GNAME(alloc)
754 addl $4,%esp # pop the size arg.
755 movl %eax,%ebx # setup the destination.
756 popl %edx # Restore edx.
757 popl %ecx # Restore ecx.
758 popl %eax # Restore eax.
759 addl $6,(%esp) # Adjust the return address to skip the next inst.
760 ret
761 ENDFUNC(alloc_overflow_ebx)
762
763 /* This routine handles an overflow with esi=crfp+size. So the
764 size=esi-crfp. */
765 FUNCDEF(alloc_overflow_esi)
766 pushl %eax # Save eax
767 pushl %ecx # Save ecx
768 pushl %edx # Save edx
769 /* Calculate the size for the allocation. */
770 subl CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%esi
771 pushl %esi # Push the size
772 call GNAME(alloc)
773 addl $4,%esp # pop the size arg.
774 movl %eax,%esi # setup the destination.
775 popl %edx # Restore edx.
776 popl %ecx # Restore ecx.
777 popl %eax # Restore eax.
778 addl $6,(%esp) # Adjust the return address to skip the next inst.
779 ret
780 ENDFUNC(alloc_overflow_esi)
781
782 /* This routine handles an overflow with edi=crfp+size. So the
783 size=edi-crfp. */
784 FUNCDEF(alloc_overflow_edi)
785 pushl %eax # Save eax
786 pushl %ecx # Save ecx
787 pushl %edx # Save edx
788 /* Calculate the size for the allocation. */
789 subl CURRENT_REGION_FREE_POINTER + SYMBOL_VALUE_OFFSET,%edi
790 pushl %edi # Push the size
791 call GNAME(alloc)
792 addl $4,%esp # pop the size arg.
793 movl %eax,%edi # setup the destination.
794 popl %edx # Restore edx.
795 popl %ecx # Restore ecx.
796 popl %eax # Restore eax.
797 addl $6,(%esp) # Adjust the return address to skip the next inst.
798 ret
799 ENDFUNC(alloc_overflow_edi)
800
801 #endif
802
803 #ifdef LINKAGE_TABLE
804
805 /* Call into C code to resolve a linkage entry. The initial code in the
806 * linkage entry has done a call to here; pass that return entry along as a
807 * parameter.
808 *
809 * We could be called from raw Lisp code or from a foreign call site, so we
810 * have to save all the registers...
811 */
812 FUNCDEF(resolve_linkage_tramp)
813 pushl %ebp # save old frame pointer
814 movl %esp,%ebp # establish new frame
815 subl $28, %esp
816 andl $-16, %esp
817 movl %eax, 24(%esp)
818 movl %ecx, 20(%esp)
819 movl %edx, 16(%esp)
820 movl %ebx, 12(%esp)
821 movl %esi, 8(%esp)
822 movl %edi, 4(%esp)
823 /* calling location (plus offset) was on top of stack */
824 movl 4(%ebp), %eax
825 movl %eax, (%esp) # push for C function
826 call GNAME(lazy_resolve_linkage)
827 /* real address of target is in %eax. Replace return address on stack
828 * with it. That way we can get out of here without trashing any
829 *registers!
830 */
831 movl %eax,4(%ebp)
832 movl 4(%esp), %edi
833 movl 8(%esp), %esi
834 movl 12(%esp), %ebx
835 movl 16(%esp), %edx
836 movl 20(%esp), %ecx
837 movl 24(%esp), %eax
838 leave
839 ret # jump to the real target
840 ENDFUNC(resolve_linkage_tramp)
841
842 /*
843 * The C-callable undefined-foreign-symbol trapping function.
844 */
845 FUNCDEF(undefined_foreign_symbol_trap)
846 /* C Calling Convention, move one arg to EAX */
847 pushl %ebp
848 movl %esp,%ebp
849 movl 8(%ebp),%eax
850
851 /* Now trap to Lisp */
852 INT3
853 .byte trap_Error
854 /* Number of argument bytes */
855 .byte 2
856 .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
857 /* SC_OFFSET(sc_DescriptorReg,reg_EAX) */
858 .byte SC_OFFSET(sc_DescriptorReg,0)
859
860 /* C Calling Convention */
861 /* Doesn't matter here, but could if we'd use trap_Cerror */
862 leave
863 ret
864 ENDFUNC(undefined_foreign_symbol_trap)
865
866 #endif /* LINKAGE_TABLE */

  ViewVC Help
Powered by ViewVC 1.1.5