mirror of
https://github.com/opnsense/src.git
synced 2026-06-03 13:58:30 -04:00
arm64/disassem.c: Add shifted register definitions with ror
Add disassembly support for the following shifted register instructions:
* mvn
* orn
* orr
* and
* ands
* bic
* bics
* eon
* eor
* tst
According to Arm64 documenation, operational pseuducode of shifted
register instruction must return `UNDEFINED` if shift type is `RESERVED`
('11'). Hence, removed "rsv" from `shift_2` array and add "ror". In case
of shift type is 3 and this type is `RESERVED`, we will return
`undefined`.
Reviewed by: mhorne
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D40386
This commit is contained in:
parent
1ad8d2ee1f
commit
9aef25d268
1 changed files with 35 additions and 1 deletions
|
|
@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
|
|||
#define OP_RT_SP (1UL << 8) /* Use sp for RT otherwise xzr */
|
||||
#define OP_RN_SP (1UL << 9) /* Use sp for RN otherwise xzr */
|
||||
#define OP_RM_SP (1UL << 10) /* Use sp for RM otherwise xzr */
|
||||
#define OP_SHIFT_ROR (1UL << 11) /* Use ror shift type */
|
||||
|
||||
static const char *w_reg[] = {
|
||||
"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
|
||||
|
|
@ -69,7 +70,7 @@ static const char *x_reg[] = {
|
|||
};
|
||||
|
||||
static const char *shift_2[] = {
|
||||
"lsl", "lsr", "asr", "rsv"
|
||||
"lsl", "lsr", "asr", "ror"
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -232,6 +233,28 @@ static struct arm64_insn arm64_i[] = {
|
|||
TYPE_01, 0 }, /* negs shifted register */
|
||||
{ "subs", "SF(1)|1101011|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, 0 }, /* subs shifted register */
|
||||
{ "mvn", "SF(1)|0101010|SHIFT(2)|1|RM(5)|IMM(6)|11111|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* mvn shifted register */
|
||||
{ "orn", "SF(1)|0101010|SHIFT(2)|1|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* orn shifted register */
|
||||
{ "mov", "SF(1)|0101010000|RM(5)|000000|11111|RD(5)",
|
||||
TYPE_01, 0 }, /* mov register */
|
||||
{ "orr", "SF(1)|0101010|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* orr shifted register */
|
||||
{ "and", "SF(1)|0001010|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* and shifted register */
|
||||
{ "tst", "SF(1)|1101010|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|11111",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* tst shifted register */
|
||||
{ "ands", "SF(1)|1101010|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* ands shifted register */
|
||||
{ "bic", "SF(1)|0001010|SHIFT(2)|1|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* bic shifted register */
|
||||
{ "bics", "SF(1)|1101010|SHIFT(2)|1|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* bics shifted register */
|
||||
{ "eon", "SF(1)|1001010|SHIFT(2)|1|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* eon shifted register */
|
||||
{ "eor", "SF(1)|1001010|SHIFT(2)|0|RM(5)|IMM(6)|RN(5)|RD(5)",
|
||||
TYPE_01, OP_SHIFT_ROR }, /* eor shifted register */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
@ -420,6 +443,8 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt)
|
|||
int pre;
|
||||
/* Indicate if x31 register should be printed as sp or xzr */
|
||||
int rm_sp, rt_sp, rd_sp, rn_sp;
|
||||
/* Indicate if shift type ror is supported */
|
||||
bool has_shift_ror;
|
||||
|
||||
/* Initialize defaults, all are 0 except SF indicating 64bit access */
|
||||
shift = rd = rm = rn = imm = idx = option = amount = scale = 0;
|
||||
|
|
@ -464,6 +489,8 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt)
|
|||
rd_sp = i_ptr->special_ops & OP_RD_SP;
|
||||
rn_sp = i_ptr->special_ops & OP_RN_SP;
|
||||
|
||||
has_shift_ror = i_ptr->special_ops & OP_SHIFT_ROR;
|
||||
|
||||
/* Print opcode by type */
|
||||
switch (i_ptr->type) {
|
||||
case TYPE_01:
|
||||
|
|
@ -479,6 +506,13 @@ disasm(const struct disasm_interface *di, vm_offset_t loc, int altfmt)
|
|||
rm_absent = arm64_disasm_read_token(i_ptr, insn, "RM", &rm);
|
||||
arm64_disasm_read_token(i_ptr, insn, "SHIFT", &shift);
|
||||
|
||||
/*
|
||||
* if shift type is RESERVED for shifted register instruction,
|
||||
* print undefined
|
||||
*/
|
||||
if (shift == 3 && !has_shift_ror)
|
||||
goto undefined;
|
||||
|
||||
di->di_printf("%s\t", i_ptr->name);
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue