mirror of
https://github.com/86Box/86Box.git
synced 2026-02-26 05:53:15 -07:00
PADDSIW, PSUBSIW, PMULHRW (named PMULHRWC in the code as recognized by some assemblers), PMULHRIW, PDISTIB, PMACHRIW, PAVEB, PMAGW, PMVZB, PMVNZB, PMVLZB, PMVGEZB, FTSTP, FRINT2, FRINEAR, FRICHOP are implemented for Cyrix 6x86MX. Cyrix 6x86(L) only has the last 4 instructions.
884 lines
48 KiB
C
884 lines
48 KiB
C
#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 softfloat_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 = extF80_add(a, use_var, &status); \
|
|
\
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_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 = extF80_div(a, use_var, &status); \
|
|
} \
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_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 = extF80_div(use_var, a, &status); \
|
|
} \
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_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 = extF80_mul(a, use_var, &status); \
|
|
} \
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_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 = extF80_sub(a, use_var, &status); \
|
|
\
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_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 = extF80_sub(use_var, a, &status); \
|
|
\
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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(), f32_to_extF80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32)
|
|
#ifndef FPU_8087
|
|
sf_FPU(s, float32, 32, temp, geteal(), f32_to_extF80(temp, &status), FPU_handle_NaN32(a, temp, &result, &status), _32)
|
|
#endif
|
|
sf_FPU(d, float64, 16, temp, geteaq(), f64_to_extF80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64)
|
|
#ifndef FPU_8087
|
|
sf_FPU(d, float64, 32, temp, geteaq(), f64_to_extF80(temp, &status), FPU_handle_NaN64(a, temp, &result, &status), _64)
|
|
#endif
|
|
|
|
sf_FPU(iw, uint16_t, 16, temp, geteaw(), i32_to_extF80((int16_t)temp), 0, _i16)
|
|
#ifndef FPU_8087
|
|
sf_FPU(iw, uint16_t, 32, temp, geteaw(), i32_to_extF80((int16_t)temp), 0, _i16)
|
|
#endif
|
|
sf_FPU(il, uint32_t, 16, temp, geteal(), i32_to_extF80((int32_t)temp), 0, _i32)
|
|
#ifndef FPU_8087
|
|
sf_FPU(il, uint32_t, 32, temp, geteal(), i32_to_extF80((int32_t)temp), 0, _i32)
|
|
#endif
|
|
// clang-format on
|
|
|
|
static int sf_FADD_st0_stj(uint32_t fetchdat)
|
|
{
|
|
floatx80 a;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_add(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_add(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_add(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_div(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_div(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_div(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(fetchdat & 7);
|
|
b = FPU_read_regi(0);
|
|
result = extF80_div(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(0);
|
|
b = FPU_read_regi(fetchdat & 7);
|
|
result = extF80_div(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(0);
|
|
b = FPU_read_regi(fetchdat & 7);
|
|
result = extF80_div(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_mul(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(0);
|
|
b = FPU_read_regi(fetchdat & 7);
|
|
result = extF80_mul(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_mul(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_sub(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_sub(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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 = extF80_sub(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(fetchdat & 7);
|
|
b = FPU_read_regi(0);
|
|
result = extF80_sub(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(0);
|
|
b = FPU_read_regi(fetchdat & 7);
|
|
result = extF80_sub(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
floatx80 b;
|
|
floatx80 result;
|
|
struct softfloat_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(0);
|
|
b = FPU_read_regi(fetchdat & 7);
|
|
result = extF80_sub(a, b, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_status_t status;
|
|
|
|
FP_ENTER();
|
|
FPU_check_pending_exceptions();
|
|
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 = extF80_sqrt(FPU_read_regi(0), &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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 softfloat_status_t status;
|
|
|
|
FP_ENTER();
|
|
FPU_check_pending_exceptions();
|
|
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 = extF80_roundToInt_normal(FPU_read_regi(0), &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
}
|
|
|
|
static int
|
|
sf_FRINT2(uint32_t fetchdat)
|
|
{
|
|
floatx80 result;
|
|
struct softfloat_status_t status;
|
|
|
|
FP_ENTER();
|
|
FPU_check_pending_exceptions();
|
|
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 = extF80_roundToInt(FPU_read_regi(0), softfloat_round_near_maxMag, true, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
}
|
|
|
|
static int
|
|
sf_FRINEAR(uint32_t fetchdat)
|
|
{
|
|
floatx80 result;
|
|
struct softfloat_status_t status;
|
|
|
|
FP_ENTER();
|
|
FPU_check_pending_exceptions();
|
|
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 = extF80_roundToInt(FPU_read_regi(0), softfloat_round_near_even, true, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
}
|
|
|
|
static int
|
|
sf_FRICHOP(uint32_t fetchdat)
|
|
{
|
|
floatx80 result;
|
|
struct softfloat_status_t status;
|
|
|
|
FP_ENTER();
|
|
FPU_check_pending_exceptions();
|
|
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 = extF80_roundToInt(FPU_read_regi(0), softfloat_round_to_zero, true, &status);
|
|
|
|
if (!FPU_exception(fetchdat, status.softfloat_exceptionFlags, 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;
|
|
}
|