From 13521048bccf86a5405bccad0cb4c9d8e8af260c Mon Sep 17 00:00:00 2001 From: "Dr. Christian Giessen" Date: Wed, 22 Apr 2026 19:41:07 +0000 Subject: [PATCH] Add 2-word instruction decode: Types 22, 22a, 32a, 36 - Type 22: DM/PM = Data16 (2-word immediate data write) - Type 22a: PM = Data24 (2-word 24-bit data write) - Type 32a: DAG register store with register transfer - Type 36: LJUMP/LCALL (2-word long jump/call, 24-bit address) - op->size = 6 for all 2-word instructions - Zero compiler warnings - Full regression: all 48 isa_test.bin instructions unchanged --- r2plugin/asm_adsp219x.c | 77 ++++++++++++++++++++++++++++++++++++++- r2plugin/asm_adsp219x.so | Bin 24416 -> 24416 bytes 2 files changed, 76 insertions(+), 1 deletion(-) 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 bb388d5c40f60c2741309199e2238e4720b52e42..08914ba492dfae4e098a3820c8b3c672a85a89ff 100755 GIT binary patch literal 24416 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