summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2017-11-16 22:40:44 +0100
committer mooglyguy <therealmogminer@gmail.com>2017-11-16 22:40:56 +0100
commit79b715783ef95646d263a7d3d3daefcdc465a493 (patch)
tree687d4108c7f39a9a6a4adbe82428bdef3aab1cec
parentdc323f06509e113706af8ac38d3f28386934a447 (diff)
e132xs: templated div ops, that's the last of them. nw
-rw-r--r--src/devices/cpu/e132xs/e132xs.cpp16
-rw-r--r--src/devices/cpu/e132xs/e132xs.h10
-rw-r--r--src/devices/cpu/e132xs/e132xsop.hxx303
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<GLOBAL, LOCAL>(); break;
case 0x06: hyperstone_movd<LOCAL, GLOBAL>(); break;
case 0x07: hyperstone_movd<LOCAL, LOCAL>(); 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<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 0x10: hyperstone_xm<GLOBAL, GLOBAL>(); break;
case 0x11: hyperstone_xm<GLOBAL, LOCAL>(); break;
case 0x12: hyperstone_xm<LOCAL, GLOBAL>(); 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 <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_chk();
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> 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 <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_divu();
+ template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_divs();
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_xm();
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mask();
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> 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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
+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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
+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 <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
void hyperstone_device::hyperstone_xm()
{