mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 19:00:17 +02:00
Merge pull request #5439 from Sonicadvance1/144
Fix push/pop fs/gs segments and unittests
This commit is contained in:
2 files changed
+82
-4
No files matched your search
@@ -31,19 +31,19 @@ constexpr std::array<X86InstInfo[2], ENTRY_MAX> Secondary_ArchSelect_LUT = {{
|
||||
},
|
||||
{
|
||||
{"PUSH FS", TYPE_INST, GenFlagsSrcSize(SIZE_16BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::PUSHSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX> } },
|
||||
{"PUSH FS", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::PUSHSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX> } },
|
||||
{"PUSH FS", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::PUSHSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX> } },
|
||||
},
|
||||
{
|
||||
{"POP FS", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_DEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::POPSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX> } },
|
||||
{"POP FS", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::POPSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX> } },
|
||||
{"POP FS", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_64BITDEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::POPSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_FS_PREFIX> } },
|
||||
},
|
||||
{
|
||||
{"PUSH GS", TYPE_INST, GenFlagsSrcSize(SIZE_16BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::PUSHSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX> } },
|
||||
{"PUSH GS", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::PUSHSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX> } },
|
||||
{"PUSH GS", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::PUSHSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX> } },
|
||||
},
|
||||
{
|
||||
{"POP GS", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_DEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::POPSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX> } },
|
||||
{"POP GS", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::POPSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX> } },
|
||||
{"POP GS", TYPE_INST, GenFlagsSizes(SIZE_16BIT, SIZE_64BITDEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_NO_OVERLAY, 0, { .OpDispatch = &IR::OpDispatchBuilder::Bind<&IR::OpDispatchBuilder::POPSegmentOp, FEXCore::X86Tables::DecodeFlags::FLAG_GS_PREFIX> } },
|
||||
},
|
||||
}};
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": "1"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; FEX-Emu had a bug where segment registers prefixed with `o16` were still pushing and popping a full 64-bits to the stack.
|
||||
; With o16 it is supposed to only operate on 16-bits. Run through the instructions and just ensure it is pushing/popping the correct amount.
|
||||
|
||||
; Need to save and restore fs/gs base on this test.
|
||||
rdfsbase rax
|
||||
mov [rel .data_segment], rax
|
||||
|
||||
rdgsbase rax
|
||||
mov [rel .data_segment + 8], rax
|
||||
|
||||
mov rax, 0
|
||||
mov rbx, 0xe000_0ffe
|
||||
mov rcx, 0xe000_1000
|
||||
mov rsp, 0xe000_1000
|
||||
|
||||
; Ensure 16-bit FS/GS push/pops are the correct size.
|
||||
o16 push fs
|
||||
cmp rsp, rbx
|
||||
jne .bad
|
||||
|
||||
o16 pop fs
|
||||
cmp rsp, rcx
|
||||
jne .bad
|
||||
|
||||
o16 push gs
|
||||
cmp rsp, rbx
|
||||
jne .bad
|
||||
|
||||
o16 pop gs
|
||||
cmp rsp, rcx
|
||||
jne .bad
|
||||
|
||||
; Check 64-bit as well.
|
||||
mov rbx, 0xe000_0ff8
|
||||
|
||||
push fs
|
||||
cmp rsp, rbx
|
||||
jne .bad
|
||||
|
||||
pop fs
|
||||
cmp rsp, rcx
|
||||
jne .bad
|
||||
|
||||
push gs
|
||||
cmp rsp, rbx
|
||||
jne .bad
|
||||
|
||||
pop gs
|
||||
cmp rsp, rcx
|
||||
jne .bad
|
||||
|
||||
mov rax, 1
|
||||
jmp .end
|
||||
|
||||
.bad:
|
||||
mov rax, 0
|
||||
|
||||
.end:
|
||||
mov rbx, [rel .data_segment]
|
||||
wrfsbase rbx
|
||||
|
||||
mov rbx, [rel .data_segment + 8]
|
||||
wrgsbase rbx
|
||||
|
||||
hlt
|
||||
|
||||
align 4096
|
||||
.data_segment:
|
||||
dq 0
|
||||
dq 0
|
||||
Reference in new issue
Block a user