X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fx86-assem.S;h=e1eba22f47e55e2dfa30d032611eae4b3dca04a0;hb=2e47ed527bdcb76cf5eb52f66cc08f4fb0a0041d;hp=0deae4f381350445a3c2d966d6c2bdd0b14ce69e;hpb=5de74c72e5a9522c7fdd3dbb31a39641e9de8877;p=sbcl.git diff --git a/src/runtime/x86-assem.S b/src/runtime/x86-assem.S index 0deae4f..e1eba22 100644 --- a/src/runtime/x86-assem.S +++ b/src/runtime/x86-assem.S @@ -17,6 +17,7 @@ #include "sbcl.h" #include "validate.h" #include "genesis/closure.h" +#include "genesis/funcallable-instance.h" #include "genesis/fdefn.h" #include "genesis/static-symbols.h" #include "genesis/symbol.h" @@ -37,18 +38,6 @@ #define GNAME(var) _##var #endif -#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __sun -#define GNAMEDOLLAR(var) $##var -#else -#define GNAMEDOLLAR(var) $_##var -#endif - -#if defined __linux__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __sun -#define DOLLARLITERAL(var) $##var -#else -#define DOLLARLITERAL(var) $##(var) -#endif - /* Get the right type of alignment. Linux, FreeBSD and NetBSD (but not OpenBSD) * want alignment in bytes. * @@ -99,7 +88,6 @@ #endif .text - .globl GNAME(foreign_function_call_active) .globl GNAME(all_threads) /* @@ -112,14 +100,15 @@ * floats. * * This should work for Lisp calls C calls Lisp calls C.. + * + * FIXME & OAOOM: This duplicates call-out in src/compiler/x86/c-call.lisp, + * so if you tweak this, change that too! */ .text .align align_16byte,0x90 .globl GNAME(call_into_c) TYPE(GNAME(call_into_c)) GNAME(call_into_c): - movl $1,GNAME(foreign_function_call_active) - /* Save the return Lisp address in ebx. */ popl %ebx @@ -165,7 +154,6 @@ GNAME(call_into_c): /* Restore the return value. */ movl %ecx,%eax # maybe return value - movl $0,GNAME(foreign_function_call_active) /* Return. */ jmp *%ebx @@ -183,7 +171,6 @@ Lfp_rtn_value: /* We don't need to restore eax, because the result is in st(0). */ - movl $0,GNAME(foreign_function_call_active) /* Return. */ jmp *%ebx @@ -209,7 +196,7 @@ GNAME(call_into_lisp_first_time): movl THREAD_CONTROL_STACK_START_OFFSET(%eax) ,%esp /* don't think too hard about what happens if we get interrupted * here */ - addl DOLLARLITERAL(THREAD_CONTROL_STACK_SIZE),%esp + addl $(THREAD_CONTROL_STACK_SIZE),%esp #else /* Win32 -really- doesn't like you switching stacks out from under it. */ movl GNAME(all_threads),%eax @@ -263,8 +250,6 @@ Lstack: xorl %esi,%esi # third arg /* no longer in function call */ - movl %eax, GNAME(foreign_function_call_active) - movl %esp,%ebx # remember current stack pushl %ebx # Save entry stack on (maybe) new stack. @@ -285,6 +270,19 @@ Lstack: Ldone: /* Registers eax, ecx, edx, edi, and esi are now live. */ +#ifdef LISP_FEATURE_WIN32 + /* Establish an SEH frame. */ +#ifdef LISP_FEATURE_SB_THREAD + /* FIXME: need to save BSP here. */ +#error "need to save BSP here, but don't know how yet." +#else + pushl BINDING_STACK_POINTER + SYMBOL_VALUE_OFFSET +#endif + pushl $GNAME(exception_handler_wrapper) + pushl %fs:0 + movl %esp, %fs:0 +#endif + /* Alloc new frame. */ mov %esp,%ebx # The current sp marks start of new frame. push %ebp # fp in save location S0 @@ -300,6 +298,12 @@ Ldone: LsingleValue: /* A singled value function returns here */ +#ifdef LISP_FEATURE_WIN32 + /* Remove our SEH frame. */ + popl %fs:0 + add $8, %esp +#endif + /* Restore the stack, in case there was a stack change. */ popl %esp # c-sp @@ -373,6 +377,17 @@ GNAME(closure_tramp): jmp *CLOSURE_FUN_OFFSET(%eax) SIZE(GNAME(closure_tramp)) + .text + .align align_4byte,0x90 + .globl GNAME(funcallable_instance_tramp) + TYPE(GNAME(funcallable_instance_tramp)) +GNAME(funcallable_instance_tramp): + movl FUNCALLABLE_INSTANCE_FUNCTION_OFFSET(%eax),%eax + /* KLUDGE: on this platform, whatever kind of function is in %rax + * now, the first word of it contains the address to jump to. */ + jmp *CLOSURE_FUN_OFFSET(%eax) + SIZE(GNAME(funcallable_instance_tramp)) + /* * fun-end breakpoint magic */ @@ -388,8 +403,8 @@ GNAME(fun_end_breakpoint_guts): movl %esp,%ebx # Setup ebx - the ofp. subl $4,%esp # Allocate one stack slot for the return value movl $4,%ecx # Setup ecx for one return value. - movl DOLLARLITERAL(NIL),%edi # default second value - movl DOLLARLITERAL(NIL),%esi # default third value + movl $(NIL),%edi # default second value + movl $(NIL),%esi # default third value multiple_value_return: @@ -844,6 +859,94 @@ GNAME(alloc_overflow_edi): ret SIZE(GNAME(alloc_overflow_edi)) + +#ifdef LISP_FEATURE_WIN32 + /* The guts of the exception-handling system doesn't use + * frame pointers, which manages to throw off backtraces + * rather badly. So here we grab the (known-good) EBP + * and EIP from the exception context and use it to fake + * up a stack frame which will skip over the system SEH + * code. */ + .align align_4byte + .globl GNAME(exception_handler_wrapper) + TYPE(GNAME(exception_handler_wrapper)) +GNAME(exception_handler_wrapper): + /* Context layout is: */ + /* 7 dwords before FSA. (0x1c) */ + /* 8 dwords and 0x50 bytes in the FSA. (0x70/0x8c) */ + /* 4 dwords segregs. (0x10/0x9c) */ + /* 6 dwords non-stack GPRs. (0x18/0xb4) */ + /* EBP (at 0xb4) */ + /* EIP (at 0xb8) */ +#define CONTEXT_EBP_OFFSET 0xb4 +#define CONTEXT_EIP_OFFSET 0xb8 + /* some other stuff we don't care about. */ + pushl %ebp + movl 0x10(%esp), %ebp /* context */ + pushl CONTEXT_EIP_OFFSET(%ebp) + pushl CONTEXT_EBP_OFFSET(%ebp) + movl %esp, %ebp + pushl 0x1c(%esp) + pushl 0x1c(%esp) + pushl 0x1c(%esp) + pushl 0x1c(%esp) + call GNAME(handle_exception) + lea 8(%ebp), %esp + popl %ebp + ret + SIZE(GNAME(exception_handler_wrapper)) +#endif + +#ifdef LISP_FEATURE_DARWIN + .align align_4byte + .globl GNAME(call_into_lisp_tramp) + TYPE(GNAME(call_into_lisp_tramp)) +GNAME(call_into_lisp_tramp): + /* 1. build the stack frame from the block that's pointed to by ECX + 2. free the block + 3. set ECX to 0 + 4. call the function via call_into_lisp + */ + pushl 0(%ecx) /* return address */ + + pushl %ebp + movl %esp, %ebp + + pushl 32(%ecx) /* eflags */ + pushl 28(%ecx) /* EAX */ + pushl 20(%ecx) /* ECX */ + pushl 16(%ecx) /* EDX */ + pushl 24(%ecx) /* EBX */ + pushl $0 /* popal is going to ignore esp */ + pushl %ebp /* is this right?? */ + pushl 12(%ecx) /* ESI */ + pushl 8(%ecx) /* EDI */ + pushl $0 /* args for call_into_lisp */ + pushl $0 + pushl 4(%ecx) /* function to call */ + + /* free our save block */ + pushl %ecx /* reserve sufficient space on stack for args */ + pushl %ecx + andl $0xfffffff0, %esp /* align stack */ + movl $0x40, 4(%esp) + movl %ecx, (%esp) + call GNAME(os_invalidate) + + /* call call_into_lisp */ + leal -48(%ebp), %esp + call GNAME(call_into_lisp) + + /* Clean up our mess */ + leal -36(%ebp), %esp + popal + popfl + leave + ret + + SIZE(call_into_lisp_tramp) +#endif + .align align_4byte,0x90 .globl GNAME(post_signal_tramp) TYPE(GNAME(post_signal_tramp)) @@ -854,43 +957,14 @@ GNAME(post_signal_tramp): addl $12,%esp /* clear call_into_lisp args from stack */ popal /* restore registers */ popfl +#ifdef LISP_FEATURE_DARWIN + /* skip two padding words */ + addl $8,%esp +#endif leave ret SIZE(GNAME(post_signal_tramp)) -#ifdef LISP_FEATURE_WIN32 - /* - * This is part of the funky magic for exception handling on win32. - * see sigtrap_emulator() in win32-os.c for details. - */ - .globl GNAME(sigtrap_trampoline) -GNAME(sigtrap_trampoline): - pushl %eax - pushl %ebp - movl %esp, %ebp - call GNAME(sigtrap_wrapper) - pop %eax - pop %eax - TRAP - .byte trap_ContextRestore - hlt # We should never return here. - - /* - * This is part of the funky magic for exception handling on win32. - * see handle_exception() in win32-os.c for details. - */ - .globl GNAME(exception_trampoline) -GNAME(exception_trampoline): - pushl %eax - pushl %ebp - movl %esp, %ebp - call GNAME(handle_win32_exception_wrapper) - pop %eax - pop %eax - TRAP - .byte trap_ContextRestore - hlt # We should never return here. -#endif /* fast_bzero implementations and code to detect which implementation * to use. @@ -937,10 +1011,10 @@ GNAME(fast_bzero_detect): * for all non-SSE2 processors. */ Lbase: - movl GNAMEDOLLAR(fast_bzero_base), GNAME(fast_bzero_pointer) + movl $(GNAME(fast_bzero_base)), GNAME(fast_bzero_pointer) jmp Lrestore Lsse2: - movl GNAMEDOLLAR(fast_bzero_sse), GNAME(fast_bzero_pointer) + movl $(GNAME(fast_bzero_sse)), GNAME(fast_bzero_pointer) jmp Lrestore Lrestore: