Add Types 12, 14, 16, 19, 21a, 29, 32, 34, 35 decode

- Type 12: Shift with DM/PM memory access
- Type 14: Shift with Dreg move
- Type 16: Conditional shift
- Type 29: DM/PM read/write with immediate modify
- Type 32: Any Reg <-> DM/PM with DAG postmodify
- Type 34: IO register read/write (both directions)
- Type 35: System control register read/write (both directions)
- Type 21a: MODIFY with immediate offset
- Fix: Move Type 34/35 from b23_22==1 block to b23_22==0
- Fix: Type 12 prefix corrected to bits 23-17 = 0001001
- Zero compiler warnings (except unused xop_shift, now used)
- Full regression test: all 48 isa_test.bin instructions pass
This commit is contained in:
Dr. Christian Giessen
2026-04-22 19:37:27 +00:00
parent 62b9363c13
commit aa486f09b0
2 changed files with 148 additions and 2 deletions

View File

@@ -170,8 +170,7 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
{
if (b21_20 == 0) { op->mnemonic = r_str_newf ("%s = 0x%04X", reg0[ins&0xF], (ins>>4)&0xFFFF); return true; } /* Type 6 */
if (b21_20 == 1) { op->mnemonic = r_str_newf ("%s = 0x%04X", reg1[ins&0xF], (ins>>4)&0xFFFF); return true; } /* Type 7 */
if ((ins >> 16) == 0x6D) { op->mnemonic = r_str_newf ("IO(0x%X) = %s", (ins>>4)&0xFF, reg0[ins&0xF]); return true; } /* Type 34 */
if ((ins >> 16) == 0x6C) { op->mnemonic = r_str_newf ("REG(0x%X) = %s", (ins>>4)&0xFF, reg0[ins&0xF]); return true; } /* Type 35 */
/* Type 34 and 35 are in the b23_22==0 block below */
}
/* Type 8/9/10/11/17... (00xxxx) */
@@ -237,6 +236,59 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
return true;
}
/* Type 12: Shift | DM/PM (bits 23-17 = 0001001) */
if ((ins >> 17) == 0x09)
{
ut32 g = (ins >> 16) & 1;
ut32 sf = (ins >> 13) & 0x7;
ut32 d = (ins >> 12) & 1;
ut32 xop_i = (ins >> 9) & 0x7;
ut32 dreg = (ins >> 4) & 0xF;
ut32 ireg = (ins >> 2) & 0x3;
ut32 mreg = ins & 0x3;
int base = g ? 4 : 0;
if (d)
op->mnemonic = r_str_newf ("%s %s, %cM(I%d += M%d) = %s",
sf_names[sf], xop_shift[xop_i],
g ? 'P' : 'D', ireg + base, mreg + base,
reg0[dreg]);
else
op->mnemonic = r_str_newf ("%s %s, %s = %cM(I%d += M%d)",
sf_names[sf], xop_shift[xop_i],
reg0[dreg],
g ? 'P' : 'D', ireg + base, mreg + base);
return true;
}
/* Type 14: Shift | Dreg move (bits 23-16 = 00010100) */
if ((ins >> 16) == 0x14)
{
ut32 sf = (ins >> 12) & 0x7;
ut32 xreg = (ins >> 9) & 0x7;
ut32 ddreg = (ins >> 4) & 0xF;
ut32 sdreg = ins & 0xF;
op->mnemonic = r_str_newf ("%s %s, %s = %s",
sf_names[sf], xop_shift[xreg],
reg0[ddreg], reg0[sdreg]);
return true;
}
/* Type 16: Conditional Shift (bits 23-16 = 00001110) */
if ((ins >> 16) == 0x0E)
{
ut32 sf = (ins >> 12) & 0xF;
ut32 xreg = (ins >> 8) & 0x7;
ut32 cond = ins & 0xF;
if (cond == 15)
op->mnemonic = r_str_newf ("SR = %s %s",
sf_names[sf], xop_shift[xreg]);
else
op->mnemonic = r_str_newf ("IF %s SR = %s %s",
cond_str[cond], sf_names[sf],
xop_shift[xreg]);
return true;
}
/* Type 11: DO UNTIL (bits 23-16 = 00010110) */
if ((ins >> 16) == 0x16)
{
@@ -400,6 +452,100 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
return true;
}
/* Type 29: Dreg <-> DM imm modify (bits 23-18 = 000010) */
if ((ins >> 18) == 0x02)
{
ut32 u = (ins >> 16) & 1;
ut32 dru = (ins >> 14) & 0x3;
ut32 g = (ins >> 13) & 1;
ut32 d = (ins >> 12) & 1;
ut32 mod = (ins >> 4) & 0xFF;
ut32 ireg = (ins >> 2) & 0x3;
ut32 drl = ins & 0x3;
ut32 dreg = (dru << 2) | drl;
int8_t smod = (int8_t) mod;
int base = g ? 4 : 0;
const char *mem = g ? "PM" : "DM";
const char *op_str = u ? "+=" : "+";
if (d)
op->mnemonic = r_str_newf ("%s(I%d %s %d) = %s",
mem, ireg + base, op_str, smod,
reg0[dreg]);
else
op->mnemonic = r_str_newf ("%s = %s(I%d %s %d)",
reg0[dreg], mem, ireg + base, op_str,
smod);
return true;
}
/* Type 32: Any Reg <-> DM/PM (bits 23-17 = 0001010, bit11=0) */
if ((ins >> 17) == 0x0A && !((ins >> 11) & 1))
{
ut32 ms = (ins >> 15) & 1;
ut32 u_bit = (ins >> 14) & 1;
ut32 g = (ins >> 13) & 1;
ut32 d = (ins >> 12) & 1;
ut32 rgp = (ins >> 8) & 0x3;
ut32 reg = (ins >> 4) & 0xF;
ut32 ireg = (ins >> 2) & 0x3;
ut32 mreg = ins & 0x3;
int base = g ? 4 : 0;
const char *mem = (ms || g) ? "PM" : "DM";
const char *mod = u_bit ? "+=" : "+";
const char *rname = get_reg (rgp, reg);
if (d)
op->mnemonic = r_str_newf ("%s(I%d %s M%d) = %s",
mem, ireg + base, mod, mreg + base,
rname);
else
op->mnemonic = r_str_newf ("%s = %s(I%d %s M%d)",
rname, mem, ireg + base, mod,
mreg + base);
return true;
}
/* Type 21a: MODIFY imm (bits 23-16 = 00000001, bit15=0) */
if ((ins >> 16) == 0x01 && !((ins >> 15) & 1))
{
ut32 g = (ins >> 12) & 1;
ut32 ireg = ins & 0x3;
int8_t mod = (int8_t)((ins >> 4) & 0xFF);
int base = g ? 4 : 0;
op->mnemonic = r_str_newf ("MODIFY(I%d += %d)",
ireg + base, mod);
return true;
}
/* Type 34: IO reg (bits 23-16 = 00000110, bit15=1) */
if ((ins >> 16) == 0x06 && ((ins >> 15) & 1))
{
ut32 d = (ins >> 12) & 1;
ut32 addr_hi = (ins >> 13) & 0x3;
ut32 addr = (addr_hi << 8) | ((ins >> 4) & 0xFF);
ut32 dreg = ins & 0xF;
if (d)
op->mnemonic = r_str_newf ("IO(0x%03X) = %s",
addr, reg0[dreg]);
else
op->mnemonic = r_str_newf ("%s = IO(0x%03X)",
reg0[dreg], addr);
return true;
}
/* Type 35: Sys ctrl reg (bits 23-16 = 00000110, bit15=0) */
if ((ins >> 16) == 0x06 && !((ins >> 15) & 1))
{
ut32 d = (ins >> 12) & 1;
ut32 addr = (ins >> 4) & 0xFF;
ut32 dreg = ins & 0xF;
if (d)
op->mnemonic = r_str_newf ("REG(0x%02X) = %s",
addr, reg0[dreg]);
else
op->mnemonic = r_str_newf ("%s = REG(0x%02X)",
reg0[dreg], addr);
return true;
}
/* Type 37: SETINT/CLRINT (bits 23-15 = 000001110) */
if ((ins >> 15) == 0x0E)
{