Skip to content

Commit

Permalink
Merge pull request #4169 from Sonicadvance1/x87_loadstore_tests
Browse files Browse the repository at this point in the history
unittests/ASM: Fixes x87 80-bit loads on the edge of page boundaries.
  • Loading branch information
lioncash authored Nov 30, 2024
2 parents baddfe0 + f0d25d4 commit 2e7fc60
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 10 deletions.
8 changes: 8 additions & 0 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4307,6 +4307,14 @@ Ref OpDispatchBuilder::LoadSource_WithOpSize(RegisterClassType Class, const X86T
}

if ((IsOperandMem(Operand, true) && LoadData) || ForceLoad) {
if (OpSize == OpSize::f80Bit) {
Ref MemSrc = LoadEffectiveAddress(A, true);

// For X87 extended doubles, Split the load.
auto Res = _LoadMem(Class, OpSize::i64Bit, MemSrc, Align == OpSize::iInvalid ? OpSize : Align);
return _VLoadVectorElement(OpSize::i128Bit, OpSize::i16Bit, Res, 4, _Add(OpSize::i64Bit, MemSrc, _InlineConstant(8)));
}

return _LoadMemAutoTSO(Class, OpSize, A, Align == OpSize::iInvalid ? OpSize : Align);
} else {
return LoadEffectiveAddress(A, false, AllowUpperGarbage);
Expand Down
4 changes: 2 additions & 2 deletions FEXCore/Source/Interface/Core/OpcodeDispatcher/X87.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void OpDispatchBuilder::SetX87Top(Ref Value) {
void OpDispatchBuilder::FLD(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);
Ref ConvertedData = Data;
// Convert to 80bit float
if (Width == OpSize::i32Bit || Width == OpSize::i64Bit) {
Expand All @@ -79,7 +79,7 @@ void OpDispatchBuilder::FLDFromStack(OpcodeArgs) {

void OpDispatchBuilder::FBLD(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);
_PushStack(ConvertedData, Data, OpSize::i128Bit, true);
}
Expand Down
32 changes: 32 additions & 0 deletions unittests/ASM/X87/LoadAtBoundary.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
%ifdef CONFIG
{
"RegData": {
"MM7": ["0x5354555657584142", "0x0000000000005152"],
"MM6": ["0xe94de5eae34fc1c0", "0x0000000000004039"]
},
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif

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]

hlt
33 changes: 33 additions & 0 deletions unittests/ASM/X87/StoreAtBoundary.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
%ifdef CONFIG
{
"MemoryRegions": {
"0x100000000": "4096"
}
}
%endif

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

; Load the data in to an x87 register for storing.
fld tword [rdx - 16]
fld tword [rdx - 16]

; Do an 80-bit store at the edge of a page.
; Ensuring tword stores don't extend past the end of a page.
; If storing past the end of the page, then an unhandled SIGSEGV will occur.
fstp tword [rdx - 10]

; Do an 80-bit bcd store at the edge of a page.
fbstp [rdx - 10]

hlt
12 changes: 8 additions & 4 deletions unittests/InstructionCountCI/FlagM/x87.json
Original file line number Diff line number Diff line change
Expand Up @@ -6869,12 +6869,14 @@
]
},
"fld tword [rax]": {
"ExpectedInstructionCount": 12,
"ExpectedInstructionCount": 14,
"Comment": [
"0xdb !11b /5"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"ldrb w20, [x28, #1019]",
"mov w21, #0x1",
"sub w20, w20, #0x1 (1)",
Expand Down Expand Up @@ -16690,12 +16692,14 @@
]
},
"fbld tword [rax]": {
"ExpectedInstructionCount": 40,
"ExpectedInstructionCount": 42,
"Comment": [
"0xdf !11b /4"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"mrs x0, nzcv",
"str w0, [x28, #1000]",
"stp x4, x7, [x28, #280]",
Expand Down
12 changes: 8 additions & 4 deletions unittests/InstructionCountCI/x87.json
Original file line number Diff line number Diff line change
Expand Up @@ -6868,12 +6868,14 @@
]
},
"fld tword [rax]": {
"ExpectedInstructionCount": 12,
"ExpectedInstructionCount": 14,
"Comment": [
"0xdb !11b /5"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"ldrb w20, [x28, #1019]",
"mov w21, #0x1",
"sub w20, w20, #0x1 (1)",
Expand Down Expand Up @@ -16548,12 +16550,14 @@
]
},
"fbld tword [rax]": {
"ExpectedInstructionCount": 40,
"ExpectedInstructionCount": 42,
"Comment": [
"0xdf !11b /4"
],
"ExpectedArm64ASM": [
"ldr q2, [x4]",
"ldr d2, [x4]",
"add x20, x4, #0x8 (8)",
"ld1 {v2.h}[4], [x20]",
"mrs x0, nzcv",
"str w0, [x28, #1000]",
"stp x4, x7, [x28, #280]",
Expand Down

0 comments on commit 2e7fc60

Please sign in to comment.