Add 2-word instruction decode: Types 22, 22a, 32a, 36

- Type 22: DM/PM = Data16 (2-word immediate data write)
- Type 22a: PM = Data24 (2-word 24-bit data write)
- Type 32a: DAG register store with register transfer
- Type 36: LJUMP/LCALL (2-word long jump/call, 24-bit address)
- op->size = 6 for all 2-word instructions
- Zero compiler warnings
- Full regression: all 48 isa_test.bin instructions unchanged
This commit is contained in:
Dr. Christian Giessen
2026-04-22 19:41:07 +00:00
parent aa486f09b0
commit 13521048bc
2 changed files with 76 additions and 1 deletions

View File

@@ -59,11 +59,13 @@ get_reg (int gp, int idx)
static bool
decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
{
ut32 ins;
ut32 ins, ins2 = 0;
const ut8 *b = op->bytes;
if (op->size < 3) return false;
ins = ((ut32) b[0] << 16) | ((ut32) b[1] << 8) | (ut32) b[2];
if (op->size >= 6)
ins2 = ((ut32) b[3] << 16) | ((ut32) b[4] << 8) | (ut32) b[5];
op->size = 3;
op->type = R_ANAL_OP_TYPE_UNK;
if (!(mask & R_ARCH_OP_MASK_DISASM)) return true;
@@ -177,6 +179,60 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
if (b23_22 == 0)
{
if (b21_20 == 3) { op->mnemonic = r_str_newf ("%s = 0x%04X", reg2[ins&0xF], (ins>>4)&0xFFFF); return true; } /* Type 7 (Reg2) */
/* Type 36: Long Jump/Call (2-word, bits 23-16 = 00000101) */
if ((ins >> 16) == 0x05)
{
ut32 s_bit = (ins >> 12) & 1;
ut32 cond = ins & 0xF;
ut32 addr_hi = (ins >> 4) & 0xFF;
ut32 addr_lo = ins2 & 0xFFFFFF;
ut32 addr = (addr_hi << 16) | (addr_lo & 0xFFFF);
op->size = 6;
if (cond == 15)
op->mnemonic = r_str_newf ("%s 0x%06X",
s_bit ? "LCALL" : "LJUMP", addr);
else
op->mnemonic = r_str_newf ("IF %s %s 0x%06X",
cond_str[cond],
s_bit ? "LCALL" : "LJUMP", addr);
op->type = s_bit ? R_ANAL_OP_TYPE_CALL
: R_ANAL_OP_TYPE_JMP;
return true;
}
/* Type 22: DM/PM = Data16 (2-word, bits 23-13 = 00000011110) */
if ((ins >> 13) == 0x1E && !((ins >> 12) & 1))
{
ut32 g = (ins >> 12) & 1;
ut32 ireg = (ins >> 2) & 0x3;
ut32 mreg = ins & 0x3;
ut32 data_lo = (ins >> 4) & 0xFF;
ut32 data_hi = (ins2 >> 16) & 0xFF;
ut32 data = (data_hi << 8) | data_lo;
int base = g ? 4 : 0;
op->size = 6;
op->mnemonic = r_str_newf ("%cM(I%d += M%d) = 0x%04X",
g ? 'P' : 'D', ireg + base, mreg + base, data);
return true;
}
/* Type 22a: PM = Data24 (2-word, bits 23-13 = 00000011111) */
if ((ins >> 13) == 0x1F)
{
ut32 g = (ins >> 12) & 1;
ut32 ireg = (ins >> 2) & 0x3;
ut32 mreg = ins & 0x3;
ut32 data_mid = (ins >> 4) & 0xFF;
ut32 data_hi = (ins2 >> 16) & 0xFF;
ut32 data_lo = (ins2 >> 8) & 0xFF;
ut32 data = (data_hi << 16) | (data_mid << 8) | data_lo;
int base = g ? 4 : 0;
op->size = 6;
op->mnemonic = r_str_newf ("PM(I%d += M%d) = 0x%06X:24",
ireg + base, mreg + base, data);
return true;
}
/* Type 10a: bits 23-18 = 000111 (unconditional 16-bit) */
if ((ins >> 18) == 0x07)
{
@@ -504,6 +560,25 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
return true;
}
/* Type 32a: DAG reg store + transfer (bits 23-17=0001010, bit11=1) */
if ((ins >> 17) == 0x0A && ((ins >> 11) & 1))
{
ut32 u_bit = (ins >> 14) & 1;
ut32 g = (ins >> 13) & 1;
ut32 rgp = (ins >> 8) & 0x3;
ut32 dag_reg = (ins >> 4) & 0x7;
ut32 ireg = (ins >> 2) & 0x3;
ut32 mreg = ins & 0x3;
int base = g ? 4 : 0;
const char *mod = u_bit ? "+=" : "+";
const char *rname = get_reg (rgp, dag_reg);
op->mnemonic = r_str_newf (
"DM(I%d %s M%d) = %s, %s = I%d",
ireg + base, mod, mreg + base,
rname, rname, ireg + base);
return true;
}
/* Type 21a: MODIFY imm (bits 23-16 = 00000001, bit15=0) */
if ((ins >> 16) == 0x01 && !((ins >> 15) & 1))
{