mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
e132xs: merged divs/u and muls/u using templates, nw
This commit is contained in:
parent
7572b7241d
commit
f86271bade
@ -1641,14 +1641,14 @@ void hyperstone_device::execute_run()
|
|||||||
case 0x05: hyperstone_movd<GLOBAL, LOCAL>(); break;
|
case 0x05: hyperstone_movd<GLOBAL, LOCAL>(); break;
|
||||||
case 0x06: hyperstone_movd<LOCAL, GLOBAL>(); break;
|
case 0x06: hyperstone_movd<LOCAL, GLOBAL>(); break;
|
||||||
case 0x07: hyperstone_movd<LOCAL, LOCAL>(); break;
|
case 0x07: hyperstone_movd<LOCAL, LOCAL>(); break;
|
||||||
case 0x08: hyperstone_divu<GLOBAL, GLOBAL>(); break;
|
case 0x08: hyperstone_divsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break;
|
||||||
case 0x09: hyperstone_divu<GLOBAL, LOCAL>(); break;
|
case 0x09: hyperstone_divsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break;
|
||||||
case 0x0a: hyperstone_divu<LOCAL, GLOBAL>(); break;
|
case 0x0a: hyperstone_divsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break;
|
||||||
case 0x0b: hyperstone_divu<LOCAL, LOCAL>(); break;
|
case 0x0b: hyperstone_divsu<LOCAL, LOCAL, IS_UNSIGNED>(); break;
|
||||||
case 0x0c: hyperstone_divs<GLOBAL, GLOBAL>(); break;
|
case 0x0c: hyperstone_divsu<GLOBAL, GLOBAL, IS_SIGNED>(); break;
|
||||||
case 0x0d: hyperstone_divs<GLOBAL, LOCAL>(); break;
|
case 0x0d: hyperstone_divsu<GLOBAL, LOCAL, IS_SIGNED>(); break;
|
||||||
case 0x0e: hyperstone_divs<LOCAL, GLOBAL>(); break;
|
case 0x0e: hyperstone_divsu<LOCAL, GLOBAL, IS_SIGNED>(); break;
|
||||||
case 0x0f: hyperstone_divs<LOCAL, LOCAL>(); break;
|
case 0x0f: hyperstone_divsu<LOCAL, LOCAL, IS_SIGNED>(); break;
|
||||||
case 0x10: hyperstone_xm<GLOBAL, GLOBAL>(); break;
|
case 0x10: hyperstone_xm<GLOBAL, GLOBAL>(); break;
|
||||||
case 0x11: hyperstone_xm<GLOBAL, LOCAL>(); break;
|
case 0x11: hyperstone_xm<GLOBAL, LOCAL>(); break;
|
||||||
case 0x12: hyperstone_xm<LOCAL, GLOBAL>(); break;
|
case 0x12: hyperstone_xm<LOCAL, GLOBAL>(); break;
|
||||||
@ -1809,14 +1809,14 @@ void hyperstone_device::execute_run()
|
|||||||
case 0xad: hyperstone_reserved(); break;
|
case 0xad: hyperstone_reserved(); break;
|
||||||
case 0xae: hyperstone_reserved(); break;
|
case 0xae: hyperstone_reserved(); break;
|
||||||
case 0xaf: hyperstone_reserved(); break;
|
case 0xaf: hyperstone_reserved(); break;
|
||||||
case 0xb0: hyperstone_mulu<GLOBAL, GLOBAL>(); break;
|
case 0xb0: hyperstone_mulsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break;
|
||||||
case 0xb1: hyperstone_mulu<GLOBAL, LOCAL>(); break;
|
case 0xb1: hyperstone_mulsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break;
|
||||||
case 0xb2: hyperstone_mulu<LOCAL, GLOBAL>(); break;
|
case 0xb2: hyperstone_mulsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break;
|
||||||
case 0xb3: hyperstone_mulu<LOCAL, LOCAL>(); break;
|
case 0xb3: hyperstone_mulsu<LOCAL, LOCAL, IS_UNSIGNED>(); break;
|
||||||
case 0xb4: hyperstone_muls<GLOBAL, GLOBAL>(); break;
|
case 0xb4: hyperstone_mulsu<GLOBAL, GLOBAL, IS_SIGNED>(); break;
|
||||||
case 0xb5: hyperstone_muls<GLOBAL, LOCAL>(); break;
|
case 0xb5: hyperstone_mulsu<GLOBAL, LOCAL, IS_SIGNED>(); break;
|
||||||
case 0xb6: hyperstone_muls<LOCAL, GLOBAL>(); break;
|
case 0xb6: hyperstone_mulsu<LOCAL, GLOBAL, IS_SIGNED>(); break;
|
||||||
case 0xb7: hyperstone_muls<LOCAL, LOCAL>(); break;
|
case 0xb7: hyperstone_mulsu<LOCAL, LOCAL, IS_SIGNED>(); break;
|
||||||
case 0xb8: hyperstone_set<N_LO, GLOBAL>(); break;
|
case 0xb8: hyperstone_set<N_LO, GLOBAL>(); break;
|
||||||
case 0xb9: hyperstone_set<N_HI, GLOBAL>(); break;
|
case 0xb9: hyperstone_set<N_HI, GLOBAL>(); break;
|
||||||
case 0xba: hyperstone_set<N_LO, LOCAL>(); break;
|
case 0xba: hyperstone_set<N_LO, LOCAL>(); break;
|
||||||
|
@ -111,7 +111,13 @@ protected:
|
|||||||
enum shift_type
|
enum shift_type
|
||||||
{
|
{
|
||||||
N_LO = 0,
|
N_LO = 0,
|
||||||
N_HI = 1,
|
N_HI = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum sign_mode
|
||||||
|
{
|
||||||
|
IS_UNSIGNED = 0,
|
||||||
|
IS_SIGNED = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
@ -216,8 +222,7 @@ private:
|
|||||||
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_chk();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_chk();
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_movd();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_movd();
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_divu();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void hyperstone_divsu();
|
||||||
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_xm();
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mask();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mask();
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sum();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sum();
|
||||||
@ -265,8 +270,7 @@ private:
|
|||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx1();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx1();
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx2();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx2();
|
||||||
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mulu();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void hyperstone_mulsu();
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_muls();
|
|
||||||
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mul();
|
template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mul();
|
||||||
|
|
||||||
template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_set();
|
template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_set();
|
||||||
|
@ -119,8 +119,8 @@ void hyperstone_device::hyperstone_movd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED>
|
||||||
void hyperstone_device::hyperstone_divu()
|
void hyperstone_device::hyperstone_divsu()
|
||||||
{
|
{
|
||||||
check_delay_PC();
|
check_delay_PC();
|
||||||
|
|
||||||
@ -137,58 +137,11 @@ void hyperstone_device::hyperstone_divu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
||||||
|
|
||||||
if (sreg == 0)
|
|
||||||
{
|
|
||||||
//Rd//Rdf -> undefined
|
|
||||||
//Z -> undefined
|
|
||||||
//N -> undefined
|
|
||||||
SR |= V_MASK;
|
|
||||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_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 uint32_t dregf = (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code];
|
||||||
const uint64_t dividend = concat_64(dreg, dregf);
|
const uint64_t dividend = concat_64(dreg, dregf);
|
||||||
|
|
||||||
/* TODO: add quotient overflow */
|
if (sreg == 0 || (SIGNED && (dividend & 0x8000000000000000U)))
|
||||||
uint32_t quotient = dividend / sreg;
|
|
||||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = dividend % sreg;
|
|
||||||
(DST_GLOBAL ? m_global_regs : 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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_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 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))
|
|
||||||
{
|
{
|
||||||
//Rd//Rdf -> undefined
|
//Rd//Rdf -> undefined
|
||||||
//Z -> undefined
|
//Z -> undefined
|
||||||
@ -199,10 +152,9 @@ void hyperstone_device::hyperstone_divs()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO: add quotient overflow */
|
/* TODO: add quotient overflow */
|
||||||
const int32_t quotient = dividend / sreg;
|
const uint32_t quotient = SIGNED ? (uint32_t)((int64_t)dividend / (int32_t)sreg) : (dividend / sreg);
|
||||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = dividend % sreg;
|
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = SIGNED ? (uint32_t)((int64_t)dividend % (int32_t)sreg) : (dividend % sreg);
|
||||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = quotient;
|
(DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)quotient;
|
||||||
|
|
||||||
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
||||||
if (quotient == 0)
|
if (quotient == 0)
|
||||||
SR |= Z_MASK;
|
SR |= Z_MASK;
|
||||||
@ -2239,8 +2191,8 @@ void hyperstone_device::hyperstone_shli()
|
|||||||
m_icount -= m_clock_cycles_1;
|
m_icount -= m_clock_cycles_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED>
|
||||||
void hyperstone_device::hyperstone_mulu()
|
void hyperstone_device::hyperstone_mulsu()
|
||||||
{
|
{
|
||||||
check_delay_PC();
|
check_delay_PC();
|
||||||
|
|
||||||
@ -2251,13 +2203,13 @@ void hyperstone_device::hyperstone_mulu()
|
|||||||
|
|
||||||
if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2))
|
if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2))
|
||||||
{
|
{
|
||||||
LOG("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC);
|
LOG("Denoted PC or SR in hyperstone_muls/u instruction. PC = %08X\n", PC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
|
const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
|
||||||
const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
||||||
const uint64_t double_word = (uint64_t)sreg *(uint64_t)dreg;
|
const uint64_t double_word = SIGNED ? (uint64_t)((int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg) : ((uint64_t)sreg *(uint64_t)dreg);
|
||||||
|
|
||||||
const uint32_t high_order = (uint32_t)(double_word >> 32);
|
const uint32_t high_order = (uint32_t)(double_word >> 32);
|
||||||
|
|
||||||
@ -2269,43 +2221,9 @@ void hyperstone_device::hyperstone_mulu()
|
|||||||
SR |= Z_MASK;
|
SR |= Z_MASK;
|
||||||
SR |= SIGN_TO_N(high_order);
|
SR |= SIGN_TO_N(high_order);
|
||||||
|
|
||||||
if(sreg <= 0xffff && dreg <= 0xffff)
|
if(SIGNED == IS_SIGNED && (sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff))
|
||||||
m_icount -= m_clock_cycles_4;
|
m_icount -= m_clock_cycles_4;
|
||||||
else
|
else if(SIGNED == IS_UNSIGNED && sreg <= 0xffff && dreg <= 0xffff)
|
||||||
m_icount -= m_clock_cycles_6;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
|
|
||||||
void hyperstone_device::hyperstone_muls()
|
|
||||||
{
|
|
||||||
check_delay_PC();
|
|
||||||
|
|
||||||
const uint32_t fp = GET_FP;
|
|
||||||
const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
|
||||||
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);
|
|
||||||
|
|
||||||
if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2))
|
|
||||||
{
|
|
||||||
LOG("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32_t dreg = (int32_t)(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
|
|
||||||
const int32_t sreg = (int32_t)(SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code];
|
|
||||||
const int64_t double_word = (int64_t)sreg * (int64_t)dreg;
|
|
||||||
|
|
||||||
const uint32_t high_order = (uint32_t)(double_word >> 32);
|
|
||||||
|
|
||||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = high_order;
|
|
||||||
(DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)double_word;
|
|
||||||
|
|
||||||
SR &= ~(Z_MASK | N_MASK);
|
|
||||||
if (double_word == 0)
|
|
||||||
SR |= Z_MASK;
|
|
||||||
SR |= SIGN_TO_N(high_order);
|
|
||||||
|
|
||||||
if((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff))
|
|
||||||
m_icount -= m_clock_cycles_4;
|
m_icount -= m_clock_cycles_4;
|
||||||
else
|
else
|
||||||
m_icount -= m_clock_cycles_6;
|
m_icount -= m_clock_cycles_6;
|
||||||
|
Loading…
Reference in New Issue
Block a user