Merge pull request #1585 from CallumDev/x87f64

Emulate reduced-precision X87 with 64-bit host FPU ops
This commit is contained in:
Ryan Houdek authored and GitHub committed 2022-04-21 09:22:03 -07:00
commit 42a6320935
132 files changed
+5314 -1

No files matched your search

+1
View File
@@ -89,6 +89,7 @@ set (SRCS
Interface/Core/OpcodeDispatcher/Flags.cpp
Interface/Core/OpcodeDispatcher/Vector.cpp
Interface/Core/OpcodeDispatcher/X87.cpp
Interface/Core/OpcodeDispatcher/X87F64.cpp
Interface/Core/OpcodeDispatcher.cpp
Interface/Core/SignalDelegator.cpp
Interface/Core/X86Tables.cpp
@@ -241,6 +241,13 @@
"Highly likely to break any multithreaded application if disabled."
]
},
"X87ReducedPrecision": {
"Type": "bool",
"Default": "false",
"Desc": [
"Emulates X87 floating point using 64-bit precision. This reduces emulation accuracy and may result in rendering bugs."
]
},
"ABILocalFlags": {
"Type": "bool",
"Default": "false",
@@ -356,6 +356,81 @@ DEF_OP(F80BCDSTORE) {
memcpy(GDP, BCD, 10);
}
DEF_OP(F64SIN) {
auto Op = IROp->C<IR::IROp_F64SIN>();
double Src = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Tmp = sin(Src);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64COS) {
auto Op = IROp->C<IR::IROp_F64COS>();
double Src = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Tmp = cos(Src);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64TAN) {
auto Op = IROp->C<IR::IROp_F64TAN>();
double Src = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Tmp = tan(Src);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64F2XM1) {
auto Op = IROp->C<IR::IROp_F64F2XM1>();
double Src = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Tmp = exp2(Src) - 1.0;
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64ATAN) {
auto Op = IROp->C<IR::IROp_F64ATAN>();
double Src1 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Src2 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[1]);
double Tmp = atan2(Src1, Src2);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64FPREM) {
auto Op = IROp->C<IR::IROp_F64FPREM>();
double Src1 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Src2 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[1]);
double Tmp = fmod(Src1, Src2);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64FPREM1) {
auto Op = IROp->C<IR::IROp_F64FPREM1>();
double Src1 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Src2 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[1]);
double Tmp = remainder(Src1, Src2);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64FYL2X) {
auto Op = IROp->C<IR::IROp_F64FYL2X>();
double Src1 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Src2 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[1]);
double Tmp = Src2 * log2(Src1);
memcpy(GDP, &Tmp, sizeof(double));
}
DEF_OP(F64SCALE) {
auto Op = IROp->C<IR::IROp_F64SCALE>();
double Src1 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[0]);
double Src2 = *GetSrc<double*>(Data->SSAData, Op->Header.Args[1]);
double trunc = (double)(int64_t)(Src2); //truncate
double Tmp = Src1 * exp2(trunc);
memcpy(GDP, &Tmp, sizeof(double));
}
#undef DEF_OP
} // namespace FEXCore::CPU
@@ -222,6 +222,73 @@ struct OpHandlers<IR::OP_F80SCALE> {
}
};
template<>
struct OpHandlers<IR::OP_F64SIN> {
static double handle(double src) {
return sin(src);
}
};
template<>
struct OpHandlers<IR::OP_F64COS> {
static double handle(double src) {
return cos(src);
}
};
template<>
struct OpHandlers<IR::OP_F64TAN> {
static double handle(double src) {
return tan(src);
}
};
template<>
struct OpHandlers<IR::OP_F64F2XM1> {
static double handle(double src) {
return exp2(src) - 1.0;
}
};
template<>
struct OpHandlers<IR::OP_F64ATAN> {
static double handle(double src1, double src2) {
return atan2(src1, src2);
}
};
template<>
struct OpHandlers<IR::OP_F64FPREM> {
static double handle(double src1, double src2) {
return fmod(src1, src2);
}
};
template<>
struct OpHandlers<IR::OP_F64FPREM1> {
static double handle(double src1, double src2) {
return remainder(src1, src2);
}
};
template<>
struct OpHandlers<IR::OP_F64FYL2X> {
static double handle(double src1, double src2) {
return src2 * log2(src1);
}
};
template<>
struct OpHandlers<IR::OP_F64SCALE> {
static double handle(double src1, double src2) {
double trunc = (double)(int64_t)(src2); //truncate
return src1 * exp2(trunc);
}
};
template<>
struct OpHandlers<IR::OP_F80BCDSTORE> {
static X80SoftFloat handle(X80SoftFloat Src1) {
@@ -47,6 +47,16 @@ FallbackInfo GetFallbackInfo(double(*fn)(X80SoftFloat), FEXCore::Core::FallbackH
return {FABI_F64_F80, (void*)fn, HandlerIndex};
}
template<>
FallbackInfo GetFallbackInfo(double(*fn)(double), FEXCore::Core::FallbackHandlerIndex HandlerIndex) {
return {FABI_F64_F64, (void*)fn, HandlerIndex};
}
template<>
FallbackInfo GetFallbackInfo(double(*fn)(double,double), FEXCore::Core::FallbackHandlerIndex HandlerIndex) {
return {FABI_F64_F64_F64, (void*)fn, HandlerIndex};
}
template<>
FallbackInfo GetFallbackInfo(int16_t(*fn)(X80SoftFloat), FEXCore::Core::FallbackHandlerIndex HandlerIndex) {
return {FABI_I16_F80, (void*)fn, HandlerIndex};
@@ -122,6 +132,18 @@ void InterpreterOps::FillFallbackIndexPointers(uint64_t *Info) {
Info[Core::OPINDEX_F80FPREM1] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F80FPREM1>::handle, Core::OPINDEX_F80FPREM1).fn);
Info[Core::OPINDEX_F80FPREM] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F80FPREM>::handle, Core::OPINDEX_F80FPREM).fn);
Info[Core::OPINDEX_F80SCALE] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F80SCALE>::handle, Core::OPINDEX_F80SCALE).fn);
// Double Precision
Info[Core::OPINDEX_F64SIN] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64SIN>::handle, Core::OPINDEX_F64SIN).fn);
Info[Core::OPINDEX_F64COS] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64COS>::handle, Core::OPINDEX_F64COS).fn);
Info[Core::OPINDEX_F64TAN] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64TAN>::handle, Core::OPINDEX_F64TAN).fn);
Info[Core::OPINDEX_F64ATAN] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64ATAN>::handle, Core::OPINDEX_F64ATAN).fn);
Info[Core::OPINDEX_F64F2XM1] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64F2XM1>::handle, Core::OPINDEX_F64F2XM1).fn);
Info[Core::OPINDEX_F64FYL2X] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64FYL2X>::handle, Core::OPINDEX_F64FYL2X).fn);
Info[Core::OPINDEX_F64FPREM] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64FPREM>::handle, Core::OPINDEX_F64FPREM).fn);
Info[Core::OPINDEX_F64FPREM1] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64FPREM1>::handle, Core::OPINDEX_F64FPREM1).fn);
Info[Core::OPINDEX_F64SCALE] = reinterpret_cast<uint64_t>(GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64SCALE>::handle, Core::OPINDEX_F64SCALE).fn);
}
bool InterpreterOps::GetFallbackHandler(IR::IROp_Header *IROp, FallbackInfo *Info) {
@@ -238,6 +260,12 @@ bool InterpreterOps::GetFallbackHandler(IR::IROp_Header *IROp, FallbackInfo *Inf
return true; \
}
#define COMMON_F64_OP(OP) \
case IR::OP_F64##OP: { \
*Info = GetFallbackInfo(&FEXCore::CPU::OpHandlers<IR::OP_F64##OP>::handle, Core::OPINDEX_F64##OP); \
return true; \
}
// Unary
COMMON_X87_OP(ROUND)
COMMON_X87_OP(F2XM1)
@@ -261,6 +289,19 @@ bool InterpreterOps::GetFallbackHandler(IR::IROp_Header *IROp, FallbackInfo *Inf
COMMON_X87_OP(FPREM)
COMMON_X87_OP(SCALE)
// Double Precision Unary
COMMON_F64_OP(F2XM1)
COMMON_F64_OP(TAN)
COMMON_F64_OP(SIN)
COMMON_F64_OP(COS)
// Double Precision Binary
COMMON_F64_OP(FYL2X)
COMMON_F64_OP(ATAN)
COMMON_F64_OP(FPREM1)
COMMON_F64_OP(FPREM)
COMMON_F64_OP(SCALE)
default:
break;
}
@@ -311,6 +311,17 @@ constexpr OpHandlerArray InterpreterOpHandlers = [] {
REGISTER_OP(F80BCDLOAD, F80BCDLOAD);
REGISTER_OP(F80BCDSTORE, F80BCDSTORE);
// F64 ops
REGISTER_OP(F64SIN, F64SIN);
REGISTER_OP(F64COS, F64COS);
REGISTER_OP(F64TAN, F64TAN);
REGISTER_OP(F64F2XM1, F64F2XM1);
REGISTER_OP(F64ATAN, F64ATAN);
REGISTER_OP(F64FPREM, F64FPREM);
REGISTER_OP(F64FPREM1, F64FPREM1);
REGISTER_OP(F64FYL2X, F64FYL2X);
REGISTER_OP(F64SCALE, F64SCALE);
return Handlers;
}();
@@ -28,6 +28,8 @@ namespace FEXCore::CPU {
FABI_F80_I32,
FABI_F32_F80,
FABI_F64_F80,
FABI_F64_F64,
FABI_F64_F64_F64,
FABI_I16_F80,
FABI_I32_F80,
FABI_I64_F80,
@@ -328,6 +330,17 @@ namespace FEXCore::CPU {
DEF_OP(F80CMP);
DEF_OP(F80BCDLOAD);
DEF_OP(F80BCDSTORE);
//< F64 ops
DEF_OP(F64SIN);
DEF_OP(F64COS);
DEF_OP(F64TAN);
DEF_OP(F64F2XM1);
DEF_OP(F64ATAN);
DEF_OP(F64FPREM);
DEF_OP(F64FPREM1);
DEF_OP(F64FYL2X);
DEF_OP(F64SCALE);
#undef DEF_OP
template<typename unsigned_type, typename signed_type, typename float_type>
[[nodiscard]] static bool IsConditionTrue(uint8_t Cond, uint64_t Src1, uint64_t Src2) {
@@ -198,6 +198,43 @@ void Arm64JITCore::Op_Unhandled(IR::IROp_Header *IROp, IR::NodeID Node) {
}
break;
case FABI_F64_F64: {
SpillStaticRegs();
PushDynamicRegsAndLR();
mov(v0.D(), GetSrc(IROp->Args[0].ID()).D());
ldr(x0, MemOperand(STATE, offsetof(FEXCore::Core::CpuStateFrame, Pointers.AArch64.FallbackHandlerPointers[Info.HandlerIndex])));
blr(x0);
PopDynamicRegsAndLR();
FillStaticRegs();
mov(GetDst(Node).D(), v0.D());
}
break;
case FABI_F64_F64_F64: {
SpillStaticRegs();
PushDynamicRegsAndLR();
mov(v0.D(), GetSrc(IROp->Args[0].ID()).D());
mov(v1.D(), GetSrc(IROp->Args[1].ID()).D());
ldr(x0, MemOperand(STATE, offsetof(FEXCore::Core::CpuStateFrame, Pointers.AArch64.FallbackHandlerPointers[Info.HandlerIndex])));
blr(x0);
PopDynamicRegsAndLR();
FillStaticRegs();
mov(GetDst(Node).D(), v0.D());
}
break;
case FABI_I16_F80:{
SpillStaticRegs();
@@ -191,6 +191,33 @@ void X86JITCore::Op_Unhandled(IR::IROp_Header *IROp, IR::NodeID Node) {
}
break;
case FABI_F64_F64: {
PushRegs();
movsd(xmm0, GetSrc(IROp->Args[0].ID()));
call(qword [STATE + offsetof(FEXCore::Core::CpuStateFrame, Pointers.X86.FallbackHandlerPointers[Info.HandlerIndex])]);
PopRegs();
movsd(GetDst(Node), xmm0);
}
break;
case FABI_F64_F64_F64: {
PushRegs();
movsd(xmm0, GetSrc(IROp->Args[0].ID()));
movsd(xmm1, GetSrc(IROp->Args[1].ID()));
call(qword [STATE + offsetof(FEXCore::Core::CpuStateFrame, Pointers.X86.FallbackHandlerPointers[Info.HandlerIndex])]);
PopRegs();
movsd(GetDst(Node), xmm0);
}
break;
case FABI_I16_F80:{
PushRegs();
+236 -1
View File
@@ -5953,6 +5953,236 @@ constexpr uint16_t PF_F2 = 3;
// All OPDReg versions need it
#define OPDReg(op, reg) ((1 << 15) | ((op - 0xD8) << 8) | (reg << 3))
#define OPD(op, modrmop) (((op - 0xD8) << 8) | modrmop)
constexpr std::tuple<uint16_t, uint8_t, FEXCore::X86Tables::OpDispatchPtr> X87F64OpTable[] = {
{OPDReg(0xD8, 0) | 0x00, 8, &OpDispatchBuilder::FADDF64<32, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xD8, 1) | 0x00, 8, &OpDispatchBuilder::FMULF64<32, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xD8, 2) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<32, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xD8, 3) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<32, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xD8, 4) | 0x00, 8, &OpDispatchBuilder::FSUBF64<32, false, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xD8, 5) | 0x00, 8, &OpDispatchBuilder::FSUBF64<32, false, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xD8, 6) | 0x00, 8, &OpDispatchBuilder::FDIVF64<32, false, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xD8, 7) | 0x00, 8, &OpDispatchBuilder::FDIVF64<32, false, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xD8, 0xC0), 8, &OpDispatchBuilder::FADDF64<80, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xD8, 0xC8), 8, &OpDispatchBuilder::FMULF64<80, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xD8, 0xD0), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPD(0xD8, 0xD8), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPD(0xD8, 0xE0), 8, &OpDispatchBuilder::FSUBF64<80, false, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xD8, 0xE8), 8, &OpDispatchBuilder::FSUBF64<80, false, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xD8, 0xF0), 8, &OpDispatchBuilder::FDIVF64<80, false, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xD8, 0xF8), 8, &OpDispatchBuilder::FDIVF64<80, false, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xD9, 0) | 0x00, 8, &OpDispatchBuilder::FLDF64<32>},
// 1 = Invalid
{OPDReg(0xD9, 2) | 0x00, 8, &OpDispatchBuilder::FSTF64<32>},
{OPDReg(0xD9, 3) | 0x00, 8, &OpDispatchBuilder::FSTF64<32>},
{OPDReg(0xD9, 4) | 0x00, 8, &OpDispatchBuilder::X87LDENV},
{OPDReg(0xD9, 5) | 0x00, 8, &OpDispatchBuilder::X87FLDCW}, // XXX: stubbed FLDCW
{OPDReg(0xD9, 6) | 0x00, 8, &OpDispatchBuilder::X87FNSTENV},
{OPDReg(0xD9, 7) | 0x00, 8, &OpDispatchBuilder::X87FSTCW},
{OPD(0xD9, 0xC0), 8, &OpDispatchBuilder::FLDF64<80>},
{OPD(0xD9, 0xC8), 8, &OpDispatchBuilder::FXCH},
{OPD(0xD9, 0xD0), 1, &OpDispatchBuilder::NOPOp}, // FNOP
// D1 = Invalid
// D8 = Invalid
{OPD(0xD9, 0xE0), 1, &OpDispatchBuilder::FCHSF64},
{OPD(0xD9, 0xE1), 1, &OpDispatchBuilder::FABSF64},
// E2 = Invalid
{OPD(0xD9, 0xE4), 1, &OpDispatchBuilder::FTSTF64},
{OPD(0xD9, 0xE5), 1, &OpDispatchBuilder::X87FXAMF64},
// E6 = Invalid
{OPD(0xD9, 0xE8), 1, &OpDispatchBuilder::FLDF64_Const<0x3FF0000000000000>}, // 1.0
{OPD(0xD9, 0xE9), 1, &OpDispatchBuilder::FLDF64_Const<0x400A934F0979A372>}, // log2l(10)
{OPD(0xD9, 0xEA), 1, &OpDispatchBuilder::FLDF64_Const<0x3FF71547652B82FE>}, // log2l(e)
{OPD(0xD9, 0xEB), 1, &OpDispatchBuilder::FLDF64_Const<0x400921FB54442D18>}, // pi
{OPD(0xD9, 0xEC), 1, &OpDispatchBuilder::FLDF64_Const<0x3FD34413509F79FF>}, // log10l(2)
{OPD(0xD9, 0xED), 1, &OpDispatchBuilder::FLDF64_Const<0x3FE62E42FEFA39EF>}, // log(2)
{OPD(0xD9, 0xEE), 1, &OpDispatchBuilder::FLDF64_Const<0>}, // 0.0
// EF = Invalid
{OPD(0xD9, 0xF0), 1, &OpDispatchBuilder::X87UnaryOpF64<IR::OP_F64F2XM1>},
{OPD(0xD9, 0xF1), 1, &OpDispatchBuilder::X87FYL2XF64},
{OPD(0xD9, 0xF2), 1, &OpDispatchBuilder::X87TANF64},
{OPD(0xD9, 0xF3), 1, &OpDispatchBuilder::X87ATANF64},
{OPD(0xD9, 0xF4), 1, &OpDispatchBuilder::FXTRACTF64},
{OPD(0xD9, 0xF5), 1, &OpDispatchBuilder::X87BinaryOpF64<IR::OP_F64FPREM1>},
{OPD(0xD9, 0xF6), 1, &OpDispatchBuilder::X87ModifySTP<false>},
{OPD(0xD9, 0xF7), 1, &OpDispatchBuilder::X87ModifySTP<true>},
{OPD(0xD9, 0xF8), 1, &OpDispatchBuilder::X87BinaryOpF64<IR::OP_F64FPREM>},
{OPD(0xD9, 0xF9), 1, &OpDispatchBuilder::X87FYL2XF64},
{OPD(0xD9, 0xFA), 1, &OpDispatchBuilder::FSQRTF64},
{OPD(0xD9, 0xFB), 1, &OpDispatchBuilder::X87SinCosF64},
{OPD(0xD9, 0xFC), 1, &OpDispatchBuilder::FRNDINTF64},
{OPD(0xD9, 0xFD), 1, &OpDispatchBuilder::X87BinaryOpF64<IR::OP_F64SCALE>},
{OPD(0xD9, 0xFE), 1, &OpDispatchBuilder::X87UnaryOpF64<IR::OP_F64SIN>},
{OPD(0xD9, 0xFF), 1, &OpDispatchBuilder::X87UnaryOpF64<IR::OP_F64COS>},
{OPDReg(0xDA, 0) | 0x00, 8, &OpDispatchBuilder::FADDF64<32, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDA, 1) | 0x00, 8, &OpDispatchBuilder::FMULF64<32, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDA, 2) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<32, true, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDA, 3) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<32, true, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDA, 4) | 0x00, 8, &OpDispatchBuilder::FSUBF64<32, true, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDA, 5) | 0x00, 8, &OpDispatchBuilder::FSUBF64<32, true, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDA, 6) | 0x00, 8, &OpDispatchBuilder::FDIVF64<32, true, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDA, 7) | 0x00, 8, &OpDispatchBuilder::FDIVF64<32, true, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xDA, 0xC0), 8, &OpDispatchBuilder::X87FCMOV},
{OPD(0xDA, 0xC8), 8, &OpDispatchBuilder::X87FCMOV},
{OPD(0xDA, 0xD0), 8, &OpDispatchBuilder::X87FCMOV},
{OPD(0xDA, 0xD8), 8, &OpDispatchBuilder::X87FCMOV},
// E0 = Invalid
// E8 = Invalid
{OPD(0xDA, 0xE9), 1, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, true>},
// EA = Invalid
// F0 = Invalid
// F8 = Invalid
{OPDReg(0xDB, 0) | 0x00, 8, &OpDispatchBuilder::FILDF64},
{OPDReg(0xDB, 1) | 0x00, 8, &OpDispatchBuilder::FISTF64<true>},
{OPDReg(0xDB, 2) | 0x00, 8, &OpDispatchBuilder::FISTF64<false>},
{OPDReg(0xDB, 3) | 0x00, 8, &OpDispatchBuilder::FISTF64<false>},
// 4 = Invalid
{OPDReg(0xDB, 5) | 0x00, 8, &OpDispatchBuilder::FLDF64<80>},
// 6 = Invalid
{OPDReg(0xDB, 7) | 0x00, 8, &OpDispatchBuilder::FSTF64<80>},
{OPD(0xDB, 0xC0), 8, &OpDispatchBuilder::X87FCMOV},
{OPD(0xDB, 0xC8), 8, &OpDispatchBuilder::X87FCMOV},
{OPD(0xDB, 0xD0), 8, &OpDispatchBuilder::X87FCMOV},
{OPD(0xDB, 0xD8), 8, &OpDispatchBuilder::X87FCMOV},
// E0 = Invalid
{OPD(0xDB, 0xE2), 1, &OpDispatchBuilder::NOPOp}, // FNCLEX
{OPD(0xDB, 0xE3), 1, &OpDispatchBuilder::FNINIT},
// E4 = Invalid
{OPD(0xDB, 0xE8), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_RFLAGS, false>},
{OPD(0xDB, 0xF0), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_RFLAGS, false>},
// F8 = Invalid
{OPDReg(0xDC, 0) | 0x00, 8, &OpDispatchBuilder::FADDF64<64, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDC, 1) | 0x00, 8, &OpDispatchBuilder::FMULF64<64, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDC, 2) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<64, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDC, 3) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<64, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDC, 4) | 0x00, 8, &OpDispatchBuilder::FSUBF64<64, false, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDC, 5) | 0x00, 8, &OpDispatchBuilder::FSUBF64<64, false, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDC, 6) | 0x00, 8, &OpDispatchBuilder::FDIVF64<64, false, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDC, 7) | 0x00, 8, &OpDispatchBuilder::FDIVF64<64, false, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xDC, 0xC0), 8, &OpDispatchBuilder::FADDF64<80, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDC, 0xC8), 8, &OpDispatchBuilder::FMULF64<80, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDC, 0xE0), 8, &OpDispatchBuilder::FSUBF64<80, false, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDC, 0xE8), 8, &OpDispatchBuilder::FSUBF64<80, false, true, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDC, 0xF0), 8, &OpDispatchBuilder::FDIVF64<80, false, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDC, 0xF8), 8, &OpDispatchBuilder::FDIVF64<80, false, true, OpDispatchBuilder::OpResult::RES_STI>},
{OPDReg(0xDD, 0) | 0x00, 8, &OpDispatchBuilder::FLDF64<64>},
{OPDReg(0xDD, 1) | 0x00, 8, &OpDispatchBuilder::FISTF64<true>},
{OPDReg(0xDD, 2) | 0x00, 8, &OpDispatchBuilder::FSTF64<64>},
{OPDReg(0xDD, 3) | 0x00, 8, &OpDispatchBuilder::FSTF64<64>},
{OPDReg(0xDD, 4) | 0x00, 8, &OpDispatchBuilder::X87FRSTORF64},
// 5 = Invalid
{OPDReg(0xDD, 6) | 0x00, 8, &OpDispatchBuilder::X87FNSAVEF64},
{OPDReg(0xDD, 7) | 0x00, 8, &OpDispatchBuilder::X87FNSTSW},
{OPD(0xDD, 0xC0), 8, &OpDispatchBuilder::X87FFREE},
{OPD(0xDD, 0xD0), 8, &OpDispatchBuilder::FST}, //register-register from regular X87
{OPD(0xDD, 0xD8), 8, &OpDispatchBuilder::FST}, //^
{OPD(0xDD, 0xE0), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPD(0xDD, 0xE8), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDE, 0) | 0x00, 8, &OpDispatchBuilder::FADDF64<16, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDE, 1) | 0x00, 8, &OpDispatchBuilder::FMULF64<16, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDE, 2) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<16, true, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDE, 3) | 0x00, 8, &OpDispatchBuilder::FCOMIF64<16, true, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, false>},
{OPDReg(0xDE, 4) | 0x00, 8, &OpDispatchBuilder::FSUBF64<16, true, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDE, 5) | 0x00, 8, &OpDispatchBuilder::FSUBF64<16, true, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDE, 6) | 0x00, 8, &OpDispatchBuilder::FDIVF64<16, true, false, OpDispatchBuilder::OpResult::RES_ST0>},
{OPDReg(0xDE, 7) | 0x00, 8, &OpDispatchBuilder::FDIVF64<16, true, true, OpDispatchBuilder::OpResult::RES_ST0>},
{OPD(0xDE, 0xC0), 8, &OpDispatchBuilder::FADDF64<80, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDE, 0xC8), 8, &OpDispatchBuilder::FMULF64<80, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDE, 0xD9), 1, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_X87, true>},
{OPD(0xDE, 0xE0), 8, &OpDispatchBuilder::FSUBF64<80, false, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDE, 0xE8), 8, &OpDispatchBuilder::FSUBF64<80, false, true, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDE, 0xF0), 8, &OpDispatchBuilder::FDIVF64<80, false, false, OpDispatchBuilder::OpResult::RES_STI>},
{OPD(0xDE, 0xF8), 8, &OpDispatchBuilder::FDIVF64<80, false, true, OpDispatchBuilder::OpResult::RES_STI>},
{OPDReg(0xDF, 0) | 0x00, 8, &OpDispatchBuilder::FILDF64},
{OPDReg(0xDF, 1) | 0x00, 8, &OpDispatchBuilder::FISTF64<true>},
{OPDReg(0xDF, 2) | 0x00, 8, &OpDispatchBuilder::FISTF64<false>},
{OPDReg(0xDF, 3) | 0x00, 8, &OpDispatchBuilder::FISTF64<false>},
{OPDReg(0xDF, 4) | 0x00, 8, &OpDispatchBuilder::FBLDF64},
{OPDReg(0xDF, 5) | 0x00, 8, &OpDispatchBuilder::FILDF64},
{OPDReg(0xDF, 6) | 0x00, 8, &OpDispatchBuilder::FBSTPF64},
{OPDReg(0xDF, 7) | 0x00, 8, &OpDispatchBuilder::FISTF64<false>},
// XXX: This should also set the x87 tag bits to empty
// We don't support this currently, so just pop the stack
{OPD(0xDF, 0xC0), 8, &OpDispatchBuilder::X87ModifySTP<true>},
{OPD(0xDF, 0xE0), 8, &OpDispatchBuilder::X87FNSTSW},
{OPD(0xDF, 0xE8), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_RFLAGS, false>},
{OPD(0xDF, 0xF0), 8, &OpDispatchBuilder::FCOMIF64<80, false, OpDispatchBuilder::FCOMIFlags::FLAGS_RFLAGS, false>},
};
constexpr std::tuple<uint16_t, uint8_t, FEXCore::X86Tables::OpDispatchPtr> X87OpTable[] = {
{OPDReg(0xD8, 0) | 0x00, 8, &OpDispatchBuilder::FADD<32, false, OpDispatchBuilder::OpResult::RES_ST0>},
@@ -6439,7 +6669,12 @@ constexpr uint16_t PF_F2 = 3;
InstallToTable(FEXCore::X86Tables::SecondModRMTableOps, SecondaryModRMExtensionOpTable);
InstallToX87Table(FEXCore::X86Tables::X87Ops, X87OpTable);
FEX_CONFIG_OPT(ReducedPrecision, X87REDUCEDPRECISION);
if(ReducedPrecision) {
InstallToX87Table(FEXCore::X86Tables::X87Ops, X87F64OpTable);
} else {
InstallToX87Table(FEXCore::X86Tables::X87Ops, X87OpTable);
}
InstallToTable(FEXCore::X86Tables::H0F38TableOps, H0F38Table);
InstallToTable(FEXCore::X86Tables::H0F3ATableOps, H0F3ATable);
@@ -463,6 +463,55 @@ public:
template<size_t width, bool Integer, FCOMIFlags whichflags, bool poptwice>
void FCOMI(OpcodeArgs);
// F64 X87 Ops
template<size_t width>
void FLDF64(OpcodeArgs);
template<uint64_t num>
void FLDF64_Const(OpcodeArgs);
void FBLDF64(OpcodeArgs);
void FBSTPF64(OpcodeArgs);
void FILDF64(OpcodeArgs);
template<size_t width>
void FSTF64(OpcodeArgs);
void FSTF64(OpcodeArgs);
template<bool Truncate>
void FISTF64(OpcodeArgs);
template<size_t width, bool Integer, OpResult ResInST0>
void FADDF64(OpcodeArgs);
template<size_t width, bool Integer, OpResult ResInST0>
void FMULF64(OpcodeArgs);
template<size_t width, bool Integer, bool reverse, OpResult ResInST0>
void FDIVF64(OpcodeArgs);
template<size_t width, bool Integer, bool reverse, OpResult ResInST0>
void FSUBF64(OpcodeArgs);
void FCHSF64(OpcodeArgs);
void FABSF64(OpcodeArgs);
void FTSTF64(OpcodeArgs);
void FRNDINTF64(OpcodeArgs);
void FXTRACTF64(OpcodeArgs);
void FSQRTF64(OpcodeArgs);
template<FEXCore::IR::IROps IROp>
void X87UnaryOpF64(OpcodeArgs);
template<FEXCore::IR::IROps IROp>
void X87BinaryOpF64(OpcodeArgs);
void X87SinCosF64(OpcodeArgs);
void X87FYL2XF64(OpcodeArgs);
void X87TANF64(OpcodeArgs);
void X87ATANF64(OpcodeArgs);
void X87FNSAVEF64(OpcodeArgs);
void X87FRSTORF64(OpcodeArgs);
void X87FXAMF64(OpcodeArgs);
template<size_t width, bool Integer, FCOMIFlags whichflags, bool poptwice>
void FCOMIF64(OpcodeArgs);
void FXSaveOp(OpcodeArgs);
void FXRStoreOp(OpcodeArgs);
File diff suppressed because it is too large. Load diff
+29
View File
@@ -1478,6 +1478,35 @@
"DestSize": "std::max<uint8_t>(4, GetOpSize(_Src1))"
}
},
"F64": {
"FPR = F64ATAN FPR:$Src1, FPR:$Src2": {
"DestSize": "8"
},
"FPR = F64FPREM FPR:$Src1, FPR:$Src2": {
"DestSize": "8"
},
"FPR = F64FPREM1 FPR:$Src1, FPR:$Src2": {
"DestSize": "8"
},
"FPR = F64SCALE FPR:$Src1, FPR:$Src2": {
"DestSize": "8"
},
"FPR = F64F2XM1 FPR:$Src": {
"DestSize": "8"
},
"FPR = F64FYL2X FPR:$Src, FPR:$Src2": {
"DestSize": "8"
},
"FPR = F64TAN FPR:$Src": {
"DestSize": "8"
},
"FPR = F64SIN FPR:$Src": {
"DestSize": "8"
},
"FPR = F64COS FPR:$Src": {
"DestSize": "8"
}
},
"F80": {
"F80LoadFCW GPR:$Src": {
"HasSideEffects": true
+10
View File
@@ -78,6 +78,16 @@ namespace FEXCore::Core {
OPINDEX_F80FPREM,
OPINDEX_F80SCALE,
// Double Precision
OPINDEX_F64SIN,
OPINDEX_F64COS,
OPINDEX_F64TAN,
OPINDEX_F64ATAN,
OPINDEX_F64F2XM1,
OPINDEX_F64FYL2X,
OPINDEX_F64FPREM,
OPINDEX_F64FPREM1,
OPINDEX_F64SCALE,
// Maximum
OPINDEX_MAX,
};
+7
View File
@@ -526,6 +526,13 @@ namespace {
ConfigChanged = true;
}
Value = LoadedConfig->Get(FEXCore::Config::ConfigOption::CONFIG_X87REDUCEDPRECISION);
bool X87ReducedPrecision = Value.has_value() && **Value == "1";
if (ImGui::Checkbox("X87 Reduced Precision", &X87ReducedPrecision)) {
LoadedConfig->EraseSet(FEXCore::Config::ConfigOption::CONFIG_X87REDUCEDPRECISION, X87ReducedPrecision ? "1" : "0");
ConfigChanged = true;
}
ImGui::Text("SMC Checks: ");
int SMCChecks = FEXCore::Config::CONFIG_SMC_MMAN;
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4008000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fadd dword [rdx + 8 * 1]
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4000000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fmul dword [rdx + 8 * 1]
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0xbff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fsub dword [rdx + 8 * 1]
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fsubr dword [rdx + 8 * 1]
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3fe0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fdiv dword [rdx + 8 * 1]
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fdivr dword [rdx + 8 * 1]
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+26
View File
@@ -0,0 +1,26 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4008000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
; fadd st(0), st(i)
fadd st0, st1
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+21
View File
@@ -0,0 +1,21 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4010000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 0], rax
fld qword [rdx + 8 * 0]
fmul st0, st0
fst qword [rdx + 8 * 2]
mov rax, [rdx + 8 * 2]
hlt
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
; Only tests pop behaviour
fld1
fldz
fcomp
fld1
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
+24
View File
@@ -0,0 +1,24 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0xbff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 0], rax
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
fsub st0, st1
fst qword [rdx]
mov rax, [rdx]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 0], rax
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
fsubr st0, st1
fst qword [rdx]
mov rax, [rdx]
hlt
+21
View File
@@ -0,0 +1,21 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 0], rax
fld qword [rdx + 8 * 0]
fdiv st0, st0
fst qword [rdx]
mov rax, [rdx]
hlt
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3fe0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 0], rax
mov rax, 0x4010000000000000 ; 4.0
mov [rdx + 8 * 1], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
fdivr st0, st1
fst qword [rdx]
mov rax, [rdx]
hlt
+21
View File
@@ -0,0 +1,21 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3f800000"
},
"X86ReducedPrecision": "1"
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld dword [rdx + 8 * 0]
fst dword [rdx]
xor eax, eax
mov eax, [rdx]
hlt
+22
View File
@@ -0,0 +1,22 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3F800000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
mov eax, 0x0
mov [rdx + 8 * 1], eax
fld dword [rdx + 8 * 0]
fst dword [rdx + 8 * 1]
mov eax, [rdx + 8 * 1]
hlt
+28
View File
@@ -0,0 +1,28 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3F800000",
"RBX": "0x40000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
mov eax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], eax
mov eax, 0x0 ; 1.0
mov [rdx + 8 * 2], eax
fld dword [rdx + 8 * 0]
fstp dword [rdx + 8 * 2]
fld dword [rdx + 8 * 1]
mov eax, [rdx + 8 * 2]
fst dword [rdx + 8 * 2]
mov ebx, [rdx + 8 * 2]
hlt
+11
View File
@@ -0,0 +1,11 @@
%ifdef CONFIG
{
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
; Just to ensure execution
fldcw [rdx]
hlt
+53
View File
@@ -0,0 +1,53 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
mov eax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], eax
mov eax, 0x40800000 ; 4.0
mov [rdx + 8 * 2], eax
fld dword [rdx + 8 * 0]
o32 fstenv [rdx + 8 * 3]
fld dword [rdx + 8 * 2]
o32 fldenv [rdx + 8 * 3]
; This will overwrite the previous load
; This is since the control word is stored and reloaded
fld dword [rdx + 8 * 1]
; 14 bytes for 16bit
; 2 Bytes : FCW
; 2 Bytes : FSW
; 2 bytes : FTW
; 2 bytes : Instruction offset
; 2 bytes : Instruction CS selector
; 2 bytes : Data offset
; 2 bytes : Data selector
; 28 bytes for 32bit
; 4 bytes : FCW
; 4 bytes : FSW
; 4 bytes : FTW
; 4 bytes : Instruction pointer
; 2 bytes : instruction pointer selector
; 2 bytes : Opcode
; 4 bytes : data pointer offset
; 4 bytes : data pointer selector
fstp qword [rdx + 8]
mov rax, [rdx + 8]
fst qword [rdx + 8]
mov rbx, [rdx + 8]
hlt
+52
View File
@@ -0,0 +1,52 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
mov eax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], eax
mov eax, 0x40800000 ; 4.0
mov [rdx + 8 * 2], eax
fld dword [rdx + 8 * 0]
o16 fstenv [rdx + 8 * 3]
fld dword [rdx + 8 * 2]
o16 fldenv [rdx + 8 * 3]
; This will overwrite the previous load
; This is since the control word is stored and reloaded
fld dword [rdx + 8 * 1]
; 14 bytes for 16bit
; 2 Bytes : FCW
; 2 Bytes : FSW
; 2 bytes : FTW
; 2 bytes : Instruction offset
; 2 bytes : Instruction CS selector
; 2 bytes : Data offset
; 2 bytes : Data selector
; 28 bytes for 32bit
; 4 bytes : FCW
; 4 bytes : FSW
; 4 bytes : FTW
; 4 bytes : Instruction pointer
; 2 bytes : instruction pointer selector
; 2 bytes : Opcode
; 4 bytes : data pointer offset
; 4 bytes : data pointer selector
fstp qword [rdx + 8]
mov rax, [rdx + 8]
fst qword [rdx + 8]
mov rbx, [rdx + 8]
hlt
+15
View File
@@ -0,0 +1,15 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x37F"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
fnstcw [rdx]
mov eax, 0
mov ax, [rdx]
hlt
+37
View File
@@ -0,0 +1,37 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0x4000000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fld st0
; dump stack to registers
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dt 2.0
dq 0
+28
View File
@@ -0,0 +1,28 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0x4000000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
mov eax, 0x40000000 ; 2.0
mov [rdx + 8 * 1], eax
fld dword [rdx + 8 * 0]
fld dword [rdx + 8 * 1]
fxch
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
+9
View File
@@ -0,0 +1,9 @@
%ifdef CONFIG
{
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
; Just to ensure execution
fnop
hlt
+35
View File
@@ -0,0 +1,35 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0xc000000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fchs
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fchs
fstp qword [rcx]
mov rax, [rcx]
fst qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt -1.0
dq 0
+35
View File
@@ -0,0 +1,35 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0x4000000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fabs
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fabs
fstp qword [rcx]
mov rax, [rcx]
fst qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt -1.0
dq 0
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fld1
fst qword [rcx]
mov rax, [rcx]
hlt
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x40549a78"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fldl2t
fst dword [rcx] ; Can't compare 64-bit precision with host
mov eax, [rcx]
hlt
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3fb8aa3b"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fldl2e
fst dword [rcx] ; Can't compare 64-bit precision with host
mov eax, [rcx]
hlt
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x40490fdb"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fldpi
fst dword [rcx] ; Can't compare 64-bit precision with host
mov eax, [rcx]
hlt
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3e9a209b"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fldlg2
fst dword [rcx] ; Can't compare 64-bit precision with host
mov eax, [rcx]
hlt
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3f317218"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fldln2
fst dword [rcx] ; Can't compare 64-bit precision with host
mov eax, [rcx]
hlt
+17
View File
@@ -0,0 +1,17 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
fldz
fst qword [rcx]
mov rax, [rcx]
hlt
+24
View File
@@ -0,0 +1,24 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x0"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rbx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
f2xm1
fst qword [rbx]
mov rax, [rbx]
hlt
align 8
data:
dt 0.0
dq 0
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0x4020000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fyl2x
fld1
fstp qword [rcx]
mov rax, [rcx]
fst qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt 16.0
dq 0
data2:
dt 2.0
dq 0
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rbx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fptan
fst qword [rbx]
mov rax, [rbx]
hlt
align 8
data:
dt 1.0
dq 0
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0x3ff921fb54442d18"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fpatan
fld1
fstp qword [rcx]
mov rax, [rcx]
fstp qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt 7.0
dq 0
data2:
dt 0.0
dq 0
+28
View File
@@ -0,0 +1,28 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0xbffe000000000000"],
"RBX": ["0x4008000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fxtract
fstp qword [rcx]
mov rax, [rcx]
fst qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt -15.0
dq 0
+37
View File
@@ -0,0 +1,37 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0xbf666666"],
"RBX": ["0x40400000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fprem1
; Store as single precision to get around precision issues
fstp dword [rcx]
mov eax, [rcx]
fst dword [rcx]
mov ebx, [rcx]
hlt
align 8
data:
dt 3.0
dq 0
data2:
dt 5.1
dq 0
+44
View File
@@ -0,0 +1,44 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4010000000000000",
"RBX": "0x0",
"RCX": "0x4000000000000000",
"RDX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 1], rax
mov rax, 0x4010000000000000 ; 4.0
mov [rdx + 8 * 2], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
; Do Some stack shenanigans
fldz
fincstp
fdecstp
fld qword [rdx + 8 * 2]
; dump stack to registers
mov r9, 0xe0000000
fstp qword [r9]
mov rax, [r9]
fstp qword [r9]
mov rbx, [r9]
fstp qword [r9]
mov rcx, [r9]
fstp qword [r9]
mov rdx, [r9]
hlt
+65
View File
@@ -0,0 +1,65 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4060000000000000",
"RBX": "0x4050000000000000",
"RCX": "0x4040000000000000",
"RDX": "0x4030000000000000",
"R8": "0x4020000000000000",
"R9": "0x4000000000000000",
"R10": "0x3ff0000000000000",
"R11": "0x4070000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 1], rax
mov rax, 0x4020000000000000 ; 4.0
mov [rdx + 8 * 2], rax
mov rax, 0x4030000000000000
mov [rdx + 8 * 3], rax
mov rax, 0x4040000000000000
mov [rdx + 8 * 4], rax
mov rax, 0x4050000000000000
mov [rdx + 8 * 5], rax
mov rax, 0x4060000000000000
mov [rdx + 8 * 6], rax
mov rax, 0x4070000000000000
mov [rdx + 8 * 7], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
fld qword [rdx + 8 * 2]
fld qword [rdx + 8 * 3]
fld qword [rdx + 8 * 4]
fld qword [rdx + 8 * 5]
fld qword [rdx + 8 * 6]
fld qword [rdx + 8 * 7]
fincstp
; dump stack to registers
mov r12, 0xe0000000
fstp qword [r12]
mov rax, [r12]
fstp qword [r12]
mov rbx, [r12]
fstp qword [r12]
mov rcx, [r12]
fstp qword [r12]
mov rdx, [r12]
fstp qword [r12]
mov r8, [r12]
fstp qword [r12]
mov r9, [r12]
fstp qword [r12]
mov r10, [r12]
fstp qword [r12]
mov r11, [r12]
hlt
+32
View File
@@ -0,0 +1,32 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x40066666",
"RBX": "0x40400000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fprem
fstp dword [rdx + 8]
mov eax, [rdx + 8]
fst dword [rdx + 8]
mov ebx, [rdx + 8]
hlt
align 8
data:
dt 3.0
dq 0
data2:
dt 5.1
dq 0
+35
View File
@@ -0,0 +1,35 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3f800000",
"RBX": "0x41be320c"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fyl2xp1
fld1
mov rcx, 0xe0000000
fstp dword [rcx]
mov eax, [rcx]
fstp dword [rcx]
mov ebx, [rcx]
hlt
align 8
data:
dt 15.0
dq 0
data2:
dt 2.0
dq 0
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4010000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rbx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fsqrt
fst qword [rbx]
mov rax, [rbx]
hlt
align 8
data:
dt 16.0
dq 0
+27
View File
@@ -0,0 +1,27 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3fe14a280fb5068c"],
"RBX": ["0x3feaed548f090cee"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fsincos
fstp qword [rcx]
mov rax, [rcx]
fstp qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt 1.0
dq 0
+22
View File
@@ -0,0 +1,22 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f834241 ; 1.02546
mov [rdx + 8 * 0], eax
fld dword [rdx + 8 * 0]
frndint
fst qword [rdx]
mov rax, [rdx]
hlt
+34
View File
@@ -0,0 +1,34 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0xc01a000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fscale
mov rcx, 0xe0000000
fstp qword [rcx]
mov rax, [rcx]
fstp qword [rcx]
mov rbx, [rcx]
hlt
align 8
data:
dt 64.0
dq 0
data2:
dt -6.5
dq 0
+38
View File
@@ -0,0 +1,38 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x43000000"],
"RBX": ["0x40b00000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rcx, 0xe0000000
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fscale
; Store as single precision to get around precision issues
fstp dword [rcx]
mov eax, [rcx]
fst dword [rcx]
mov ebx, [rcx]
hlt
align 8
data:
dt 4.0
dq 0
data2:
dt 5.5
dq 0
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3feaed548f090cee"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rbx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fsin
fst qword [rbx]
mov rax, [rbx]
hlt
align 8
data:
dt 1.0
dq 0
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0xbfdaa22657537205"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rbx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
fcos
fst qword [rbx]
mov rax, [rbx]
hlt
align 8
data:
dt 2.0
dq 0
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4000000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov eax, 2
mov [rdx + 8 * 1], eax
fld qword [rdx + 8 * 0]
fimul dword [rdx + 8 * 1]
fst qword [rdx]
mov rax, [rdx]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0xbff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov eax, 2
mov [rdx + 8 * 1], eax
fld qword [rdx + 8 * 0]
fisub dword [rdx + 8 * 1]
fst qword [rdx]
mov rax, [rdx]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov eax, 2
mov [rdx + 8 * 1], eax
fld qword [rdx + 8 * 0]
fisubr dword [rdx + 8 * 1]
fst qword [rdx]
mov rax, [rdx]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3fe0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov eax, 2
mov [rdx + 8 * 1], eax
fld qword [rdx + 8 * 0]
fidiv dword [rdx + 8 * 1]
fst qword [rdx]
mov rax, [rdx]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4000000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov eax, 2
mov [rdx + 8 * 1], eax
fld qword [rdx + 8 * 0]
fidivr dword [rdx + 8 * 1]
fst qword [rdx]
mov rax, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0x0000000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 2
cmp eax, 1
fcmovb st0, st1
fldz
cmp eax, 3
fcmovb st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x0000000000000000",
"RBX": "0x3ff0000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 1
cmp eax, 1
fcmove st0, st1
fldz
cmp eax, 0
fcmove st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x0000000000000000",
"RBX": "0x3ff0000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 2
cmp eax, 2
fcmovbe st0, st1
fldz
cmp eax, 0
fcmovbe st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0x0000000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 0x0
cmp eax, -1
fcmovu st0, st1
fldz
cmp eax, 1
fcmovu st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+25
View File
@@ -0,0 +1,25 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x3ff0000000000000"],
"RBX": ["0x3ff0000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
; Only tests pop behaviour
fld1
fldz
fldz
fcompp
fld1
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
+24
View File
@@ -0,0 +1,24 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
; Only tests pop behaviour
fld1
fldz
fldz
fucompp
fld1
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
+20
View File
@@ -0,0 +1,20 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4090000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 1024
mov [rdx + 8 * 0], eax
fild dword [rdx + 8 * 0]
fstp qword [rdx]
mov rax, [rdx]
hlt
+29
View File
@@ -0,0 +1,29 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x400",
"RBX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x44800000 ; 1024.0
mov [rdx + 8 * 0], eax
mov eax, 0
mov [rdx + 8 * 1], eax
fld dword [rdx + 8 * 0]
fisttp dword [rdx + 8 * 1]
fld1
mov eax, [rdx + 8 * 1]
fst qword [rdx]
mov rbx, [rdx]
hlt
+35
View File
@@ -0,0 +1,35 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x400",
"RBX": "0x3ff0000000000000",
"RCX": "0x4090000000000000"
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov eax, 0x44800000 ; 1024.0
mov [rdx + 8 * 0], eax
mov eax, 0
mov [rdx + 8 * 1], eax
fld dword [rdx + 8 * 0]
fist dword [rdx + 8 * 1]
fld1
mov eax, [rdx + 8 * 1]
fstp qword [rdx]
mov rbx, [rdx]
fst qword [rdx]
mov rcx, [rdx]
hlt
+31
View File
@@ -0,0 +1,31 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x400",
"RBX": ["0x3ff0000000000000"]
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif
mov rdx, 0xe0000000
mov eax, 0x44800000 ; 1024.0
mov [rdx + 8 * 0], eax
mov eax, 0
mov [rdx + 8 * 1], eax
fld dword [rdx + 8 * 0]
fistp dword [rdx + 8 * 1]
fld1
mov eax, [rdx + 8 * 1]
fst qword [rdx]
mov rbx, [rdx]
hlt
+23
View File
@@ -0,0 +1,23 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 2.0
dq 0
+29
View File
@@ -0,0 +1,29 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fstp tword [rdx + 8 * 0]
fld tword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt 0.0
dq 0
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x0000000000000000",
"RBX": "0x3ff0000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 2
cmp eax, 1
fcmovnb st0, st1
fldz
cmp eax, 3
fcmovnb st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+37
View File
@@ -0,0 +1,37 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0x0000000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 1
cmp eax, 1
fcmovne st0, st1
fldz
cmp eax, 0
fcmovne st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0x0000000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 2
cmp eax, 2
fcmovnbe st0, st1
fldz
cmp eax, 0
fcmovnbe st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x0000000000000000",
"RBX": "0x3ff0000000000000",
"RCX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov eax, 0x3f800000 ; 1.0
mov [rdx + 8 * 0], eax
fld1
fldz
mov eax, 0x0
cmp eax, -1
fcmovnu st0, st1
fldz
cmp eax, 1
fcmovnu st0, st2
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+28
View File
@@ -0,0 +1,28 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4008000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fadd qword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dq 2.0
+27
View File
@@ -0,0 +1,27 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fmul qword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dq 2.0
+27
View File
@@ -0,0 +1,27 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0xbff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fsub qword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dq 2.0
+27
View File
@@ -0,0 +1,27 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fsubr qword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dq 2.0
+27
View File
@@ -0,0 +1,27 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3fe0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fdiv qword [rdx + 8 * 0]
mov rdx, 0xe0000000
fstp qword [rdx]
mov rax, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dq 2.0
+28
View File
@@ -0,0 +1,28 @@
%ifdef CONFIG
{
"RegData": {
"RAX": ["0x4010000000000000"]
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rbx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fdivr qword [rdx + 8 * 0]
fst qword [rbx]
mov rax, [rbx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dq 8.0
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4010000000000000",
"RBX": "0x4000000000000000",
"RCX": "0x4014000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x3ff0000000000000 ; 1.0
mov [rdx + 8 * 0], rax
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 1], rax
mov rax, 0x4010000000000000 ; 4.0
mov [rdx + 8 * 2], rax
fld qword [rdx + 8 * 0]
fld qword [rdx + 8 * 1]
fld qword [rdx + 8 * 2]
; fadd st(i), st(0)
fadd st2, st0
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
+34
View File
@@ -0,0 +1,34 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4010000000000000",
"RBX": "0x4020000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fmul st1, st0
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt 4.0
dq 0
+32
View File
@@ -0,0 +1,32 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fsubr st1, st0
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dt 2.0
dq 0
+33
View File
@@ -0,0 +1,33 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0xbff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fsub st1, st0
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
align 8
data:
dt 1.0
dq 0
data2:
dt 2.0
dq 0
+32
View File
@@ -0,0 +1,32 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x3ff0000000000000",
"RBX": "0x3fe0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fdivr st1, st0
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt 1.0
dq 0
+32
View File
@@ -0,0 +1,32 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0x4010000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fdiv st1, st0
fstp qword [rdx]
mov rax, [rdx]
fstp qword [rdx]
mov rbx, [rdx]
hlt
align 8
data:
dt 8.0
dq 0
data2:
dt 2.0
dq 0
+20
View File
@@ -0,0 +1,20 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
mov rdx, 0xe0000000
mov rax, 0x4000000000000000 ; 2.0
mov [rdx + 8 * 0], rax
fld qword [rdx + 8 * 0]
fstp qword [rdx]
mov rax, [rdx]
hlt
+36
View File
@@ -0,0 +1,36 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x2",
"RBX": "0x3ff0000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data3]
fisttp qword [rdx + 8 * 0]
mov rax, [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fstp qword [rdx]
mov rbx, [rdx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt 1.0
dq 0
data3:
dq 0
dq 0
+39
View File
@@ -0,0 +1,39 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4000000000000000",
"RBX": "0x3ff0000000000000",
"RCX": "0x4000000000000000"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
lea rdx, [rel data]
fld tword [rdx + 8 * 0]
lea rdx, [rel data3]
fst qword [rdx + 8 * 0]
mov rax, [rdx + 8 * 0]
lea rdx, [rel data2]
fld tword [rdx + 8 * 0]
fstp qword [rdx]
mov rbx, [rdx]
fstp qword [rdx]
mov rcx, [rdx]
hlt
align 8
data:
dt 2.0
dq 0
data2:
dt 1.0
dq 0
data3:
dq 0
dq 0
Loaded 100 of 132 files, more files were not shown because too many files have changed in this diff. Show more