Implemented the x87 instruction FXTRACT.

This commit is contained in:
OBattler
2023-04-29 18:05:20 +02:00
parent 7ea34dbb1d
commit 19ce34787d
2 changed files with 30 additions and 5 deletions

View File

@@ -46,6 +46,17 @@ static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARD
#define STATUS_ZERODIVIDE 4
typedef union
{
double d;
struct {
unsigned int mantissa:52;
unsigned int exponent:11;
unsigned int negative:1;
};
} double_decompose;
#if defined(_MSC_VER) && !defined(__clang__)
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
# define X87_INLINE_ASM
@@ -570,7 +581,7 @@ const OpFn OP_TABLE(fpu_8087_d9)[256] = {
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/
opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP,
opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16
// clang-format on
};
@@ -839,7 +850,7 @@ const OpFn OP_TABLE(fpu_287_d9_a16)[256] = {
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/
opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP,
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
// clang-format on
};
@@ -879,7 +890,7 @@ const OpFn OP_TABLE(fpu_287_d9_a32)[256] = {
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, /*Invalid*/
opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP,
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
// clang-format on
};
@@ -919,7 +930,7 @@ const OpFn OP_TABLE(fpu_d9_a16)[256] = {
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/
opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP,
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
// clang-format on
};
@@ -959,7 +970,7 @@ const OpFn OP_TABLE(fpu_d9_a32)[256] = {
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/
opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, opFXTRACT, opFPREM1, opFDECSTP, opFINCSTP,
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
// clang-format on
};

View File

@@ -33,6 +33,20 @@ opFNOP(uint32_t fetchdat)
return 0;
}
static int
opFXTRACT(uint32_t fetchdat)
{
double_decompose_t temp = (double_decompose_t) ST(0);
FP_ENTER();
cpu_state.pc++;
ST(0) = (double) temp.exponent;
x87_push((double) temp.mantissa);
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
opFCLEX(uint32_t fetchdat)
{