From adfc7b34b402c8133e76e4ea2592661ceeedd0dd Mon Sep 17 00:00:00 2001 From: "Dr. Christian Giessen" Date: Wed, 22 Apr 2026 19:50:07 +0000 Subject: [PATCH] Fix Type 8 decode: correct all bitfield extractions - DDREG: fixed to bits 7-4 (was bits 8-6, mixed XOP bit into dest) - SDREG: fixed to bits 3-0 (was bits 5-0, included foreign bits) - Dest/src registers now correctly use reg0[] table (was xop_alu[]) - NONE pattern: check full bits 7-0 == 0xAA (was only bits 5-0) - XOP/YOP tables now follow AMF type (MAC vs ALU), not Z bit - Output format: f(xop, yop), ddreg = sdreg (matches ADI syntax) - Verified against assembler output for all three Type 8 variants: ALU+move, MAC+move, and NONE=ALU status-only - Full regression: isa_test.bin, fir.bin, iir.bin all unchanged --- examples/build/type8_test.dsp | 16 ++++++++++++ r2plugin/asm_adsp219x.c | 46 +++++++++++++++++++++++++--------- r2plugin/asm_adsp219x.so | Bin 24416 -> 28512 bytes 3 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 examples/build/type8_test.dsp diff --git a/examples/build/type8_test.dsp b/examples/build/type8_test.dsp new file mode 100644 index 0000000..e03708e --- /dev/null +++ b/examples/build/type8_test.dsp @@ -0,0 +1,16 @@ + .section/PM program0; + .global _start; +_start: + /* Type 8: Compute + Dreg move */ + /* AR = AX0 + AY0, MX0 = AX1 */ + ar = ax0 + ay0, ax0 = mx0; + + /* MR = MX0 * MY0 (SS), AX1 = AY0 */ + mr = mx0 * my0 (ss), ax1 = ay0; + + /* NONE = AX0 + AY0 (generate status only) */ + none = ax0 + ay0; + + nop; +_halt: + jump _halt; diff --git a/r2plugin/asm_adsp219x.c b/r2plugin/asm_adsp219x.c index a2ccc28..746e2a6 100644 --- a/r2plugin/asm_adsp219x.c +++ b/r2plugin/asm_adsp219x.c @@ -153,20 +153,42 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask) return true; } - /* Type 8: Compute | Dreg1 <- Dreg2 (00101Z) */ - /* Bits 23-18 = 001010 (Z=0) or 001011 (Z=1) */ - if ((ins >> 18) == 0x0A || (ins >> 18) == 0x0B) + /* Type 8: Compute | Dreg1 <- Dreg2 (00101Z) + Z=bit18, AMF=bits17-13, YOP=bits12-11, + XOP=bits10-8, DDREG=bits7-4, SDREG=bits3-0. + NONE pattern: bits7-0 = 10101010 = 0xAA. */ + if ((ins >> 19) == 0x05) { - 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) */ - ut32 ddreg = (ins >> 6) & 0x7; - ut32 sdreg = ins & 0x3F; - /* For NONE=ALU case: SDREG = 0x2A (101010) */ - if (sdreg == 0x2A) - op->mnemonic = r_str_newf ("NONE = %s", f); + ut32 amf = (ins >> 13) & 0x1F; + ut32 yop_i = (ins >> 11) & 0x3; + ut32 xop_i = (ins >> 8) & 0x7; + ut32 ddreg = (ins >> 4) & 0xF; + ut32 sdreg = ins & 0xF; + const char *f; + const char *x; + const char *y; + /* AMF < 16 = MAC op, AMF >= 16 = ALU op. + XOP/YOP tables follow the operation type, not Z. */ + if (amf < 16) + { + f = amf_mac[amf]; + x = xop_mac[xop_i]; + y = yop_mac[yop_i]; + } else - op->mnemonic = r_str_newf ("%s, %s = %s", f, xop_alu[ddreg], reg0[sdreg & 0xF]); + { + f = amf_alu[amf - 16]; + x = xop_alu[xop_i]; + y = yop_alu[yop_i]; + } + /* NONE = ALU/MAC: bits 7-0 == 0xAA (10101010) */ + if ((ins & 0xFF) == 0xAA) + op->mnemonic = r_str_newf ("NONE = %s(%s, %s)", + f, x, y); + else + op->mnemonic = r_str_newf ("%s(%s, %s), %s = %s", + f, x, y, + reg0[ddreg], reg0[sdreg]); return true; } diff --git a/r2plugin/asm_adsp219x.so b/r2plugin/asm_adsp219x.so index dddd5ccbc7aea4c0a7e37e829c7c44da15245562..4744074cfab47d8f8cb612ef0bfde434a27975ab 100755 GIT binary patch literal 28512 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