mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 17:00:19 +02:00
Merge pull request #3504 from Sonicadvance1/fix_loop_a16
OpcodeDispatcher: Fixes 32-bit mode LOOP RCX register usage
This commit is contained in:
3 files changed
+60
-2
No files matched your search
@@ -1058,13 +1058,19 @@ void OpDispatchBuilder::LoopOp(OpcodeArgs) {
|
||||
|
||||
BlockSetRIP = true;
|
||||
uint32_t SrcSize = (Op->Flags & X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) ? 4 : 8;
|
||||
auto OpSize = SrcSize == 8 ? OpSize::i64Bit : OpSize::i32Bit;
|
||||
|
||||
if (!CTX->Config.Is64BitMode) {
|
||||
// RCX size is 32-bit or 16-bit when executing in 32-bit mode.
|
||||
SrcSize >>= 1;
|
||||
OpSize = OpSize::i32Bit;
|
||||
}
|
||||
|
||||
LOGMAN_THROW_A_FMT(Op->Src[1].IsLiteral(), "Src1 needs to be literal here");
|
||||
|
||||
uint64_t Target = Op->PC + Op->InstSize + Op->Src[1].Data.Literal.Value;
|
||||
|
||||
auto OpSize = SrcSize == 8 ? OpSize::i64Bit : OpSize::i32Bit;
|
||||
OrderedNode *CondReg = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags);
|
||||
OrderedNode *CondReg = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], SrcSize, Op->Flags);
|
||||
CondReg = _Sub(OpSize, CondReg, _Constant(SrcSize * 8, 1));
|
||||
StoreResult(GPRClass, Op, Op->Src[0], CondReg, -1);
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": "0x0000000000000001",
|
||||
"RBX": "0x0000000000010001"
|
||||
},
|
||||
"Mode": "32BIT"
|
||||
}
|
||||
%endif
|
||||
|
||||
; FEX-Emu had a bug where a16 loop instructions weren't treating the input RCX register as 16-bit.
|
||||
; Effectively always treating it as 32-bit.
|
||||
; Little test that operates at 16-bit and 32-bit sizes to ensure it is correctly handled.
|
||||
mov eax, 0
|
||||
mov ebx, 0
|
||||
mov ecx, 0x0001_0001
|
||||
|
||||
.test:
|
||||
inc eax
|
||||
a16 loop .test
|
||||
|
||||
mov ecx, 0x0001_0001
|
||||
.test2:
|
||||
inc ebx
|
||||
a32 loop .test2
|
||||
|
||||
hlt
|
||||
@@ -0,0 +1,25 @@
|
||||
%ifdef CONFIG
|
||||
{
|
||||
"RegData": {
|
||||
"RAX": "0x0000000000010001",
|
||||
"RBX": "0x0000000000000001"
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
; FEX-Emu had a bug in the 32-bit implementation of LOOP where it didn't handle 16-bit RCX correctly.
|
||||
; For test coverage on the 64-bit side, ensure that both 64-bit and 32-bit operation works correctly.
|
||||
mov rax, 0
|
||||
mov rbx, 0
|
||||
mov rcx, 0x0001_0001
|
||||
|
||||
.test:
|
||||
inc rax
|
||||
a64 loop .test
|
||||
|
||||
mov rcx, 0x1_0000_0001
|
||||
.test2:
|
||||
inc rbx
|
||||
a32 loop .test2
|
||||
|
||||
hlt
|
||||
Reference in new issue
Block a user