mirror of
https://github.com/holub/mame
synced 2025-05-25 23:35:26 +03:00
1726 lines
49 KiB
C
1726 lines
49 KiB
C
/***************************************************************************
|
|
|
|
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 (am29000->r[RA])
|
|
#define GET_RB_VAL (am29000->r[RB])
|
|
|
|
#define RA (get_abs_reg(am29000, am29000->exec_ir >> 8, am29000->ipa))
|
|
#define RB (get_abs_reg(am29000, am29000->exec_ir >> 0, am29000->ipb))
|
|
#define RC (get_abs_reg(am29000, am29000->exec_ir >> 16, am29000->ipc))
|
|
|
|
#define INST_SA ((am29000->exec_ir >> 8) & 0xff)
|
|
#define INST_VN ((am29000->exec_ir >> 16) & 0xff)
|
|
#define INST_M_BIT (am29000->exec_ir & (1 << 24))
|
|
#define INST_CE_BIT (am29000->exec_ir & (1 << 23))
|
|
#define INST_AS_BIT (am29000->exec_ir & (1 << 22))
|
|
#define INST_PA_BIT (am29000->exec_ir & (1 << 21))
|
|
#define INST_SB_BIT (am29000->exec_ir & (1 << 20))
|
|
#define INST_UA_BIT (am29000->exec_ir & (1 << 19))
|
|
#define INST_OPT_MASK (7)
|
|
#define INST_OPT_SHIFT (16)
|
|
#define INST_OPT_FIELD (((am29000->exec_ir) >> INST_OPT_SHIFT) & INST_OPT_MASK)
|
|
#define INST_CNTL_MASK (0x7f)
|
|
#define INST_CNTL_SHIFT (16)
|
|
|
|
#define I8 (am29000->exec_ir & 0xff)
|
|
#define I16 (((am29000->exec_ir >> 8) & 0xff00) | (am29000->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)(((am29000->exec_ir >> 8) & 0xff00) | (am29000->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__, am29000->exec_pc);
|
|
|
|
|
|
/***************************************************************************
|
|
STRUCTS
|
|
***************************************************************************/
|
|
|
|
typedef struct _op_info
|
|
{
|
|
void (*opcode)(am29000_state *);
|
|
UINT32 flags;
|
|
} op_info;
|
|
|
|
|
|
/***************************************************************************
|
|
ALU FLAG CALCULATION
|
|
***************************************************************************/
|
|
|
|
#define SET_ALU_Z(r) am29000->alu &= ~ALU_Z; \
|
|
am29000->alu |= (r == 0) << ALU_Z_SHIFT;
|
|
|
|
#define SET_ALU_N(r) am29000->alu &= ~ALU_N; \
|
|
am29000->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) am29000->alu &= ~ALU_C; \
|
|
am29000->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) am29000->alu &= ~ALU_C; \
|
|
am29000->alu |= CALC_C_SUB(a, b) << ALU_C_SHIFT;
|
|
|
|
#define SET_ALU_V_ADD(r, a, b) am29000->alu &= ~ALU_V; \
|
|
am29000->alu |= (((INT32)(~((a) ^ (b)) & ((a) ^ (r))) < 0)) << ALU_V_SHIFT;
|
|
|
|
#define SET_ALU_V_SUB(r, a, b) am29000->alu &= ~ALU_V; \
|
|
am29000->alu |= ((INT32)(((a) ^ (b)) & ((a) ^ (r))) < 0) << ALU_V_SHIFT;
|
|
|
|
#define GET_CARRY ((am29000->alu >> ALU_C_SHIFT) & 1)
|
|
|
|
|
|
|
|
static UINT32 read_spr(am29000_state *am29000, UINT32 idx)
|
|
{
|
|
UINT32 val = 0;
|
|
|
|
switch (idx)
|
|
{
|
|
case SPR_VAB: val = am29000->vab; break;
|
|
case SPR_OPS: val = am29000->ops; break;
|
|
case SPR_CPS: val = am29000->cps; break;
|
|
case SPR_CFG: val = am29000->cfg; break;
|
|
case SPR_CHA: val = am29000->cha; break;
|
|
case SPR_CHD: val = am29000->chd; break;
|
|
case SPR_CHC: val = am29000->chc; break;
|
|
case SPR_RBP: val = am29000->rbp; break;
|
|
case SPR_TMC: val = am29000->tmc; break;
|
|
case SPR_TMR: val = am29000->tmr; break;
|
|
case SPR_PC0: val = am29000->pc0; break;
|
|
case SPR_PC1: val = am29000->pc1; break;
|
|
case SPR_PC2: val = am29000->pc2; break;
|
|
case SPR_MMU: val = am29000->mmu; break;
|
|
case SPR_LRU: val = am29000->lru; break;
|
|
case SPR_IPC: val = am29000->ipc; break;
|
|
case SPR_IPA: val = am29000->ipa; break;
|
|
case SPR_IPB: val = am29000->ipb; break;
|
|
case SPR_Q: val = am29000->q; break;
|
|
case SPR_ALU: val = am29000->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 = am29000->fpe; break;
|
|
case SPR_INTE: val = am29000->inte; break;
|
|
case SPR_FPS: val = am29000->fps; break;
|
|
default:
|
|
logerror("Unknown SPR read (%d)\n", idx);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
|
|
static void write_spr(am29000_state *am29000, UINT32 idx, UINT32 val)
|
|
{
|
|
switch (idx)
|
|
{
|
|
case SPR_VAB: am29000->vab = val & (VAB_MASK << VAB_SHIFT);
|
|
break;
|
|
case SPR_OPS: am29000->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: am29000->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: am29000->cfg = val & (CFG_DW | CFG_VF | CFG_RV | CFG_BO | CFG_CP | CFG_CD);
|
|
am29000->cfg |= PROCESSOR_REL_FIELD << CFG_PRL_SHIFT;
|
|
break;
|
|
case SPR_CHA: am29000->cha = val;
|
|
break;
|
|
case SPR_CHD: am29000->chd = val;
|
|
break;
|
|
case SPR_CHC: am29000->chc = val;
|
|
break;
|
|
case SPR_RBP: am29000->rbp = val & RBP_MASK;
|
|
break;
|
|
case SPR_TMC: am29000->tmc = val & TCV_MASK;
|
|
break;
|
|
case SPR_TMR: am29000->tmr = val & (TMR_OV | TMR_IN | TMR_IE | TMR_TRV_MASK);
|
|
break;
|
|
case SPR_PC0: am29000->pc0 = val & PC_MASK;
|
|
break;
|
|
case SPR_PC1: am29000->pc1 = val & PC_MASK;
|
|
break;
|
|
case SPR_PC2: am29000->pc2 = val & PC_MASK;
|
|
break;
|
|
case SPR_MMU: am29000->mmu = val & ((MMU_PS_MASK << MMU_PS_SHIFT) | MMU_PID_MASK);
|
|
break;
|
|
case SPR_LRU: am29000->lru = val & (LRU_MASK << LRU_SHIFT);
|
|
break;
|
|
case SPR_IPC: am29000->ipc = val;// & IPX_MASK;
|
|
break;
|
|
case SPR_IPA: am29000->ipa = val;// & IPX_MASK;
|
|
break;
|
|
case SPR_IPB: am29000->ipb = val;// & IPX_MASK;
|
|
break;
|
|
case SPR_Q: am29000->q = val;
|
|
break;
|
|
case SPR_ALU: am29000->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: am29000->alu &= ~(ALU_BP_MASK << ALU_BP_SHIFT);
|
|
am29000->alu |= (val & ALU_BP_MASK) << ALU_BP_SHIFT;
|
|
break;
|
|
case SPR_FC: am29000->alu &= ~(ALU_FC_MASK << ALU_FC_SHIFT);
|
|
am29000->alu |= (val & ALU_FC_MASK) << ALU_FC_SHIFT;
|
|
break;
|
|
case SPR_CR: am29000->chc &= ~(CHC_CR_MASK << CHC_CR_SHIFT);
|
|
am29000->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
|
|
***************************************************************************/
|
|
|
|
static void ADD(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void ADDS(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void ADDU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void ADDC(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void ADDCS(am29000_state *am29000)
|
|
{
|
|
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);
|
|
am29000->alu &= ~ALU_C;
|
|
am29000->alu |= carry << ALU_C_SHIFT;
|
|
}
|
|
|
|
// TODO: Trap on signed overflow
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void ADDCU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUB(am29000_state *am29000)
|
|
{
|
|
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
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void SUBS(am29000_state *am29000)
|
|
{
|
|
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);
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void SUBU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBC(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBCS(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBCU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBR(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void SUBRS(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBRU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBRC(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void SUBRCS(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SUBRCU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void MULTIPLU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void MULTIPLY(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void MUL(am29000_state *am29000)
|
|
{
|
|
/* 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 (am29000->q & 1)
|
|
{
|
|
r = a + b;
|
|
sign = (r >> 31) ^ (((INT32)(~((a) ^ (b)) & ((a) ^ (r))) < 0));
|
|
}
|
|
else
|
|
{
|
|
r = b;
|
|
sign = b >> 31;
|
|
}
|
|
|
|
v = ((((UINT64)r << 32) | am29000->q) >> 1) | ((UINT64)sign << 63);
|
|
am29000->q = v & 0xffffffff;
|
|
|
|
am29000->r[RC] = v >> 32;
|
|
}
|
|
|
|
static void MULL(am29000_state *am29000)
|
|
{
|
|
/* 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 (am29000->q & 1)
|
|
{
|
|
r = b - a;
|
|
sign = (r >> 31) ^ ((INT32)(((a) ^ (b)) & ((a) ^ (r))) < 0);
|
|
}
|
|
else
|
|
{
|
|
r = b;
|
|
sign = b >> 31;
|
|
}
|
|
|
|
v = ((((UINT64)r << 32) | am29000->q) >> 1) | ((UINT64)sign << 63);
|
|
am29000->q = v & 0xffffffff;
|
|
|
|
am29000->r[RC] = v >> 32;
|
|
}
|
|
|
|
static void MULU(am29000_state *am29000)
|
|
{
|
|
/* 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 (am29000->q & 1)
|
|
{
|
|
r = a + b;
|
|
c = (UINT32)(r) < (UINT32)(a);
|
|
}
|
|
else
|
|
{
|
|
r = b;
|
|
c = 0;
|
|
}
|
|
|
|
v = ((((UINT64)r << 32) | am29000->q) >> 1) | ((UINT64)c << 63);
|
|
am29000->q = v & 0xffffffff;
|
|
|
|
am29000->r[RC] = v >> 32;
|
|
}
|
|
|
|
static void DIVIDE(am29000_state *am29000)
|
|
{
|
|
am29000->ipa = RA << IPX_SHIFT;
|
|
am29000->ipb = RB << IPX_SHIFT;
|
|
am29000->ipc = RC << IPX_SHIFT;
|
|
|
|
SIGNAL_EXCEPTION(EXCEPTION_DIVIDE);
|
|
}
|
|
|
|
static void DIVIDU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void DIV0(am29000_state *am29000)
|
|
{
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT64 v;
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
am29000->alu |= ALU_DF;
|
|
SET_ALU_N(b);
|
|
}
|
|
|
|
v = (((UINT64)b << 32) | am29000->q) << 1;
|
|
|
|
am29000->q = v & 0xffffffff;
|
|
|
|
am29000->r[RC] = v >> 32;
|
|
}
|
|
|
|
static void DIV(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 c;
|
|
UINT32 r;
|
|
UINT64 r64;
|
|
UINT32 df;
|
|
|
|
if (am29000->alu & ALU_DF)
|
|
{
|
|
r = a - b;
|
|
c = !((UINT32)(a) < (UINT32)(b));
|
|
}
|
|
else
|
|
{
|
|
r = a + b;
|
|
c = (UINT32)(r) < (UINT32)(a);
|
|
}
|
|
|
|
|
|
df = (~(c ^ (am29000->alu >> ALU_DF_SHIFT) ^ (am29000->alu >> ALU_N_SHIFT)) & 1);
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
am29000->alu &= ~ALU_DF;
|
|
am29000->alu |= df << ALU_DF_SHIFT;
|
|
SET_ALU_N(r);
|
|
}
|
|
|
|
r64 = ((((UINT64)r << 32) | am29000->q) << 1) | df;
|
|
am29000->q = r64 & 0xffffffff;
|
|
|
|
am29000->r[RC] = r64 >> 32;
|
|
}
|
|
|
|
static void DIVL(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 c;
|
|
UINT32 r;
|
|
UINT32 df;
|
|
|
|
if (am29000->alu & ALU_DF)
|
|
{
|
|
r = a - b;
|
|
c = !((UINT32)(a) < (UINT32)(b));
|
|
}
|
|
else
|
|
{
|
|
r = a + b;
|
|
c = (UINT32)(r) < (UINT32)(a);
|
|
}
|
|
|
|
df = (~(c ^ (am29000->alu >> ALU_DF_SHIFT) ^ (am29000->alu >> ALU_N_SHIFT)) & 1);
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
am29000->alu &= ~ALU_DF;
|
|
am29000->alu |= df << ALU_DF_SHIFT;
|
|
SET_ALU_N(r);
|
|
}
|
|
|
|
am29000->q = (am29000->q << 1) | df;
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void DIVREM(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
|
|
if (am29000->alu & ALU_DF)
|
|
am29000->r[RC] = a;
|
|
else
|
|
am29000->r[RC] = a + b;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
COMPARE
|
|
***************************************************************************/
|
|
|
|
static void CPEQ(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = a == b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPNEQ(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = a != b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPLT(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (INT32)a < (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPLTU(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (UINT32)a < (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPLE(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (INT32)a <= (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPLEU(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (UINT32)a <= (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPGT(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (INT32)a > (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPGTU(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (UINT32)a > (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPGE(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (INT32)a >= (INT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPGEU(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 r = (UINT32)a >= (UINT32)b ? BOOLEAN_TRUE : BOOLEAN_FALSE;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void CPBYTE(am29000_state *am29000)
|
|
{
|
|
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;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void ASEQ(am29000_state *am29000)
|
|
{
|
|
if (USER_MODE && INST_VN < 64)
|
|
SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
|
|
else if (!(GET_RA_VAL == GET_RB_VAL))
|
|
SIGNAL_EXCEPTION(INST_VN);
|
|
}
|
|
|
|
static void ASNEQ(am29000_state *am29000)
|
|
{
|
|
if (USER_MODE && INST_VN < 64)
|
|
SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
|
|
else if (!(GET_RA_VAL != GET_RB_VAL))
|
|
SIGNAL_EXCEPTION(INST_VN);
|
|
}
|
|
|
|
static void ASLT(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASLTU(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASLE(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASLEU(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASGT(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASGTU(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASGE(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void ASGEU(am29000_state *am29000)
|
|
{
|
|
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
|
|
***************************************************************************/
|
|
|
|
static void AND(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void ANDN(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void NAND(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void OR(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void NOR(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void XOR(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void XNOR(am29000_state *am29000)
|
|
{
|
|
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);
|
|
}
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
SHIFT
|
|
***************************************************************************/
|
|
|
|
static void SLL(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL) & 0x1f;
|
|
UINT32 r = a << b;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void SRL(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL) & 0x1f;
|
|
UINT32 r = a >> b;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void SRA(am29000_state *am29000)
|
|
{
|
|
INT32 a = GET_RA_VAL;
|
|
UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL) & 0x1f;
|
|
UINT32 r = a >> b;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void EXTRACT(am29000_state *am29000)
|
|
{
|
|
INT32 a = GET_RA_VAL;
|
|
UINT32 b = (INST_M_BIT ? I8: GET_RB_VAL);
|
|
UINT64 r;
|
|
|
|
r = (((UINT64)a << 32) | b) << GET_ALU_FC;
|
|
|
|
am29000->r[RC] = r >> 32;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
DATA MOVEMENT
|
|
***************************************************************************/
|
|
|
|
static void LOAD(am29000_state *am29000)
|
|
{
|
|
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 && !(am29000->cps & CPS_PD))
|
|
{
|
|
fatalerror("Am29000: Address translation on LOAD\n");
|
|
}
|
|
else
|
|
{
|
|
if (USER_MODE)
|
|
{
|
|
SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
|
|
return;
|
|
}
|
|
|
|
r = memory_read_dword_32be(am29000->data, addr);
|
|
}
|
|
}
|
|
|
|
// if (opt & 2)
|
|
// logerror("Am29000: Half word LOAD\n");
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
am29000->chc = ((am29000->exec_ir << 8) & 0xff) |
|
|
CHC_LS |
|
|
RA << CHC_TR_SHIFT |
|
|
CHC_CV;
|
|
|
|
am29000->cha = addr;
|
|
am29000->chd = r;
|
|
|
|
if (!(am29000->cfg & CFG_DW) && (am29000->exec_ir & INST_SB_BIT))
|
|
SET_ALU_BP(addr & 3);
|
|
}
|
|
|
|
am29000->r[RA] = r;
|
|
|
|
if (am29000->cfg & CFG_DW)
|
|
logerror("DW ON A STORE");
|
|
}
|
|
|
|
static void LOADL(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void LOADSET(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void LOADM(am29000_state *am29000)
|
|
{
|
|
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 && !(am29000->cps & CPS_PD))
|
|
{
|
|
fatalerror("Am29000: Address translation on LOAD\n");
|
|
}
|
|
else
|
|
{
|
|
if (USER_MODE)
|
|
{
|
|
SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
|
|
return;
|
|
}
|
|
|
|
r = memory_read_dword_32be(am29000->data, addr);
|
|
}
|
|
}
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
// TODO
|
|
am29000->chc &= (CHC_CR_MASK << CHC_CR_SHIFT);
|
|
am29000->chc |= ((am29000->exec_ir << 8) & 0xff) |
|
|
RA << CHC_TR_SHIFT |
|
|
CHC_CV;
|
|
|
|
am29000->cha = addr;
|
|
am29000->chd = r; // ?????
|
|
|
|
if (!(am29000->cfg & CFG_DW) && (am29000->exec_ir & INST_SB_BIT))
|
|
SET_ALU_BP(addr & 3);
|
|
}
|
|
|
|
r = RA;
|
|
|
|
{
|
|
int cnt;
|
|
for (cnt = 0; cnt <= GET_CHC_CR; ++cnt)
|
|
{
|
|
am29000->r[r] = memory_read_dword_32be(am29000->data, addr);
|
|
|
|
// SET_CHC_CR(cnt - 1);
|
|
addr += 4;
|
|
|
|
if (++r == 256)
|
|
r = 128;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void STORE(am29000_state *am29000)
|
|
{
|
|
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 && !(am29000->cps & CPS_PD))
|
|
{
|
|
fatalerror("Am29000: Address translation on LOAD\n");
|
|
}
|
|
else
|
|
{
|
|
if (USER_MODE)
|
|
{
|
|
SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
memory_write_dword_32be(am29000->data, addr, am29000->r[RA]);
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
am29000->chc = ((am29000->exec_ir << 8) & 0xff) |
|
|
RA << CHC_TR_SHIFT |
|
|
CHC_CV;
|
|
|
|
am29000->cha = addr;
|
|
|
|
if (!(am29000->cfg & CFG_DW) && (am29000->exec_ir & INST_SB_BIT))
|
|
SET_ALU_BP(addr & 3);
|
|
}
|
|
|
|
if (am29000->cfg & CFG_DW)
|
|
logerror("DW ON A STORE");
|
|
}
|
|
|
|
static void STOREL(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void STOREM(am29000_state *am29000)
|
|
{
|
|
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 && !(am29000->cps & CPS_PD))
|
|
{
|
|
fatalerror("Am29000: Address translation on LOAD\n");
|
|
}
|
|
else
|
|
{
|
|
if (USER_MODE)
|
|
{
|
|
SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (!FREEZE_MODE)
|
|
{
|
|
// TODO
|
|
am29000->chc &= (CHC_CR_MASK << CHC_CR_SHIFT);
|
|
am29000->chc |= ((am29000->exec_ir << 8) & 0xff) |
|
|
RA << CHC_TR_SHIFT |
|
|
CHC_CV;
|
|
|
|
am29000->cha = addr;
|
|
|
|
if (!(am29000->cfg & CFG_DW) && (am29000->exec_ir & INST_SB_BIT))
|
|
SET_ALU_BP(addr & 3);
|
|
}
|
|
|
|
r = RA;
|
|
|
|
{
|
|
int cnt;
|
|
for (cnt = 0; cnt <= GET_CHC_CR; ++cnt)
|
|
{
|
|
memory_write_dword_32be(am29000->data, addr, am29000->r[r]);
|
|
|
|
// SET_CHC_CR(cnt - 1);
|
|
addr += 4;
|
|
|
|
if (++r == 256)
|
|
r = 128;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void EXBYTE(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 bp = GET_ALU_BP;
|
|
UINT8 srcbyte;
|
|
UINT32 r;
|
|
|
|
if (am29000->cfg & CFG_BO)
|
|
srcbyte = a >> 8 * bp;
|
|
else
|
|
srcbyte = a >> (8 * (3 - bp));
|
|
|
|
r = (b & 0xffffff00) | srcbyte;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void EXHW(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 wp = ((am29000->alu >> ALU_BP_SHIFT) & ALU_BP_MASK) >> 1;
|
|
UINT16 srcword;
|
|
UINT32 r;
|
|
|
|
if (am29000->cfg & CFG_BO)
|
|
srcword = a >> 16 * wp;
|
|
else
|
|
srcword = a >> (16 * (1 - wp));
|
|
|
|
r = (b & 0xffff0000) | srcword;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void EXHWS(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 wp = ((am29000->alu >> ALU_BP_SHIFT) & ALU_BP_MASK) >> 1;
|
|
UINT16 srcword;
|
|
UINT32 r;
|
|
|
|
if (am29000->cfg & CFG_BO)
|
|
srcword = a >> 16 * wp;
|
|
else
|
|
srcword = a >> (16 * (1 - wp));
|
|
|
|
r = (INT32)(INT16)srcword;
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void INBYTE(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 bp = GET_ALU_BP;
|
|
UINT8 shift = (am29000->cfg & CFG_BO) ? 8 * bp : (8 * (3 - bp));
|
|
UINT32 r;
|
|
|
|
r = (a & ~(0xff << shift)) | ((b & 0xff) << shift);
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void INHW(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
UINT32 wp = ((am29000->alu >> ALU_BP_SHIFT) & ALU_BP_MASK) >> 1;
|
|
UINT32 shift = (am29000->cfg & CFG_BO) ? 16 * wp : (16 * (1 - wp));
|
|
UINT32 r;
|
|
|
|
r = (a & ~(0xffff << shift)) | ((b & 0xffff) << shift);
|
|
|
|
am29000->r[RC] = r;
|
|
}
|
|
|
|
static void MFSR(am29000_state *am29000)
|
|
{
|
|
am29000->r[RC] = read_spr(am29000, INST_SA);
|
|
}
|
|
|
|
static void MFTLB(am29000_state *am29000)
|
|
{
|
|
am29000->r[RC] = am29000->tlb[GET_RA_VAL & 0x7f];
|
|
}
|
|
|
|
static void MTSR(am29000_state *am29000)
|
|
{
|
|
write_spr(am29000, INST_SA, GET_RB_VAL);
|
|
}
|
|
|
|
static void MTSRIM(am29000_state *am29000)
|
|
{
|
|
write_spr(am29000, INST_SA, I16_ZEX);
|
|
}
|
|
|
|
static void MTTLB(am29000_state *am29000)
|
|
{
|
|
am29000->tlb[GET_RA_VAL & 0x7f] = GET_RB_VAL;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
CONSTANT
|
|
***************************************************************************/
|
|
|
|
static void CONST(am29000_state *am29000)
|
|
{
|
|
am29000->r[RA] = I16_ZEX;
|
|
}
|
|
|
|
static void CONSTH(am29000_state *am29000)
|
|
{
|
|
am29000->r[RA] = (I16 << 16) | GET_RA_VAL;
|
|
}
|
|
|
|
static void CONSTN(am29000_state *am29000)
|
|
{
|
|
am29000->r[RA] = I16_OEX;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
BRANCH INSTRUCTIONS
|
|
***************************************************************************/
|
|
|
|
static void CALL(am29000_state *am29000)
|
|
{
|
|
UINT32 ret = am29000->next_pc;
|
|
|
|
if (INST_M_BIT)
|
|
am29000->next_pc = JMP_ZEX;
|
|
else
|
|
am29000->next_pc = am29000->exec_pc + JMP_SEX;
|
|
|
|
am29000->r[RA] = ret;
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
|
|
static void CALLI(am29000_state *am29000)
|
|
{
|
|
UINT32 ret = am29000->next_pc;
|
|
am29000->next_pc = GET_RB_VAL;
|
|
am29000->r[RA] = ret;
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
|
|
static void JMP(am29000_state *am29000)
|
|
{
|
|
if (INST_M_BIT)
|
|
am29000->next_pc = JMP_ZEX;
|
|
else
|
|
am29000->next_pc = am29000->exec_pc + JMP_SEX;
|
|
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
|
|
static void JMPI(am29000_state *am29000)
|
|
{
|
|
am29000->next_pc = GET_RB_VAL;
|
|
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
|
|
static void JMPT(am29000_state *am29000)
|
|
{
|
|
if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_TRUE)
|
|
{
|
|
if (INST_M_BIT)
|
|
am29000->next_pc = JMP_ZEX;
|
|
else
|
|
am29000->next_pc = am29000->exec_pc + JMP_SEX;
|
|
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
}
|
|
|
|
static void JMPTI(am29000_state *am29000)
|
|
{
|
|
if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_TRUE)
|
|
{
|
|
am29000->next_pc = GET_RB_VAL;
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
}
|
|
|
|
static void JMPF(am29000_state *am29000)
|
|
{
|
|
if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_FALSE)
|
|
{
|
|
if (INST_M_BIT)
|
|
am29000->next_pc = JMP_ZEX;
|
|
else
|
|
am29000->next_pc = am29000->exec_pc + JMP_SEX;
|
|
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
}
|
|
|
|
static void JMPFI(am29000_state *am29000)
|
|
{
|
|
if ((GET_RA_VAL & BOOLEAN_MASK) == BOOLEAN_FALSE)
|
|
{
|
|
am29000->next_pc = GET_RB_VAL;
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
}
|
|
|
|
static void JMPFDEC(am29000_state *am29000)
|
|
{
|
|
UINT32 a = GET_RA_VAL;
|
|
|
|
if ((a & BOOLEAN_MASK) == BOOLEAN_FALSE)
|
|
{
|
|
if (INST_M_BIT)
|
|
am29000->next_pc = JMP_ZEX;
|
|
else
|
|
am29000->next_pc = am29000->exec_pc + JMP_SEX;
|
|
|
|
am29000->next_pl_flags |= PFLAG_JUMP;
|
|
}
|
|
|
|
am29000->r[RA] = a - 1;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
MISCELLANEOUS INSTRUCTIONS
|
|
***************************************************************************/
|
|
|
|
static void CLZ(am29000_state *am29000)
|
|
{
|
|
UINT32 b = INST_M_BIT ? I8: GET_RB_VAL;
|
|
|
|
am29000->r[RC] = count_leading_zeros(b);
|
|
}
|
|
|
|
static void SETIP(am29000_state *am29000)
|
|
{
|
|
am29000->ipa = RA << IPX_SHIFT;
|
|
am29000->ipb = RB << IPX_SHIFT;
|
|
am29000->ipc = RC << IPX_SHIFT;
|
|
}
|
|
|
|
static void EMULATE(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void INV(am29000_state *am29000)
|
|
{
|
|
/* Nothing to do yet */
|
|
}
|
|
|
|
static void IRET(am29000_state *am29000)
|
|
{
|
|
am29000->iret_pc = am29000->pc0;
|
|
am29000->next_pc = am29000->pc1;
|
|
am29000->cps = am29000->ops;
|
|
am29000->next_pl_flags = PFLAG_IRET;
|
|
}
|
|
|
|
static void IRETINV(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void HALT(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
|
|
static void ILLEGAL(am29000_state *am29000)
|
|
{
|
|
fatalerror("Am29000: Executed illegal instruction - this should never happen! %x (%x)\n", am29000->pc2, am29000->exec_pc);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
UNHANDLED
|
|
***************************************************************************/
|
|
|
|
static void CONVERT(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void SQRT(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void CLASS(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void MULTM(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
static void MULTMU(am29000_state *am29000)
|
|
{
|
|
UNHANDLED_OP;
|
|
}
|
|
|
|
|
|
const op_info op_table[256] =
|
|
{
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ CONSTN, IFLAG_RA_PRESENT },
|
|
{ CONSTH, IFLAG_RA_PRESENT },
|
|
{ CONST, IFLAG_RA_PRESENT },
|
|
{ MTSRIM, 0 },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ LOADL, 0 },
|
|
{ LOADL, 0 },
|
|
{ CLZ, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT },
|
|
{ CLZ, IFLAG_RC_PRESENT },
|
|
{ EXBYTE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ EXBYTE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ INBYTE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ INBYTE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ STOREL, 0 },
|
|
{ STOREL, 0 },
|
|
{ ADDS, 0 },
|
|
{ ADDS, 0 },
|
|
{ ADDU, 0 },
|
|
{ ADDU, 0 },
|
|
{ ADD, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ADD, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ LOAD, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ LOAD, IFLAG_RA_PRESENT },
|
|
{ ADDCS, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ADDCS, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ADDCU, 0 },
|
|
{ ADDCU, 0 },
|
|
{ ADDC, 0 },
|
|
{ ADDC, 0 },
|
|
{ STORE, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ STORE, IFLAG_RA_PRESENT },
|
|
{ SUBS, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SUBS, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SUBU, 0 },
|
|
{ SUBU, 0 },
|
|
{ SUB, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SUB, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ LOADSET, 0 },
|
|
{ LOADSET, 0 },
|
|
{ SUBCS, 0 },
|
|
{ SUBCS, 0 },
|
|
{ SUBCU, 0 },
|
|
{ SUBCU, 0 },
|
|
{ SUBC, 0 },
|
|
{ SUBC, 0 },
|
|
{ CPBYTE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPBYTE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SUBRS, 0 },
|
|
{ SUBRS, 0 },
|
|
{ SUBRU, 0 },
|
|
{ SUBRU, 0 },
|
|
{ SUBR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SUBR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ LOADM, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ LOADM, IFLAG_RA_PRESENT },
|
|
{ SUBRCS, 0 },
|
|
{ SUBRCS, 0 },
|
|
{ SUBRCU, 0 },
|
|
{ SUBRCU, 0 },
|
|
{ SUBRC, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SUBRC, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ STOREM, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ STOREM, IFLAG_RA_PRESENT },
|
|
{ CPLT, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLT, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLTU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLTU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLEU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPLEU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGT, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGT, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGTU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGTU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGE, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGE, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGEU, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPGEU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ASLT, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASLT, IFLAG_RA_PRESENT },
|
|
{ ASLTU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASLTU, IFLAG_RA_PRESENT },
|
|
{ ASLE, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASLE, IFLAG_RA_PRESENT },
|
|
{ ASLEU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASLEU, IFLAG_RA_PRESENT },
|
|
{ ASGT, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASGT, IFLAG_RA_PRESENT },
|
|
{ ASGTU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASGTU, IFLAG_RA_PRESENT },
|
|
{ ASGE, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASGE, IFLAG_RA_PRESENT },
|
|
{ ASGEU, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASGEU, IFLAG_RA_PRESENT },
|
|
{ CPEQ, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPEQ, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPNEQ, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ CPNEQ, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ MUL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ MUL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ MULL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ MULL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ DIV0, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT },
|
|
{ DIV0, IFLAG_RC_PRESENT },
|
|
{ DIV, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ DIV, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ DIVL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ DIVL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ DIVREM, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ DIVREM, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ASEQ, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASEQ, IFLAG_RA_PRESENT },
|
|
{ ASNEQ, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ASNEQ, IFLAG_RA_PRESENT },
|
|
{ MULU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ MULU, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ INHW, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ INHW, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ EXTRACT, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ EXTRACT, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ EXHW, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ EXHW, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ EXHWS, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ SLL, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SLL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SRL, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SRL, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ SRA, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SRA, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ IRET, IFLAG_SUPERVISOR_ONLY },
|
|
{ HALT, IFLAG_SUPERVISOR_ONLY },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ IRETINV, IFLAG_SUPERVISOR_ONLY },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ AND, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ AND, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ OR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ OR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ XOR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ XOR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ XNOR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ XNOR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ NOR, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ NOR, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ NAND, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ NAND, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ANDN, IFLAG_RC_PRESENT | IFLAG_RB_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ANDN, IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ SETIP, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT | IFLAG_RC_PRESENT },
|
|
{ INV, IFLAG_SUPERVISOR_ONLY },
|
|
{ JMP, 0 },
|
|
{ JMP, 0 },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ JMPF, IFLAG_RA_PRESENT },
|
|
{ JMPF, IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ CALL, IFLAG_RA_PRESENT },
|
|
{ CALL, IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ JMPT, IFLAG_RA_PRESENT },
|
|
{ JMPT, IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ JMPFDEC, IFLAG_RA_PRESENT },
|
|
{ JMPFDEC, IFLAG_RA_PRESENT },
|
|
{ MFTLB, IFLAG_SUPERVISOR_ONLY | IFLAG_RC_PRESENT | IFLAG_RA_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ MTTLB, IFLAG_SUPERVISOR_ONLY | IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ JMPI, IFLAG_RB_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ JMPFI, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ MFSR, IFLAG_RC_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ CALLI, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ JMPTI, IFLAG_RA_PRESENT | IFLAG_RB_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ MTSR, IFLAG_RB_PRESENT },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ EMULATE, 0 },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ MULTM, 0 },
|
|
{ MULTMU, 0 },
|
|
{ MULTIPLY, 0 },
|
|
{ DIVIDE, 0 },
|
|
{ MULTIPLU, 0 },
|
|
{ DIVIDU, 0 },
|
|
{ CONVERT, 0 },
|
|
{ SQRT, 0 },
|
|
{ CLASS, 0 },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
{ ILLEGAL, IFLAG_ILLEGAL },
|
|
// FEQ
|
|
// DEQ
|
|
// TODO! etc
|
|
};
|