Fix Constant-YOP table, Type 18, truncation guards
Type 9 Constant-YOP: Implement exact constant table from docs. Index = (YY<<2)|CC, value = 1<<idx for BO=01, -(1<<idx)-1 for BO=11. Special case idx=15: -32768 / +32767. (was: simple cc with optional negate, completely wrong values) Type 18: Fix DIS encoding to check for bit pattern 10 (was 01). Verified all 8 modes against assembler: ENA/DIS for AS, MM, BR, TI all correct. Truncation guards: Use saved 'avail' from original op->size instead of checking op->size after it was set to 3. (was: always true, guards never triggered)
This commit is contained in:
17
examples/build/type18_test.dsp
Normal file
17
examples/build/type18_test.dsp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* type18_test.dsp -- Verify Type 18 mode control encoding.
|
||||||
|
*/
|
||||||
|
.section/PM program0;
|
||||||
|
.global _start;
|
||||||
|
_start:
|
||||||
|
ena ar_sat;
|
||||||
|
dis ar_sat;
|
||||||
|
ena m_mode;
|
||||||
|
dis m_mode;
|
||||||
|
ena bit_rev;
|
||||||
|
dis bit_rev;
|
||||||
|
ena timer;
|
||||||
|
dis timer;
|
||||||
|
nop;
|
||||||
|
_halt:
|
||||||
|
jump _halt;
|
||||||
@@ -61,10 +61,11 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
{
|
{
|
||||||
ut32 ins, ins2 = 0;
|
ut32 ins, ins2 = 0;
|
||||||
const ut8 *b = op->bytes;
|
const ut8 *b = op->bytes;
|
||||||
if (op->size < 3) return false;
|
int avail = op->size;
|
||||||
|
if (avail < 3) return false;
|
||||||
|
|
||||||
ins = ((ut32) b[0] << 16) | ((ut32) b[1] << 8) | (ut32) b[2];
|
ins = ((ut32) b[0] << 16) | ((ut32) b[1] << 8) | (ut32) b[2];
|
||||||
if (op->size >= 6)
|
if (avail >= 6)
|
||||||
ins2 = ((ut32) b[3] << 16) | ((ut32) b[4] << 8) | (ut32) b[5];
|
ins2 = ((ut32) b[3] << 16) | ((ut32) b[4] << 8) | (ut32) b[5];
|
||||||
op->size = 3;
|
op->size = 3;
|
||||||
op->type = R_ANAL_OP_TYPE_UNK;
|
op->type = R_ANAL_OP_TYPE_UNK;
|
||||||
@@ -217,13 +218,22 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Constant YOP form: CC=bits7-6, BO=bits5-4 */
|
/* Constant YOP form: YY=bits12-11, CC=bits7-6, BO=bits5-4.
|
||||||
|
Index = (YY<<2)|CC. BO=01: val = 1<<idx (idx<15)
|
||||||
|
or -32768 (idx=15). BO=11: val = -(1<<idx)-1
|
||||||
|
or +32767 (idx=15). */
|
||||||
{
|
{
|
||||||
|
ut32 yy = (ins >> 11) & 0x3;
|
||||||
ut32 cc = (ins >> 6) & 0x3;
|
ut32 cc = (ins >> 6) & 0x3;
|
||||||
ut32 bo = (ins >> 4) & 0x3;
|
ut32 bo = (ins >> 4) & 0x3;
|
||||||
int val = (int) cc;
|
ut32 idx = (yy << 2) | cc;
|
||||||
if (bo & 0x2)
|
int32_t val;
|
||||||
val = -val;
|
if (idx == 15)
|
||||||
|
val = (bo & 0x2) ? 32767 : -32768;
|
||||||
|
else if (bo & 0x2)
|
||||||
|
val = -((int32_t)(1 << idx)) - 1;
|
||||||
|
else
|
||||||
|
val = (int32_t)(1 << idx);
|
||||||
op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s, %d)",
|
op->mnemonic = r_str_newf ("%s%s%s%s = %s(%s, %d)",
|
||||||
cp, cs, sp, dst, f, x, val);
|
cp, cs, sp, dst, f, x, val);
|
||||||
return true;
|
return true;
|
||||||
@@ -285,7 +295,7 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
/* Type 36: Long Jump/Call (2-word, bits 23-16 = 00000101) */
|
/* Type 36: Long Jump/Call (2-word, bits 23-16 = 00000101) */
|
||||||
if ((ins >> 16) == 0x05)
|
if ((ins >> 16) == 0x05)
|
||||||
{
|
{
|
||||||
if (op->size < 6)
|
if (avail < 6)
|
||||||
{
|
{
|
||||||
op->mnemonic = r_str_newf ("trunc L%s 0x%06X",
|
op->mnemonic = r_str_newf ("trunc L%s 0x%06X",
|
||||||
((ins >> 12) & 1) ? "CALL" : "JUMP", ins);
|
((ins >> 12) & 1) ? "CALL" : "JUMP", ins);
|
||||||
@@ -314,7 +324,7 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
/* Type 22: DM/PM = Data16 (2-word, bits 23-13 = 00000011110) */
|
/* Type 22: DM/PM = Data16 (2-word, bits 23-13 = 00000011110) */
|
||||||
if ((ins >> 13) == 0x1E && !((ins >> 12) & 1))
|
if ((ins >> 13) == 0x1E && !((ins >> 12) & 1))
|
||||||
{
|
{
|
||||||
if (op->size < 6)
|
if (avail < 6)
|
||||||
{
|
{
|
||||||
op->mnemonic = r_str_newf ("trunc DM_IMM16 0x%06X",
|
op->mnemonic = r_str_newf ("trunc DM_IMM16 0x%06X",
|
||||||
ins);
|
ins);
|
||||||
@@ -336,7 +346,7 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
/* Type 22a: PM = Data24 (2-word, bits 23-13 = 00000011111) */
|
/* Type 22a: PM = Data24 (2-word, bits 23-13 = 00000011111) */
|
||||||
if ((ins >> 13) == 0x1F)
|
if ((ins >> 13) == 0x1F)
|
||||||
{
|
{
|
||||||
if (op->size < 6)
|
if (avail < 6)
|
||||||
{
|
{
|
||||||
op->mnemonic = r_str_newf ("trunc PM_IMM24 0x%06X",
|
op->mnemonic = r_str_newf ("trunc PM_IMM24 0x%06X",
|
||||||
ins);
|
ins);
|
||||||
@@ -512,7 +522,7 @@ decode (RArchSession *as, RAnalOp *op, RAnalOpMask mask)
|
|||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
ut32 v = (ins >> (i * 2)) & 0x3;
|
ut32 v = (ins >> (i * 2)) & 0x3;
|
||||||
if (v == 1)
|
if (v == 2)
|
||||||
pos += snprintf (buf + pos,
|
pos += snprintf (buf + pos,
|
||||||
sizeof (buf) - pos, "%sDIS %s",
|
sizeof (buf) - pos, "%sDIS %s",
|
||||||
pos ? ", " : "", mbits[i]);
|
pos ? ", " : "", mbits[i]);
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user