aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykola Hohsadze <koliagogsadze@gmail.com>2023-06-17 15:31:25 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2023-07-07 19:20:50 +0000
commit7b1b44551ff9bc71031a8faebf7c560427f67880 (patch)
tree43bbd1692af5e3f5e72a72540cb2da6c8749dfdd
parente3a1fe9acad96afbcecae1cd7f677ae64a93f89d (diff)
downloadsrc-7b1b44551ff9bc71031a8faebf7c560427f67880.tar.gz
src-7b1b44551ff9bc71031a8faebf7c560427f67880.zip
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 (cherry picked from commit 9aef25d2686b9e7fb9cb700d63291338e8e30bb6)
-rw-r--r--sys/arm64/arm64/disassem.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/sys/arm64/arm64/disassem.c b/sys/arm64/arm64/disassem.c
index f1a4f9206c1b..5dc0bf5100ef 100644
--- a/sys/arm64/arm64/disassem.c
+++ b/sys/arm64/arm64/disassem.c
@@ -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);
/*