diff --git a/r2plugin/asm_adsp219x.c b/r2plugin/asm_adsp219x.c index 1c72b2e..0a31e91 100644 --- a/r2plugin/asm_adsp219x.c +++ b/r2plugin/asm_adsp219x.c @@ -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)) { diff --git a/r2plugin/asm_adsp219x.so b/r2plugin/asm_adsp219x.so index bb388d5..08914ba 100755 Binary files a/r2plugin/asm_adsp219x.so and b/r2plugin/asm_adsp219x.so differ