Moved the softfloat-enabled ops back to the cpu directory.

Made softfloat always enabled, thus dynarec disabled, only for the IBM PS/2 model 70 type 4, in preparation for its comeback to main use.
This commit is contained in:
TC1995
2023-04-30 18:18:12 +02:00
parent 7a53e1de45
commit 7c372ca789
10 changed files with 19 additions and 7 deletions

View File

@@ -1,750 +0,0 @@
#define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \
static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a, result; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
FPU_check_pending_exceptions(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_stack_underflow(fetchdat, 0, 0); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (!is_nan) \
result = floatx80_add(a, use_var, &status); \
\
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_save_regi(result, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
return 0; \
} \
static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a, result; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
FPU_check_pending_exceptions(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_stack_underflow(fetchdat, 0, 0); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (!is_nan) { \
result = floatx80_div(a, use_var, &status); \
} \
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_save_regi(result, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
return 0; \
} \
static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a, result; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
FPU_check_pending_exceptions(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_stack_underflow(fetchdat, 0, 0); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (!is_nan) { \
result = floatx80_div(use_var, a, &status); \
} \
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_save_regi(result, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \
return 0; \
} \
static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a, result; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
FPU_check_pending_exceptions(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_stack_underflow(fetchdat, 0, 0); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (!is_nan) { \
result = floatx80_mul(a, use_var, &status); \
} \
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_save_regi(result, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \
return 0; \
} \
static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a, result; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
FPU_check_pending_exceptions(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_stack_underflow(fetchdat, 0, 0); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (!is_nan) \
result = floatx80_sub(a, use_var, &status); \
\
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_save_regi(result, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
return 0; \
} \
static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a, result; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
FPU_check_pending_exceptions(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_stack_underflow(fetchdat, 0, 0); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (!is_nan) \
result = floatx80_sub(use_var, a, &status); \
\
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_save_regi(result, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
return 0; \
}
// clang-format off
sf_FPU(s, float32, 16, temp, geteal(), float32_to_floatx80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32)
#ifndef FPU_8087
sf_FPU(s, float32, 32, temp, geteal(), float32_to_floatx80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32)
#endif
sf_FPU(d, float64, 16, temp, geteaq(), float64_to_floatx80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64)
#ifndef FPU_8087
sf_FPU(d, float64, 32, temp, geteaq(), float64_to_floatx80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64)
#endif
sf_FPU(iw, uint16_t, 16, temp, geteaw(), int32_to_floatx80((int16_t)temp), 0, _i16)
#ifndef FPU_8087
sf_FPU(iw, uint16_t, 32, temp, geteaw(), int32_to_floatx80((int16_t)temp), 0, _i16)
#endif
sf_FPU(il, uint32_t, 16, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i32)
#ifndef FPU_8087
sf_FPU(il, uint32_t, 32, temp, geteal(), int32_to_floatx80((int32_t)temp), 0, _i32)
#endif
// clang-format on
static int
sf_FADD_st0_stj(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_add(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FADD_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_add(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, fetchdat & 7);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FADDP_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_add(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FDIV_st0_stj(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_div(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
return 0;
}
static int
sf_FDIV_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_div(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, fetchdat & 7);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
return 0;
}
static int
sf_FDIVP_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_div(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
return 0;
}
static int
sf_FDIVR_st0_stj(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_div(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
return 0;
}
static int
sf_FDIVR_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_div(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, fetchdat & 7);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
return 0;
}
static int
sf_FDIVRP_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_div(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
return 0;
}
static int
sf_FMUL_st0_stj(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_mul(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
return 0;
}
static int
sf_FMUL_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_mul(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
return 0;
}
static int
sf_FMULP_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_mul(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
return 0;
}
static int
sf_FSUB_st0_stj(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_sub(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FSUB_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_sub(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FSUBP_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_sub(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FSUBR_st0_stj(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(fetchdat & 7);
b = FPU_read_regi(0);
result = floatx80_sub(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FSUBR_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_sub(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FSUBRP_sti_st0(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_stack_underflow(fetchdat, fetchdat & 7, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
result = floatx80_sub(a, b, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, fetchdat & 7);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
return 0;
}
static int
sf_FSQRT(uint32_t fetchdat)
{
floatx80 result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
result = floatx80_sqrt(FPU_read_regi(0), &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi));
return 0;
}
static int
sf_FRNDINT(uint32_t fetchdat)
{
floatx80 result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
result = floatx80_round_to_int(FPU_read_regi(0), &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi));
return 0;
}

View File

@@ -1,489 +0,0 @@
#define cmp_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \
static int sf_FCOM##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a; \
int rc; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \
setcc(C0 | C2 | C3); \
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (is_nan) { \
rc = float_relation_unordered; \
float_raise(&status, float_flag_invalid); \
} else { \
rc = floatx80_compare_two(a, use_var, &status); \
} \
setcc(FPU_status_word_flags_fpu_compare(rc)); \
FPU_exception(fetchdat, status.float_exception_flags, 0); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \
return 0; \
} \
static int sf_FCOMP##name##_a##a_size(uint32_t fetchdat) \
{ \
floatx80 a; \
int rc; \
struct float_status_t status; \
optype temp; \
FP_ENTER(); \
fetch_ea_##a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = rw; \
if (cpu_state.abrt) \
return 1;\
clear_C1(); \
if (IS_TAG_EMPTY(0)) { \
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0); \
setcc(C0 | C2 | C3); \
if (is_IA_masked()) \
FPU_pop(); \
\
goto next_ins; \
} \
status = i387cw_to_softfloat_status_word(i387_get_control_word()); \
a = FPU_read_regi(0); \
if (is_nan) { \
rc = float_relation_unordered; \
float_raise(&status, float_flag_invalid); \
} else { \
rc = floatx80_compare_two(a, use_var, &status); \
} \
setcc(FPU_status_word_flags_fpu_compare(rc)); \
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) \
FPU_pop(); \
\
next_ins: \
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \
return 0; \
} \
// clang-format off
cmp_FPU(s, float32, 16, temp, geteal(), float32_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(temp), _32)
#ifndef FPU_8087
cmp_FPU(s, float32, 32, temp, geteal(), float32_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float32_is_nan(temp), _32)
#endif
cmp_FPU(d, float64, 16, temp, geteaq(), float64_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(temp), _64)
#ifndef FPU_8087
cmp_FPU(d, float64, 32, temp, geteaq(), float64_to_floatx80(temp, &status), floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(temp), _64)
#endif
cmp_FPU(iw, int16_t, 16, temp, (int16_t)geteaw(), int32_to_floatx80((int32_t)temp), 0, _i16)
#ifndef FPU_8087
cmp_FPU(iw, int16_t, 32, temp, (int16_t)geteaw(), int32_to_floatx80((int32_t)temp), 0, _i16)
#endif
cmp_FPU(il, int32_t, 16, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i32)
#ifndef FPU_8087
cmp_FPU(il, int32_t, 32, temp, (int32_t)geteal(), int32_to_floatx80(temp), 0, _i32)
#endif
// clang-format on
static int
sf_FCOM_sti(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_two(a, b, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
FPU_exception(fetchdat, status.float_exception_flags, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
return 0;
}
static int
sf_FCOMP_sti(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
if (is_IA_masked()) {
FPU_pop();
}
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_two(a, b, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
return 0;
}
static int
sf_FCOMPP(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
if (is_IA_masked()) {
FPU_pop();
FPU_pop();
}
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(1);
rc = floatx80_compare_two(a, b, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_pop();
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
return 0;
}
#ifndef FPU_8087
static int
sf_FUCOMPP(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
if (is_IA_masked()) {
FPU_pop();
FPU_pop();
}
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(1);
rc = floatx80_compare_quiet(a, b, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_pop();
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
return 0;
}
static int
sf_FCOMI_st0_stj(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
cpu_state.flags |= (Z_FLAG | P_FLAG | C_FLAG);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_two(a, b, &status);
FPU_write_eflags_fpu_compare(rc);
FPU_exception(fetchdat, status.float_exception_flags, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
return 0;
}
static int
sf_FCOMIP_st0_stj(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
cpu_state.flags |= (Z_FLAG | P_FLAG | C_FLAG);
if (is_IA_masked()) {
FPU_pop();
}
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_two(a, b, &status);
FPU_write_eflags_fpu_compare(rc);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
return 0;
}
static int
sf_FUCOM_sti(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_quiet(a, b, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
FPU_exception(fetchdat, status.float_exception_flags, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
return 0;
}
static int
sf_FUCOMP_sti(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
if (is_IA_masked())
FPU_pop();
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_quiet(a, b, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_pop();
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
return 0;
}
static int
sf_FUCOMI_st0_stj(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
cpu_state.flags |= (Z_FLAG | P_FLAG | C_FLAG);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_quiet(a, b, &status);
FPU_write_eflags_fpu_compare(rc);
FPU_exception(fetchdat, status.float_exception_flags, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
return 0;
}
static int
sf_FUCOMIP_st0_stj(uint32_t fetchdat)
{
floatx80 a, b;
struct float_status_t status;
int rc;
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(fetchdat & 7)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
cpu_state.flags |= (Z_FLAG | P_FLAG | C_FLAG);
if (is_IA_masked())
FPU_pop();
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(fetchdat & 7);
rc = floatx80_compare_quiet(a, b, &status);
FPU_write_eflags_fpu_compare(rc);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_pop();
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
return 0;
}
#endif
static int
sf_FTST(uint32_t fetchdat)
{
int rc;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
setcc(C0 | C2 | C3);
} else {
status = i387cw_to_softfloat_status_word(i387_get_control_word());
rc = floatx80_compare_two(FPU_read_regi(0), Const_Z, &status);
setcc(FPU_status_word_flags_fpu_compare(rc));
FPU_exception(fetchdat, status.float_exception_flags, 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi));
return 0;
}
static int
sf_FXAM(uint32_t fetchdat)
{
floatx80 reg;
int sign;
float_class_t aClass;
FP_ENTER();
cpu_state.pc++;
reg = FPU_read_regi(0);
sign = floatx80_sign(reg);
/*
* Examine the contents of the ST(0) register and sets the condition
* code flags C0, C2 and C3 in the FPU status word to indicate the
* class of value or number in the register.
*/
if (IS_TAG_EMPTY(0)) {
setcc(C3 | C1 | C0);
} else {
aClass = floatx80_class(reg);
switch (aClass) {
case float_zero:
setcc(C3 | C1);
break;
case float_SNaN:
case float_QNaN:
// unsupported handled as NaNs
if (floatx80_is_unsupported(reg)) {
setcc(C1);
} else {
setcc(C1 | C0);
}
break;
case float_negative_inf:
case float_positive_inf:
setcc(C2 | C1 | C0);
break;
case float_denormal:
setcc(C3 | C2 | C1);
break;
case float_normalized:
setcc(C2 | C1);
break;
}
}
/*
* The C1 flag is set to the sign of the value in ST(0), regardless
* of whether the register is empty or full.
*/
if (!sign)
clear_C1();
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi));
return 0;
}

View File

@@ -1,131 +0,0 @@
/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
(and not one of RC_RND or RC_UP).
*/
#define DOWN_OR_CHOP() (fpu_state.cwd & FPU_CW_RC & FPU_RC_DOWN)
static __inline floatx80
FPU_round_const(const floatx80 a, int adj)
{
floatx80 result = a;
result.fraction += adj;
return result;
}
static int
sf_FLDL2T(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(FPU_round_const(Const_L2T, (fpu_state.cwd & FPU_CW_RC) == X87_ROUNDING_UP), 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi));
return 0;
}
static int
sf_FLDL2E(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(FPU_round_const(Const_L2E, DOWN_OR_CHOP() ? -1 : 0), 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi));
return 0;
}
static int
sf_FLDPI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(FPU_round_const(Const_PI, DOWN_OR_CHOP() ? -1 : 0), 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi));
return 0;
}
static int
sf_FLDEG2(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(FPU_round_const(Const_LG2, DOWN_OR_CHOP() ? -1 : 0), 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi));
return 0;
}
static int
sf_FLDLN2(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(FPU_round_const(Const_LN2, DOWN_OR_CHOP() ? -1 : 0), 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi));
return 0;
}
static int
sf_FLD1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(Const_1, 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi));
return 0;
}
static int
sf_FLDZ(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (!IS_TAG_EMPTY(-1))
FPU_stack_overflow(fetchdat);
else {
FPU_push();
FPU_save_regi(Const_Z, 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi));
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,134 +0,0 @@
static int
sf_FXCH_sti(uint32_t fetchdat)
{
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
floatx80 st0_reg, sti_reg;
int st0_tag, sti_tag;
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
st0_tag = FPU_gettagi(0);
sti_tag = FPU_gettagi(fetchdat & 7);
st0_reg = FPU_read_regi(0);
sti_reg = FPU_read_regi(fetchdat & 7);
clear_C1();
if ((st0_tag == X87_TAG_EMPTY) || (sti_tag == X87_TAG_EMPTY)) {
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
if (is_IA_masked()) {
/* Masked response */
if (st0_tag == X87_TAG_EMPTY)
st0_reg = floatx80_default_nan;
if (sti_tag == X87_TAG_EMPTY)
sti_reg = floatx80_default_nan;
} else
goto next_ins;
}
FPU_save_regi(st0_reg, fetchdat & 7);
FPU_save_regi(sti_reg, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi));
return 0;
}
static int
sf_FCHS(uint32_t fetchdat)
{
floatx80 st0_reg;
floatx80 result;
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
if (IS_TAG_EMPTY(0))
FPU_stack_underflow(fetchdat, 0, 0);
else {
clear_C1();
st0_reg = FPU_read_regi(0);
result = floatx80_chs(st0_reg);
FPU_save_regi(result, 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi));
return 0;
}
static int
sf_FABS(uint32_t fetchdat)
{
floatx80 st0_reg;
floatx80 result;
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
if (IS_TAG_EMPTY(0))
FPU_stack_underflow(fetchdat, 0, 0);
else {
clear_C1();
st0_reg = FPU_read_regi(0);
result = floatx80_abs(st0_reg);
FPU_save_regi(result, 0);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi));
return 0;
}
static int
sf_FDECSTP(uint32_t fetchdat)
{
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
fpu_state.tos = (fpu_state.tos - 1) & 7;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi));
return 0;
}
static int
sf_FINCSTP(uint32_t fetchdat)
{
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
fpu_state.tos = (fpu_state.tos + 1) & 7;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi));
return 0;
}
static int
sf_FFREE_sti(uint32_t fetchdat)
{
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
FPU_settagi(X87_TAG_EMPTY, fetchdat & 7);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi));
return 0;
}
static int
sf_FFREEP_sti(uint32_t fetchdat)
{
FP_ENTER();
FPU_check_pending_exceptions();
cpu_state.pc++;
clear_C1();
FPU_settagi(X87_TAG_EMPTY, fetchdat & 7);
if (cpu_state.abrt)
return 1;
FPU_pop();
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi));
return 0;
}

View File

@@ -1,593 +0,0 @@
static uint32_t
fpu_save_environment(void)
{
int tag;
unsigned offset;
/* read all registers in stack order and update x87 tag word */
for (int n = 0; n < 8; n++) {
// update tag only if it is not empty
if (!IS_TAG_EMPTY(n)) {
tag = FPU_tagof(FPU_read_regi(n));
FPU_settagi(tag, n);
}
}
fpu_state.swd = (fpu_state.swd & ~(7 << 11)) | ((fpu_state.tos & 7) << 11);
switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) {
case 0x000: { /*16-bit real mode*/
uint16_t tmp;
uint32_t fp_ip, fp_dp;
fp_ip = ((uint32_t)(fpu_state.fcs << 4)) | fpu_state.fip;
fp_dp = ((uint32_t)(fpu_state.fds << 4)) | fpu_state.fdp;
tmp = i387_get_control_word();
writememw(easeg, cpu_state.eaaddr + 0x00, tmp);
tmp = i387_get_status_word();
writememw(easeg, cpu_state.eaaddr + 0x02, tmp);
tmp = fpu_state.tag;
writememw(easeg, cpu_state.eaaddr + 0x04, tmp);
tmp = fp_ip & 0xffff;
writememw(easeg, cpu_state.eaaddr + 0x06, tmp);
tmp = (uint16_t)((fp_ip & 0xf0000) >> 4) | fpu_state.foo;
writememw(easeg, cpu_state.eaaddr + 0x08, tmp);
tmp = fp_dp & 0xffff;
writememw(easeg, cpu_state.eaaddr + 0x0a, tmp);
tmp = (uint16_t)((fp_dp & 0xf0000) >> 4);
writememw(easeg, cpu_state.eaaddr + 0x0c, tmp);
offset = 0x0e;
}
break;
case 0x001: {/*16-bit protected mode*/
uint16_t tmp;
tmp = i387_get_control_word();
writememw(easeg, cpu_state.eaaddr + 0x00, tmp);
tmp = i387_get_status_word();
writememw(easeg, cpu_state.eaaddr + 0x02, tmp);
tmp = fpu_state.tag;
writememw(easeg, cpu_state.eaaddr + 0x04, tmp);
tmp = (uint16_t)(fpu_state.fip) & 0xffff;
writememw(easeg, cpu_state.eaaddr + 0x06, tmp);
tmp = fpu_state.fcs;
writememw(easeg, cpu_state.eaaddr + 0x08, tmp);
tmp = (uint16_t)(fpu_state.fdp) & 0xffff;
writememw(easeg, cpu_state.eaaddr + 0x0a, tmp);
tmp = fpu_state.fds;
writememw(easeg, cpu_state.eaaddr + 0x0c, tmp);
offset = 0x0e;
}
break;
case 0x100: { /*32-bit real mode*/
uint32_t tmp, fp_ip, fp_dp;
fp_ip = ((uint32_t)(fpu_state.fcs << 4)) | fpu_state.fip;
fp_dp = ((uint32_t)(fpu_state.fds << 4)) | fpu_state.fdp;
tmp = 0xffff0000 | i387_get_control_word();
writememl(easeg, cpu_state.eaaddr + 0x00, tmp);
tmp = 0xffff0000 | i387_get_status_word();
writememl(easeg, cpu_state.eaaddr + 0x04, tmp);
tmp = 0xffff0000 | fpu_state.tag;
writememl(easeg, cpu_state.eaaddr + 0x08, tmp);
tmp = 0xffff0000 | (fp_ip & 0xffff);
writememl(easeg, cpu_state.eaaddr + 0x0c, tmp);
tmp = ((fp_ip & 0xffff0000) >> 4) | fpu_state.foo;
writememl(easeg, cpu_state.eaaddr + 0x10, tmp);
tmp = 0xffff0000 | (fp_dp & 0xffff);
writememl(easeg, cpu_state.eaaddr + 0x14, tmp);
tmp = (fp_dp & 0xffff0000) >> 4;
writememl(easeg, cpu_state.eaaddr + 0x18, tmp);
offset = 0x1c;
}
break;
case 0x101: { /*32-bit protected mode*/
uint32_t tmp;
tmp = 0xffff0000 | i387_get_control_word();
writememl(easeg, cpu_state.eaaddr + 0x00, tmp);
tmp = 0xffff0000 | i387_get_status_word();
writememl(easeg, cpu_state.eaaddr + 0x04, tmp);
tmp = 0xffff0000 | fpu_state.tag;
writememl(easeg, cpu_state.eaaddr + 0x08, tmp);
tmp = (uint32_t)(fpu_state.fip);
writememl(easeg, cpu_state.eaaddr + 0x0c, tmp);
tmp = fpu_state.fcs | (((uint32_t)(fpu_state.foo)) << 16);
writememl(easeg, cpu_state.eaaddr + 0x10, tmp);
tmp = (uint32_t)(fpu_state.fdp);
writememl(easeg, cpu_state.eaaddr + 0x14, tmp);
tmp = 0xffff0000 | fpu_state.fds;
writememl(easeg, cpu_state.eaaddr + 0x18, tmp);
offset = 0x1c;
}
break;
}
return (cpu_state.eaaddr + offset);
}
static uint32_t
fpu_load_environment(void)
{
unsigned offset;
switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) {
case 0x000: { /*16-bit real mode*/
uint16_t tmp;
uint32_t fp_ip, fp_dp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c);
fp_dp = (tmp & 0xf000) << 4;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a);
fpu_state.fdp = fp_dp | tmp;
fpu_state.fds = 0;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x08);
fp_ip = (tmp & 0xf000) << 4;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x06);
fpu_state.fip = fp_ip | tmp;
fpu_state.fcs = 0;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x04);
fpu_state.tag = tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x02);
fpu_state.swd = tmp;
fpu_state.tos = (tmp >> 11) & 7;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x00);
fpu_state.cwd = tmp;
offset = 0x0e;
}
break;
case 0x001: {/*16-bit protected mode*/
uint16_t tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x0c);
fpu_state.fds = tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x0a);
fpu_state.fdp = tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x08);
fpu_state.fcs = tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x06);
fpu_state.fip = tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x04);
fpu_state.tag = tmp;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x02);
fpu_state.swd = tmp;
fpu_state.tos = (tmp >> 11) & 7;
tmp = readmemw(easeg, cpu_state.eaaddr + 0x00);
fpu_state.cwd = tmp;
offset = 0x0e;
}
break;
case 0x100: { /*32-bit real mode*/
uint32_t tmp, fp_ip, fp_dp;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x18);
fp_dp = (tmp & 0x0ffff000) << 4;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x14);
fp_dp |= (tmp & 0xffff);
fpu_state.fdp = fp_dp;
fpu_state.fds = 0;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x10);
fpu_state.foo = tmp & 0x07ff;
fp_ip = (tmp & 0x0ffff000) << 4;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c);
fp_ip |= (tmp & 0xffff);
fpu_state.fip = fp_ip;
fpu_state.fcs = 0;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x08);
fpu_state.tag = tmp & 0xffff;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x04);
fpu_state.swd = tmp & 0xffff;
fpu_state.tos = (tmp >> 11) & 7;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x00);
fpu_state.cwd = tmp & 0xffff;
offset = 0x1c;
}
break;
case 0x101: { /*32-bit protected mode*/
uint32_t tmp;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x18);
fpu_state.fds = tmp & 0xffff;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x14);
fpu_state.fdp = tmp;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x10);
fpu_state.fcs = tmp & 0xffff;
fpu_state.foo = (tmp >> 16) & 0x07ff;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x0c);
fpu_state.fip = tmp;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x08);
fpu_state.tag = tmp & 0xffff;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x04);
fpu_state.swd = tmp & 0xffff;
fpu_state.tos = (tmp >> 11) & 7;
tmp = readmeml(easeg, cpu_state.eaaddr + 0x00);
fpu_state.cwd = tmp & 0xffff;
offset = 0x1c;
}
break;
}
/* always set bit 6 as '1 */
fpu_state.cwd = (fpu_state.cwd & ~FPU_CW_Reserved_Bits) | 0x0040;
/* check for unmasked exceptions */
if (fpu_state.swd & ~fpu_state.cwd & FPU_CW_Exceptions_Mask) {
/* set the B and ES bits in the status-word */
fpu_state.swd |= (FPU_SW_Summary | FPU_SW_Backward);
} else {
/* clear the B and ES bits in the status-word */
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
return (cpu_state.eaaddr + offset);
}
static int
sf_FLDCW_a16(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
fpu_state.cwd = (tempw & ~FPU_CW_Reserved_Bits) | 0x0040; // bit 6 is reserved as '1
/* check for unmasked exceptions */
if (fpu_state.swd & (~fpu_state.cwd & FPU_CW_Exceptions_Mask)) {
/* set the B and ES bits in the status-word */
fpu_state.swd |= (FPU_SW_Summary | FPU_SW_Backward);
} else {
/* clear the B and ES bits in the status-word */
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi));
return 0;
}
#ifndef FPU_8087
static int
sf_FLDCW_a32(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt)
return 1;
fpu_state.cwd = (tempw & ~FPU_CW_Reserved_Bits) | 0x0040; // bit 6 is reserved as '1
/* check for unmasked exceptions */
if (fpu_state.swd & (~fpu_state.cwd & FPU_CW_Exceptions_Mask)) {
/* set the B and ES bits in the status-word */
fpu_state.swd |= (FPU_SW_Summary | FPU_SW_Backward);
} else {
/* clear the B and ES bits in the status-word */
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi));
return 0;
}
#endif
static int
sf_FNSTCW_a16(uint32_t fetchdat)
{
uint16_t cwd = i387_get_control_word();
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(cwd);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi));
return cpu_state.abrt;
}
#ifndef FPU_8087
static int
sf_FNSTCW_a32(uint32_t fetchdat)
{
uint16_t cwd = i387_get_control_word();
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(cwd);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi));
return cpu_state.abrt;
}
#endif
static int
sf_FNSTSW_a16(uint32_t fetchdat)
{
uint16_t swd = i387_get_status_word();
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(swd);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi));
return cpu_state.abrt;
}
#ifndef FPU_8087
static int
sf_FNSTSW_a32(uint32_t fetchdat)
{
uint16_t swd = i387_get_status_word();
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(swd);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi));
return cpu_state.abrt;
}
#endif
#ifdef FPU_8087
static int
sf_FI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_state.cwd &= ~FPU_SW_Summary;
if (rmdat == 0xe1)
fpu_state.cwd |= FPU_SW_Summary;
wait(3, 0);
return 0;
}
#else
static int
sf_FNSTSW_AX(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
AX = i387_get_status_word();
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi));
return 0;
}
#endif
static int
sf_FRSTOR_a16(uint32_t fetchdat)
{
floatx80 tmp;
int offset;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
offset = fpu_load_environment();
for (int n = 0; n < 8; n++) {
tmp.fraction = readmemq(easeg, offset + (n * 10));
tmp.exp = readmemw(easeg, offset + (n * 10) + 8);
FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi));
return cpu_state.abrt;
}
#ifndef FPU_8087
static int
sf_FRSTOR_a32(uint32_t fetchdat)
{
floatx80 tmp;
int offset;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
offset = fpu_load_environment();
for (int n = 0; n < 8; n++) {
tmp.fraction = readmemq(easeg, offset + (n * 10));
tmp.exp = readmemw(easeg, offset + (n * 10) + 8);
FPU_save_regi_tag(tmp, IS_TAG_EMPTY(n) ? X87_TAG_EMPTY : FPU_tagof(tmp), n);
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi));
return cpu_state.abrt;
}
#endif
static int
sf_FNSAVE_a16(uint32_t fetchdat)
{
floatx80 stn;
int offset;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
offset = fpu_save_environment();
/* save all registers in stack order. */
for (int m = 0; m < 8; m++) {
stn = FPU_read_regi(m);
writememq(easeg, offset + (m * 10), stn.fraction);
writememw(easeg, offset + (m * 10) + 8, stn.exp);
}
#ifdef FPU_8087
fpu_state.swd = 0x3FF;
#else
fpu_state.cwd = 0x37F;
#endif
fpu_state.swd = 0;
fpu_state.tos = 0;
fpu_state.tag = 0xffff;
cpu_state.ismmx = 0;
fpu_state.foo = 0;
fpu_state.fds = 0;
fpu_state.fdp = 0;
fpu_state.fcs = 0;
fpu_state.fip = 0;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi));
return cpu_state.abrt;
}
#ifndef FPU_8087
static int
sf_FNSAVE_a32(uint32_t fetchdat)
{
floatx80 stn;
int offset;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
offset = fpu_save_environment();
/* save all registers in stack order. */
for (int m = 0; m < 8; m++) {
stn = FPU_read_regi(m);
writememq(easeg, offset + (m * 10), stn.fraction);
writememw(easeg, offset + (m * 10) + 8, stn.exp);
}
#ifdef FPU_8087
fpu_state.swd = 0x3FF;
#else
fpu_state.cwd = 0x37F;
#endif
fpu_state.swd = 0;
fpu_state.tos = 0;
fpu_state.tag = 0xffff;
cpu_state.ismmx = 0;
fpu_state.foo = 0;
fpu_state.fds = 0;
fpu_state.fdp = 0;
fpu_state.fcs = 0;
fpu_state.fip = 0;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi));
return cpu_state.abrt;
}
#endif
static int
sf_FNCLEX(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
fpu_state.swd &= ~(FPU_SW_Backward | FPU_SW_Summary | FPU_SW_Stack_Fault | FPU_SW_Precision |
FPU_SW_Underflow | FPU_SW_Overflow | FPU_SW_Zero_Div | FPU_SW_Denormal_Op |
FPU_SW_Invalid);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi));
return 0;
}
static int
sf_FNINIT(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
#ifdef FPU_8087
fpu_state.cwd = 0x3FF;
#else
fpu_state.cwd = 0x37F;
#endif
fpu_state.swd = 0;
fpu_state.tos = 0;
fpu_state.tag = 0xffff;
fpu_state.foo = 0;
fpu_state.fds = 0;
fpu_state.fdp = 0;
fpu_state.fcs = 0;
fpu_state.fip = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi));
CPU_BLOCK_END();
return 0;
}
static int
sf_FLDENV_a16(uint32_t fetchdat)
{
int tag;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
fpu_load_environment();
/* read all registers in stack order and update x87 tag word */
for (int n = 0; n < 8; n++) {
// update tag only if it is not empty
if (!IS_TAG_EMPTY(n)) {
tag = FPU_tagof(FPU_read_regi(n));
FPU_settagi(tag, n);
}
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi));
return cpu_state.abrt;
}
#ifndef FPU_8087
static int
sf_FLDENV_a32(uint32_t fetchdat)
{
int tag;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
fpu_load_environment();
/* read all registers in stack order and update x87 tag word */
for (int n = 0; n < 8; n++) {
// update tag only if it is not empty
if (!IS_TAG_EMPTY(n)) {
tag = FPU_tagof(FPU_read_regi(n));
FPU_settagi(tag, n);
}
}
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi));
return cpu_state.abrt;
}
#endif
static int
sf_FNSTENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
fpu_save_environment();
/* mask all floating point exceptions */
fpu_state.cwd |= FPU_CW_Exceptions_Mask;
/* clear the B and ES bits in the status word */
fpu_state.swd &= ~(FPU_SW_Backward|FPU_SW_Summary);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi));
return cpu_state.abrt;
}
#ifndef FPU_8087
static int
sf_FNSTENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
fpu_save_environment();
/* mask all floating point exceptions */
fpu_state.cwd |= FPU_CW_Exceptions_Mask;
/* clear the B and ES bits in the status word */
fpu_state.swd &= ~(FPU_SW_Backward|FPU_SW_Summary);
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi));
return cpu_state.abrt;
}
#endif
static int
sf_FNOP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi));
return 0;
}

