diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp index cc89eea1f..c19c9cc11 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher/X87F64.cpp @@ -153,7 +153,10 @@ void OpDispatchBuilder::FILDF64(OpcodeArgs) { size_t read_width = GetSrcSize(Op); // Read from memory auto data = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], read_width, Op->Flags, -1); - auto converted = _Float_FromGPR_S(8, 8, data); + if(read_width == 2) { + data = _Sext(read_width * 8, data); + } + auto converted = _Float_FromGPR_S(8, read_width == 4 ? 4 : 8, data); // Write to ST[TOP] _StoreContextIndexed(converted, top, 8, MMBaseOffset(), 16, FPRClass); } @@ -198,9 +201,9 @@ void OpDispatchBuilder::FISTF64(OpcodeArgs) { auto orig_top = GetX87Top(); OrderedNode *data = _LoadContextIndexed(orig_top, 8, MMBaseOffset(), 16, FPRClass); if constexpr (Truncate) { - data = _Float_ToGPR_ZS(8, 8, data); + data = _Float_ToGPR_ZS(Size == 4 ? 4 : 8, 8, data); } else { - data = _Float_ToGPR_S(8, 8, data); + data = _Float_ToGPR_S(Size == 4 ? 4 : 8, 8, data); } StoreResult_WithOpSize(GPRClass, Op, Op->Dest, data, Size, 1); diff --git a/unittests/ASM/X87_F64/FILD_NEG_F64.asm b/unittests/ASM/X87_F64/FILD_NEG_F64.asm new file mode 100644 index 000000000..93c1cca70 --- /dev/null +++ b/unittests/ASM/X87_F64/FILD_NEG_F64.asm @@ -0,0 +1,29 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0xC090000000000000", + "RBX": "0xC070000000000000" + }, + "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] + +xor rbx, rbx +mov bx, -256 +mov [rdx + 8 * 0], bx +fild word [rdx + 8 * 0] + +fstp qword [rdx] +mov rbx, [rdx] + +hlt diff --git a/unittests/ASM/X87_F64/FIST_F64.asm b/unittests/ASM/X87_F64/FIST_F64.asm new file mode 100644 index 000000000..f99455b07 --- /dev/null +++ b/unittests/ASM/X87_F64/FIST_F64.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "Env": { "FEX_X87REDUCEDPRECISION" : "1" }, + "RegData": { + "RAX": "0xffffffff" + } +} +%endif + +; Test behaviour of overflow +; and storing negative numbers +; to 32-bit registers. + +lea rbp, [rel data] +mov rdx, 0xe0000000 + +fld qword [rbp] +fistp dword [rdx] +mov eax, [rdx] + +hlt + +align 8 +data: + dq 0xbff0000000000000