diff --git a/r2plugin/asm_adsp219x.c b/r2plugin/asm_adsp219x.c index 746e2a6..23ef21f 100644 --- a/r2plugin/asm_adsp219x.c +++ b/r2plugin/asm_adsp219x.c @@ -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) diff --git a/r2plugin/asm_adsp219x.so b/r2plugin/asm_adsp219x.so index 4744074..198f093 100755 Binary files a/r2plugin/asm_adsp219x.so and b/r2plugin/asm_adsp219x.so differ