diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/cpu/drcbearm64.cpp | 18 | ||||
-rw-r--r-- | src/devices/cpu/drcbex64.cpp | 23 |
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); - } } |