Fix Types 3, 4, 29, 32; add relative addressing; truncation guards
Type 3: Fix D-bit read/write direction (was always write). DM-only (no PM), use reg1[] for Ireg/Mreg variant. Type 4: Add D-bit for read vs write direction (was always read). Properly distinguish DM(I+=M)=Dreg vs Dreg=DM(I+=M). Type 29: G selects DAG register group, not memory bus. Always DM (was incorrectly PM when G=1). Type 32: MS selects bus (DM/PM), G selects DAG group only. (was: MS||G for bus, causing false PM on G=1 MS=0). Type 10/10a/11: Relative offsets resolved to absolute byte addresses using PC + (offset * 3). op->jump set for r2 xref analysis. Type 36: op->jump set for LJUMP/LCALL. 2-word instructions: Truncation guard when buffer < 6 bytes. Emits 'trunc ...' instead of decoding with zeroed second word. Zero warnings, full regression pass on isa_test/fir/iir.
This commit is contained in:
@@ -98,23 +98,47 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Type 3: Direct Memory (10xxxx) */
|
||||
/* Type 3: Direct Memory (10xxxx)
|
||||
bit21: 1=Ireg/Mreg, 0=Dreg. D=bit20: 0=read, 1=write.
|
||||
Addr16=bits19-4. Reg=bits3-0. DM only (no PM). */
|
||||
if (b23_22 == 2)
|
||||
{
|
||||
ut32 d = (ins >> 20) & 1, addr = (ins >> 4) & 0xFFFF, reg = ins & 0xF;
|
||||
if ((ins >> 21) & 1) /* Ireg/Mreg */
|
||||
op->mnemonic = r_str_newf ("%s(0x%04X) = %s%d", d?"DM":"DM", addr, (reg<8?"I":"M"), reg&7);
|
||||
else /* Dreg */
|
||||
op->mnemonic = r_str_newf ("%s(0x%04X) = %s", d?"DM":"DM", addr, reg0[reg]);
|
||||
ut32 d = (ins >> 20) & 1;
|
||||
ut32 addr = (ins >> 4) & 0xFFFF;
|
||||
ut32 reg = ins & 0xF;
|
||||
const char *rname = ((ins >> 21) & 1)
|
||||
? reg1[reg] : reg0[reg];
|
||||
if (d)
|
||||
op->mnemonic = r_str_newf ("DM(0x%04X) = %s",
|
||||
addr, rname);
|
||||
else
|
||||
op->mnemonic = r_str_newf ("%s = DM(0x%04X)",
|
||||
rname, addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Type 4: Compute | DM/PM Postmodify (011xxx) */
|
||||
/* Type 4: Compute | DM/PM Postmodify (011xxx)
|
||||
G=bit20 (0=DM/DAG1, 1=PM/DAG2), D=bit19 (0=read, 1=write),
|
||||
Z=bit18, AMF=bits17-13, YOP=bits12-11, XOP=bits10-8,
|
||||
DREG=bits7-4, I=bits3-2, M=bits1-0. */
|
||||
if ((ins >> 21) == 0x3)
|
||||
{
|
||||
ut32 g = (ins >> 20) & 1, amf = (ins >> 13) & 0x1F;
|
||||
const char *f = (amf < 16) ? amf_mac[amf] : amf_alu[amf-16];
|
||||
op->mnemonic = r_str_newf ("%s, %s = %cM(I%d += M%d)", f, reg0[(ins>>4)&0xF], g?'P':'D', ((ins>>2)&3)|(g?4:0), (ins&3)|(g?4:0));
|
||||
ut32 g = (ins >> 20) & 1;
|
||||
ut32 d = (ins >> 19) & 1;
|
||||
ut32 amf = (ins >> 13) & 0x1F;
|
||||
const char *f = (amf < 16) ? amf_mac[amf] : amf_alu[amf - 16];
|
||||
ut32 dreg = (ins >> 4) & 0xF;
|
||||
ut32 ireg = ((ins >> 2) & 3) | (g ? 4 : 0);
|
||||
ut32 mreg = (ins & 3) | (g ? 4 : 0);
|
||||
char mem = g ? 'P' : 'D';
|
||||
if (d)
|
||||
op->mnemonic = r_str_newf ("%s, %cM(I%d += M%d) = %s",
|
||||
f, mem, ireg, mreg,
|
||||
reg0[dreg]);
|
||||
else
|
||||
op->mnemonic = r_str_newf ("%s, %s = %cM(I%d += M%d)",
|
||||
f, reg0[dreg], mem,
|
||||
ireg, mreg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -208,11 +232,18 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
/* Type 36: Long Jump/Call (2-word, bits 23-16 = 00000101) */
|
||||
if ((ins >> 16) == 0x05)
|
||||
{
|
||||
if (op->size < 6)
|
||||
{
|
||||
op->mnemonic = r_str_newf ("trunc L%s 0x%06X",
|
||||
((ins >> 12) & 1) ? "CALL" : "JUMP", ins);
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
/* 24-bit absolute address for long jump/call */
|
||||
op->size = 6;
|
||||
if (cond == 15)
|
||||
op->mnemonic = r_str_newf ("%s 0x%06X",
|
||||
@@ -223,12 +254,19 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
s_bit ? "LCALL" : "LJUMP", addr);
|
||||
op->type = s_bit ? R_ANAL_OP_TYPE_CALL
|
||||
: R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = addr;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Type 22: DM/PM = Data16 (2-word, bits 23-13 = 00000011110) */
|
||||
if ((ins >> 13) == 0x1E && !((ins >> 12) & 1))
|
||||
{
|
||||
if (op->size < 6)
|
||||
{
|
||||
op->mnemonic = r_str_newf ("trunc DM_IMM16 0x%06X",
|
||||
ins);
|
||||
return true;
|
||||
}
|
||||
ut32 g = (ins >> 12) & 1;
|
||||
ut32 ireg = (ins >> 2) & 0x3;
|
||||
ut32 mreg = ins & 0x3;
|
||||
@@ -245,6 +283,12 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
/* Type 22a: PM = Data24 (2-word, bits 23-13 = 00000011111) */
|
||||
if ((ins >> 13) == 0x1F)
|
||||
{
|
||||
if (op->size < 6)
|
||||
{
|
||||
op->mnemonic = r_str_newf ("trunc PM_IMM24 0x%06X",
|
||||
ins);
|
||||
return true;
|
||||
}
|
||||
ut32 g = (ins >> 12) & 1;
|
||||
ut32 ireg = (ins >> 2) & 0x3;
|
||||
ut32 mreg = ins & 0x3;
|
||||
@@ -258,36 +302,45 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
ireg + base, mreg + base, data);
|
||||
return true;
|
||||
}
|
||||
/* Type 10a: bits 23-18 = 000111 (unconditional 16-bit) */
|
||||
/* Type 10a: bits 23-18 = 000111 (unconditional 16-bit rel) */
|
||||
if ((ins >> 18) == 0x07)
|
||||
{
|
||||
/* addr = bits 17-4 (14 bits) | bits 1-0 (2 MSBs) */
|
||||
ut32 addr = ((ins >> 4) & 0x3FFF) | ((ins & 0x3) << 14);
|
||||
ut32 rel = ((ins >> 4) & 0x3FFF) | ((ins & 0x3) << 14);
|
||||
ut32 b_bit = (ins >> 3) & 1;
|
||||
ut32 s_bit = (ins >> 2) & 1;
|
||||
op->mnemonic = r_str_newf ("%s 0x%04X%s",
|
||||
/* Sign-extend 16-bit relative offset */
|
||||
int32_t srel = (int32_t)(int16_t) rel;
|
||||
ut64 target = op->addr + (srel * 3);
|
||||
op->mnemonic = r_str_newf ("%s 0x%06" PFMT64x "%s",
|
||||
s_bit ? "CALL" : "JUMP",
|
||||
addr,
|
||||
target,
|
||||
b_bit ? " (DB)" : "");
|
||||
op->type = s_bit ? R_ANAL_OP_TYPE_CALL
|
||||
: R_ANAL_OP_TYPE_JMP;
|
||||
op->jump = target;
|
||||
return true;
|
||||
}
|
||||
/* Type 10: bits 23-19 = 00011, bit18 = 0 (conditional 13-bit) */
|
||||
/* Type 10: bits 23-19 = 00011, bit18 = 0 (conditional 13-bit rel) */
|
||||
if ((ins >> 19) == 0x03 && !((ins >> 18) & 1))
|
||||
{
|
||||
ut32 b_bit = (ins >> 17) & 1;
|
||||
ut32 addr = (ins >> 4) & 0x1FFF;
|
||||
ut32 rel = (ins >> 4) & 0x1FFF;
|
||||
ut32 cond = ins & 0xF;
|
||||
/* Sign-extend 13-bit relative offset */
|
||||
int32_t srel = (rel & 0x1000)
|
||||
? (int32_t)(rel | 0xFFFFE000) : (int32_t) rel;
|
||||
ut64 target = op->addr + (srel * 3);
|
||||
if (cond == 15)
|
||||
op->mnemonic = r_str_newf ("JUMP 0x%04X%s",
|
||||
addr,
|
||||
op->mnemonic = r_str_newf ("JUMP 0x%06" PFMT64x "%s",
|
||||
target,
|
||||
b_bit ? " (DB)" : "");
|
||||
else
|
||||
op->mnemonic = r_str_newf ("IF %s JUMP 0x%04X%s",
|
||||
cond_str[cond], addr,
|
||||
op->mnemonic = r_str_newf ("IF %s JUMP 0x%06" PFMT64x "%s",
|
||||
cond_str[cond], target,
|
||||
b_bit ? " (DB)" : "");
|
||||
op->type = R_ANAL_OP_TYPE_CJMP;
|
||||
op->jump = target;
|
||||
return true;
|
||||
}
|
||||
/* Type 17: Reg = Reg (bits 23-16 = 00001101) */
|
||||
@@ -370,13 +423,17 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Type 11: DO UNTIL (bits 23-16 = 00010110) */
|
||||
/* Type 11: DO UNTIL (bits 23-16 = 00010110, 12-bit rel) */
|
||||
if ((ins >> 16) == 0x16)
|
||||
{
|
||||
ut32 addr = (ins >> 4) & 0xFFF;
|
||||
ut32 rel = (ins >> 4) & 0xFFF;
|
||||
ut32 term = ins & 0xF;
|
||||
op->mnemonic = r_str_newf ("DO 0x%03X UNTIL %s",
|
||||
addr, cond_str[term]);
|
||||
int32_t srel = (rel & 0x800)
|
||||
? (int32_t)(rel | 0xFFFFF000) : (int32_t) rel;
|
||||
ut64 target = op->addr + (srel * 3);
|
||||
op->mnemonic = r_str_newf (
|
||||
"DO 0x%06" PFMT64x " UNTIL %s",
|
||||
target, cond_str[term]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -533,7 +590,11 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Type 29: Dreg <-> DM imm modify (bits 23-18 = 000010) */
|
||||
/* Type 29: Dreg <-> DM imm modify (bits 23-18 = 000010)
|
||||
Always DM. G=bit13 selects DAG group (I0-3 vs I4-7),
|
||||
not the memory bus. U=bit16 (post/pre), D=bit12 (r/w),
|
||||
DRU=bits15-14, DRL=bits1-0, DREG=(DRU<<2)|DRL,
|
||||
MOD=bits11-4 (signed), I=bits3-2. */
|
||||
if ((ins >> 18) == 0x02)
|
||||
{
|
||||
ut32 u = (ins >> 16) & 1;
|
||||
@@ -546,15 +607,14 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
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,
|
||||
op->mnemonic = r_str_newf ("DM(I%d %s %d) = %s",
|
||||
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,
|
||||
op->mnemonic = r_str_newf ("%s = DM(I%d %s %d)",
|
||||
reg0[dreg], ireg + base, op_str,
|
||||
smod);
|
||||
return true;
|
||||
}
|
||||
@@ -571,7 +631,9 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
||||
ut32 ireg = (ins >> 2) & 0x3;
|
||||
ut32 mreg = ins & 0x3;
|
||||
int base = g ? 4 : 0;
|
||||
const char *mem = (ms || g) ? "PM" : "DM";
|
||||
/* MS selects bus (0=DM 16-bit, 1=PM 24-bit).
|
||||
G selects DAG group only. */
|
||||
const char *mem = ms ? "PM" : "DM";
|
||||
const char *mod = u_bit ? "+=" : "+";
|
||||
const char *rname = get_reg (rgp, reg);
|
||||
if (d)
|
||||
|
||||
Reference in New Issue
Block a user