From 79b715783ef95646d263a7d3d3daefcdc465a493 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Thu, 16 Nov 2017 22:40:44 +0100 Subject: e132xs: templated div ops, that's the last of them. nw --- src/devices/cpu/e132xs/e132xs.cpp | 16 +- src/devices/cpu/e132xs/e132xs.h | 10 +- src/devices/cpu/e132xs/e132xsop.hxx | 303 +++++------------------------------- 3 files changed, 53 insertions(+), 276 deletions(-) diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index 227ce35de43..8a8e18fd5f3 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -1639,14 +1639,14 @@ void hyperstone_device::execute_run() case 0x05: hyperstone_movd(); break; case 0x06: hyperstone_movd(); break; case 0x07: hyperstone_movd(); break; - case 0x08: hyperstone_divu_global_global(); break; - case 0x09: hyperstone_divu_global_local(); break; - case 0x0a: hyperstone_divu_local_global(); break; - case 0x0b: hyperstone_divu_local_local(); break; - case 0x0c: hyperstone_divs_global_global(); break; - case 0x0d: hyperstone_divs_global_local(); break; - case 0x0e: hyperstone_divs_local_global(); break; - case 0x0f: hyperstone_divs_local_local(); break; + case 0x08: hyperstone_divu(); break; + case 0x09: hyperstone_divu(); break; + case 0x0a: hyperstone_divu(); break; + case 0x0b: hyperstone_divu(); break; + case 0x0c: hyperstone_divs(); break; + case 0x0d: hyperstone_divs(); break; + case 0x0e: hyperstone_divs(); break; + case 0x0f: hyperstone_divs(); break; case 0x10: hyperstone_xm(); break; case 0x11: hyperstone_xm(); break; case 0x12: hyperstone_xm(); break; diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index a26aeb34918..44730b4f163 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -210,14 +210,8 @@ private: template void hyperstone_chk(); template void hyperstone_movd(); - void hyperstone_divu_global_global(); - void hyperstone_divu_global_local(); - void hyperstone_divu_local_global(); - void hyperstone_divu_local_local(); - void hyperstone_divs_global_global(); - void hyperstone_divs_global_local(); - void hyperstone_divs_local_global(); - void hyperstone_divs_local_local(); + template void hyperstone_divu(); + template void hyperstone_divs(); template void hyperstone_xm(); template void hyperstone_mask(); template void hyperstone_sum(); diff --git a/src/devices/cpu/e132xs/e132xsop.hxx b/src/devices/cpu/e132xs/e132xsop.hxx index 0fa3d3f9d7f..f25eecca9ec 100644 --- a/src/devices/cpu/e132xs/e132xsop.hxx +++ b/src/devices/cpu/e132xs/e132xsop.hxx @@ -119,100 +119,24 @@ void hyperstone_device::hyperstone_movd() } } -void hyperstone_device::hyperstone_divu_global_global() +template +void hyperstone_device::hyperstone_divu() { check_delay_PC(); - const uint32_t dst_code = DST_CODE; - const uint32_t dstf_code = dst_code + 1; - - const uint32_t src_code = SRC_CODE; - const uint32_t sreg = m_global_regs[src_code]; + const uint32_t fp = GET_FP; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); - if (src_code == dst_code || src_code == dstf_code || src_code < 2) + if ((SRC_GLOBAL == DST_GLOBAL && (src_code == dst_code || src_code == dstf_code)) || (SRC_GLOBAL && src_code < 2)) { LOG("Denoted the same register code or PC/SR as source in hyperstone_divu instruction. PC = %08X\n", PC); m_icount -= 36 << m_clck_scale; return; } - if (src_code == 0) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - SR |= V_MASK; - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - const uint64_t dividend = concat_64(m_global_regs[dst_code], m_global_regs[dstf_code]); - - /* TODO: add quotient overflow */ - uint32_t quotient = dividend / sreg; - set_global_register(dst_code, dividend % sreg); - set_global_register(dst_code + 1, quotient); - - SR &= ~(V_MASK | Z_MASK | N_MASK); - if (quotient == 0) - SR |= Z_MASK; - SR |= SIGN_TO_N(quotient); - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divu_global_local() -{ - check_delay_PC(); - - const uint32_t dst_code = DST_CODE; - const uint32_t dstf_code = dst_code + 1; - const uint32_t sreg = m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; - - if (sreg == 0) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - SR |= V_MASK; - execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); - } - else - { - const uint64_t dividend = concat_64(m_global_regs[dst_code], m_global_regs[dstf_code]); - - /* TODO: add quotient overflow */ - uint32_t quotient = dividend / sreg; - set_global_register(dst_code, dividend % sreg); - set_global_register(dstf_code, quotient); - - SR &= ~(V_MASK | Z_MASK | N_MASK); - if (quotient == 0) - SR |= Z_MASK; - SR |= SIGN_TO_N(quotient); - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divu_local_global() -{ - check_delay_PC(); - - const uint32_t src_code = SRC_CODE; - const uint32_t sreg = m_global_regs[src_code]; - - const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; - const uint32_t dstf_code = (dst_code + 1) & 0x3f; - - if (src_code < 2) - { - LOG("Denoted the same register code or PC/SR as source in hyperstone_divu instruction. PC = %08X\n", PC); - m_icount -= 36 << m_clck_scale; - return; - } + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; if (sreg == 0) { @@ -220,16 +144,27 @@ void hyperstone_device::hyperstone_divu_local_global() //Z -> undefined //N -> undefined SR |= V_MASK; - execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); + execute_exception(addr); } else { - const uint64_t dividend = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t dregf = (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code]; + const uint64_t dividend = concat_64(dreg, dregf); /* TODO: add quotient overflow */ uint32_t quotient = dividend / sreg; - m_local_regs[dst_code] = dividend % sreg; - m_local_regs[dstf_code] = quotient; + if (DST_GLOBAL) + { + set_global_register(dst_code, dividend % sreg); + set_global_register(dst_code + 1, quotient); + } + else + { + m_local_regs[dst_code] = dividend % sreg; + m_local_regs[dstf_code] = quotient; + } SR &= ~(V_MASK | Z_MASK | N_MASK); if (quotient == 0) @@ -240,185 +175,27 @@ void hyperstone_device::hyperstone_divu_local_global() m_icount -= 36 << m_clck_scale; } -void hyperstone_device::hyperstone_divu_local_local() +template +void hyperstone_device::hyperstone_divs() { check_delay_PC(); const uint32_t fp = GET_FP; - const uint32_t src_code = (SRC_CODE + fp) & 0x3f; - const uint32_t d_code = DST_CODE + fp; - const uint32_t dst_code = d_code & 0x3f; - const uint32_t dstf_code = (d_code + 1) & 0x3f; - - if (src_code == dst_code || src_code == dstf_code) - { - m_icount -= 36 << m_clck_scale; - return; - } - - const uint32_t sreg = m_local_regs[src_code]; - const uint64_t dividend = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); - - if (sreg == 0) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - SR |= V_MASK; - execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); - } - else - { - /* TODO: add quotient overflow */ - const uint32_t quotient = dividend / sreg; - m_local_regs[dst_code] = dividend % sreg; - m_local_regs[dstf_code] = quotient; - - SR &= ~(V_MASK | Z_MASK | N_MASK); - if (quotient == 0) - SR |= Z_MASK; - SR |= SIGN_TO_N(quotient); - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divs_global_global() -{ - check_delay_PC(); - - const uint32_t src_code = SRC_CODE; - const uint32_t dst_code = DST_CODE; - const uint32_t dstf_code = dst_code + 1; - const int32_t sreg = (int32_t)m_global_regs[src_code]; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); - if(src_code == dst_code || src_code == dstf_code || src_code < 2) + if ((SRC_GLOBAL == DST_GLOBAL && (src_code == dst_code || src_code == dstf_code)) || (SRC_GLOBAL && src_code < 2)) { LOG("Denoted invalid register code in hyperstone_divs instruction. PC = %08X\n", PC); m_icount -= 36 << m_clck_scale; return; } - const int64_t dividend = (int64_t) concat_64(m_global_regs[dst_code], m_global_regs[dstf_code]); - - if (sreg == 0 || (dividend & 0x8000000000000000U)) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - SR |= V_MASK; - execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); - } - else - { - /* TODO: add quotient overflow */ - const int32_t quotient = dividend / sreg; - set_global_register(dst_code, dividend % sreg); - set_global_register(dst_code + 1, quotient); - - SR &= ~(V_MASK | Z_MASK | N_MASK); - if (quotient == 0) - SR |= Z_MASK; - SR |= SIGN_TO_N(quotient); - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divs_global_local() -{ - check_delay_PC(); - - const uint32_t dst_code = DST_CODE; - const int32_t sreg = (int32_t)m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; - const int64_t dividend = (int64_t) concat_64(m_global_regs[dst_code], m_global_regs[dst_code + 1]); - - if (sreg == 0 || (dividend & 0x8000000000000000U)) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - SR |= V_MASK; - execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); - } - else - { - /* TODO: add quotient overflow */ - const int32_t quotient = dividend / sreg; - set_global_register(dst_code, dividend % sreg); - set_global_register(dst_code + 1, quotient); - - SR &= ~(V_MASK | Z_MASK | N_MASK); - if (quotient == 0) - SR |= Z_MASK; - SR |= SIGN_TO_N(quotient); - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divs_local_global() -{ - check_delay_PC(); - - const uint32_t fp = GET_FP; - const uint32_t dst_code = (DST_CODE + fp) & 0x3f; - const uint32_t dstf_code = (dst_code + 1) & 0x3f; - const uint32_t src_code = SRC_CODE; - const int32_t sreg = (int32_t)m_global_regs[src_code]; - - if (src_code < 2) - { - LOG("Denoted PC or SR as source register in hyperstone_divs instruction. PC = %08X\n", PC); - m_icount -= 36 << m_clck_scale; - return; - } - - const int64_t dividend = (int64_t) concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); - - if (sreg == 0 || (dividend & 0x8000000000000000U)) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - SR |= V_MASK; - execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); - } - else - { - /* TODO: add quotient overflow */ - const int32_t quotient = dividend / sreg; - m_local_regs[dst_code] = (int32_t)(dividend % sreg); - m_local_regs[dstf_code] = quotient; - - SR &= ~(V_MASK | Z_MASK | N_MASK); - - if (quotient == 0) - SR |= Z_MASK; - SR |= SIGN_TO_N(quotient); - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divs_local_local() -{ - check_delay_PC(); - - const uint32_t fp = GET_FP; - const uint32_t src_code = (SRC_CODE + fp) & 0x3f; - const uint32_t d_code = DST_CODE; - const uint32_t dst_code = (d_code + fp) & 0x3f; - const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f; - - if (src_code == dst_code || src_code == dstf_code) - { - m_icount -= 36 << m_clck_scale; - return; - } - - const int32_t sreg = (int32_t)m_local_regs[src_code]; - const int64_t dividend = (int64_t) concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); + const int32_t sreg = (int32_t)(SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t dregf = (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code]; + const int64_t dividend = (int64_t) concat_64(dreg, dregf); if (sreg == 0 || (dividend & 0x8000000000000000U)) { @@ -432,8 +209,16 @@ void hyperstone_device::hyperstone_divs_local_local() { /* TODO: add quotient overflow */ const int32_t quotient = dividend / sreg; - m_local_regs[dst_code] = dividend % sreg; - m_local_regs[dstf_code] = quotient; + if (DST_GLOBAL) + { + set_global_register(dst_code, dividend % sreg); + set_global_register(dst_code + 1, quotient); + } + else + { + m_local_regs[dst_code] = dividend % sreg; + m_local_regs[dstf_code] = quotient; + } SR &= ~(V_MASK | Z_MASK | N_MASK); if (quotient == 0) @@ -444,8 +229,6 @@ void hyperstone_device::hyperstone_divs_local_local() m_icount -= 36 << m_clck_scale; } - - template void hyperstone_device::hyperstone_xm() { -- cgit v1.2.3