summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/drcbex64.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2025-04-03 02:40:43 +1100
committer Vas Crabb <vas@vastheman.com>2025-04-03 02:40:43 +1100
commit436431d99b4f2d8a502fd4fc911830ac0d237db5 (patch)
tree145b752c16ac0ad2c217162da4e21d10e1bc385c /src/devices/cpu/drcbex64.cpp
parent9349b16a17d6395e301c719af14b4428fee73421 (diff)
-cpu/e132xs: Miscellaneous fixes/optimisation:
* Fixed behaviour of delayed branches, trace exceptions, and saved PC calculation for error exceptions in delay slots for the interpreter. All instructions in delay slots, branching instructions that can raise exceptions and tracing shoud now (mis)behave properly for the interpreter, including things the manual says you shouldn't do. * Fixed and optimised flag updates for left shifts for the recompiler. * Optimised ROL instruction for the recompiler and made flag calculation equivalent to the interpreter both with and without the "Missioncraft flags" compile-time option. * Only block interrupts for one instruction following a delayed branch. * Optimised the SOFTWARE instruction a little for the recompiler. * Added more SDRAM configuration logging and cleaned up code a bit. -cpu/drcbearm64.cpp: Apply the change from 7efe37938f9dd6a366e to OR and XOR instructions as well, and fix some cases where a 32-bit logical operation would fail to clear the upper bits of a register. -cpu/drcbex64.cpp: Avoid more conditional branches on conditional MOV.
Diffstat (limited to 'src/devices/cpu/drcbex64.cpp')
-rw-r--r--src/devices/cpu/drcbex64.cpp43
1 files changed, 28 insertions, 15 deletions
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp
index 45d442e8576..f95a3700804 100644
--- a/src/devices/cpu/drcbex64.cpp
+++ b/src/devices/cpu/drcbex64.cpp
@@ -3661,26 +3661,28 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst)
// add a conditional branch unless a conditional move is possible
Label skip;
- if (inst.condition() != uml::COND_ALWAYS && !(dstp.is_int_register() && !srcp.is_immediate()))
+ const bool need_skip = (inst.condition() != uml::COND_ALWAYS) && !dstp.is_int_register();
+ if (need_skip)
{
skip = a.newLabel();
a.short_().j(X86_NOT_CONDITION(inst.condition()), skip);
}
- // register to memory
if (dstp.is_memory() && srcp.is_int_register())
{
+ // register to memory
Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg());
a.mov(MABS(dstp.memory()), src);
}
- // immediate to memory
else if (dstp.is_memory() && srcp.is_immediate() && short_immediate(srcp.immediate()))
+ {
+ // immediate to memory
a.mov(MABS(dstp.memory(), inst.size()), s32(srcp.immediate()));
-
- // conditional memory to register
+ }
else if (dstp.is_int_register() && srcp.is_memory())
{
+ // conditional memory to register
Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg());
if (inst.condition() != uml::COND_ALWAYS)
@@ -3688,30 +3690,41 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst)
else
a.mov(dst, MABS(srcp.memory()));
}
-
- // conditional register to register
- else if (dstp.is_int_register() && srcp.is_int_register())
+ else if (dstp.is_int_register())
{
- Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg());
+ // conditional register to register
Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg());
if (inst.condition() != uml::COND_ALWAYS)
- a.cmov(X86_CONDITION(inst.condition()), dst, src);
+ {
+ if (srcp.is_int_register())
+ {
+ Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg());
+ a.cmov(X86_CONDITION(inst.condition()), dst, src);
+ }
+ else
+ {
+ Gp const src = (inst.size() == 4) ? Gp(eax) : Gp(rax);
+ mov_reg_param(a, src, srcp, true);
+ a.cmov(X86_CONDITION(inst.condition()), dst, src);
+ }
+ }
else
- a.mov(dst, src);
+ {
+ mov_reg_param(a, dst, srcp, true);
+ }
}
-
- // general case
else
{
- Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax);
+ // general case
+ Gp const dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax);
mov_reg_param(a, dstreg, srcp, true);
mov_param_reg(a, dstp, dstreg);
}
// resolve the jump
- if (inst.condition() != uml::COND_ALWAYS && !(dstp.is_int_register() && !srcp.is_immediate()))
+ if (need_skip)
a.bind(skip);
}