summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/drcbearm64.cpp18
-rw-r--r--src/devices/cpu/drcbex64.cpp23
2 files changed, 22 insertions, 19 deletions
diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp
index b9eee3fd6b8..028099abdf0 100644
--- a/src/devices/cpu/drcbearm64.cpp
+++ b/src/devices/cpu/drcbearm64.cpp
@@ -3421,8 +3421,13 @@ template <bool CarryIn> void drcbe_arm64::op_add(a64::Assembler &a, const uml::i
const a64::Gp zero = select_register(a64::xzr, inst.size());
const a64::Gp output = dstp.select_register(TEMP_REG3, inst.size());
- if (CarryIn)
- load_carry(a);
+ if (CarryIn && (m_carry_state != carry_state::CANONICAL))
+ {
+ m_carry_state = carry_state::CANONICAL;
+
+ a.sbfx(TEMP_REG1, FLAGS_REG, FLAG_BIT_C, 1);
+ a.cmn(TEMP_REG1, 1);
+ }
if (src1p.is_immediate_value(0))
{
@@ -3551,8 +3556,13 @@ template <bool CarryIn> void drcbe_arm64::op_sub(a64::Assembler &a, const uml::i
be_parameter src1p(*this, inst.param(1), PTYPE_MRI);
be_parameter src2p(*this, inst.param(2), PTYPE_MRI);
- if (CarryIn)
- load_carry(a, true);
+ if (CarryIn && (m_carry_state != carry_state::LOGICAL))
+ {
+ m_carry_state = carry_state::LOGICAL;
+
+ a.ubfx(TEMP_REG1, FLAGS_REG, FLAG_BIT_C, 1);
+ a.cmp(a64::xzr, TEMP_REG1);
+ }
const a64::Gp zero = select_register(a64::xzr, inst.size());
const a64::Gp output = dstp.select_register(TEMP_REG3, inst.size());
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp
index 7c8a8003644..5bfe57c39fe 100644
--- a/src/devices/cpu/drcbex64.cpp
+++ b/src/devices/cpu/drcbex64.cpp
@@ -3547,7 +3547,7 @@ void drcbe_x64::op_carry(Assembler &a, const instruction &inst)
// degenerate case: source is immediate
if (srcp.is_immediate() && bitp.is_immediate())
{
- if (srcp.immediate() & ((uint64_t)1 << (bitp.immediate() & (inst.size() * 8 - 1))))
+ if (BIT(srcp.immediate(), bitp.immediate() & ((inst.size() * 8) - 1)))
a.stc();
else
a.clc();
@@ -3556,36 +3556,29 @@ void drcbe_x64::op_carry(Assembler &a, const instruction &inst)
}
// load non-immediate bit numbers into a register
-
- Gp const bitreg = rcx;
+ Gp const bitreg = (inst.size() == 8) ? Gp(rcx) : Gp(ecx);
if (!bitp.is_immediate())
{
mov_reg_param(a, bitreg, bitp);
- a.and_(bitreg, inst.size() * 8 - 1);
+ a.and_(bitreg, (inst.size() * 8) - 1);
}
if (srcp.is_memory())
{
if (bitp.is_immediate())
- a.bt(MABS(srcp.memory(), inst.size()), (bitp.immediate() & (inst.size() * 8 - 1)));
+ a.bt(MABS(srcp.memory(), inst.size()), bitp.immediate() & ((inst.size() * 8) - 1));
else
a.bt(MABS(srcp.memory(), inst.size()), bitreg);
}
- else if (srcp.is_int_register())
+ else
{
- Gp const src = Gp::fromTypeAndId(RegType::kX86_Gpq, srcp.ireg());
+ Gp const src = srcp.select_register(Gp(bitreg, Gp::kIdAx));
+ mov_reg_param(a, src, srcp);
if (bitp.is_immediate())
- a.bt(src, (bitp.immediate() & (inst.size() * 8 - 1)));
+ a.bt(src, bitp.immediate() & ((inst.size() * 8) - 1));
else
a.bt(src, bitreg);
}
- else if (srcp.is_immediate())
- {
- a.push(rax);
- mov_reg_param(a, rax, srcp);
- a.bt(rax, bitreg);
- a.pop(rax);
- }
}