/*
* very-low-level utilities for runtime support
- *
- * $Header$
*/
/*
* files for more information.
*/
\f
-#include "x86-validate.h"
-
#define LANGUAGE_ASSEMBLY
+#include "validate.h"
#include "sbcl.h"
-
+#include "genesis/closure.h"
+#include "genesis/fdefn.h"
+#include "genesis/static-symbols.h"
+#include "genesis/symbol.h"
+#include "genesis/thread.h"
+
/* Minimize conditionalization for different OS naming schemes. */
#if defined __linux__ || defined __FreeBSD__ /* (but *not* OpenBSD) */
#define GNAME(var) var
.text
.global GNAME(foreign_function_call_active)
+ .global GNAME(all_threads)
\f
/*
\f
.text
+ .global GNAME(call_into_lisp_first_time)
+ .type GNAME(call_into_lisp_first_time),@function
+
+/* The *ALIEN-STACK* pointer is set up on the first call_into_lisp when
+ * the stack changes. We don't worry too much about saving registers
+ * here, because we never expect to return from the initial call to lisp
+ * anyway */
+
+ .align align_16byte,0x90
+GNAME(call_into_lisp_first_time):
+ pushl %ebp # Save old frame pointer.
+ movl %esp,%ebp # Establish new frame.
+ movl %esp,ALIEN_STACK + SYMBOL_VALUE_OFFSET
+ movl GNAME(all_threads),%eax
+ movl THREAD_CONTROL_STACK_START_OFFSET(%eax) ,%esp
+ /* don't think too hard about what happens if we get interrupted
+ * here */
+ addl $THREAD_CONTROL_STACK_SIZE-4,%esp
+ jmp Lstack
+\f
+ .text
.global GNAME(call_into_lisp)
.type GNAME(call_into_lisp),@function
/* The C conventions require that ebx, esi, edi, and ebp be preserved
* across function calls. */
-/* The *ALIEN-STACK* pointer is set up on the first call_into_lisp when
- * the stack changes. */
.align align_16byte,0x90
GNAME(call_into_lisp):
pushl %ebp # Save old frame pointer.
movl %esp,%ebp # Establish new frame.
-
+Lstack:
/* Save the NPX state */
fwait # Catch any pending NPX exceptions.
subl $108,%esp # Make room for the NPX state.
- fnsave (%esp) # resets NPX
+ fnsave (%esp) # save and reset NPX
movl (%esp),%eax # Load NPX control word.
andl $0xfffff3ff,%eax # Set rounding mode to nearest.
movl %eax, GNAME(foreign_function_call_active)
movl %esp,%ebx # remember current stack
- cmpl $CONTROL_STACK_START,%esp
- jbe ChangeToLispStack
- cmpl $CONTROL_STACK_END,%esp
- jbe OnLispStack
-ChangeToLispStack:
- /* Setup the *alien-stack* pointer */
- movl %esp,ALIEN_STACK + SYMBOL_VALUE_OFFSET
- movl $CONTROL_STACK_END,%esp # new stack
-OnLispStack:
pushl %ebx # Save entry stack on (maybe) new stack.
/* Establish Lisp args. */
sub $8,%esp # Ensure 3 slots are allocated, one above.
mov %ebx,%ebp # Switch to new frame.
- /* Indirect the closure. */
- call *CLOSURE_FUNCTION_OFFSET(%eax)
+ call *CLOSURE_FUN_OFFSET(%eax)
- /* Multi-value return; blow off any extra values. */
+ /* If the function returned multiple values, it will return to
+ this point. Lose them */
mov %ebx, %esp
- /* single value return */
+ /* A singled value function returns here */
/* Restore the stack, in case there was a stack change. */
popl %esp # c-sp
int3
.byte trap_Error
.byte 2
-#ifdef type_LongFloat
- .byte 24
-#else
- .byte 23
-#endif
+ .byte UNDEFINED_FUN_ERROR
.byte sc_DescriptorReg # eax in the Descriptor-reg SC
ret
.size GNAME(undefined_tramp), .-GNAME(undefined_tramp)
.global GNAME(closure_tramp)
.type GNAME(closure_tramp),@function
GNAME(closure_tramp):
- movl FDEFN_FUNCTION_OFFSET(%eax),%eax
+ movl FDEFN_FUN_OFFSET(%eax),%eax
/* FIXME: The '*' after "jmp" in the next line is from PVE's
* patch posted to the CMU CL mailing list Oct 6, 1999. It looks
* reasonable, and it certainly seems as though if CMU CL needs it,
* SBCL needs it too, but I haven't actually verified that it's
* right. It would be good to find a way to force the flow of
* control through here to test it. */
- jmp *CLOSURE_FUNCTION_OFFSET(%eax)
+ jmp *CLOSURE_FUN_OFFSET(%eax)
.size GNAME(closure_tramp), .-GNAME(closure_tramp)
/*
- * function-end breakpoint magic
+ * fun-end breakpoint magic
*/
.text
- .global GNAME(function_end_breakpoint_guts)
+ .global GNAME(fun_end_breakpoint_guts)
.align align_4byte
-GNAME(function_end_breakpoint_guts):
+GNAME(fun_end_breakpoint_guts):
/* Multiple Value return */
jmp multiple_value_return
/* Single value return: The eventual return will now use the
multiple_value_return:
- .global GNAME(function_end_breakpoint_trap)
-GNAME(function_end_breakpoint_trap):
+ .global GNAME(fun_end_breakpoint_trap)
+GNAME(fun_end_breakpoint_trap):
int3
- .byte trap_FunctionEndBreakpoint
+ .byte trap_FunEndBreakpoint
hlt # We should never return here.
- .global GNAME(function_end_breakpoint_end)
-GNAME(function_end_breakpoint_end):
+ .global GNAME(fun_end_breakpoint_end)
+GNAME(fun_end_breakpoint_end):
\f
.global GNAME(do_pending_interrupt)
ret
.size GNAME(do_pending_interrupt),.-GNAME(do_pending_interrupt)
\f
-#ifdef WANT_CGC
-/* This is a copy function which is optimized for the Pentium and
- * works OK on 486 as well. This assumes (does not check) that the
- * input byte count is a multiple of 8 bytes (one Lisp object).
- * This code takes advantage of pairing in the Pentium as well
- * as the 128-bit cache line.
- */
- .global GNAME(fastcopy16)
- .type GNAME(fastcopy16),@function
- .align align_4byte,0x90
-GNAME(fastcopy16):
- pushl %ebp
- movl %esp,%ebp
- movl 8(%ebp), %edx # dst
- movl 12(%ebp),%eax # src
- movl 16(%ebp),%ecx # bytes
- pushl %ebx
- pushl %esi
- pushl %edi
- movl %edx,%edi
- movl %eax,%esi
- sarl $3,%ecx # number 8-byte units
- testl $1,%ecx # odd?
- jz Lquad
- movl (%esi),%eax
- movl 4(%esi),%ebx
- movl %eax,(%edi)
- movl %ebx,4(%edi)
- leal 8(%esi),%esi
- leal 8(%edi),%edi
-Lquad: sarl $1,%ecx # count 16-byte units
- jz Lend
- movl %ecx,%ebp # use ebp for loop counter
- .align align_16byte,0x90
-Ltop:
- movl (%edi),%eax # prefetch! MAJOR Pentium win..
- movl (%esi),%eax
- movl 4(%esi),%ebx
- movl 8(%esi),%ecx
- movl 12(%esi),%edx
- movl %eax, (%edi)
- movl %ebx, 4(%edi)
- movl %ecx, 8(%edi)
- movl %edx,12(%edi)
- leal 16(%esi),%esi
- leal 16(%edi),%edi
- decl %ebp
- jnz Ltop # non-prefixed jump saves cycles
-Lend:
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
- .size GNAME(fastcopy16),.-GNAME(fastcopy16)
-#endif
-\f
-#ifdef GENCGC
+#ifdef LISP_FEATURE_GENCGC
/* This is a fast bzero using the FPU. The first argument is the start
* address which needs to be aligned on an 8 byte boundary, the second
* argument is the number of bytes, which must be a nonzero multiple
* of 8 bytes. */
+/* FIXME whether this is still faster than using the OS's bzero or
+ * equivalent, we don't know */
.text
.globl GNAME(i586_bzero)
.type GNAME(i586_bzero),@function
.size GNAME(alloc_16_to_edi),.-GNAME(alloc_16_to_edi)
+ .align align_4byte,0x90
+ .globl GNAME(post_signal_tramp)
+ .type GNAME(post_signal_tramp),@function
+GNAME(post_signal_tramp):
+ /* this is notionally the second half of a function whose first half
+ * doesn't exist. This is where call_into_lisp returns when called
+ * using return_to_lisp_function */
+ addl $12,%esp /* clear call_into_lisp args from stack */
+ popa /* restore registers */
+ popl %ebp
+ ret
+ .size GNAME(post_signal_tramp),.-GNAME(post_signal_tramp)
+
+
\f
-#ifdef GENCGC
+#ifdef GENCGC_INLINE_ALLOC /* LISP_FEATURE_GENCGC */
/* These routines are called from Lisp when an inline allocation
* overflows. Every register except the result needs to be preserved.