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:
16
examples/build/type8_test.dsp
Normal file
16
examples/build/type8_test.dsp
Normal 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;
|
||||||
@@ -153,20 +153,42 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type 8: Compute | Dreg1 <- Dreg2 (00101Z) */
|
/* Type 8: Compute | Dreg1 <- Dreg2 (00101Z)
|
||||||
/* Bits 23-18 = 001010 (Z=0) or 001011 (Z=1) */
|
Z=bit18, AMF=bits17-13, YOP=bits12-11,
|
||||||
if ((ins >> 18) == 0x0A || (ins >> 18) == 0x0B)
|
XOP=bits10-8, DDREG=bits7-4, SDREG=bits3-0.
|
||||||
|
NONE pattern: bits7-0 = 10101010 = 0xAA. */
|
||||||
|
if ((ins >> 19) == 0x05)
|
||||||
{
|
{
|
||||||
ut32 amf = (ins >> 12) & 0x1F;
|
ut32 amf = (ins >> 13) & 0x1F;
|
||||||
const char *f = (amf < 16) ? amf_mac[amf] : amf_alu[amf-16];
|
ut32 yop_i = (ins >> 11) & 0x3;
|
||||||
/* DDREG = bits 8-6 (dest), SDREG = bits 5-0 (src, masked) */
|
ut32 xop_i = (ins >> 8) & 0x7;
|
||||||
ut32 ddreg = (ins >> 6) & 0x7;
|
ut32 ddreg = (ins >> 4) & 0xF;
|
||||||
ut32 sdreg = ins & 0x3F;
|
ut32 sdreg = ins & 0xF;
|
||||||
/* For NONE=ALU case: SDREG = 0x2A (101010) */
|
const char *f;
|
||||||
if (sdreg == 0x2A)
|
const char *x;
|
||||||
op->mnemonic = r_str_newf ("NONE = %s", f);
|
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
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user