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
This commit is contained in:
Dr. Christian Giessen
2026-04-22 19:50:07 +00:00
parent 6849a701d4
commit adfc7b34b4
3 changed files with 50 additions and 12 deletions

View File

@@ -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;

View File

@@ -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;
}

Binary file not shown.