diff --git a/examples/build/type9_test.dsp b/examples/build/type9_test.dsp new file mode 100644 index 0000000..136e1fd --- /dev/null +++ b/examples/build/type9_test.dsp @@ -0,0 +1,30 @@ +/* + * type9_test.dsp -- Test all Type 9/9a sub-encodings. + */ + .section/PM program0; + .global _start; +_start: + /* Type 9 standard: conditional ALU */ + ar = ax0 + ay0; + if ne ar = ax0 - ay0; + ar = ax0 and ay0; + ar = pass ax0; + ar = -ax0; + ar = abs ax0; + + /* Type 9 standard: conditional MAC */ + mr = mx0 * my0 (ss); + if eq mr = mr + mx0 * my0 (ss); + mr = mr - mx0 * my0 (ss); + mr = 0; + + /* Type 9a: unconditional register-file ALU */ + ar = ax0 + ay1; + ar = mx0 xor my0; + + /* Type 9a: unconditional register-file MAC */ + mr = ax0 * ay0 (ss); + + nop; +_halt: + jump _halt; diff --git a/r2plugin/asm_adsp219x.c b/r2plugin/asm_adsp219x.c index 23ef21f..3a83c5f 100644 --- a/r2plugin/asm_adsp219x.c +++ b/r2plugin/asm_adsp219x.c @@ -142,39 +142,92 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask) return true; } - /* Type 9/9a: Compute (001000 / 001001) */ - /* Bits 23-19 = 00100 */ + /* Type 9/9a: Compute (bits 23-19 = 00100) + Z=bit18, AMF=bits17-13. + Five sub-encodings distinguished by lower bits: + 9a register-file: bits5-4 = 10 + 9 standard: bits7-4 = 0000, bits12-11 != 11 + 9 YOP=0: bits7-4 = 0000, bits12-11 = 11 + 9 MAC square: bits12-11 = 00, bit4 = 1, bits7-5 = 000 + 9 constant YOP: otherwise */ 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; + + /* Select AMF mnemonic and XOP table based on operation */ 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; + + /* Type 9a: register-file form (bits5-4 = 10) + XREG=bits11-8 (4 bits), YREG=bits3-0 (4 bits), + both index into reg0[]. */ + if (((ins >> 4) & 0x3) == 0x2) + { + ut32 xreg = (ins >> 8) & 0xF; + ut32 yreg = ins & 0xF; + op->mnemonic = r_str_newf ("%s = %s(%s, %s)", + dst, f, reg0[xreg], + reg0[yreg]); + return true; + } + + ut32 cond = ins & 0xF; + ut32 yop_i = (ins >> 11) & 0x3; + const char *cp = (cond == 15) ? "" : "IF "; + const char *cs = (cond == 15) ? "" : cond_str[cond]; + const char *sp = (cond == 15) ? "" : " "; + + /* MAC squaring: bits12-11 = 00, bit4 = 1, bits7-5 = 000 */ + if (yop_i == 0 && ((ins >> 4) & 0xF) == 0x1) + { + op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s^2)", + cp, cs, sp, dst, f, x); + return true; + } + + /* YOP=0 form: bits12-11 = 11, bits7-4 = 0000 */ + if (yop_i == 3 && ((ins >> 4) & 0xF) == 0) + { + op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s, 0)", + cp, cs, sp, dst, f, x); + return true; + } + + /* Standard form: bits7-4 = 0000 */ + if (((ins >> 4) & 0xF) == 0) + { + const char *y = (amf < 16) ? yop_mac[yop_i] + : yop_alu[yop_i]; + op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s, %s)", + cp, cs, sp, dst, f, x, y); + return true; + } + + /* Constant YOP form: CC=bits7-6, BO=bits5-4 */ + { + ut32 cc = (ins >> 6) & 0x3; + ut32 bo = (ins >> 4) & 0x3; + int val = (int) cc; + if (bo & 0x2) + val = -val; + op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s, %d)", + cp, cs, sp, dst, f, x, val); + return true; + } } /* Type 8: Compute | Dreg1 <- Dreg2 (00101Z) diff --git a/r2plugin/asm_adsp219x.so b/r2plugin/asm_adsp219x.so index 198f093..967848e 100755 Binary files a/r2plugin/asm_adsp219x.so and b/r2plugin/asm_adsp219x.so differ