0.8.9.29:
[sbcl.git] / src / runtime / x86-assem.S
1 /*
2  * very-low-level utilities for runtime support
3  */
4
5 /*
6  * This software is part of the SBCL system. See the README file for
7  * more information.
8  *
9  * This software is derived from the CMU CL system, which was
10  * written at Carnegie Mellon University and released into the
11  * public domain. The software is in the public domain and is
12  * provided with absolutely no warranty. See the COPYING and CREDITS
13  * files for more information.
14  */
15 \f
16 #define LANGUAGE_ASSEMBLY
17 #include "validate.h"
18 #include "sbcl.h"
19 #include "genesis/closure.h"
20 #include "genesis/fdefn.h"
21 #include "genesis/static-symbols.h"
22 #include "genesis/symbol.h"
23 #include "genesis/thread.h"
24         
25 /* Minimize conditionalization for different OS naming schemes. */
26 #if defined __linux__  || defined __FreeBSD__ || defined __NetBSD__ /* (but *not* OpenBSD) */
27 #define GNAME(var) var
28 #else
29 #define GNAME(var) _##var
30 #endif
31
32 /* Get the right type of alignment. Linux, FreeBSD and NetBSD (but not OpenBSD)
33  * want alignment in bytes. */
34 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
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         .global GNAME(all_threads)
47         
48 \f
49 /*
50  * A call to call_into_c preserves esi, edi, and ebp.   
51  * (The C function will preserve ebx, esi, edi, and ebp across its
52  * function call, but we trash ebx ourselves by using it to save the
53  * return Lisp address.)
54  *
55  * Return values are in eax and maybe edx for quads, or st(0) for
56  * floats.
57  *
58  * This should work for Lisp calls C calls Lisp calls C..
59  */
60         .text
61         .align  align_16byte,0x90
62         .global GNAME(call_into_c)
63         .type   GNAME(call_into_c),@function
64 GNAME(call_into_c):
65         movl    $1,GNAME(foreign_function_call_active)
66
67 /* Save the return Lisp address in ebx. */
68         popl    %ebx
69
70 /* Setup the NPX for C */
71         fstp    %st(0)
72         fstp    %st(0)
73         fstp    %st(0)
74         fstp    %st(0)
75         fstp    %st(0)
76         fstp    %st(0)
77         fstp    %st(0)
78         fstp    %st(0)
79
80         call    *%eax           # normal callout using Lisp stack
81
82         movl    %eax,%ecx       # remember integer return value
83
84 /* Check for a return FP value. */
85         fxam
86         fnstsw  %eax
87         andl    $0x4500,%eax
88         cmpl    $0x4100,%eax
89         jne     Lfp_rtn_value
90
91 /* The return value is in eax, or eax,edx? */
92 /* Set up the NPX stack for Lisp. */
93         fldz                    # Ensure no regs are empty.
94         fldz
95         fldz
96         fldz
97         fldz
98         fldz
99         fldz
100         fldz
101
102 /* Restore the return value. */
103         movl    %ecx,%eax       # maybe return value
104
105         movl    $0,GNAME(foreign_function_call_active)
106 /* Return. */
107         jmp     *%ebx
108
109 Lfp_rtn_value:
110 /* The return result is in st(0). */
111 /* Set up the NPX stack for Lisp, placing the result in st(0). */
112         fldz                    # Ensure no regs are empty.
113         fldz
114         fldz
115         fldz
116         fldz
117         fldz
118         fldz
119         fxch    %st(7)          # Move the result back to st(0).
120
121 /* We don't need to restore eax, because the result is in st(0). */
122
123         movl    $0,GNAME(foreign_function_call_active)
124 /* Return. */   
125         jmp     *%ebx
126
127         .size   GNAME(call_into_c), . - GNAME(call_into_c)
128
129 \f
130         .text   
131         .global GNAME(call_into_lisp_first_time)
132         .type  GNAME(call_into_lisp_first_time),@function
133                 
134 /* The *ALIEN-STACK* pointer is set up on the first call_into_lisp when
135  * the stack changes.  We don't worry too much about saving registers 
136  * here, because we never expect to return from the initial call to lisp 
137  * anyway */
138         
139         .align  align_16byte,0x90
140 GNAME(call_into_lisp_first_time):
141         pushl   %ebp            # Save old frame pointer.
142         movl    %esp,%ebp       # Establish new frame.
143         movl    %esp,ALIEN_STACK + SYMBOL_VALUE_OFFSET
144         movl    GNAME(all_threads),%eax
145         movl    THREAD_CONTROL_STACK_START_OFFSET(%eax) ,%esp
146         /* don't think too hard about what happens if we get interrupted
147         * here */
148         addl    $THREAD_CONTROL_STACK_SIZE-4,%esp
149         jmp     Lstack
150 \f
151         .text   
152         .global GNAME(call_into_lisp)
153         .type  GNAME(call_into_lisp),@function
154                 
155 /* The C conventions require that ebx, esi, edi, and ebp be preserved
156  * across function calls. */
157         
158         .align  align_16byte,0x90
159 GNAME(call_into_lisp):
160         pushl   %ebp            # Save old frame pointer.
161         movl    %esp,%ebp       # Establish new frame.
162 Lstack:
163 /* Save the NPX state */
164         fwait                   # Catch any pending NPX exceptions.
165         subl    $108,%esp       # Make room for the NPX state.
166         fnsave  (%esp)          # save and reset NPX
167
168         movl    (%esp),%eax     # Load NPX control word.
169         andl    $0xfffff3ff,%eax        # Set rounding mode to nearest.
170         orl     $0x00000300,%eax        # Set precision to 64 bits.
171         pushl   %eax
172         fldcw   (%esp)          # Recover modes.
173         popl    %eax
174
175         fldz                    # Ensure no FP regs are empty.
176         fldz
177         fldz
178         fldz
179         fldz
180         fldz
181         fldz
182         fldz
183         
184 /* Save C regs: ebx esi edi. */
185         pushl   %ebx
186         pushl   %esi
187         pushl   %edi
188         
189 /* Clear descriptor regs. */
190         xorl    %eax,%eax       # lexenv
191         xorl    %ebx,%ebx       # available
192         xorl    %ecx,%ecx       # arg count
193         xorl    %edx,%edx       # first arg
194         xorl    %edi,%edi       # second arg
195         xorl    %esi,%esi       # third arg
196
197 /* no longer in function call */
198         movl    %eax, GNAME(foreign_function_call_active)
199
200         movl    %esp,%ebx       # remember current stack
201         pushl   %ebx            # Save entry stack on (maybe) new stack.
202
203         /* Establish Lisp args. */
204         movl     8(%ebp),%eax   # lexenv?
205         movl    12(%ebp),%ebx   # address of arg vec
206         movl    16(%ebp),%ecx   # num args
207         shll    $2,%ecx         # Make num args into fixnum.
208         cmpl    $0,%ecx
209         je      Ldone
210         movl    (%ebx),%edx     # arg0
211         cmpl    $4,%ecx
212         je      Ldone
213         movl    4(%ebx),%edi    # arg1
214         cmpl    $8,%ecx
215         je      Ldone
216         movl    8(%ebx),%esi    # arg2
217 Ldone:  
218         /* Registers eax, ecx, edx, edi, and esi are now live. */
219
220         /* Alloc new frame. */
221         mov     %esp,%ebx       # The current sp marks start of new frame.
222         push    %ebp            # fp in save location S0
223         sub     $8,%esp         # Ensure 3 slots are allocated, one above.
224         mov     %ebx,%ebp       # Switch to new frame.
225
226         call    *CLOSURE_FUN_OFFSET(%eax)
227         
228         /* If the function returned multiple values, it will return to
229            this point.  Lose them */
230         mov     %ebx, %esp
231         /* A singled value function returns here */
232
233 /* Restore the stack, in case there was a stack change. */
234         popl    %esp            # c-sp
235
236 /* Restore C regs: ebx esi edi. */
237         popl    %edi
238         popl    %esi
239         popl    %ebx
240
241 /* Restore the NPX state. */
242         frstor  (%esp)
243         addl    $108, %esp
244         
245         popl    %ebp            # c-sp
246         movl    %edx,%eax       # c-val
247         ret
248         .size   GNAME(call_into_lisp), . - GNAME(call_into_lisp)
249 \f
250 /* support for saving and restoring the NPX state from C */
251         .text
252         .global GNAME(fpu_save)
253         .type   GNAME(fpu_save),@function
254         .align  2,0x90
255 GNAME(fpu_save):
256         movl    4(%esp),%eax
257         fnsave  (%eax)          # Save the NPX state. (resets NPX)
258         ret
259         .size   GNAME(fpu_save),.-GNAME(fpu_save)
260
261         .global GNAME(fpu_restore)
262         .type   GNAME(fpu_restore),@function
263         .align  2,0x90
264 GNAME(fpu_restore):
265         movl    4(%esp),%eax
266         frstor  (%eax)          # Restore the NPX state.
267         ret
268         .size   GNAME(fpu_restore),.-GNAME(fpu_restore)
269 \f
270 /*
271  * the undefined-function trampoline
272  */
273         .text
274         .align  align_4byte,0x90
275         .global GNAME(undefined_tramp)
276         .type   GNAME(undefined_tramp),@function
277 GNAME(undefined_tramp):
278         int3
279         .byte   trap_Error
280         .byte   2
281         .byte   UNDEFINED_FUN_ERROR
282         .byte   sc_DescriptorReg # eax in the Descriptor-reg SC
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         movl    FDEFN_FUN_OFFSET(%eax),%eax
295         /* FIXME: The '*' after "jmp" in the next line is from PVE's
296          * patch posted to the CMU CL mailing list Oct 6, 1999. It looks
297          * reasonable, and it certainly seems as though if CMU CL needs it,
298          * SBCL needs it too, but I haven't actually verified that it's
299          * right. It would be good to find a way to force the flow of
300          * control through here to test it. */
301         jmp     *CLOSURE_FUN_OFFSET(%eax)
302         .size   GNAME(closure_tramp), .-GNAME(closure_tramp)
303
304 /*
305  * fun-end breakpoint magic
306  */
307         .text
308         .global GNAME(fun_end_breakpoint_guts)
309         .align  align_4byte
310 GNAME(fun_end_breakpoint_guts):
311         /* Multiple Value return */
312         jmp     multiple_value_return
313         /* Single value return: The eventual return will now use the
314            multiple values return convention but with a return values
315            count of one. */
316         movl    %esp,%ebx       # Setup ebx - the ofp.
317         subl    $4,%esp         # Allocate one stack slot for the return value
318         movl    $4,%ecx         # Setup ecx for one return value.
319         movl    $NIL,%edi       # default second value
320         movl    $NIL,%esi       # default third value
321                 
322 multiple_value_return:
323         
324         .global GNAME(fun_end_breakpoint_trap)
325 GNAME(fun_end_breakpoint_trap):
326         int3
327         .byte   trap_FunEndBreakpoint
328         hlt                     # We should never return here.
329
330         .global GNAME(fun_end_breakpoint_end)
331 GNAME(fun_end_breakpoint_end):
332
333 \f
334         .global GNAME(do_pending_interrupt)
335         .type   GNAME(do_pending_interrupt),@function
336         .align  align_4byte,0x90
337 GNAME(do_pending_interrupt):
338         int3
339         .byte   trap_PendingInterrupt
340         ret
341         .size   GNAME(do_pending_interrupt),.-GNAME(do_pending_interrupt)
342 \f
343
344 /*
345  * Allocate bytes and return the start of the allocated space
346  * in the specified destination register.
347  *
348  * In the general case the size will be in the destination register.
349  *
350  * All registers must be preserved except the destination.
351  * The C conventions will preserve ebx, esi, edi, and ebp.
352  * So only eax, ecx, and edx need special care here.
353  */
354         
355         .globl  GNAME(alloc_to_eax)
356         .type   GNAME(alloc_to_eax),@function
357         .align  align_4byte,0x90
358 GNAME(alloc_to_eax):
359         pushl   %ecx    # Save ecx and edx as C could destroy them.
360         pushl   %edx
361         pushl   %eax    # Push the size.
362         call    GNAME(alloc)
363         addl    $4,%esp # Pop the size arg.
364         popl    %edx    # Restore ecx and edx.
365         popl    %ecx
366         ret
367         .size   GNAME(alloc_to_eax),.-GNAME(alloc_to_eax)
368
369         .globl  GNAME(alloc_8_to_eax)
370         .type   GNAME(alloc_8_to_eax),@function
371         .align  align_4byte,0x90
372 GNAME(alloc_8_to_eax):
373         pushl   %ecx    # Save ecx and edx as C could destroy them.
374         pushl   %edx
375         pushl   $8      # Push the size.
376         call    GNAME(alloc)
377         addl    $4,%esp # Pop the size arg.
378         popl    %edx    # Restore ecx and edx.
379         popl    %ecx
380         ret
381         .size   GNAME(alloc_8_to_eax),.-GNAME(alloc_8_to_eax)
382
383         .globl  GNAME(alloc_8_to_eax)
384         .type   GNAME(alloc_8_to_eax),@function
385         .align  align_4byte,0x90
386
387         .globl  GNAME(alloc_16_to_eax)
388         .type   GNAME(alloc_16_to_eax),@function
389         .align  align_4byte,0x90
390 GNAME(alloc_16_to_eax):
391         pushl   %ecx    # Save ecx and edx as C could destroy them.
392         pushl   %edx
393         pushl   $16     # Push the size.
394         call    GNAME(alloc)
395         addl    $4,%esp # Pop the size arg.
396         popl    %edx    # Restore ecx and edx.
397         popl    %ecx
398         ret
399         .size   GNAME(alloc_16_to_eax),.-GNAME(alloc_16_to_eax)
400
401         .globl  GNAME(alloc_to_ecx)
402         .type   GNAME(alloc_to_ecx),@function
403         .align  align_4byte,0x90
404 GNAME(alloc_to_ecx):
405         pushl   %eax    # Save eax and edx as C could destroy them.
406         pushl   %edx
407         pushl   %ecx    # Push the size.
408         call    GNAME(alloc)
409         addl    $4,%esp # Pop the size arg.
410         movl    %eax,%ecx       # Set up the destination.
411         popl    %edx    # Restore eax and edx.
412         popl    %eax
413         ret
414         .size   GNAME(alloc_to_ecx),.-GNAME(alloc_to_ecx)
415
416         .globl  GNAME(alloc_8_to_ecx)
417         .type   GNAME(alloc_8_to_ecx),@function
418         .align  align_4byte,0x90
419 GNAME(alloc_8_to_ecx):
420         pushl   %eax    # Save eax and edx as C could destroy them.
421         pushl   %edx
422         pushl   $8      # Push the size.
423         call    GNAME(alloc)
424         addl    $4,%esp # Pop the size arg.
425         movl    %eax,%ecx       # Set up the destination.
426         popl    %edx    # Restore eax and edx.
427         popl    %eax
428         ret
429         .size   GNAME(alloc_8_to_ecx),.-GNAME(alloc_8_to_ecx)
430
431         .globl  GNAME(alloc_16_to_ecx)
432         .type   GNAME(alloc_16_to_ecx),@function
433         .align  align_4byte,0x90
434 GNAME(alloc_16_to_ecx):
435         pushl   %eax    # Save eax and edx as C could destroy them.
436         pushl   %edx
437         pushl   $16     # Push the size.
438         call    GNAME(alloc)
439         addl    $4,%esp # Pop the size arg.
440         movl    %eax,%ecx       # Set up the destination.
441         popl    %edx    # Restore eax and edx.
442         popl    %eax
443         ret
444         .size   GNAME(alloc_16_to_ecx),.-GNAME(alloc_16_to_ecx)
445
446
447         .globl  GNAME(alloc_to_edx)
448         .type   GNAME(alloc_to_edx),@function
449         .align  align_4byte,0x90
450 GNAME(alloc_to_edx):
451         pushl   %eax    # Save eax and ecx as C could destroy them.
452         pushl   %ecx
453         pushl   %edx    # Push the size.
454         call    GNAME(alloc)
455         addl    $4,%esp # Pop the size arg.
456         movl    %eax,%edx       # Set up the destination.
457         popl    %ecx    # Restore eax and ecx.
458         popl    %eax
459         ret
460         .size   GNAME(alloc_to_edx),.-GNAME(alloc_to_edx)
461
462         .globl  GNAME(alloc_8_to_edx)
463         .type   GNAME(alloc_8_to_edx),@function
464         .align  align_4byte,0x90
465 GNAME(alloc_8_to_edx):
466         pushl   %eax    # Save eax and ecx as C could destroy them.
467         pushl   %ecx
468         pushl   $8      # Push the size.
469         call    GNAME(alloc)
470         addl    $4,%esp # Pop the size arg.
471         movl    %eax,%edx       # Set up the destination.
472         popl    %ecx    # Restore eax and ecx.
473         popl    %eax
474         ret
475         .size   GNAME(alloc_8_to_edx),.-GNAME(alloc_8_to_edx)
476
477         .globl  GNAME(alloc_16_to_edx)
478         .type   GNAME(alloc_16_to_edx),@function
479         .align  align_4byte,0x90
480 GNAME(alloc_16_to_edx):
481         pushl   %eax    # Save eax and ecx as C could destroy them.
482         pushl   %ecx
483         pushl   $16     # Push the size.
484         call    GNAME(alloc)
485         addl    $4,%esp # Pop the size arg.
486         movl    %eax,%edx       # Set up the destination.
487         popl    %ecx    # Restore eax and ecx.
488         popl    %eax
489         ret
490         .size   GNAME(alloc_16_to_edx),.-GNAME(alloc_16_to_edx)
491
492
493
494         .globl  GNAME(alloc_to_ebx)
495         .type   GNAME(alloc_to_ebx),@function
496         .align  align_4byte,0x90
497 GNAME(alloc_to_ebx):
498         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
499         pushl   %ecx
500         pushl   %edx
501         pushl   %ebx    # Push the size.
502         call    GNAME(alloc)
503         addl    $4,%esp # Pop the size arg.
504         movl    %eax,%ebx       # Set up the destination.
505         popl    %edx    # Restore eax, ecx and edx.
506         popl    %ecx
507         popl    %eax
508         ret
509         .size   GNAME(alloc_to_ebx),.-GNAME(alloc_to_ebx)
510
511         .globl  GNAME(alloc_8_to_ebx)
512         .type   GNAME(alloc_8_to_ebx),@function
513         .align  align_4byte,0x90
514 GNAME(alloc_8_to_ebx):
515         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
516         pushl   %ecx
517         pushl   %edx
518         pushl   $8      # Push the size.
519         call    GNAME(alloc)
520         addl    $4,%esp # Pop the size arg.
521         movl    %eax,%ebx       # Set up the destination.
522         popl    %edx    # Restore eax, ecx and edx.
523         popl    %ecx
524         popl    %eax
525         ret
526         .size   GNAME(alloc_8_to_ebx),.-GNAME(alloc_8_to_ebx)
527
528         .globl  GNAME(alloc_16_to_ebx)
529         .type   GNAME(alloc_16_to_ebx),@function
530         .align  align_4byte,0x90
531 GNAME(alloc_16_to_ebx):
532         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
533         pushl   %ecx
534         pushl   %edx
535         pushl   $16     # Push the size
536         call    GNAME(alloc)
537         addl    $4,%esp # pop the size arg.
538         movl    %eax,%ebx       # setup the destination.
539         popl    %edx    # Restore eax, ecx and edx.
540         popl    %ecx
541         popl    %eax
542         ret
543         .size   GNAME(alloc_16_to_ebx),.-GNAME(alloc_16_to_ebx)
544
545
546
547         .globl  GNAME(alloc_to_esi)
548         .type   GNAME(alloc_to_esi),@function
549         .align  align_4byte,0x90
550 GNAME(alloc_to_esi):
551         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
552         pushl   %ecx
553         pushl   %edx
554         pushl   %esi    # Push the size
555         call    GNAME(alloc)
556         addl    $4,%esp # pop the size arg.
557         movl    %eax,%esi       # setup the destination.
558         popl    %edx    # Restore eax, ecx and edx.
559         popl    %ecx
560         popl    %eax
561         ret
562         .size   GNAME(alloc_to_esi),.-GNAME(alloc_to_esi)
563
564         .globl  GNAME(alloc_8_to_esi)
565         .type   GNAME(alloc_8_to_esi),@function
566         .align  align_4byte,0x90
567 GNAME(alloc_8_to_esi):
568         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
569         pushl   %ecx
570         pushl   %edx
571         pushl   $8      # Push the size
572         call    GNAME(alloc)
573         addl    $4,%esp # pop the size arg.
574         movl    %eax,%esi       # setup the destination.
575         popl    %edx    # Restore eax, ecx and edx.
576         popl    %ecx
577         popl    %eax
578         ret
579         .size   GNAME(alloc_8_to_esi),.-GNAME(alloc_8_to_esi)
580
581         .globl  GNAME(alloc_16_to_esi)
582         .type   GNAME(alloc_16_to_esi),@function
583         .align  align_4byte,0x90
584 GNAME(alloc_16_to_esi):
585         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
586         pushl   %ecx
587         pushl   %edx
588         pushl   $16     # Push the size
589         call    GNAME(alloc)
590         addl    $4,%esp # pop the size arg.
591         movl    %eax,%esi       # setup the destination.
592         popl    %edx    # Restore eax, ecx and edx.
593         popl    %ecx
594         popl    %eax
595         ret
596         .size   GNAME(alloc_16_to_esi),.-GNAME(alloc_16_to_esi)
597
598
599         .globl  GNAME(alloc_to_edi)
600         .type   GNAME(alloc_to_edi),@function
601         .align  align_4byte,0x90
602 GNAME(alloc_to_edi):
603         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
604         pushl   %ecx
605         pushl   %edx
606         pushl   %edi    # Push the size
607         call    GNAME(alloc)
608         addl    $4,%esp # pop the size arg.
609         movl    %eax,%edi       # setup the destination.
610         popl    %edx    # Restore eax, ecx and edx.
611         popl    %ecx
612         popl    %eax
613         ret
614         .size   GNAME(alloc_to_edi),.-GNAME(alloc_to_edi)
615
616         .globl  GNAME(alloc_8_to_edi)
617         .type   GNAME(alloc_8_to_edi),@function
618         .align  align_4byte,0x90
619 GNAME(alloc_8_to_edi):
620         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
621         pushl   %ecx
622         pushl   %edx
623         pushl   $8      # Push the size
624         call    GNAME(alloc)
625         addl    $4,%esp # pop the size arg.
626         movl    %eax,%edi       # setup the destination.
627         popl    %edx    # Restore eax, ecx and edx.
628         popl    %ecx
629         popl    %eax
630         ret
631         .size   GNAME(alloc_8_to_edi),.-GNAME(alloc_8_to_edi)
632
633         .globl  GNAME(alloc_16_to_edi)
634         .type   GNAME(alloc_16_to_edi),@function
635         .align  align_4byte,0x90
636 GNAME(alloc_16_to_edi):
637         pushl   %eax    # Save eax, ecx, and edx as C could destroy them.
638         pushl   %ecx
639         pushl   %edx
640         pushl   $16     # Push the size
641         call    GNAME(alloc)
642         addl    $4,%esp # pop the size arg.
643         movl    %eax,%edi       # setup the destination.
644         popl    %edx    # Restore eax, ecx and edx.
645         popl    %ecx
646         popl    %eax
647         ret
648         .size   GNAME(alloc_16_to_edi),.-GNAME(alloc_16_to_edi)
649                 
650
651         .align  align_4byte,0x90
652         .globl  GNAME(post_signal_tramp)
653         .type   GNAME(post_signal_tramp),@function
654 GNAME(post_signal_tramp):
655         /* this is notionally the second half of a function whose first half
656          * doesn't exist.  This is where call_into_lisp returns when called 
657          * using return_to_lisp_function */
658         addl $12,%esp   /* clear call_into_lisp args from stack */
659         popa            /* restore registers */
660         popl %ebp       
661         ret
662         .size GNAME(post_signal_tramp),.-GNAME(post_signal_tramp)
663
664         
665 \f
666 #ifdef GENCGC_INLINE_ALLOC /* LISP_FEATURE_GENCGC */
667
668 /* These routines are called from Lisp when an inline allocation 
669  * overflows. Every register except the result needs to be preserved.
670  * We depend on C to preserve ebx, esi, edi, and ebp.
671  * But where necessary must save eax, ecx, edx. */
672
673 /* This routine handles an overflow with eax=crfp+size. So the
674  * size=eax-crfp. */
675         .align  align_4byte
676         .globl  GNAME(alloc_overflow_eax)
677         .type   GNAME(alloc_overflow_eax),@function
678 GNAME(alloc_overflow_eax):
679         pushl   %ecx            # Save ecx
680         pushl   %edx            # Save edx
681         /* Calculate the size for the allocation. */
682         subl    GNAME(current_region_free_pointer),%eax
683         pushl   %eax            # Push the size
684         call    GNAME(alloc)
685         addl    $4,%esp # pop the size arg.
686         popl    %edx    # Restore edx.
687         popl    %ecx    # Restore ecx.
688         addl    $6,(%esp) # Adjust the return address to skip the next inst.
689         ret
690         .size    GNAME(alloc_overflow_eax),.-GNAME(alloc_overflow_eax)
691
692 /* This routine handles an overflow with ecx=crfp+size. So the
693  * size=ecx-crfp. */
694         .align  align_4byte
695         .globl  GNAME(alloc_overflow_ecx)
696         .type   GNAME(alloc_overflow_ecx),@function
697 GNAME(alloc_overflow_ecx):
698         pushl   %eax            # Save eax
699         pushl   %edx            # Save edx
700         /* Calculate the size for the allocation. */
701         subl    GNAME(current_region_free_pointer),%ecx
702         pushl   %ecx            # Push the size
703         call    GNAME(alloc)
704         addl    $4,%esp # pop the size arg.
705         movl    %eax,%ecx       # setup the destination.
706         popl    %edx    # Restore edx.
707         popl    %eax    # Restore eax.
708         addl    $6,(%esp) # Adjust the return address to skip the next inst.
709         ret
710         .size    GNAME(alloc_overflow_ecx),.-GNAME(alloc_overflow_ecx)
711
712 /* This routine handles an overflow with edx=crfp+size. So the
713  * size=edx-crfp. */
714         .align  align_4byte
715         .globl  GNAME(alloc_overflow_edx)
716         .type   GNAME(alloc_overflow_edx),@function
717 GNAME(alloc_overflow_edx):
718         pushl   %eax            # Save eax
719         pushl   %ecx            # Save ecx
720         /* Calculate the size for the allocation. */
721         subl    GNAME(current_region_free_pointer),%edx
722         pushl   %edx            # Push the size
723         call    GNAME(alloc)
724         addl    $4,%esp # pop the size arg.
725         movl    %eax,%edx       # setup the destination.
726         popl    %ecx    # Restore ecx.
727         popl    %eax    # Restore eax.
728         addl    $6,(%esp) # Adjust the return address to skip the next inst.
729         ret
730         .size    GNAME(alloc_overflow_edx),.-GNAME(alloc_overflow_edx)
731
732 /* This routine handles an overflow with ebx=crfp+size. So the
733  * size=ebx-crfp. */
734         .align  align_4byte
735         .globl  GNAME(alloc_overflow_ebx)
736         .type   GNAME(alloc_overflow_ebx),@function
737 GNAME(alloc_overflow_ebx):
738         pushl   %eax            # Save eax
739         pushl   %ecx            # Save ecx
740         pushl   %edx            # Save edx
741         /* Calculate the size for the allocation. */
742         subl    GNAME(current_region_free_pointer),%ebx
743         pushl   %ebx            # Push the size
744         call    GNAME(alloc)
745         addl    $4,%esp # pop the size arg.
746         movl    %eax,%ebx       # setup the destination.
747         popl    %edx    # Restore edx.
748         popl    %ecx    # Restore ecx.
749         popl    %eax    # Restore eax.
750         addl    $6,(%esp) # Adjust the return address to skip the next inst.
751         ret
752         .size    GNAME(alloc_overflow_ebx),.-GNAME(alloc_overflow_ebx)
753
754 /* This routine handles an overflow with esi=crfp+size. So the
755  * size=esi-crfp. */
756         .align  align_4byte
757         .globl  GNAME(alloc_overflow_esi)
758         .type   GNAME(alloc_overflow_esi),@function
759 GNAME(alloc_overflow_esi):
760         pushl   %eax            # Save eax
761         pushl   %ecx            # Save ecx
762         pushl   %edx            # Save edx
763         /* Calculate the size for the allocation. */
764         subl    GNAME(current_region_free_pointer),%esi
765         pushl   %esi            # Push the size
766         call    GNAME(alloc)
767         addl    $4,%esp # pop the size arg.
768         movl    %eax,%esi       # setup the destination.
769         popl    %edx    # Restore edx.
770         popl    %ecx    # Restore ecx.
771         popl    %eax    # Restore eax.
772         addl    $6,(%esp) # Adjust the return address to skip the next inst.
773         ret
774         .size    GNAME(alloc_overflow_esi),.-GNAME(alloc_overflow_esi)
775
776 /* This routine handles an overflow with edi=crfp+size. So the
777  * size=edi-crfp. */
778         .align  align_4byte
779         .globl  GNAME(alloc_overflow_edi)
780         .type   GNAME(alloc_overflow_edi),@function
781 GNAME(alloc_overflow_edi):
782         pushl   %eax            # Save eax
783         pushl   %ecx            # Save ecx
784         pushl   %edx            # Save edx
785         /* Calculate the size for the allocation. */
786         subl    GNAME(current_region_free_pointer),%edi
787         pushl   %edi            # Push the size
788         call    GNAME(alloc)
789         addl    $4,%esp # pop the size arg.
790         movl    %eax,%edi       # setup the destination.
791         popl    %edx    # Restore edx.
792         popl    %ecx    # Restore ecx.
793         popl    %eax    # Restore eax.
794         addl    $6,(%esp) # Adjust the return address to skip the next inst.
795         ret
796         .size    GNAME(alloc_overflow_edi),.-GNAME(alloc_overflow_edi)
797
798 #endif
799
800         .end