View File

@@ -1,418 +0,0 @@
static int
sf_F2XM1(uint32_t fetchdat)
{
floatx80 result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
result = f2xm1(FPU_read_regi(0), &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi));
return 0;
}
static int
sf_FYL2X(uint32_t fetchdat)
{
floatx80 result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_stack_underflow(fetchdat, 1, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
result = fyl2x(FPU_read_regi(0), FPU_read_regi(1), &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_pop();
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi));
return 0;
}
static int
sf_FPTAN(uint32_t fetchdat)
{
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
floatx80 y;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
clear_C2();
if (IS_TAG_EMPTY(0) || !IS_TAG_EMPTY(-1)) {
if (IS_TAG_EMPTY(0))
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
else
FPU_exception(fetchdat, FPU_EX_Stack_Overflow, 0);
/* The masked response */
if (is_IA_masked()) {
FPU_save_regi(floatx80_default_nan, 0);
FPU_push();
FPU_save_regi(floatx80_default_nan, 0);
}
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
y = FPU_read_regi(0);
if (ftan(&y, &status) == -1) {
fpu_state.swd |= C2;
goto next_ins;
}
if (floatx80_is_nan(y)) {
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(y, 0);
FPU_push();
FPU_save_regi(y, 0);
}
goto next_ins;
}
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(y, 0);
FPU_push();
FPU_save_regi(Const_1, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi));
return 0;
}
static int
sf_FPATAN(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_stack_underflow(fetchdat, 1, 1);
goto next_ins;
}
a = FPU_read_regi(0);
b = FPU_read_regi(1);
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
result = fpatan(a, b, &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_pop();
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi));
return 0;
}
static int
sf_FXTRACT(uint32_t fetchdat)
{
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
struct float_status_t status;
floatx80 a, b;
FP_ENTER();
cpu_state.pc++;
clear_C1();
#if 0 //TODO
if ((IS_TAG_EMPTY(0) || IS_TAG_EMPTY(-1))) {
if (IS_TAG_EMPTY(0))
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
else
FPU_exception(fetchdat, FPU_EX_Stack_Overflow, 0);
/* The masked response */
if (is_IA_masked()) {
FPU_save_regi(floatx80_default_nan, 0);
FPU_push();
FPU_save_regi(floatx80_default_nan, 0);
}
goto next_ins;
}
#endif
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = floatx80_extract(&a, &status);
if (!FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(b, 0); // exponent
FPU_push();
FPU_save_regi(a, 0); // fraction
}
#if 0 //TODO.
next_ins:
#endif
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxtract) : (x87_timings.fxtract * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxtract) : (x87_concurrency.fxtract * cpu_multi));
return 0;
}
static int
sf_FPREM1(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
uint64_t quotient = 0;
int flags, cc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
clear_C2();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(1);
flags = floatx80_ieee754_remainder(a, b, &result, &quotient, &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
if (flags >= 0) {
cc = 0;
if (flags)
cc = C2;
else {
if (quotient & 1)
cc |= C1;
if (quotient & 2)
cc |= C3;
if (quotient & 4)
cc |= C0;
}
setcc(cc);
}
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi));
return 0;
}
static int
sf_FPREM(uint32_t fetchdat)
{
floatx80 a, b, result;
struct float_status_t status;
uint64_t quotient = 0;
int flags, cc;
FP_ENTER();
cpu_state.pc++;
clear_C1();
clear_C2();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
a = FPU_read_regi(0);
b = FPU_read_regi(1);
// handle unsupported extended double-precision floating encodings
flags = floatx80_remainder(a, b, &result, &quotient, &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
if (flags >= 0) {
cc = 0;
if (flags)
cc = C2;
else {
if (quotient & 1)
cc |= C1;
if (quotient & 2)
cc |= C3;
if (quotient & 4)
cc |= C0;
}
setcc(cc);
}
FPU_save_regi(result, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi));
return 0;
}
static int
sf_FYL2XP1(uint32_t fetchdat)
{
floatx80 result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_stack_underflow(fetchdat, 1, 1);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
result = fyl2xp1(FPU_read_regi(0), FPU_read_regi(1), &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(result, 1);
FPU_pop();
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi));
return 0;
}
#ifndef FPU_8087
static int
sf_FSINCOS(uint32_t fetchdat)
{
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
struct float_status_t status;
floatx80 y, sin_y, cos_y;
FP_ENTER();
cpu_state.pc++;
clear_C1();
clear_C2();
if (IS_TAG_EMPTY(0) || !IS_TAG_EMPTY(-1)) {
if (IS_TAG_EMPTY(0))
FPU_exception(fetchdat, FPU_EX_Stack_Underflow, 0);
else
FPU_exception(fetchdat, FPU_EX_Stack_Overflow, 0);
/* The masked response */
if (is_IA_masked()) {
FPU_save_regi(floatx80_default_nan, 0);
FPU_push();
FPU_save_regi(floatx80_default_nan, 0);
}
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
y = FPU_read_regi(0);
if (fsincos(y, &sin_y, &cos_y, &status) == -1) {
fpu_state.swd |= C2;
goto next_ins;
}
if (! FPU_exception(fetchdat, status.float_exception_flags, 0)) {
FPU_save_regi(sin_y, 0);
FPU_push();
FPU_save_regi(cos_y, 0);
}
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi));
return 0;
}
#endif
static int
sf_FSCALE(uint32_t fetchdat)
{
floatx80 result;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word());
result = floatx80_scale(FPU_read_regi(0), FPU_read_regi(1), &status);
if (! FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(result, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi));
return 0;
}
#ifndef FPU_8087
static int
sf_FSIN(uint32_t fetchdat)
{
floatx80 y;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
clear_C2();
if (IS_TAG_EMPTY(0)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
y = FPU_read_regi(0);
if (fsin(&y, &status) == -1) {
fpu_state.swd |= C2;
goto next_ins;
}
if (! FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(y, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi));
return 0;
}
static int
sf_FCOS(uint32_t fetchdat)
{
floatx80 y;
struct float_status_t status;
FP_ENTER();
cpu_state.pc++;
clear_C1();
clear_C2();
if (IS_TAG_EMPTY(0)) {
FPU_stack_underflow(fetchdat, 0, 0);
goto next_ins;
}
status = i387cw_to_softfloat_status_word(i387_get_control_word() | FPU_PR_80_BITS);
y = FPU_read_regi(0);
if (fcos(&y, &status) == -1) {
fpu_state.swd |= C2;
goto next_ins;
}
if (! FPU_exception(fetchdat, status.float_exception_flags, 0))
FPU_save_regi(y, 0);
next_ins:
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi));
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi));
return 0;
}
#endif