diff options
author | Mykola Hohsadze <koliagogsadze@gmail.com> | 2023-06-17 15:31:25 +0000 |
---|---|---|
committer | Mitchell Horne <mhorne@FreeBSD.org> | 2023-06-17 16:19:37 +0000 |
commit | 9aef25d2686b9e7fb9cb700d63291338e8e30bb6 (patch) | |
tree | 480f90c10af0679bad86ec5c8b45a63e291d1c6f | |
parent | 1ad8d2ee1f7dec1d747ec955a68fbbb362958315 (diff) | |
download | src-9aef25d2686b9e7fb9cb700d63291338e8e30bb6.tar.gz src-9aef25d2686b9e7fb9cb700d63291338e8e30bb6.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
-rw-r--r-- | sys/arm64/arm64/disassem.c | 36 |
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); /* |