Merge pull request #4864 from Sonicadvance1/fix_x87_reduced_load

FEXCore: Fixes OOB access on x87 reduced precision loads
This commit is contained in:
LC authored and GitHub committed 2025-09-10 23:08:50 -04:00
commit 5f0a1d55e5
5 files changed
+65 -10

No files matched your search

@@ -60,7 +60,7 @@ void OpDispatchBuilder::X87FLDCWF64(OpcodeArgs) {
// Float load op with memory operand
void OpDispatchBuilder::FLDF64(OpcodeArgs, IR::OpSize Width) {
const auto ReadWidth = (Width == OpSize::f80Bit) ? OpSize::i128Bit : Width;
Ref Data = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], ReadWidth, Op->Flags);
Ref Data = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], Width, Op->Flags);
// Convert to 64bit float
Ref ConvertedData = Data;
if (Width == OpSize::i32Bit) {
@@ -73,7 +73,7 @@ void OpDispatchBuilder::FLDF64(OpcodeArgs, IR::OpSize Width) {
void OpDispatchBuilder::FBLDF64(OpcodeArgs) {
// Read from memory
Ref Data = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], OpSize::i128Bit, Op->Flags);
Ref Data = LoadSource_WithOpSize(FPRClass, Op, Op->Src[0], OpSize::f80Bit, Op->Flags);
Ref ConvertedData = _F80BCDLoad(Data);
ConvertedData = _F80CVT(OpSize::i64Bit, ConvertedData);
_PushStack(ConvertedData, Data, OpSize::i64Bit, true);
@@ -0,0 +1,37 @@
%ifdef CONFIG
{
"MemoryRegions": {
"0x100000000": "4096"
},
"Env": { "FEX_X87REDUCEDPRECISION" : "1" }
}
%endif
; FEX-Emu had a bug where x87 loadstores at a page boundary with reduced precision enabled would loadstore 128-bits.
finit ; enters x87 state
mov rax, 0x100000000
mov rbx, 0x4142434445464748
mov rcx, 0x5152535455565758
mov rdx, (0x100000000 + 0x1000 - 16)
mov [rdx], rbx
mov [rdx + 8], rcx
mov rdx, 0x100000000 + 0x1000
; Do an 80-bit load at the edge of a page.
; Ensuring tword loads don't extend past the end of a page.
fld tword [rdx - 10]
; Do an 80-bit BCD load at the edge of a page.
fbld [rdx - 10]
; Do a BCD store
fbstp [rdx - 10]
; Regular 80-bit store
fstp tword [rdx - 10]
hlt
+10
View File
@@ -29,4 +29,14 @@ fld tword [rdx - 10]
; Do an 80-bit BCD load at the edge of a page.
fbld [rdx - 10]
; Do a BCD store
fbstp [rdx - 10]
; Regular 80-bit store
fstp tword [rdx - 10]
; Loads again to get register state.
fld tword [rdx - 10]
fbld [rdx - 10]
hlt
@@ -3558,12 +3558,14 @@
]
},
"fld tword [rax]": {
"ExpectedInstructionCount": 19,
"ExpectedInstructionCount": 21,
"Comment": [
"0xdb !11b /5"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"str x30, [sp, #-16]!",
"mov v0.16b, v2.16b",
"ldr x0, [x28, #1624]",
@@ -8471,12 +8473,14 @@
]
},
"fbld tword [rax]": {
"ExpectedInstructionCount": 26,
"ExpectedInstructionCount": 28,
"Comment": [
"0xdf !11b /4"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"str x30, [sp, #-16]!",
"mov v0.16b, v2.16b",
"ldr x0, [x28, #1944]",
+8 -4
View File
@@ -3579,12 +3579,14 @@
]
},
"fld tword [rax]": {
"ExpectedInstructionCount": 19,
"ExpectedInstructionCount": 21,
"Comment": [
"0xdb !11b /5"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"str x30, [sp, #-16]!",
"mov v0.16b, v2.16b",
"ldr x0, [x28, #1624]",
@@ -8529,12 +8531,14 @@
]
},
"fbld tword [rax]": {
"ExpectedInstructionCount": 26,
"ExpectedInstructionCount": 28,
"Comment": [
"0xdf !11b /4"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"str x30, [sp, #-16]!",
"mov v0.16b, v2.16b",
"ldr x0, [x28, #1944]",