Home | History | Annotate | Line # | Download | only in aarch64
      1 /*	$NetBSD: disasm.c,v 1.17 2026/01/09 07:37:13 skrll Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2018 Ryo Shimizu
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: disasm.c,v 1.17 2026/01/09 07:37:13 skrll Exp $");
     31 
     32 #include <sys/param.h>
     33 #include <sys/types.h>
     34 #include <sys/bitops.h>
     35 #include <sys/endian.h>
     36 
     37 #include <arch/aarch64/aarch64/disasm.h>
     38 
     39 #ifndef _KERNEL
     40 #include <stdio.h>
     41 #include <stdbool.h>
     42 #endif
     43 
     44 #define PRINTF		di->di_printf
     45 #define PRINTADDR	di->di_printaddr
     46 
     47 #define OPFUNC_DECL(func, a, b, c, d, e, f, g, h)		\
     48 func(const disasm_interface_t *di, uint64_t pc, uint32_t insn,	\
     49     uint64_t a, uint64_t b, uint64_t c, uint64_t d,		\
     50     uint64_t e, uint64_t f, uint64_t g, uint64_t h)
     51 
     52 #define UNUSED0	arg0 __unused
     53 #define UNUSED1	arg1 __unused
     54 #define UNUSED2	arg2 __unused
     55 #define UNUSED3	arg3 __unused
     56 #define UNUSED4	arg4 __unused
     57 #define UNUSED5	arg5 __unused
     58 #define UNUSED6	arg6 __unused
     59 #define UNUSED7	arg7 __unused
     60 
     61 #define OP0FUNC(func)						\
     62 	static void						\
     63 	OPFUNC_DECL(func,					\
     64 	    UNUSED0, UNUSED1, UNUSED2, UNUSED3,			\
     65 	    UNUSED4, UNUSED5, UNUSED6, UNUSED7)
     66 #define OP1FUNC(func, a)					\
     67 	static void						\
     68 	OPFUNC_DECL(func, a,					\
     69 	    UNUSED1, UNUSED2, UNUSED3, UNUSED4,			\
     70 	    UNUSED5, UNUSED6, UNUSED7)
     71 #define OP2FUNC(func, a, b)					\
     72 	static void						\
     73 	OPFUNC_DECL(func, a, b,					\
     74 	    UNUSED2, UNUSED3, UNUSED4, UNUSED5,			\
     75 	    UNUSED6, UNUSED7)
     76 #define OP3FUNC(func, a, b, c)					\
     77 	static void						\
     78 	OPFUNC_DECL(func, a, b, c,				\
     79 	    UNUSED3, UNUSED4, UNUSED5, UNUSED6,			\
     80 	    UNUSED7)
     81 #define OP4FUNC(func, a, b, c, d)				\
     82 	static void						\
     83 	OPFUNC_DECL(func, a, b, c, d,				\
     84 	    UNUSED4, UNUSED5, UNUSED6, UNUSED7)
     85 #define OP5FUNC(func, a, b, c, d, e)				\
     86 	static void						\
     87 	OPFUNC_DECL(  func, a, b, c, d, e,			\
     88 	    UNUSED5, UNUSED6, UNUSED7)
     89 #define OP6FUNC(func, a, b, c, d, e, f)				\
     90 	static void						\
     91 	OPFUNC_DECL(func, a, b, c, d, e, f,			\
     92 	    UNUSED6, UNUSED7)
     93 #define OP7FUNC(func, a, b, c, d, e, f, g)			\
     94 	static void						\
     95 	OPFUNC_DECL(func, a, b, c, d, e, f, g,			\
     96 	    UNUSED7)
     97 #define OP8FUNC(func, a, b, c, d, e, f, g, h)			\
     98 	static void						\
     99 	OPFUNC_DECL(func, a, b, c, d, e, f, g, h)
    100 
    101 static const char *z_wxregs[2][32] = {
    102 	{
    103 		 "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",
    104 		 "w8",  "w9", "w10", "w11", "w12", "w13", "w14", "w15",
    105 		"w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
    106 		"w24", "w25", "w26", "w27", "w28", "w29", "w30", "wzr"
    107 	},
    108 	{
    109 		 "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
    110 		 "x8",  "x9", "x10", "x11", "x12", "x13", "x14", "x15",
    111 		"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
    112 		"x24", "x25", "x26", "x27", "x28", "x29", "x30", "xzr"
    113 	}
    114 };
    115 
    116 static const char *s_wxregs[2][32] = {
    117 	{
    118 		 "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",
    119 		 "w8",  "w9", "w10", "w11", "w12", "w13", "w14", "w15",
    120 		"w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
    121 		"w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp"
    122 	},
    123 	{
    124 		 "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",
    125 		 "x8",  "x9", "x10", "x11", "x12", "x13", "x14", "x15",
    126 		"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
    127 		"x24", "x25", "x26", "x27", "x28", "x29", "x30",  "sp"
    128 	}
    129 };
    130 #define ZREGNAME(s, n)	(z_wxregs[(s) & 1][(n) & 31])
    131 #define SREGNAME(s, n)	(s_wxregs[(s) & 1][(n) & 31])
    132 
    133 static const char *simdregs[5][32] = {
    134 	{
    135 		 "b0",  "b1",  "b2",  "b3",  "b4",  "b5",  "b6",  "b7",
    136 		 "b8",  "b9", "b10", "b11", "b12", "b13", "b14", "b15",
    137 		"b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23",
    138 		"b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31"
    139 	},
    140 	{
    141 		 "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
    142 		 "h8",  "h9", "h10", "h11", "h12", "h13", "h14", "h15",
    143 		"h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
    144 		"h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31"
    145 	},
    146 	{
    147 		 "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",
    148 		 "s8",  "s9", "s10", "s11", "s12", "s13", "s14", "s15",
    149 		"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
    150 		"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"
    151 	},
    152 	{
    153 		 "d0",  "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",
    154 		 "d8",  "d9", "d10", "d11", "d12", "d13", "d14", "d15",
    155 		"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
    156 		"d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"
    157 	},
    158 	{
    159 		 "q0",  "q1",  "q2",  "q3",  "q4",  "q5",  "q6",  "q7",
    160 		 "q8",  "q9", "q10", "q11", "q12", "q13", "q14", "q15",
    161 		"q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
    162 		"q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
    163 	}
    164 };
    165 #define FREGSZ_B	0
    166 #define FREGSZ_H	1
    167 #define FREGSZ_S	2
    168 #define FREGSZ_D	3
    169 #define FREGSZ_Q	4
    170 #define FREGNAME(s, n)	(simdregs[(s)][(n) & 31])
    171 
    172 static const char *vecregs[32] = {
    173 	 "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
    174 	 "v8",  "v9", "v10", "v11", "v12", "v13", "v14", "v15",
    175 	"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
    176 	"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
    177 };
    178 #define VREGNAME(n)	vecregs[(n) & 31]
    179 
    180 static const char *cregs[16] = {
    181 	 "C0",  "C1",  "C2",  "C3",  "C4",  "C5",  "C6",  "C7",
    182 	 "C8",  "C9", "C10", "C11", "C12", "C13", "C14", "C15"
    183 };
    184 #define CREGNAME(n)	cregs[(n) & 15]
    185 
    186 static const char *conditioncode[16] = {
    187 	"eq", "ne", "cs", "cc",
    188 	"mi", "pl", "vs", "vc",
    189 	"hi", "ls", "ge", "lt",
    190 	"gt", "le", "al", "nv"
    191 };
    192 #define CONDNAME(c)	conditioncode[(c) & 15]
    193 #define IVCONDNAME(c)	conditioncode[((c) ^ 1) & 15]
    194 
    195 static const char *barrierop[16] = {
    196 	 "#0", "oshld", "oshst", "osh",
    197 	 "#4", "nshld", "nshst", "nsh",
    198 	 "#8", "ishld", "ishst", "ish",
    199 	"#12",    "ld",    "st",  "sy"
    200 };
    201 #define BARRIERNAME(op)	barrierop[(op) & 15]
    202 
    203 static const char *prefetchop[32] = {
    204 	"pldl1keep", "pldl1strm", "pldl2keep", "pldl2strm",
    205 	"pldl3keep", "pldl3strm",        "#6",        "#7",
    206 	"plil1keep", "plil1strm", "plil2keep", "plil2strm",
    207 	"plil3keep", "plil3strm",       "#14",       "#15",
    208 	"pstl1keep", "pstl1strm", "pstl2keep", "pstl2strm",
    209 	"pstl3keep", "pstl3strm",       "#22",       "#23",
    210 	      "#24",       "#25",       "#26",       "#27",
    211 	      "#28",       "#29",       "#30",       "#31"
    212 };
    213 #define PREFETCHNAME(op)	prefetchop[(op) & 31]
    214 
    215 
    216 #define SYSREG_ENC(op0, op1, CRn, CRm, op2)		\
    217 	(((op0)<<19)|((op1)<<16)|((CRn)<<12)|((CRm)<<8)|((op2)<<5))
    218 
    219 struct sysreg_table {
    220 	uint32_t code;
    221 	const char *regname;
    222 };
    223 
    224 /* must be sorted by code */
    225 const struct sysreg_table sysreg_table[] = {
    226 	/*	         op0 op1 CRn CRm op2 name			*/
    227 	{	SYSREG_ENC(2, 0,  0,  0, 2), "osdtrrx_el1"		},
    228 	{	SYSREG_ENC(2, 0,  0,  0, 4), "dbgbvr0_el1"		},
    229 	{	SYSREG_ENC(2, 0,  0,  0, 5), "dbgbcr0_el1"		},
    230 	{	SYSREG_ENC(2, 0,  0,  0, 6), "dbgwvr0_el1"		},
    231 	{	SYSREG_ENC(2, 0,  0,  0, 7), "dbgwcr0_el1"		},
    232 	{	SYSREG_ENC(2, 0,  0,  1, 4), "dbgbvr1_el1"		},
    233 	{	SYSREG_ENC(2, 0,  0,  1, 5), "dbgbcr1_el1"		},
    234 	{	SYSREG_ENC(2, 0,  0,  1, 6), "dbgwvr1_el1"		},
    235 	{	SYSREG_ENC(2, 0,  0,  1, 7), "dbgwcr1_el1"		},
    236 	{	SYSREG_ENC(2, 0,  0,  2, 0), "mdccint_el1"		},
    237 	{	SYSREG_ENC(2, 0,  0,  2, 2), "mdscr_el1"		},
    238 	{	SYSREG_ENC(2, 0,  0,  2, 4), "dbgbvr2_el1"		},
    239 	{	SYSREG_ENC(2, 0,  0,  2, 5), "dbgbcr2_el1"		},
    240 	{	SYSREG_ENC(2, 0,  0,  2, 6), "dbgwvr2_el1"		},
    241 	{	SYSREG_ENC(2, 0,  0,  2, 7), "dbgwcr2_el1"		},
    242 	{	SYSREG_ENC(2, 0,  0,  3, 2), "osdtrtx_el1"		},
    243 	{	SYSREG_ENC(2, 0,  0,  3, 4), "dbgbvr3_el1"		},
    244 	{	SYSREG_ENC(2, 0,  0,  3, 5), "dbgbcr3_el1"		},
    245 	{	SYSREG_ENC(2, 0,  0,  3, 6), "dbgwvr3_el1"		},
    246 	{	SYSREG_ENC(2, 0,  0,  3, 7), "dbgwcr3_el1"		},
    247 	{	SYSREG_ENC(2, 0,  0,  4, 4), "dbgbvr4_el1"		},
    248 	{	SYSREG_ENC(2, 0,  0,  4, 5), "dbgbcr4_el1"		},
    249 	{	SYSREG_ENC(2, 0,  0,  4, 6), "dbgwvr4_el1"		},
    250 	{	SYSREG_ENC(2, 0,  0,  4, 7), "dbgwcr4_el1"		},
    251 	{	SYSREG_ENC(2, 0,  0,  5, 4), "dbgbvr5_el1"		},
    252 	{	SYSREG_ENC(2, 0,  0,  5, 5), "dbgbcr5_el1"		},
    253 	{	SYSREG_ENC(2, 0,  0,  5, 6), "dbgwvr5_el1"		},
    254 	{	SYSREG_ENC(2, 0,  0,  5, 7), "dbgwcr5_el1"		},
    255 	{	SYSREG_ENC(2, 0,  0,  6, 2), "oseccr_el1"		},
    256 	{	SYSREG_ENC(2, 0,  0,  6, 4), "dbgbvr6_el1"		},
    257 	{	SYSREG_ENC(2, 0,  0,  6, 5), "dbgbcr6_el1"		},
    258 	{	SYSREG_ENC(2, 0,  0,  6, 6), "dbgwvr6_el1"		},
    259 	{	SYSREG_ENC(2, 0,  0,  6, 7), "dbgwcr6_el1"		},
    260 	{	SYSREG_ENC(2, 0,  0,  7, 4), "dbgbvr7_el1"		},
    261 	{	SYSREG_ENC(2, 0,  0,  7, 5), "dbgbcr7_el1"		},
    262 	{	SYSREG_ENC(2, 0,  0,  7, 6), "dbgwvr7_el1"		},
    263 	{	SYSREG_ENC(2, 0,  0,  7, 7), "dbgwcr7_el1"		},
    264 	{	SYSREG_ENC(2, 0,  0,  8, 4), "dbgbvr8_el1"		},
    265 	{	SYSREG_ENC(2, 0,  0,  8, 5), "dbgbcr8_el1"		},
    266 	{	SYSREG_ENC(2, 0,  0,  8, 6), "dbgwvr8_el1"		},
    267 	{	SYSREG_ENC(2, 0,  0,  8, 7), "dbgwcr8_el1"		},
    268 	{	SYSREG_ENC(2, 0,  0,  9, 4), "dbgbvr9_el1"		},
    269 	{	SYSREG_ENC(2, 0,  0,  9, 5), "dbgbcr9_el1"		},
    270 	{	SYSREG_ENC(2, 0,  0,  9, 6), "dbgwvr9_el1"		},
    271 	{	SYSREG_ENC(2, 0,  0,  9, 7), "dbgwcr9_el1"		},
    272 	{	SYSREG_ENC(2, 0,  0, 10, 4), "dbgbvr10_el1"		},
    273 	{	SYSREG_ENC(2, 0,  0, 10, 5), "dbgbcr10_el1"		},
    274 	{	SYSREG_ENC(2, 0,  0, 10, 6), "dbgwvr10_el1"		},
    275 	{	SYSREG_ENC(2, 0,  0, 10, 7), "dbgwcr10_el1"		},
    276 	{	SYSREG_ENC(2, 0,  0, 11, 4), "dbgbvr11_el1"		},
    277 	{	SYSREG_ENC(2, 0,  0, 11, 5), "dbgbcr11_el1"		},
    278 	{	SYSREG_ENC(2, 0,  0, 11, 6), "dbgwvr11_el1"		},
    279 	{	SYSREG_ENC(2, 0,  0, 11, 7), "dbgwcr11_el1"		},
    280 	{	SYSREG_ENC(2, 0,  0, 12, 4), "dbgbvr12_el1"		},
    281 	{	SYSREG_ENC(2, 0,  0, 12, 5), "dbgbcr12_el1"		},
    282 	{	SYSREG_ENC(2, 0,  0, 12, 6), "dbgwvr12_el1"		},
    283 	{	SYSREG_ENC(2, 0,  0, 12, 7), "dbgwcr12_el1"		},
    284 	{	SYSREG_ENC(2, 0,  0, 13, 4), "dbgbvr13_el1"		},
    285 	{	SYSREG_ENC(2, 0,  0, 13, 5), "dbgbcr13_el1"		},
    286 	{	SYSREG_ENC(2, 0,  0, 13, 6), "dbgwvr13_el1"		},
    287 	{	SYSREG_ENC(2, 0,  0, 13, 7), "dbgwcr13_el1"		},
    288 	{	SYSREG_ENC(2, 0,  0, 14, 4), "dbgbvr14_el1"		},
    289 	{	SYSREG_ENC(2, 0,  0, 14, 5), "dbgbcr14_el1"		},
    290 	{	SYSREG_ENC(2, 0,  0, 14, 6), "dbgwvr14_el1"		},
    291 	{	SYSREG_ENC(2, 0,  0, 14, 7), "dbgwcr14_el1"		},
    292 	{	SYSREG_ENC(2, 0,  0, 15, 4), "dbgbvr15_el1"		},
    293 	{	SYSREG_ENC(2, 0,  0, 15, 5), "dbgbcr15_el1"		},
    294 	{	SYSREG_ENC(2, 0,  0, 15, 6), "dbgwvr15_el1"		},
    295 	{	SYSREG_ENC(2, 0,  0, 15, 7), "dbgwcr15_el1"		},
    296 	{	SYSREG_ENC(2, 0,  1,  0, 0), "mdrar_el1"		},
    297 	{	SYSREG_ENC(2, 0,  1,  0, 4), "oslar_el1"		},
    298 	{	SYSREG_ENC(2, 0,  1,  1, 4), "oslsr_el1"		},
    299 	{	SYSREG_ENC(2, 0,  1,  3, 4), "osdlr_el1"		},
    300 	{	SYSREG_ENC(2, 0,  1,  4, 4), "dbgprcr_el1"		},
    301 	{	SYSREG_ENC(2, 0,  7,  8, 6), "dbgclaimset_el1"		},
    302 	{	SYSREG_ENC(2, 0,  7,  9, 6), "dbgclaimclr_el1"		},
    303 	{	SYSREG_ENC(2, 0,  7, 14, 6), "dbgauthstatus_el1"	},
    304 	{	SYSREG_ENC(2, 2,  0,  0, 0), "teecr32_el1"		},
    305 	{	SYSREG_ENC(2, 2,  1,  0, 0), "teehbr32_el1"		},
    306 	{	SYSREG_ENC(2, 3,  0,  1, 0), "mdccsr_el0"		},
    307 	{	SYSREG_ENC(2, 3,  0,  4, 0), "dbgdtr_el0"		},
    308 	{	SYSREG_ENC(2, 3,  0,  5, 0), "dbgdtrrx_el0"		},
    309 	{	SYSREG_ENC(2, 4,  0,  7, 0), "dbgvcr32_el2"		},
    310 	{	SYSREG_ENC(3, 0,  0,  0, 0), "midr_el1"			},
    311 	{	SYSREG_ENC(3, 0,  0,  0, 5), "mpidr_el1"		},
    312 	{	SYSREG_ENC(3, 0,  0,  0, 6), "revidr_el1"		},
    313 	{	SYSREG_ENC(3, 0,  0,  1, 0), "id_pfr0_el1"		},
    314 	{	SYSREG_ENC(3, 0,  0,  1, 1), "id_pfr1_el1"		},
    315 	{	SYSREG_ENC(3, 0,  0,  1, 2), "id_dfr0_el1"		},
    316 	{	SYSREG_ENC(3, 0,  0,  1, 3), "id_afr0_el1"		},
    317 	{	SYSREG_ENC(3, 0,  0,  1, 4), "id_mmfr0_el1"		},
    318 	{	SYSREG_ENC(3, 0,  0,  1, 5), "id_mmfr1_el1"		},
    319 	{	SYSREG_ENC(3, 0,  0,  1, 6), "id_mmfr2_el1"		},
    320 	{	SYSREG_ENC(3, 0,  0,  1, 7), "id_mmfr3_el1"		},
    321 	{	SYSREG_ENC(3, 0,  0,  2, 0), "id_isar0_el1"		},
    322 	{	SYSREG_ENC(3, 0,  0,  2, 1), "id_isar1_el1"		},
    323 	{	SYSREG_ENC(3, 0,  0,  2, 2), "id_isar2_el1"		},
    324 	{	SYSREG_ENC(3, 0,  0,  2, 3), "id_isar3_el1"		},
    325 	{	SYSREG_ENC(3, 0,  0,  2, 4), "id_isar4_el1"		},
    326 	{	SYSREG_ENC(3, 0,  0,  2, 5), "id_isar5_el1"		},
    327 	{	SYSREG_ENC(3, 0,  0,  2, 6), "id_mmfr4_el1"		},
    328 	{	SYSREG_ENC(3, 0,  0,  2, 7), "id_isar6_el1"		},
    329 	{	SYSREG_ENC(3, 0,  0,  3, 0), "mvfr0_el1"		},
    330 	{	SYSREG_ENC(3, 0,  0,  3, 1), "mvfr1_el1"		},
    331 	{	SYSREG_ENC(3, 0,  0,  3, 2), "mvfr2_el1"		},
    332 	{	SYSREG_ENC(3, 0,  0,  3, 4), "id_pfr2_el1"		},
    333 	{	SYSREG_ENC(3, 0,  0,  3, 5), "id_dfr1_el1"		},
    334 	{	SYSREG_ENC(3, 0,  0,  3, 6), "id_mmfr5_el1"		},
    335 	{	SYSREG_ENC(3, 0,  0,  4, 0), "id_aa64pfr0_el1"		},
    336 	{	SYSREG_ENC(3, 0,  0,  4, 1), "id_aa64pfr1_el1"		},
    337 	{	SYSREG_ENC(3, 0,  0,  5, 0), "id_aa64dfr0_el1"		},
    338 	{	SYSREG_ENC(3, 0,  0,  5, 1), "id_aa64dfr1_el1"		},
    339 	{	SYSREG_ENC(3, 0,  0,  5, 4), "id_aa64afr0_el1"		},
    340 	{	SYSREG_ENC(3, 0,  0,  5, 5), "id_aa64afr1_el1"		},
    341 	{	SYSREG_ENC(3, 0,  0,  6, 0), "id_aa64isar0_el1"		},
    342 	{	SYSREG_ENC(3, 0,  0,  6, 1), "id_aa64isar1_el1"		},
    343 	{	SYSREG_ENC(3, 0,  0,  7, 0), "id_aa64mmfr0_el1"		},
    344 	{	SYSREG_ENC(3, 0,  0,  7, 1), "id_aa64mmfr1_el1"		},
    345 	{	SYSREG_ENC(3, 0,  0,  7, 2), "id_aa64mmfr2_el1"		},
    346 	{	SYSREG_ENC(3, 0,  1,  0, 0), "sctlr_el1"		},
    347 	{	SYSREG_ENC(3, 0,  1,  0, 1), "actlr_el1"		},
    348 	{	SYSREG_ENC(3, 0,  1,  0, 2), "cpacr_el1"		},
    349 	{	SYSREG_ENC(3, 0,  1,  0, 5), "rgsr_el1"			},
    350 	{	SYSREG_ENC(3, 0,  1,  0, 6), "gcr_el1"			},
    351 	{	SYSREG_ENC(3, 0,  2,  0, 0), "ttbr0_el1"		},
    352 	{	SYSREG_ENC(3, 0,  2,  0, 1), "ttbr1_el1"		},
    353 	{	SYSREG_ENC(3, 0,  2,  0, 2), "tcr_el1"			},
    354 	{	SYSREG_ENC(3, 0,  2,  1, 0), "apiakeylo_el1"		},
    355 	{	SYSREG_ENC(3, 0,  2,  1, 1), "apiakeyhi_el1"		},
    356 	{	SYSREG_ENC(3, 0,  2,  1, 2), "apibkeylo_el1"		},
    357 	{	SYSREG_ENC(3, 0,  2,  1, 3), "apibkeyhi_el1"		},
    358 	{	SYSREG_ENC(3, 0,  2,  2, 0), "apdakeylo_el1"		},
    359 	{	SYSREG_ENC(3, 0,  2,  2, 1), "apdakeyhi_el1"		},
    360 	{	SYSREG_ENC(3, 0,  2,  2, 2), "apdbkeylo_el1"		},
    361 	{	SYSREG_ENC(3, 0,  2,  2, 3), "apdbkeyhi_el1"		},
    362 	{	SYSREG_ENC(3, 0,  2,  3, 0), "apgakeylo_el1"		},
    363 	{	SYSREG_ENC(3, 0,  2,  3, 1), "apgakeyhi_el1"		},
    364 	{	SYSREG_ENC(3, 0,  4,  0, 0), "spsr_el1"			},
    365 	{	SYSREG_ENC(3, 0,  4,  0, 1), "elr_el1"			},
    366 	{	SYSREG_ENC(3, 0,  4,  1, 0), "sp_el0"			},
    367 	{	SYSREG_ENC(3, 0,  4,  2, 0), "spsel"			},
    368 	{	SYSREG_ENC(3, 0,  4,  2, 2), "currentel"		},
    369 	{	SYSREG_ENC(3, 0,  4,  2, 3), "pan"			},
    370 	{	SYSREG_ENC(3, 0,  4,  2, 4), "uao"			},
    371 	{	SYSREG_ENC(3, 0,  5,  1, 0), "afsr0_el1"		},
    372 	{	SYSREG_ENC(3, 0,  5,  1, 1), "afsr1_el1"		},
    373 	{	SYSREG_ENC(3, 0,  5,  2, 0), "esr_el1"			},
    374 	{	SYSREG_ENC(3, 0,  5,  6, 0), "tfsr_el1"			},
    375 	{	SYSREG_ENC(3, 0,  5,  6, 1), "tfsre0_el1"		},
    376 	{	SYSREG_ENC(3, 0,  6,  0, 0), "far_el1"			},
    377 	{	SYSREG_ENC(3, 0,  7,  4, 0), "par_el1"			},
    378 	{	SYSREG_ENC(3, 0,  9, 14, 1), "pmintenset_el1"		},
    379 	{	SYSREG_ENC(3, 0,  9, 14, 2), "pmintenclr_el1"		},
    380 	{	SYSREG_ENC(3, 0, 10,  2, 0), "mair_el1"			},
    381 	{	SYSREG_ENC(3, 0, 10,  3, 0), "amair_el1"		},
    382 	{	SYSREG_ENC(3, 0, 10,  4, 0), "lorsa_el1"		},
    383 	{	SYSREG_ENC(3, 0, 10,  4, 1), "lorea_el1"		},
    384 	{	SYSREG_ENC(3, 0, 10,  4, 2), "lorn_el1"			},
    385 	{	SYSREG_ENC(3, 0, 10,  4, 3), "lorc_el1"			},
    386 	{	SYSREG_ENC(3, 0, 10,  4, 7), "lorid_el1"		},
    387 	{	SYSREG_ENC(3, 0, 12,  0, 0), "vbar_el1"			},
    388 	{	SYSREG_ENC(3, 0, 12,  0, 1), "rvbar_el1"		},
    389 	{	SYSREG_ENC(3, 0, 12,  0, 2), "rmr_el1"			},
    390 	{	SYSREG_ENC(3, 0, 12,  1, 0), "isr_el1"			},
    391 	{	SYSREG_ENC(3, 0, 13,  0, 1), "contextidr_el1"		},
    392 	{	SYSREG_ENC(3, 0, 13,  0, 4), "tpidr_el1"		},
    393 	{	SYSREG_ENC(3, 0, 13,  0, 7), "scxtnum_el1"		},
    394 	{	SYSREG_ENC(3, 0, 14,  1, 0), "cntkctl_el1"		},
    395 	{	SYSREG_ENC(3, 1,  0,  0, 0), "ccsidr_el1"		},
    396 	{	SYSREG_ENC(3, 1,  0,  0, 1), "clidr_el1"		},
    397 	{	SYSREG_ENC(3, 1,  0,  0, 2), "ccsidr2_el1"		},
    398 	{	SYSREG_ENC(3, 1,  0,  0, 4), "gmid_el1"			},
    399 	{	SYSREG_ENC(3, 1,  0,  0, 7), "aidr_el1"			},
    400 	{	SYSREG_ENC(3, 2,  0,  0, 0), "csselr_el1"		},
    401 	{	SYSREG_ENC(3, 3,  0,  0, 1), "ctr_el0"			},
    402 	{	SYSREG_ENC(3, 3,  0,  0, 7), "dczid_el0"		},
    403 	{	SYSREG_ENC(3, 3,  2,  4, 0), "rndr"			},
    404 	{	SYSREG_ENC(3, 3,  2,  4, 1), "rndrrs"			},
    405 	{	SYSREG_ENC(3, 3,  4,  2, 0), "nzcv"			},
    406 	{	SYSREG_ENC(3, 3,  4,  2, 1), "daif"			},
    407 	{	SYSREG_ENC(3, 3,  4,  2, 5), "dit"			},
    408 	{	SYSREG_ENC(3, 3,  4,  2, 6), "ssbs"			},
    409 	{	SYSREG_ENC(3, 3,  4,  2, 7), "tco"			},
    410 	{	SYSREG_ENC(3, 3,  4,  4, 0), "fpcr"			},
    411 	{	SYSREG_ENC(3, 3,  4,  4, 1), "fpsr"			},
    412 	{	SYSREG_ENC(3, 3,  4,  5, 0), "dspsr_el0"		},
    413 	{	SYSREG_ENC(3, 3,  4,  5, 1), "dlr_el0"			},
    414 	{	SYSREG_ENC(3, 3,  9, 12, 0), "pmcr_el0"			},
    415 	{	SYSREG_ENC(3, 3,  9, 12, 1), "pmcntenset_el0"		},
    416 	{	SYSREG_ENC(3, 3,  9, 12, 2), "pmcntenclr_el0"		},
    417 	{	SYSREG_ENC(3, 3,  9, 12, 3), "pmovsclr_el0"		},
    418 	{	SYSREG_ENC(3, 3,  9, 12, 4), "pmswinc_el0"		},
    419 	{	SYSREG_ENC(3, 3,  9, 12, 5), "pmselr_el0"		},
    420 	{	SYSREG_ENC(3, 3,  9, 12, 6), "pmceid0_el0"		},
    421 	{	SYSREG_ENC(3, 3,  9, 12, 7), "pmceid1_el0"		},
    422 	{	SYSREG_ENC(3, 3,  9, 13, 0), "pmccntr_el0"		},
    423 	{	SYSREG_ENC(3, 3,  9, 13, 1), "pmxevtyper_el0"		},
    424 	{	SYSREG_ENC(3, 3,  9, 13, 2), "pmxevcntr_el0"		},
    425 	{	SYSREG_ENC(3, 3,  9, 14, 0), "pmuserenr_el0"		},
    426 	{	SYSREG_ENC(3, 3,  9, 14, 3), "pmovsset_el0"		},
    427 	{	SYSREG_ENC(3, 3, 13,  0, 2), "tpidr_el0"		},
    428 	{	SYSREG_ENC(3, 3, 13,  0, 3), "tpidrro_el0"		},
    429 	{	SYSREG_ENC(3, 3, 13,  0, 7), "scxtnum_el0"		},
    430 	{	SYSREG_ENC(3, 3, 14,  0, 0), "cntfrq_el0"		},
    431 	{	SYSREG_ENC(3, 3, 14,  0, 1), "cntpct_el0"		},
    432 	{	SYSREG_ENC(3, 3, 14,  0, 2), "cntvct_el0"		},
    433 	{	SYSREG_ENC(3, 3, 14,  2, 0), "cntp_tval_el0"		},
    434 	{	SYSREG_ENC(3, 3, 14,  2, 1), "cntp_ctl_el0"		},
    435 	{	SYSREG_ENC(3, 3, 14,  2, 2), "cntp_cval_el0"		},
    436 	{	SYSREG_ENC(3, 3, 14,  3, 0), "cntv_tval_el0"		},
    437 	{	SYSREG_ENC(3, 3, 14,  3, 1), "cntv_ctl_el0"		},
    438 	{	SYSREG_ENC(3, 3, 14,  3, 2), "cntv_cval_el0"		},
    439 	{	SYSREG_ENC(3, 3, 14,  8, 0), "pmevcntr0_el0"		},
    440 	{	SYSREG_ENC(3, 3, 14,  8, 1), "pmevcntr1_el0"		},
    441 	{	SYSREG_ENC(3, 3, 14,  8, 2), "pmevcntr2_el0"		},
    442 	{	SYSREG_ENC(3, 3, 14,  8, 3), "pmevcntr3_el0"		},
    443 	{	SYSREG_ENC(3, 3, 14,  8, 4), "pmevcntr4_el0"		},
    444 	{	SYSREG_ENC(3, 3, 14,  8, 5), "pmevcntr5_el0"		},
    445 	{	SYSREG_ENC(3, 3, 14,  8, 6), "pmevcntr6_el0"		},
    446 	{	SYSREG_ENC(3, 3, 14,  8, 7), "pmevcntr7_el0"		},
    447 	{	SYSREG_ENC(3, 3, 14,  9, 0), "pmevcntr8_el0"		},
    448 	{	SYSREG_ENC(3, 3, 14,  9, 1), "pmevcntr9_el0"		},
    449 	{	SYSREG_ENC(3, 3, 14,  9, 2), "pmevcntr10_el0"		},
    450 	{	SYSREG_ENC(3, 3, 14,  9, 3), "pmevcntr11_el0"		},
    451 	{	SYSREG_ENC(3, 3, 14,  9, 4), "pmevcntr12_el0"		},
    452 	{	SYSREG_ENC(3, 3, 14,  9, 5), "pmevcntr13_el0"		},
    453 	{	SYSREG_ENC(3, 3, 14,  9, 6), "pmevcntr14_el0"		},
    454 	{	SYSREG_ENC(3, 3, 14,  9, 7), "pmevcntr15_el0"		},
    455 	{	SYSREG_ENC(3, 3, 14, 10, 0), "pmevcntr16_el0"		},
    456 	{	SYSREG_ENC(3, 3, 14, 10, 1), "pmevcntr17_el0"		},
    457 	{	SYSREG_ENC(3, 3, 14, 10, 2), "pmevcntr18_el0"		},
    458 	{	SYSREG_ENC(3, 3, 14, 10, 3), "pmevcntr19_el0"		},
    459 	{	SYSREG_ENC(3, 3, 14, 10, 4), "pmevcntr20_el0"		},
    460 	{	SYSREG_ENC(3, 3, 14, 10, 5), "pmevcntr21_el0"		},
    461 	{	SYSREG_ENC(3, 3, 14, 10, 6), "pmevcntr22_el0"		},
    462 	{	SYSREG_ENC(3, 3, 14, 10, 7), "pmevcntr23_el0"		},
    463 	{	SYSREG_ENC(3, 3, 14, 11, 0), "pmevcntr24_el0"		},
    464 	{	SYSREG_ENC(3, 3, 14, 11, 1), "pmevcntr25_el0"		},
    465 	{	SYSREG_ENC(3, 3, 14, 11, 2), "pmevcntr26_el0"		},
    466 	{	SYSREG_ENC(3, 3, 14, 11, 3), "pmevcntr27_el0"		},
    467 	{	SYSREG_ENC(3, 3, 14, 11, 4), "pmevcntr28_el0"		},
    468 	{	SYSREG_ENC(3, 3, 14, 11, 5), "pmevcntr29_el0"		},
    469 	{	SYSREG_ENC(3, 3, 14, 11, 6), "pmevcntr30_el0"		},
    470 	{	SYSREG_ENC(3, 3, 14, 12, 0), "pmevtyper0_el0"		},
    471 	{	SYSREG_ENC(3, 3, 14, 12, 1), "pmevtyper1_el0"		},
    472 	{	SYSREG_ENC(3, 3, 14, 12, 2), "pmevtyper2_el0"		},
    473 	{	SYSREG_ENC(3, 3, 14, 12, 3), "pmevtyper3_el0"		},
    474 	{	SYSREG_ENC(3, 3, 14, 12, 4), "pmevtyper4_el0"		},
    475 	{	SYSREG_ENC(3, 3, 14, 12, 5), "pmevtyper5_el0"		},
    476 	{	SYSREG_ENC(3, 3, 14, 12, 6), "pmevtyper6_el0"		},
    477 	{	SYSREG_ENC(3, 3, 14, 12, 7), "pmevtyper7_el0"		},
    478 	{	SYSREG_ENC(3, 3, 14, 13, 0), "pmevtyper8_el0"		},
    479 	{	SYSREG_ENC(3, 3, 14, 13, 1), "pmevtyper9_el0"		},
    480 	{	SYSREG_ENC(3, 3, 14, 13, 2), "pmevtyper10_el0"		},
    481 	{	SYSREG_ENC(3, 3, 14, 13, 3), "pmevtyper11_el0"		},
    482 	{	SYSREG_ENC(3, 3, 14, 13, 4), "pmevtyper12_el0"		},
    483 	{	SYSREG_ENC(3, 3, 14, 13, 5), "pmevtyper13_el0"		},
    484 	{	SYSREG_ENC(3, 3, 14, 13, 6), "pmevtyper14_el0"		},
    485 	{	SYSREG_ENC(3, 3, 14, 13, 7), "pmevtyper15_el0"		},
    486 	{	SYSREG_ENC(3, 3, 14, 14, 0), "pmevtyper16_el0"		},
    487 	{	SYSREG_ENC(3, 3, 14, 14, 1), "pmevtyper17_el0"		},
    488 	{	SYSREG_ENC(3, 3, 14, 14, 2), "pmevtyper18_el0"		},
    489 	{	SYSREG_ENC(3, 3, 14, 14, 3), "pmevtyper19_el0"		},
    490 	{	SYSREG_ENC(3, 3, 14, 14, 4), "pmevtyper20_el0"		},
    491 	{	SYSREG_ENC(3, 3, 14, 14, 5), "pmevtyper21_el0"		},
    492 	{	SYSREG_ENC(3, 3, 14, 14, 6), "pmevtyper22_el0"		},
    493 	{	SYSREG_ENC(3, 3, 14, 14, 7), "pmevtyper23_el0"		},
    494 	{	SYSREG_ENC(3, 3, 14, 15, 0), "pmevtyper24_el0"		},
    495 	{	SYSREG_ENC(3, 3, 14, 15, 1), "pmevtyper25_el0"		},
    496 	{	SYSREG_ENC(3, 3, 14, 15, 2), "pmevtyper26_el0"		},
    497 	{	SYSREG_ENC(3, 3, 14, 15, 3), "pmevtyper27_el0"		},
    498 	{	SYSREG_ENC(3, 3, 14, 15, 4), "pmevtyper28_el0"		},
    499 	{	SYSREG_ENC(3, 3, 14, 15, 5), "pmevtyper29_el0"		},
    500 	{	SYSREG_ENC(3, 3, 14, 15, 6), "pmevtyper30_el0"		},
    501 	{	SYSREG_ENC(3, 3, 14, 15, 7), "pmccfiltr_el0"		},
    502 	{	SYSREG_ENC(3, 4,  0,  0, 0), "vpidr_el2"		},
    503 	{	SYSREG_ENC(3, 4,  0,  0, 5), "vmpidr_el2"		},
    504 	{	SYSREG_ENC(3, 4,  1,  0, 0), "sctlr_el2"		},
    505 	{	SYSREG_ENC(3, 4,  1,  0, 1), "actlr_el2"		},
    506 	{	SYSREG_ENC(3, 4,  1,  1, 0), "hcr_el2"			},
    507 	{	SYSREG_ENC(3, 4,  1,  1, 1), "mdcr_el2"			},
    508 	{	SYSREG_ENC(3, 4,  1,  1, 2), "cptr_el2"			},
    509 	{	SYSREG_ENC(3, 4,  1,  1, 3), "hstr_el2"			},
    510 	{	SYSREG_ENC(3, 4,  1,  1, 4), "hfgrtr_el2"		},
    511 	{	SYSREG_ENC(3, 4,  1,  1, 5), "hfgwtr_el2"		},
    512 	{	SYSREG_ENC(3, 4,  1,  1, 6), "hfgitr_el2"		},
    513 	{	SYSREG_ENC(3, 4,  1,  1, 7), "hacr_el2"			},
    514 	{	SYSREG_ENC(3, 4,  2,  0, 0), "ttbr0_el2"		},
    515 	{	SYSREG_ENC(3, 4,  2,  0, 1), "ttbr1_el2"		},
    516 	{	SYSREG_ENC(3, 4,  2,  0, 2), "tcr_el2"			},
    517 	{	SYSREG_ENC(3, 4,  2,  1, 0), "vttbr_el2"		},
    518 	{	SYSREG_ENC(3, 4,  2,  1, 2), "vtcr_el2"			},
    519 	{	SYSREG_ENC(3, 4,  2,  2, 0), "vncr_el2"			},
    520 	{	SYSREG_ENC(3, 4,  2,  6, 0), "vsttbr_el2"		},
    521 	{	SYSREG_ENC(3, 4,  2,  6, 2), "vstcr_el2"		},
    522 	{	SYSREG_ENC(3, 4,  3,  0, 0), "dacr32_el2"		},
    523 	{	SYSREG_ENC(3, 4,  3,  1, 4), "hdfgrtr_el2"		},
    524 	{	SYSREG_ENC(3, 4,  3,  1, 5), "hdfgwtr_el2"		},
    525 	{	SYSREG_ENC(3, 4,  3,  1, 6), "hafgrtr_el2"		},
    526 	{	SYSREG_ENC(3, 4,  4,  0, 0), "spsr_el2"			},
    527 	{	SYSREG_ENC(3, 4,  4,  0, 1), "elr_el2"			},
    528 	{	SYSREG_ENC(3, 4,  4,  1, 0), "sp_el1"			},
    529 	{	SYSREG_ENC(3, 4,  4,  3, 0), "spsr_irq"			},
    530 	{	SYSREG_ENC(3, 4,  4,  3, 1), "spsr_abt"			},
    531 	{	SYSREG_ENC(3, 4,  4,  3, 2), "spsr_und"			},
    532 	{	SYSREG_ENC(3, 4,  4,  3, 3), "spsr_fiq"			},
    533 	{	SYSREG_ENC(3, 4,  5,  0, 1), "ifsr32_el2"		},
    534 	{	SYSREG_ENC(3, 4,  5,  1, 0), "afsr0_el2"		},
    535 	{	SYSREG_ENC(3, 4,  5,  1, 1), "afsr1_el2"		},
    536 	{	SYSREG_ENC(3, 4,  5,  2, 0), "esr_el2"			},
    537 	{	SYSREG_ENC(3, 4,  5,  3, 0), "fpexc32_el2"		},
    538 	{	SYSREG_ENC(3, 4,  5,  6, 0), "tfsr_el2"			},
    539 	{	SYSREG_ENC(3, 4,  6,  0, 0), "far_el2"			},
    540 	{	SYSREG_ENC(3, 4,  6,  0, 4), "hpfar_el2"		},
    541 	{	SYSREG_ENC(3, 4, 10,  2, 0), "mair_el2"			},
    542 	{	SYSREG_ENC(3, 4, 10,  3, 0), "amair_el2"		},
    543 	{	SYSREG_ENC(3, 4, 12,  0, 0), "vbar_el2"			},
    544 	{	SYSREG_ENC(3, 4, 12,  0, 1), "rvbar_el2"		},
    545 	{	SYSREG_ENC(3, 4, 12,  0, 2), "rmr_el2"			},
    546 	{	SYSREG_ENC(3, 4, 13,  0, 1), "contextidr_el2"		},
    547 	{	SYSREG_ENC(3, 4, 13,  0, 2), "tpidr_el2"		},
    548 	{	SYSREG_ENC(3, 4, 13,  0, 7), "scxtnum_el2"		},
    549 	{	SYSREG_ENC(3, 4, 14,  0, 3), "cntvoff_el2"		},
    550 	{	SYSREG_ENC(3, 4, 14,  1, 0), "cnthctl_el2"		},
    551 	{	SYSREG_ENC(3, 4, 14,  2, 0), "cnthp_tval_el2"		},
    552 	{	SYSREG_ENC(3, 4, 14,  2, 1), "cnthp_ctl_el2"		},
    553 	{	SYSREG_ENC(3, 4, 14,  2, 2), "cnthp_cval_el2"		},
    554 	{	SYSREG_ENC(3, 4, 14,  3, 0), "cnthv_tval_el2"		},
    555 	{	SYSREG_ENC(3, 4, 14,  3, 1), "cnthv_ctl_el2"		},
    556 	{	SYSREG_ENC(3, 4, 14,  3, 2), "cnthv_cval_el2"		},
    557 	{	SYSREG_ENC(3, 4, 14,  4, 0), "cnthvs_tval_el2"		},
    558 	{	SYSREG_ENC(3, 4, 14,  4, 1), "cnthvs_ctl_el2"		},
    559 	{	SYSREG_ENC(3, 4, 14,  4, 2), "cnthvs_cval_el2"		},
    560 	{	SYSREG_ENC(3, 4, 14,  5, 0), "cnthps_tval_el2"		},
    561 	{	SYSREG_ENC(3, 4, 14,  5, 1), "cnthps_ctl_el2"		},
    562 	{	SYSREG_ENC(3, 4, 14,  5, 2), "cnthps_cval_el2"		},
    563 	{	SYSREG_ENC(3, 6,  1,  0, 0), "sctlr_el3"		},
    564 	{	SYSREG_ENC(3, 6,  1,  0, 1), "actlr_el3"		},
    565 	{	SYSREG_ENC(3, 6,  1,  1, 0), "scr_el3"			},
    566 	{	SYSREG_ENC(3, 6,  1,  1, 1), "sder32_el3"		},
    567 	{	SYSREG_ENC(3, 6,  1,  1, 2), "cptr_el3"			},
    568 	{	SYSREG_ENC(3, 6,  1,  3, 1), "mdcr_el3"			},
    569 	{	SYSREG_ENC(3, 6,  2,  0, 0), "ttbr0_el3"		},
    570 	{	SYSREG_ENC(3, 6,  2,  0, 2), "tcr_el3"			},
    571 	{	SYSREG_ENC(3, 6,  4,  0, 0), "spsr_el3"			},
    572 	{	SYSREG_ENC(3, 6,  4,  0, 1), "elr_el3"			},
    573 	{	SYSREG_ENC(3, 6,  4,  1, 0), "sp_el2"			},
    574 	{	SYSREG_ENC(3, 6,  5,  1, 0), "afsr0_el3"		},
    575 	{	SYSREG_ENC(3, 6,  5,  1, 1), "afsr1_el3"		},
    576 	{	SYSREG_ENC(3, 6,  5,  2, 0), "esr_el3"			},
    577 	{	SYSREG_ENC(3, 6,  5,  6, 0), "tfsr_el3"			},
    578 	{	SYSREG_ENC(3, 6,  6,  0, 0), "far_el3"			},
    579 	{	SYSREG_ENC(3, 6, 10,  2, 0), "mair_el3"			},
    580 	{	SYSREG_ENC(3, 6, 10,  3, 0), "amair_el3"		},
    581 	{	SYSREG_ENC(3, 6, 12,  0, 0), "vbar_el3"			},
    582 	{	SYSREG_ENC(3, 6, 12,  0, 1), "rvbar_el3"		},
    583 	{	SYSREG_ENC(3, 6, 12,  0, 2), "rmr_el3"			},
    584 	{	SYSREG_ENC(3, 6, 13,  0, 2), "tpidr_el3"		},
    585 	{	SYSREG_ENC(3, 6, 13,  0, 7), "scxtnum_el3"		},
    586 	{	SYSREG_ENC(3, 7, 14,  2, 0), "cntps_tval_el1"		},
    587 	{	SYSREG_ENC(3, 7, 14,  2, 1), "cntps_ctl_el1"		},
    588 	{	SYSREG_ENC(3, 7, 14,  2, 2), "cntps_cval_el1"		}
    589 };
    590 
    591 static const char *
    592 sysregname_bsearch(uint32_t code)
    593 {
    594 	const struct sysreg_table *base, *p;
    595 	unsigned int lim;
    596 	int32_t cmp;
    597 
    598 	base = sysreg_table;
    599 	for (lim = __arraycount(sysreg_table); lim != 0; lim >>= 1) {
    600 		p = base + (lim >> 1);
    601 		cmp = code - p->code;
    602 		if (cmp == 0)
    603 			return p->regname;
    604 		if (cmp > 0) {
    605 			base = p + 1;
    606 			lim--;
    607 		}
    608 	}
    609 	return NULL;
    610 }
    611 
    612 #define SYSREG_OP_READ	0x01
    613 #define SYSREG_OP_WRITE	0x02
    614 
    615 static const char *
    616 sysregname(char *buf, size_t buflen, uint32_t rw,
    617     uint64_t op0, uint64_t op1, uint64_t CRn, uint64_t CRm, uint64_t op2)
    618 {
    619 	const char *name;
    620 	uint32_t code;
    621 
    622 	code = SYSREG_ENC(op0, op1, CRn, CRm, op2);
    623 
    624 	/* special case for dbgdtrrx_el0(RO) and dbgdtrtx_el0(WO) */
    625 	if (code == SYSREG_ENC(2,3,0,5,0)) {
    626 		if (rw & SYSREG_OP_WRITE)
    627 			return "dbgdtrtx_el0";
    628 		return "dbgdtrrx_el0";
    629 	}
    630 
    631 	name = sysregname_bsearch(code);
    632 	if (name == NULL) {
    633 #define SYSREGNAMEBUFLEN	sizeof("s99_99_c99_c99_99")
    634 		snprintf(buf, buflen, "s%u_%u_c%u_c%u_%u",
    635 		    (u_int)op0, (u_int)op1, (u_int)CRn, (u_int)CRm, (u_int)op2);
    636 		return buf;
    637 	}
    638 	return name;
    639 }
    640 #define RSYSREGNAME(buf, buflen, op0, op1, CRn, CRm, op2)		\
    641 	sysregname(buf, buflen, SYSREG_OP_READ, op0, op1, CRn, CRm, op2)
    642 #define WSYSREGNAME(buf, buflen, op0, op1, CRn, CRm, op2)		\
    643 	sysregname(buf, buflen, SYSREG_OP_WRITE, op0, op1, CRn, CRm, op2)
    644 
    645 
    646 static uint64_t
    647 SignExtend(int bitwidth, uint64_t imm, unsigned int multiply)
    648 {
    649 	const uint64_t signbit = ((uint64_t)1 << (bitwidth - 1));
    650 	const uint64_t immmax = signbit << 1;
    651 
    652 	if (imm & signbit)
    653 		imm -= immmax;
    654 	return imm * multiply;
    655 }
    656 
    657 static uint64_t
    658 ZeroExtend(int bitwidth, uint64_t imm, unsigned int multiply)
    659 {
    660 	return imm * multiply;
    661 }
    662 
    663 /* rotate right. if n < 0, rotate left. */
    664 static uint64_t
    665 rotate(int bitwidth, uint64_t v, int n)
    666 {
    667 	uint64_t result;
    668 
    669 	n &= (bitwidth - 1);
    670 	result = (((v << (bitwidth - n)) | (v >> n)));
    671 	if (bitwidth < 64)
    672 		result &= ((1ULL << bitwidth) - 1);
    673 	return result;
    674 }
    675 
    676 static bool
    677 ValidBitMasks(uint64_t sf, uint64_t n, uint64_t imms, uint64_t immr)
    678 {
    679 	int esize, len;
    680 
    681 	if ((sf == 0) && (n != 0))
    682 		return false;
    683 
    684 	len = fls64((n << 6) + (~imms & 0x3f)) - 1;
    685 	if (len < 0)
    686 		return false;
    687 
    688 	esize = (1 << len);
    689 	imms &= (esize - 1);
    690 	if (imms == (uint64_t)(esize - 1))
    691 		return false;
    692 
    693 	return true;
    694 }
    695 
    696 static uint64_t
    697 DecodeBitMasks(uint64_t sf, uint64_t n, uint64_t imms, uint64_t immr)
    698 {
    699 	const int bitwidth = (sf == 0) ? 32 : 64;
    700 	uint64_t result;
    701 	int esize, len;
    702 
    703 	len = fls64((n << 6) + (~imms & 0x3f)) - 1;
    704 	esize = (1 << len);
    705 	imms &= (esize - 1);
    706 	immr &= (esize - 1);
    707 	result = rotate(esize, (1ULL << (imms + 1)) - 1, immr);
    708 	while (esize < bitwidth) {
    709 		result |= (result << esize);
    710 		esize <<= 1;
    711 	}
    712 	if (sf == 0)
    713 		result &= ((1ULL << bitwidth) - 1);
    714 	return result;
    715 }
    716 
    717 static bool
    718 MoveWidePreferred(uint64_t sf, uint64_t n, uint64_t imms, uint64_t immr)
    719 {
    720 #if 1
    721 	uint64_t x = DecodeBitMasks(sf, n, imms, immr);
    722 
    723 	if (sf == 0)
    724 		x &= 0xffffffff;
    725 	if (((x & 0xffffffffffff0000UL) == 0) ||
    726 	    ((x & 0xffffffff0000ffffUL) == 0) ||
    727 	    ((x & 0xffff0000ffffffffUL) == 0) ||
    728 	    ((x & 0x0000ffffffffffffUL) == 0))
    729 		return true;
    730 
    731 	x = ~x;
    732 	if (sf == 0)
    733 		x &= 0xffffffff;
    734 	if (((x & 0xffffffffffff0000UL) == 0) ||
    735 	    ((x & 0xffffffff0000ffffUL) == 0) ||
    736 	    ((x & 0xffff0000ffffffffUL) == 0) ||
    737 	    ((x & 0x0000ffffffffffffUL) == 0))
    738 		return true;
    739 
    740 	return false;
    741 #else
    742 	const int bitwidth = (sf == 0) ? 32 : 64;
    743 
    744 	if ((sf != 0) && (n == 0))
    745 		return false;
    746 	if ((sf == 0) && ((n != 0) || (immr > 0x1f)))
    747 		return false;
    748 	if (imms < 16)
    749 		return ((-immr & 15) <= (15 - imms));
    750 	if (imms >= (uint64_t)(bitwidth - 15))
    751 		return ((immr & 15) <= (imms - (bitwidth - 15)));
    752 	return false;
    753 #endif
    754 }
    755 
    756 static bool
    757 BFXPreferred(uint64_t sf, uint64_t opc, uint64_t imms, uint64_t immr)
    758 {
    759 	const uint64_t bitwidth = (sf == 0) ? 32 : 64;
    760 
    761 	if (imms < immr)
    762 		return false;
    763 	if (imms == (bitwidth - 1))
    764 		return false;
    765 	if (immr == 0) {
    766 		if ((sf == 0) && ((imms == 7) || (imms == 15)))
    767 			return false;
    768 		if ((sf != 0) && (opc == 0) &&
    769 		    ((imms == 7) || (imms == 15) || (imms == 31)))
    770 			return false;
    771 	}
    772 
    773 	return true;
    774 }
    775 
    776 #define SHIFTOP2(s, op1, op2)					\
    777 	((const char *[]){ op1, op2 })[(s) & 1]
    778 #define SHIFTOP4(s, op1, op2, op3, op4)				\
    779 	((const char *[]){ op1, op2, op3, op4 })[(s) & 3]
    780 #define SHIFTOP8(s, op1, op2, op3, op4, op5, op6, op7, op8)	\
    781 	((const char *[]){ op1, op2, op3, op4, op5, op6, op7, op8 })[(s) & 7]
    782 
    783 static const char *
    784 DecodeShift(uint64_t shift)
    785 {
    786 	return SHIFTOP4(shift, "lsl", "lsr", "asr", "ror");
    787 }
    788 
    789 #ifdef DISASM_WITH_COMMENT
    790 #define UNDEFINED(pc, insn, comment)	\
    791 	PRINTF(".insn\t0x%08x\t# %s\n", insn, comment);
    792 #else
    793 #define UNDEFINED(pc, insn, comment)	\
    794 	PRINTF(".insn\t0x%08x\n", insn);
    795 #endif
    796 
    797 static void
    798 extendreg_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
    799     uint64_t sf, uint64_t Rm, uint64_t option, uint64_t imm3,
    800     uint64_t Rn, uint64_t Rd,
    801     const char *op, const char *z_op)
    802 {
    803 	const int r = (sf == 0) ? 0 : ((option & 3) == 3) ? 1 : 0;
    804 
    805 	if ((z_op != NULL) && (Rd == 31)) {
    806 		PRINTF("%s\t", z_op);
    807 	} else {
    808 		PRINTF("%s\t%s, ", op, SREGNAME(sf, Rd));
    809 	}
    810 
    811 	PRINTF("%s, %s", SREGNAME(sf, Rn), ZREGNAME(r, Rm));
    812 
    813 	if ((Rd == 31) || (Rn == 31)) {
    814 		if (imm3 == 0) {
    815 			if (!((sf == 0) && (option == 2)) &&
    816 			    !((sf != 0) && (option == 3))) {
    817 				PRINTF(", %s",
    818 				    SHIFTOP8(option,
    819 				    "uxtb", "uxth", "uxtw", "uxtx",
    820 				    "sxtb", "sxth", "sxtw", "sxtx"));
    821 			}
    822 		} else {
    823 			PRINTF(", %s #%u",
    824 			    SHIFTOP8(option,
    825 			    "uxtb", "uxth", "lsl", "lsl",
    826 			    "sxtb", "sxth", "sxtw", "sxtx"),
    827 			    (u_int)imm3);
    828 		}
    829 	} else {
    830 		PRINTF(", %s",
    831 		    SHIFTOP8(option,
    832 		    "uxtb", "uxth", "uxtw", "uxtx",
    833 		    "sxtb", "sxth", "sxtw", "sxtx"));
    834 		if (imm3 != 0)
    835 			PRINTF(" #%u", (u_int)imm3);
    836 	}
    837 	PRINTF("\n");
    838 }
    839 
    840 static void
    841 shiftreg_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
    842     uint64_t sf, uint64_t shift, uint64_t Rm, uint64_t imm6,
    843     uint64_t Rn, uint64_t Rd,
    844     const char *dnm_op, const char *dzm_op, const char *znm_op)
    845 {
    846 	if ((sf == 0) && (imm6 >= 32)) {
    847 		UNDEFINED(pc, insn, "illegal imm6");
    848 		return;
    849 	}
    850 
    851 	if ((dzm_op != NULL) && (Rn == 31)) {
    852 		PRINTF("%s\t%s, %s",
    853 		    dzm_op,
    854 		    ZREGNAME(sf, Rd),
    855 		    ZREGNAME(sf, Rm));
    856 	} else if ((znm_op != NULL) && (Rd == 31)) {
    857 		PRINTF("%s\t%s, %s",
    858 		    znm_op,
    859 		    ZREGNAME(sf, Rn),
    860 		    ZREGNAME(sf, Rm));
    861 	} else {
    862 		PRINTF("%s\t%s, %s, %s",
    863 		    dnm_op,
    864 		    ZREGNAME(sf, Rd),
    865 		    ZREGNAME(sf, Rn),
    866 		    ZREGNAME(sf, Rm));
    867 	}
    868 	if (imm6 != 0)
    869 		PRINTF(", %s #%u", DecodeShift(shift), (u_int)imm6);
    870 	PRINTF("\n");
    871 }
    872 
    873 static inline int
    874 regoffset_option_to_r(uint64_t option)
    875 {
    876 	switch (option) {
    877 	case 2:
    878 	case 6:
    879 		return 0;
    880 	case 3:
    881 	case 7:
    882 		return 1;
    883 	default:
    884 		return -1;
    885 	}
    886 }
    887 
    888 static void
    889 regoffset_b_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
    890     uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt,
    891     const char *op)
    892 {
    893 	int r;
    894 
    895 	if ((r = regoffset_option_to_r(option)) < 0) {
    896 		UNDEFINED(pc, insn, "illegal option");
    897 		return;
    898 	}
    899 
    900 	if (shift == 0) {
    901 		PRINTF("%s\t%s, [%s,%s%s]\n",
    902 		    op,
    903 		    ZREGNAME(0, Rt),
    904 		    SREGNAME(1, Rn),
    905 		    ZREGNAME(r, Rm),
    906 		    SHIFTOP8(option,
    907 		        "", "", ",uxtw", "", "", "", ",sxtw", ",sxtx"));
    908 	} else {
    909 		PRINTF("%s\t%s, [%s,%s,%s #%d]\n",
    910 		    op,
    911 		    ZREGNAME(0, Rt),
    912 		    SREGNAME(1, Rn),
    913 		    ZREGNAME(r, Rm),
    914 		    SHIFTOP8(option,
    915 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"),
    916 		    0);
    917 	}
    918 }
    919 
    920 static void
    921 regoffset_h_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
    922     uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt,
    923     uint64_t RtSz, const char *op)
    924 {
    925 	int r;
    926 
    927 	if ((r = regoffset_option_to_r(option)) < 0) {
    928 		UNDEFINED(pc, insn, "illegal option");
    929 		return;
    930 	}
    931 
    932 	if ((shift == 0) && (option == 3)) {
    933 		PRINTF("%s\t%s, [%s,%s]\n",
    934 		    op,
    935 		    ZREGNAME(RtSz, Rt),
    936 		    SREGNAME(1, Rn),
    937 		    ZREGNAME(r, Rm));
    938 	} else if (shift == 0) {
    939 		PRINTF("%s\t%s, [%s,%s,%s]\n",
    940 		    op,
    941 		    ZREGNAME(RtSz, Rt),
    942 		    SREGNAME(1, Rn),
    943 		    ZREGNAME(r, Rm),
    944 		    SHIFTOP8(option,
    945 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"));
    946 	} else {
    947 		PRINTF("%s\t%s, [%s,%s,%s #%u]\n",
    948 		    op,
    949 		    ZREGNAME(RtSz, Rt),
    950 		    SREGNAME(1, Rn),
    951 		    ZREGNAME(r, Rm),
    952 		    SHIFTOP8(option,
    953 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"),
    954 		    (u_int)shift);
    955 	}
    956 }
    957 
    958 static void
    959 regoffset_w_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
    960     uint64_t Rm, uint64_t option, uint64_t shift, uint64_t Rn, uint64_t Rt,
    961     const char *op)
    962 {
    963 	int r;
    964 
    965 	if ((r = regoffset_option_to_r(option)) < 0) {
    966 		UNDEFINED(pc, insn, "illegal option");
    967 		return;
    968 	}
    969 
    970 	if ((shift == 0) && (option == 3)) {
    971 		PRINTF("%s\t%s, [%s,%s]\n",
    972 		    op,
    973 		    ZREGNAME(1, Rt),
    974 		    SREGNAME(1, Rn),
    975 		    ZREGNAME(r, Rm));
    976 	} else if (shift == 0) {
    977 		PRINTF("%s\t%s, [%s,%s,%s]\n",
    978 		    op,
    979 		    ZREGNAME(1, Rt),
    980 		    SREGNAME(1, Rn),
    981 		    ZREGNAME(r, Rm),
    982 		    SHIFTOP8(option,
    983 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"));
    984 	} else {
    985 		PRINTF("%s\t%s, [%s,%s,%s #%u]\n",
    986 		    op,
    987 		    ZREGNAME(1, Rt),
    988 		    SREGNAME(1, Rn),
    989 		    ZREGNAME(r, Rm),
    990 		    SHIFTOP8(option,
    991 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"),
    992 		    (u_int)shift * 2);
    993 	}
    994 }
    995 
    996 static void
    997 regoffset_x_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
    998     uint64_t size, uint64_t Rm, uint64_t option, uint64_t shift,
    999     uint64_t Rn, uint64_t Rt,
   1000     const char *op)
   1001 {
   1002 	int r;
   1003 
   1004 	if ((r = regoffset_option_to_r(option)) < 0) {
   1005 		UNDEFINED(pc, insn, "illegal option");
   1006 		return;
   1007 	}
   1008 
   1009 	if (shift == 0) {
   1010 		PRINTF("%s\t%s, [%s,%s%s]\n",
   1011 		    op,
   1012 		    ZREGNAME(size, Rt),
   1013 		    SREGNAME(1, Rn),
   1014 		    ZREGNAME(r, Rm),
   1015 		    SHIFTOP8(option,
   1016 		        "", "", ",uxtw", "", "", "", ",sxtw", ",sxtx"));
   1017 	} else {
   1018 		uint64_t amount = 2 + size;
   1019 		PRINTF("%s\t%s, [%s,%s,%s #%u]\n",
   1020 		    op,
   1021 		    ZREGNAME(size, Rt),
   1022 		    SREGNAME(1, Rn),
   1023 		    ZREGNAME(r, Rm),
   1024 		    SHIFTOP8(option,
   1025 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"),
   1026 		    (u_int)amount);
   1027 	}
   1028 }
   1029 
   1030 static void
   1031 addsub_imm_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
   1032     uint64_t sf, uint64_t shift, uint64_t imm12, uint64_t Rn, uint64_t Rd,
   1033     const char *op, const char *zop)
   1034 {
   1035 	if (shift & 2) {
   1036 		UNDEFINED(pc, insn, "illegal shift");
   1037 		return;
   1038 	}
   1039 
   1040 	if (Rd == 31) {
   1041 		PRINTF("%s\t%s, #0x%"PRIx64"%s\n",
   1042 		    zop,
   1043 		    SREGNAME(sf, Rn),
   1044 		    ZeroExtend(12, imm12, 1),
   1045 		    SHIFTOP4(shift, "", ", lsl #12", "", ""));
   1046 	} else {
   1047 		PRINTF("%s\t%s, %s, #0x%"PRIx64"%s\n",
   1048 		    op,
   1049 		    ZREGNAME(sf, Rd),
   1050 		    SREGNAME(sf, Rn),
   1051 		    ZeroExtend(12, imm12, 1),
   1052 		    SHIFTOP4(shift, "", ", lsl #12", "", ""));
   1053 	}
   1054 }
   1055 
   1056 static void
   1057 csetsel_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
   1058     uint64_t sf, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd,
   1059     const char *op, const char *op2, const char *op3)
   1060 {
   1061 	if ((Rn == Rm) && (Rn != 31) && ((cond & 0xe) != 0x0e)) {
   1062 		PRINTF("%s\t%s, %s, %s\n",
   1063 		    op3,
   1064 		    ZREGNAME(sf, Rd),
   1065 		    ZREGNAME(sf, Rn),
   1066 		    IVCONDNAME(cond));
   1067 	} else if ((Rn == Rm) && (Rn == 31) && ((cond & 0xe) != 0x0e)) {
   1068 		PRINTF("%s\t%s, %s\n",
   1069 		    op2,
   1070 		    ZREGNAME(sf, Rd),
   1071 		    IVCONDNAME(cond));
   1072 	} else {
   1073 		PRINTF("%s\t%s, %s, %s, %s\n",
   1074 		    op,
   1075 		    ZREGNAME(sf, Rd),
   1076 		    ZREGNAME(sf, Rn),
   1077 		    ZREGNAME(sf, Rm),
   1078 		    CONDNAME(cond));
   1079 	}
   1080 }
   1081 
   1082 OP0FUNC(op_undefined)
   1083 {
   1084 	UNDEFINED(pc, insn, "undefined");
   1085 }
   1086 
   1087 OP4FUNC(op_adc, sf, Rm, Rn, Rd)
   1088 {
   1089 	PRINTF("adc\t%s, %s, %s\n",
   1090 	    ZREGNAME(sf, Rd),
   1091 	    ZREGNAME(sf, Rn),
   1092 	    ZREGNAME(sf, Rm));
   1093 }
   1094 
   1095 OP4FUNC(op_adcs, sf, Rm, Rn, Rd)
   1096 {
   1097 	PRINTF("adcs\t%s, %s, %s\n",
   1098 	    ZREGNAME(sf, Rd),
   1099 	    ZREGNAME(sf, Rn),
   1100 	    ZREGNAME(sf, Rm));
   1101 }
   1102 
   1103 OP6FUNC(op_add_extreg, sf, Rm, option, imm3, Rn, Rd)
   1104 {
   1105 	extendreg_common(di, pc, insn, sf, Rm, option, imm3, Rn, Rd,
   1106 	    "add", NULL);
   1107 }
   1108 
   1109 OP5FUNC(op_add_imm, sf, shift, imm12, Rn, Rd)
   1110 {
   1111 	if (shift & 2) {
   1112 		UNDEFINED(pc, insn, "illegal shift");
   1113 		return;
   1114 	}
   1115 
   1116 	/* ALIAS: mov_tofromsp */
   1117 	if ((Rd == 31 || Rn == 31) && (imm12 == 0)) {
   1118 		PRINTF("mov\t%s, %s\n",
   1119 		    SREGNAME(sf, Rd),
   1120 		    SREGNAME(sf, Rn));
   1121 	} else {
   1122 		PRINTF("add\t%s, %s, #0x%"PRIx64"%s\n",
   1123 		    SREGNAME(sf, Rd),
   1124 		    SREGNAME(sf, Rn),
   1125 		    ZeroExtend(12, imm12, 1),
   1126 		    SHIFTOP2(shift, "", ", lsl #12"));
   1127 	}
   1128 }
   1129 
   1130 OP6FUNC(op_add_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1131 {
   1132 	if (shift == 3) {
   1133 		UNDEFINED(pc, insn, "illegal shift");
   1134 		return;
   1135 	}
   1136 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1137 	    "add", NULL, NULL);
   1138 }
   1139 
   1140 OP6FUNC(op_adds_extreg, sf, Rm, option, imm3, Rn, Rd)
   1141 {
   1142 	/* ALIAS: cmn_extreg */
   1143 	extendreg_common(di, pc, insn, sf, Rm, option, imm3, Rn, Rd,
   1144 	    "adds", "cmn");
   1145 }
   1146 
   1147 OP5FUNC(op_adds_imm, sf, shift, imm12, Rn, Rd)
   1148 {
   1149 	/* ALIAS: cmn_imm */
   1150 	addsub_imm_common(di, pc, insn, sf, shift, imm12, Rn, Rd,
   1151 	    "adds", "cmn");
   1152 }
   1153 
   1154 OP6FUNC(op_adds_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1155 {
   1156 	if (shift == 3) {
   1157 		UNDEFINED(pc, insn, "illegal shift");
   1158 		return;
   1159 	}
   1160 	/* ALIAS: cmn_shiftreg */
   1161 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1162 	    "adds", NULL, "cmn");
   1163 }
   1164 
   1165 OP3FUNC(op_adr, immlo, immhi, Rd)
   1166 {
   1167 	uint64_t imm = ((immhi << 2) | immlo);
   1168 
   1169 	PRINTF("adr\t%s, ", ZREGNAME(1, Rd));
   1170 	PRINTADDR(SignExtend(21, imm, 1) + pc);
   1171 	PRINTF("\n");
   1172 }
   1173 
   1174 OP3FUNC(op_adrp, immlo, immhi, Rd)
   1175 {
   1176 	uint64_t imm = ((immhi << 2) | immlo);
   1177 
   1178 	PRINTF("adrp\t%s, ", ZREGNAME(1, Rd));
   1179 	PRINTADDR(SignExtend(21, imm, 4096) + (pc & -4096));
   1180 	PRINTF("\n");
   1181 }
   1182 
   1183 OP6FUNC(op_and_imm, sf, n, immr, imms, Rn, Rd)
   1184 {
   1185 	if (!ValidBitMasks(sf, n, imms, immr)) {
   1186 		UNDEFINED(pc, insn, "illegal bitmasks");
   1187 		return;
   1188 	}
   1189 
   1190 	PRINTF("and\t%s, %s, #0x%"PRIx64"\n",
   1191 	    ZREGNAME(sf, Rd),
   1192 	    ZREGNAME(sf, Rn),
   1193 	    DecodeBitMasks(sf, n, imms, immr));
   1194 }
   1195 
   1196 OP6FUNC(op_and_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1197 {
   1198 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1199 	    "and", NULL, NULL);
   1200 }
   1201 
   1202 OP6FUNC(op_ands_imm, sf, n, immr, imms, Rn, Rd)
   1203 {
   1204 	if (!ValidBitMasks(sf, n, imms, immr)) {
   1205 		UNDEFINED(pc, insn, "illegal bitmasks");
   1206 		return;
   1207 	}
   1208 
   1209 	/* ALIAS: tst_imm */
   1210 	if (Rd == 31) {
   1211 		PRINTF("tst\t%s, #0x%"PRIx64"\n",
   1212 		    ZREGNAME(sf, Rn),
   1213 		    DecodeBitMasks(sf, n, imms, immr));
   1214 	} else {
   1215 		PRINTF("ands\t%s, %s, #0x%"PRIx64"\n",
   1216 		    ZREGNAME(sf, Rd),
   1217 		    ZREGNAME(sf, Rn),
   1218 		    DecodeBitMasks(sf, n, imms, immr));
   1219 	}
   1220 }
   1221 
   1222 OP6FUNC(op_ands_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1223 {
   1224 	/* ALIAS: tst_shiftreg */
   1225 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1226 	    "ands", NULL, "tst");
   1227 }
   1228 
   1229 OP6FUNC(op_sbfm, sf, n, immr, imms, Rn, Rd)
   1230 {
   1231 	const uint64_t bitwidth = (sf == 0) ? 32 : 64;
   1232 
   1233 	/* ALIAS: asr_imm,sbfiz,sbfx,sxtb,sxth,sxtw */
   1234 	if ((imms != (bitwidth - 1)) && ((imms + 1) == immr)) {
   1235 		PRINTF("asr\t%s, %s, #%"PRIu64"\n",
   1236 		    ZREGNAME(sf, Rd),
   1237 		    ZREGNAME(sf, Rn),
   1238 		    bitwidth - immr);
   1239 	} else if (imms == (bitwidth - 1)) {
   1240 		PRINTF("asr\t%s, %s, #%"PRIu64"\n",
   1241 		    ZREGNAME(sf, Rd),
   1242 		    ZREGNAME(sf, Rn),
   1243 		    immr);
   1244 	} else if (imms < immr) {
   1245 		PRINTF("sbfiz\t%s, %s, #%"PRIu64", #%"PRIu64"\n",
   1246 		    ZREGNAME(sf, Rd),
   1247 		    ZREGNAME(sf, Rn),
   1248 		    (bitwidth - immr) & (bitwidth - 1),
   1249 		    (imms + 1) & (bitwidth - 1));
   1250 	} else if (BFXPreferred(sf, 0, imms, immr)) {
   1251 		PRINTF("sbfx\t%s, %s, #%"PRIu64", #%"PRIu64"\n",
   1252 		    ZREGNAME(sf, Rd),
   1253 		    ZREGNAME(sf, Rn),
   1254 		    immr,
   1255 		    (imms - immr + 1) & (bitwidth - 1));
   1256 	} else if ((immr == 0) && (imms == 7)) {
   1257 		PRINTF("sxtb\t%s, %s\n",
   1258 		    ZREGNAME(sf, Rd),
   1259 		    ZREGNAME(0, Rn));
   1260 	} else if ((immr == 0) && (imms == 15)) {
   1261 		PRINTF("sxth\t%s, %s\n",
   1262 		    ZREGNAME(sf, Rd),
   1263 		    ZREGNAME(0, Rn));
   1264 	} else if ((immr == 0) && (imms == 31)) {
   1265 		PRINTF("sxtw\t%s, %s\n",
   1266 		    ZREGNAME(sf, Rd),
   1267 		    ZREGNAME(0, Rn));
   1268 	} else {
   1269 		UNDEFINED(pc, insn, "undefined");
   1270 	}
   1271 }
   1272 
   1273 OP4FUNC(op_asr_reg, sf, Rm, Rn, Rd)
   1274 {
   1275 	/* ALIAS: asrv */
   1276 	/* "asr" always the preferred disassembly */
   1277 	PRINTF("asr\t%s, %s, %s\n",
   1278 	    ZREGNAME(sf, Rd),
   1279 	    ZREGNAME(sf, Rn),
   1280 	    ZREGNAME(sf, Rm));
   1281 }
   1282 
   1283 struct op_sys_table {
   1284 	uint32_t code;
   1285 	int flags;
   1286 #define OPE_NONE	0x00000000
   1287 #define OPE_XT		0x00000001
   1288 	const char *opname;
   1289 };
   1290 
   1291 static struct op_sys_table op_sys_table[] = {
   1292 	{ SYSREG_ENC(1, 0, 7,  1, 0), OPE_NONE,	"ic\tialluis"		},
   1293 	{ SYSREG_ENC(1, 0, 7,  5, 0), OPE_NONE,	"ic\tiallu"		},
   1294 	{ SYSREG_ENC(1, 3, 7,  5, 1), OPE_XT,	"ic\tivau"		},
   1295 	{ SYSREG_ENC(1, 0, 7,  6, 1), OPE_XT,	"dc\tivac"		},
   1296 	{ SYSREG_ENC(1, 0, 7,  6, 2), OPE_XT,	"dc\tisw"		},
   1297 	{ SYSREG_ENC(1, 0, 7, 10, 2), OPE_XT,	"dc\tcsw"		},
   1298 	{ SYSREG_ENC(1, 0, 7, 14, 2), OPE_XT,	"dc\tcisw"		},
   1299 	{ SYSREG_ENC(1, 3, 7, 10, 1), OPE_XT,	"dc\tcvac"		},
   1300 	{ SYSREG_ENC(1, 3, 7, 11, 1), OPE_XT,	"dc\tcvau"		},
   1301 	{ SYSREG_ENC(1, 3, 7, 14, 1), OPE_XT,	"dc\tcivac"		},
   1302 	{ SYSREG_ENC(1, 3, 7,  4, 1), OPE_XT,	"dc\tzva"		},
   1303 	{ SYSREG_ENC(1, 0, 7,  6, 3), OPE_XT,	"dc\tigvac"		},
   1304 	{ SYSREG_ENC(1, 0, 7,  6, 4), OPE_XT,	"dc\tigsw"		},
   1305 	{ SYSREG_ENC(1, 0, 7,  6, 5), OPE_XT,	"dc\tigdvac"		},
   1306 	{ SYSREG_ENC(1, 0, 7,  6, 6), OPE_XT,	"dc\tigdsw"		},
   1307 	{ SYSREG_ENC(1, 0, 7, 10, 4), OPE_XT,	"dc\tcgsw"		},
   1308 	{ SYSREG_ENC(1, 0, 7, 10, 6), OPE_XT,	"dc\tcgdsw"		},
   1309 	{ SYSREG_ENC(1, 0, 7, 14, 4), OPE_XT,	"dc\tcigsw"		},
   1310 	{ SYSREG_ENC(1, 0, 7, 14, 6), OPE_XT,	"dc\tcigdsw"		},
   1311 	{ SYSREG_ENC(1, 3, 7,  4, 3), OPE_XT,	"dc\tgva"		},
   1312 	{ SYSREG_ENC(1, 3, 7,  4, 4), OPE_XT,	"dc\tgzva"		},
   1313 	{ SYSREG_ENC(1, 3, 7, 10, 3), OPE_XT,	"dc\tcgvac"		},
   1314 	{ SYSREG_ENC(1, 3, 7, 10, 5), OPE_XT,	"dc\tcgdvac"		},
   1315 	{ SYSREG_ENC(1, 3, 7, 12, 3), OPE_XT,	"dc\tcgvap"		},
   1316 	{ SYSREG_ENC(1, 3, 7, 12, 5), OPE_XT,	"dc\tcgdvap"		},
   1317 	{ SYSREG_ENC(1, 3, 7, 13, 3), OPE_XT,	"dc\tcgvadp"		},
   1318 	{ SYSREG_ENC(1, 3, 7, 13, 5), OPE_XT,	"dc\tcgdvadp"		},
   1319 	{ SYSREG_ENC(1, 3, 7, 14, 3), OPE_XT,	"dc\tcigvac"		},
   1320 	{ SYSREG_ENC(1, 3, 7, 14, 5), OPE_XT,	"dc\tcigdvac"		},
   1321 	{ SYSREG_ENC(1, 3, 7, 12, 1), OPE_XT,	"dc\tcvap"		},
   1322 	{ SYSREG_ENC(1, 3, 7, 13, 1), OPE_XT,	"dc\tcvadp"		},
   1323 
   1324 	{ SYSREG_ENC(1, 0, 7,  8, 0), OPE_XT,	"at\ts1e1r"		},
   1325 	{ SYSREG_ENC(1, 0, 7,  8, 1), OPE_XT,	"at\ts1e1w"		},
   1326 	{ SYSREG_ENC(1, 0, 7,  8, 2), OPE_XT,	"at\ts1e0r"		},
   1327 	{ SYSREG_ENC(1, 0, 7,  8, 3), OPE_XT,	"at\ts1e0w"		},
   1328 	{ SYSREG_ENC(1, 0, 7,  9, 0), OPE_XT,	"at\ts1e1rp"		},
   1329 	{ SYSREG_ENC(1, 0, 7,  9, 1), OPE_XT,	"at\ts1e1wp"		},
   1330 	{ SYSREG_ENC(1, 4, 7,  8, 0), OPE_XT,	"at\ts1e2r"		},
   1331 	{ SYSREG_ENC(1, 4, 7,  8, 1), OPE_XT,	"at\ts1e2w"		},
   1332 	{ SYSREG_ENC(1, 4, 7,  8, 4), OPE_XT,	"at\ts12e1r"		},
   1333 	{ SYSREG_ENC(1, 4, 7,  8, 5), OPE_XT,	"at\ts12e1w"		},
   1334 	{ SYSREG_ENC(1, 4, 7,  8, 6), OPE_XT,	"at\ts12e0r"		},
   1335 	{ SYSREG_ENC(1, 4, 7,  8, 7), OPE_XT,	"at\ts12e0w"		},
   1336 	{ SYSREG_ENC(1, 6, 7,  8, 0), OPE_XT,	"at\ts1e3r"		},
   1337 	{ SYSREG_ENC(1, 6, 7,  8, 1), OPE_XT,	"at\ts1e3w"		},
   1338 
   1339 	{ SYSREG_ENC(1, 3, 7,  3, 4), OPE_XT,	"cfp\trctx"		},
   1340 	{ SYSREG_ENC(1, 3, 7,  3, 5), OPE_XT,	"dvp\trctx"		},
   1341 	{ SYSREG_ENC(1, 3, 7,  3, 7), OPE_XT,	"cpp\trctx"		},
   1342 
   1343 	{ SYSREG_ENC(1, 0, 8,  3, 0), OPE_NONE,	"tlbi\tvmalle1is"	},
   1344 	{ SYSREG_ENC(1, 0, 8,  3, 1), OPE_XT,	"tlbi\tvae1is"		},
   1345 	{ SYSREG_ENC(1, 0, 8,  3, 2), OPE_XT,	"tlbi\taside1is"	},
   1346 	{ SYSREG_ENC(1, 0, 8,  3, 3), OPE_XT,	"tlbi\tvaae1is"		},
   1347 	{ SYSREG_ENC(1, 0, 8,  3, 5), OPE_XT,	"tlbi\tvale1is"		},
   1348 	{ SYSREG_ENC(1, 0, 8,  3, 7), OPE_XT,	"tlbi\tvaale1is"	},
   1349 	{ SYSREG_ENC(1, 0, 8,  7, 0), OPE_NONE,	"tlbi\tvmalle1"		},
   1350 	{ SYSREG_ENC(1, 0, 8,  7, 1), OPE_XT,	"tlbi\tvae1"		},
   1351 	{ SYSREG_ENC(1, 0, 8,  7, 2), OPE_XT,	"tlbi\taside1"		},
   1352 	{ SYSREG_ENC(1, 0, 8,  7, 3), OPE_XT,	"tlbi\tvaae1"		},
   1353 	{ SYSREG_ENC(1, 0, 8,  7, 5), OPE_XT,	"tlbi\tvale1"		},
   1354 	{ SYSREG_ENC(1, 0, 8,  7, 7), OPE_XT,	"tlbi\tvaale1"		},
   1355 	{ SYSREG_ENC(1, 4, 8,  0, 1), OPE_XT,	"tlbi\tipas2e1is"	},
   1356 	{ SYSREG_ENC(1, 4, 8,  0, 5), OPE_XT,	"tlbi\tipas2le1is"	},
   1357 	{ SYSREG_ENC(1, 4, 8,  3, 0), OPE_NONE,	"tlbi\talle2is"		},
   1358 	{ SYSREG_ENC(1, 4, 8,  3, 1), OPE_XT,	"tlbi\tvae2is"		},
   1359 	{ SYSREG_ENC(1, 4, 8,  3, 4), OPE_NONE,	"tlbi\talle1is"		},
   1360 	{ SYSREG_ENC(1, 4, 8,  3, 5), OPE_XT,	"tlbi\tvale2is"		},
   1361 	{ SYSREG_ENC(1, 4, 8,  3, 6), OPE_NONE,	"tlbi\tvmalls12e1is"	},
   1362 	{ SYSREG_ENC(1, 4, 8,  4, 1), OPE_XT,	"tlbi\tipas2e1"		},
   1363 	{ SYSREG_ENC(1, 4, 8,  4, 5), OPE_XT,	"tlbi\tipas2le1"	},
   1364 	{ SYSREG_ENC(1, 4, 8,  7, 0), OPE_NONE,	"tlbi\talle2"		},
   1365 	{ SYSREG_ENC(1, 4, 8,  7, 1), OPE_XT,	"tlbi\tvae2"		},
   1366 	{ SYSREG_ENC(1, 4, 8,  7, 4), OPE_NONE,	"tlbi\talle1"		},
   1367 	{ SYSREG_ENC(1, 4, 8,  7, 5), OPE_XT,	"tlbi\tvale2"		},
   1368 	{ SYSREG_ENC(1, 4, 8,  7, 6), OPE_NONE,	"tlbi\tvmalls12e1"	},
   1369 	{ SYSREG_ENC(1, 6, 8,  3, 0), OPE_NONE,	"tlbi\talle3is"		},
   1370 	{ SYSREG_ENC(1, 6, 8,  3, 1), OPE_XT,	"tlbi\tvae3is"		},
   1371 	{ SYSREG_ENC(1, 6, 8,  3, 5), OPE_XT,	"tlbi\tvale3is"		},
   1372 	{ SYSREG_ENC(1, 6, 8,  7, 0), OPE_NONE,	"tlbi\talle3"		},
   1373 	{ SYSREG_ENC(1, 6, 8,  7, 1), OPE_XT,	"tlbi\tvae3"		},
   1374 	{ SYSREG_ENC(1, 6, 8,  7, 5), OPE_XT,	"tlbi\tvale3"		}
   1375 };
   1376 
   1377 OP5FUNC(op_sys, op1, CRn, CRm, op2, Rt)
   1378 {
   1379 	uint32_t code;
   1380 	size_t i;
   1381 
   1382 	/* ALIAS: at,dc,ic,sys,tlbi */
   1383 	code = SYSREG_ENC(1, op1, CRn, CRm, op2);
   1384 	for (i = 0; i < __arraycount(op_sys_table); i++) {
   1385 		if (op_sys_table[i].code != code)
   1386 			continue;
   1387 
   1388 		if (((op_sys_table[i].flags & OPE_XT) != 0) || (Rt != 31)) {
   1389 			PRINTF("%s, %s\n",
   1390 			    op_sys_table[i].opname,
   1391 			    ZREGNAME(1, Rt));
   1392 		} else {
   1393 			PRINTF("%s\n",
   1394 			    op_sys_table[i].opname);
   1395 		}
   1396 		return;
   1397 	}
   1398 
   1399 	/* default, sys instruction */
   1400 	PRINTF("sys\t#%"PRIu64", %s, %s, #%"PRIu64", %s\n",
   1401 	    op1,
   1402 	    CREGNAME(CRn),
   1403 	    CREGNAME(CRm),
   1404 	    op2,
   1405 	    ZREGNAME(1,Rt));
   1406 }
   1407 
   1408 OP1FUNC(op_b, imm26)
   1409 {
   1410 	PRINTF("b\t");
   1411 	PRINTADDR(SignExtend(26, imm26, 4) + pc);
   1412 	PRINTF("\n");
   1413 }
   1414 
   1415 OP2FUNC(op_b_cond, imm19, cond)
   1416 {
   1417 	PRINTF("b.%s\t", CONDNAME(cond));
   1418 	PRINTADDR(SignExtend(19, imm19, 4) + pc);
   1419 	PRINTF("\n");
   1420 }
   1421 
   1422 OP6FUNC(op_bfi, sf, n, immr, imms, Rn, Rd)
   1423 {
   1424 	const uint64_t bitwidth = (sf == 0) ? 32 : 64;
   1425 
   1426 	/* ALIAS: bfm,bfxil */
   1427 	/* it is not disassembled as bfm */
   1428 
   1429 	/* XXX: if Rn=31, should be used "bfc"? (armv8.2) */
   1430 	if (imms < immr) {
   1431 		PRINTF("bfi\t%s, %s, #%"PRIu64", #%"PRIu64"\n",
   1432 		    ZREGNAME(sf, Rd),
   1433 		    ZREGNAME(sf, Rn),
   1434 		    (bitwidth - immr) & (bitwidth - 1),
   1435 		    (imms + 1) & (bitwidth - 1));
   1436 	} else {
   1437 		PRINTF("bfxil\t%s, %s, #%"PRIu64", #%"PRIu64"\n",
   1438 		    ZREGNAME(sf, Rd),
   1439 		    ZREGNAME(sf, Rn),
   1440 		    immr,
   1441 		    (imms -immr + 1) & (bitwidth - 1));
   1442 	}
   1443 }
   1444 
   1445 OP6FUNC(op_bic_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1446 {
   1447 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1448 	    "bic", NULL, NULL);
   1449 }
   1450 
   1451 OP6FUNC(op_bics_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1452 {
   1453 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1454 	    "bics", NULL, NULL);
   1455 }
   1456 
   1457 OP1FUNC(op_bl, imm26)
   1458 {
   1459 	PRINTF("bl\t");
   1460 	PRINTADDR(SignExtend(26, imm26, 4) + pc);
   1461 	PRINTF("\n");
   1462 }
   1463 
   1464 OP1FUNC(op_blr, Rn)
   1465 {
   1466 	PRINTF("blr\t%s\n", ZREGNAME(1, Rn));
   1467 }
   1468 
   1469 OP1FUNC(op_br, Rn)
   1470 {
   1471 	PRINTF("br\t%s\n", ZREGNAME(1, Rn));
   1472 }
   1473 
   1474 OP1FUNC(op_brk, imm16)
   1475 {
   1476 	PRINTF("brk\t#0x%"PRIx64"\n", imm16);
   1477 }
   1478 
   1479 OP3FUNC(op_cbnz, sf, imm19, Rt)
   1480 {
   1481 	PRINTF("cbnz\t%s, ", ZREGNAME(sf, Rt));
   1482 	PRINTADDR(SignExtend(19, imm19, 4) + pc);
   1483 	PRINTF("\n");
   1484 }
   1485 
   1486 OP3FUNC(op_cbz, sf, imm19, Rt)
   1487 {
   1488 	PRINTF("cbz\t%s, ", ZREGNAME(sf, Rt));
   1489 	PRINTADDR(SignExtend(19, imm19, 4) + pc);
   1490 	PRINTF("\n");
   1491 }
   1492 
   1493 OP5FUNC(op_ccmn_imm, sf, imm5, cond, Rn, nzcv)
   1494 {
   1495 	PRINTF("ccmn\t%s, #0x%"PRIx64", #0x%"PRIx64", %s\n",
   1496 	    ZREGNAME(sf, Rn),
   1497 	    imm5,
   1498 	    nzcv,
   1499 	    CONDNAME(cond));
   1500 }
   1501 
   1502 OP5FUNC(op_ccmn_reg, sf, Rm, cond, Rn, nzcv)
   1503 {
   1504 	PRINTF("ccmn\t%s, %s, #0x%"PRIx64", %s\n",
   1505 	    ZREGNAME(sf, Rn),
   1506 	    ZREGNAME(sf, Rm),
   1507 	    nzcv,
   1508 	    CONDNAME(cond));
   1509 }
   1510 
   1511 OP5FUNC(op_ccmp_imm, sf, imm5, cond, Rn, nzcv)
   1512 {
   1513 	PRINTF("ccmp\t%s, #0x%"PRIx64", #0x%"PRIx64", %s\n",
   1514 	    ZREGNAME(sf, Rn),
   1515 	    imm5,
   1516 	    nzcv,
   1517 	    CONDNAME(cond));
   1518 }
   1519 
   1520 OP5FUNC(op_ccmp_reg, sf, Rm, cond, Rn, nzcv)
   1521 {
   1522 	PRINTF("ccmp\t%s, %s, #0x%"PRIx64", %s\n",
   1523 	    ZREGNAME(sf, Rn),
   1524 	    ZREGNAME(sf, Rm),
   1525 	    nzcv,
   1526 	    CONDNAME(cond));
   1527 }
   1528 
   1529 OP5FUNC(op_cinc, sf, Rm, cond, Rn, Rd)
   1530 {
   1531 	/* ALIAS: cset,csinc */
   1532 	csetsel_common(di, pc, insn, sf, Rm, cond, Rn, Rd,
   1533 	    "csinc", "cset", "cinc");
   1534 }
   1535 
   1536 OP5FUNC(op_csinv, sf, Rm, cond, Rn, Rd)
   1537 {
   1538 	/* ALIAS: csetm,cinv */
   1539 	csetsel_common(di, pc, insn, sf, Rm, cond, Rn, Rd,
   1540 	    "csinv", "csetm", "cinv");
   1541 }
   1542 
   1543 OP1FUNC(op_clrex, CRm)
   1544 {
   1545 	if (CRm == 15) {
   1546 		PRINTF("clrex\n");
   1547 	} else {
   1548 		PRINTF("clrex\t#0x%"PRIx64"\n", CRm);
   1549 	}
   1550 }
   1551 
   1552 OP3FUNC(op_cls, sf, Rn, Rd)
   1553 {
   1554 	PRINTF("cls\t%s, %s\n",
   1555 	    ZREGNAME(sf, Rd),
   1556 	    ZREGNAME(sf, Rn));
   1557 }
   1558 
   1559 OP3FUNC(op_clz, sf, Rn, Rd)
   1560 {
   1561 	PRINTF("clz\t%s, %s\n",
   1562 	    ZREGNAME(sf, Rd),
   1563 	    ZREGNAME(sf, Rn));
   1564 }
   1565 
   1566 OP6FUNC(op_subs_extreg, sf, Rm, option, imm3, Rn, Rd)
   1567 {
   1568 	/* ALIAS: cmp_extreg */
   1569 	extendreg_common(di, pc, insn, sf, Rm, option, imm3, Rn, Rd,
   1570 	    "subs", "cmp");
   1571 }
   1572 
   1573 OP5FUNC(op_subs_imm, sf, shift, imm12, Rn, Rd)
   1574 {
   1575 	/* ALIAS: cmp_imm */
   1576 	addsub_imm_common(di, pc, insn, sf, shift, imm12, Rn, Rd,
   1577 	    "subs", "cmp");
   1578 }
   1579 
   1580 OP6FUNC(op_subs_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1581 {
   1582 	if (shift == 3) {
   1583 		UNDEFINED(pc, insn, "illegal shift");
   1584 		return;
   1585 	}
   1586 
   1587 	/* ALIAS: negs,cmp_shiftreg */
   1588 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1589 	    "subs", "negs", "cmp");
   1590 }
   1591 
   1592 OP5FUNC(op_csneg, sf, Rm, cond, Rn, Rd)
   1593 {
   1594 	/* ALIAS: cneg */
   1595 	if ((Rn == Rm) && ((cond & 0xe) != 0x0e)) {
   1596 		PRINTF("cneg\t%s, %s, %s\n",
   1597 		    ZREGNAME(sf, Rd),
   1598 		    ZREGNAME(sf, Rn),
   1599 		    IVCONDNAME(cond));
   1600 	} else {
   1601 		PRINTF("csneg\t%s, %s, %s, %s\n",
   1602 		    ZREGNAME(sf, Rd),
   1603 		    ZREGNAME(sf, Rn),
   1604 		    ZREGNAME(sf, Rm),
   1605 		    CONDNAME(cond));
   1606 	}
   1607 }
   1608 
   1609 static void
   1610 crc32_common(const disasm_interface_t *di, uint64_t pc, uint32_t insn,
   1611     uint64_t sf, uint64_t Rm, uint64_t sz, uint64_t Rn, uint64_t Rd,
   1612     const char *op)
   1613 {
   1614 	const char bhwx[4] = "bhwx";	/* "crc32x" + SizeChar */
   1615 
   1616 	if (((sf != 0) && (sz != 3)) ||
   1617 	    ((sf == 0) && (sz == 3))) {
   1618 		UNDEFINED(pc, insn, "illegal size");
   1619 		return;
   1620 	}
   1621 
   1622 	PRINTF("%s%c\t%s, %s, %s\n",
   1623 	    op, bhwx[sz & 3],
   1624 	    ZREGNAME(0, Rd),
   1625 	    ZREGNAME(0, Rn),
   1626 	    ZREGNAME(sf, Rm));
   1627 }
   1628 
   1629 OP5FUNC(op_crc32, sf, Rm, sz, Rn, Rd)
   1630 {
   1631 	crc32_common(di, pc, insn, sf, Rm, sz, Rn, Rd, "crc32");
   1632 }
   1633 
   1634 OP5FUNC(op_crc32c, sf, Rm, sz, Rn, Rd)
   1635 {
   1636 	crc32_common(di, pc, insn, sf, Rm, sz, Rn, Rd, "crc32c");
   1637 }
   1638 
   1639 OP5FUNC(op_csel, sf, Rm, cond, Rn, Rd)
   1640 {
   1641 	PRINTF("csel\t%s, %s, %s, %s\n",
   1642 	    ZREGNAME(sf, Rd),
   1643 	    ZREGNAME(sf, Rn),
   1644 	    ZREGNAME(sf, Rm),
   1645 	    CONDNAME(cond));
   1646 }
   1647 
   1648 OP2FUNC(op_dcps, imm16, ll)
   1649 {
   1650 	if (ll == 0) {
   1651 		UNDEFINED(pc, insn, "illegal level");
   1652 		return;
   1653 	}
   1654 
   1655 	if (imm16 == 0)
   1656 		PRINTF("dcps%"PRIu64"\n", ll);
   1657 	else
   1658 		PRINTF("dcps%"PRIu64"\t#0x%"PRIx64"\n", ll, imm16);
   1659 }
   1660 
   1661 OP0FUNC(op_drps)
   1662 {
   1663 	PRINTF("drps\n");
   1664 }
   1665 
   1666 OP1FUNC(op_dmb, CRm)
   1667 {
   1668 	PRINTF("dmb\t%s\n", BARRIERNAME(CRm));
   1669 }
   1670 
   1671 OP1FUNC(op_dsb, CRm)
   1672 {
   1673 	PRINTF("dsb\t%s\n", BARRIERNAME(CRm));
   1674 }
   1675 
   1676 OP6FUNC(op_eon_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1677 {
   1678 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1679 	    "eon", NULL, NULL);
   1680 }
   1681 
   1682 OP6FUNC(op_eor_imm, sf, n, immr, imms, Rn, Rd)
   1683 {
   1684 	if (!ValidBitMasks(sf, n, imms, immr)) {
   1685 		UNDEFINED(pc, insn, "illegal bitmasks");
   1686 		return;
   1687 	}
   1688 
   1689 	PRINTF("eor\t%s, %s, #0x%"PRIx64"\n",
   1690 	    ZREGNAME(sf, Rd),
   1691 	    ZREGNAME(sf, Rn),
   1692 	    DecodeBitMasks(sf, n, imms, immr));
   1693 }
   1694 
   1695 OP6FUNC(op_eor_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   1696 {
   1697 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   1698 	    "eor", NULL, NULL);
   1699 }
   1700 
   1701 OP0FUNC(op_eret)
   1702 {
   1703 	PRINTF("eret\n");
   1704 }
   1705 
   1706 OP6FUNC(op_ror_imm, sf, n, Rm, imms, Rn, Rd)
   1707 {
   1708 	if (((sf ^ n) != 0) || (n == 0 && imms >= 0x20)) {
   1709 		UNDEFINED(pc, insn, "illegal sf and N");
   1710 		return;
   1711 	}
   1712 
   1713 	/* ALIAS: extr */
   1714 	if (Rn == Rm) {
   1715 		PRINTF("ror\t%s, %s, #%"PRIu64"\n",
   1716 		    ZREGNAME(sf, Rd),
   1717 		    ZREGNAME(sf, Rn),
   1718 		    imms);
   1719 	} else {
   1720 		PRINTF("extr\t%s, %s, %s, #%"PRIu64"\n",
   1721 		    ZREGNAME(sf, Rd),
   1722 		    ZREGNAME(sf, Rn),
   1723 		    ZREGNAME(sf, Rm),
   1724 		    imms);
   1725 	}
   1726 }
   1727 
   1728 #define CRm_OP2(crm,op)	((crm) << 3 | (op))
   1729 static const char *hint_table[] = {
   1730 	[CRm_OP2(0, 0)] = "nop",
   1731 	[CRm_OP2(0, 1)] = "yield",
   1732 	[CRm_OP2(0, 2)] = "wfe",
   1733 	[CRm_OP2(0, 3)] = "wfi",
   1734 	[CRm_OP2(0, 4)] = "sev",
   1735 	[CRm_OP2(0, 5)] = "sevl",
   1736 	[CRm_OP2(0, 7)] = "xpaclri",
   1737 	[CRm_OP2(1, 0)] = "pacia1716",
   1738 	[CRm_OP2(1, 2)] = "pacib1716",
   1739 	[CRm_OP2(1, 4)] = "autia1716",
   1740 	[CRm_OP2(1, 6)] = "autib1716",
   1741 	[CRm_OP2(2, 0)] = "esb",
   1742 	[CRm_OP2(2, 1)] = "psb\tcsync",
   1743 	[CRm_OP2(2, 2)] = "tsb\tcsync",
   1744 	[CRm_OP2(2, 4)] = "csdb",
   1745 	[CRm_OP2(3, 0)] = "paciaz",
   1746 	[CRm_OP2(3, 1)] = "paciasp",
   1747 	[CRm_OP2(3, 2)] = "pacibz",
   1748 	[CRm_OP2(3, 3)] = "pacibsp",
   1749 	[CRm_OP2(3, 4)] = "autiaz",
   1750 	[CRm_OP2(3, 5)] = "autiasp",
   1751 	[CRm_OP2(3, 6)] = "autibz",
   1752 	[CRm_OP2(3, 7)] = "autibsp",
   1753 	[CRm_OP2(4, 0)] = "bti",
   1754 	[CRm_OP2(4, 2)] = "bti\tc",
   1755 	[CRm_OP2(4, 4)] = "bti\tj",
   1756 	[CRm_OP2(4, 6)] = "bti\tjc",
   1757 };
   1758 
   1759 OP2FUNC(op_hint, CRm, op2)
   1760 {
   1761 	const uint64_t op = CRm_OP2(CRm, op2);
   1762 
   1763 	/* ALIAS: nop,sev,sevl,wfe,wfi,yield,etc,.. */
   1764 	if (op < __arraycount(hint_table) &&
   1765 	    hint_table[op] != NULL) {
   1766 		PRINTF("%s\n", hint_table[op]);
   1767 	} else {
   1768 		PRINTF("hint\t#0x%"PRIx64"\n", op);
   1769 	}
   1770 }
   1771 
   1772 OP1FUNC(op_hlt, imm16)
   1773 {
   1774 	PRINTF("hlt\t#0x%"PRIx64"\n", imm16);
   1775 }
   1776 
   1777 OP1FUNC(op_hvc, imm16)
   1778 {
   1779 	PRINTF("hvc\t#0x%"PRIx64"\n", imm16);
   1780 }
   1781 
   1782 OP1FUNC(op_isb, CRm)
   1783 {
   1784 	if (CRm == 15)
   1785 		PRINTF("isb\n");
   1786 	else
   1787 		PRINTF("isb\t#0x%"PRIx64"\n", CRm);
   1788 }
   1789 
   1790 OP3FUNC(op_ldar, size, Rn, Rt)
   1791 {
   1792 	PRINTF("ldar\t%s, [%s]\n",
   1793 	    ZREGNAME(size, Rt),
   1794 	    SREGNAME(1, Rn));
   1795 }
   1796 
   1797 OP2FUNC(op_ldarb, Rn, Rt)
   1798 {
   1799 	PRINTF("ldarb\t%s, [%s]\n",
   1800 	    ZREGNAME(0, Rt),
   1801 	    SREGNAME(1, Rn));
   1802 }
   1803 
   1804 OP2FUNC(op_ldarh, Rn, Rt)
   1805 {
   1806 	PRINTF("ldarh\t%s, [%s]\n",
   1807 	    ZREGNAME(0, Rt),
   1808 	    SREGNAME(1, Rn));
   1809 }
   1810 
   1811 OP4FUNC(op_ldaxp, size, Rt2, Rn, Rt)
   1812 {
   1813 	PRINTF("ldaxp\t%s, %s, [%s]\n",
   1814 	    ZREGNAME(size, Rt),
   1815 	    ZREGNAME(size, Rt2),
   1816 	    SREGNAME(1, Rn));
   1817 }
   1818 
   1819 OP3FUNC(op_ldaxr, size, Rn, Rt)
   1820 {
   1821 	PRINTF("ldaxr\t%s, [%s]\n",
   1822 	    ZREGNAME(size, Rt),
   1823 	    SREGNAME(1, Rn));
   1824 }
   1825 
   1826 OP2FUNC(op_ldaxrb, Rn, Rt)
   1827 {
   1828 	PRINTF("ldaxrb\t%s, [%s]\n",
   1829 	    ZREGNAME(0, Rt),
   1830 	    SREGNAME(1, Rn));
   1831 }
   1832 
   1833 OP2FUNC(op_ldaxrh, Rn, Rt)
   1834 {
   1835 	PRINTF("ldaxrh\t%s, [%s]\n",
   1836 	    ZREGNAME(0, Rt),
   1837 	    SREGNAME(1, Rn));
   1838 }
   1839 
   1840 OP5FUNC(op_ldnp, sf, imm7, Rt2, Rn, Rt)
   1841 {
   1842 	if (imm7 == 0) {
   1843 		PRINTF("ldnp\t%s, %s, [%s]\n",
   1844 		    ZREGNAME(sf, Rt),
   1845 		    ZREGNAME(sf, Rt2),
   1846 		    SREGNAME(1, Rn));
   1847 	} else {
   1848 		PRINTF("ldnp\t%s, %s, [%s,#%"PRId64"]\n",
   1849 		    ZREGNAME(sf, Rt),
   1850 		    ZREGNAME(sf, Rt2),
   1851 		    SREGNAME(1, Rn),
   1852 		    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   1853 	}
   1854 }
   1855 
   1856 OP5FUNC(op_ldp_postidx, sf, imm7, Rt2, Rn, Rt)
   1857 {
   1858 	PRINTF("ldp\t%s, %s, [%s],#%"PRId64"\n",
   1859 	    ZREGNAME(sf, Rt),
   1860 	    ZREGNAME(sf, Rt2),
   1861 	    SREGNAME(1, Rn),
   1862 	    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   1863 }
   1864 
   1865 OP5FUNC(op_ldp_preidx, sf, imm7, Rt2, Rn, Rt)
   1866 {
   1867 	PRINTF("ldp\t%s, %s, [%s,#%"PRId64"]!\n",
   1868 	    ZREGNAME(sf, Rt),
   1869 	    ZREGNAME(sf, Rt2),
   1870 	    SREGNAME(1, Rn),
   1871 	    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   1872 }
   1873 
   1874 OP5FUNC(op_ldp_signed, sf, imm7, Rt2, Rn, Rt)
   1875 {
   1876 	if (imm7 == 0) {
   1877 		PRINTF("ldp\t%s, %s, [%s]\n",
   1878 		    ZREGNAME(sf, Rt),
   1879 		    ZREGNAME(sf, Rt2),
   1880 		    SREGNAME(1, Rn));
   1881 	} else {
   1882 		PRINTF("ldp\t%s, %s, [%s,#%"PRId64"]\n",
   1883 		    ZREGNAME(sf, Rt),
   1884 		    ZREGNAME(sf, Rt2),
   1885 		    SREGNAME(1, Rn),
   1886 		    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   1887 	}
   1888 }
   1889 
   1890 OP4FUNC(op_ldpsw_postidx, imm7, Rt2, Rn, Rt)
   1891 {
   1892 	PRINTF("ldpsw\t%s, %s, [%s],#%"PRId64"\n",
   1893 	    ZREGNAME(1, Rt),
   1894 	    ZREGNAME(1, Rt2),
   1895 	    SREGNAME(1, Rn),
   1896 	    SignExtend(7, imm7, 4));
   1897 }
   1898 
   1899 OP4FUNC(op_ldpsw_preidx, imm7, Rt2, Rn, Rt)
   1900 {
   1901 	PRINTF("ldpsw\t%s, %s, [%s,#%"PRId64"]!\n",
   1902 	    ZREGNAME(1, Rt),
   1903 	    ZREGNAME(1, Rt2),
   1904 	    SREGNAME(1, Rn),
   1905 	    SignExtend(7, imm7, 4));
   1906 }
   1907 
   1908 OP4FUNC(op_ldpsw_signed, imm7, Rt2, Rn, Rt)
   1909 {
   1910 	if (imm7 == 0) {
   1911 		PRINTF("ldpsw\t%s, %s, [%s]\n",
   1912 		    ZREGNAME(1, Rt),
   1913 		    ZREGNAME(1, Rt2),
   1914 		    SREGNAME(1, Rn));
   1915 	} else {
   1916 		PRINTF("ldpsw\t%s, %s, [%s,#%"PRId64"]\n",
   1917 		    ZREGNAME(1, Rt),
   1918 		    ZREGNAME(1, Rt2),
   1919 		    SREGNAME(1, Rn),
   1920 		    SignExtend(7, imm7, 4));
   1921 	}
   1922 }
   1923 
   1924 OP4FUNC(op_ldr_immpostidx, size, imm9, Rn, Rt)
   1925 {
   1926 	PRINTF("ldr\t%s, [%s],#%"PRId64"\n",
   1927 	    ZREGNAME(size, Rt),
   1928 	    SREGNAME(1, Rn),
   1929 	    SignExtend(9, imm9, 1));
   1930 }
   1931 
   1932 OP4FUNC(op_ldr_immpreidx, size, imm9, Rn, Rt)
   1933 {
   1934 	PRINTF("ldr\t%s, [%s,#%"PRId64"]!\n",
   1935 	    ZREGNAME(size, Rt),
   1936 	    SREGNAME(1, Rn),
   1937 	    SignExtend(9, imm9, 1));
   1938 }
   1939 
   1940 OP4FUNC(op_ldr_immunsign, size, imm12, Rn, Rt)
   1941 {
   1942 	if (imm12 == 0) {
   1943 		PRINTF("ldr\t%s, [%s]\n",
   1944 		    ZREGNAME(size, Rt),
   1945 		    SREGNAME(1, Rn));
   1946 	} else {
   1947 		PRINTF("ldr\t%s, [%s,#%"PRId64"]\n",
   1948 		    ZREGNAME(size, Rt),
   1949 		    SREGNAME(1, Rn),
   1950 		    ZeroExtend(12, imm12, (size == 0) ? 4 : 8));
   1951 	}
   1952 }
   1953 
   1954 OP3FUNC(op_ldr_literal, size, imm19, Rt)
   1955 {
   1956 	PRINTF("ldr\t%s, ", ZREGNAME(size, Rt));
   1957 	PRINTADDR(SignExtend(19, imm19, 4) + pc);
   1958 	PRINTF("\n");
   1959 }
   1960 
   1961 OP6FUNC(op_ldr_reg, size, Rm, option, shift, Rn, Rt)
   1962 {
   1963 	regoffset_x_common(di, pc, insn, size, Rm, option, shift, Rn, Rt,
   1964 	    "ldr");
   1965 }
   1966 
   1967 OP3FUNC(op_ldrb_immpostidx, imm9, Rn, Rt)
   1968 {
   1969 	PRINTF("ldrb\t%s, [%s],#%"PRId64"\n",
   1970 	    ZREGNAME(0, Rt),
   1971 	    SREGNAME(1, Rn),
   1972 	    SignExtend(9, imm9, 1));
   1973 }
   1974 
   1975 OP3FUNC(op_ldrb_immpreidx, imm9, Rn, Rt)
   1976 {
   1977 	PRINTF("ldrb\t%s, [%s,#%"PRId64"]!\n",
   1978 	    ZREGNAME(0, Rt),
   1979 	    SREGNAME(1, Rn),
   1980 	    SignExtend(9, imm9, 1));
   1981 }
   1982 
   1983 OP3FUNC(op_ldrb_immunsign, imm12, Rn, Rt)
   1984 {
   1985 	if (imm12 == 0) {
   1986 		PRINTF("ldrb\t%s, [%s]\n",
   1987 		    ZREGNAME(0, Rt),
   1988 		    SREGNAME(1, Rn));
   1989 	} else {
   1990 		PRINTF("ldrb\t%s, [%s,#%"PRId64"]\n",
   1991 		    ZREGNAME(0, Rt),
   1992 		    SREGNAME(1, Rn),
   1993 		    ZeroExtend(12, imm12, 1));
   1994 	}
   1995 }
   1996 
   1997 OP5FUNC(op_ldrb_reg, Rm, option, shift, Rn, Rt)
   1998 {
   1999 	regoffset_b_common(di, pc, insn, Rm, option, shift, Rn, Rt, "ldrb");
   2000 }
   2001 
   2002 OP3FUNC(op_ldrh_immpostidx, imm9, Rn, Rt)
   2003 {
   2004 	PRINTF("ldrh\t%s, [%s],#%"PRId64"\n",
   2005 	    ZREGNAME(0, Rt),
   2006 	    SREGNAME(1, Rn),
   2007 	    SignExtend(9, imm9, 1));
   2008 }
   2009 
   2010 OP3FUNC(op_ldrh_immpreidx, imm9, Rn, Rt)
   2011 {
   2012 	PRINTF("ldrh\t%s, [%s,#%"PRId64"]!\n",
   2013 	    ZREGNAME(0, Rt),
   2014 	    SREGNAME(1, Rn),
   2015 	    SignExtend(9, imm9, 1));
   2016 }
   2017 
   2018 OP3FUNC(op_ldrh_immunsign, imm12, Rn, Rt)
   2019 {
   2020 	if (imm12 == 0) {
   2021 		PRINTF("ldrh\t%s, [%s]\n",
   2022 		    ZREGNAME(0, Rt),
   2023 		    SREGNAME(1, Rn));
   2024 	} else {
   2025 		PRINTF("ldrh\t%s, [%s,#%"PRId64"]\n",
   2026 		    ZREGNAME(0, Rt),
   2027 		    SREGNAME(1, Rn),
   2028 		    ZeroExtend(12, imm12, 2));
   2029 	}
   2030 }
   2031 
   2032 OP5FUNC(op_ldrh_reg, Rm, option, shift, Rn, Rt)
   2033 {
   2034 	regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, 0, "ldrh");
   2035 }
   2036 
   2037 OP4FUNC(op_ldrsb_immpostidx, opc, imm9, Rn, Rt)
   2038 {
   2039 	PRINTF("ldrsb\t%s, [%s],#%"PRId64"\n",
   2040 	    ZREGNAME((opc ^ 1), Rt),
   2041 	    SREGNAME(1, Rn),
   2042 	    SignExtend(9, imm9, 1));
   2043 }
   2044 
   2045 OP4FUNC(op_ldrsb_immpreidx, opc, imm9, Rn, Rt)
   2046 {
   2047 	PRINTF("ldrsb\t%s, [%s,#%"PRId64"]!\n",
   2048 	    ZREGNAME((opc ^ 1), Rt),
   2049 	    SREGNAME(1, Rn),
   2050 	    SignExtend(9, imm9, 1));
   2051 }
   2052 
   2053 OP4FUNC(op_ldrsb_immunsign, opc, imm12, Rn, Rt)
   2054 {
   2055 	if (imm12 == 0) {
   2056 		PRINTF("ldrsb\t%s, [%s]\n",
   2057 		    ZREGNAME((opc ^ 1), Rt),
   2058 		    SREGNAME(1, Rn));
   2059 	} else {
   2060 		PRINTF("ldrsb\t%s, [%s,#%"PRId64"]\n",
   2061 		    ZREGNAME((opc ^ 1), Rt),
   2062 		    SREGNAME(1, Rn),
   2063 		    ZeroExtend(12, imm12, 1));
   2064 	}
   2065 }
   2066 
   2067 OP6FUNC(op_ldrsb_reg, opc, Rm, option, shift, Rn, Rt)
   2068 {
   2069 	regoffset_b_common(di, pc, insn, Rm, option, shift, Rn, Rt, "ldrsb");
   2070 }
   2071 
   2072 OP4FUNC(op_ldrsh_immpostidx, opc, imm9, Rn, Rt)
   2073 {
   2074 	PRINTF("ldrsh\t%s, [%s],#%"PRId64"\n",
   2075 	    ZREGNAME((opc ^ 1), Rt),
   2076 	    SREGNAME(1, Rn),
   2077 	    SignExtend(9, imm9, 1));
   2078 }
   2079 
   2080 OP4FUNC(op_ldrsh_immpreidx, opc, imm9, Rn, Rt)
   2081 {
   2082 	PRINTF("ldrsh\t%s, [%s,#%"PRId64"]!\n",
   2083 	    ZREGNAME((opc ^ 1), Rt),
   2084 	    SREGNAME(1, Rn),
   2085 	    SignExtend(9, imm9, 1));
   2086 }
   2087 
   2088 OP4FUNC(op_ldrsh_immunsign, opc, imm12, Rn, Rt)
   2089 {
   2090 	if (imm12 == 0) {
   2091 		PRINTF("ldrsh\t%s, [%s]\n",
   2092 		    ZREGNAME((opc ^ 1), Rt),
   2093 		    SREGNAME(1, Rn));
   2094 	} else {
   2095 		PRINTF("ldrsh\t%s, [%s,#%"PRId64"]\n",
   2096 		    ZREGNAME((opc ^ 1), Rt),
   2097 		    SREGNAME(1, Rn),
   2098 		    ZeroExtend(12, imm12, 2));
   2099 	}
   2100 }
   2101 
   2102 OP6FUNC(op_ldrsh_reg, opc, Rm, option, shift, Rn, Rt)
   2103 {
   2104 	regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, opc ^ 1,
   2105 	    "ldrsh");
   2106 }
   2107 
   2108 OP3FUNC(op_ldrsw_immpostidx, imm9, Rn, Rt)
   2109 {
   2110 	PRINTF("ldrsw\t%s, [%s],#%"PRId64"\n",
   2111 	    ZREGNAME(1, Rt),
   2112 	    SREGNAME(1, Rn),
   2113 	    SignExtend(9, imm9, 1));
   2114 }
   2115 
   2116 OP3FUNC(op_ldrsw_immpreidx, imm9, Rn, Rt)
   2117 {
   2118 	PRINTF("ldrsw\t%s, [%s,#%"PRId64"]!\n",
   2119 	    ZREGNAME(1, Rt),
   2120 	    SREGNAME(1, Rn),
   2121 	    SignExtend(9, imm9, 1));
   2122 }
   2123 
   2124 OP3FUNC(op_ldrsw_immunsign, imm12, Rn, Rt)
   2125 {
   2126 	if (imm12 == 0) {
   2127 		PRINTF("ldrsw\t%s, [%s]\n",
   2128 		    ZREGNAME(1, Rt),
   2129 		    SREGNAME(1, Rn));
   2130 	} else {
   2131 		PRINTF("ldrsw\t%s, [%s,#%"PRId64"]\n",
   2132 		    ZREGNAME(1, Rt),
   2133 		    SREGNAME(1, Rn),
   2134 		    ZeroExtend(12, imm12, 4));
   2135 	}
   2136 }
   2137 
   2138 OP2FUNC(op_ldrsw_literal, imm19, Rt)
   2139 {
   2140 	PRINTF("ldrsw\t%s, ", ZREGNAME(1, Rt));
   2141 	PRINTADDR(SignExtend(19, imm19, 4) + pc);
   2142 	PRINTF("\n");
   2143 }
   2144 
   2145 OP5FUNC(op_ldrsw_reg, Rm, option, shift, Rn, Rt)
   2146 {
   2147 	regoffset_w_common(di, pc, insn, Rm, option, shift, Rn, Rt, "ldrsw");
   2148 }
   2149 
   2150 OP4FUNC(op_ldtr, size, imm9, Rn, Rt)
   2151 {
   2152 	if (imm9 == 0) {
   2153 		PRINTF("ldtr\t%s, [%s]\n",
   2154 		    ZREGNAME(size, Rt),
   2155 		    SREGNAME(1, Rn));
   2156 	} else {
   2157 		PRINTF("ldtr\t%s, [%s,#%"PRId64"]\n",
   2158 		    ZREGNAME(size, Rt),
   2159 		    SREGNAME(1, Rn),
   2160 		    SignExtend(9, imm9, 1));
   2161 	}
   2162 }
   2163 
   2164 OP3FUNC(op_ldtrb, imm9, Rn, Rt)
   2165 {
   2166 	if (imm9 == 0) {
   2167 		PRINTF("ldtrb\t%s, [%s]\n",
   2168 		    ZREGNAME(0, Rt),
   2169 		    SREGNAME(1, Rn));
   2170 	} else {
   2171 		PRINTF("ldtrb\t%s, [%s,#%"PRId64"]\n",
   2172 		    ZREGNAME(0, Rt),
   2173 		    SREGNAME(1, Rn),
   2174 		    SignExtend(9, imm9, 1));
   2175 	}
   2176 }
   2177 
   2178 OP3FUNC(op_ldtrh, imm9, Rn, Rt)
   2179 {
   2180 	if (imm9 == 0) {
   2181 		PRINTF("ldtrh\t%s, [%s]\n",
   2182 		    ZREGNAME(0, Rt),
   2183 		    SREGNAME(1, Rn));
   2184 	} else {
   2185 		PRINTF("ldtrh\t%s, [%s,#%"PRId64"]\n",
   2186 		    ZREGNAME(0, Rt),
   2187 		    SREGNAME(1, Rn),
   2188 		    SignExtend(9, imm9, 1));
   2189 	}
   2190 }
   2191 
   2192 OP4FUNC(op_ldtrsb, opc, imm9, Rn, Rt)
   2193 {
   2194 	if (imm9 == 0) {
   2195 		PRINTF("ldtrsb\t%s, [%s]\n",
   2196 		    ZREGNAME((opc ^ 1), Rt),
   2197 		    SREGNAME(1, Rn));
   2198 	} else {
   2199 		PRINTF("ldtrsb\t%s, [%s,#%"PRId64"]\n",
   2200 		    ZREGNAME((opc ^ 1), Rt),
   2201 		    SREGNAME(1, Rn),
   2202 		    SignExtend(9, imm9, 1));
   2203 	}
   2204 }
   2205 
   2206 OP4FUNC(op_ldtrsh, opc, imm9, Rn, Rt)
   2207 {
   2208 	if (imm9 == 0) {
   2209 		PRINTF("ldtrsh\t%s, [%s]\n",
   2210 		    ZREGNAME((opc ^ 1), Rt),
   2211 		    SREGNAME(1, Rn));
   2212 	} else {
   2213 		PRINTF("ldtrsh\t%s, [%s,#%"PRId64"]\n",
   2214 		    ZREGNAME((opc ^ 1), Rt),
   2215 		    SREGNAME(1, Rn),
   2216 		    SignExtend(9, imm9, 1));
   2217 	}
   2218 }
   2219 
   2220 OP3FUNC(op_ldtrsw, imm9, Rn, Rt)
   2221 {
   2222 	if (imm9 == 0) {
   2223 		PRINTF("ldtrsw\t%s, [%s]\n",
   2224 		    ZREGNAME(1, Rt),
   2225 		    SREGNAME(1, Rn));
   2226 	} else {
   2227 		PRINTF("ldtrsw\t%s, [%s,#%"PRId64"]\n",
   2228 		    ZREGNAME(1, Rt),
   2229 		    SREGNAME(1, Rn),
   2230 		    SignExtend(9, imm9, 1));
   2231 	}
   2232 }
   2233 
   2234 OP4FUNC(op_ldur, size, imm9, Rn, Rt)
   2235 {
   2236 	if (imm9 == 0) {
   2237 		PRINTF("ldur\t%s, [%s]\n",
   2238 		    ZREGNAME(size, Rt),
   2239 		    SREGNAME(1, Rn));
   2240 	} else {
   2241 		PRINTF("ldur\t%s, [%s,#%"PRId64"]\n",
   2242 		    ZREGNAME(size, Rt),
   2243 		    SREGNAME(1, Rn),
   2244 		    SignExtend(9, imm9, 1));
   2245 	}
   2246 }
   2247 
   2248 OP3FUNC(op_ldurb, imm9, Rn, Rt)
   2249 {
   2250 	if (imm9 == 0) {
   2251 		PRINTF("ldurb\t%s, [%s]\n",
   2252 		    ZREGNAME(0, Rt),
   2253 		    SREGNAME(1, Rn));
   2254 	} else {
   2255 		PRINTF("ldurb\t%s, [%s,#%"PRId64"]\n",
   2256 		    ZREGNAME(0, Rt),
   2257 		    SREGNAME(1, Rn),
   2258 		    SignExtend(9, imm9, 1));
   2259 	}
   2260 }
   2261 
   2262 OP3FUNC(op_ldurh, imm9, Rn, Rt)
   2263 {
   2264 	if (imm9 == 0) {
   2265 		PRINTF("ldurh\t%s, [%s]\n",
   2266 		    ZREGNAME(0, Rt),
   2267 		    SREGNAME(1, Rn));
   2268 	} else {
   2269 		PRINTF("ldurh\t%s, [%s,#%"PRId64"]\n",
   2270 		    ZREGNAME(0, Rt),
   2271 		    SREGNAME(1, Rn),
   2272 		    SignExtend(9, imm9, 1));
   2273 	}
   2274 }
   2275 
   2276 OP4FUNC(op_ldursb, opc, imm9, Rn, Rt)
   2277 {
   2278 	if (imm9 == 0) {
   2279 		PRINTF("ldursb\t%s, [%s]\n",
   2280 		    ZREGNAME((opc ^ 1), Rt),
   2281 		    SREGNAME(1, Rn));
   2282 	} else {
   2283 		PRINTF("ldursb\t%s, [%s,#%"PRId64"]\n",
   2284 		    ZREGNAME((opc ^ 1), Rt),
   2285 		    SREGNAME(1, Rn),
   2286 		    SignExtend(9, imm9, 1));
   2287 	}
   2288 }
   2289 
   2290 OP4FUNC(op_ldursh, opc, imm9, Rn, Rt)
   2291 {
   2292 	if (imm9 == 0) {
   2293 		PRINTF("ldursh\t%s, [%s]\n",
   2294 		    ZREGNAME((opc ^ 1), Rt),
   2295 		    SREGNAME(1, Rn));
   2296 	} else {
   2297 		PRINTF("ldursh\t%s, [%s,#%"PRId64"]\n",
   2298 		    ZREGNAME((opc ^ 1), Rt),
   2299 		    SREGNAME(1, Rn),
   2300 		    SignExtend(9, imm9, 1));
   2301 	}
   2302 }
   2303 
   2304 OP3FUNC(op_ldursw, imm9, Rn, Rt)
   2305 {
   2306 	if (imm9 == 0) {
   2307 		PRINTF("ldursw\t%s, [%s]\n",
   2308 		    ZREGNAME(1, Rt),
   2309 		    SREGNAME(1, Rn));
   2310 	} else {
   2311 		PRINTF("ldursw\t%s, [%s,#%"PRId64"]\n",
   2312 		    ZREGNAME(1, Rt),
   2313 		    SREGNAME(1, Rn),
   2314 		    SignExtend(9, imm9, 1));
   2315 	}
   2316 }
   2317 
   2318 OP4FUNC(op_ldxp, size, Rt2, Rn, Rt)
   2319 {
   2320 	PRINTF("ldxp\t%s, %s, [%s]\n",
   2321 	    ZREGNAME(size, Rt),
   2322 	    ZREGNAME(size, Rt2),
   2323 	    SREGNAME(1, Rn));
   2324 }
   2325 
   2326 OP3FUNC(op_ldxr, size, Rn, Rt)
   2327 {
   2328 	PRINTF("ldxr\t%s, [%s]\n",
   2329 	    ZREGNAME(size, Rt),
   2330 	    SREGNAME(1, Rn));
   2331 }
   2332 
   2333 OP2FUNC(op_ldxrb, Rn, Rt)
   2334 {
   2335 	PRINTF("ldxrb\t%s, [%s]\n",
   2336 	    ZREGNAME(0, Rt),
   2337 	    SREGNAME(1, Rn));
   2338 }
   2339 
   2340 OP2FUNC(op_ldxrh, Rn, Rt)
   2341 {
   2342 	PRINTF("ldxrh\t%s, [%s]\n",
   2343 	    ZREGNAME(0, Rt),
   2344 	    SREGNAME(1, Rn));
   2345 }
   2346 
   2347 OP6FUNC(op_ubfm, sf, n, immr, imms, Rn, Rd)
   2348 {
   2349 	const uint64_t bitwidth = (sf == 0) ? 32 : 64;
   2350 
   2351 	/* ALIAS: lsr_imm,ubfiz,ubfm,ubfx,uxtb,uxth */
   2352 	if ((imms != (bitwidth - 1)) && ((imms + 1) == immr)) {
   2353 		PRINTF("lsl\t%s, %s, #%"PRIu64"\n",
   2354 		    ZREGNAME(sf, Rd),
   2355 		    ZREGNAME(sf, Rn),
   2356 		    bitwidth - immr);
   2357 	} else if (imms == (bitwidth - 1)) {
   2358 		PRINTF("lsr\t%s, %s, #%"PRIu64"\n",
   2359 		    ZREGNAME(sf, Rd),
   2360 		    ZREGNAME(sf, Rn),
   2361 		    immr);
   2362 	} else if (imms < immr) {
   2363 		PRINTF("ubfiz\t%s, %s, #%"PRIu64", #%"PRIu64"\n",
   2364 		    ZREGNAME(sf, Rd),
   2365 		    ZREGNAME(sf, Rn),
   2366 		    (bitwidth - immr) & (bitwidth - 1),
   2367 		    (imms + 1) & (bitwidth - 1));
   2368 	} else if (BFXPreferred(sf, 1, imms, immr)) {
   2369 		PRINTF("ubfx\t%s, %s, #%"PRIu64", #%"PRIu64"\n",
   2370 		    ZREGNAME(sf, Rd),
   2371 		    ZREGNAME(sf, Rn),
   2372 		    immr,
   2373 		    (imms - immr + 1) & (bitwidth - 1));
   2374 	} else if ((immr == 0) && (imms == 7)) {
   2375 		PRINTF("uxtb\t%s, %s\n",
   2376 		    ZREGNAME(0, Rd),
   2377 		    ZREGNAME(0, Rn));
   2378 	} else if ((immr == 0) && (imms == 15)) {
   2379 		PRINTF("uxth\t%s, %s\n",
   2380 		    ZREGNAME(0, Rd),
   2381 		    ZREGNAME(0, Rn));
   2382 	} else {
   2383 		UNDEFINED(pc, insn, "undefined");
   2384 	}
   2385 }
   2386 
   2387 OP4FUNC(op_lsl_reg, sf, Rm, Rn, Rd)
   2388 {
   2389 	/* ALIAS: lslv */
   2390 	/* "lsl" always the preferred disassembly */
   2391 	PRINTF("lsl\t%s, %s, %s\n",
   2392 	    ZREGNAME(sf, Rd),
   2393 	    ZREGNAME(sf, Rn),
   2394 	    ZREGNAME(sf, Rm));
   2395 }
   2396 
   2397 OP4FUNC(op_lsr_reg, sf, Rm, Rn, Rd)
   2398 {
   2399 	/* ALIAS: lsrv */
   2400 	/* "lsr" always the preferred disassembly */
   2401 	PRINTF("lsr\t%s, %s, %s\n",
   2402 	    ZREGNAME(sf, Rd),
   2403 	    ZREGNAME(sf, Rn),
   2404 	    ZREGNAME(sf, Rm));
   2405 }
   2406 
   2407 OP5FUNC(op_madd, sf, Rm, Ra, Rn, Rd)
   2408 {
   2409 	/* ALIAS: mul */
   2410 	if (Ra == 31) {
   2411 		PRINTF("mul\t%s, %s, %s\n",
   2412 		    ZREGNAME(sf, Rd),
   2413 		    ZREGNAME(sf, Rn),
   2414 		    ZREGNAME(sf, Rm));
   2415 	} else {
   2416 		PRINTF("madd\t%s, %s, %s, %s\n",
   2417 		    ZREGNAME(sf, Rd),
   2418 		    ZREGNAME(sf, Rn),
   2419 		    ZREGNAME(sf, Rm),
   2420 		    ZREGNAME(sf, Ra));
   2421 	}
   2422 }
   2423 
   2424 OP5FUNC(op_msub, sf, Rm, Ra, Rn, Rd)
   2425 {
   2426 	/* ALIAS: mneg */
   2427 	if (Ra == 31) {
   2428 		PRINTF("mneg\t%s, %s, %s\n",
   2429 		    ZREGNAME(sf, Rd),
   2430 		    ZREGNAME(sf, Rn),
   2431 		    ZREGNAME(sf, Rm));
   2432 	} else {
   2433 		PRINTF("msub\t%s, %s, %s, %s\n",
   2434 		    ZREGNAME(sf, Rd),
   2435 		    ZREGNAME(sf, Rn),
   2436 		    ZREGNAME(sf, Rm),
   2437 		    ZREGNAME(sf, Ra));
   2438 	}
   2439 }
   2440 
   2441 OP6FUNC(op_orr_imm, sf, n, immr, imms, Rn, Rd)
   2442 {
   2443 	if (!ValidBitMasks(sf, n, imms, immr)) {
   2444 		UNDEFINED(pc, insn, "illegal bitmasks");
   2445 		return;
   2446 	}
   2447 
   2448 	/* ALIAS: mov_bmimm */
   2449 #if 1
   2450 	/* to distinguish from mov_iwimm */
   2451 	if ((Rn == 31) && !MoveWidePreferred(sf, n, imms, immr)) {
   2452 #else
   2453 	/* "orr Rd, XZR, #imm" -> "mov Rd, #imm" */
   2454 	(void)MoveWidePreferred;
   2455 	if (Rn == 31) {
   2456 #endif
   2457 		PRINTF("mov\t%s, #0x%"PRIx64"\n",
   2458 		    SREGNAME(sf, Rd),
   2459 		    DecodeBitMasks(sf, n, imms, immr));
   2460 	} else {
   2461 		PRINTF("orr\t%s, %s, #0x%"PRIx64"\n",
   2462 		    SREGNAME(sf, Rd),
   2463 		    ZREGNAME(sf, Rn),
   2464 		    DecodeBitMasks(sf, n, imms, immr));
   2465 	}
   2466 }
   2467 
   2468 OP4FUNC(op_movn, sf, hw, imm16, Rd)
   2469 {
   2470 	const uint64_t mask = (sf == 0) ? 0xffffffff : 0xffffffffffffffffUL;
   2471 
   2472 	if ((sf == 0) && (hw >= 2)) {
   2473 		UNDEFINED(pc, insn, "illegal size");
   2474 		return;
   2475 	}
   2476 
   2477 	/* ALIAS: mov_iwimm */
   2478 	if ((hw == 0) || (imm16 == 0)) {
   2479 		PRINTF("mov\t%s, #0x%"PRIx64"\n",
   2480 		    ZREGNAME(sf, Rd),
   2481 		    (~(ZeroExtend(16, imm16, 1) & mask)) & mask);
   2482 	} else {
   2483 		/* movn */
   2484 		const uint64_t shift = hw * 16;
   2485 		PRINTF("mov\t%s, #0x%"PRIx64"\n",
   2486 		    ZREGNAME(sf, Rd),
   2487 		    ~(ZeroExtend(16, imm16, 1) << shift) & mask);
   2488 	}
   2489 }
   2490 
   2491 OP6FUNC(op_orr_reg, sf, shift, Rm, imm6, Rn, Rd)
   2492 {
   2493 	/* ALIAS: mov_reg */
   2494 	if ((Rn == 31) && (imm6 == 0)) {
   2495 		PRINTF("mov\t%s, %s\n",
   2496 		    ZREGNAME(sf, Rd),
   2497 		    ZREGNAME(sf, Rm));
   2498 	} else {
   2499 		shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   2500 		    "orr", NULL, NULL);
   2501 	}
   2502 }
   2503 
   2504 OP4FUNC(op_movz, sf, hw, imm16, Rd)
   2505 {
   2506 	/* ALIAS: mov_wimm */
   2507 	if ((hw == 0) || (imm16 == 0)) {
   2508 		PRINTF("mov\t%s, #0x%"PRIx64"\n",
   2509 		    ZREGNAME(sf, Rd),
   2510 		    ZeroExtend(16, imm16, 1));
   2511 	} else {
   2512 		const int shift = hw * 16;
   2513 #if 0
   2514 		PRINTF("movz\t%s, #0x%lx, lsl #%d\n",
   2515 		    ZREGNAME(sf, Rd),
   2516 		    ZeroExtend(16, imm16, 1), shift);
   2517 #else
   2518 		/* same as objdump */
   2519 		PRINTF("mov\t%s, #0x%"PRIx64"\n",
   2520 		    ZREGNAME(sf, Rd),
   2521 		    ZeroExtend(16, imm16, 1) << shift);
   2522 #endif
   2523 	}
   2524 }
   2525 
   2526 OP4FUNC(op_movk, sf, hw, imm16, Rd)
   2527 {
   2528 	const int shift = hw * 16;
   2529 
   2530 	if (hw == 0) {
   2531 		PRINTF("movk\t%s, #0x%"PRIx64"\n",
   2532 		    ZREGNAME(sf, Rd),
   2533 		    ZeroExtend(16, imm16, 1));
   2534 	} else {
   2535 		PRINTF("movk\t%s, #0x%"PRIx64", lsl #%d\n",
   2536 		    ZREGNAME(sf, Rd),
   2537 		    ZeroExtend(16, imm16, 1), shift);
   2538 	}
   2539 }
   2540 
   2541 OP6FUNC(op_mrs, op0, op1, CRn, CRm, op2, Rt)
   2542 {
   2543 	char buf[SYSREGNAMEBUFLEN];
   2544 
   2545 	PRINTF("mrs\t%s, %s\n",
   2546 	    ZREGNAME(1, Rt),
   2547 	    RSYSREGNAME(buf, sizeof(buf), op0, op1, CRn, CRm, op2));
   2548 }
   2549 
   2550 OP6FUNC(op_msr, op0, op1, CRn, CRm, op2, Rt)
   2551 {
   2552 	char buf[SYSREGNAMEBUFLEN];
   2553 
   2554 	PRINTF("msr\t%s, %s\n",
   2555 	    WSYSREGNAME(buf, sizeof(buf), op0, op1, CRn, CRm, op2),
   2556 	    ZREGNAME(1, Rt));
   2557 }
   2558 
   2559 OP3FUNC(op_msr_imm, op1, CRm, op2)
   2560 {
   2561 	const char *pstatefield;
   2562 
   2563 #define MSRIMM_OP(op1, op2)	(((op1) << 3) | (op2))
   2564 
   2565 	switch (MSRIMM_OP(op1, op2)) {
   2566 	case MSRIMM_OP(0, 0):
   2567 		PRINTF("cfinv\n");
   2568 		return;
   2569 	case MSRIMM_OP(0, 1):
   2570 		PRINTF("xaflag\n");
   2571 		return;
   2572 	case MSRIMM_OP(0, 2):
   2573 		PRINTF("axflag\n");
   2574 		return;
   2575 	case MSRIMM_OP(0, 3):
   2576 		pstatefield = "uao";
   2577 		break;
   2578 	case MSRIMM_OP(0, 4):
   2579 		pstatefield = "pan";
   2580 		break;
   2581 	case MSRIMM_OP(0, 5):
   2582 		pstatefield = "spsel";
   2583 		break;
   2584 	case MSRIMM_OP(3, 1):
   2585 		pstatefield = "ssbs";
   2586 		break;
   2587 	case MSRIMM_OP(3, 2):
   2588 		pstatefield = "dit";
   2589 		break;
   2590 	case MSRIMM_OP(3, 4):
   2591 		pstatefield = "tco";
   2592 		break;
   2593 	case MSRIMM_OP(3, 6):
   2594 		pstatefield = "daifset";
   2595 		break;
   2596 	case MSRIMM_OP(3, 7):
   2597 		pstatefield = "daifclr";
   2598 		break;
   2599 	default:
   2600 		UNDEFINED(pc, insn, "illegal op1/op2");
   2601 		return;
   2602 	}
   2603 
   2604 	PRINTF("msr\t%s, #0x%"PRIx64"\n",
   2605 	    pstatefield, CRm);
   2606 }
   2607 
   2608 OP6FUNC(op_orn, sf, shift, Rm, imm6, Rn, Rd)
   2609 {
   2610 	/* ALIAS: mvn */
   2611 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   2612 	    "orn", "mvn", NULL);
   2613 }
   2614 
   2615 OP6FUNC(op_sub_shiftreg, sf, shift, Rm, imm6, Rn, Rd)
   2616 {
   2617 	/* ALIAS: neg */
   2618 	shiftreg_common(di, pc, insn, sf, shift, Rm, imm6, Rn, Rd,
   2619 	    "sub", "neg", NULL);
   2620 }
   2621 
   2622 OP4FUNC(op_sbc, sf, Rm, Rn, Rd)
   2623 {
   2624 	/* ALIAS: ngc */
   2625 	if (Rn == 31) {
   2626 		PRINTF("ngc\t%s, %s\n",
   2627 		    ZREGNAME(sf, Rd),
   2628 		    ZREGNAME(sf, Rm));
   2629 	} else {
   2630 		PRINTF("sbc\t%s, %s, %s\n",
   2631 		    ZREGNAME(sf, Rd),
   2632 		    ZREGNAME(sf, Rn),
   2633 		    ZREGNAME(sf, Rm));
   2634 	}
   2635 }
   2636 
   2637 OP4FUNC(op_sbcs, sf, Rm, Rn, Rd)
   2638 {
   2639 	/* ALIAS: ngcs */
   2640 	if (Rn == 31) {
   2641 		PRINTF("ngcs\t%s, %s\n",
   2642 		    ZREGNAME(sf, Rd),
   2643 		    ZREGNAME(sf, Rm));
   2644 	} else {
   2645 		PRINTF("sbcs\t%s, %s, %s\n",
   2646 		    ZREGNAME(sf, Rd),
   2647 		    ZREGNAME(sf, Rn),
   2648 		    ZREGNAME(sf, Rm));
   2649 	}
   2650 }
   2651 
   2652 OP3FUNC(op_prfm_imm, imm12, Rn, Rt)
   2653 {
   2654 	if (imm12 == 0) {
   2655 		PRINTF("prfm\t%s, [%s]\n",
   2656 		    PREFETCHNAME(Rt),
   2657 		    SREGNAME(1, Rn));
   2658 	} else {
   2659 		PRINTF("prfm\t%s, [%s,#%"PRId64"]\n",
   2660 		    PREFETCHNAME(Rt),
   2661 		    SREGNAME(1, Rn),
   2662 		    SignExtend(12, imm12, 8));
   2663 	}
   2664 }
   2665 
   2666 OP2FUNC(op_prfm_literal, imm19, Rt)
   2667 {
   2668 	PRINTF("prfm\t%s, ", PREFETCHNAME(Rt));
   2669 	PRINTADDR(SignExtend(19, imm19, 4) + pc);
   2670 	PRINTF("\n");
   2671 }
   2672 
   2673 OP5FUNC(op_prfm_reg, Rm, option, shift, Rn, Rt)
   2674 {
   2675 	int r;
   2676 
   2677 	if ((r = regoffset_option_to_r(option)) < 0) {
   2678 		UNDEFINED(pc, insn, "illegal option");
   2679 		return;
   2680 	}
   2681 
   2682 	if (shift == 0) {
   2683 		PRINTF("prfm\t%s, [%s,%s%s]\n",
   2684 		    PREFETCHNAME(Rt),
   2685 		    SREGNAME(1, Rn),
   2686 		    ZREGNAME(r, Rm),
   2687 		    SHIFTOP8(option,
   2688 		        "", "", ",uxtw", "", "", "", ",sxtw", ",sxtx"));
   2689 	} else {
   2690 		PRINTF("prfm\t%s, [%s,%s,%s #%d]\n",
   2691 		    PREFETCHNAME(Rt),
   2692 		    SREGNAME(1, Rn),
   2693 		    ZREGNAME(r, Rm),
   2694 		    SHIFTOP8(option,
   2695 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"),
   2696 		    3);
   2697 	}
   2698 }
   2699 
   2700 OP3FUNC(op_prfum, imm9, Rn, Rt)
   2701 {
   2702 	if (imm9 == 0) {
   2703 		PRINTF("prfum\t%s, [%s]\n",
   2704 		    PREFETCHNAME(Rt),
   2705 		    SREGNAME(1, Rn));
   2706 	} else {
   2707 		PRINTF("prfum\t%s, [%s,#%"PRId64"]\n",
   2708 		    PREFETCHNAME(Rt),
   2709 		    SREGNAME(1, Rn),
   2710 		    SignExtend(9, imm9, 1));
   2711 	}
   2712 }
   2713 
   2714 OP1FUNC(op_ret, Rn)
   2715 {
   2716 	if (Rn == 30)
   2717 		PRINTF("ret\n");
   2718 	else
   2719 		PRINTF("ret\t%s\n", ZREGNAME(1, Rn));
   2720 }
   2721 
   2722 OP4FUNC(op_rev, sf, opc, Rn, Rd)
   2723 {
   2724 	/*
   2725 	 * sf opc insn
   2726 	 * -- --- -------------
   2727 	 * 0  00  rbit    Wd,Wn
   2728 	 * 0  01  rev16   Wd,Wn
   2729 	 * 0  10  rev     Wd,Wn
   2730 	 * 0  11  undefined
   2731 	 * 1  00  rbit    Xd,Xn
   2732 	 * 1  01  rev16   Xd,Xn
   2733 	 * 1  10  rev32   Xd,Xn
   2734 	 * 1  11  rev     Xd,Xn
   2735 	 */
   2736 	const char *const opcode[2][4] = {
   2737 		{ "rbit", "rev16", "rev",   NULL  },
   2738 		{ "rbit", "rev16", "rev32", "rev" }
   2739 	};
   2740 	const char *const op = opcode[sf][opc];
   2741 
   2742 	if (op == NULL) {
   2743 		UNDEFINED(pc, insn, "undefined");
   2744 		return;
   2745 	}
   2746 
   2747 	PRINTF("%s\t%s, %s\n",
   2748 	    op,
   2749 	    ZREGNAME(sf, Rd),
   2750 	    ZREGNAME(sf, Rn));
   2751 }
   2752 
   2753 OP4FUNC(op_ror_reg, sf, Rm, Rn, Rd)
   2754 {
   2755 	/* ALIAS: rorv */
   2756 	/* "ror" always the preferred disassembly */
   2757 	PRINTF("ror\t%s, %s, %s\n",
   2758 	    ZREGNAME(sf, Rd),
   2759 	    ZREGNAME(sf, Rn),
   2760 	    ZREGNAME(sf, Rm));
   2761 }
   2762 
   2763 OP4FUNC(op_sdiv, sf, Rm, Rn, Rd)
   2764 {
   2765 	PRINTF("sdiv\t%s, %s, %s\n",
   2766 	    ZREGNAME(sf, Rd),
   2767 	    ZREGNAME(sf, Rn),
   2768 	    ZREGNAME(sf, Rm));
   2769 }
   2770 
   2771 OP4FUNC(op_smaddl, Rm, Ra, Rn, Rd)
   2772 {
   2773 	/* ALIAS: smull */
   2774 	if (Ra == 31) {
   2775 		PRINTF("smull\t%s, %s, %s\n",
   2776 		    ZREGNAME(1, Rd),
   2777 		    ZREGNAME(0, Rn),
   2778 		    ZREGNAME(0, Rm));
   2779 	} else {
   2780 		PRINTF("smaddl\t%s, %s, %s, %s\n",
   2781 		    ZREGNAME(1, Rd),
   2782 		    ZREGNAME(0, Rn),
   2783 		    ZREGNAME(0, Rm),
   2784 		    ZREGNAME(1, Ra));
   2785 	}
   2786 }
   2787 
   2788 OP1FUNC(op_smc, imm16)
   2789 {
   2790 	PRINTF("smc\t#0x%"PRIx64"\n", imm16);
   2791 }
   2792 
   2793 OP4FUNC(op_smsubl, Rm, Ra, Rn, Rd)
   2794 {
   2795 	/* ALIAS: smnegl */
   2796 	if (Ra == 31) {
   2797 		PRINTF("smnegl\t%s, %s, %s\n",
   2798 		    ZREGNAME(1, Rd),
   2799 		    ZREGNAME(0, Rn),
   2800 		    ZREGNAME(0, Rm));
   2801 	} else {
   2802 		PRINTF("smsubl\t%s, %s, %s, %s\n",
   2803 		    ZREGNAME(1, Rd),
   2804 		    ZREGNAME(0, Rn),
   2805 		    ZREGNAME(0, Rm),
   2806 		    ZREGNAME(1, Ra));
   2807 	}
   2808 }
   2809 
   2810 OP3FUNC(op_smulh, Rm, Rn, Rd)
   2811 {
   2812 	PRINTF("smulh\t%s, %s, %s\n",
   2813 	    ZREGNAME(1, Rd),
   2814 	    ZREGNAME(1, Rn),
   2815 	    ZREGNAME(1, Rm));
   2816 }
   2817 
   2818 OP3FUNC(op_stlr, size, Rn, Rt)
   2819 {
   2820 	PRINTF("stlr\t%s, [%s]\n",
   2821 	    ZREGNAME(size, Rt),
   2822 	    SREGNAME(1, Rn));
   2823 }
   2824 
   2825 OP2FUNC(op_stlrb, Rn, Rt)
   2826 {
   2827 	PRINTF("stlrb\t%s, [%s]\n",
   2828 	    ZREGNAME(0, Rt),
   2829 	    SREGNAME(1, Rn));
   2830 }
   2831 
   2832 OP2FUNC(op_stlrh, Rn, Rt)
   2833 {
   2834 	PRINTF("stlrh\t%s, [%s]\n",
   2835 	    ZREGNAME(0, Rt),
   2836 	    SREGNAME(1, Rn));
   2837 }
   2838 
   2839 OP5FUNC(op_stlxp, size, Rs, Rt2, Rn, Rt)
   2840 {
   2841 	PRINTF("stlxp\t%s, %s, [%s]\n",
   2842 	    ZREGNAME(size, Rt),
   2843 	    ZREGNAME(size, Rt2),
   2844 	    SREGNAME(1, Rn));
   2845 }
   2846 
   2847 OP4FUNC(op_stlxr, size, Rs, Rn, Rt)
   2848 {
   2849 	PRINTF("stlxr\t%s, [%s]\n",
   2850 	    ZREGNAME(size, Rt),
   2851 	    SREGNAME(1, Rn));
   2852 }
   2853 
   2854 OP3FUNC(op_stlxrb, Rs, Rn, Rt)
   2855 {
   2856 	PRINTF("stlxrb\t%s, [%s]\n",
   2857 	    ZREGNAME(0, Rt),
   2858 	    SREGNAME(1, Rn));
   2859 }
   2860 
   2861 OP3FUNC(op_stlxrh, Rs, Rn, Rt)
   2862 {
   2863 	PRINTF("stlxrh\t%s, [%s]\n",
   2864 	    ZREGNAME(0, Rt),
   2865 	    SREGNAME(1, Rn));
   2866 }
   2867 
   2868 OP5FUNC(op_stnp, sf, imm7, Rt2, Rn, Rt)
   2869 {
   2870 	if (imm7 == 0) {
   2871 		PRINTF("stnp\t%s, %s, [%s]\n",
   2872 		    ZREGNAME(sf, Rt),
   2873 		    ZREGNAME(sf, Rt2),
   2874 		    SREGNAME(1, Rn));
   2875 	} else {
   2876 		PRINTF("stnp\t%s, %s, [%s,#%"PRId64"]\n",
   2877 		    ZREGNAME(sf, Rt),
   2878 		    ZREGNAME(sf, Rt2),
   2879 		    SREGNAME(1, Rn),
   2880 		    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   2881 	}
   2882 }
   2883 
   2884 OP5FUNC(op_stp_postidx, sf, imm7, Rt2, Rn, Rt)
   2885 {
   2886 	PRINTF("stp\t%s, %s, [%s],#%"PRId64"\n",
   2887 	    ZREGNAME(sf, Rt),
   2888 	    ZREGNAME(sf, Rt2),
   2889 	    SREGNAME(1, Rn),
   2890 	    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   2891 }
   2892 
   2893 OP5FUNC(op_stp_preidx, sf, imm7, Rt2, Rn, Rt)
   2894 {
   2895 	PRINTF("stp\t%s, %s, [%s,#%"PRId64"]!\n",
   2896 	    ZREGNAME(sf, Rt),
   2897 	    ZREGNAME(sf, Rt2),
   2898 	    SREGNAME(1, Rn),
   2899 	    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   2900 }
   2901 
   2902 OP5FUNC(op_stp_signed, sf, imm7, Rt2, Rn, Rt)
   2903 {
   2904 	if (imm7 == 0) {
   2905 		PRINTF("stp\t%s, %s, [%s]\n",
   2906 		    ZREGNAME(sf, Rt),
   2907 		    ZREGNAME(sf, Rt2),
   2908 		    SREGNAME(1, Rn));
   2909 	} else {
   2910 		PRINTF("stp\t%s, %s, [%s,#%"PRId64"]\n",
   2911 		    ZREGNAME(sf, Rt),
   2912 		    ZREGNAME(sf, Rt2),
   2913 		    SREGNAME(1, Rn),
   2914 		    SignExtend(7, imm7, (sf == 0) ? 4 : 8));
   2915 	}
   2916 }
   2917 
   2918 OP4FUNC(op_str_immpostidx, size, imm9, Rn, Rt)
   2919 {
   2920 	PRINTF("str\t%s, [%s],#%"PRId64"\n",
   2921 	    ZREGNAME(size, Rt),
   2922 	    SREGNAME(1, Rn),
   2923 	    SignExtend(9, imm9, 1));
   2924 }
   2925 
   2926 OP4FUNC(op_str_immpreidx, size, imm9, Rn, Rt)
   2927 {
   2928 	PRINTF("str\t%s, [%s,#%"PRId64"]!\n",
   2929 	    ZREGNAME(size, Rt),
   2930 	    SREGNAME(1, Rn),
   2931 	    SignExtend(9, imm9, 1));
   2932 }
   2933 
   2934 OP4FUNC(op_str_immunsign, size, imm12, Rn, Rt)
   2935 {
   2936 	if (imm12 == 0) {
   2937 		PRINTF("str\t%s, [%s]\n",
   2938 		    ZREGNAME(size, Rt),
   2939 		    SREGNAME(1, Rn));
   2940 	} else {
   2941 		PRINTF("str\t%s, [%s,#%"PRIu64"]\n",
   2942 		    ZREGNAME(size, Rt),
   2943 		    SREGNAME(1, Rn),
   2944 		    ZeroExtend(12, imm12, (size == 0) ? 4 : 8));
   2945 	}
   2946 }
   2947 
   2948 OP6FUNC(op_str_reg, size, Rm, option, shift, Rn, Rt)
   2949 {
   2950 	regoffset_x_common(di, pc, insn, size, Rm, option, shift, Rn, Rt,
   2951 	    "str");
   2952 }
   2953 
   2954 OP3FUNC(op_strb_immpostidx, imm9, Rn, Rt)
   2955 {
   2956 	PRINTF("strb\t%s, [%s],#%"PRId64"\n",
   2957 	    ZREGNAME(0, Rt),
   2958 	    SREGNAME(1, Rn),
   2959 	    SignExtend(9, imm9, 1));
   2960 }
   2961 
   2962 OP3FUNC(op_strb_immpreidx, imm9, Rn, Rt)
   2963 {
   2964 	PRINTF("strb\t%s, [%s,#%"PRId64"]!\n",
   2965 	    ZREGNAME(0, Rt),
   2966 	    SREGNAME(1, Rn),
   2967 	    SignExtend(9, imm9, 1));
   2968 }
   2969 
   2970 OP3FUNC(op_strb_immunsign, imm12, Rn, Rt)
   2971 {
   2972 	if (imm12 == 0) {
   2973 		PRINTF("strb\t%s, [%s]\n",
   2974 		    ZREGNAME(0, Rt),
   2975 		    SREGNAME(1, Rn));
   2976 	} else {
   2977 		PRINTF("strb\t%s, [%s,#%"PRIu64"]\n",
   2978 		    ZREGNAME(0, Rt),
   2979 		    SREGNAME(1, Rn),
   2980 		    ZeroExtend(12, imm12, 1));
   2981 	}
   2982 }
   2983 
   2984 OP5FUNC(op_strb_reg, Rm, option, shift, Rn, Rt)
   2985 {
   2986 	regoffset_b_common(di, pc, insn, Rm, option, shift, Rn, Rt, "strb");
   2987 }
   2988 
   2989 OP3FUNC(op_strh_immpostidx, imm9, Rn, Rt)
   2990 {
   2991 	PRINTF("strh\t%s, [%s],#%"PRId64"\n",
   2992 	    ZREGNAME(0, Rt),
   2993 	    SREGNAME(1, Rn),
   2994 	    SignExtend(9, imm9, 1));
   2995 }
   2996 
   2997 OP3FUNC(op_strh_immpreidx, imm9, Rn, Rt)
   2998 {
   2999 	PRINTF("strh\t%s, [%s,#%"PRId64"]!\n",
   3000 	    ZREGNAME(0, Rt),
   3001 	    SREGNAME(1, Rn),
   3002 	    SignExtend(9, imm9, 1));
   3003 }
   3004 
   3005 OP3FUNC(op_strh_immunsign, imm12, Rn, Rt)
   3006 {
   3007 	if (imm12 == 0) {
   3008 		PRINTF("strh\t%s, [%s]\n",
   3009 		    ZREGNAME(0, Rt),
   3010 		    SREGNAME(1, Rn));
   3011 	} else {
   3012 		PRINTF("strh\t%s, [%s,#%"PRId64"]\n",
   3013 		    ZREGNAME(0, Rt),
   3014 		    SREGNAME(1, Rn),
   3015 		    ZeroExtend(12, imm12, 2));
   3016 	}
   3017 }
   3018 
   3019 OP5FUNC(op_strh_reg, Rm, option, shift, Rn, Rt)
   3020 {
   3021 	regoffset_h_common(di, pc, insn, Rm, option, shift, Rn, Rt, 0, "strh");
   3022 }
   3023 
   3024 OP4FUNC(op_sttr, size, imm9, Rn, Rt)
   3025 {
   3026 	if (imm9 == 0) {
   3027 		PRINTF("sttr\t%s, [%s]\n",
   3028 		    ZREGNAME(size, Rt),
   3029 		    SREGNAME(1, Rn));
   3030 	} else {
   3031 		PRINTF("sttr\t%s, [%s,#%"PRId64"]\n",
   3032 		    ZREGNAME(size, Rt),
   3033 		    SREGNAME(1, Rn),
   3034 		    SignExtend(9, imm9, 1));
   3035 	}
   3036 }
   3037 
   3038 OP3FUNC(op_sttrb, imm9, Rn, Rt)
   3039 {
   3040 	if (imm9 == 0) {
   3041 		PRINTF("sttrb\t%s, [%s]\n",
   3042 		    ZREGNAME(0, Rt),
   3043 		    SREGNAME(1, Rn));
   3044 	} else {
   3045 		PRINTF("sttrb\t%s, [%s,#%"PRId64"]\n",
   3046 		    ZREGNAME(0, Rt),
   3047 		    SREGNAME(1, Rn),
   3048 		    SignExtend(9, imm9, 1));
   3049 	}
   3050 }
   3051 
   3052 OP3FUNC(op_sttrh, imm9, Rn, Rt)
   3053 {
   3054 	if (imm9 == 0) {
   3055 		PRINTF("sttrh\t%s, [%s]\n",
   3056 		    ZREGNAME(0, Rt),
   3057 		    SREGNAME(1, Rn));
   3058 	} else {
   3059 		PRINTF("sttrh\t%s, [%s,#%"PRId64"]\n",
   3060 		    ZREGNAME(0, Rt),
   3061 		    SREGNAME(1, Rn),
   3062 		    SignExtend(9, imm9, 1));
   3063 	}
   3064 }
   3065 
   3066 OP4FUNC(op_stur, size, imm9, Rn, Rt)
   3067 {
   3068 	if (imm9 == 0) {
   3069 		PRINTF("stur\t%s, [%s]\n",
   3070 		    ZREGNAME(size, Rt),
   3071 		    SREGNAME(1, Rn));
   3072 	} else {
   3073 		PRINTF("stur\t%s, [%s,#%"PRId64"]\n",
   3074 		    ZREGNAME(size, Rt),
   3075 		    SREGNAME(1, Rn),
   3076 		    SignExtend(9, imm9, 1));
   3077 	}
   3078 }
   3079 
   3080 OP3FUNC(op_sturb, imm9, Rn, Rt)
   3081 {
   3082 	if (imm9 == 0) {
   3083 		PRINTF("sturb\t%s, [%s]\n",
   3084 		    ZREGNAME(0, Rt),
   3085 		    SREGNAME(1, Rn));
   3086 	} else {
   3087 		PRINTF("sturb\t%s, [%s,#%"PRId64"]\n",
   3088 		    ZREGNAME(0, Rt),
   3089 		    SREGNAME(1, Rn),
   3090 		    SignExtend(9, imm9, 1));
   3091 	}
   3092 }
   3093 
   3094 OP3FUNC(op_sturh, imm9, Rn, Rt)
   3095 {
   3096 	if (imm9 == 0) {
   3097 		PRINTF("sturh\t%s, [%s]\n",
   3098 		    ZREGNAME(0, Rt),
   3099 		    SREGNAME(1, Rn));
   3100 	} else {
   3101 		PRINTF("sturh\t%s, [%s,#%"PRId64"]\n",
   3102 		    ZREGNAME(0, Rt),
   3103 		    SREGNAME(1, Rn),
   3104 		    SignExtend(9, imm9, 1));
   3105 	}
   3106 }
   3107 
   3108 OP5FUNC(op_stxp, size, Rs, Rt2, Rn, Rt)
   3109 {
   3110 	PRINTF("stxp\t%s, %s, [%s]\n",
   3111 	    ZREGNAME(size, Rt),
   3112 	    ZREGNAME(size, Rt2),
   3113 	    SREGNAME(1, Rn));
   3114 }
   3115 
   3116 OP4FUNC(op_stxr, size, Rs, Rn, Rt)
   3117 {
   3118 	PRINTF("stxr\t%s, %s, [%s]\n",
   3119 	    ZREGNAME(0, Rs),
   3120 	    ZREGNAME(size, Rt),
   3121 	    SREGNAME(1, Rn));
   3122 }
   3123 
   3124 OP3FUNC(op_stxrb, Rs, Rn, Rt)
   3125 {
   3126 	PRINTF("stxrb\t%s, %s, [%s]\n",
   3127 	    ZREGNAME(0, Rs),
   3128 	    ZREGNAME(0, Rt),
   3129 	    SREGNAME(1, Rn));
   3130 }
   3131 
   3132 OP3FUNC(op_stxrh, Rs, Rn, Rt)
   3133 {
   3134 	PRINTF("stxrh\t%s, %s, [%s]\n",
   3135 	    ZREGNAME(0, Rs),
   3136 	    ZREGNAME(0, Rt),
   3137 	    SREGNAME(1, Rn));
   3138 }
   3139 
   3140 OP6FUNC(op_sub_extreg, sf, Rm, option, imm3, Rn, Rd)
   3141 {
   3142 	extendreg_common(di, pc, insn, sf, Rm, option, imm3, Rn, Rd,
   3143 	    "sub", NULL);
   3144 }
   3145 
   3146 OP5FUNC(op_sub_imm, sf, shift, imm12, Rn, Rd)
   3147 {
   3148 	if (shift & 2) {
   3149 		UNDEFINED(pc, insn, "illegal shift");
   3150 		return;
   3151 	}
   3152 
   3153 	PRINTF("sub\t%s, %s, #0x%"PRIx64"%s\n",
   3154 	    SREGNAME(sf, Rd),
   3155 	    SREGNAME(sf, Rn),
   3156 	    ZeroExtend(12, imm12, 1),
   3157 	    SHIFTOP2(shift, "", ", lsl #12"));
   3158 }
   3159 
   3160 OP1FUNC(op_svc, imm16)
   3161 {
   3162 	PRINTF("svc\t#0x%"PRIx64"\n",
   3163 	    imm16);
   3164 }
   3165 
   3166 OP5FUNC(op_sysl, op1, CRn, CRm, op2, Rt)
   3167 {
   3168 	PRINTF("sysl\t%s, #%"PRIu64", %s, %s, #%"PRIu64"\n",
   3169 	    ZREGNAME(1, Rt),
   3170 	    op1,
   3171 	    CREGNAME(CRn),
   3172 	    CREGNAME(CRm),
   3173 	    op2);
   3174 }
   3175 
   3176 OP4FUNC(op_tbnz, b5, b40, imm14, Rt)
   3177 {
   3178 	uint64_t bit = (b5 << 5) + b40;
   3179 
   3180 	PRINTF("tbnz\t%s, #%"PRIu64", ",
   3181 	    ZREGNAME(b5, Rt),
   3182 	    bit);
   3183 	PRINTADDR(SignExtend(14, imm14, 4) + pc);
   3184 	PRINTF("\n");
   3185 }
   3186 
   3187 OP4FUNC(op_tbz, b5, b40, imm14, Rt)
   3188 {
   3189 	uint64_t bit = (b5 << 5) + b40;
   3190 
   3191 	PRINTF("tbz\t%s, #%"PRIu64", ",
   3192 	    ZREGNAME(b5, Rt),
   3193 	    bit);
   3194 	PRINTADDR(SignExtend(14, imm14, 4) + pc);
   3195 	PRINTF("\n");
   3196 }
   3197 
   3198 OP4FUNC(op_udiv, sf, Rm, Rn, Rd)
   3199 {
   3200 	PRINTF("udiv\t%s, %s, %s\n",
   3201 	    ZREGNAME(sf, Rd),
   3202 	    ZREGNAME(sf, Rn),
   3203 	    ZREGNAME(sf, Rm));
   3204 }
   3205 
   3206 OP4FUNC(op_umaddl, Rm, Ra, Rn, Rd)
   3207 {
   3208 	/* ALIAS: umull */
   3209 	if (Ra == 31) {
   3210 		PRINTF("umull\t%s, %s, %s\n",
   3211 		    ZREGNAME(1, Rd),
   3212 		    ZREGNAME(0, Rn),
   3213 		    ZREGNAME(0, Rm));
   3214 	} else {
   3215 		PRINTF("umaddl\t%s, %s, %s, %s\n",
   3216 		    ZREGNAME(1, Rd),
   3217 		    ZREGNAME(0, Rn),
   3218 		    ZREGNAME(0, Rm),
   3219 		    ZREGNAME(1, Ra));
   3220 	}
   3221 }
   3222 
   3223 OP4FUNC(op_umsubl, Rm, Ra, Rn, Rd)
   3224 {
   3225 	/* ALIAS: umnegl */
   3226 	if (Ra == 31) {
   3227 		PRINTF("umnegl\t%s, %s, %s\n",
   3228 		    ZREGNAME(1, Rd),
   3229 		    ZREGNAME(1, Rn),
   3230 		    ZREGNAME(1, Rm));
   3231 	} else {
   3232 		PRINTF("umsubl\t%s, %s, %s, %s\n",
   3233 		    ZREGNAME(1, Rd),
   3234 		    ZREGNAME(1, Rn),
   3235 		    ZREGNAME(1, Rm),
   3236 		    ZREGNAME(1, Ra));
   3237 	}
   3238 }
   3239 
   3240 OP3FUNC(op_umulh, Rm, Rn, Rd)
   3241 {
   3242 	PRINTF("umulh\t%s, %s, %s\n",
   3243 	    ZREGNAME(1, Rd),
   3244 	    ZREGNAME(1, Rn),
   3245 	    ZREGNAME(1, Rm));
   3246 }
   3247 
   3248 /*
   3249  * load/store SIMD instructions
   3250  */
   3251 OP6FUNC(op_simd_ldstnp, opc, l, imm7, Rt2, Rn, Rt)
   3252 {
   3253 	const char *op = (l == 0) ? "stnp" : "ldnp";
   3254 	const int regsz = (opc & 3) + 2;
   3255 
   3256 	if (opc == 3) {
   3257 		UNDEFINED(pc, insn, "illegal opc");
   3258 		return;
   3259 	}
   3260 
   3261 	if (imm7 == 0) {
   3262 		PRINTF("%s\t%s, %s, [%s]\n",
   3263 		    op,
   3264 		    FREGNAME(regsz, Rt),
   3265 		    FREGNAME(regsz, Rt2),
   3266 		    SREGNAME(1, Rn));
   3267 	} else {
   3268 		PRINTF("%s\t%s, %s, [%s,#%"PRId64"]\n",
   3269 		    op,
   3270 		    FREGNAME(regsz, Rt),
   3271 		    FREGNAME(regsz, Rt2),
   3272 		    SREGNAME(1, Rn),
   3273 		    SignExtend(7, imm7, (4 << opc)));
   3274 	}
   3275 }
   3276 
   3277 OP6FUNC(op_simd_ldstp_postidx, opc, l, imm7, Rt2, Rn, Rt)
   3278 {
   3279 	const char *op = (l == 0) ? "stp" : "ldp";
   3280 	const int regsz = (opc & 3) + 2;
   3281 
   3282 	PRINTF("%s\t%s, %s, [%s],#%"PRId64"\n",
   3283 	    op,
   3284 	    FREGNAME(regsz, Rt),
   3285 	    FREGNAME(regsz, Rt2),
   3286 	    SREGNAME(1, Rn),
   3287 	    SignExtend(7, imm7, (4 << opc)));
   3288 }
   3289 
   3290 OP6FUNC(op_simd_ldstp_preidx, opc, l, imm7, Rt2, Rn, Rt)
   3291 {
   3292 	const char *op = (l == 0) ? "stp" : "ldp";
   3293 	const int regsz = (opc & 3) + 2;
   3294 
   3295 	PRINTF("%s\t%s, %s, [%s,#%"PRId64"]!\n",
   3296 	    op,
   3297 	    FREGNAME(regsz, Rt),
   3298 	    FREGNAME(regsz, Rt2),
   3299 	    SREGNAME(1, Rn),
   3300 	    SignExtend(7, imm7, (4 << opc)));
   3301 }
   3302 
   3303 OP6FUNC(op_simd_ldstp_signed, opc, l, imm7, Rt2, Rn, Rt)
   3304 {
   3305 	const char *op = (l == 0) ? "stp" : "ldp";
   3306 	const int regsz = (opc & 3) + 2;
   3307 
   3308 	if (opc == 3) {
   3309 		UNDEFINED(pc, insn, "illegal opc");
   3310 		return;
   3311 	}
   3312 
   3313 	if (imm7 == 0) {
   3314 		PRINTF("%s\t%s, %s, [%s]\n",
   3315 		    op,
   3316 		    FREGNAME(regsz, Rt),
   3317 		    FREGNAME(regsz, Rt2),
   3318 		    SREGNAME(1, Rn));
   3319 	} else {
   3320 		PRINTF("%s\t%s, %s, [%s,#%"PRId64"]\n",
   3321 		    op,
   3322 		    FREGNAME(regsz, Rt),
   3323 		    FREGNAME(regsz, Rt2),
   3324 		    SREGNAME(1, Rn),
   3325 		    SignExtend(7, imm7, (4 << opc)));
   3326 	}
   3327 }
   3328 
   3329 static inline int
   3330 simd_ldstr_regsz(uint64_t size, uint64_t opc)
   3331 {
   3332 	if ((opc & 2) == 0)
   3333 		return size;
   3334 	if (size == 0)
   3335 		return 4;
   3336 	return -1;
   3337 }
   3338 
   3339 OP5FUNC(op_simd_ldstr_immpostidx, size, opc, imm9, Rn, Rt)
   3340 {
   3341 	const char *op = ((opc & 1) == 0) ? "str" : "ldr";
   3342 	int regsz;
   3343 
   3344 	if ((regsz = simd_ldstr_regsz(size, opc)) < 0) {
   3345 		UNDEFINED(pc, insn, "illegal size/opc");
   3346 		return;
   3347 	}
   3348 
   3349 	PRINTF("%s\t%s, [%s],#%"PRId64"\n",
   3350 	    op,
   3351 	    FREGNAME(regsz, Rt),
   3352 	    SREGNAME(1, Rn),
   3353 	    SignExtend(9, imm9, 1));
   3354 }
   3355 
   3356 OP5FUNC(op_simd_ldstr_immpreidx, size, opc, imm9, Rn, Rt)
   3357 {
   3358 	const char *op = ((opc & 1) == 0) ? "str" : "ldr";
   3359 	int regsz;
   3360 
   3361 	if ((regsz = simd_ldstr_regsz(size, opc)) < 0) {
   3362 		UNDEFINED(pc, insn, "illegal size/opc");
   3363 		return;
   3364 	}
   3365 
   3366 	PRINTF("%s\t%s, [%s,#%"PRId64"]!\n",
   3367 	    op,
   3368 	    FREGNAME(regsz, Rt),
   3369 	    SREGNAME(1, Rn),
   3370 	    SignExtend(9, imm9, 1));
   3371 }
   3372 
   3373 OP5FUNC(op_simd_ldstr_immunsign, size, opc, imm12, Rn, Rt)
   3374 {
   3375 	const char *op = ((opc & 1) == 0) ? "str" : "ldr";
   3376 	int regsz;
   3377 
   3378 	if ((regsz = simd_ldstr_regsz(size, opc)) < 0) {
   3379 		UNDEFINED(pc, insn, "illegal size/opc");
   3380 		return;
   3381 	}
   3382 
   3383 	if (imm12 == 0) {
   3384 		PRINTF("%s\t%s, [%s]\n",
   3385 		    op,
   3386 		    FREGNAME(regsz, Rt),
   3387 		    SREGNAME(1, Rn));
   3388 	} else {
   3389 		PRINTF("%s\t%s, [%s,#%"PRIu64"]\n",
   3390 		    op,
   3391 		    FREGNAME(regsz, Rt),
   3392 		    SREGNAME(1, Rn),
   3393 		    ZeroExtend(12, imm12, 1 << regsz));
   3394 	}
   3395 }
   3396 
   3397 OP7FUNC(op_simd_ldstr_reg, size, opc, Rm, option, S, Rn, Rt)
   3398 {
   3399 	const char *op = ((opc & 1) == 0) ? "str" : "ldr";
   3400 	int regsz, r;
   3401 
   3402 	if ((regsz = simd_ldstr_regsz(size, opc)) < 0) {
   3403 		UNDEFINED(pc, insn, "illegal size/opc");
   3404 		return;
   3405 	}
   3406 
   3407 	if ((r = regoffset_option_to_r(option)) < 0) {
   3408 		UNDEFINED(pc, insn, "illegal option");
   3409 		return;
   3410 	}
   3411 
   3412 	if (S == 0) {
   3413 		PRINTF("%s\t%s, [%s,%s%s]\n",
   3414 		    op,
   3415 		    FREGNAME(regsz, Rt),
   3416 		    SREGNAME(1, Rn),
   3417 		    ZREGNAME(r, Rm),
   3418 		    SHIFTOP8(option,
   3419 		        "", "", ",uxtw", "", "", "", ",sxtw", ",sxtx"));
   3420 	} else {
   3421 		u_int amount = regsz;
   3422 		PRINTF("%s\t%s, [%s,%s,%s #%u]\n",
   3423 		    op,
   3424 		    FREGNAME(regsz, Rt),
   3425 		    SREGNAME(1, Rn),
   3426 		    ZREGNAME(r, Rm),
   3427 		    SHIFTOP8(option,
   3428 		        "", "", "uxtw", "lsl", "", "", "sxtw", "sxtx"),
   3429 		    amount);
   3430 	}
   3431 }
   3432 
   3433 OP4FUNC(op_simd_aes, m, d, Rn, Rt)
   3434 {
   3435 	const char *aesop[2][2] = {
   3436 		{	"aese",  "aesd",	},
   3437 		{	"aesmc", "aesimc"	}
   3438 	};
   3439 
   3440 	PRINTF("%s\t%s.16b, %s.16b\n",
   3441 	    aesop[m & 1][d & 1],
   3442 	    VREGNAME(Rn),
   3443 	    VREGNAME(Rt));
   3444 }
   3445 
   3446 OP4FUNC(op_simd_sha_reg3, Rm, op, Rn, Rd)
   3447 {
   3448 	const char *shaop[8] = {
   3449 		"sha1c",   "sha1p",    "sha1m",     "sha1su0",
   3450 		"sha256h", "sha256h2", "sha256su1", NULL
   3451 	};
   3452 
   3453 	switch (op) {
   3454 	case 0:
   3455 	case 1:
   3456 	case 2:
   3457 		PRINTF("%s\t%s, %s, %s.4s\n",
   3458 		    shaop[op],
   3459 		    FREGNAME(FREGSZ_Q, Rd),
   3460 		    FREGNAME(FREGSZ_S, Rn),
   3461 		    VREGNAME(Rm));
   3462 		break;
   3463 
   3464 	case 4:
   3465 	case 5:
   3466 		PRINTF("%s\t%s, %s, %s.4s\n",
   3467 		    shaop[op],
   3468 		    FREGNAME(FREGSZ_Q, Rd),
   3469 		    FREGNAME(FREGSZ_Q, Rn),
   3470 		    VREGNAME(Rm));
   3471 		break;
   3472 
   3473 	case 3:
   3474 	case 6:
   3475 		PRINTF("%s\t%s.4s, %s.4s, %s.4s\n",
   3476 		    shaop[op],
   3477 		    VREGNAME(Rd),
   3478 		    VREGNAME(Rn),
   3479 		    VREGNAME(Rm));
   3480 		break;
   3481 
   3482 	default:
   3483 		UNDEFINED(pc, insn, "illegal sha operation");
   3484 		break;
   3485 	}
   3486 }
   3487 
   3488 OP3FUNC(op_simd_sha_reg2, op, Rn, Rd)
   3489 {
   3490 	const char *shaop[4] = {
   3491 		"sha1h", "sha1su1", "sha256su0", NULL
   3492 	};
   3493 
   3494 	switch (op) {
   3495 	case 0:
   3496 		PRINTF("%s\t%s, %s\n",
   3497 		    shaop[op],
   3498 		    FREGNAME(FREGSZ_S, Rd),
   3499 		    FREGNAME(FREGSZ_S, Rn));
   3500 		break;
   3501 	case 1:
   3502 	case 2:
   3503 		PRINTF("%s\t%s.4s, %s.4s\n",
   3504 		    shaop[op],
   3505 		    VREGNAME(Rd),
   3506 		    VREGNAME(Rn));
   3507 		break;
   3508 	default:
   3509 		UNDEFINED(pc, insn, "illegal sha operation");
   3510 		break;
   3511 	}
   3512 }
   3513 
   3514 OP4FUNC(op_simd_sha512_reg3, Rm, op, Rn, Rd)
   3515 {
   3516 	const char *shaop[4] = {
   3517 		"sha512h", "sha512h2", "sha512su1", "rax1"
   3518 	};
   3519 
   3520 	switch (op) {
   3521 	case 0:
   3522 	case 1:
   3523 		PRINTF("%s\t%s, %s, %s.2d\n",
   3524 		    shaop[op],
   3525 		    FREGNAME(FREGSZ_Q, Rd),
   3526 		    FREGNAME(FREGSZ_Q, Rn),
   3527 		    VREGNAME(Rm));
   3528 		break;
   3529 	case 2:
   3530 	case 3:
   3531 		PRINTF("%s\t%s.2d, %s,.2d %s.2d\n",
   3532 		    shaop[op],
   3533 		    VREGNAME(Rd),
   3534 		    VREGNAME(Rn),
   3535 		    VREGNAME(Rm));
   3536 		break;
   3537 	}
   3538 }
   3539 
   3540 OP3FUNC(op_simd_sha512_reg2, op, Rn, Rd)
   3541 {
   3542 	const char *shaop[4] = {
   3543 		"sha512su0", "sm4e", NULL, NULL
   3544 	};
   3545 
   3546 	switch (op) {
   3547 	case 0:
   3548 	case 1:
   3549 		PRINTF("%s\t%s.2d, %s.2d\n",
   3550 		    shaop[op],
   3551 		    VREGNAME(Rd),
   3552 		    VREGNAME(Rn));
   3553 		break;
   3554 	default:
   3555 		UNDEFINED(pc, insn, "illegal sha512 operation");
   3556 		break;
   3557 	}
   3558 }
   3559 
   3560 OP5FUNC(op_simd_pmull, q, size, Rm, Rn, Rd)
   3561 {
   3562 	const char *op = (q == 0) ? "pmull" : "pmull2";
   3563 	const char *regspec_Ta[4] = {
   3564 		"8h", NULL, NULL, "1q"
   3565 	};
   3566 	const char *regspec_Tb[8] = {
   3567 		"8b", "16b", NULL, NULL,
   3568 		NULL, NULL, "1d", "2d"
   3569 	};
   3570 
   3571 	if ((regspec_Ta[size & 3] != NULL) &&
   3572 	    (regspec_Tb[((size & 3) << 1) + (q & 1)] != NULL)) {
   3573 		PRINTF("%s\t%s.%s, %s.%s, %s.%s\n",
   3574 		    op,
   3575 		    VREGNAME(Rd), regspec_Ta[size & 3],
   3576 		    VREGNAME(Rn), regspec_Tb[((size & 3) << 1) + (q & 1)],
   3577 		    VREGNAME(Rd), regspec_Tb[((size & 3) << 1) + (q & 1)]);
   3578 	} else {
   3579 		UNDEFINED(pc, insn, "illegal pmull size");
   3580 	}
   3581 }
   3582 
   3583 OP1FUNC(op_eretaa, m)
   3584 {
   3585 	if (m == 0)
   3586 		PRINTF("eretaa\n");
   3587 	else
   3588 		PRINTF("eretab\n");
   3589 
   3590 }
   3591 
   3592 OP1FUNC(op_retaa, m)
   3593 {
   3594 	if (m == 0)
   3595 		PRINTF("retaa\n");
   3596 	else
   3597 		PRINTF("retab\n");
   3598 }
   3599 
   3600 OP4FUNC(op_blraa, z, m, Rn, Rm)
   3601 {
   3602 	if (z == 0) {
   3603 		if (Rm != 31) {
   3604 			UNDEFINED(pc, insn, "undefined");
   3605 		} else {
   3606 			PRINTF("%s\t%s\n",
   3607 			    SHIFTOP2(m, "blraaz", "blrabz"),
   3608 			    SREGNAME(1, Rn));
   3609 		}
   3610 	} else {
   3611 		PRINTF("%s\t%s, %s\n",
   3612 		    SHIFTOP2(m, "blraa", "blrab"),
   3613 		    SREGNAME(1, Rn),
   3614 		    SREGNAME(1, Rm));
   3615 	}
   3616 }
   3617 
   3618 OP4FUNC(op_braa, z, m, Rn, Rm)
   3619 {
   3620 	if (z == 0) {
   3621 		if (Rm != 31) {
   3622 			UNDEFINED(pc, insn, "undefined");
   3623 		} else {
   3624 			PRINTF("%s\t%s\n",
   3625 			    SHIFTOP2(m, "braaz", "brabz"),
   3626 			    SREGNAME(1, Rn));
   3627 		}
   3628 	} else {
   3629 		PRINTF("%s\t%s, %s\n",
   3630 		    SHIFTOP2(m, "braa", "brab"),
   3631 		    SREGNAME(1, Rn),
   3632 		    SREGNAME(1, Rm));
   3633 	}
   3634 }
   3635 
   3636 OP4FUNC(op_pacda, z, m, Rn, Rd)
   3637 {
   3638 	if (z != 0) {
   3639 		if (Rn != 31) {
   3640 			UNDEFINED(pc, insn, "undefined");
   3641 		} else {
   3642 			PRINTF("%s\t%s\n",
   3643 			    SHIFTOP2(m, "pacdza", "pacdzb"),
   3644 			    SREGNAME(1, Rd));
   3645 		}
   3646 	} else {
   3647 		PRINTF("%s\t%s, %s\n",
   3648 		    SHIFTOP2(m, "pacda", "pacdb"),
   3649 		    ZREGNAME(1, Rd),
   3650 		    SREGNAME(1, Rn));
   3651 	}
   3652 }
   3653 
   3654 OP4FUNC(op_pacia, z, m, Rn, Rd)
   3655 {
   3656 	if (z != 0) {
   3657 		if (Rn != 31) {
   3658 			UNDEFINED(pc, insn, "undefined");
   3659 		} else {
   3660 			PRINTF("%s\t%s\n",
   3661 			    SHIFTOP2(m, "paciza", "pacizb"),
   3662 			    SREGNAME(1, Rd));
   3663 		}
   3664 	} else {
   3665 		PRINTF("%s\t%s, %s\n",
   3666 		    SHIFTOP2(m, "pacia", "pacib"),
   3667 		    ZREGNAME(1, Rd),
   3668 		    SREGNAME(1, Rn));
   3669 	}
   3670 }
   3671 
   3672 OP3FUNC(op_pacga, Rm, Rn, Rd)
   3673 {
   3674 	PRINTF("pacga\t%s, %s, %s\n",
   3675 	    ZREGNAME(1, Rd),
   3676 	    ZREGNAME(1, Rn),
   3677 	    SREGNAME(1, Rm));
   3678 }
   3679 
   3680 OP1FUNC(op_xpaci, Rd)
   3681 {
   3682 	PRINTF("xpaci\t%s\n",
   3683 	    ZREGNAME(1, Rd));
   3684 }
   3685 
   3686 OP1FUNC(op_xpacd, Rd)
   3687 {
   3688 	PRINTF("xpacd\t%s\n",
   3689 	    ZREGNAME(1, Rd));
   3690 }
   3691 
   3692 OP0FUNC(op_xpaclri)
   3693 {
   3694 	PRINTF("xpaclri\n");
   3695 }
   3696 
   3697 /*
   3698  * SIMD instructions are not supported except some insns.
   3699  * They are disassembled as '.insn 0xXXXXXXXX'.
   3700  */
   3701 struct bitpos {
   3702 	uint8_t pos;
   3703 	uint8_t width;
   3704 };
   3705 
   3706 struct insn_info {
   3707 	uint32_t mask;
   3708 	uint32_t pattern;
   3709 #define INSN_MAXARG	8
   3710 	struct bitpos bitinfo[INSN_MAXARG];
   3711 	OPFUNC_DECL(void (*opfunc),,,,,,,,);
   3712 };
   3713 
   3714 /* define code format  { {bitpos, bitwidth}, ... (maximum 8 args) } */
   3715 #define FMT_NOARG			\
   3716 	{{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3717 #define FMT_RD				\
   3718 	{{ 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3719 #define FMT_RN				\
   3720 	{{ 5, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3721 #define FMT_RN_RT			\
   3722 	{{ 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3723 #define FMT_M				\
   3724 	{{10, 1}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3725 #define FMT_CRM				\
   3726 	{{ 8, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3727 #define FMT_CRM_OP2			\
   3728 	{{ 8, 4}, { 5, 3}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3729 #define FMT_OP2_RN_RD			\
   3730 	{{10, 2}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3731 #define FMT_Z_M_RN_RD			\
   3732 	{{13, 1}, {10, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3733 #define FMT_M_D_RN_RD			\
   3734 	{{13, 1}, {12, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3735 #define FMT_OP3_RN_RD			\
   3736 	{{12, 3}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3737 #define FMT_OP1_CRM_OP2			\
   3738 	{{16, 3}, { 8, 4}, { 5, 3}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3739 #define FMT_OP1_CRN_CRM_OP2_RT		\
   3740 	{{16, 3}, {12, 4}, { 8, 4}, { 5, 3}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3741 #define FMT_RM_RN_RD			\
   3742 	{{16, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3743 #define FMT_RS_RN_RT			\
   3744 	{{16, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3745 #define FMT_RM_OP2_RN_RD		\
   3746 	{{16, 5}, {10, 2}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3747 #define FMT_RM_OP_RN_RD			\
   3748 	{{16, 5}, {12, 3}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3749 #define FMT_RM_RA_RN_RD			\
   3750 	{{16, 5}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3751 #define FMT_IMM9_RN_RT			\
   3752 	{{12, 9}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3753 #define FMT_RM_OPT_SHIFT_RN_RT		\
   3754 	{{16, 5}, {13, 3}, {12, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3755 #define FMT_IMM16			\
   3756 	{{ 5,16}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3757 #define FMT_IMM16_LL			\
   3758 	{{ 5,16}, { 0, 2}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3759 #define FMT_OP0_OP1_CRN_CRM_OP2_RT	\
   3760 	{{19, 2}, {16, 3}, {12, 4}, { 8, 4}, { 5, 3}, { 0, 5}, { 0, 0}, { 0, 0}}
   3761 #define FMT_IMM7_RT2_RN_RT		\
   3762 	{{15, 7}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3763 #define FMT_IMM12_RN_RT			\
   3764 	{{10,12}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3765 #define FMT_OPC_IMM9_RN_RT		\
   3766 	{{22, 1}, {12, 9}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3767 #define FMT_OPC_RM_OPT_SHIFT_RN_RT	\
   3768 	{{22, 1}, {16, 5}, {13, 3}, {12, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3769 #define FMT_OPC_IMM12_RN_RT		\
   3770 	{{22, 1}, {10,12}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3771 #define FMT_IMM19_COND			\
   3772 	{{ 5,19}, { 0, 4}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3773 #define FMT_IMM19_RT			\
   3774 	{{ 5,19}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3775 #define FMT_Z_M_RN_RM			\
   3776 	{{24, 1}, {10, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3777 #define FMT_IMM26			\
   3778 	{{ 0,26}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3779 #define FMT_SIZE_RN_RT			\
   3780 	{{30, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3781 #define FMT_SIZE_RT2_RN_RT		\
   3782 	{{30, 1}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3783 #define FMT_SIZE_RS_RN_RT		\
   3784 	{{30, 1}, {16, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3785 #define FMT_SIZE_RS_RT2_RN_RT		\
   3786 	{{30, 1}, {16, 5}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3787 #define FMT_SIZE_IMM9_RN_RT		\
   3788 	{{30, 1}, {12, 9}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3789 #define FMT_SIZE_RM_OPT_SHIFT_RN_RT	\
   3790 	{{30, 1}, {16, 5}, {13, 3}, {12, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3791 #define FMT_SIZE_IMM12_RN_RT		\
   3792 	{{30, 1}, {10,12}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3793 #define FMT_Q_SIZE_RM_RN_RD		\
   3794 	{{30, 1}, {22, 2}, {16, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3795 #define FMT_SIZE_IMM19_RT		\
   3796 	{{30, 1}, { 5,19}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3797 #define FMT_IMMLO_IMMHI_RD		\
   3798 	{{29, 2}, { 5,19}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3799 #define FMT_SF_RN_RD			\
   3800 	{{31, 1}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3801 #define FMT_SF_OPC_RN_RD		\
   3802 	{{31, 1}, {10, 2}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3803 #define FMT_SF_RM_RN_RD			\
   3804 	{{31, 1}, {16, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3805 #define FMT_SF_RM_SZ_RN_RD		\
   3806 	{{31, 1}, {16, 5}, {10, 2}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3807 #define FMT_SF_RM_RA_RN_RD		\
   3808 	{{31, 1}, {16, 5}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3809 #define FMT_SF_IMM5_COND_RN_NZCV	\
   3810 	{{31, 1}, {16, 5}, {12, 4}, { 5, 5}, { 0, 4}, { 0, 0}, { 0, 0}, { 0, 0}}
   3811 #define FMT_SF_RM_COND_RN_NZCV		\
   3812 	{{31, 1}, {16, 5}, {12, 4}, { 5, 5}, { 0, 4}, { 0, 0}, { 0, 0}, { 0, 0}}
   3813 #define FMT_SF_RM_COND_RN_RD		\
   3814 	{{31, 1}, {16, 5}, {12, 4}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3815 #define FMT_SF_RM_OPT_IMM3_RN_RD	\
   3816 	{{31, 1}, {16, 5}, {13, 3}, {10, 3}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3817 #define FMT_SF_RM_OP_IMM3_RN_RD		\
   3818 	{{31, 1}, {16, 5}, {13, 3}, {10, 3}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3819 #define FMT_SF_IMM7_RT2_RN_RT		\
   3820 	{{31, 1}, {15, 7}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3821 #define FMT_SF_N_RM_IMM6_RN_RD		\
   3822 	{{31, 1}, {22, 1}, {16, 5}, {10, 6}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3823 #define FMT_SF_N_RM_IMMS_RN_RD		\
   3824 	{{31, 1}, {22, 1}, {16, 5}, {10, 6}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3825 #define FMT_SF_HW_IMM16_RD		\
   3826 	{{31, 1}, {21, 2}, { 5,16}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3827 #define FMT_SF_N_IMMR_IMMS_RN_RD	\
   3828 	{{31, 1}, {22, 1}, {16, 6}, {10, 6}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3829 #define FMT_SF_SHIFT_RM_IMM6_RN_RD	\
   3830 	{{31, 1}, {22, 2}, {16, 5}, {10, 6}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3831 #define FMT_SF_SHIFT_IMM12_RN_RD	\
   3832 	{{31, 1}, {22, 2}, {10,12}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3833 #define FMT_SF_IMM19_RT			\
   3834 	{{31, 1}, { 5,19}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3835 #define FMT_B5_B40_IMM14_RT		\
   3836 	{{31, 1}, {19, 5}, { 5,14}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}
   3837 #define FMT_OPC_L_IMM7_RT2_RN_RT	\
   3838 	{{30, 2}, {22, 1}, {15, 7}, {10, 5}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}}
   3839 #define FMT_SIZE_OPC_IMM9_RN_RT		\
   3840 	{{30, 2}, {22, 2}, {12, 9}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3841 #define FMT_SIZE_OPC_RM_OPT_S_RN_RT	\
   3842 	{{30, 2}, {22, 2}, {16, 5}, {13, 3}, {12, 1}, { 5, 5}, { 0, 5}, { 0, 0}}
   3843 #define FMT_SIZE_OPC_IMM12_RN_RT	\
   3844 	{{30, 2}, {22, 2}, {10,12}, { 5, 5}, { 0, 5}, { 0, 0}, { 0, 0}, { 0, 0}}
   3845 
   3846 static const struct insn_info insn_tables[] = {
   3847  /* mask,      pattern,    opcode format,               opfunc             */
   3848  /* ---------  ----------  ---------------------------  ------------------ */
   3849  { 0xffffffff, 0xd6bf03e0, FMT_NOARG,                   op_drps },
   3850  { 0xffffffff, 0xd69f03e0, FMT_NOARG,                   op_eret },
   3851  { 0xffffffff, 0xd50320ff, FMT_NOARG,                   op_xpaclri },
   3852  { 0xffffffe0, 0xdac143e0, FMT_RD,                      op_xpaci },
   3853  { 0xffffffe0, 0xdac147e0, FMT_RD,                      op_xpacd },
   3854  { 0xfffffc1f, 0xd63f0000, FMT_RN,                      op_blr },
   3855  { 0xfffffc1f, 0xd61f0000, FMT_RN,                      op_br },
   3856  { 0xfffffc1f, 0xd65f0000, FMT_RN,                      op_ret },
   3857  { 0xfffffc00, 0x08dffc00, FMT_RN_RT,                   op_ldarb },
   3858  { 0xfffffc00, 0x48dffc00, FMT_RN_RT,                   op_ldarh },
   3859  { 0xfffffc00, 0x085ffc00, FMT_RN_RT,                   op_ldaxrb },
   3860  { 0xfffffc00, 0x485ffc00, FMT_RN_RT,                   op_ldaxrh },
   3861  { 0xfffffc00, 0x085f7c00, FMT_RN_RT,                   op_ldxrb },
   3862  { 0xfffffc00, 0x485f7c00, FMT_RN_RT,                   op_ldxrh },
   3863  { 0xfffffc00, 0x089ffc00, FMT_RN_RT,                   op_stlrb },
   3864  { 0xfffffc00, 0x489ffc00, FMT_RN_RT,                   op_stlrh },
   3865  { 0xfffffbff, 0xd69f0bff, FMT_M,                       op_eretaa },
   3866  { 0xfffffbff, 0xd65f0bff, FMT_M,                       op_retaa },
   3867  { 0xfffff0ff, 0xd503305f, FMT_CRM,                     op_clrex },
   3868  { 0xfffff0ff, 0xd50330bf, FMT_CRM,                     op_dmb },
   3869  { 0xfffff0ff, 0xd503309f, FMT_CRM,                     op_dsb },
   3870  { 0xfffff0ff, 0xd50330df, FMT_CRM,                     op_isb },
   3871  { 0xfffff01f, 0xd503201f, FMT_CRM_OP2,                 op_hint },
   3872  { 0xfffff000, 0xcec08000, FMT_OP2_RN_RD,               op_simd_sha512_reg2 },
   3873  { 0xffffd800, 0xdac10800, FMT_Z_M_RN_RD,               op_pacda },
   3874  { 0xffffd800, 0xdac10000, FMT_Z_M_RN_RD,               op_pacia },
   3875  { 0xffffcc00, 0x4e284800, FMT_M_D_RN_RD,               op_simd_aes },
   3876  { 0xffff8c00, 0x5e280800, FMT_OP3_RN_RD,               op_simd_sha_reg2 },
   3877  { 0xfff8f01f, 0xd500401f, FMT_OP1_CRM_OP2,             op_msr_imm },
   3878  { 0xfff80000, 0xd5080000, FMT_OP1_CRN_CRM_OP2_RT,      op_sys },
   3879  { 0xfff80000, 0xd5280000, FMT_OP1_CRN_CRM_OP2_RT,      op_sysl },
   3880  { 0xffe0fc00, 0x9b407c00, FMT_RM_RN_RD,                op_smulh },
   3881  { 0xffe0fc00, 0x0800fc00, FMT_RS_RN_RT,                op_stlxrb },
   3882  { 0xffe0fc00, 0x4800fc00, FMT_RS_RN_RT,                op_stlxrh },
   3883  { 0xffe0fc00, 0x08007c00, FMT_RS_RN_RT,                op_stxrb },
   3884  { 0xffe0fc00, 0x48007c00, FMT_RS_RN_RT,                op_stxrh },
   3885  { 0xffe0fc00, 0x9bc07c00, FMT_RM_RN_RD,                op_umulh },
   3886  { 0xffe0fc00, 0x9ac03000, FMT_RM_RN_RD,                op_pacga },
   3887  { 0xffe0f000, 0xce608000, FMT_RM_OP2_RN_RD,            op_simd_sha512_reg3 },
   3888  { 0xffe08c00, 0x5e000000, FMT_RM_OP_RN_RD,             op_simd_sha_reg3 },
   3889  { 0xffe08000, 0x9b208000, FMT_RM_RA_RN_RD,             op_smsubl },
   3890  { 0xffe08000, 0x9ba08000, FMT_RM_RA_RN_RD,             op_umsubl },
   3891  { 0xffe08000, 0x9b200000, FMT_RM_RA_RN_RD,             op_smaddl },
   3892  { 0xffe08000, 0x9ba00000, FMT_RM_RA_RN_RD,             op_umaddl },
   3893  { 0xffe00c00, 0x38400400, FMT_IMM9_RN_RT,              op_ldrb_immpostidx },
   3894  { 0xffe00c00, 0x38400c00, FMT_IMM9_RN_RT,              op_ldrb_immpreidx },
   3895  { 0xffe00c00, 0x38600800, FMT_RM_OPT_SHIFT_RN_RT,      op_ldrb_reg },
   3896  { 0xffe00c00, 0x78400400, FMT_IMM9_RN_RT,              op_ldrh_immpostidx },
   3897  { 0xffe00c00, 0x78400c00, FMT_IMM9_RN_RT,              op_ldrh_immpreidx },
   3898  { 0xffe00c00, 0x78600800, FMT_RM_OPT_SHIFT_RN_RT,      op_ldrh_reg },
   3899  { 0xffe00c00, 0xb8800400, FMT_IMM9_RN_RT,              op_ldrsw_immpostidx },
   3900  { 0xffe00c00, 0xb8800c00, FMT_IMM9_RN_RT,              op_ldrsw_immpreidx },
   3901  { 0xffe00c00, 0xb8a00800, FMT_RM_OPT_SHIFT_RN_RT,      op_ldrsw_reg },
   3902  { 0xffe00c00, 0x38400800, FMT_IMM9_RN_RT,              op_ldtrb },
   3903  { 0xffe00c00, 0x78400800, FMT_IMM9_RN_RT,              op_ldtrh },
   3904  { 0xffe00c00, 0xb8800800, FMT_IMM9_RN_RT,              op_ldtrsw },
   3905  { 0xffe00c00, 0x38400000, FMT_IMM9_RN_RT,              op_ldurb },
   3906  { 0xffe00c00, 0x78400000, FMT_IMM9_RN_RT,              op_ldurh },
   3907  { 0xffe00c00, 0xb8800000, FMT_IMM9_RN_RT,              op_ldursw },
   3908  { 0xffe00c00, 0xf8a00800, FMT_RM_OPT_SHIFT_RN_RT,      op_prfm_reg },
   3909  { 0xffe00c00, 0xf8800000, FMT_IMM9_RN_RT,              op_prfum },
   3910  { 0xffe00c00, 0x38000400, FMT_IMM9_RN_RT,              op_strb_immpostidx },
   3911  { 0xffe00c00, 0x38000c00, FMT_IMM9_RN_RT,              op_strb_immpreidx },
   3912  { 0xffe00c00, 0x38200800, FMT_RM_OPT_SHIFT_RN_RT,      op_strb_reg },
   3913  { 0xffe00c00, 0x78000400, FMT_IMM9_RN_RT,              op_strh_immpostidx },
   3914  { 0xffe00c00, 0x78000c00, FMT_IMM9_RN_RT,              op_strh_immpreidx },
   3915  { 0xffe00c00, 0x78200800, FMT_RM_OPT_SHIFT_RN_RT,      op_strh_reg },
   3916  { 0xffe00c00, 0x38000800, FMT_IMM9_RN_RT,              op_sttrb },
   3917  { 0xffe00c00, 0x78000800, FMT_IMM9_RN_RT,              op_sttrh },
   3918  { 0xffe00c00, 0x38000000, FMT_IMM9_RN_RT,              op_sturb },
   3919  { 0xffe00c00, 0x78000000, FMT_IMM9_RN_RT,              op_sturh },
   3920  { 0xffe0001f, 0xd4200000, FMT_IMM16,                   op_brk },
   3921  { 0xffe0001f, 0xd4400000, FMT_IMM16,                   op_hlt },
   3922  { 0xffe0001f, 0xd4000002, FMT_IMM16,                   op_hvc },
   3923  { 0xffe0001f, 0xd4000003, FMT_IMM16,                   op_smc },
   3924  { 0xffe0001f, 0xd4000001, FMT_IMM16,                   op_svc },
   3925  { 0xffe0001c, 0xd4a00000, FMT_IMM16_LL,                op_dcps },
   3926  { 0xffe00000, 0xd5200000, FMT_OP0_OP1_CRN_CRM_OP2_RT,  op_mrs },
   3927  { 0xffe00000, 0xd5000000, FMT_OP0_OP1_CRN_CRM_OP2_RT,  op_msr },
   3928  { 0xffc00000, 0x68c00000, FMT_IMM7_RT2_RN_RT,          op_ldpsw_postidx },
   3929  { 0xffc00000, 0x69c00000, FMT_IMM7_RT2_RN_RT,          op_ldpsw_preidx },
   3930  { 0xffc00000, 0x69400000, FMT_IMM7_RT2_RN_RT,          op_ldpsw_signed },
   3931  { 0xffc00000, 0x39400000, FMT_IMM12_RN_RT,             op_ldrb_immunsign },
   3932  { 0xffc00000, 0x79400000, FMT_IMM12_RN_RT,             op_ldrh_immunsign },
   3933  { 0xffc00000, 0xb9800000, FMT_IMM12_RN_RT,             op_ldrsw_immunsign },
   3934  { 0xffc00000, 0xf9800000, FMT_IMM12_RN_RT,             op_prfm_imm },
   3935  { 0xffc00000, 0x39000000, FMT_IMM12_RN_RT,             op_strb_immunsign },
   3936  { 0xffc00000, 0x79000000, FMT_IMM12_RN_RT,             op_strh_immunsign },
   3937  { 0xffa00c00, 0x38800400, FMT_OPC_IMM9_RN_RT,          op_ldrsb_immpostidx },
   3938  { 0xffa00c00, 0x38800c00, FMT_OPC_IMM9_RN_RT,          op_ldrsb_immpreidx },
   3939  { 0xffa00c00, 0x38a00800, FMT_OPC_RM_OPT_SHIFT_RN_RT,  op_ldrsb_reg },
   3940  { 0xffa00c00, 0x78800400, FMT_OPC_IMM9_RN_RT,          op_ldrsh_immpostidx },
   3941  { 0xffa00c00, 0x78800c00, FMT_OPC_IMM9_RN_RT,          op_ldrsh_immpreidx },
   3942  { 0xffa00c00, 0x78a00800, FMT_OPC_RM_OPT_SHIFT_RN_RT,  op_ldrsh_reg },
   3943  { 0xffa00c00, 0x38800800, FMT_OPC_IMM9_RN_RT,          op_ldtrsb },
   3944  { 0xffa00c00, 0x78800800, FMT_OPC_IMM9_RN_RT,          op_ldtrsh },
   3945  { 0xffa00c00, 0x38800000, FMT_OPC_IMM9_RN_RT,          op_ldursb },
   3946  { 0xffa00c00, 0x78800000, FMT_OPC_IMM9_RN_RT,          op_ldursh },
   3947  { 0xff800000, 0x39800000, FMT_OPC_IMM12_RN_RT,         op_ldrsb_immunsign },
   3948  { 0xff800000, 0x79800000, FMT_OPC_IMM12_RN_RT,         op_ldrsh_immunsign },
   3949  { 0xff000010, 0x54000000, FMT_IMM19_COND,              op_b_cond },
   3950  { 0xff000000, 0x98000000, FMT_IMM19_RT,                op_ldrsw_literal },
   3951  { 0xff000000, 0xd8000000, FMT_IMM19_RT,                op_prfm_literal },
   3952  { 0xfefff800, 0xd63f0800, FMT_Z_M_RN_RM,               op_blraa },
   3953  { 0xfefff800, 0xd61f0800, FMT_Z_M_RN_RM,               op_braa },
   3954  { 0xfc000000, 0x14000000, FMT_IMM26,                   op_b },
   3955  { 0xfc000000, 0x94000000, FMT_IMM26,                   op_bl },
   3956  { 0xbffffc00, 0x88dffc00, FMT_SIZE_RN_RT,              op_ldar },
   3957  { 0xbffffc00, 0x885ffc00, FMT_SIZE_RN_RT,              op_ldaxr },
   3958  { 0xbffffc00, 0x885f7c00, FMT_SIZE_RN_RT,              op_ldxr },
   3959  { 0xbffffc00, 0x889ffc00, FMT_SIZE_RN_RT,              op_stlr },
   3960  { 0xbfff8000, 0x887f8000, FMT_SIZE_RT2_RN_RT,          op_ldaxp },
   3961  { 0xbfff8000, 0x887f0000, FMT_SIZE_RT2_RN_RT,          op_ldxp },
   3962  { 0xbfe0fc00, 0x8800fc00, FMT_SIZE_RS_RN_RT,           op_stlxr },
   3963  { 0xbfe0fc00, 0x88007c00, FMT_SIZE_RS_RN_RT,           op_stxr },
   3964  { 0xbfe08000, 0x88208000, FMT_SIZE_RS_RT2_RN_RT,       op_stlxp },
   3965  { 0xbfe08000, 0x88200000, FMT_SIZE_RS_RT2_RN_RT,       op_stxp },
   3966  { 0xbfe00c00, 0xb8400400, FMT_SIZE_IMM9_RN_RT,         op_ldr_immpostidx },
   3967  { 0xbfe00c00, 0xb8400c00, FMT_SIZE_IMM9_RN_RT,         op_ldr_immpreidx },
   3968  { 0xbfe00c00, 0xb8600800, FMT_SIZE_RM_OPT_SHIFT_RN_RT, op_ldr_reg },
   3969  { 0xbfe00c00, 0xb8400800, FMT_SIZE_IMM9_RN_RT,         op_ldtr },
   3970  { 0xbfe00c00, 0xb8400000, FMT_SIZE_IMM9_RN_RT,         op_ldur },
   3971  { 0xbfe00c00, 0xb8000400, FMT_SIZE_IMM9_RN_RT,         op_str_immpostidx },
   3972  { 0xbfe00c00, 0xb8000c00, FMT_SIZE_IMM9_RN_RT,         op_str_immpreidx },
   3973  { 0xbfe00c00, 0xb8200800, FMT_SIZE_RM_OPT_SHIFT_RN_RT, op_str_reg },
   3974  { 0xbfe00c00, 0xb8000800, FMT_SIZE_IMM9_RN_RT,         op_sttr },
   3975  { 0xbfe00c00, 0xb8000000, FMT_SIZE_IMM9_RN_RT,         op_stur },
   3976  { 0xbfc00000, 0xb9400000, FMT_SIZE_IMM12_RN_RT,        op_ldr_immunsign },
   3977  { 0xbfc00000, 0xb9000000, FMT_SIZE_IMM12_RN_RT,        op_str_immunsign },
   3978  { 0xbf20fc00, 0x0e20e000, FMT_Q_SIZE_RM_RN_RD,         op_simd_pmull },
   3979  { 0xbf000000, 0x18000000, FMT_SIZE_IMM19_RT,           op_ldr_literal },
   3980  { 0x9f000000, 0x10000000, FMT_IMMLO_IMMHI_RD,          op_adr },
   3981  { 0x9f000000, 0x90000000, FMT_IMMLO_IMMHI_RD,          op_adrp },
   3982  { 0x7ffffc00, 0x5ac01400, FMT_SF_RN_RD,                op_cls },
   3983  { 0x7ffffc00, 0x5ac01000, FMT_SF_RN_RD,                op_clz },
   3984  { 0x7ffff000, 0x5ac00000, FMT_SF_OPC_RN_RD,            op_rev },
   3985  { 0x7fe0fc00, 0x5a000000, FMT_SF_RM_RN_RD,             op_sbc },
   3986  { 0x7fe0fc00, 0x7a000000, FMT_SF_RM_RN_RD,             op_sbcs },
   3987  { 0x7fe0fc00, 0x1a000000, FMT_SF_RM_RN_RD,             op_adc },
   3988  { 0x7fe0fc00, 0x3a000000, FMT_SF_RM_RN_RD,             op_adcs },
   3989  { 0x7fe0fc00, 0x1ac02800, FMT_SF_RM_RN_RD,             op_asr_reg },
   3990  { 0x7fe0fc00, 0x1ac02000, FMT_SF_RM_RN_RD,             op_lsl_reg },
   3991  { 0x7fe0fc00, 0x1ac02400, FMT_SF_RM_RN_RD,             op_lsr_reg },
   3992  { 0x7fe0fc00, 0x1ac02c00, FMT_SF_RM_RN_RD,             op_ror_reg },
   3993  { 0x7fe0fc00, 0x1ac00c00, FMT_SF_RM_RN_RD,             op_sdiv },
   3994  { 0x7fe0fc00, 0x1ac00800, FMT_SF_RM_RN_RD,             op_udiv },
   3995  { 0x7fe0f000, 0x1ac04000, FMT_SF_RM_SZ_RN_RD,          op_crc32 },
   3996  { 0x7fe0f000, 0x1ac05000, FMT_SF_RM_SZ_RN_RD,          op_crc32c },
   3997  { 0x7fe08000, 0x1b008000, FMT_SF_RM_RA_RN_RD,          op_msub },
   3998  { 0x7fe08000, 0x1b000000, FMT_SF_RM_RA_RN_RD,          op_madd },
   3999  { 0x7fe00c10, 0x3a400800, FMT_SF_IMM5_COND_RN_NZCV,    op_ccmn_imm },
   4000  { 0x7fe00c10, 0x3a400000, FMT_SF_RM_COND_RN_NZCV,      op_ccmn_reg },
   4001  { 0x7fe00c10, 0x7a400800, FMT_SF_IMM5_COND_RN_NZCV,    op_ccmp_imm },
   4002  { 0x7fe00c10, 0x7a400000, FMT_SF_RM_COND_RN_NZCV,      op_ccmp_reg },
   4003  { 0x7fe00c00, 0x5a800000, FMT_SF_RM_COND_RN_RD,        op_csinv },
   4004  { 0x7fe00c00, 0x5a800400, FMT_SF_RM_COND_RN_RD,        op_csneg },
   4005  { 0x7fe00c00, 0x1a800400, FMT_SF_RM_COND_RN_RD,        op_cinc },
   4006  { 0x7fe00c00, 0x1a800000, FMT_SF_RM_COND_RN_RD,        op_csel },
   4007  { 0x7fe00000, 0x6b200000, FMT_SF_RM_OPT_IMM3_RN_RD,    op_subs_extreg },
   4008  { 0x7fe00000, 0x0b200000, FMT_SF_RM_OPT_IMM3_RN_RD,    op_add_extreg },
   4009  { 0x7fe00000, 0x2b200000, FMT_SF_RM_OP_IMM3_RN_RD,     op_adds_extreg },
   4010  { 0x7fe00000, 0x4b200000, FMT_SF_RM_OPT_IMM3_RN_RD,    op_sub_extreg },
   4011  { 0x7fc00000, 0x28400000, FMT_SF_IMM7_RT2_RN_RT,       op_ldnp },
   4012  { 0x7fc00000, 0x28c00000, FMT_SF_IMM7_RT2_RN_RT,       op_ldp_postidx },
   4013  { 0x7fc00000, 0x29c00000, FMT_SF_IMM7_RT2_RN_RT,       op_ldp_preidx },
   4014  { 0x7fc00000, 0x29400000, FMT_SF_IMM7_RT2_RN_RT,       op_ldp_signed },
   4015  { 0x7fc00000, 0x28000000, FMT_SF_IMM7_RT2_RN_RT,       op_stnp },
   4016  { 0x7fc00000, 0x28800000, FMT_SF_IMM7_RT2_RN_RT,       op_stp_postidx },
   4017  { 0x7fc00000, 0x29800000, FMT_SF_IMM7_RT2_RN_RT,       op_stp_preidx },
   4018  { 0x7fc00000, 0x29000000, FMT_SF_IMM7_RT2_RN_RT,       op_stp_signed },
   4019  { 0x7fa00000, 0x13800000, FMT_SF_N_RM_IMM6_RN_RD,      op_ror_imm },
   4020  { 0x7f800000, 0x12800000, FMT_SF_HW_IMM16_RD,          op_movn },
   4021  { 0x7f800000, 0x52800000, FMT_SF_HW_IMM16_RD,          op_movz },
   4022  { 0x7f800000, 0x32000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_orr_imm },
   4023  { 0x7f800000, 0x13000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_sbfm },
   4024  { 0x7f800000, 0x53000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_ubfm },
   4025  { 0x7f800000, 0x12000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_and_imm },
   4026  { 0x7f800000, 0x72000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_ands_imm },
   4027  { 0x7f800000, 0x33000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_bfi },
   4028  { 0x7f800000, 0x52000000, FMT_SF_N_IMMR_IMMS_RN_RD,    op_eor_imm },
   4029  { 0x7f800000, 0x72800000, FMT_SF_HW_IMM16_RD,          op_movk },
   4030  { 0x7f200000, 0x2a200000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_orn },
   4031  { 0x7f200000, 0x2a000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_orr_reg },
   4032  { 0x7f200000, 0x4b000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_sub_shiftreg },
   4033  { 0x7f200000, 0x6b000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_subs_shiftreg },
   4034  { 0x7f200000, 0x0b000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_add_shiftreg },
   4035  { 0x7f200000, 0x2b000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_adds_shiftreg },
   4036  { 0x7f200000, 0x0a000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_and_shiftreg },
   4037  { 0x7f200000, 0x6a000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_ands_shiftreg },
   4038  { 0x7f200000, 0x0a200000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_bic_shiftreg },
   4039  { 0x7f200000, 0x6a200000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_bics_shiftreg },
   4040  { 0x7f200000, 0x4a200000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_eon_shiftreg },
   4041  { 0x7f200000, 0x4a000000, FMT_SF_SHIFT_RM_IMM6_RN_RD,  op_eor_shiftreg },
   4042  { 0x7f000000, 0x71000000, FMT_SF_SHIFT_IMM12_RN_RD,    op_subs_imm },
   4043  { 0x7f000000, 0x11000000, FMT_SF_SHIFT_IMM12_RN_RD,    op_add_imm },
   4044  { 0x7f000000, 0x31000000, FMT_SF_SHIFT_IMM12_RN_RD,    op_adds_imm },
   4045  { 0x7f000000, 0x35000000, FMT_SF_IMM19_RT,             op_cbnz },
   4046  { 0x7f000000, 0x34000000, FMT_SF_IMM19_RT,             op_cbz },
   4047  { 0x7f000000, 0x51000000, FMT_SF_SHIFT_IMM12_RN_RD,    op_sub_imm },
   4048  { 0x7f000000, 0x37000000, FMT_B5_B40_IMM14_RT,         op_tbnz },
   4049  { 0x7f000000, 0x36000000, FMT_B5_B40_IMM14_RT,         op_tbz },
   4050  { 0x3f800000, 0x2c000000, FMT_OPC_L_IMM7_RT2_RN_RT,    op_simd_ldstnp },
   4051  { 0x3f800000, 0x2c800000, FMT_OPC_L_IMM7_RT2_RN_RT, op_simd_ldstp_postidx },
   4052  { 0x3f800000, 0x2d800000, FMT_OPC_L_IMM7_RT2_RN_RT,    op_simd_ldstp_preidx },
   4053  { 0x3f800000, 0x2d000000, FMT_OPC_L_IMM7_RT2_RN_RT,    op_simd_ldstp_signed },
   4054  { 0x3f200c00, 0x3c000400, FMT_SIZE_OPC_IMM9_RN_RT, op_simd_ldstr_immpostidx },
   4055  { 0x3f200c00, 0x3c000c00, FMT_SIZE_OPC_IMM9_RN_RT, op_simd_ldstr_immpreidx },
   4056  { 0x3f200c00, 0x3c200800, FMT_SIZE_OPC_RM_OPT_S_RN_RT, op_simd_ldstr_reg },
   4057  { 0x3f000000, 0x3d000000, FMT_SIZE_OPC_IMM12_RN_RT, op_simd_ldstr_immunsign },
   4058  { 0x00000000, 0x00000000, FMT_NOARG,                   op_undefined }
   4059 };
   4060 
   4061 #define WIDTHMASK(w)	(0xffffffff >> (32 - (w)))
   4062 
   4063 void
   4064 disasm_insn(const disasm_interface_t *di, uintptr_t loc, uint32_t insn)
   4065 {
   4066 	uint64_t args[INSN_MAXARG];
   4067 	unsigned int i, j;
   4068 
   4069 	for (i = 0; i < __arraycount(insn_tables); i++) {
   4070 		if ((insn & insn_tables[i].mask) != insn_tables[i].pattern)
   4071 			continue;
   4072 
   4073 		/* extract operands */
   4074 		for (j = 0; j < INSN_MAXARG; j++) {
   4075 			if (insn_tables[i].bitinfo[j].width == 0)
   4076 				break;
   4077 			args[j] = (insn >> insn_tables[i].bitinfo[j].pos) &
   4078 			    WIDTHMASK(insn_tables[i].bitinfo[j].width);
   4079 		}
   4080 		insn_tables[i].opfunc(di, loc, insn,
   4081 		    args[0], args[1], args[2], args[3],
   4082 		    args[4], args[5], args[6], args[7]);
   4083 		break;
   4084 	}
   4085 }
   4086 
   4087 uintptr_t
   4088 disasm(const disasm_interface_t *di, uintptr_t loc)
   4089 {
   4090 	uint32_t insn;
   4091 
   4092 	insn = le32toh(di->di_readword(loc));
   4093 	disasm_insn(di, loc, insn);
   4094 
   4095 	/* return next address */
   4096 	return loc + sizeof(insn);
   4097 }
   4098