Merge branch 'master' of git://factorcode.org/git/factor
commit
c051ee4ffd
|
@ -192,6 +192,7 @@ IN: compiler.cfg.builder.tests
|
||||||
[ [ ##unbox-alien? ] contains-insn? ] bi
|
[ [ ##unbox-alien? ] contains-insn? ] bi
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
\ alien-float "intrinsic" word-prop [
|
||||||
[ f t ] [
|
[ f t ] [
|
||||||
[ { byte-array fixnum } declare alien-cell 4 alien-float ]
|
[ { byte-array fixnum } declare alien-cell 4 alien-float ]
|
||||||
[ [ ##box-alien? ] contains-insn? ]
|
[ [ ##box-alien? ] contains-insn? ]
|
||||||
|
@ -203,3 +204,4 @@ IN: compiler.cfg.builder.tests
|
||||||
[ [ ##box-alien? ] contains-insn? ]
|
[ [ ##box-alien? ] contains-insn? ]
|
||||||
[ [ ##box-float? ] contains-insn? ] bi
|
[ [ ##box-float? ] contains-insn? ] bi
|
||||||
] unit-test
|
] unit-test
|
||||||
|
] when
|
|
@ -1,6 +1,7 @@
|
||||||
USING: kernel math math.floats.env math.floats.env.private
|
USING: kernel math math.floats.env math.floats.env.private
|
||||||
math.functions math.libm sequences tools.test locals
|
math.functions math.libm sequences tools.test locals
|
||||||
compiler.units kernel.private fry compiler math.private words ;
|
compiler.units kernel.private fry compiler math.private words
|
||||||
|
system ;
|
||||||
IN: math.floats.env.tests
|
IN: math.floats.env.tests
|
||||||
|
|
||||||
: set-default-fp-env ( -- )
|
: set-default-fp-env ( -- )
|
||||||
|
@ -29,7 +30,13 @@ set-default-fp-env
|
||||||
[ t ] +fp-overflow+ [ 1.0e250 1.0e100 ] [ * ] test-fp-exception-compiled unit-test
|
[ t ] +fp-overflow+ [ 1.0e250 1.0e100 ] [ * ] test-fp-exception-compiled unit-test
|
||||||
[ t ] +fp-underflow+ [ 1.0e-250 1.0e-100 ] [ * ] test-fp-exception-compiled unit-test
|
[ t ] +fp-underflow+ [ 1.0e-250 1.0e-100 ] [ * ] test-fp-exception-compiled unit-test
|
||||||
[ t ] +fp-overflow+ [ 2.0 100,000.0 ] [ fpow ] test-fp-exception-compiled unit-test
|
[ t ] +fp-overflow+ [ 2.0 100,000.0 ] [ fpow ] test-fp-exception-compiled unit-test
|
||||||
|
|
||||||
|
! No underflow on Linux with this test, just inexact. Reported as an Ubuntu bug:
|
||||||
|
! https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/429113
|
||||||
|
os linux? cpu x86.64? and [
|
||||||
[ t ] +fp-underflow+ [ 2.0 -100,000.0 ] [ fpow ] test-fp-exception-compiled unit-test
|
[ t ] +fp-underflow+ [ 2.0 -100,000.0 ] [ fpow ] test-fp-exception-compiled unit-test
|
||||||
|
] unless
|
||||||
|
|
||||||
[ t ] +fp-invalid-operation+ [ 0.0 0.0 ] [ /f ] test-fp-exception-compiled unit-test
|
[ t ] +fp-invalid-operation+ [ 0.0 0.0 ] [ /f ] test-fp-exception-compiled unit-test
|
||||||
[ t ] +fp-invalid-operation+ [ -1.0 ] [ fsqrt ] test-fp-exception-compiled unit-test
|
[ t ] +fp-invalid-operation+ [ -1.0 ] [ fsqrt ] test-fp-exception-compiled unit-test
|
||||||
|
|
||||||
|
@ -112,13 +119,13 @@ set-default-fp-env
|
||||||
{ +fp-inexact+ } [ 1.0 3.0 ] [ /f ] test-traps must-fail
|
{ +fp-inexact+ } [ 1.0 3.0 ] [ /f ] test-traps must-fail
|
||||||
{ +fp-invalid-operation+ } [ -1.0 ] [ fsqrt ] test-traps must-fail
|
{ +fp-invalid-operation+ } [ -1.0 ] [ fsqrt ] test-traps must-fail
|
||||||
{ +fp-overflow+ } [ 2.0 ] [ 100,000.0 ^ ] test-traps must-fail
|
{ +fp-overflow+ } [ 2.0 ] [ 100,000.0 ^ ] test-traps must-fail
|
||||||
{ +fp-underflow+ } [ 2.0 ] [ -100,000.0 ^ ] test-traps must-fail
|
{ +fp-underflow+ +fp-inexact+ } [ 2.0 ] [ -100,000.0 ^ ] test-traps must-fail
|
||||||
|
|
||||||
{ +fp-zero-divide+ } [ 1.0 0.0 ] [ /f ] test-traps-compiled must-fail
|
{ +fp-zero-divide+ } [ 1.0 0.0 ] [ /f ] test-traps-compiled must-fail
|
||||||
{ +fp-inexact+ } [ 1.0 3.0 ] [ /f ] test-traps-compiled must-fail
|
{ +fp-inexact+ } [ 1.0 3.0 ] [ /f ] test-traps-compiled must-fail
|
||||||
{ +fp-invalid-operation+ } [ -1.0 ] [ fsqrt ] test-traps-compiled must-fail
|
{ +fp-invalid-operation+ } [ -1.0 ] [ fsqrt ] test-traps-compiled must-fail
|
||||||
{ +fp-overflow+ } [ 2.0 ] [ 100,000.0 ^ ] test-traps-compiled must-fail
|
{ +fp-overflow+ } [ 2.0 ] [ 100,000.0 ^ ] test-traps-compiled must-fail
|
||||||
{ +fp-underflow+ } [ 2.0 ] [ -100,000.0 ^ ] test-traps-compiled must-fail
|
{ +fp-underflow+ +fp-inexact+ } [ 2.0 ] [ -100,000.0 ^ ] test-traps-compiled must-fail
|
||||||
|
|
||||||
! Ensure ordered comparisons raise traps
|
! Ensure ordered comparisons raise traps
|
||||||
:: test-comparison-quot ( word -- quot )
|
:: test-comparison-quot ( word -- quot )
|
||||||
|
|
|
@ -34,7 +34,7 @@ M: ppc-vmx-env (set-fp-env-register)
|
||||||
M: ppc (fp-env-registers)
|
M: ppc (fp-env-registers)
|
||||||
<ppc-fpu-env> <ppc-vmx-env> 2array ;
|
<ppc-fpu-env> <ppc-vmx-env> 2array ;
|
||||||
|
|
||||||
CONSTANT: ppc-exception-flag-bits HEX: 3e00,0000
|
CONSTANT: ppc-exception-flag-bits HEX: fff8,0000
|
||||||
CONSTANT: ppc-exception-flag>bit
|
CONSTANT: ppc-exception-flag>bit
|
||||||
H{
|
H{
|
||||||
{ +fp-invalid-operation+ HEX: 2000,0000 }
|
{ +fp-invalid-operation+ HEX: 2000,0000 }
|
||||||
|
|
|
@ -33,9 +33,9 @@ IN: math.functions.tests
|
||||||
[ 0.0 ] [ 1.0 log ] unit-test
|
[ 0.0 ] [ 1.0 log ] unit-test
|
||||||
[ 1.0 ] [ e log ] unit-test
|
[ 1.0 ] [ e log ] unit-test
|
||||||
|
|
||||||
[ t ] [ 1 exp e = ] unit-test
|
[ t ] [ 1 exp e 1.e-10 ~ ] unit-test
|
||||||
[ t ] [ 1.0 exp e = ] unit-test
|
[ t ] [ 1.0 exp e 1.e-10 ~ ] unit-test
|
||||||
[ 1.0 ] [ -1 exp e * ] unit-test
|
[ t ] [ -1 exp e * 1.0 1.e-10 ~ ] unit-test
|
||||||
|
|
||||||
[ 1.0 ] [ 0 cosh ] unit-test
|
[ 1.0 ] [ 0 cosh ] unit-test
|
||||||
[ 1.0 ] [ 0.0 cosh ] unit-test
|
[ 1.0 ] [ 0.0 cosh ] unit-test
|
||||||
|
|
|
@ -62,6 +62,24 @@ inline static bool tail_call_site_p(cell return_address)
|
||||||
return (insn & 0x1) == 0;
|
return (insn & 0x1) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static unsigned int fpu_status(unsigned int status)
|
||||||
|
{
|
||||||
|
unsigned int r = 0;
|
||||||
|
|
||||||
|
if (status & 0x20000000)
|
||||||
|
r |= FP_TRAP_INVALID_OPERATION;
|
||||||
|
if (status & 0x10000000)
|
||||||
|
r |= FP_TRAP_OVERFLOW;
|
||||||
|
if (status & 0x08000000)
|
||||||
|
r |= FP_TRAP_UNDERFLOW;
|
||||||
|
if (status & 0x04000000)
|
||||||
|
r |= FP_TRAP_ZERO_DIVIDE;
|
||||||
|
if (status & 0x02000000)
|
||||||
|
r |= FP_TRAP_INEXACT;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Defined in assembly */
|
/* Defined in assembly */
|
||||||
VM_ASM_API void c_to_factor(cell quot);
|
VM_ASM_API void c_to_factor(cell quot);
|
||||||
VM_ASM_API void throw_impl(cell quot, stack_frame *rewind);
|
VM_ASM_API void throw_impl(cell quot, stack_frame *rewind);
|
||||||
|
|
|
@ -50,6 +50,24 @@ inline static bool tail_call_site_p(cell return_address)
|
||||||
return call_site_opcode(return_address) == jmp_opcode;
|
return call_site_opcode(return_address) == jmp_opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static unsigned int fpu_status(unsigned int status)
|
||||||
|
{
|
||||||
|
unsigned int r = 0;
|
||||||
|
|
||||||
|
if (status & 0x01)
|
||||||
|
r |= FP_TRAP_INVALID_OPERATION;
|
||||||
|
if (status & 0x04)
|
||||||
|
r |= FP_TRAP_ZERO_DIVIDE;
|
||||||
|
if (status & 0x08)
|
||||||
|
r |= FP_TRAP_OVERFLOW;
|
||||||
|
if (status & 0x10)
|
||||||
|
r |= FP_TRAP_UNDERFLOW;
|
||||||
|
if (status & 0x20)
|
||||||
|
r |= FP_TRAP_INEXACT;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Defined in assembly */
|
/* Defined in assembly */
|
||||||
VM_ASM_API void c_to_factor(cell quot);
|
VM_ASM_API void c_to_factor(cell quot);
|
||||||
VM_ASM_API void throw_impl(cell quot, stack_frame *rewind_to);
|
VM_ASM_API void throw_impl(cell quot, stack_frame *rewind_to);
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace factor
|
||||||
user-space */
|
user-space */
|
||||||
cell signal_number;
|
cell signal_number;
|
||||||
cell signal_fault_addr;
|
cell signal_fault_addr;
|
||||||
|
unsigned int signal_fpu_status;
|
||||||
stack_frame *signal_callstack_top;
|
stack_frame *signal_callstack_top;
|
||||||
|
|
||||||
void out_of_memory()
|
void out_of_memory()
|
||||||
|
@ -130,9 +131,9 @@ void divide_by_zero_error()
|
||||||
general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
|
general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fp_trap_error(stack_frame *signal_callstack_top)
|
void fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top)
|
||||||
{
|
{
|
||||||
general_error(ERROR_FP_TRAP,F,F,signal_callstack_top);
|
general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),F,signal_callstack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIMITIVE(call_clear)
|
PRIMITIVE(call_clear)
|
||||||
|
@ -158,7 +159,7 @@ void misc_signal_handler_impl()
|
||||||
|
|
||||||
void fp_signal_handler_impl()
|
void fp_signal_handler_impl()
|
||||||
{
|
{
|
||||||
fp_trap_error(signal_callstack_top);
|
fp_trap_error(signal_fpu_status,signal_callstack_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ void memory_protection_error(cell addr, stack_frame *native_stack);
|
||||||
void signal_error(int signal, stack_frame *native_stack);
|
void signal_error(int signal, stack_frame *native_stack);
|
||||||
void type_error(cell type, cell tagged);
|
void type_error(cell type, cell tagged);
|
||||||
void not_implemented_error();
|
void not_implemented_error();
|
||||||
void fp_trap_error();
|
void fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top);
|
||||||
|
|
||||||
PRIMITIVE(call_clear);
|
PRIMITIVE(call_clear);
|
||||||
PRIMITIVE(unimplemented);
|
PRIMITIVE(unimplemented);
|
||||||
|
@ -45,6 +45,7 @@ PRIMITIVE(unimplemented);
|
||||||
user-space */
|
user-space */
|
||||||
extern cell signal_number;
|
extern cell signal_number;
|
||||||
extern cell signal_fault_addr;
|
extern cell signal_fault_addr;
|
||||||
|
extern unsigned int signal_fpu_status;
|
||||||
extern stack_frame *signal_callstack_top;
|
extern stack_frame *signal_callstack_top;
|
||||||
|
|
||||||
void memory_signal_handler_impl();
|
void memory_signal_handler_impl();
|
||||||
|
|
|
@ -67,6 +67,16 @@ inline static cell align8(cell a)
|
||||||
/* Not a real type, but code_block's type field can be set to this */
|
/* Not a real type, but code_block's type field can be set to this */
|
||||||
#define PIC_TYPE 69
|
#define PIC_TYPE 69
|
||||||
|
|
||||||
|
/* Constants used when floating-point trap exceptions are thrown */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FP_TRAP_INVALID_OPERATION = 1 << 0,
|
||||||
|
FP_TRAP_OVERFLOW = 1 << 1,
|
||||||
|
FP_TRAP_UNDERFLOW = 1 << 2,
|
||||||
|
FP_TRAP_ZERO_DIVIDE = 1 << 3,
|
||||||
|
FP_TRAP_INEXACT = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
inline static bool immediate_p(cell obj)
|
inline static bool immediate_p(cell obj)
|
||||||
{
|
{
|
||||||
return (obj == F || TAG(obj) == FIXNUM_TYPE);
|
return (obj == F || TAG(obj) == FIXNUM_TYPE);
|
||||||
|
|
|
@ -32,7 +32,8 @@ static void call_fault_handler(
|
||||||
exception_type_t exception,
|
exception_type_t exception,
|
||||||
exception_data_type_t code,
|
exception_data_type_t code,
|
||||||
MACH_EXC_STATE_TYPE *exc_state,
|
MACH_EXC_STATE_TYPE *exc_state,
|
||||||
MACH_THREAD_STATE_TYPE *thread_state)
|
MACH_THREAD_STATE_TYPE *thread_state,
|
||||||
|
MACH_FLOAT_STATE_TYPE *float_state)
|
||||||
{
|
{
|
||||||
/* There is a race condition here, but in practice an exception
|
/* There is a race condition here, but in practice an exception
|
||||||
delivered during stack frame setup/teardown or while transitioning
|
delivered during stack frame setup/teardown or while transitioning
|
||||||
|
@ -56,6 +57,8 @@ static void call_fault_handler(
|
||||||
}
|
}
|
||||||
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
|
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
|
||||||
{
|
{
|
||||||
|
signal_fpu_status = fpu_status(mach_fpu_status(float_state));
|
||||||
|
mach_clear_fpu_status(float_state);
|
||||||
MACH_PROGRAM_COUNTER(thread_state) = (cell)fp_signal_handler_impl;
|
MACH_PROGRAM_COUNTER(thread_state) = (cell)fp_signal_handler_impl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -78,14 +81,15 @@ catch_exception_raise (mach_port_t exception_port,
|
||||||
{
|
{
|
||||||
MACH_EXC_STATE_TYPE exc_state;
|
MACH_EXC_STATE_TYPE exc_state;
|
||||||
MACH_THREAD_STATE_TYPE thread_state;
|
MACH_THREAD_STATE_TYPE thread_state;
|
||||||
mach_msg_type_number_t state_count;
|
MACH_FLOAT_STATE_TYPE float_state;
|
||||||
|
mach_msg_type_number_t exc_state_count, thread_state_count, float_state_count;
|
||||||
|
|
||||||
/* Get fault information and the faulting thread's register contents..
|
/* Get fault information and the faulting thread's register contents..
|
||||||
|
|
||||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_get_state.html. */
|
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_get_state.html. */
|
||||||
state_count = MACH_EXC_STATE_COUNT;
|
exc_state_count = MACH_EXC_STATE_COUNT;
|
||||||
if (thread_get_state (thread, MACH_EXC_STATE_FLAVOR,
|
if (thread_get_state (thread, MACH_EXC_STATE_FLAVOR,
|
||||||
(natural_t *)&exc_state, &state_count)
|
(natural_t *)&exc_state, &exc_state_count)
|
||||||
!= KERN_SUCCESS)
|
!= KERN_SUCCESS)
|
||||||
{
|
{
|
||||||
/* The thread is supposed to be suspended while the exception
|
/* The thread is supposed to be suspended while the exception
|
||||||
|
@ -93,9 +97,19 @@ catch_exception_raise (mach_port_t exception_port,
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
state_count = MACH_THREAD_STATE_COUNT;
|
thread_state_count = MACH_THREAD_STATE_COUNT;
|
||||||
if (thread_get_state (thread, MACH_THREAD_STATE_FLAVOR,
|
if (thread_get_state (thread, MACH_THREAD_STATE_FLAVOR,
|
||||||
(natural_t *)&thread_state, &state_count)
|
(natural_t *)&thread_state, &thread_state_count)
|
||||||
|
!= KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
/* The thread is supposed to be suspended while the exception
|
||||||
|
handler is called. This shouldn't fail. */
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
float_state_count = MACH_FLOAT_STATE_COUNT;
|
||||||
|
if (thread_get_state (thread, MACH_FLOAT_STATE_FLAVOR,
|
||||||
|
(natural_t *)&float_state, &float_state_count)
|
||||||
!= KERN_SUCCESS)
|
!= KERN_SUCCESS)
|
||||||
{
|
{
|
||||||
/* The thread is supposed to be suspended while the exception
|
/* The thread is supposed to be suspended while the exception
|
||||||
|
@ -105,13 +119,20 @@ catch_exception_raise (mach_port_t exception_port,
|
||||||
|
|
||||||
/* Modify registers so to have the thread resume executing the
|
/* Modify registers so to have the thread resume executing the
|
||||||
fault handler */
|
fault handler */
|
||||||
call_fault_handler(exception,code[0],&exc_state,&thread_state);
|
call_fault_handler(exception,code[0],&exc_state,&thread_state,&float_state);
|
||||||
|
|
||||||
/* Set the faulting thread's register contents..
|
/* Set the faulting thread's register contents..
|
||||||
|
|
||||||
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_set_state.html. */
|
See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_set_state.html. */
|
||||||
|
if (thread_set_state (thread, MACH_FLOAT_STATE_FLAVOR,
|
||||||
|
(natural_t *)&float_state, float_state_count)
|
||||||
|
!= KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
return KERN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (thread_set_state (thread, MACH_THREAD_STATE_FLAVOR,
|
if (thread_set_state (thread, MACH_THREAD_STATE_FLAVOR,
|
||||||
(natural_t *)&thread_state, state_count)
|
(natural_t *)&thread_state, thread_state_count)
|
||||||
!= KERN_SUCCESS)
|
!= KERN_SUCCESS)
|
||||||
{
|
{
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
|
#include <machine/npx.h>
|
||||||
|
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
@ -9,6 +10,32 @@ inline static void *ucontext_stack_pointer(void *uap)
|
||||||
return (void *)ucontext->uc_mcontext.mc_esp;
|
return (void *)ucontext->uc_mcontext.mc_esp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
if (uap->uc_mcontext.mc_fpformat == _MC_FPFMT_387) {
|
||||||
|
struct save87 *x87 = (struct save87 *)(&ucontext->uc_mcontext.mc_fpstate);
|
||||||
|
return x87->en_sw;
|
||||||
|
} else if (uap->uc_mcontext.mc_fpformat == _MC_FPFMT_XMM) {
|
||||||
|
struct savexmm *xmm = (struct savexmm *)(&ucontext->uc_mcontext.mc_fpstate);
|
||||||
|
return xmm->en_sw | xmm->en_mxcsr;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
if (uap->uc_mcontext.mc_fpformat == _MC_FPFMT_387) {
|
||||||
|
struct save87 *x87 = (struct save87 *)(&ucontext->uc_mcontext.mc_fpstate);
|
||||||
|
x87->en_sw = 0;
|
||||||
|
} else if (uap->uc_mcontext.mc_fpformat == _MC_FPFMT_XMM) {
|
||||||
|
struct savexmm *xmm = (struct savexmm *)(&ucontext->uc_mcontext.mc_fpstate);
|
||||||
|
xmm->en_sw = 0;
|
||||||
|
xmm->en_mxcsr &= 0xffffffc0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_eip)
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_eip)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
|
#include <machine/fpu.h>
|
||||||
|
|
||||||
namespace factor
|
namespace factor
|
||||||
{
|
{
|
||||||
|
@ -9,6 +10,26 @@ inline static void *ucontext_stack_pointer(void *uap)
|
||||||
return (void *)ucontext->uc_mcontext.mc_rsp;
|
return (void *)ucontext->uc_mcontext.mc_rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
if (uap->uc_mcontext.mc_fpformat == _MC_FPFMT_XMM) {
|
||||||
|
struct savexmm *xmm = (struct savexmm *)(&ucontext->uc_mcontext.mc_fpstate);
|
||||||
|
return xmm->en_sw | xmm->en_mxcsr;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
if (uap->uc_mcontext.mc_fpformat == _MC_FPFMT_XMM) {
|
||||||
|
struct savexmm *xmm = (struct savexmm *)(&ucontext->uc_mcontext.mc_fpstate);
|
||||||
|
xmm->en_sw = 0;
|
||||||
|
xmm->en_mxcsr &= 0xffffffc0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_rip)
|
#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_rip)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,20 @@ inline static void *ucontext_stack_pointer(void *uap)
|
||||||
return (void *)ucontext->uc_mcontext.gregs[7];
|
return (void *)ucontext->uc_mcontext.gregs[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
return ucontext->uc_mcontext.fpregs->swd
|
||||||
|
| ucontext->uc_mcontext.fpregs->mxcsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
ucontext->uc_mcontext.fpregs->swd = 0;
|
||||||
|
ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0;
|
||||||
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
#define UAP_PROGRAM_COUNTER(ucontext) \
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[14])
|
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[14])
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,20 @@ inline static void *ucontext_stack_pointer(void *uap)
|
||||||
return (void *)ucontext->uc_mcontext.gregs[15];
|
return (void *)ucontext->uc_mcontext.gregs[15];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
return ucontext->uc_mcontext.fpregs->swd
|
||||||
|
| ucontext->uc_mcontext.fpregs->mxcsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
ucontext_t *ucontext = (ucontext_t *)uap;
|
||||||
|
ucontext->uc_mcontext.fpregs->swd = 0;
|
||||||
|
ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0;
|
||||||
|
}
|
||||||
|
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
#define UAP_PROGRAM_COUNTER(ucontext) \
|
||||||
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[16])
|
(((ucontext_t *)(ucontext))->uc_mcontext.gregs[16])
|
||||||
|
|
||||||
|
|
|
@ -18,28 +18,63 @@ Modified for Factor by Slava Pestov */
|
||||||
#define MACH_EXC_STATE_TYPE ppc_exception_state_t
|
#define MACH_EXC_STATE_TYPE ppc_exception_state_t
|
||||||
#define MACH_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE
|
#define MACH_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE
|
||||||
#define MACH_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT
|
#define MACH_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT
|
||||||
|
|
||||||
#define MACH_EXC_INTEGER_DIV EXC_PPC_ZERO_DIVIDE
|
#define MACH_EXC_INTEGER_DIV EXC_PPC_ZERO_DIVIDE
|
||||||
|
|
||||||
#define MACH_THREAD_STATE_TYPE ppc_thread_state_t
|
#define MACH_THREAD_STATE_TYPE ppc_thread_state_t
|
||||||
#define MACH_THREAD_STATE_FLAVOR PPC_THREAD_STATE
|
#define MACH_THREAD_STATE_FLAVOR PPC_THREAD_STATE
|
||||||
#define MACH_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
|
#define MACH_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
|
||||||
|
|
||||||
|
#define MACH_FLOAT_STATE_TYPE ppc_float_state_t
|
||||||
|
#define MACH_FLOAT_STATE_FLAVOR PPC_FLOAT_STATE
|
||||||
|
#define MACH_FLOAT_STATE_COUNT PPC_FLOAT_STATE_COUNT
|
||||||
|
|
||||||
#if __DARWIN_UNIX03
|
#if __DARWIN_UNIX03
|
||||||
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__dar
|
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__dar
|
||||||
#define MACH_STACK_POINTER(thr_state) (thr_state)->__r1
|
#define MACH_STACK_POINTER(thr_state) (thr_state)->__r1
|
||||||
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__srr0
|
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__srr0
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
MACH_PROGRAM_COUNTER(&(((ucontext_t *)(ucontext))->uc_mcontext->__ss))
|
#define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__ss)
|
||||||
|
#define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__fs)
|
||||||
|
|
||||||
|
#define FPSCR(float_state) (float_state)->__fpscr
|
||||||
#else
|
#else
|
||||||
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->dar
|
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->dar
|
||||||
#define MACH_STACK_POINTER(thr_state) (thr_state)->r1
|
#define MACH_STACK_POINTER(thr_state) (thr_state)->r1
|
||||||
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->srr0
|
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->srr0
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
MACH_PROGRAM_COUNTER(&(((ucontext_t *)(ucontext))->uc_mcontext->ss))
|
#define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->ss)
|
||||||
|
#define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->fs)
|
||||||
|
|
||||||
|
#define FPSCR(float_state) (float_state)->fpscr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) \
|
||||||
|
MACH_PROGRAM_COUNTER(UAP_SS(ucontext))
|
||||||
|
|
||||||
|
inline static unsigned int mach_fpu_status(ppc_float_state_t *float_state)
|
||||||
|
{
|
||||||
|
return FPSCR(float_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
return mach_fpu_status(UAP_FS(uap));
|
||||||
|
}
|
||||||
|
|
||||||
inline static cell fix_stack_pointer(cell sp)
|
inline static cell fix_stack_pointer(cell sp)
|
||||||
{
|
{
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void mach_clear_fpu_status(ppc_float_state_t *float_state)
|
||||||
|
{
|
||||||
|
FPSCR(float_state) &= 0x0007ffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
mach_clear_fpu_status(UAP_FS(uap));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,28 +16,68 @@ Modified for Factor by Slava Pestov */
|
||||||
#define MACH_EXC_STATE_TYPE i386_exception_state_t
|
#define MACH_EXC_STATE_TYPE i386_exception_state_t
|
||||||
#define MACH_EXC_STATE_FLAVOR i386_EXCEPTION_STATE
|
#define MACH_EXC_STATE_FLAVOR i386_EXCEPTION_STATE
|
||||||
#define MACH_EXC_STATE_COUNT i386_EXCEPTION_STATE_COUNT
|
#define MACH_EXC_STATE_COUNT i386_EXCEPTION_STATE_COUNT
|
||||||
|
|
||||||
#define MACH_EXC_INTEGER_DIV EXC_I386_DIV
|
#define MACH_EXC_INTEGER_DIV EXC_I386_DIV
|
||||||
|
|
||||||
#define MACH_THREAD_STATE_TYPE i386_thread_state_t
|
#define MACH_THREAD_STATE_TYPE i386_thread_state_t
|
||||||
#define MACH_THREAD_STATE_FLAVOR i386_THREAD_STATE
|
#define MACH_THREAD_STATE_FLAVOR i386_THREAD_STATE
|
||||||
#define MACH_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT
|
#define MACH_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT
|
||||||
|
|
||||||
|
#define MACH_FLOAT_STATE_TYPE i386_float_state_t
|
||||||
|
#define MACH_FLOAT_STATE_FLAVOR i386_FLOAT_STATE
|
||||||
|
#define MACH_FLOAT_STATE_COUNT i386_FLOAT_STATE_COUNT
|
||||||
|
|
||||||
#if __DARWIN_UNIX03
|
#if __DARWIN_UNIX03
|
||||||
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr
|
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr
|
||||||
#define MACH_STACK_POINTER(thr_state) (thr_state)->__esp
|
#define MACH_STACK_POINTER(thr_state) (thr_state)->__esp
|
||||||
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__eip
|
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__eip
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
MACH_PROGRAM_COUNTER(&(((ucontext_t *)(ucontext))->uc_mcontext->__ss))
|
#define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__ss)
|
||||||
|
#define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__fs)
|
||||||
|
|
||||||
|
#define MXCSR(float_state) (float_state)->__fpu_mxcsr
|
||||||
|
#define X87SW(float_state) (float_state)->__fpu_fsw
|
||||||
#else
|
#else
|
||||||
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr
|
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr
|
||||||
#define MACH_STACK_POINTER(thr_state) (thr_state)->esp
|
#define MACH_STACK_POINTER(thr_state) (thr_state)->esp
|
||||||
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->eip
|
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->eip
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
|
||||||
MACH_PROGRAM_COUNTER(&(((ucontext_t *)(ucontext))->uc_mcontext->ss))
|
#define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->ss)
|
||||||
|
#define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->fs)
|
||||||
|
|
||||||
|
#define MXCSR(float_state) (float_state)->fpu_mxcsr
|
||||||
|
#define X87SW(float_state) (float_state)->fpu_fsw
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) \
|
||||||
|
MACH_PROGRAM_COUNTER(UAP_SS(ucontext))
|
||||||
|
|
||||||
|
inline static unsigned int mach_fpu_status(i386_float_state_t *float_state)
|
||||||
|
{
|
||||||
|
unsigned short x87sw;
|
||||||
|
memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw));
|
||||||
|
return MXCSR(float_state) | x87sw;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
return mach_fpu_status(UAP_FS(uap));
|
||||||
|
}
|
||||||
|
|
||||||
inline static cell fix_stack_pointer(cell sp)
|
inline static cell fix_stack_pointer(cell sp)
|
||||||
{
|
{
|
||||||
return ((sp + 4) & ~15) - 4;
|
return ((sp + 4) & ~15) - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void mach_clear_fpu_status(i386_float_state_t *float_state)
|
||||||
|
{
|
||||||
|
MXCSR(float_state) &= 0xffffffc0;
|
||||||
|
memset(&X87SW(float_state), 0, sizeof(X87SW(float_state)));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
mach_clear_fpu_status(UAP_FS(uap));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,28 +16,66 @@ Modified for Factor by Slava Pestov and Daniel Ehrenberg */
|
||||||
#define MACH_EXC_STATE_TYPE x86_exception_state64_t
|
#define MACH_EXC_STATE_TYPE x86_exception_state64_t
|
||||||
#define MACH_EXC_STATE_FLAVOR x86_EXCEPTION_STATE64
|
#define MACH_EXC_STATE_FLAVOR x86_EXCEPTION_STATE64
|
||||||
#define MACH_EXC_STATE_COUNT x86_EXCEPTION_STATE64_COUNT
|
#define MACH_EXC_STATE_COUNT x86_EXCEPTION_STATE64_COUNT
|
||||||
|
|
||||||
#define MACH_EXC_INTEGER_DIV EXC_I386_DIV
|
#define MACH_EXC_INTEGER_DIV EXC_I386_DIV
|
||||||
|
|
||||||
#define MACH_THREAD_STATE_TYPE x86_thread_state64_t
|
#define MACH_THREAD_STATE_TYPE x86_thread_state64_t
|
||||||
#define MACH_THREAD_STATE_FLAVOR x86_THREAD_STATE64
|
#define MACH_THREAD_STATE_FLAVOR x86_THREAD_STATE64
|
||||||
#define MACH_THREAD_STATE_COUNT MACHINE_THREAD_STATE_COUNT
|
#define MACH_THREAD_STATE_COUNT MACHINE_THREAD_STATE_COUNT
|
||||||
|
|
||||||
|
#define MACH_FLOAT_STATE_TYPE x86_float_state64_t
|
||||||
|
#define MACH_FLOAT_STATE_FLAVOR x86_FLOAT_STATE64
|
||||||
|
#define MACH_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT
|
||||||
|
|
||||||
#if __DARWIN_UNIX03
|
#if __DARWIN_UNIX03
|
||||||
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr
|
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr
|
||||||
#define MACH_STACK_POINTER(thr_state) (thr_state)->__rsp
|
#define MACH_STACK_POINTER(thr_state) (thr_state)->__rsp
|
||||||
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__rip
|
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__rip
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
#define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__ss)
|
||||||
MACH_PROGRAM_COUNTER(&(((ucontext_t *)(ucontext))->uc_mcontext->__ss))
|
#define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__fs)
|
||||||
|
|
||||||
|
#define MXCSR(float_state) (float_state)->__fpu_mxcsr
|
||||||
|
#define X87SW(float_state) (float_state)->__fpu_fsw
|
||||||
#else
|
#else
|
||||||
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr
|
#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr
|
||||||
#define MACH_STACK_POINTER(thr_state) (thr_state)->rsp
|
#define MACH_STACK_POINTER(thr_state) (thr_state)->rsp
|
||||||
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->rip
|
#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->rip
|
||||||
#define UAP_PROGRAM_COUNTER(ucontext) \
|
#define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->ss)
|
||||||
MACH_PROGRAM_COUNTER(&(((ucontext_t *)(ucontext))->uc_mcontext->ss))
|
#define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->fs)
|
||||||
|
|
||||||
|
#define MXCSR(float_state) (float_state)->fpu_mxcsr
|
||||||
|
#define X87SW(float_state) (float_state)->fpu_fsw
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UAP_PROGRAM_COUNTER(ucontext) \
|
||||||
|
MACH_PROGRAM_COUNTER(UAP_SS(ucontext))
|
||||||
|
|
||||||
|
inline static unsigned int mach_fpu_status(x86_float_state64_t *float_state)
|
||||||
|
{
|
||||||
|
unsigned short x87sw;
|
||||||
|
memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw));
|
||||||
|
return MXCSR(float_state) | x87sw;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static unsigned int uap_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
return mach_fpu_status(UAP_FS(uap));
|
||||||
|
}
|
||||||
|
|
||||||
inline static cell fix_stack_pointer(cell sp)
|
inline static cell fix_stack_pointer(cell sp)
|
||||||
{
|
{
|
||||||
return ((sp + 8) & ~15) - 8;
|
return ((sp + 8) & ~15) - 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void mach_clear_fpu_status(x86_float_state64_t *float_state)
|
||||||
|
{
|
||||||
|
MXCSR(float_state) &= 0xffffffc0;
|
||||||
|
memset(&X87SW(float_state), 0, sizeof(X87SW(float_state)));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uap_clear_fpu_status(void *uap)
|
||||||
|
{
|
||||||
|
mach_clear_fpu_status(UAP_FS(uap));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,7 @@ namespace factor
|
||||||
|
|
||||||
#define ucontext_stack_pointer(uap) ((void *)_UC_MACHINE_SP((ucontext_t *)uap))
|
#define ucontext_stack_pointer(uap) ((void *)_UC_MACHINE_SP((ucontext_t *)uap))
|
||||||
|
|
||||||
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
|
static inline void uap_clear_fpu_status(void *uap) { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,7 @@ namespace factor
|
||||||
#define ucontext_stack_pointer(uap) \
|
#define ucontext_stack_pointer(uap) \
|
||||||
((void *)(((ucontext_t *)(uap))->uc_mcontext.__gregs[_REG_URSP]))
|
((void *)(((ucontext_t *)(uap))->uc_mcontext.__gregs[_REG_URSP]))
|
||||||
|
|
||||||
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
|
static inline void uap_clear_fpu_status(void *uap) { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,7 @@ inline static void *openbsd_stack_pointer(void *uap)
|
||||||
#define ucontext_stack_pointer openbsd_stack_pointer
|
#define ucontext_stack_pointer openbsd_stack_pointer
|
||||||
#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_eip)
|
#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_eip)
|
||||||
|
|
||||||
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
|
static inline void uap_clear_fpu_status(void *uap) { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,7 @@ inline static void *openbsd_stack_pointer(void *uap)
|
||||||
#define ucontext_stack_pointer openbsd_stack_pointer
|
#define ucontext_stack_pointer openbsd_stack_pointer
|
||||||
#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_rip)
|
#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_rip)
|
||||||
|
|
||||||
|
static inline unsigned int uap_fpu_status(void *uap) { return 0; }
|
||||||
|
static inline void uap_clear_fpu_status(void *uap) { }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,8 @@ void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
||||||
{
|
{
|
||||||
signal_number = signal;
|
signal_number = signal;
|
||||||
signal_callstack_top = uap_stack_pointer(uap);
|
signal_callstack_top = uap_stack_pointer(uap);
|
||||||
|
signal_fpu_status = fpu_status(uap_fpu_status(uap));
|
||||||
|
uap_clear_fpu_status(uap);
|
||||||
UAP_PROGRAM_COUNTER(uap) =
|
UAP_PROGRAM_COUNTER(uap) =
|
||||||
(siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
|
(siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
|
||||||
? (cell)misc_signal_handler_impl
|
? (cell)misc_signal_handler_impl
|
||||||
|
|
|
@ -34,6 +34,9 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
|
||||||
case EXCEPTION_FLT_OVERFLOW:
|
case EXCEPTION_FLT_OVERFLOW:
|
||||||
case EXCEPTION_FLT_STACK_CHECK:
|
case EXCEPTION_FLT_STACK_CHECK:
|
||||||
case EXCEPTION_FLT_UNDERFLOW:
|
case EXCEPTION_FLT_UNDERFLOW:
|
||||||
|
/* XXX MxCsr is not available in CONTEXT structure on x86.32 */
|
||||||
|
signal_fpu_status = c->FloatSave.StatusWord;
|
||||||
|
c->FloatSave.StatusWord = 0;
|
||||||
c->EIP = (cell)fp_signal_handler_impl;
|
c->EIP = (cell)fp_signal_handler_impl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue