mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-24 19:00:48 +02:00
Merge pull request #4169 from Sonicadvance1/x87_loadstore_tests
unittests/ASM: Fixes x87 80-bit loads on the edge of page boundaries.
This commit is contained in:
6 files changed
+91
-10
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)",
|
||||
@@ -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]",
|
||||
|
||||
@@ -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)",
|
||||
@@ -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]",
|
||||
|
||||
Reference in new issue
Block a user