blob: 5bc96aca6164efb19c08a24cc3870d144350a959 [file] [log] [blame]
// Helper:
//
// Given an extended register number, translate it into an index into the
// register array. This is necessary as the upper 8 extended registers are
// actually synonyms for the d0-d3/a0-a3 registers.
//
//
:function:::int:translate_rreg:int rreg
{
/* The higher register numbers actually correspond to the
basic machine's address and data registers. */
if (rreg > 7 && rreg < 12)
return REG_A0 + rreg - 8;
else if (rreg > 11 && rreg < 16)
return REG_D0 + rreg - 12;
else
return REG_E0 + rreg;
}
:function:::int:translate_xreg:int xreg
{
switch (xreg)
{
case 0:
return REG_SP;
case 1:
return REG_MDRQ;
case 2:
return REG_MCRH;
case 3:
return REG_MCRL;
case 4:
return REG_MCVF;
default:
sim_engine_abort (SD, CPU, cia, "%s:%d: bad switch\n", __FILE__, __LINE__);
}
}
// 1111 0000 0010 00An; mov USP,An
8.0xf0+4.0x2,00,2.AN0:D0m:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_A0 + AN0] = State.regs[REG_USP];
}
// 1111 0000 0010 01An; mov SSP,An
8.0xf0+4.0x2,01,2.AN0:D0n:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_A0 + AN0] = State.regs[REG_SSP];
}
// 1111 0000 0010 10An; mov MSP,An
8.0xf0+4.0x2,10,2.AN0:D0o:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_A0 + AN0] = State.regs[REG_MSP];
}
// 1111 0000 0010 11An; mov PC,An
8.0xf0+4.0x2,11,2.AN0:D0p:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_A0 + AN0] = PC;
}
// 1111 0000 0011 Am00; mov Am,USP
8.0xf0+4.0x3,2.AM1,00:D0q:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_USP] = State.regs[REG_A0 + AM1];
}
// 1111 0000 0011 Am01; mov Am,SSP
8.0xf0+4.0x3,2.AM1,01:D0r:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_SSP] = State.regs[REG_A0 + AM1];
}
// 1111 0000 0011 Am10; mov Am,MSP
8.0xf0+4.0x3,2.AM1,10:D0s:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_MSP] = State.regs[REG_A0 + AM1];
}
// 1111 0000 1110 imm4; syscall
8.0xf0+4.0xe,IMM4:D0t:::syscall
"syscall"
*am33
*am33_2
{
unsigned32 sp, next_pc;
PC = cia;
sp = State.regs[REG_SP];
next_pc = State.regs[REG_PC] + 2;
store_word (sp - 4, next_pc);
store_word (sp - 8, PSW);
State.regs[REG_PC] = 0x40000000 + IMM4 * 8;
nia = PC;
}
// 1111 0010 1110 11Dn; mov EPSW,Dn
8.0xf2+4.0xe,11,2.DN0:D0u:::mov
"mov"
*am33
*am33_2
{
PC = cia;
State.regs[REG_D0 + DN0] = PSW;
}
// 1111 0010 1111 Dm01; mov Dm,EPSW
8.0xf2+4.0xf,2.DM1,01:D0v:::mov
"mov"
*am33
*am33_2
{
PC = cia;
PSW = State.regs[REG_D0 + DM1];
}
// 1111 0101 00Am Rn; mov Am,Rn
8.0xf5+00,2.AM1,4.RN0:D0w:::mov
"mov"
*am33
*am33_2
{
int destreg = translate_rreg (SD_, RN0);
PC = cia;
State.regs[destreg] = State.regs[REG_A0 + AM1];
}
// 1111 0101 01Dm Rn; mov Dm,Rn
8.0xf5+01,2.DM1,4.RN0:D0x:::mov
"mov"
*am33
*am33_2
{
int destreg = translate_rreg (SD_, RN0);
PC = cia;
State.regs[destreg] = State.regs[REG_D0 + DM1];
}
// 1111 0101 10Rm An; mov Rm,An
8.0xf5+10,4.RM1,2.AN0:D0y:::mov
"mov"
*am33
*am33_2
{
int destreg = translate_rreg (SD_, RM1);
PC = cia;
State.regs[REG_A0 + AN0] = State.regs[destreg];
}
// 1111 0101 11Rm Dn; mov Rm,Dn
8.0xf5+11,4.RM1,2.DN0:D0z:::mov
"mov"
*am33
*am33_2
{
int destreg = translate_rreg (SD_, RM1);
PC = cia;
State.regs[REG_D0 + DN0] = State.regs[destreg];
}
// 1111 1000 1100 1110 regs....; movm (USP),regs
8.0xf8+8.0xce+8.REGS:D1a:::movm
"movm"
*am33
*am33_2
{
unsigned32 usp = State.regs[REG_USP];
unsigned32 mask;
PC = cia;
mask = REGS;
if (mask & 0x8)
{
usp += 4;
State.regs[REG_LAR] = load_word (usp);
usp += 4;
State.regs[REG_LIR] = load_word (usp);
usp += 4;
State.regs[REG_MDR] = load_word (usp);
usp += 4;
State.regs[REG_A0 + 1] = load_word (usp);
usp += 4;
State.regs[REG_A0] = load_word (usp);
usp += 4;
State.regs[REG_D0 + 1] = load_word (usp);
usp += 4;
State.regs[REG_D0] = load_word (usp);
usp += 4;
}
if (mask & 0x10)
{
State.regs[REG_A0 + 3] = load_word (usp);
usp += 4;
}
if (mask & 0x20)
{
State.regs[REG_A0 + 2] = load_word (usp);
usp += 4;
}
if (mask & 0x40)
{
State.regs[REG_D0 + 3] = load_word (usp);
usp += 4;
}
if (mask & 0x80)
{
State.regs[REG_D0 + 2] = load_word (usp);
usp += 4;
}
if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_am33
|| STATE_ARCHITECTURE (sd)->mach == bfd_mach_am33_2
)
{
if (mask & 0x1)
{
/* Need to restore MDQR, MCRH, MCRL, and MCVF */
usp += 16;
State.regs[REG_E0 + 1] = load_word (usp);
usp += 4;
State.regs[REG_E0 + 0] = load_word (usp);
usp += 4;
}
if (mask & 0x2)
{
State.regs[REG_E0 + 7] = load_word (usp);
usp += 4;
State.regs[REG_E0 + 6] = load_word (usp);
usp += 4;
State.regs[REG_E0 + 5] = load_word (usp);
usp += 4;
State.regs[REG_E0 + 4] = load_word (usp);
usp += 4;
}
if (mask & 0x4)
{
State.regs[REG_E0 + 3] = load_word (usp);
usp += 4;
State.regs[REG_E0 + 2] = load_word (usp);
usp += 4;
}
}
/* And make sure to update the stack pointer. */
State.regs[REG_USP] = usp;
}
// 1111 1000 1100 1111 regs....; movm (USP),regs
8.0xf8+8.0xcf+8.REGS:D1b:::movm
"movm"
*am33
*am33_2
{
unsigned32 usp = State.regs[REG_USP];
unsigned32 mask;
PC = cia;
mask = REGS;
if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_am33
|| STATE_ARCHITECTURE (sd)->mach == bfd_mach_am33_2
)
{
if (mask & 0x4)
{
usp -= 4;
store_word (usp, State.regs[REG_E0 + 2]);
usp -= 4;
store_word (usp, State.regs[REG_E0 + 3]);
}
if (mask & 0x2)
{
usp -= 4;
store_word (usp, State.regs[REG_E0 + 4]);
usp -= 4;
store_word (usp, State.regs[REG_E0 + 5]);
usp -= 4;
store_word (usp, State.regs[REG_E0 + 6]);
usp -= 4;
store_word (usp, State.regs[REG_E0 + 7]);
}
if (mask & 0x1)
{
usp -= 4;
store_word (usp, State.regs[REG_E0 + 0]);
usp -= 4;
store_word (usp, State.regs[REG_E0 + 1]);
usp -= 16;
/* Need to save MDQR, MCRH, MCRL, and MCVF */
}
}
if (mask & 0x80)
{
usp -= 4;
store_word (usp, State.regs[REG_D0 + 2]);
}
if (mask & 0x40)
{
usp -= 4;
store_word (usp, State.regs[REG_D0 + 3]);
}
if (mask & 0x20)
{
usp -= 4;
store_word (usp, State.regs[REG_A0 + 2]);
}
if (mask & 0x10)
{
usp -= 4;
store_word (usp, State.regs[REG_A0 + 3]);
}
if (mask & 0x8)
{
usp -= 4;
store_word (usp, State.regs[REG_D0]);
usp -= 4;
store_word (usp, State.regs[REG_D0 + 1]);
usp -= 4;
store_word (usp, State.regs[REG_A0]);
usp -= 4;
store_word (usp, State.regs[REG_A0 + 1]);
usp -= 4;
store_word (usp, State.regs[REG_MDR]);
usp -= 4;
store_word (usp, State.regs[REG_LIR]);
usp -= 4;
store_word (usp, State.regs[REG_LAR]);
usp -= 4;
}
/* And make sure to update the stack pointer. */
State.regs[REG_USP] = usp;
}
// 1111 1100 1111 1100 imm32...; and imm32,EPSW
8.0xfc+8.0xfc+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:4a:::and
"and"
*am33
*am33_2
{
PC = cia;
PSW &= FETCH32(IMM32A, IMM32B, IMM32C, IMM32D);
}
// 1111 1100 1111 1101 imm32...; or imm32,EPSW
8.0xfc+8.0xfd+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D4a:::or
"or"
*am33
*am33_2
{
PC = cia;
PSW |= FETCH32(IMM32A, IMM32B, IMM32C, IMM32D);
}
// 1111 1001 0000 1000 Rm Rn; mov Rm,Rn (Rm != Rn)
8.0xf9+8.0x08+4.RM2,4.RN0!RM2:D1g:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = State.regs[srcreg];
}
// 1111 1001 0001 1000 Rn Rn; ext Rn
8.0xf9+8.0x18+4.RN0,4.RN2=RN0:D1:::ext
"mov"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RN0);
if (State.regs[srcreg] & 0x80000000)
State.regs[REG_MDR] = -1;
else
State.regs[REG_MDR] = 0;
}
// 1111 1001 0010 1000 Rm Rn; extb Rm,Rn
8.0xf9+8.0x28+4.RM2,4.RN0!RM2:D1:::extb
"extb"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = EXTEND8 (State.regs[srcreg]);
}
// 1111 1001 0011 1000 Rm Rn; extbu Rm,Rn
8.0xf9+8.0x38+4.RM2,4.RN0!RM2:D1:::extbu
"extbu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = State.regs[srcreg] & 0xff;
}
// 1111 1001 0100 1000 Rm Rn; exth Rm,Rn
8.0xf9+8.0x48+4.RM2,4.RN0!RM2:D1:::exth
"exth"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = EXTEND16 (State.regs[srcreg]);
}
// 1111 1001 0101 1000 Rm Rn; exthu Rm,Rn
8.0xf9+8.0x58+4.RM2,4.RN0!RM2:D1:::exthu
"exthu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = State.regs[srcreg] & 0xffff;
}
// 1111 1001 0110 1000 Rn Rn; clr Rn
8.0xf9+8.0x68+4.RM2,4.RN0=RM2:D1:::clr
"clr"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = 0;
PSW |= PSW_Z;
PSW &= ~(PSW_V | PSW_C | PSW_N);
}
// 1111 1001 0111 1000 Rm Rn; add Rm,Rn
8.0xf9+8.0x78+4.RM2,4.RN0:D1b:::add
"add"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
genericAdd (State.regs[srcreg], dstreg);
}
// 1111 1001 1000 1000 Rm Rn; addc Rm,Rn
8.0xf9+8.0x88+4.RM2,4.RN0:D1b:::addc
"addc"
*am33
*am33_2
{
int srcreg, dstreg;
int z, c, n, v;
unsigned32 reg1, reg2, sum;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
reg1 = State.regs[srcreg];
reg2 = State.regs[dstreg];
sum = reg1 + reg2 + ((PSW & PSW_C) != 0);
State.regs[dstreg] = sum;
z = ((PSW & PSW_Z) != 0) && (sum == 0);
n = (sum & 0x80000000);
c = (sum < reg1) || (sum < reg2);
v = ((reg2 & 0x80000000) == (reg1 & 0x80000000)
&& (reg2 & 0x80000000) != (sum & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1001 1001 1000 Rm Rn; sub Rm,Rn
8.0xf9+8.0x98+4.RM2,4.RN0:D1b:::sub
"sub"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
genericSub (State.regs[srcreg], dstreg);
}
// 1111 1001 1010 1000 Rm Rn; subc Rm,Rn
8.0xf9+8.0xa8+4.RM2,4.RN0:D1b:::subc
"subc"
*am33
*am33_2
{
int srcreg, dstreg;
int z, c, n, v;
unsigned32 reg1, reg2, difference;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
reg1 = State.regs[srcreg];
reg2 = State.regs[dstreg];
difference = reg2 - reg1 - ((PSW & PSW_C) != 0);
State.regs[dstreg] = difference;
z = ((PSW & PSW_Z) != 0) && (difference == 0);
n = (difference & 0x80000000);
c = (reg1 > reg2);
v = ((reg2 & 0x80000000) == (reg1 & 0x80000000)
&& (reg2 & 0x80000000) != (difference & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1001 1011 1000 Rn Rn; inc Rn
8.0xf9+8.0xb8+4.RN0,4.RN2=RN0:D1:::inc
"inc"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
genericAdd (1, dstreg);
}
// 1111 1001 1101 1000 Rn Rn; inc Rn
8.0xf9+8.0xc8+4.RN0,4.RN2=RN0:D1:::inc4
"inc4"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
genericAdd (4, dstreg);
}
// 1111 1001 1101 1000 Rm Rn; cmp Rm,Rn
8.0xf9+8.0xd8+4.RM2,4.RN0:D1:::cmp
"cmp"
*am33
*am33_2
{
int srcreg1, srcreg2;
PC = cia;
srcreg1 = translate_rreg (SD_, RN0);
srcreg2 = translate_rreg (SD_, RM2);
genericCmp (State.regs[srcreg2], State.regs[srcreg1]);
}
// 1111 1001 1110 1000 XRm Rn; mov XRm,Rn
8.0xf9+8.0xe8+4.XRM2,4.RN0:D1l:::mov
"mov"
*am33
*am33_2
{
int dstreg, srcreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
srcreg = translate_xreg (SD_, XRM2);
State.regs[dstreg] = State.regs[srcreg];
}
// 1111 1001 1111 1000 Rm XRn; mov Rm,XRn
8.0xf9+8.0xf8+4.RM2,4.XRN0:D1m:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_xreg (SD_, XRN0);
State.regs[dstreg] = State.regs[srcreg];
}
// 1111 1001 0000 1001 Rm Rn; and Rm,Rn
8.0xf9+8.0x09+4.RM2,4.RN0:D1a:::and
"and"
*am33
*am33_2
{
int srcreg, dstreg;
int z, n;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] &= State.regs[srcreg];
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 0001 1001 Rm Rn; or Rm,Rn
8.0xf9+8.0x19+4.RM2,4.RN0:D1a:::or
"or"
*am33
*am33_2
{
int srcreg, dstreg;
int z, n;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] |= State.regs[srcreg];
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 0010 1001 Rm Rn; xor Rm,Rn
8.0xf9+8.0x29+4.RM2,4.RN0:D1a:::xor
"xor"
*am33
*am33_2
{
int srcreg, dstreg;
int z, n;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] ^= State.regs[srcreg];
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 0011 1001 Rn Rn; not Rn
8.0xf9+8.0x39+4.RM2,4.RN0=RM2:D1:::not
"not"
*am33
*am33_2
{
int dstreg;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = ~State.regs[dstreg];
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 0100 1001 Rm Rn; asr Rm,Rn
8.0xf9+8.0x49+4.RM2,4.RN0:D1a:::asr
"asr"
*am33
*am33_2
{
int srcreg, dstreg;
signed32 temp;
int c, z, n;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = State.regs[dstreg];
c = temp & 1;
temp >>= State.regs[srcreg];
State.regs[dstreg] = temp;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0));
}
// 1111 1001 0101 1001 Rm Rn; lsr Rm,Rn
8.0xf9+8.0x59+4.RM2,4.RN0:D1a:::lsr
"lsr"
*am33
*am33_2
{
int srcreg, dstreg;
int z, n, c;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
c = State.regs[dstreg] & 1;
State.regs[dstreg] >>= State.regs[srcreg];
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0));
}
// 1111 1001 0110 1001 Rm Rn; asl Rm,Rn
8.0xf9+8.0x69+4.RM2,4.RN0:D1a:::asl
"asl"
*am33
*am33_2
{
int srcreg, dstreg;
int z, n;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] <<= State.regs[srcreg];
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 0111 1001 Rn Rn; asl2 Rn
8.0xf9+8.0x79+4.RM2,4.RN0=RM2:D1:::asl2
"asl2"
*am33
*am33_2
{
int dstreg;
int n, z;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] <<= 2;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 1000 1001 Rn Rn; ror Rn
8.0xf9+8.0x89+4.RM2,4.RN0=RM2:D1:::ror
"ror"
*am33
*am33_2
{
int dstreg;
int c, n, z;
unsigned32 value;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
value = State.regs[dstreg];
c = (value & 0x1);
value >>= 1;
value |= ((PSW & PSW_C) != 0) ? 0x80000000 : 0;
State.regs[dstreg] = value;
z = (value == 0);
n = (value & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0));
}
// 1111 1001 1001 1001 Rn Rn; rol Rn
8.0xf9+8.0x99+4.RM2,4.RN0=RM2:D1:::rol
"rol"
*am33
*am33_2
{
int dstreg;
int c, n, z;
unsigned32 value;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
value = State.regs[dstreg];
c = (value & 0x80000000) ? 1 : 0;
value <<= 1;
value |= ((PSW & PSW_C) != 0);
State.regs[dstreg] = value;
z = (value == 0);
n = (value & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0));
}
// 1111 1001 1010 1001 Rm Rn; mul Rm,Rn
8.0xf9+8.0xa9+4.RM2,4.RN0:D1b:::mul
"mul"
*am33
*am33_2
{
int srcreg, dstreg;
unsigned64 temp;
int n, z;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = ((signed64)(signed32)State.regs[dstreg]
* (signed64)(signed32)State.regs[srcreg]);
State.regs[dstreg] = temp & 0xffffffff;
State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 1011 1001 Rm Rn; mulu Rm,Rn
8.0xf9+8.0xb9+4.RM2,4.RN0:D1b:::mulu
"mulu"
*am33
*am33_2
{
int srcreg, dstreg;
unsigned64 temp;
int n, z;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = ((unsigned64)State.regs[dstreg]
* (unsigned64)State.regs[srcreg]);
State.regs[dstreg] = temp & 0xffffffff;
State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 1100 1001 Rm Rn; div Rm,Rn
8.0xf9+8.0xc9+4.RM2,4.RN0:D1b:::div
"div"
*am33
*am33_2
{
int srcreg, dstreg;
signed64 temp;
int n, z;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = State.regs[REG_MDR];
temp <<= 32;
temp |= State.regs[dstreg];
State.regs[REG_MDR] = temp % (signed32)State.regs[srcreg];
temp /= (signed32)State.regs[srcreg];
State.regs[dstreg] = temp & 0xffffffff;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 1101 1001 Rm Rn; divu Rm,Rn
8.0xf9+8.0xd9+4.RM2,4.RN0:D1b:::divu
"divu"
*am33
*am33_2
{
int srcreg, dstreg;
unsigned64 temp;
int n, z;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = State.regs[REG_MDR];
temp <<= 32;
temp |= State.regs[dstreg];
State.regs[REG_MDR] = temp % State.regs[srcreg];
temp /= State.regs[srcreg];
State.regs[dstreg] = temp & 0xffffffff;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 0000 1010 Rm Rn; mov (Rm),Rn
8.0xf9+8.0x0a+4.RN2,4.RM0:D1h:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_word (State.regs[srcreg]);
}
// 1111 1001 0001 1010 Rm Rn; mov Rm,(Rn)
8.0xf9+8.0x1a+4.RM2,4.RN0:D1i:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_word (State.regs[dstreg], State.regs[srcreg]);
}
// 1111 1001 0010 1010 Rm Rn; movbu (Rm),Rn
8.0xf9+8.0x2a+4.RN2,4.RM0:D1g:::movbu
"movbu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_byte (State.regs[srcreg]);
}
// 1111 1001 0011 1010 Rm Rn; movbu Rm,(Rn)
8.0xf9+8.0x3a+4.RM2,4.RN0:D1i:::movbu
"movbu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_byte (State.regs[dstreg], State.regs[srcreg]);
}
// 1111 1001 0100 1010 Rm Rn; movhu (Rm),Rn
8.0xf9+8.0x4a+4.RN2,4.RM0:D1g:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_half (State.regs[srcreg]);
}
// 1111 1001 0101 1010 Rm Rn; movhu Rm,(Rn)
8.0xf9+8.0x5a+4.RM2,4.RN0:D1i:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_half (State.regs[dstreg], State.regs[srcreg]);
}
// 1111 1001 0110 1010 Rm Rn; mov (Rm+),Rn
8.0xf9+8.0x6a+4.RN2,4.RM0!RN2:D1y:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_word (State.regs[srcreg]);
State.regs[srcreg] += 4;
}
// 1111 1001 0111 1010 Rm Rn; mov Rm,(Rn+)
8.0xf9+8.0x7a+4.RM2,4.RN0:D1z:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_word (State.regs[dstreg], State.regs[srcreg]);
State.regs[dstreg] += 4;
}
// 1111 1001 1000 1010 Rn 0000; mov (sp),Rn
8.0xf9+8.0x8a+4.RN2,4.0000:D1j:::mov
"mov"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_word (State.regs[REG_SP]);
}
// 1111 1001 1001 1010 Rm 0000; mov Rm, (sp)
8.0xf9+8.0x9a+4.RM2,4.0000:D1k:::mov
"mov"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
store_word (State.regs[REG_SP], State.regs[srcreg]);
}
// 1111 1001 1010 1010 Rn 0000; mobvu (sp),Rn
8.0xf9+8.0xaa+4.RN2,4.0000:D1j:::movbu
"movbu"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_byte (State.regs[REG_SP]);
}
// 1111 1001 1011 1010 Rm 0000; movbu Rm, (sp)
8.0xf9+8.0xba+4.RM2,4.0000:D1k:::movbu
"movbu"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
store_byte (State.regs[REG_SP], State.regs[srcreg]);
}
// 1111 1001 1000 1100 Rn 0000; movhu (sp),Rn
8.0xf9+8.0xca+4.RN2,4.0000:D1j:::movhu
"movhu"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_half (State.regs[REG_SP]);
}
// 1111 1001 1001 1101 Rm 0000; movhu Rm, (sp)
8.0xf9+8.0xda+4.RM2,4.0000:D1k:::movhu
"movhu"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
store_half (State.regs[REG_SP], State.regs[srcreg]);
}
// 1111 1001 1110 1010 Rm Rn; movhu (Rm+),Rn
8.0xf9+8.0xea+4.RN2,4.RM0!RN2:D1y:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_half (State.regs[srcreg]);
State.regs[srcreg] += 2;
}
// 1111 1001 1111 1010 Rm Rn; movhu Rm,(Rn+)
8.0xf9+8.0xfa+4.RM2,4.RN0:D1z:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_half (State.regs[dstreg], State.regs[srcreg]);
State.regs[dstreg] += 2;
}
// 1111 1001 0000 1011 Rm Rn; mac Rm,Rn
8.0xf9+8.0x0b+4.RM2,4.RN0:D1:::mac
"mac"
*am33
*am33_2
{
int srcreg1, srcreg2;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((signed64)(signed32)State.regs[srcreg2]
* (signed64)(signed32)State.regs[srcreg1]);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0001 1011 Rm Rn; macu Rm,Rn
8.0xf9+8.0x1b+4.RM2,4.RN0:D1:::macu
"macu"
*am33
*am33_2
{
int srcreg1, srcreg2;
unsigned64 temp, sum;
int c, v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((unsigned64)State.regs[srcreg2]
* (unsigned64)State.regs[srcreg1]);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0010 1011 Rm Rn; macb Rm,Rn
8.0xf9+8.0x2b+4.RM2,4.RN0:D1:::macb
"macb"
*am33
*am33_2
{
int srcreg1, srcreg2;
signed32 temp, sum;
int v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((signed32)(signed8)(State.regs[srcreg2] & 0xff)
* (signed32)(signed8)(State.regs[srcreg1] & 0xff));
sum = State.regs[REG_MCRL] + temp;
v = ((State.regs[REG_MCRL] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRL] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0011 1011 Rm Rn; macbu Rm,Rn
8.0xf9+8.0x3b+4.RM2,4.RN0:D1:::macbu
"macbu"
*am33
*am33_2
{
int srcreg1, srcreg2;
signed64 temp, sum;
int v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((unsigned32)(State.regs[srcreg2] & 0xff)
* (unsigned32)(State.regs[srcreg1] & 0xff));
sum = State.regs[REG_MCRL] + temp;
v = ((State.regs[REG_MCRL] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRL] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0100 1011 Rm Rn; mach Rm,Rn
8.0xf9+8.0x4b+4.RM2,4.RN0:D1:::mach
"mach"
*am33
*am33_2
{
int srcreg1, srcreg2;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((unsigned64)(signed16)(State.regs[srcreg2] & 0xffff)
* (unsigned64)(signed16)(State.regs[srcreg1] & 0xffff));
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0101 1011 Rm Rn; machu Rm,Rn
8.0xf9+8.0x5b+4.RM2,4.RN0:D1:::machu
"machu"
*am33
*am33_2
{
int srcreg1, srcreg2;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((unsigned64)(State.regs[srcreg2] & 0xffff)
* (unsigned64)(State.regs[srcreg1] & 0xffff));
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0110 1011 Rm Rn; dmach Rm,Rn
8.0xf9+8.0x6b+4.RM2,4.RN0:D1:::dmach
"dmach"
*am33
*am33_2
{
int srcreg1, srcreg2;
signed32 temp, temp2, sum;
int v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((signed32)(signed16)(State.regs[srcreg2] & 0xffff)
* (signed32)(signed16)(State.regs[srcreg1] & 0xffff));
temp2 = ((signed32)(signed16)((State.regs[srcreg1] >> 16) & 0xffff)
* (signed32)(signed16)((State.regs[srcreg2] >> 16) & 0xffff));
sum = temp + temp2 + State.regs[REG_MCRL];
v = ((State.regs[REG_MCRL] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRL] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 0111 1011 Rm Rn; dmachu Rm,Rn
8.0xf9+8.0x7b+4.RM2,4.RN0:D1:::dmachu
"dmachu"
*am33
*am33_2
{
int srcreg1, srcreg2;
unsigned32 temp, temp2, sum;
int v;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
temp = ((unsigned32)(State.regs[srcreg2] & 0xffff)
* (unsigned32)(State.regs[srcreg1] & 0xffff));
temp2 = ((unsigned32)((State.regs[srcreg1] >> 16) & 0xffff)
* (unsigned32)((State.regs[srcreg2] >> 16) & 0xffff));
sum = temp + temp2 + State.regs[REG_MCRL];
v = ((State.regs[REG_MCRL] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRL] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1001 1000 1011 Rm Rn; dmulh Rm,Rn
8.0xf9+8.0x8b+4.RM2,4.RN0:D1:::dmulh
"dmulh"
*am33
*am33_2
{
int srcreg, dstreg;
signed32 temp;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = ((signed32)(signed16)(State.regs[dstreg] & 0xffff)
* (signed32)(signed16)(State.regs[srcreg] & 0xffff));
State.regs[REG_MDRQ] = temp;
temp = ((signed32)(signed16)((State.regs[dstreg] >> 16) & 0xffff)
* (signed32)(signed16)((State.regs[srcreg] >>16) & 0xffff));
State.regs[dstreg] = temp;
}
// 1111 1001 1001 1011 Rm Rn; dmulhu Rm,Rn
8.0xf9+8.0x9b+4.RM2,4.RN0:D1:::dumachu
"dmachu"
*am33
*am33_2
{
int srcreg, dstreg;
unsigned32 temp;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = ((unsigned32)(State.regs[dstreg] & 0xffff)
* (unsigned32)(State.regs[srcreg] & 0xffff));
State.regs[REG_MDRQ] = temp;
temp = ((unsigned32)((State.regs[dstreg] >> 16) & 0xffff)
* (unsigned32)((State.regs[srcreg] >>16) & 0xffff));
State.regs[dstreg] = temp;
}
// 1111 1001 1010 1011 Rm Rn; sat16 Rm,Rn
8.0xf9+8.0xab+4.RM2,4.RN0:D1:::sat16
"sat16"
*am33
*am33_2
{
int srcreg, dstreg;
int value, z, n;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
value = State.regs[srcreg];
if (value >= 0x7fff)
State.regs[dstreg] = 0x7fff;
else if (value <= 0xffff8000)
State.regs[dstreg] = 0xffff8000;
else
State.regs[dstreg] = value;
n = (State.regs[dstreg] & 0x8000) != 0;
z = (State.regs[dstreg] == 0);
PSW &= ~(PSW_Z | PSW_N);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1001 1011 1011 Rm Rn; mcste Rm,Rn
8.0xf9+8.0xbb+4.RM2,4.RN0:D1:::mcste
"mcste"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
PSW &= ~(PSW_V | PSW_C);
PSW |= (State.regs[REG_MCVF] ? PSW_V : 0);
/* 32bit saturation. */
if (State.regs[srcreg] == 0x20)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7fffffff)
State.regs[dstreg] = 0x7fffffff;
else if (tmp < 0xffffffff80000000LL)
State.regs[dstreg] = 0x80000000;
else
State.regs[dstreg] = tmp;
}
/* 16bit saturation */
else if (State.regs[srcreg] == 0x10)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7fff)
State.regs[dstreg] = 0x7fff;
else if (tmp < 0xffffffffffff8000LL)
State.regs[dstreg] = 0x8000;
else
State.regs[dstreg] = tmp;
}
/* 8 bit saturation */
else if (State.regs[srcreg] == 0x8)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7f)
State.regs[dstreg] = 0x7f;
else if (tmp < 0xffffffffffffff80LL)
State.regs[dstreg] = 0x80;
else
State.regs[dstreg] = tmp;
}
/* 9 bit saturation */
else if (State.regs[srcreg] == 0x9)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x80)
State.regs[dstreg] = 0x80;
else if (tmp < 0xffffffffffffff81LL)
State.regs[dstreg] = 0x81;
else
State.regs[dstreg] = tmp;
}
/* 9 bit saturation */
else if (State.regs[srcreg] == 0x30)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7fffffffffffLL)
tmp = 0x7fffffffffffLL;
else if (tmp < 0xffff800000000000LL)
tmp = 0xffff800000000000LL;
tmp >>= 16;
State.regs[dstreg] = tmp;
}
}
// 1111 1001 1100 1011 Rm Rn; swap Rm,Rn
8.0xf9+8.0xcb+4.RM2,4.RN0:D1:::swap
"swap"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = (((State.regs[srcreg] & 0xff) << 24)
| (((State.regs[srcreg] >> 8) & 0xff) << 16)
| (((State.regs[srcreg] >> 16) & 0xff) << 8)
| ((State.regs[srcreg] >> 24) & 0xff));
}
// 1111 1101 1101 1011 Rm Rn; swaph Rm,Rn
8.0xf9+8.0xdb+4.RM2,4.RN0:D1:::swaph
"swaph"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = (((State.regs[srcreg] & 0xff) << 8)
| ((State.regs[srcreg] >> 8) & 0xff)
| (((State.regs[srcreg] >> 16) & 0xff) << 24)
| (((State.regs[srcreg] >> 24) & 0xff) << 16));
}
// 1111 1001 1110 1011 Rm Rn; swhw Rm,Rn
8.0xf9+8.0xeb+4.RM2,4.RN0:D1:::swhw
"swhw"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = (((State.regs[srcreg] & 0xffff) << 16)
| ((State.regs[srcreg] >> 16) & 0xffff));
}
// 1111 1001 1111 1011 Rm Rn; bsch Rm,Rn
8.0xf9+8.0xfb+4.RM2,4.RN0:D1:::bsch
"bsch"
*am33
*am33_2
{
int temp, c, i;
int srcreg, dstreg;
int start;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
temp = State.regs[srcreg];
start = (State.regs[dstreg] & 0x1f) - 1;
if (start == -1)
start = 31;
c = 0;
for (i = start; i >= 0; i--)
{
if (temp & (1 << i))
{
c = 1;
State.regs[dstreg] = i;
break;
}
}
if (i < 0)
{
c = 0;
State.regs[dstreg] = 0;
}
PSW &= ~(PSW_C);
PSW |= (c ? PSW_C : 0);
}
// 1111 1011 0000 1000 Rn Rn IMM8; mov IMM8,Rn
8.0xfb+8.0x08+4.RM2,4.RN0=RM2+8.IMM8:D2j:::mov
"mov"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = EXTEND8 (IMM8);
}
// 1111 1011 0001 1000 Rn Rn IMM8; movu IMM8,Rn
8.0xfb+8.0x18+4.RM2,4.RN0=RM2+8.IMM8:D2:::movu
"movu"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] = IMM8 & 0xff;
}
// 1111 1011 0111 1000 Rn Rn IMM8; add IMM8,Rn
8.0xfb+8.0x78+4.RM2,4.RN0=RM2+8.IMM8:D2d:::add
"add"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
genericAdd (EXTEND8 (IMM8), dstreg);
}
// 1111 1011 1000 1000 Rn Rn IMM8; addc IMM8,Rn
8.0xfb+8.0x88+4.RM2,4.RN0=RM2+8.IMM8:D2d:::addc
"addc"
*am33
*am33_2
{
int dstreg, imm;
int z, c, n, v;
unsigned32 reg2, sum;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
imm = EXTEND8 (IMM8);
reg2 = State.regs[dstreg];
sum = imm + reg2 + ((PSW & PSW_C) != 0);
State.regs[dstreg] = sum;
z = ((PSW & PSW_Z) != 0) && (sum == 0);
n = (sum & 0x80000000);
c = (sum < imm) || (sum < reg2);
v = ((reg2 & 0x80000000) == (imm & 0x80000000)
&& (reg2 & 0x80000000) != (sum & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1011 1001 1000 Rn Rn IMM8; sub IMM8,Rn
8.0xfb+8.0x98+4.RM2,4.RN0=RM2+8.IMM8:D2d:::sub
"sub"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
genericSub (EXTEND8 (IMM8), dstreg);
}
// 1111 1011 1010 1000 Rn Rn IMM8; subc IMM8,Rn
8.0xfb+8.0xa8+4.RM2,4.RN0=RM2+8.IMM8:D2d:::subc
"subc"
*am33
*am33_2
{
int imm, dstreg;
int z, c, n, v;
unsigned32 reg2, difference;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
imm = EXTEND8 (IMM8);
reg2 = State.regs[dstreg];
difference = reg2 - imm - ((PSW & PSW_C) != 0);
State.regs[dstreg] = difference;
z = ((PSW & PSW_Z) != 0) && (difference == 0);
n = (difference & 0x80000000);
c = (imm > reg2);
v = ((reg2 & 0x80000000) == (imm & 0x80000000)
&& (reg2 & 0x80000000) != (difference & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1011 1101 1000 Rn Rn IMM8; cmp IMM8,Rn
8.0xfb+8.0xd8+4.RM2,4.RN0=RM2+8.IMM8:D2b:::cmp
"cmp"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RN0);
genericCmp (EXTEND8 (IMM8), State.regs[srcreg]);
}
// 1111 1011 1111 1000 XRn XRn IMM8; mov IMM8,XRn
8.0xfb+8.0xf8+4.XRM2,4.XRN0=XRM2+8.IMM8:D2k:::mov
"mov"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_xreg (SD_, XRN0);
State.regs[dstreg] = IMM8;
}
// 1111 1011 0000 1001 Rn Rn IMM8; and IMM8,Rn
8.0xfb+8.0x09+4.RM2,4.RN0=RM2+8.IMM8:D2d:::and
"and"
*am33
*am33_2
{
int dstreg;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] &= (IMM8 & 0xff);
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1011 0001 1001 Rn Rn IMM8; or IMM8,Rn
8.0xfb+8.0x19+4.RM2,4.RN0=RM2+8.IMM8:D2d:::or
"or"
*am33
*am33_2
{
int dstreg;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] |= (IMM8 & 0xff);
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1011 0010 1001 Rn Rn IMM8; xor IMM8,Rn
8.0xfb+8.0x29+4.RM2,4.RN0=RM2+8.IMM8:D2d:::xor
"xor"
*am33
*am33_2
{
int dstreg;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] ^= (IMM8 & 0xff);
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1011 0100 1001 Rn Rn IMM8; asr IMM8,Rn
8.0xfb+8.0x49+4.RM2,4.RN0=RM2+8.IMM8:D2a:::asr
"asr"
*am33
*am33_2
{
int dstreg;
signed32 temp;
int c, z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
temp = State.regs[dstreg];
c = temp & 1;
temp >>= (IMM8 & 0xff);
State.regs[dstreg] = temp;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0));
}
// 1111 1011 0101 1001 Rn Rn IMM8; lsr IMM8,Rn
8.0xfb+8.0x59+4.RM2,4.RN0=RM2+8.IMM8:D2a:::lsr
"lsr"
*am33
*am33_2
{
int dstreg;
int z, n, c;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
c = State.regs[dstreg] & 1;
State.regs[dstreg] >>= (IMM8 & 0xff);
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0) | (c ? PSW_C : 0));
}
// 1111 1011 0110 1001 Rn Rn IMM8; asl IMM8,Rn
8.0xfb+8.0x69+4.RM2,4.RN0=RM2+8.IMM8:D2a:::asl
"asl"
*am33
*am33_2
{
int dstreg;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
State.regs[dstreg] <<= (IMM8 & 0xff);
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1011 1010 1001 Rn Rn IMM8; mul IMM8,Rn
8.0xfb+8.0xa9+4.RM2,4.RN0=RM2+8.IMM8:D2a:::mul
"mul"
*am33
*am33_2
{
int dstreg;
unsigned64 temp;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
temp = ((signed64)(signed32)State.regs[dstreg]
* (signed64)(signed32)EXTEND8 (IMM8));
State.regs[dstreg] = temp & 0xffffffff;
State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1011 1011 1001 Rn Rn IMM8; mulu IMM8,Rn
8.0xfb+8.0xb9+4.RM2,4.RN0=RM2+8.IMM8:D2a:::mulu
"mulu"
*am33
*am33_2
{
int dstreg;
unsigned64 temp;
int z, n;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
temp = ((unsigned64)State.regs[dstreg]
* (unsigned64)(IMM8 & 0xff));
State.regs[dstreg] = temp & 0xffffffff;
State.regs[REG_MDR] = (temp & 0xffffffff00000000LL) >> 32;
z = (State.regs[dstreg] == 0);
n = (State.regs[dstreg] & 0x80000000) != 0;
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
}
// 1111 1011 1110 1001 Rn Rn IMM8; btst imm8,Rn
8.0xfb+8.0xe9+4.RN2,4.RM0=RN2+8.IMM8:D2l:::btst
"btst"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
genericBtst(IMM8, State.regs[srcreg]);
}
// 1111 1011 0000 1010 Rn Rm IMM8; mov (d8,Rm),Rn
8.0xfb+8.0x0a+4.RN2,4.RM0+8.IMM8:D2l:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_word (State.regs[srcreg] + EXTEND8 (IMM8));
}
// 1111 1011 0001 1010 Rn Rm IMM8; mov Rm,(d8,Rn)
8.0xfb+8.0x1a+4.RM2,4.RN0+8.IMM8:D2m:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_word (State.regs[dstreg] + EXTEND8 (IMM8), State.regs[srcreg]);
}
// 1111 1011 0010 1010 Rn Rm IMM8; movbu (d8,Rm),Rn
8.0xfb+8.0x2a+4.RN2,4.RM0+8.IMM8:D2l:::movbu
"movbu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_byte (State.regs[srcreg] + EXTEND8 (IMM8));
}
// 1111 1011 0011 1010 Rn Rm IMM8; movbu Rm,(d8,Rn)
8.0xfb+8.0x3a+4.RM2,4.RN0+8.IMM8:D2m:::movbu
"movbu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_byte (State.regs[dstreg] + EXTEND8 (IMM8), State.regs[srcreg]);
}
// 1111 1011 0100 1010 Rn Rm IMM8; movhu (d8,Rm),Rn
8.0xfb+8.0x4a+4.RN2,4.RM0+8.IMM8:D2l:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_half (State.regs[srcreg] + EXTEND8 (IMM8));
}
// 1111 1011 0101 1010 Rn Rm IMM8; movhu Rm,(d8,Rn)
8.0xfb+8.0x5a+4.RM2,4.RN0+8.IMM8:D2m:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_half (State.regs[dstreg] + EXTEND8 (IMM8), State.regs[srcreg]);
}
// 1111 1011 0110 1010 Rn Rm IMM8; mov (d8,Rm+),Rn
8.0xfb+8.0x6a+4.RN2,4.RM0!RN2+8.IMM8:D2y:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_word (State.regs[srcreg]);
State.regs[srcreg] += EXTEND8 (IMM8);
}
// 1111 1011 0111 1010 Rn Rm IMM8; mov Rm,(d8,Rn+)
8.0xfb+8.0x7a+4.RM2,4.RN0+8.IMM8:D2z:::mov
"mov"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_word (State.regs[dstreg], State.regs[srcreg]);
State.regs[dstreg] += EXTEND8 (IMM8);
}
// 1111 1011 1000 1010 Rn 0000 IMM8; mov (d8,sp),Rn
8.0xfb+8.0x8a+4.RN2,4.0x0+8.IMM8:D2n:::mov
"mov"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_word (State.regs[REG_SP] + IMM8);
}
// 1111 1011 1001 1010 Rm 0000 IMM8; mov Rm,(d8,sp)
8.0xfb+8.0x9a+4.RM2,4.0x0+8.IMM8:D2o:::mov
"mov"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
store_word (State.regs[REG_SP] + IMM8, State.regs[srcreg]);
}
// 1111 1011 1010 1010 Rn Rm IMM8; movbu (d8,sp),Rn
8.0xfb+8.0xaa+4.RN2,4.0x0+8.IMM8:D2n:::movbu
"movbu"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_byte (State.regs[REG_SP] + IMM8);
}
// 1111 1011 1011 1010 Rn Rm IMM8; movbu Rm,(d8,sp)
8.0xfb+8.0xba+4.RM2,4.0x0+8.IMM8:D2o:::movbu
"movbu"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
store_byte (State.regs[REG_SP] + IMM8, State.regs[srcreg]);
}
// 1111 1011 1100 1010 Rn Rm IMM8; movhu (d8,sp),Rn
8.0xfb+8.0xca+4.RN2,4.0x0+8.IMM8:D2n:::movhu
"movhu"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_half (State.regs[REG_SP] + IMM8);
}
// 1111 1011 1101 1010 Rn Rm IMM8; movhu Rm,(d8,sp)
8.0xfb+8.0xda+4.RM2,4.0x0+8.IMM8:D2o:::movhu
"movhu"
*am33
*am33_2
{
int srcreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
store_half (State.regs[REG_SP] + IMM8, State.regs[srcreg]);
}
// 1111 1011 1110 1010 Rn Rm IMM8; movhu (d8,Rm+),Rn
8.0xfb+8.0xea+4.RN2,4.RM0!RN2+8.IMM8:D2y:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM0);
dstreg = translate_rreg (SD_, RN2);
State.regs[dstreg] = load_half (State.regs[srcreg]);
State.regs[srcreg] += EXTEND8 (IMM8);
}
// 1111 1011 1111 1010 Rn Rm IMM8; movhu Rm,(d8,Rn+)
8.0xfb+8.0xfa+4.RM2,4.RN0+8.IMM8:D2z:::movhu
"movhu"
*am33
*am33_2
{
int srcreg, dstreg;
PC = cia;
srcreg = translate_rreg (SD_, RM2);
dstreg = translate_rreg (SD_, RN0);
store_half (State.regs[dstreg], State.regs[srcreg]);
State.regs[dstreg] += EXTEND8 (IMM8);
}
// 1111 1011 0000 1011 Rn Rn IMM8; mac imm8,Rn
8.0xfb+8.0x0b+4.RN2,4.RN0=RN2+8.IMM8:D2:::mac
"mac"
*am33
*am33_2
{
int srcreg;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg = translate_rreg (SD_, RN2);
temp = ((signed64)(signed32)EXTEND8 (IMM8)
* (signed64)(signed32)State.regs[srcreg]);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1011 0001 1011 Rn Rn IMM8; macu imm8,Rn
8.0xfb+8.0x1b+4.RN2,4.RN0=RN2+8.IMM8:D2:::macu
"macu"
*am33
*am33_2
{
int srcreg;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg = translate_rreg (SD_, RN2);
temp = ((unsigned64) (IMM8)
* (unsigned64)State.regs[srcreg]);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1011 0010 1011 Rn Rn IMM8; macb imm8,Rn
8.0xfb+8.0x2b+4.RN2,4.RN0=RN2+8.IMM8:D2:::macb
"macb"
*am33
*am33_2
{
int srcreg;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg = translate_rreg (SD_, RN2);
temp = ((signed64)(signed8)EXTEND8 (IMM8)
* (signed64)(signed8)State.regs[srcreg] & 0xff);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1011 0011 1011 Rn Rn IMM8; macbu imm8,Rn
8.0xfb+8.0x3b+4.RN2,4.RN0=RN2+8.IMM8:D2:::macbu
"macbu"
*am33
*am33_2
{
int srcreg;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg = translate_rreg (SD_, RN2);
temp = ((unsigned64) (IMM8)
* (unsigned64)State.regs[srcreg] & 0xff);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1011 0100 1011 Rn Rn IMM8; mach imm8,Rn
8.0xfb+8.0x4b+4.RN2,4.RN0=RN2+8.IMM8:D2:::mach
"mach"
*am33
*am33_2
{
int srcreg;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg = translate_rreg (SD_, RN2);
temp = ((signed64)(signed16)EXTEND8 (IMM8)
* (signed64)(signed16)State.regs[srcreg] & 0xffff);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1011 0101 1011 Rn Rn IMM8; machu imm8,Rn
8.0xfb+8.0x5b+4.RN2,4.RN0=RN2+8.IMM8:D2:::machu
"machu"
*am33
*am33_2
{
int srcreg;
signed64 temp, sum;
int c, v;
PC = cia;
srcreg = translate_rreg (SD_, RN2);
temp = ((unsigned64) (IMM8)
* (unsigned64)State.regs[srcreg] & 0xffff);
sum = State.regs[REG_MCRL] + (temp & 0xffffffff);
c = (sum < State.regs[REG_MCRL]) || (sum < (temp & 0xffffffff));
State.regs[REG_MCRL] = sum;
temp >>= 32;
temp &= 0xffffffff;
sum = State.regs[REG_MCRH] + temp + c;
v = ((State.regs[REG_MCRH] & 0x80000000) == (temp & 0x80000000)
&& (temp & 0x80000000) != (sum & 0x80000000));
State.regs[REG_MCRH] = sum;
if (v)
State.regs[REG_MCVF] = 1;
}
// 1111 1011 1011 1011 Rn Rn IMM8; mcste imm8,Rn
8.0xfb+8.0xbb+4.RN2,4.RN0=RN2+8.IMM8:D2:::mcste
"mcste"
*am33
*am33_2
{
int dstreg;
PC = cia;
dstreg = translate_rreg (SD_, RN0);
PSW &= ~(PSW_V | PSW_C);
PSW |= (State.regs[REG_MCVF] ? PSW_V : 0);
/* 32bit saturation. */
if (IMM8 == 0x20)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7fffffff)
State.regs[dstreg] = 0x7fffffff;
else if (tmp < 0xffffffff80000000LL)
State.regs[dstreg] = 0x80000000;
else
State.regs[dstreg] = tmp;
}
/* 16bit saturation */
else if (IMM8 == 0x10)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7fff)
State.regs[dstreg] = 0x7fff;
else if (tmp < 0xffffffffffff8000LL)
State.regs[dstreg] = 0x8000;
else
State.regs[dstreg] = tmp;
}
/* 8 bit saturation */
else if (IMM8 == 0x8)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7f)
State.regs[dstreg] = 0x7f;
else if (tmp < 0xffffffffffffff80LL)
State.regs[dstreg] = 0x80;
else
State.regs[dstreg] = tmp;
}
/* 9 bit saturation */
else if (IMM8 == 0x9)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x80)
State.regs[dstreg] = 0x80;
else if (tmp < 0xffffffffffffff81LL)
State.regs[dstreg] = 0x81;
else
State.regs[dstreg] = tmp;
}
/* 9 bit saturation */
else if (IMM8 == 0x30)
{
signed64 tmp;
tmp = State.regs[REG_MCRH];
tmp <<= 32;
tmp += State.regs[REG_MCRL];
if (tmp > 0x7fffffffffffLL)
tmp = 0x7fffffffffffLL;
else if (tmp < 0xffff800000000000LL)
tmp = 0xffff800000000000LL;
tmp >>= 16;
State.regs[dstreg] = tmp;
}
}
// 1111 1011 0111 1100 Rm Rn Rd; add Rm,Rn,Rd
8.0xfb+8.0x7c+4.RM2,4.RN0+4.RD0,4.0x0:D2c:::add
"add"
*am33
*am33_2
{
int z, c, n, v;
unsigned32 sum, source1, source2;
int srcreg1, srcreg2, dstreg;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
dstreg = translate_rreg (SD_, RD0);
source1 = State.regs[srcreg1];
source2 = State.regs[srcreg2];
sum = source1 + source2;
State.regs[dstreg] = sum;
z = (sum == 0);
n = (sum & 0x80000000);
c = (sum < source1) || (sum < source2);
v = ((source1 & 0x80000000) == (source2 & 0x80000000)
&& (source1 & 0x80000000) != (sum & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1011 1000 1100 Rm Rn Rd; addc Rm,Rn,Rd
8.0xfb+8.0x8c+4.RM2,4.RN0+4.RD0,4.0x0:D2c:::addc
"addc"
*am33
*am33_2
{
int z, c, n, v;
unsigned32 sum, source1, source2;
int srcreg1, srcreg2, dstreg;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
dstreg = translate_rreg (SD_, RD0);
source1 = State.regs[srcreg1];
source2 = State.regs[srcreg2];
sum = source1 + source2 + ((PSW & PSW_C) != 0);
State.regs[dstreg] = sum;
z = ((PSW & PSW_Z) != 0) && (sum == 0);
n = (sum & 0x80000000);
c = (sum < source1) || (sum < source2);
v = ((source1 & 0x80000000) == (source2 & 0x80000000)
&& (source1 & 0x80000000) != (sum & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1011 1001 1100 Rm Rn Rd; sub Rm,Rn,Rd
8.0xfb+8.0x9c+4.RM2,4.RN0+4.RD0,4.0x0:D2c:::sub
"sub"
*am33
*am33_2
{
int z, c, n, v;
unsigned32 difference, source1, source2;
int srcreg1, srcreg2, dstreg;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
dstreg = translate_rreg (SD_, RD0);
source1 = State.regs[srcreg1];
source2 = State.regs[srcreg2];
difference = source2 - source1;
State.regs[dstreg] = difference;
z = (difference == 0);
n = (difference & 0x80000000);
c = (source1 > source2);
v = ((source1 & 0x80000000) == (source2 & 0x80000000)
&& (source1 & 0x80000000) != (difference & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1011 1010 1100 Rm Rn Rd; subc Rm,Rn,Rd
8.0xfb+8.0xac+4.RM2,4.RN0+4.RD0,4.0x0:D2c:::subc
"subc"
*am33
*am33_2
{
int z, c, n, v;
unsigned32 difference, source1, source2;
int srcreg1, srcreg2, dstreg;
PC = cia;
srcreg1 = translate_rreg (SD_, RM2);
srcreg2 = translate_rreg (SD_, RN0);
dstreg = translate_rreg (SD_, RD0);
source1 = State.regs[srcreg1];
source2 = State.regs[srcreg2];
difference = source2 - source1 - ((PSW & PSW_C) != 0);
State.regs[dstreg] = difference;
z = ((PSW & PSW_Z) != 0) && (difference == 0);
n = (difference & 0x80000000);
c = (source1 > source2);
v = ((source1 & 0x80000000) == (source2 & 0x80000000)
&& (source1 & 0x80000000) != (difference & 0x80000000));
PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
| (c ? PSW_C : 0) | (v ? PSW_V : 0));
}
// 1111 1011 0000 1101 Rm Rn Rd; and Rm,Rn,Rd
8.0xfb+