diff --git a/r2plugin/asm_adsp219x.c b/r2plugin/asm_adsp219x.c index ea66cce..f85aff1 100644 --- a/r2plugin/asm_adsp219x.c +++ b/r2plugin/asm_adsp219x.c @@ -109,7 +109,42 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask) { 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)); + 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)); + return true; + } + + /* Type 9/9a: Compute (001000 / 001001) */ + /* Bits 23-19 = 00100 */ + if ((ins >> 19) == 0x04) + { + ut32 amf = (ins >> 13) & 0x1F; + ut32 xop_i = (ins >> 8) & 0x7; + ut32 yop_i = (ins >> 11) & 0x3; + ut32 cond = ins & 0xF; + const char *f; + const char *dst; + const char *x; + const char *y; + if (amf < 16) + { + f = amf_mac[amf]; + dst = "MR"; + x = xop_mac[xop_i]; + y = yop_mac[yop_i]; + } + else + { + f = amf_alu[amf - 16]; + dst = "AR"; + x = xop_alu[xop_i]; + y = yop_alu[yop_i]; + } + if (cond == 15) + op->mnemonic = r_str_newf ("%s = %s(%s, %s)", + dst, f, x, y); + else + op->mnemonic = r_str_newf ("IF %s %s = %s(%s, %s)", + cond_str[cond], dst, f, x, y); return true; } @@ -117,7 +152,6 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask) /* Bits 23-18 = 001010 (Z=0) or 001011 (Z=1) */ if ((ins >> 18) == 0x0A || (ins >> 18) == 0x0B) { - ut32 z = (ins >> 18) & 1; ut32 amf = (ins >> 12) & 0x1F; const char *f = (amf < 16) ? amf_mac[amf] : amf_alu[amf-16]; /* DDREG = bits 8-6 (dest), SDREG = bits 5-0 (src, masked) */ @@ -144,16 +178,237 @@ 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) */ - if ((ins >> 19) == 0x3) /* Type 10/10a Jumps */ + /* Type 10a: bits 23-18 = 000111 (unconditional 16-bit) */ + if ((ins >> 18) == 0x07) { - ut32 db = (ins >> 18) & 1, s = (ins >> 17) & 1, cond = ins & 0xF; - op->mnemonic = r_str_newf ("%s%s %s 0x%X%s", (cond==15?"":"IF "), (cond==15?"":cond_str[cond]), s?"CALL":"JUMP", (ins>>4)&0x1FFF, db?" (DB)":""); + /* addr = bits 17-4 (14 bits) | bits 1-0 (2 MSBs) */ + ut32 addr = ((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", + s_bit ? "CALL" : "JUMP", + addr, + b_bit ? " (DB)" : ""); + op->type = s_bit ? R_ANAL_OP_TYPE_CALL + : R_ANAL_OP_TYPE_JMP; + return true; + } + /* Type 10: bits 23-19 = 00011, bit18 = 0 (conditional 13-bit) */ + if ((ins >> 19) == 0x03 && !((ins >> 18) & 1)) + { + ut32 b_bit = (ins >> 17) & 1; + ut32 addr = (ins >> 4) & 0x1FFF; + ut32 cond = ins & 0xF; + if (cond == 15) + op->mnemonic = r_str_newf ("JUMP 0x%04X%s", + addr, + b_bit ? " (DB)" : ""); + else + op->mnemonic = r_str_newf ("IF %s JUMP 0x%04X%s", + cond_str[cond], addr, + b_bit ? " (DB)" : ""); + op->type = R_ANAL_OP_TYPE_CJMP; + return true; + } + /* Type 17: Reg = Reg (bits 23-16 = 00001101) */ + if ((ins >> 16) == 0x0D) + { + op->mnemonic = r_str_newf ("%s = %s", + get_reg ((ins >> 10) & 3, (ins >> 4) & 0xF), + get_reg ((ins >> 8) & 3, ins & 0xF)); + return true; + } + + /* Type 20: RTS/RTI (bits 23-16 = 00001010) */ + if ((ins >> 16) == 0x0A) + { + ut32 b_bit = (ins >> 15) & 1; + ut32 t_bit = (ins >> 14) & 1; + ut32 cond = (ins >> 4) & 0xF; + const char *ret = t_bit ? "RTI" : "RTS"; + if (cond == 15) + op->mnemonic = r_str_newf ("%s%s", ret, + b_bit ? " (DB)" : ""); + else + op->mnemonic = r_str_newf ("IF %s %s%s", + cond_str[cond], ret, + b_bit ? " (DB)" : ""); + op->type = R_ANAL_OP_TYPE_RET; + return true; + } + + /* Type 11: DO UNTIL (bits 23-16 = 00010110) */ + if ((ins >> 16) == 0x16) + { + ut32 addr = (ins >> 4) & 0xFFF; + ut32 term = ins & 0xF; + op->mnemonic = r_str_newf ("DO 0x%03X UNTIL %s", + addr, cond_str[term]); + return true; + } + + /* Type 15: Shift Imm (bits 23-16 = 00001111) */ + if ((ins >> 16) == 0x0F) + { + ut32 sf = (ins >> 12) & 0xF; + ut32 xreg = (ins >> 8) & 0xF; + int8_t exp = (int8_t)(ins & 0xFF); + op->mnemonic = r_str_newf ("SR = %s %s BY %d", + sf_names[sf], reg0[xreg], + exp); + return true; + } + + /* Type 18: Mode Control (bits 23-16 = 00001100) */ + if ((ins >> 16) == 0x0C) + { + static const char *mbits[] = + { "INT", "SD", "SR", "BR", "OL", "AS", "MM", "TI" }; + char buf[128]; + int pos = 0, i; + for (i = 0; i < 8; i++) + { + ut32 v = (ins >> (i * 2)) & 0x3; + if (v == 1) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sDIS %s", + pos ? ", " : "", mbits[i]); + else if (v == 3) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sENA %s", + pos ? ", " : "", mbits[i]); + } + op->mnemonic = pos ? strdup (buf) + : strdup ("MODE NOP"); + return true; + } + + /* Type 25: SAT MR/SR (bits 23-14 = 0000001100) */ + if ((ins >> 14) == 0x0C) + { + ut32 r = (ins >> 13) & 1; + op->mnemonic = r_str_newf ("SAT %s", + r ? "SR" : "MR"); + return true; + } + + /* Type 33: Reg3 = Data12 (bits 23-16 = 00010000) */ + if ((ins >> 16) == 0x10) + { + ut32 data = (ins >> 4) & 0xFFF; + ut32 reg = ins & 0xF; + op->mnemonic = r_str_newf ("%s = 0x%03X", + reg3[reg], data); + return true; + } + + /* Type 19: Indirect Jump/Call (bits 23-16 = 00001011) */ + if ((ins >> 16) == 0x0B) + { + ut32 b_bit = (ins >> 15) & 1; + ut32 s_bit = (ins >> 14) & 1; + ut32 g = (ins >> 13) & 1; + ut32 cond = (ins >> 4) & 0xF; + ut32 ireg = ins & 0x3; + int base = g ? 4 : 0; + if (cond == 15) + op->mnemonic = r_str_newf ("%s (I%d)%s", + s_bit ? "CALL" : "JUMP", + ireg + base, + b_bit ? " (DB)" : ""); + else + op->mnemonic = r_str_newf ("IF %s %s (I%d)%s", + cond_str[cond], + s_bit ? "CALL" : "JUMP", + ireg + base, + b_bit ? " (DB)" : ""); + op->type = s_bit ? R_ANAL_OP_TYPE_CALL + : R_ANAL_OP_TYPE_JMP; + return true; + } + + /* Type 21: MODIFY (bits 23-16 = 00000001, bit15=1) */ + if ((ins >> 16) == 0x01 && ((ins >> 15) & 1)) + { + ut32 g = (ins >> 12) & 1; + ut32 ireg = ins & 0x3; + ut32 mreg = (ins >> 2) & 0x3; + int base = g ? 4 : 0; + op->mnemonic = r_str_newf ("MODIFY(I%d += M%d)", + ireg + base, mreg + base); + return true; + } + + /* Type 23: DIVQ (bits 23-12 = 000000111101) */ + if ((ins >> 12) == 0x03D) + { + ut32 xop_i = (ins >> 8) & 0x7; + op->mnemonic = r_str_newf ("DIVQ %s", + xop_alu[xop_i]); + return true; + } + + /* Type 24: DIVS (bits 23-13 = 00000011100) */ + if ((ins >> 13) == 0x1C) + { + ut32 yop_i = (ins >> 11) & 0x3; + ut32 xop_i = (ins >> 8) & 0x7; + op->mnemonic = r_str_newf ("DIVS %s, %s", + yop_alu[yop_i], + xop_alu[xop_i]); + return true; + } + + /* Type 26: Push/Pop/Cache (bits 23-16 = 00001000) */ + if ((ins >> 16) == 0x08) + { + ut32 cf = (ins >> 7) & 1; + ut32 ppp = (ins >> 4) & 0x7; + ut32 lpp = (ins >> 2) & 0x3; + ut32 spp = ins & 0x3; + char buf[64]; + int pos = 0; + if (cf) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "FLUSH CACHE"); + if (ppp == 1) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sPUSH PC", + pos ? ", " : ""); + else if (ppp == 2) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sPOP PC", + pos ? ", " : ""); + if (lpp == 1) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sPUSH LOOP", + pos ? ", " : ""); + else if (lpp == 2) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sPOP LOOP", + pos ? ", " : ""); + if (spp == 1) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sPUSH STS", + pos ? ", " : ""); + else if (spp == 2) + pos += snprintf (buf + pos, + sizeof (buf) - pos, "%sPOP STS", + pos ? ", " : ""); + op->mnemonic = pos ? strdup (buf) + : strdup ("STACK NOP"); + return true; + } + + /* Type 37: SETINT/CLRINT (bits 23-15 = 000001110) */ + if ((ins >> 15) == 0x0E) + { + ut32 c = (ins >> 5) & 1; + ut32 bit = ins & 0xF; + op->mnemonic = r_str_newf ("%s %d", + c ? "CLRINT" : "SETINT", bit); return true; } - if ((ins >> 16) == 0x0D) { op->mnemonic = r_str_newf ("%s = %s", get_reg((ins>>10)&3, (ins>>4)&0xF), get_reg((ins>>8)&3, ins&0xF)); return true; } /* Type 17 */ - if ((ins >> 16) == 0x0A) { op->mnemonic = r_str_newf ("%s%s %s", (ins&0xF)==15?"":cond_str[ins&0xF], (ins&0xF)==15?"":" ", (ins>>13)&1?"RTI":"RTS"); return true; } /* Type 20 */ - if ((ins >> 16) == 0x16) { op->mnemonic = r_str_newf ("DO 0x%X UNTIL %s", (ins>>4)&0xFFF, cond_str[ins&0xF]); return true; } /* Type 11 */ - if ((ins >> 16) == 0x0F) { op->mnemonic = r_str_newf ("SR = %s %s BY 0x%X", sf_names[(ins>>12)&0xF], reg0[(ins>>8)&0xF], ins&0xFF); return true; } /* Type 15 */ } op->mnemonic = r_str_newf ("unk 0x%06X", ins); diff --git a/r2plugin/asm_adsp219x.so b/r2plugin/asm_adsp219x.so index 33c60bc..feccfca 100755 Binary files a/r2plugin/asm_adsp219x.so and b/r2plugin/asm_adsp219x.so differ