F64: Implement FLDCW using host rounding mode

This commit is contained in:
CallumDev 2022-04-29 04:39:57 +09:30
parent 89d6752d3d
commit 93926641d9
4 changed files with 53 additions and 2 deletions

View File

@ -5994,7 +5994,7 @@ constexpr uint16_t PF_F2 = 3;
{OPDReg(0xD9, 4) | 0x00, 8, &OpDispatchBuilder::X87LDENV},
{OPDReg(0xD9, 5) | 0x00, 8, &OpDispatchBuilder::X87FLDCW}, // XXX: stubbed FLDCW
{OPDReg(0xD9, 5) | 0x00, 8, &OpDispatchBuilder::X87FLDCWF64},
{OPDReg(0xD9, 6) | 0x00, 8, &OpDispatchBuilder::X87FNSTENV},

View File

@ -503,6 +503,7 @@ public:
template<FEXCore::IR::IROps IROp>
void X87BinaryOpF64(OpcodeArgs);
void X87SinCosF64(OpcodeArgs);
void X87FLDCWF64(OpcodeArgs);
void X87FYL2XF64(OpcodeArgs);
void X87TANF64(OpcodeArgs);
void X87ATANF64(OpcodeArgs);

View File

@ -33,7 +33,6 @@ class OrderedNode;
//LDENV
//FNSTENV
//FNINIT
//FLDCW
//FSTCW
//LDSW
//FNSTSW
@ -41,6 +40,19 @@ class OrderedNode;
//FCMOV
//FST(register to register)
void OpDispatchBuilder::X87FLDCWF64(OpcodeArgs) {
OrderedNode *NewFCW = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
//ignore the rounding precision, we're always 64-bit in F64.
//extract rounding mode
OrderedNode *roundingMode = NewFCW;
auto shift = _Constant(10);
auto mask = _Constant(3);
roundingMode = _Lshr(roundingMode, shift);
roundingMode = _And(roundingMode, mask);
_SetRoundingMode(roundingMode);
_StoreContext(2, GPRClass, NewFCW, offsetof(FEXCore::Core::CPUState, FCW));
}
template<size_t width>
void OpDispatchBuilder::FLDF64(OpcodeArgs) {
// Update TOP

View File

@ -0,0 +1,38 @@
%ifdef CONFIG
{
"Env": { "FEX_X87REDUCEDPRECISION" : "1" },
"RegData": {
"RAX": "0x3",
"RBX": "0x2"
}
}
%endif
lea rbp, [rel data]
mov rdx, 0xe0000000
mov rcx, 0xe0004000
; save fcw
fnstcw [rdx]
; set rounding to truncate
mov eax, 0
mov ax, [rdx]
or ah, 0xc
mov [rdx+8], ax
fldcw [rdx+8]
fld dword [rbp]
fistp dword [rdx+16]
mov ebx, [rdx+16]
; restore fcw
fldcw [rdx]
fld dword [rbp]
fistp dword[rdx+16]
mov eax, [rdx+16]
hlt
align 8
data:
dd 0x40266666 ; 2.6