From 7bb6a2ef931c0bf9b61ca03991819d9744b154ba Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 20 Feb 2023 16:37:42 -0500 Subject: arm7: Clean up various code using util::sext and multiply inlines * mb86235: One more use of util::sext --- src/devices/cpu/arm7/arm7dasm.cpp | 18 +---- src/devices/cpu/arm7/arm7ops.cpp | 118 +++++++++------------------------ src/devices/cpu/arm7/arm7thmb.cpp | 22 ++---- src/devices/cpu/mb86235/mb86235drc.cpp | 3 +- 4 files changed, 41 insertions(+), 120 deletions(-) diff --git a/src/devices/cpu/arm7/arm7dasm.cpp b/src/devices/cpu/arm7/arm7dasm.cpp index 7de800bb9c8..a4a2d590b19 100644 --- a/src/devices/cpu/arm7/arm7dasm.cpp +++ b/src/devices/cpu/arm7/arm7dasm.cpp @@ -181,11 +181,7 @@ void arm7_disassembler::WriteBranchAddress( std::ostream &stream, uint32_t pc, u { opcode |= 2; } - opcode &= 0x03fffffe; - if( opcode & 0x02000000 ) - { - opcode |= 0xfc000000; /* sign-extend */ - } + opcode = util::sext( opcode, 26 ); pc += 8+opcode; util::stream_format( stream, "0x%08X", pc ); } /* WriteBranchAddress */ @@ -1362,11 +1358,7 @@ u32 arm7_disassembler::thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t } else { - offs = ( opcode & THUMB_BRANCH_OFFS ) << 1; - if( offs & 0x00000800 ) - { - offs |= 0xfffff800; - } + offs = util::sext( ( opcode & THUMB_BRANCH_OFFS ) << 1, 12 ); stream << "B"; WritePadding(stream, start_position); util::stream_format( stream, "0x%08X", uint32_t(pc + 4 + offs)); @@ -1380,11 +1372,7 @@ u32 arm7_disassembler::thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t } else { - addr = ( opcode & THUMB_BLOP_OFFS ) << 12; - if( addr & ( 1 << 22 ) ) - { - addr |= 0xff800000; - } + addr = util::sext( ( opcode & THUMB_BLOP_OFFS ) << 12, 23 ); util::stream_format( stream, "BL (HI) 0x%X", addr ); dasmflags = STEP_OVER; } diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index b1e7d2b2400..b56c6bdce4b 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -1216,18 +1216,14 @@ void arm7_cpu_device::HandleMul(uint32_t insn) // todo: add proper cycle counts void arm7_cpu_device::HandleSMulLong(uint32_t insn) { - int32_t rm, rs; - uint32_t rhi, rlo; - int64_t res; - // MULL takes 1S + (m+1)I and MLAL 1S + (m+2)I cycles to execute, where m is the // number of 8 bit multiplier array cycles required to complete the multiply, which is // controlled by the value of the multiplier operand specified by Rs. - rm = (int32_t)GetRegister(insn & 0xf); - rs = (int32_t)GetRegister(((insn >> 8) & 0xf)); - rhi = (insn >> 16) & 0xf; - rlo = (insn >> 12) & 0xf; + int32_t rm = (int32_t)GetRegister(insn & 0xf); + int32_t rs = (int32_t)GetRegister(((insn >> 8) & 0xf)); + uint32_t rhi = (insn >> 16) & 0xf; + uint32_t rlo = (insn >> 12) & 0xf; #if ARM7_DEBUG_CORE if ((insn & 0xf) == 15 || ((insn >> 8) & 0xf) == 15 || ((insn >> 16) & 0xf) == 15 || ((insn >> 12) & 0xf) == 15) @@ -1235,7 +1231,7 @@ void arm7_cpu_device::HandleSMulLong(uint32_t insn) #endif /* Perform the multiplication */ - res = (int64_t)rm * rs; + int64_t res = mul_32x32(rm, rs); /* Add on Rn if this is a MLA */ if (insn & INSN_MUL_A) @@ -1268,18 +1264,14 @@ void arm7_cpu_device::HandleSMulLong(uint32_t insn) // todo: add proper cycle counts void arm7_cpu_device::HandleUMulLong(uint32_t insn) { - uint32_t rm, rs; - uint32_t rhi, rlo; - uint64_t res; - // MULL takes 1S + (m+1)I and MLAL 1S + (m+2)I cycles to execute, where m is the // number of 8 bit multiplier array cycles required to complete the multiply, which is // controlled by the value of the multiplier operand specified by Rs. - rm = (int32_t)GetRegister(insn & 0xf); - rs = (int32_t)GetRegister(((insn >> 8) & 0xf)); - rhi = (insn >> 16) & 0xf; - rlo = (insn >> 12) & 0xf; + uint32_t rm = GetRegister(insn & 0xf); + uint32_t rs = GetRegister(((insn >> 8) & 0xf)); + uint32_t rhi = (insn >> 16) & 0xf; + uint32_t rlo = (insn >> 12) & 0xf; #if ARM7_DEBUG_CORE if (((insn & 0xf) == 15) || (((insn >> 8) & 0xf) == 15) || (((insn >> 16) & 0xf) == 15) || (((insn >> 12) & 0xf) == 15)) @@ -1287,7 +1279,7 @@ void arm7_cpu_device::HandleUMulLong(uint32_t insn) #endif /* Perform the multiplication */ - res = (uint64_t)rm * rs; + uint64_t res = mulu_32x32(rm, rs); /* Add on Rn if this is a MLA */ if (insn & INSN_MUL_A) @@ -1705,9 +1697,8 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>16)&0xf); - int64_t res; - res = saturate_qbit_overflow((int64_t)src1 + (int64_t)src2); + int64_t res = saturate_qbit_overflow((int64_t)src1 + (int64_t)src2); SetRegister((insn>>12)&0xf, (int32_t)res); R15 += 4; @@ -1716,10 +1707,9 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>16)&0xf); - int64_t res; // check if doubling operation will overflow - res = (int64_t)src2 * 2; + int64_t res = (int64_t)src2 * 2; saturate_qbit_overflow(res); src2 *= 2; @@ -1732,9 +1722,8 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>16)&0xf); - int64_t res; - res = saturate_qbit_overflow((int64_t)src1 - (int64_t)src2); + int64_t res = saturate_qbit_overflow((int64_t)src1 - (int64_t)src2); SetRegister((insn>>12)&0xf, (int32_t)res); R15 += 4; @@ -1743,10 +1732,9 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>16)&0xf); - int64_t res; // check if doubling operation will overflow - res = (int64_t)src2 * 2; + int64_t res = (int64_t)src2 * 2; saturate_qbit_overflow(res); src2 *= 2; @@ -1763,26 +1751,14 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) // select top and bottom halves of src1/src2 and sign extend if necessary if (insn & 0x20) - { src1 >>= 16; - } - - src1 &= 0xffff; - if (src1 & 0x8000) - { - src1 |= 0xffff0000; - } + else + src1 = util::sext(src1, 16); if (insn & 0x40) - { src2 >>= 16; - } - - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff0000; - } + else + src2 = util::sext(src2, 16); // do the signed multiply res1 = src1 * src2; @@ -1796,13 +1772,12 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>8)&0xf); - int64_t dst; - dst = (int64_t)GetRegister((insn>>12)&0xf); + int64_t dst = (int64_t)GetRegister((insn>>12)&0xf); dst |= (int64_t)GetRegister((insn>>16)&0xf)<<32; // do the multiply and accumulate - dst += (int64_t)src1 * (int64_t)src2; + dst += mul_32x32(src1, src2); // write back the result SetRegister((insn>>12)&0xf, (uint32_t)dst); @@ -1813,32 +1788,19 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>8)&0xf); - int32_t res; // select top and bottom halves of src1/src2 and sign extend if necessary if (insn & 0x20) - { src1 >>= 16; - } - - src1 &= 0xffff; - if (src1 & 0x8000) - { - src1 |= 0xffff0000; - } + else + src1 = util::sext(src1, 16); if (insn & 0x40) - { src2 >>= 16; - } - - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff0000; - } + else + src2 = util::sext(src2, 16); - res = src1 * src2; + int32_t res = src1 * src2; SetRegister((insn>>16)&0xf, res); R15 += 4; } @@ -1846,21 +1808,13 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) { int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>8)&0xf); - int64_t res; if (insn & 0x40) - { src2 >>= 16; - } - - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff0000; - } + else + src2 = util::sext(src2, 16); - res = (int64_t)src1 * (int64_t)src2; - res >>= 16; + int32_t res = mul_32x32_shift(src1, src2, 16); SetRegister((insn>>16)&0xf, (uint32_t)res); R15 += 4; } @@ -1869,27 +1823,19 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) int32_t src1 = GetRegister(insn&0xf); int32_t src2 = GetRegister((insn>>8)&0xf); int32_t src3 = GetRegister((insn>>12)&0xf); - int64_t res; if (insn & 0x40) - { src2 >>= 16; - } - - src2 &= 0xffff; - if (src2 & 0x8000) - { - src2 |= 0xffff0000; - } + else + src2 = util::sext(src2, 16); - res = (int64_t)src1 * (int64_t)src2; - res >>= 16; + int32_t res = mul_32x32_shift(src1, src2, 16); // check for overflow and set the Q bit saturate_qbit_overflow((int64_t)src3 + res); // do the real accumulate - src3 += (int32_t)res; + src3 += res; // write the result back SetRegister((insn>>16)&0xf, (uint32_t)res); diff --git a/src/devices/cpu/arm7/arm7thmb.cpp b/src/devices/cpu/arm7/arm7thmb.cpp index 47a0bcfe2d1..467606aee84 100644 --- a/src/devices/cpu/arm7/arm7thmb.cpp +++ b/src/devices/cpu/arm7/arm7thmb.cpp @@ -1004,18 +1004,14 @@ void arm7_cpu_device::tg05_2(uint32_t pc, uint32_t op) /* STRB Rd, [Rn, Rm] */ R15 += 2; } -void arm7_cpu_device::tg05_3(uint32_t pc, uint32_t op) /* LDSB Rd, [Rn, Rm] todo, add dasm */ +void arm7_cpu_device::tg05_3(uint32_t pc, uint32_t op) /* LDRSB Rd, [Rn, Rm] */ { uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; uint32_t rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT; uint32_t addr = GetRegister(rn) + GetRegister(rm); uint32_t op2 = READ8(addr); - if (op2 & 0x00000080) - { - op2 |= 0xffffff00; - } - SetRegister(rd, op2); + SetRegister(rd, util::sext(op2, 8)); R15 += 2; } @@ -1052,7 +1048,7 @@ void arm7_cpu_device::tg05_6(uint32_t pc, uint32_t op) /* LDRB Rd, [Rn, Rm] */ R15 += 2; } -void arm7_cpu_device::tg05_7(uint32_t pc, uint32_t op) /* LDSH Rd, [Rn, Rm] */ +void arm7_cpu_device::tg05_7(uint32_t pc, uint32_t op) /* LDRSH Rd, [Rn, Rm] */ { uint32_t rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT; uint32_t rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT; @@ -1547,11 +1543,7 @@ void arm7_cpu_device::tg0d_f(uint32_t pc, uint32_t op) // COND_NV: // SWI (thi void arm7_cpu_device::tg0e_0(uint32_t pc, uint32_t op) { - int32_t offs = (op & THUMB_BRANCH_OFFS) << 1; - if (offs & 0x00000800) - { - offs |= 0xfffff800; - } + int32_t offs = util::sext((op & THUMB_BRANCH_OFFS) << 1, 12); R15 += 4 + offs; } @@ -1572,11 +1564,7 @@ void arm7_cpu_device::tg0f_0(uint32_t pc, uint32_t op) { /* BL (HI) */ - uint32_t addr = (op & THUMB_BLOP_OFFS) << 12; - if (addr & (1 << 22)) - { - addr |= 0xff800000; - } + uint32_t addr = util::sext((op & THUMB_BLOP_OFFS) << 12, 23); addr += R15 + 4; SetRegister(14, addr); R15 += 2; diff --git a/src/devices/cpu/mb86235/mb86235drc.cpp b/src/devices/cpu/mb86235/mb86235drc.cpp index e5903a3224b..468ac24ad8f 100644 --- a/src/devices/cpu/mb86235/mb86235drc.cpp +++ b/src/devices/cpu/mb86235/mb86235drc.cpp @@ -1718,8 +1718,7 @@ void mb86235_device::generate_xfer2(drcuml_block &block, compiler_state &compile int ary = (opcode >> 4) & 7; int md = opcode & 0xf; - int disp14 = (opcode >> 7) & 0x3fff; - if (disp14 & 0x2000) disp14 |= 0xffffc000; + int disp14 = util::sext((opcode >> 7) & 0x3fff, 14); if (op == 0) // MOV2 { -- cgit v1.2.3