diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c index 2f89cd523c74eb9336d70cc296588f96565f8574..7fe143f918892fbf58eb919beff4c5d7dc30bfc6 100644 --- a/src/lisp/gencgc.c +++ b/src/lisp/gencgc.c @@ -8412,28 +8412,11 @@ gencgc_pickup_dynamic(void) void do_pending_interrupt(void); -//#pragma GCC optimize ("-O1") char * alloc(int nbytes) { -#if (defined(i386) || defined(__x86_64)) - /* - * Need to save and restore the FPU registers on x86, but only for - * sse2. See Trac ticket #61 - * (https://trac.common-lisp.net/cmucl/ticket/61) and gitlab - * ticket #86 - * (https://gitlab.common-lisp.net/cmucl/cmucl/-/issues/86). - * - * Not needed by sparc or ppc because we never call alloc from - * Lisp directly to do allocation. - */ - FPU_STATE(fpu_state); - - if (fpu_mode == SSE2) { - save_fpu_state(fpu_state); - } -#endif void *new_obj; + #if !(defined(sparc) || (defined(DARWIN) && defined(__ppc__))) /* * *current-region-free-pointer* is the same as alloc-tn (= @@ -8483,14 +8466,8 @@ alloc(int nbytes) } } -#if (defined(i386) || defined(__x86_64)) - if (fpu_mode == SSE2) { - restore_fpu_state(fpu_state); - } -#endif return new_obj; } -#pragma GCC optimize ("-O2") char * alloc_pseudo_atomic(int nbytes) diff --git a/src/lisp/x86-assem.S b/src/lisp/x86-assem.S index b7aa7f183ecb804d5b00563ef53cbd6172952cba..8d44e669256b2a56e5f9de06e5851ae5dffc1610 100644 --- a/src/lisp/x86-assem.S +++ b/src/lisp/x86-assem.S @@ -381,6 +381,7 @@ ENDFUNC(fastcopy16) * On exit: * %eax = address */ +#if 0 FUNCDEF(alloc_overflow_sse2) STACK_PROLOGUE(20) movl %ecx, 8(%esp) # Save ecx and edx registers @@ -401,7 +402,49 @@ FUNCDEF(alloc_overflow_sse2) STACK_EPILOGUE ret ENDFUNC(alloc_overflow_sse2) - +#else +FUNCDEF(alloc_overflow_sse2) + # Need 512 bytes for the fpu save area, space to save ecx and edx, + # space for mxcsr, a temp, and one arg to pass to alloc. That's + # 512 + 20. But the save area needs to be 16-byte aligned, so + # allocate 512 + 32 bytes. The fpu area will be at offset 32. + # + # Stack looks like: + # + # +544 -> end + # +32 -> fpu save + # +20 -> unused + # +16 -> temp + # +12 -> mxcsr + # + 8 -> save ecx + # + 4 -> save edx + # esp + 0 -> arg for alloc + STACK_PROLOGUE(32+512) + movl %ecx, 8(%esp) # Save ecx and edx registers + movl %edx, 4(%esp) + stmxcsr 12(%esp) # Save MXCSR + /* Clear the exceptions that might have occurred */ + movl 12(%esp), %edx + and $-64, %edx # Clear the exceptions + movl %edx, 16(%esp) + ldmxcsr 16(%esp) # Get new mxcsr value + movl %eax, (%esp) # Put size on stack for first arg to alloc() + + # Save all FPU regs because we don't know what's in use by lisp. + fxsave 32(%esp) + + call GNAME(alloc) + + fxrstor 32(%esp) + + movl 4(%esp), %edx # Restore edx and ecx registers. eax has the return value. + movl 8(%esp), %ecx + ldmxcsr 12(%esp) + STACK_EPILOGUE + ret +ENDFUNC(alloc_overflow_sse2) +#endif + #ifdef LINKAGE_TABLE /* Call into C code to resolve a linkage entry. The initial code in the