X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fx86-assem.S;h=551841aae9b74f207eb6ac6885ddfd0e5d282c5c;hb=b9e94e326f79ab01e56cb437e424ce5ea489471f;hp=2069f96c597819eda23970ae2caa7989abd6b2d7;hpb=a499f2c9099d1dc2cb4227a2505eb4cc6f310e24;p=sbcl.git diff --git a/src/runtime/x86-assem.S b/src/runtime/x86-assem.S index 2069f96..551841a 100644 --- a/src/runtime/x86-assem.S +++ b/src/runtime/x86-assem.S @@ -62,7 +62,7 @@ * that are defined to be no-ops on win32. Hopefully this still works on * other platforms. */ -#ifndef LISP_FEATURE_WIN32 +#if !defined(LISP_FEATURE_WIN32) && !defined(LISP_FEATURE_DARWIN) #define TYPE(name) .type name,@function #define SIZE(name) .size name,.-name #else @@ -70,9 +70,25 @@ #define SIZE(name) #endif +/* + * x86/darwin (as of MacOS X 10.4.5) doesn't reliably file signal + * handlers (SIGTRAP or Mach exception handlers) for 0xCC, wo we have + * to use ud2 instead. ud2 is an undefined opcode, #x0b0f, or + * 0F 0B in low-endian notation, that causes SIGILL to fire. We check + * for this instruction in the SIGILL handler and if we see it, we + * advance the EIP by two bytes to skip over ud2 instruction and + * call sigtrap_handler. */ +#if defined(LISP_FEATURE_DARWIN) +#define END() +#define TRAP ud2 +#else +#define END() .end +#define TRAP int3 +#endif + .text - .global GNAME(foreign_function_call_active) - .global GNAME(all_threads) + .globl GNAME(foreign_function_call_active) + .globl GNAME(all_threads) /* * A call to call_into_c preserves esi, edi, and ebp. @@ -87,7 +103,7 @@ */ .text .align align_16byte,0x90 - .global GNAME(call_into_c) + .globl GNAME(call_into_c) TYPE(GNAME(call_into_c)) GNAME(call_into_c): movl $1,GNAME(foreign_function_call_active) @@ -109,6 +125,9 @@ GNAME(call_into_c): cld #endif +#ifdef LISP_FEATURE_DARWIN + andl $0xfffffff0,%esp # align stack to 16-byte boundary before calling C +#endif call *%eax # normal callout using Lisp stack movl %eax,%ecx # remember integer return value @@ -160,7 +179,7 @@ Lfp_rtn_value: .text - .global GNAME(call_into_lisp_first_time) + .globl GNAME(call_into_lisp_first_time) TYPE(GNAME(call_into_lisp_first_time)) /* The *ALIEN-STACK* pointer is set up on the first call_into_lisp when @@ -178,7 +197,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 $THREAD_CONTROL_STACK_SIZE-4,%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 @@ -186,7 +205,7 @@ GNAME(call_into_lisp_first_time): jmp Lstack .text - .global GNAME(call_into_lisp) + .globl GNAME(call_into_lisp) TYPE(GNAME(call_into_lisp)) /* The C conventions require that ebx, esi, edi, and ebp be preserved @@ -264,7 +283,9 @@ Ldone: /* If the function returned multiple values, it will return to this point. Lose them */ + jnc LsingleValue mov %ebx, %esp +LsingleValue: /* A singled value function returns here */ /* Restore the stack, in case there was a stack change. */ @@ -286,7 +307,7 @@ Ldone: /* support for saving and restoring the NPX state from C */ .text - .global GNAME(fpu_save) + .globl GNAME(fpu_save) TYPE(GNAME(fpu_save)) .align 2,0x90 GNAME(fpu_save): @@ -295,7 +316,7 @@ GNAME(fpu_save): ret SIZE(GNAME(fpu_save)) - .global GNAME(fpu_restore) + .globl GNAME(fpu_restore) TYPE(GNAME(fpu_restore)) .align 2,0x90 GNAME(fpu_restore): @@ -309,11 +330,11 @@ GNAME(fpu_restore): */ .text .align align_4byte,0x90 - .global GNAME(undefined_tramp) + .globl GNAME(undefined_tramp) TYPE(GNAME(undefined_tramp)) .byte 0, 0, 0, SIMPLE_FUN_HEADER_WIDETAG GNAME(undefined_tramp): - int3 + TRAP .byte trap_Error .byte 2 .byte UNDEFINED_FUN_ERROR @@ -326,7 +347,7 @@ GNAME(undefined_tramp): */ .text .align align_4byte,0x90 - .global GNAME(closure_tramp) + .globl GNAME(closure_tramp) TYPE(GNAME(closure_tramp)) .byte 0, 0, 0, SIMPLE_FUN_HEADER_WIDETAG GNAME(closure_tramp): @@ -340,41 +361,52 @@ GNAME(closure_tramp): jmp *CLOSURE_FUN_OFFSET(%eax) SIZE(GNAME(closure_tramp)) + .text + .align align_4byte,0x90 + .global GNAME(funcallable_instance_tramp) + .type GNAME(funcallable_instance_tramp),@function +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), .-GNAME(funcallable_instance_tramp) + /* * fun-end breakpoint magic */ .text - .global GNAME(fun_end_breakpoint_guts) + .globl GNAME(fun_end_breakpoint_guts) .align align_4byte GNAME(fun_end_breakpoint_guts): /* Multiple Value return */ - jmp multiple_value_return + jc multiple_value_return /* Single value return: The eventual return will now use the multiple values return convention but with a return values count of one. */ 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 $NIL,%edi # default second value - movl $NIL,%esi # default third value + movl $(NIL),%edi # default second value + movl $(NIL),%esi # default third value multiple_value_return: - .global GNAME(fun_end_breakpoint_trap) + .globl GNAME(fun_end_breakpoint_trap) GNAME(fun_end_breakpoint_trap): - int3 + TRAP .byte trap_FunEndBreakpoint hlt # We should never return here. - .global GNAME(fun_end_breakpoint_end) + .globl GNAME(fun_end_breakpoint_end) GNAME(fun_end_breakpoint_end): - .global GNAME(do_pending_interrupt) + .globl GNAME(do_pending_interrupt) TYPE(GNAME(do_pending_interrupt)) .align align_4byte,0x90 GNAME(do_pending_interrupt): - int3 + TRAP .byte trap_PendingInterrupt ret SIZE(GNAME(do_pending_interrupt)) @@ -811,6 +843,57 @@ GNAME(alloc_overflow_edi): ret SIZE(GNAME(alloc_overflow_edi)) + +#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)) @@ -821,6 +904,10 @@ 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)) @@ -830,7 +917,7 @@ GNAME(post_signal_tramp): * This is part of the funky magic for exception handling on win32. * see sigtrap_emulator() in win32-os.c for details. */ - .global GNAME(sigtrap_trampoline) + .globl GNAME(sigtrap_trampoline) GNAME(sigtrap_trampoline): pushl %eax pushl %ebp @@ -838,7 +925,7 @@ GNAME(sigtrap_trampoline): call GNAME(sigtrap_wrapper) pop %eax pop %eax - int3 + TRAP .byte trap_ContextRestore hlt # We should never return here. @@ -846,7 +933,7 @@ GNAME(sigtrap_trampoline): * This is part of the funky magic for exception handling on win32. * see handle_exception() in win32-os.c for details. */ - .global GNAME(exception_trampoline) + .globl GNAME(exception_trampoline) GNAME(exception_trampoline): pushl %eax pushl %ebp @@ -854,7 +941,7 @@ GNAME(exception_trampoline): call GNAME(handle_win32_exception_wrapper) pop %eax pop %eax - int3 + TRAP .byte trap_ContextRestore hlt # We should never return here. #endif @@ -863,9 +950,9 @@ GNAME(exception_trampoline): * to use. */ - .global GNAME(fast_bzero_pointer) + .globl GNAME(fast_bzero_pointer) .data - .align 4 + .align align_4byte GNAME(fast_bzero_pointer): /* Variable containing a pointer to the bzero function to use. * Initially points to a basic function. Change this variable @@ -874,7 +961,7 @@ GNAME(fast_bzero_pointer): .text .align align_8byte,0x90 - .global GNAME(fast_bzero) + .globl GNAME(fast_bzero) TYPE(GNAME(fast_bzero)) GNAME(fast_bzero): /* Indirect function call */ @@ -884,7 +971,7 @@ GNAME(fast_bzero): .text .align align_8byte,0x90 - .global GNAME(fast_bzero_detect) + .globl GNAME(fast_bzero_detect) TYPE(GNAME(fast_bzero_detect)) GNAME(fast_bzero_detect): /* Decide whether to use SSE, MMX or REP version */ @@ -904,10 +991,10 @@ GNAME(fast_bzero_detect): * for all non-SSE2 processors. */ Lbase: - movl $GNAME(fast_bzero_base), GNAME(fast_bzero_pointer) + movl $(GNAME(fast_bzero_base)), GNAME(fast_bzero_pointer) jmp Lrestore Lsse2: - movl $GNAME(fast_bzero_sse), GNAME(fast_bzero_pointer) + movl $(GNAME(fast_bzero_sse)), GNAME(fast_bzero_pointer) jmp Lrestore Lrestore: @@ -922,7 +1009,7 @@ Lrestore: .text .align align_8byte,0x90 - .global GNAME(fast_bzero_sse) + .globl GNAME(fast_bzero_sse) TYPE(GNAME(fast_bzero_sse)) GNAME(fast_bzero_sse): @@ -938,7 +1025,7 @@ GNAME(fast_bzero_sse): movups %xmm7, -16(%esp) /* Save XMM register */ xorps %xmm7, %xmm7 /* Zero the XMM register */ jmp Lloop_sse - .align 16 + .align align_16byte Lloop_sse: /* Copy the 16 zeroes from xmm7 to memory, 4 times. MOVNTDQ is the @@ -968,7 +1055,7 @@ Lend_sse: .text .align align_8byte,0x90 - .global GNAME(fast_bzero_base) + .globl GNAME(fast_bzero_base) TYPE(GNAME(fast_bzero_base)) GNAME(fast_bzero_base): @@ -984,8 +1071,11 @@ GNAME(fast_bzero_base): shr $2, %ecx /* Amount of 4-byte blocks to copy */ jz Lend_base cld /* Set direction of STOSL to increment */ - rep stosl /* Store EAX to *EDI, ECX times, incrementing + + rep + stosl /* Store EAX to *EDI, ECX times, incrementing * EDI by 4 after each store */ + Lend_base: pop %edi /* Restore temp registers */ pop %ecx @@ -994,4 +1084,5 @@ Lend_base: SIZE(GNAME(fast_bzero_base)) - .end + END() + \ No newline at end of file