Merge pull request #1555 from Sonicadvance1/weirdo_edge_case

OpcodeDispatcher: Fixes weirdo edge case in segment moving
This commit is contained in:
Mai M authored and GitHub committed 2022-02-08 00:26:55 -05:00
commit ffcaf294e3
4 files changed
+62 -4

No files matched your search

+13 -1
View File
@@ -1573,19 +1573,24 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
switch (Op->Dest.Data.GPR.GPR) {
case 0: // ES
case FEXCore::X86State::REG_R8: // ES
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, es), Src);
break;
case 1: // DS
case FEXCore::X86State::REG_R11: // DS
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, ds), Src);
break;
case 2: // CS
case FEXCore::X86State::REG_R9: // CS
// CPL3 can't write to this
_Break(FEXCore::IR::Break_InvalidInstruction, 0);
break;
case 3: // SS
case FEXCore::X86State::REG_R10: // SS
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, ss), Src);
break;
case 6: // GS
case FEXCore::X86State::REG_R13: // GS
if (!CTX->Config.Is64BitMode) {
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, gs), Src);
} else {
@@ -1594,6 +1599,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
}
break;
case 7: // FS
case FEXCore::X86State::REG_R12: // FS
if (!CTX->Config.Is64BitMode) {
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, fs), Src);
} else {
@@ -1602,7 +1608,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
}
break;
default:
LogMan::Msg::EFmt("Unknown segment register: %d", Op->Dest.Data.GPR.GPR);
LogMan::Msg::EFmt("Unknown segment register: {}", Op->Dest.Data.GPR.GPR);
DecodeFailure = true;
break;
}
@@ -1612,18 +1618,23 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
switch (Op->Src[0].Data.GPR.GPR) {
case 0: // ES
case FEXCore::X86State::REG_R8: // ES
Segment = _LoadContext(2, offsetof(FEXCore::Core::CPUState, es), GPRClass);
break;
case 1: // DS
case FEXCore::X86State::REG_R11: // DS
Segment = _LoadContext(2, offsetof(FEXCore::Core::CPUState, ds), GPRClass);
break;
case 2: // CS
case FEXCore::X86State::REG_R9: // CS
Segment = _LoadContext(2, offsetof(FEXCore::Core::CPUState, cs), GPRClass);
break;
case 3: // SS
case FEXCore::X86State::REG_R10: // SS
Segment = _LoadContext(2, offsetof(FEXCore::Core::CPUState, ss), GPRClass);
break;
case 6: // GS
case FEXCore::X86State::REG_R13: // GS
if (CTX->Config.Is64BitMode) {
Segment = _Constant(0);
}
@@ -1632,6 +1643,7 @@ void OpDispatchBuilder::MOVSegOp(OpcodeArgs) {
}
break;
case 7: // FS
case FEXCore::X86State::REG_R12: // FS
if (CTX->Config.Is64BitMode) {
Segment = _Constant(0);
}
-3
View File
@@ -1,6 +1,3 @@
# Not guaranteed to work in 64bit mode
Test_Primary/Primary_8C.asm
# Needs Precision checking
Test_REP/F3_52.asm
Test_REP/F3_53.asm
+4
View File
@@ -11,3 +11,7 @@ Test_TwoByte/0F_0E.asm
# Intel doesn't support CLZero, which the CI uses
Test_SecondaryModRM/Reg_7_4.asm
Test_SecondaryModRM/Reg_7_4_2.asm
# Not guaranteed to work in 64bit mode
Test_Primary/Primary_8C.asm
Test_Primary/Primary_8C_2.asm
+45
View File
@@ -0,0 +1,45 @@
%ifdef CONFIG
{
"RegData": {
"RAX": "0x4142",
"RBX": "0x4143",
"RCX": "0x4144"
}
}
%endif
; This relies on some behaviour that isn't guaranteed in 64bit mode
; Technically this can result in an invalid selector which can cause faults
; We currently don't do any selector validation to enforce this
mov rax, 0x4142
db 0x44 ; REX.R
mov es, ax
inc rax
db 0x44 ; REX.R
mov ss, ax
inc rax
db 0x44 ; REX.R
mov ds, ax
; Can't test FS/GS here
; Behaviour is ill-defined and needs to be worked through
mov rax, 0
mov rbx, 0
mov rcx, 0
db 0x44 ; REX.R
mov ax, es
db 0x44 ; REX.R
mov bx, ss
db 0x44 ; REX.R
mov cx, ds
hlt