git: 9aef25d2686b - main - arm64/disassem.c: Add shifted register definitions with ror

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Sat, 17 Jun 2023 16:19:59 UTC
The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=9aef25d2686b9e7fb9cb700d63291338e8e30bb6

commit 9aef25d2686b9e7fb9cb700d63291338e8e30bb6
Author:     Mykola Hohsadze <koliagogsadze@gmail.com>
AuthorDate: 2023-06-17 15:31:25 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2023-06-17 16:19:37 +0000

    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
---
 sys/arm64/arm64/disassem.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

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);
 
 		/*