diff options
author | 2015-09-13 08:41:44 +0200 | |
---|---|---|
committer | 2015-09-13 08:41:44 +0200 | |
commit | f88cefad27a1737c76e09d99c9fb43e173506081 (patch) | |
tree | 2d8167d03579c46e226471747eb4407bd00ed6fa /src/devices/cpu/am29000/am29ops.h | |
parent | e92ac9e0fa8e99869894bea00589bbb526be30aa (diff) |
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/devices/cpu/am29000/am29ops.h')
-rw-r--r-- | src/devices/cpu/am29000/am29ops.h | 1716 |
1 files changed, 1716 insertions, 0 deletions
diff --git a/src/devices/cpu/am29000/am29ops.h b/src/devices/cpu/am29000/am29ops.h new file mode 100644 index 00000000000..bd3602391e6 --- /dev/null +++ b/src/devices/cpu/am29000/am29ops.h @@ -0,0 +1,1716 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + am29ops.h + Am29000 instructions + +***************************************************************************/ + +/*************************************************************************** + DEFINES +***************************************************************************/ + +#define IFLAG_ILLEGAL (1 << 0) +#define IFLAG_SUPERVISOR_ONLY (1 << 1) +#define IFLAG_RA_PRESENT (1 << 2) +#define IFLAG_RB_PRESENT (1 << 3) +#define IFLAG_RC_PRESENT (1 << 4) + +#define IFLAG_SPR_ACCESS (1 << 6) +#define IFLAG_MEMORY_ACCESS (1 << 8) +#define IFLAG_CONTROL (1 << 9) + + +#define GET_RA_VAL (m_r[RA]) +#define GET_RB_VAL (m_r[RB]) + +#define RA (get_abs_reg(m_exec_ir >> 8, m_ipa)) +#define RB (get_abs_reg(m_exec_ir >> 0, m_ipb)) +#define RC (get_abs_reg(m_exec_ir >> 16, m_ipc)) + +#define INST_SA ((m_exec_ir >> 8) & 0xff) +#define INST_VN ((m_exec_ir >> 16) & 0xff) +#define INST_M_BIT (m_exec_ir & (1 << 24)) +#define INST_CE_BIT (m_exec_ir & (1 << 23)) +#define INST_AS_BIT (m_exec_ir & (1 << 22)) +#define INST_PA_BIT (m_exec_ir & (1 << 21)) +#define INST_SB_BIT (m_exec_ir & (1 << 20)) +#define INST_UA_BIT (m_exec_ir & (1 << 19)) +#define INST_OPT_MASK (7) +#define INST_OPT_SHIFT (16) +#define INST_OPT_FIELD (((m_exec_ir) >> INST_OPT_SHIFT) & INST_OPT_MASK) +#define INST_CNTL_MASK (0x7f) +#define INST_CNTL_SHIFT (16) + +#define I8 (m_exec_ir & 0xff) +#define I16 (((m_exec_ir >> 8) & 0xff00) | (m_exec_ir & 0xff)) +#define I16_ZEX ((UINT32)(I16)) +#define I16_SEX ((INT32)(INT16)I16) +#define I16_OEX (0xffff0000 | I16) + +#define JMP_ZEX (I16 << 2) +#define JMP_SEX ((INT32)(INT16)(((m_exec_ir >> 8) & 0xff00) | (m_exec_ir & 0xff)) << 2) + +#define BOOLEAN_MASK (1 << 31) +#define BOOLEAN_TRUE (1 << 31) +#define BOOLEAN_FALSE (0) + +#define UNHANDLED_OP fatalerror("Am29000: Unhandled inst %s at %x\n", __FUNCTION__, m_exec_pc); + + +/*************************************************************************** + ALU FLAG CALCULATION +***************************************************************************/ + +#define SET_ALU_Z(r) m_alu &= ~ALU_Z; \ + m_alu |= (r == 0) << ALU_Z_SHIFT; + +#define SET_ALU_N(r) m_alu &= ~ALU_N; \ + m_alu |= ((UINT32)r & 0x80000000) >> (31 - ALU_N_SHIFT); + +#define CALC_C_ADD(r, a) ((UINT32)(r) < (UINT32)(a)) + +#define SET_ALU_C_ADD(r, a) m_alu &= ~ALU_C; \ + m_alu |= CALC_C_ADD(r, a) << ALU_C_SHIFT; + +#define CALC_C_SUB(a, b) (!((UINT32)(a) < (UINT32)(b))) + +#define SET_ALU_C_SUB(a, b) m_alu &= ~ALU_C; \ + m_alu |= CALC_C_SUB(a, b) << ALU_C_SHIFT; + +#define SET_ALU_V_ADD(r, a, b) m_alu &= ~ALU_V; \ + m_alu |= (((INT32)(~((a) ^ (b)) & ((a) ^ (r))) < 0)) << ALU_V_SHIFT; + +#define SET_ALU_V_SUB(r, a, b) m_alu &= ~ALU_V; \ + m_alu |= ((INT32)(((a) ^ (b)) & ((a) ^ (r))) < 0) << ALU_V_SHIFT; + +#define GET_CARRY ((m_alu >> ALU_C_SHIFT) & 1) + + + +UINT32 am29000_cpu_device::read_spr(UINT32 idx) +{ + UINT32 val = 0; + + switch (idx) + { + case SPR_VAB: val = m_vab; break; + case SPR_OPS: val = m_ops; break; + case SPR_CPS: val = m_cps; break; + case SPR_CFG: val = m_cfg; break; + case SPR_CHA: val = m_cha; break; + case SPR_CHD: val = m_chd; break; + case SPR_CHC: val = m_chc; break; + case SPR_RBP: val = m_rbp; break; + case SPR_TMC: val = m_tmc; break; + case SPR_TMR: val = m_tmr; break; + case SPR_PC0: val = m_pc0; break; + case SPR_PC1: val = m_pc1; break; + case SPR_PC2: val = m_pc2; break; + case SPR_MMU: val = m_mmu; break; + case SPR_LRU: val = m_lru; break; + case SPR_IPC: val = m_ipc; break; + case SPR_IPA: val = m_ipa; break; + case SPR_IPB: val = m_ipb; break; + case SPR_Q: val = m_q; break; + case SPR_ALU: val = m_alu; break; + case SPR_BP: val = GET_ALU_BP; break; + case SPR_FC: val = GET_ALU_FC; break; + case SPR_CR: val = GET_CHC_CR; break; + case SPR_FPE: val = m_fpe; break; + case SPR_INTE: val = m_inte; break; + case SPR_FPS: val = m_fps; break; + default: + logerror("Unknown SPR read (%d)\n", idx); + } + + return val; +} + + +void am29000_cpu_device::write_spr(UINT32 idx, UINT32 val) +{ + switch (idx) + { + case SPR_VAB: m_vab = val & (VAB_MASK << VAB_SHIFT); + break; + case SPR_OPS: m_ops = val & (CPS_CA | CPS_IP | CPS_TE | CPS_TP | CPS_TU | CPS_FZ | CPS_LK | CPS_RE | + CPS_WM | CPS_PD | CPS_PI | CPS_SM | (CPS_IM_MASK << CPS_IM_SHIFT) | CPS_DI | CPS_DA); + break; + case SPR_CPS: m_cps = val & (CPS_CA | CPS_IP | CPS_TE | CPS_TP | CPS_TU | CPS_FZ | CPS_LK | CPS_RE | + CPS_WM | CPS_PD | CPS_PI | CPS_SM | (CPS_IM_MASK << CPS_IM_SHIFT) | CPS_DI | CPS_DA); + break; + case SPR_CFG: m_cfg = val & (CFG_DW | CFG_VF | CFG_RV | CFG_BO | CFG_CP | CFG_CD); + m_cfg |= PROCESSOR_REL_FIELD << CFG_PRL_SHIFT; + break; + case SPR_CHA: m_cha = val; + break; + case SPR_CHD: m_chd = val; + break; + case SPR_CHC: m_chc = val; + break; + case SPR_RBP: m_rbp = val & RBP_MASK; + break; + case SPR_TMC: m_tmc = val & TCV_MASK; + break; + case SPR_TMR: m_tmr = val & (TMR_OV | TMR_IN | TMR_IE | TMR_TRV_MASK); + break; + case SPR_PC0: m_pc0 = val & PC_MASK; + break; + case SPR_PC1: m_pc1 = val & PC_MASK; + break; + case SPR_PC2: m_pc2 = val & PC_MASK; + break; + case SPR_MMU: m_mmu = val & ((MMU_PS_MASK << MMU_PS_SHIFT) | MMU_PID_MASK); + break; + case SPR_LRU: m_lru = val & (LRU_MASK << LRU_SHIFT); + break; + case SPR_IPC: m_ipc = val;// & IPX_MASK; + break; + case SPR_IPA: m_ipa = val;// & IPX_MASK; + break; + case SPR_IPB: m_ipb = val;// & IPX_MASK; + break; + case SPR_Q: m_q = val; + break; + case SPR_ALU: m_alu = val & (ALU_DF | ALU_V | ALU_N | ALU_Z | ALU_C | (ALU_BP_MASK << ALU_BP_SHIFT) | (ALU_FC_MASK << ALU_FC_SHIFT)); + break; + case SPR_BP: m_alu &= ~(ALU_BP_MASK << ALU_BP_SHIFT); + m_alu |= (val & ALU_BP_MASK) << ALU_BP_SHIFT; + break; + case SPR_FC: m_alu &= ~(ALU_FC_MASK << ALU_FC_SHIFT); + m_alu |= (val & ALU_FC_MASK) << ALU_FC_SHIFT; + break; + case SPR_CR: m_chc &= ~(CHC_CR_MASK << CHC_CR_SHIFT); + m_chc |= (val & CHC_CR_MASK) << CHC_CR_SHIFT; + break; +// case SPR_FPE: +// case SPR_INTE: +// case SPR_FPS: + default: logerror("Unhandled SPR write (%d)\n", idx); + } +} + + +/*************************************************************************** + INSTRUCTIONS +***************************************************************************/ + +/*************************************************************************** + INTEGER ARITHMETIC +***************************************************************************/ + +void am29000_cpu_device::ADD() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a + b; + + if (!FREEZE_MODE) + { + SET_ALU_V_ADD(r, a, b); + SET_ALU_Z(r); + SET_ALU_N(r); + SET_ALU_C_ADD(r, a); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::ADDS() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::ADDU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::ADDC() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::ADDCS() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a + b + GET_CARRY; + + if (!FREEZE_MODE) + { + UINT32 carry = GET_CARRY; + UINT32 tmp = a + b; + + SET_ALU_V_ADD(r, a, b); + SET_ALU_Z(r); + SET_ALU_N(r); + + carry = CALC_C_ADD(tmp, a) || CALC_C_ADD(tmp + carry, carry); + m_alu &= ~ALU_C; + m_alu |= carry << ALU_C_SHIFT; + } + + // TODO: Trap on signed overflow + m_r[RC] = r; +} + +void am29000_cpu_device::ADDCU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUB() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r = a - b; + + if (!FREEZE_MODE) + { + SET_ALU_V_SUB(r, a, b); + SET_ALU_Z(r); + SET_ALU_N(r); + SET_ALU_C_SUB(a, b); + } + + // TODO: Trap on unsigned overflow + m_r[RC] = r; +} + +void am29000_cpu_device::SUBS() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r = a - b; + + if (!FREEZE_MODE) + { + SET_ALU_V_SUB(r, a, b); + SET_ALU_Z(r); + SET_ALU_N(r); + SET_ALU_C_SUB(a, b); + } + + if ((INT32)(((a) ^ (b)) & ((a) ^ (r))) < 0) + SIGNAL_EXCEPTION(EXCEPTION_OUT_OF_RANGE); + + m_r[RC] = r; +} + +void am29000_cpu_device::SUBU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBC() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBCS() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBCU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBR() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r = b - a; + + if (!FREEZE_MODE) + { + SET_ALU_V_SUB(r, a, b); + SET_ALU_Z(r); + SET_ALU_N(r); + SET_ALU_C_SUB(a, b); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::SUBRS() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBRU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBRC() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r = b - a - 1 + GET_CARRY; + + if (!FREEZE_MODE) + { + SET_ALU_V_SUB(r, a, b); + SET_ALU_Z(r); + SET_ALU_N(r); + SET_ALU_C_SUB(a, b); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::SUBRCS() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SUBRCU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::MULTIPLU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::MULTIPLY() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::MUL() +{ + /* TODO: Zero/Neg flags ? */ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r; + UINT64 v; + UINT32 sign; + + if (m_q & 1) + { + r = a + b; + sign = (r >> 31) ^ (((INT32)(~((a) ^ (b)) & ((a) ^ (r))) < 0)); + } + else + { + r = b; + sign = b >> 31; + } + + v = ((((UINT64)r << 32) | m_q) >> 1) | ((UINT64)sign << 63); + m_q = v & 0xffffffff; + + m_r[RC] = v >> 32; +} + +void am29000_cpu_device::MULL() +{ + /* TODO: Zero/Neg flags ? */ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r; + UINT64 v; + UINT32 sign; + + if (m_q & 1) + { + r = b - a; + sign = (r >> 31) ^ ((INT32)(((a) ^ (b)) & ((a) ^ (r))) < 0); + } + else + { + r = b; + sign = b >> 31; + } + + v = ((((UINT64)r << 32) | m_q) >> 1) | ((UINT64)sign << 63); + m_q = v & 0xffffffff; + + m_r[RC] = v >> 32; +} + +void am29000_cpu_device::MULU() +{ + /* TODO: Zero/Neg flags ? */ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r; + UINT64 v; + UINT32 c; + + if (m_q & 1) + { + r = a + b; + c = (UINT32)(r) < (UINT32)(a); + } + else + { + r = b; + c = 0; + } + + v = ((((UINT64)r << 32) | m_q) >> 1) | ((UINT64)c << 63); + m_q = v & 0xffffffff; + + m_r[RC] = v >> 32; +} + +void am29000_cpu_device::DIVIDE() +{ + m_ipa = RA << IPX_SHIFT; + m_ipb = RB << IPX_SHIFT; + m_ipc = RC << IPX_SHIFT; + + SIGNAL_EXCEPTION(EXCEPTION_DIVIDE); +} + +void am29000_cpu_device::DIVIDU() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::DIV0() +{ + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT64 v; + + if (!FREEZE_MODE) + { + m_alu |= ALU_DF; + SET_ALU_N(b); + } + + v = (((UINT64)b << 32) | m_q) << 1; + + m_q = v & 0xffffffff; + + m_r[RC] = v >> 32; +} + +void am29000_cpu_device::DIV() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 c; + UINT32 r; + UINT64 r64; + UINT32 df; + + if (m_alu & ALU_DF) + { + r = a - b; + c = !((UINT32)(a) < (UINT32)(b)); + } + else + { + r = a + b; + c = (UINT32)(r) < (UINT32)(a); + } + + + df = (~(c ^ (m_alu >> ALU_DF_SHIFT) ^ (m_alu >> ALU_N_SHIFT)) & 1); + + if (!FREEZE_MODE) + { + m_alu &= ~ALU_DF; + m_alu |= df << ALU_DF_SHIFT; + SET_ALU_N(r); + } + + r64 = ((((UINT64)r << 32) | m_q) << 1) | df; + m_q = r64 & 0xffffffff; + + m_r[RC] = r64 >> 32; +} + +void am29000_cpu_device::DIVL() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 c; + UINT32 r; + UINT32 df; + + if (m_alu & ALU_DF) + { + r = a - b; + c = !((UINT32)(a) < (UINT32)(b)); + } + else + { + r = a + b; + c = (UINT32)(r) < (UINT32)(a); + } + + df = (~(c ^ (m_alu >> ALU_DF_SHIFT) ^ (m_alu >> ALU_N_SHIFT)) & 1); + + if (!FREEZE_MODE) + { + m_alu &= ~ALU_DF; + m_alu |= df << ALU_DF_SHIFT; + SET_ALU_N(r); + } + + m_q = (m_q << 1) | df; + m_r[RC] = r; +} + +void am29000_cpu_device::DIVREM() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + + if (m_alu & ALU_DF) + m_r[RC] = a; + else + m_r[RC] = a + b; +} + + +/*************************************************************************** + COMPARE +***************************************************************************/ + +void am29000_cpu_device::CPEQ() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a == b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPNEQ() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a != b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPLT() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (INT32)a < (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPLTU() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (UINT32)a < (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPLE() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (INT32)a <= (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPLEU() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (UINT32)a <= (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPGT() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (INT32)a > (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPGTU() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (UINT32)a > (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPGE() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (INT32)a >= (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPGEU() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = (UINT32)a >= (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::CPBYTE() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8 : GET_RB_VAL; + UINT32 r = + ((a & 0xff000000) == (b & 0xff000000)) || + ((a & 0x00ff0000) == (b & 0x00ff0000)) || + ((a & 0x0000ff00) == (b & 0x0000ff00)) || + ((a & 0x000000ff) == (b & 0x000000ff)) + ? BOOLEAN_TRUE : BOOLEAN_FALSE; + + m_r[RC] = r; +} + +void am29000_cpu_device::ASEQ() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!(GET_RA_VAL == GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASNEQ() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!(GET_RA_VAL != GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASLT() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((INT32)GET_RA_VAL < (INT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASLTU() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((UINT32)GET_RA_VAL < (UINT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASLE() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((INT32)GET_RA_VAL <= (INT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASLEU() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((UINT32)GET_RA_VAL <= (UINT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASGT() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((INT32)GET_RA_VAL > (INT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASGTU() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((UINT32)GET_RA_VAL > (UINT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASGE() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((INT32)GET_RA_VAL >= (INT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + +void am29000_cpu_device::ASGEU() +{ + if (USER_MODE && INST_VN < 64) + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + else if (!((UINT32)GET_RA_VAL >= (UINT32)GET_RB_VAL)) + SIGNAL_EXCEPTION(INST_VN); +} + + +/*************************************************************************** + LOGICAL +***************************************************************************/ + +void am29000_cpu_device::AND() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a & b; + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::ANDN() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a & ~b; + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::NAND() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = ~(a & b); + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::OR() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a | b; + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::NOR() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = ~(a | b); + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::XOR() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = a ^ b; + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + +void am29000_cpu_device::XNOR() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r = ~(a ^ b); + + if (!FREEZE_MODE) + { + SET_ALU_Z(r); + SET_ALU_N(r); + } + + m_r[RC] = r; +} + + +/*************************************************************************** + SHIFT +***************************************************************************/ + +void am29000_cpu_device::SLL() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL) & 0x1f; + UINT32 r = a << b; + + m_r[RC] = r; +} + +void am29000_cpu_device::SRL() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL) & 0x1f; + UINT32 r = a >> b; + + m_r[RC] = r; +} + +void am29000_cpu_device::SRA() +{ + INT32 a = GET_RA_VAL; + UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL) & 0x1f; + UINT32 r = a >> b; + + m_r[RC] = r; +} + +void am29000_cpu_device::EXTRACT() +{ + INT32 a = GET_RA_VAL; + UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL); + UINT64 r; + + r = (((UINT64)a << 32) | b) << GET_ALU_FC; + + m_r[RC] = r >> 32; +} + + +/*************************************************************************** + DATA MOVEMENT +***************************************************************************/ + +void am29000_cpu_device::LOAD() +{ + UINT32 addr = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r; + + if (INST_UA_BIT) + fatalerror("Am29000: UA bit set on LOAD\n"); + + if (INST_CE_BIT) + { + logerror("Am29000: Attempting a co-processor LOAD!\n"); + r = 0; + } + else + { + if (!INST_PA_BIT && !(m_cps & CPS_PD)) + { + fatalerror("Am29000: Address translation on LOAD\n"); + } + else + { + if (USER_MODE) + { + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + return; + } + + r = m_data->read_dword(addr); + } + } + +// if (opt & 2) +// logerror("Am29000: Half word LOAD\n"); + + if (!FREEZE_MODE) + { + m_chc = ((m_exec_ir << 8) & 0xff) | + CHC_LS | + RA << CHC_TR_SHIFT | + CHC_CV; + + m_cha = addr; + m_chd = r; + + if (!(m_cfg & CFG_DW) && (m_exec_ir & INST_SB_BIT)) + SET_ALU_BP(addr & 3); + } + + m_r[RA] = r; + + if (m_cfg & CFG_DW) + logerror("DW ON A STORE"); +} + +void am29000_cpu_device::LOADL() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::LOADSET() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::LOADM() +{ + UINT32 addr = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r; + + if (INST_UA_BIT) + fatalerror("Am29000: UA bit set on LOAD\n"); + + if (INST_CE_BIT) + { + logerror("Am29000: Attempting a co-processor LOAD!\n"); + r = 0; + } + else + { + if (!INST_PA_BIT && !(m_cps & CPS_PD)) + { + fatalerror("Am29000: Address translation on LOAD\n"); + } + else + { + if (USER_MODE) + { + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + return; + } + + r = m_data->read_dword(addr); + } + } + + if (!FREEZE_MODE) + { + // TODO + m_chc &= (CHC_CR_MASK << CHC_CR_SHIFT); + m_chc |= ((m_exec_ir << 8) & 0xff) | + RA << CHC_TR_SHIFT | + CHC_CV; + + m_cha = addr; + m_chd = r; // ????? + + if (!(m_cfg & CFG_DW) && (m_exec_ir & INST_SB_BIT)) + SET_ALU_BP(addr & 3); + } + + r = RA; + + { + int cnt; + for (cnt = 0; cnt <= GET_CHC_CR; ++cnt) + { + m_r[r] = m_data->read_dword(addr); + +// SET_CHC_CR(cnt - 1); + addr += 4; + + if (++r == 256) + r = 128; + } + } +} + +void am29000_cpu_device::STORE() +{ + UINT32 addr = INST_M_BIT ? I8: GET_RB_VAL; +// UINT32 r; + + if (INST_UA_BIT) + fatalerror("Am29000: UA bit set on LOAD\n"); + + if (INST_CE_BIT) + { + logerror("Am29000: Attempting a co-processor LOAD!\n"); +// r = 0; + } + else + { + if (!INST_PA_BIT && !(m_cps & CPS_PD)) + { + fatalerror("Am29000: Address translation on LOAD\n"); + } + else + { + if (USER_MODE) + { + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + return; + } + + } + } + + m_data->write_dword(addr, m_r[RA]); + + if (!FREEZE_MODE) + { + m_chc = ((m_exec_ir << 8) & 0xff) | + RA << CHC_TR_SHIFT | + CHC_CV; + + m_cha = addr; + + if (!(m_cfg & CFG_DW) && (m_exec_ir & INST_SB_BIT)) + SET_ALU_BP(addr & 3); + } + + if (m_cfg & CFG_DW) + logerror("DW ON A STORE"); +} + +void am29000_cpu_device::STOREL() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::STOREM() +{ + UINT32 addr = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 r; + + if (INST_UA_BIT) + fatalerror("Am29000: UA bit set on LOAD\n"); + + if (INST_CE_BIT) + { + logerror("Am29000: Attempting a co-processor LOAD!\n"); + r = 0; + } + else + { + if (!INST_PA_BIT && !(m_cps & CPS_PD)) + { + fatalerror("Am29000: Address translation on LOAD\n"); + } + else + { + if (USER_MODE) + { + SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION); + return; + } + + } + } + + if (!FREEZE_MODE) + { + // TODO + m_chc &= (CHC_CR_MASK << CHC_CR_SHIFT); + m_chc |= ((m_exec_ir << 8) & 0xff) | + RA << CHC_TR_SHIFT | + CHC_CV; + + m_cha = addr; + + if (!(m_cfg & CFG_DW) && (m_exec_ir & INST_SB_BIT)) + SET_ALU_BP(addr & 3); + } + + r = RA; + + { + int cnt; + for (cnt = 0; cnt <= GET_CHC_CR; ++cnt) + { + m_data->write_dword(addr, m_r[r]); + +// SET_CHC_CR(cnt - 1); + addr += 4; + + if (++r == 256) + r = 128; + } + } +} + +void am29000_cpu_device::EXBYTE() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 bp = GET_ALU_BP; + UINT8 srcbyte; + UINT32 r; + + if (m_cfg & CFG_BO) + srcbyte = a >> 8 * bp; + else + srcbyte = a >> (8 * (3 - bp)); + + r = (b & 0xffffff00) | srcbyte; + + m_r[RC] = r; +} + +void am29000_cpu_device::EXHW() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 wp = ((m_alu >> ALU_BP_SHIFT) & ALU_BP_MASK) >> 1; + UINT16 srcword; + UINT32 r; + + if (m_cfg & CFG_BO) + srcword = a >> 16 * wp; + else + srcword = a >> (16 * (1 - wp)); + + r = (b & 0xffff0000) | srcword; + + m_r[RC] = r; +} + +void am29000_cpu_device::EXHWS() +{ + UINT32 a = GET_RA_VAL; + UINT32 wp = ((m_alu >> ALU_BP_SHIFT) & ALU_BP_MASK) >> 1; + UINT16 srcword; + UINT32 r; + + if (m_cfg & CFG_BO) + srcword = a >> 16 * wp; + else + srcword = a >> (16 * (1 - wp)); + + r = (INT32)(INT16)srcword; + + m_r[RC] = r; +} + +void am29000_cpu_device::INBYTE() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 bp = GET_ALU_BP; + UINT8 shift = (m_cfg & CFG_BO) ? 8 * bp : (8 * (3 - bp)); + UINT32 r; + + r = (a & ~(0xff << shift)) | ((b & 0xff) << shift); + + m_r[RC] = r; +} + +void am29000_cpu_device::INHW() +{ + UINT32 a = GET_RA_VAL; + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + UINT32 wp = ((m_alu >> ALU_BP_SHIFT) & ALU_BP_MASK) >> 1; + UINT32 shift = (m_cfg & CFG_BO) ? 16 * wp : (16 * (1 - wp)); + UINT32 r; + + r = (a & ~(0xffff << shift)) | ((b & 0xffff) << shift); + + m_r[RC] = r; +} + +void am29000_cpu_device::MFSR() +{ + m_r[RC] = read_spr(INST_SA); +} + +void am29000_cpu_device::MFTLB() +{ + m_r[RC] = m_tlb[GET_RA_VAL & 0x7f]; +} + +void am29000_cpu_device::MTSR() +{ + write_spr(INST_SA, GET_RB_VAL); +} + +void am29000_cpu_device::MTSRIM() +{ + write_spr(INST_SA, I16_ZEX); +} + +void am29000_cpu_device::MTTLB() +{ + m_tlb[GET_RA_VAL & 0x7f] = GET_RB_VAL; +} + + +/*************************************************************************** + CONSTANT +***************************************************************************/ + +void am29000_cpu_device::CONST() +{ + m_r[RA] = I16_ZEX; +} + +void am29000_cpu_device::CONSTH() +{ + m_r[RA] = (I16 << 16) | GET_RA_VAL; +} + +void am29000_cpu_device::CONSTN() +{ + m_r[RA] = I16_OEX; +} + + +/*************************************************************************** + BRANCH INSTRUCTIONS +***************************************************************************/ + +void am29000_cpu_device::CALL() +{ + UINT32 ret = m_next_pc; + + if (INST_M_BIT) + m_next_pc = JMP_ZEX; + else + m_next_pc = m_exec_pc + JMP_SEX; + + m_r[RA] = ret; +m_next_pl_flags |= PFLAG_JUMP; +} + +void am29000_cpu_device::CALLI() +{ + UINT32 ret = m_next_pc; + m_next_pc = GET_RB_VAL; + m_r[RA] = ret; + m_next_pl_flags |= PFLAG_JUMP; +} + +void am29000_cpu_device::JMP() +{ + if (INST_M_BIT) + m_next_pc = JMP_ZEX; + else + m_next_pc = m_exec_pc + JMP_SEX; + + m_next_pl_flags |= PFLAG_JUMP; +} + +void am29000_cpu_device::JMPI() +{ + m_next_pc = GET_RB_VAL; + + m_next_pl_flags |= PFLAG_JUMP; +} + +void am29000_cpu_device::JMPT() +{ + if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_TRUE) + { + if (INST_M_BIT) + m_next_pc = JMP_ZEX; + else + m_next_pc = m_exec_pc + JMP_SEX; + + m_next_pl_flags |= PFLAG_JUMP; + } +} + +void am29000_cpu_device::JMPTI() +{ + if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_TRUE) + { + m_next_pc = GET_RB_VAL; + m_next_pl_flags |= PFLAG_JUMP; + } +} + +void am29000_cpu_device::JMPF() +{ + if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_FALSE) + { + if (INST_M_BIT) + m_next_pc = JMP_ZEX; + else + m_next_pc = m_exec_pc + JMP_SEX; + + m_next_pl_flags |= PFLAG_JUMP; + } +} + +void am29000_cpu_device::JMPFI() +{ + if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_FALSE) + { + m_next_pc = GET_RB_VAL; + m_next_pl_flags |= PFLAG_JUMP; + } +} + +void am29000_cpu_device::JMPFDEC() +{ + UINT32 a = GET_RA_VAL; + + if ((a & BOOLEAN_MASK) == BOOLEAN_FALSE) + { + if (INST_M_BIT) + m_next_pc = JMP_ZEX; + else + m_next_pc = m_exec_pc + JMP_SEX; + + m_next_pl_flags |= PFLAG_JUMP; + } + + m_r[RA] = a - 1; +} + + +/*************************************************************************** + MISCELLANEOUS INSTRUCTIONS +***************************************************************************/ + +void am29000_cpu_device::CLZ() +{ + UINT32 b = INST_M_BIT ? I8: GET_RB_VAL; + + m_r[RC] = count_leading_zeros(b); +} + +void am29000_cpu_device::SETIP() +{ + m_ipa = RA << IPX_SHIFT; + m_ipb = RB << IPX_SHIFT; + m_ipc = RC << IPX_SHIFT; +} + +void am29000_cpu_device::EMULATE() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::INV() +{ + /* Nothing to do yet */ +} + +void am29000_cpu_device::IRET() +{ + m_iret_pc = m_pc0; + m_next_pc = m_pc1; + m_cps = m_ops; + m_next_pl_flags = PFLAG_IRET; +} + +void am29000_cpu_device::IRETINV() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::HALT() +{ + UNHANDLED_OP; +} + + +void am29000_cpu_device::ILLEGAL() +{ + fatalerror("Am29000: Executed illegal instruction - this should never happen! %x (%x)\n", m_pc2, m_exec_pc); +} + + + +/*************************************************************************** + UNHANDLED +***************************************************************************/ + +void am29000_cpu_device::CONVERT() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::SQRT() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::CLASS() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::MULTM() +{ + UNHANDLED_OP; +} + +void am29000_cpu_device::MULTMU() +{ + UNHANDLED_OP; +} + + +const am29000_cpu_device::op_info am29000_cpu_device::op_table[256] = +{ + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::CONSTN, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CONSTH, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CONST, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::MTSRIM, 0 }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::LOADL, 0 }, + { &am29000_cpu_device::LOADL, 0 }, + { &am29000_cpu_device::CLZ, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::CLZ, IFLAG_RC_PRESENT }, + { &am29000_cpu_device::EXBYTE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::EXBYTE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::INBYTE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::INBYTE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::STOREL, 0 }, + { &am29000_cpu_device::STOREL, 0 }, + { &am29000_cpu_device::ADDS, 0 }, + { &am29000_cpu_device::ADDS, 0 }, + { &am29000_cpu_device::ADDU, 0 }, + { &am29000_cpu_device::ADDU, 0 }, + { &am29000_cpu_device::ADD, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ADD, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::LOAD, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::LOAD, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ADDCS, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ADDCS, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ADDCU, 0 }, + { &am29000_cpu_device::ADDCU, 0 }, + { &am29000_cpu_device::ADDC, 0 }, + { &am29000_cpu_device::ADDC, 0 }, + { &am29000_cpu_device::STORE, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::STORE, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBS, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBS, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBU, 0 }, + { &am29000_cpu_device::SUBU, 0 }, + { &am29000_cpu_device::SUB, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUB, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::LOADSET, 0 }, + { &am29000_cpu_device::LOADSET, 0 }, + { &am29000_cpu_device::SUBCS, 0 }, + { &am29000_cpu_device::SUBCS, 0 }, + { &am29000_cpu_device::SUBCU, 0 }, + { &am29000_cpu_device::SUBCU, 0 }, + { &am29000_cpu_device::SUBC, 0 }, + { &am29000_cpu_device::SUBC, 0 }, + { &am29000_cpu_device::CPBYTE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPBYTE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBRS, 0 }, + { &am29000_cpu_device::SUBRS, 0 }, + { &am29000_cpu_device::SUBRU, 0 }, + { &am29000_cpu_device::SUBRU, 0 }, + { &am29000_cpu_device::SUBR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::LOADM, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::LOADM, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBRCS, 0 }, + { &am29000_cpu_device::SUBRCS, 0 }, + { &am29000_cpu_device::SUBRCU, 0 }, + { &am29000_cpu_device::SUBRCU, 0 }, + { &am29000_cpu_device::SUBRC, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SUBRC, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::STOREM, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::STOREM, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLT, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLT, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLTU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLTU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLEU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPLEU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGT, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGT, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGTU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGTU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGEU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPGEU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASLT, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASLT, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASLTU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASLTU, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASLE, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASLE, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASLEU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASLEU, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASGT, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASGT, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASGTU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASGTU, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASGE, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASGE, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASGEU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASGEU, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPEQ, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPEQ, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPNEQ, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CPNEQ, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::MUL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::MUL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::MULL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::MULL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::DIV0, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::DIV0, IFLAG_RC_PRESENT }, + { &am29000_cpu_device::DIV, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::DIV, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::DIVL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::DIVL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::DIVREM, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::DIVREM, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASEQ, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASEQ, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ASNEQ, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ASNEQ, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::MULU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::MULU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::INHW, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::INHW, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::EXTRACT, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::EXTRACT, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::EXHW, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::EXHW, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::EXHWS, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::SLL, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SLL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SRL, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SRL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::SRA, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SRA, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::IRET, IFLAG_SUPERVISOR_ONLY }, + { &am29000_cpu_device::HALT, IFLAG_SUPERVISOR_ONLY }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::IRETINV, IFLAG_SUPERVISOR_ONLY }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::AND, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::AND, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::OR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::OR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::XOR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::XOR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::XNOR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::XNOR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::NOR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::NOR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::NAND, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::NAND, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ANDN, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ANDN, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::SETIP, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT | IFLAG_RC_PRESENT }, + { &am29000_cpu_device::INV, IFLAG_SUPERVISOR_ONLY }, + { &am29000_cpu_device::JMP, 0 }, + { &am29000_cpu_device::JMP, 0 }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::JMPF, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::JMPF, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::CALL, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::CALL, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::JMPT, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::JMPT, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::JMPFDEC, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::JMPFDEC, IFLAG_RA_PRESENT }, + { &am29000_cpu_device::MFTLB, IFLAG_SUPERVISOR_ONLY | IFLAG_RC_PRESENT | IFLAG_RA_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::MTTLB, IFLAG_SUPERVISOR_ONLY | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::JMPI, IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::JMPFI, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::MFSR, IFLAG_RC_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::CALLI, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::JMPTI, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::MTSR, IFLAG_RB_PRESENT }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::EMULATE, 0 }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::MULTM, 0 }, + { &am29000_cpu_device::MULTMU, 0 }, + { &am29000_cpu_device::MULTIPLY, 0 }, + { &am29000_cpu_device::DIVIDE, 0 }, + { &am29000_cpu_device::MULTIPLU, 0 }, + { &am29000_cpu_device::DIVIDU, 0 }, + { &am29000_cpu_device::CONVERT, 0 }, + { &am29000_cpu_device::SQRT, 0 }, + { &am29000_cpu_device::CLASS, 0 }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + { &am29000_cpu_device::ILLEGAL, IFLAG_ILLEGAL }, + // FEQ + // DEQ + // TODO! etc +}; |