diff options
Diffstat (limited to 'src/devices/cpu/score/score.cpp')
-rw-r--r-- | src/devices/cpu/score/score.cpp | 128 |
1 files changed, 65 insertions, 63 deletions
diff --git a/src/devices/cpu/score/score.cpp b/src/devices/cpu/score/score.cpp index f541c27a0fe..14565f23488 100644 --- a/src/devices/cpu/score/score.cpp +++ b/src/devices/cpu/score/score.cpp @@ -14,7 +14,6 @@ ******************************************************************************/ #include "emu.h" -#include "debugger.h" #include "score.h" #include "scoredsm.h" @@ -222,7 +221,6 @@ void score7_cpu_device::execute_set_input(int inputnum, int state) { if (state) { - standard_irq_callback(inputnum); if (inputnum > 0 && inputnum < 64) m_pending_interrupt |= 1ULL << inputnum; } @@ -273,13 +271,6 @@ bool score7_cpu_device::check_condition(uint8_t bc) return false; } -int32_t score7_cpu_device::sign_extend(uint32_t data, uint8_t len) -{ - data &= (1ULL << len) - 1; - uint32_t sign = 1 << (len - 1); - return (data ^ sign) - sign; -} - uint32_t score7_cpu_device::fetch() { return m_cache.read_dword(m_pc & ~3); @@ -324,7 +315,7 @@ void score7_cpu_device::check_irq() if (m_pending_interrupt & (1ULL << i)) { m_pending_interrupt &= ~(1ULL << i); - standard_irq_callback(i); + standard_irq_callback(i, m_pc); gen_exception(EXCEPTION_INTERRUPT, i); return; } @@ -561,31 +552,34 @@ void score7_cpu_device::op_specialform() } break; case 0x18: // sll - m_gpr[rd] = m_gpr[ra] << (m_gpr[rb] & 0x1f); + r = m_gpr[ra] << (m_gpr[rb] & 0x1f); if (cu) { - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); + CHECK_Z(r); + CHECK_N(r); SET_C(BIT(m_gpr[ra], 32 - (m_gpr[rb] & 0x1f))); } + m_gpr[rd] = r; break; case 0x1a: // srl - m_gpr[rd] = m_gpr[ra] >> (m_gpr[rb] & 0x1f); + r = m_gpr[ra] >> (m_gpr[rb] & 0x1f); if (cu) { - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); + CHECK_Z(r); + CHECK_N(r); SET_C(BIT(m_gpr[ra], (m_gpr[rb] & 0x1f) - 1)); } + m_gpr[rd] = r; break; case 0x1b: // sra - m_gpr[rd] = sign_extend(m_gpr[ra] >> (m_gpr[rb] & 0x1f), 32 - (m_gpr[rb] & 0x1f)); + r = util::sext(m_gpr[ra] >> (m_gpr[rb] & 0x1f), 32 - (m_gpr[rb] & 0x1f)); if (cu) { - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); + CHECK_Z(r); + CHECK_N(r); SET_C(BIT(m_gpr[ra], (m_gpr[rb] & 0x1f) - 1)); } + m_gpr[rd] = r; break; case 0x1c: // ror unemulated_op("ror"); @@ -601,18 +595,14 @@ void score7_cpu_device::op_specialform() break; case 0x20: // mul { - int64_t a = (int32_t)m_gpr[ra]; - int64_t b = (int32_t)m_gpr[rb]; - uint64_t d = a * b; + uint64_t d = mul_32x32(m_gpr[ra], m_gpr[rb]); REG_CEL = d & 0xffffffff; REG_CEH = (d >> 32) & 0xffffffff; break; } case 0x21: // mulu { - uint64_t a = (uint32_t)m_gpr[ra]; - uint64_t b = (uint32_t)m_gpr[rb]; - uint64_t d = a * b; + uint64_t d = mulu_32x32(m_gpr[ra], m_gpr[rb]); REG_CEL = d & 0xffffffff; REG_CEH = (d >> 32) & 0xffffffff; break; @@ -662,10 +652,14 @@ void score7_cpu_device::op_specialform() case 0x28: // mfsr if (rb < 3) m_gpr[rd] = m_sr[rb]; + else + logerror("%s: mfsr accessing sr%d (PC=0x%08x)\n", tag(), rb, m_ppc); break; case 0x29: // mtsr if (rb < 3) m_sr[rb] = m_gpr[ra]; + else + logerror("%s: mtsr accessing sr%d (PC=0x%08x)\n", tag(), rb, m_ppc); break; case 0x2a: // t SET_T(check_condition(rb)); @@ -676,7 +670,7 @@ void score7_cpu_device::op_specialform() break; case 0x2c: // extsb case 0x2d: // extsh - m_gpr[rd] = sign_extend(m_gpr[ra], (GET_S_FUNC6(m_op) & 1) ? 16 : 8); + m_gpr[rd] = util::sext(m_gpr[ra], (GET_S_FUNC6(m_op) & 1) ? 16 : 8); if (cu) { CHECK_N(m_gpr[rd]); @@ -711,31 +705,34 @@ void score7_cpu_device::op_specialform() unemulated_op("sce"); break; case 0x38: // slli - m_gpr[rd] = m_gpr[ra] << rb; + r = m_gpr[ra] << rb; if (cu) { - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); + CHECK_Z(r); + CHECK_N(r); SET_C(BIT(m_gpr[ra], 32 - rb)); } + m_gpr[rd] = r; break; case 0x3a: // srli - m_gpr[rd] = m_gpr[ra] >> rb; + r = m_gpr[ra] >> rb; if (cu) { - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); + CHECK_Z(r); + CHECK_N(r); SET_C(BIT(m_gpr[ra], rb - 1)); } + m_gpr[rd] = r; break; case 0x3b: // srai - m_gpr[rd] = sign_extend(m_gpr[ra] >> rb, 32 - rb); + r = util::sext(m_gpr[ra] >> rb, 32 - rb); if (cu) { - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); + CHECK_Z(r); + CHECK_N(r); SET_C(BIT(m_gpr[ra], rb - 1)); } + m_gpr[rd] = r; break; case 0x3c: // rori unemulated_op("rori"); @@ -758,7 +755,7 @@ void score7_cpu_device::op_iform1() { uint8_t rd = GET_I_RD(m_op); uint32_t imm16 = GET_I_IMM16(m_op); - int32_t simm16 = sign_extend(imm16, 16); + int32_t simm16 = util::sext(imm16, 16); uint8_t cu = GET_I_CU(m_op); uint32_t r; @@ -823,7 +820,7 @@ void score7_cpu_device::op_rixform1() uint8_t rd = GET_RIX_RD(m_op); // pre-increment - m_gpr[ra] += sign_extend(GET_RIX_IMM12(m_op), 12); + m_gpr[ra] += util::sext(GET_RIX_IMM12(m_op), 12); switch(GET_RIX_FUNC3(m_op)) { @@ -831,13 +828,13 @@ void score7_cpu_device::op_rixform1() m_gpr[rd] = read_dword(m_gpr[ra]); break; case 1: // lh - m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16); + m_gpr[rd] = util::sext(read_word(m_gpr[ra]), 16); break; case 2: // lhu m_gpr[rd] = read_word(m_gpr[ra]); break; case 3: // lb - m_gpr[rd] = sign_extend(read_byte(m_gpr[ra]), 8); + m_gpr[rd] = util::sext(read_byte(m_gpr[ra]), 8); break; case 4: // sw write_dword(m_gpr[ra], m_gpr[rd]); @@ -858,7 +855,7 @@ void score7_cpu_device::op_branch() { if (check_condition_branch(GET_BC_BC(m_op))) { - int32_t disp = sign_extend(GET_BC_DISP19(m_op), 19) << 1; + int32_t disp = util::sext(GET_BC_DISP19(m_op), 19) << 1; if (GET_BC_LK(m_op)) REG_LNK = m_pc; @@ -962,13 +959,13 @@ void score7_cpu_device::op_rixform2() m_gpr[rd] = read_dword(m_gpr[ra]); break; case 1: // lh - m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16); + m_gpr[rd] = util::sext(read_word(m_gpr[ra]), 16); break; case 2: // lhu m_gpr[rd] = read_word(m_gpr[ra]); break; case 3: // lb - m_gpr[rd] = sign_extend(read_byte(m_gpr[ra]), 8); + m_gpr[rd] = util::sext(read_byte(m_gpr[ra]), 8); break; case 4: // sw write_dword(m_gpr[ra], m_gpr[rd]); @@ -985,14 +982,14 @@ void score7_cpu_device::op_rixform2() } // post-increment - m_gpr[ra] += sign_extend(GET_RIX_IMM12(m_op), 12); + m_gpr[ra] += util::sext(GET_RIX_IMM12(m_op), 12); } void score7_cpu_device::op_addri() { uint8_t ra = GET_RI_RA(m_op); uint8_t rd = GET_RI_RD(m_op); - int32_t simm14 = sign_extend(GET_RI_IMM14(m_op), 14); + int32_t simm14 = util::sext(GET_RI_IMM14(m_op), 14); uint8_t cu = GET_RI_CU(m_op); uint32_t r = m_gpr[ra] + simm14; @@ -1040,7 +1037,7 @@ void score7_cpu_device::op_lw() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); m_gpr[rd] = read_dword(m_gpr[ra] + simm15); } @@ -1049,16 +1046,16 @@ void score7_cpu_device::op_lh() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); - m_gpr[rd] = sign_extend(read_word(m_gpr[ra] + simm15), 16); + m_gpr[rd] = util::sext(read_word(m_gpr[ra] + simm15), 16); } void score7_cpu_device::op_lhu() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); m_gpr[rd] = read_word(m_gpr[ra] + simm15); } @@ -1067,16 +1064,16 @@ void score7_cpu_device::op_lb() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); - m_gpr[rd] = sign_extend(read_byte(m_gpr[ra] + simm15), 8); + m_gpr[rd] = util::sext(read_byte(m_gpr[ra] + simm15), 8); } void score7_cpu_device::op_sw() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); write_dword(m_gpr[ra] + simm15, m_gpr[rd]); } @@ -1085,7 +1082,7 @@ void score7_cpu_device::op_sh() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); write_word(m_gpr[ra] + simm15, m_gpr[rd] & 0xffff); } @@ -1094,7 +1091,7 @@ void score7_cpu_device::op_lbu() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); m_gpr[rd] = read_byte(m_gpr[ra] + simm15); } @@ -1103,7 +1100,7 @@ void score7_cpu_device::op_sb() { uint8_t rd = GET_LS_RD(m_op); uint8_t ra = GET_LS_RA(m_op); - int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15); + int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15); write_byte(m_gpr[ra] + simm15, m_gpr[rd] & 0xff); } @@ -1158,7 +1155,7 @@ void score7_cpu_device::op_rform1() m_gpr[rd] = m_gpr[rd] >> (m_gpr[ra] & 0x1f); break; case 0x0b: // sra! - m_gpr[rd] = sign_extend(m_gpr[rd] >> (m_gpr[ra] & 0x1f), 32 - (m_gpr[ra] & 0x1f)); + m_gpr[rd] = util::sext(m_gpr[rd] >> (m_gpr[ra] & 0x1f), 32 - (m_gpr[ra] & 0x1f)); break; case 0x0c: // brl! if (check_condition_branch(rd)) @@ -1197,11 +1194,12 @@ void score7_cpu_device::op_rform2() m_gpr[rd] = r; break; case 0x02: // neg! - m_gpr[rd] = 0 - m_gpr[ra]; - CHECK_Z(m_gpr[rd]); - CHECK_N(m_gpr[rd]); - CHECK_V_SUB(0, m_gpr[ra], m_gpr[rd]); + r = 0 - m_gpr[ra]; + CHECK_Z(r); + CHECK_N(r); + CHECK_V_SUB(0, m_gpr[ra], r); CHECK_C_SUB(0, m_gpr[ra]); + m_gpr[rd] = r; break; case 0x03: // cmp! r = m_gpr[rd] - m_gpr[ra]; @@ -1234,7 +1232,7 @@ void score7_cpu_device::op_rform2() m_gpr[rd] = read_dword(m_gpr[ra]); break; case 0x09: // lh! - m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16); + m_gpr[rd] = util::sext(read_word(m_gpr[ra]), 16); break; case 0x0a: // pop! m_gpr[GET_P_RDG(m_op)] = read_dword(m_gpr[GET_P_RAG(m_op)]); @@ -1270,7 +1268,7 @@ void score7_cpu_device::op_jform() void score7_cpu_device::op_branch16() { if(check_condition_branch(GET_BX_EC(m_op))) - m_pc = m_ppc + (sign_extend(GET_BX_DISP8(m_op), 8) << 1); + m_pc = m_ppc + (util::sext(GET_BX_DISP8(m_op), 8) << 1); } void score7_cpu_device::op_ldiu() @@ -1291,9 +1289,12 @@ void score7_cpu_device::op_iform1a() else m_gpr[rd] += 1 << (imm5 & 0xf); - // condition flags are invalid after this instruction + // according to the datasheet, the flags are undefined after this instruction, but xmen expects the Z flag to be valid. + CHECK_Z(m_gpr[rd]); + CHECK_N(m_gpr[rd]); break; case 0x01: // slli! + SET_C(BIT(m_gpr[rd], 32 - imm5)); m_gpr[rd] <<= imm5; CHECK_Z(m_gpr[rd]); CHECK_N(m_gpr[rd]); @@ -1302,6 +1303,7 @@ void score7_cpu_device::op_iform1a() unemulated_op("sdbbp!"); break; case 0x03: // srli! + SET_C(BIT(m_gpr[rd], imm5 - 1)); m_gpr[rd] >>= imm5; CHECK_Z(m_gpr[rd]); CHECK_N(m_gpr[rd]); @@ -1341,7 +1343,7 @@ void score7_cpu_device::op_iform1b() m_gpr[rd] = read_dword(REG_BP + (imm5<<2)); break; case 0x01: // lhp! - m_gpr[rd] = sign_extend(read_word(REG_BP + (imm5<<1)), 16); + m_gpr[rd] = util::sext(read_word(REG_BP + (imm5<<1)), 16); break; case 0x03: // lbup! m_gpr[rd] = read_byte(REG_BP + imm5); |