From 1c28f027b823a9f7724aaa067003135bc60d4ae1 Mon Sep 17 00:00:00 2001 From: "Dr. Christian Giessen" Date: Wed, 22 Apr 2026 20:01:08 +0000 Subject: [PATCH] Rewrite Type 9/9a decode: five sub-encodings Type 9a (register-file, unconditional): - XREG=bits11-8 (4 bits), YREG=bits3-0 (4 bits), both reg0[] - Discriminated by bits5-4 = 10 - Verified: ar=mx0 xor my0, mr=ax0*ay0(ss) Type 9 standard (conditional): - XOP=bits10-8, YOP=bits12-11, COND=bits3-0 - bits7-4 = 0000 required - Verified: all ALU ops, conditional MAC Type 9 YOP=0: - bits12-11 = 11, bits7-4 = 0000 - Renders f(xop, 0) Type 9 MAC squaring: - bits12-11 = 00, bit4 = 1, bits7-5 = 000 - Renders f(xop^2) Type 9 constant YOP: - CC=bits7-6, BO=bits5-4 - Renders f(xop, const) Tested with open21xx assembler output for 15 instructions. Full regression: isa_test, fir, iir unchanged. --- examples/build/type9_test.dsp | 30 +++++++++++++ r2plugin/asm_adsp219x.c | 81 ++++++++++++++++++++++++++++------ r2plugin/asm_adsp219x.so | Bin 28512 -> 28512 bytes 3 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 examples/build/type9_test.dsp 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 198f093324eb1b144d7cb9989c3e5b817895098b..967848e94a2ac305f5f87b9cfed0f605215fc472 100755 GIT binary patch literal 28512 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∋q_bhBgHo=>ZGfcn(8TM{r|X$NGl0U{k20t2@}R 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 s>r6gAY!9zrbbhhzN