xref: /dflybsd-src/contrib/binutils-2.27/include/opcode/aarch64.h (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
1*a9fa9459Szrj /* AArch64 assembler/disassembler support.
2*a9fa9459Szrj 
3*a9fa9459Szrj    Copyright (C) 2009-2016 Free Software Foundation, Inc.
4*a9fa9459Szrj    Contributed by ARM Ltd.
5*a9fa9459Szrj 
6*a9fa9459Szrj    This file is part of GNU Binutils.
7*a9fa9459Szrj 
8*a9fa9459Szrj    This program is free software; you can redistribute it and/or modify
9*a9fa9459Szrj    it under the terms of the GNU General Public License as published by
10*a9fa9459Szrj    the Free Software Foundation; either version 3 of the license, or
11*a9fa9459Szrj    (at your option) any later version.
12*a9fa9459Szrj 
13*a9fa9459Szrj    This program is distributed in the hope that it will be useful,
14*a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*a9fa9459Szrj    GNU General Public License for more details.
17*a9fa9459Szrj 
18*a9fa9459Szrj    You should have received a copy of the GNU General Public License
19*a9fa9459Szrj    along with this program; see the file COPYING3. If not,
20*a9fa9459Szrj    see <http://www.gnu.org/licenses/>.  */
21*a9fa9459Szrj 
22*a9fa9459Szrj #ifndef OPCODE_AARCH64_H
23*a9fa9459Szrj #define OPCODE_AARCH64_H
24*a9fa9459Szrj 
25*a9fa9459Szrj #include "bfd.h"
26*a9fa9459Szrj #include "bfd_stdint.h"
27*a9fa9459Szrj #include <assert.h>
28*a9fa9459Szrj #include <stdlib.h>
29*a9fa9459Szrj 
30*a9fa9459Szrj #ifdef __cplusplus
31*a9fa9459Szrj extern "C" {
32*a9fa9459Szrj #endif
33*a9fa9459Szrj 
34*a9fa9459Szrj /* The offset for pc-relative addressing is currently defined to be 0.  */
35*a9fa9459Szrj #define AARCH64_PCREL_OFFSET		0
36*a9fa9459Szrj 
37*a9fa9459Szrj typedef uint32_t aarch64_insn;
38*a9fa9459Szrj 
39*a9fa9459Szrj /* The following bitmasks control CPU features.  */
40*a9fa9459Szrj #define AARCH64_FEATURE_V8	0x00000001	/* All processors.  */
41*a9fa9459Szrj #define AARCH64_FEATURE_V8_2	0x00000020      /* ARMv8.2 processors.  */
42*a9fa9459Szrj #define AARCH64_FEATURE_CRYPTO	0x00010000	/* Crypto instructions.  */
43*a9fa9459Szrj #define AARCH64_FEATURE_FP	0x00020000	/* FP instructions.  */
44*a9fa9459Szrj #define AARCH64_FEATURE_SIMD	0x00040000	/* SIMD instructions.  */
45*a9fa9459Szrj #define AARCH64_FEATURE_CRC	0x00080000	/* CRC instructions.  */
46*a9fa9459Szrj #define AARCH64_FEATURE_LSE	0x00100000	/* LSE instructions.  */
47*a9fa9459Szrj #define AARCH64_FEATURE_PAN	0x00200000	/* PAN instructions.  */
48*a9fa9459Szrj #define AARCH64_FEATURE_LOR	0x00400000	/* LOR instructions.  */
49*a9fa9459Szrj #define AARCH64_FEATURE_RDMA	0x00800000	/* v8.1 SIMD instructions.  */
50*a9fa9459Szrj #define AARCH64_FEATURE_V8_1	0x01000000	/* v8.1 features.  */
51*a9fa9459Szrj #define AARCH64_FEATURE_F16	0x02000000	/* v8.2 FP16 instructions.  */
52*a9fa9459Szrj #define AARCH64_FEATURE_RAS	0x04000000	/* RAS Extensions.  */
53*a9fa9459Szrj #define AARCH64_FEATURE_PROFILE	0x08000000	/* Statistical Profiling.  */
54*a9fa9459Szrj 
55*a9fa9459Szrj /* Architectures are the sum of the base and extensions.  */
56*a9fa9459Szrj #define AARCH64_ARCH_V8		AARCH64_FEATURE (AARCH64_FEATURE_V8, \
57*a9fa9459Szrj 						 AARCH64_FEATURE_FP  \
58*a9fa9459Szrj 						 | AARCH64_FEATURE_SIMD)
59*a9fa9459Szrj #define AARCH64_ARCH_V8_1	AARCH64_FEATURE (AARCH64_FEATURE_V8, \
60*a9fa9459Szrj 						 AARCH64_FEATURE_FP  \
61*a9fa9459Szrj 						 | AARCH64_FEATURE_SIMD	\
62*a9fa9459Szrj 						 | AARCH64_FEATURE_CRC	\
63*a9fa9459Szrj 						 | AARCH64_FEATURE_V8_1 \
64*a9fa9459Szrj 						 | AARCH64_FEATURE_LSE	\
65*a9fa9459Szrj 						 | AARCH64_FEATURE_PAN	\
66*a9fa9459Szrj 						 | AARCH64_FEATURE_LOR	\
67*a9fa9459Szrj 						 | AARCH64_FEATURE_RDMA)
68*a9fa9459Szrj #define AARCH64_ARCH_V8_2	AARCH64_FEATURE (AARCH64_FEATURE_V8,	\
69*a9fa9459Szrj 						 AARCH64_FEATURE_V8_2	\
70*a9fa9459Szrj 						 | AARCH64_FEATURE_F16	\
71*a9fa9459Szrj 						 | AARCH64_FEATURE_RAS	\
72*a9fa9459Szrj 						 | AARCH64_FEATURE_FP	\
73*a9fa9459Szrj 						 | AARCH64_FEATURE_SIMD	\
74*a9fa9459Szrj 						 | AARCH64_FEATURE_CRC	\
75*a9fa9459Szrj 						 | AARCH64_FEATURE_V8_1 \
76*a9fa9459Szrj 						 | AARCH64_FEATURE_LSE	\
77*a9fa9459Szrj 						 | AARCH64_FEATURE_PAN	\
78*a9fa9459Szrj 						 | AARCH64_FEATURE_LOR	\
79*a9fa9459Szrj 						 | AARCH64_FEATURE_RDMA)
80*a9fa9459Szrj 
81*a9fa9459Szrj #define AARCH64_ARCH_NONE	AARCH64_FEATURE (0, 0)
82*a9fa9459Szrj #define AARCH64_ANY		AARCH64_FEATURE (-1, 0)	/* Any basic core.  */
83*a9fa9459Szrj 
84*a9fa9459Szrj /* CPU-specific features.  */
85*a9fa9459Szrj typedef unsigned long aarch64_feature_set;
86*a9fa9459Szrj 
87*a9fa9459Szrj #define AARCH64_CPU_HAS_FEATURE(CPU,FEAT)	\
88*a9fa9459Szrj   (((CPU) & (FEAT)) != 0)
89*a9fa9459Szrj 
90*a9fa9459Szrj #define AARCH64_MERGE_FEATURE_SETS(TARG,F1,F2)	\
91*a9fa9459Szrj   do						\
92*a9fa9459Szrj     {						\
93*a9fa9459Szrj       (TARG) = (F1) | (F2);			\
94*a9fa9459Szrj     }						\
95*a9fa9459Szrj   while (0)
96*a9fa9459Szrj 
97*a9fa9459Szrj #define AARCH64_CLEAR_FEATURE(TARG,F1,F2)	\
98*a9fa9459Szrj   do						\
99*a9fa9459Szrj     { 						\
100*a9fa9459Szrj       (TARG) = (F1) &~ (F2);			\
101*a9fa9459Szrj     }						\
102*a9fa9459Szrj   while (0)
103*a9fa9459Szrj 
104*a9fa9459Szrj #define AARCH64_FEATURE(core,coproc) ((core) | (coproc))
105*a9fa9459Szrj 
106*a9fa9459Szrj #define AARCH64_OPCODE_HAS_FEATURE(OPC,FEAT)	\
107*a9fa9459Szrj   (((OPC) & (FEAT)) != 0)
108*a9fa9459Szrj 
109*a9fa9459Szrj enum aarch64_operand_class
110*a9fa9459Szrj {
111*a9fa9459Szrj   AARCH64_OPND_CLASS_NIL,
112*a9fa9459Szrj   AARCH64_OPND_CLASS_INT_REG,
113*a9fa9459Szrj   AARCH64_OPND_CLASS_MODIFIED_REG,
114*a9fa9459Szrj   AARCH64_OPND_CLASS_FP_REG,
115*a9fa9459Szrj   AARCH64_OPND_CLASS_SIMD_REG,
116*a9fa9459Szrj   AARCH64_OPND_CLASS_SIMD_ELEMENT,
117*a9fa9459Szrj   AARCH64_OPND_CLASS_SISD_REG,
118*a9fa9459Szrj   AARCH64_OPND_CLASS_SIMD_REGLIST,
119*a9fa9459Szrj   AARCH64_OPND_CLASS_CP_REG,
120*a9fa9459Szrj   AARCH64_OPND_CLASS_ADDRESS,
121*a9fa9459Szrj   AARCH64_OPND_CLASS_IMMEDIATE,
122*a9fa9459Szrj   AARCH64_OPND_CLASS_SYSTEM,
123*a9fa9459Szrj   AARCH64_OPND_CLASS_COND,
124*a9fa9459Szrj };
125*a9fa9459Szrj 
126*a9fa9459Szrj /* Operand code that helps both parsing and coding.
127*a9fa9459Szrj    Keep AARCH64_OPERANDS synced.  */
128*a9fa9459Szrj 
129*a9fa9459Szrj enum aarch64_opnd
130*a9fa9459Szrj {
131*a9fa9459Szrj   AARCH64_OPND_NIL,	/* no operand---MUST BE FIRST!*/
132*a9fa9459Szrj 
133*a9fa9459Szrj   AARCH64_OPND_Rd,	/* Integer register as destination.  */
134*a9fa9459Szrj   AARCH64_OPND_Rn,	/* Integer register as source.  */
135*a9fa9459Szrj   AARCH64_OPND_Rm,	/* Integer register as source.  */
136*a9fa9459Szrj   AARCH64_OPND_Rt,	/* Integer register used in ld/st instructions.  */
137*a9fa9459Szrj   AARCH64_OPND_Rt2,	/* Integer register used in ld/st pair instructions.  */
138*a9fa9459Szrj   AARCH64_OPND_Rs,	/* Integer register used in ld/st exclusive.  */
139*a9fa9459Szrj   AARCH64_OPND_Ra,	/* Integer register used in ddp_3src instructions.  */
140*a9fa9459Szrj   AARCH64_OPND_Rt_SYS,	/* Integer register used in system instructions.  */
141*a9fa9459Szrj 
142*a9fa9459Szrj   AARCH64_OPND_Rd_SP,	/* Integer Rd or SP.  */
143*a9fa9459Szrj   AARCH64_OPND_Rn_SP,	/* Integer Rn or SP.  */
144*a9fa9459Szrj   AARCH64_OPND_PAIRREG,	/* Paired register operand.  */
145*a9fa9459Szrj   AARCH64_OPND_Rm_EXT,	/* Integer Rm extended.  */
146*a9fa9459Szrj   AARCH64_OPND_Rm_SFT,	/* Integer Rm shifted.  */
147*a9fa9459Szrj 
148*a9fa9459Szrj   AARCH64_OPND_Fd,	/* Floating-point Fd.  */
149*a9fa9459Szrj   AARCH64_OPND_Fn,	/* Floating-point Fn.  */
150*a9fa9459Szrj   AARCH64_OPND_Fm,	/* Floating-point Fm.  */
151*a9fa9459Szrj   AARCH64_OPND_Fa,	/* Floating-point Fa.  */
152*a9fa9459Szrj   AARCH64_OPND_Ft,	/* Floating-point Ft.  */
153*a9fa9459Szrj   AARCH64_OPND_Ft2,	/* Floating-point Ft2.  */
154*a9fa9459Szrj 
155*a9fa9459Szrj   AARCH64_OPND_Sd,	/* AdvSIMD Scalar Sd.  */
156*a9fa9459Szrj   AARCH64_OPND_Sn,	/* AdvSIMD Scalar Sn.  */
157*a9fa9459Szrj   AARCH64_OPND_Sm,	/* AdvSIMD Scalar Sm.  */
158*a9fa9459Szrj 
159*a9fa9459Szrj   AARCH64_OPND_Vd,	/* AdvSIMD Vector Vd.  */
160*a9fa9459Szrj   AARCH64_OPND_Vn,	/* AdvSIMD Vector Vn.  */
161*a9fa9459Szrj   AARCH64_OPND_Vm,	/* AdvSIMD Vector Vm.  */
162*a9fa9459Szrj   AARCH64_OPND_VdD1,	/* AdvSIMD <Vd>.D[1]; for FMOV only.  */
163*a9fa9459Szrj   AARCH64_OPND_VnD1,	/* AdvSIMD <Vn>.D[1]; for FMOV only.  */
164*a9fa9459Szrj   AARCH64_OPND_Ed,	/* AdvSIMD Vector Element Vd.  */
165*a9fa9459Szrj   AARCH64_OPND_En,	/* AdvSIMD Vector Element Vn.  */
166*a9fa9459Szrj   AARCH64_OPND_Em,	/* AdvSIMD Vector Element Vm.  */
167*a9fa9459Szrj   AARCH64_OPND_LVn,	/* AdvSIMD Vector register list used in e.g. TBL.  */
168*a9fa9459Szrj   AARCH64_OPND_LVt,	/* AdvSIMD Vector register list used in ld/st.  */
169*a9fa9459Szrj   AARCH64_OPND_LVt_AL,	/* AdvSIMD Vector register list for loading single
170*a9fa9459Szrj 			   structure to all lanes.  */
171*a9fa9459Szrj   AARCH64_OPND_LEt,	/* AdvSIMD Vector Element list.  */
172*a9fa9459Szrj 
173*a9fa9459Szrj   AARCH64_OPND_Cn,	/* Co-processor register in CRn field.  */
174*a9fa9459Szrj   AARCH64_OPND_Cm,	/* Co-processor register in CRm field.  */
175*a9fa9459Szrj 
176*a9fa9459Szrj   AARCH64_OPND_IDX,	/* AdvSIMD EXT index operand.  */
177*a9fa9459Szrj   AARCH64_OPND_IMM_VLSL,/* Immediate for shifting vector registers left.  */
178*a9fa9459Szrj   AARCH64_OPND_IMM_VLSR,/* Immediate for shifting vector registers right.  */
179*a9fa9459Szrj   AARCH64_OPND_SIMD_IMM,/* AdvSIMD modified immediate without shift.  */
180*a9fa9459Szrj   AARCH64_OPND_SIMD_IMM_SFT,	/* AdvSIMD modified immediate with shift.  */
181*a9fa9459Szrj   AARCH64_OPND_SIMD_FPIMM,/* AdvSIMD 8-bit fp immediate.  */
182*a9fa9459Szrj   AARCH64_OPND_SHLL_IMM,/* Immediate shift for AdvSIMD SHLL instruction
183*a9fa9459Szrj 			   (no encoding).  */
184*a9fa9459Szrj   AARCH64_OPND_IMM0,	/* Immediate for #0.  */
185*a9fa9459Szrj   AARCH64_OPND_FPIMM0,	/* Immediate for #0.0.  */
186*a9fa9459Szrj   AARCH64_OPND_FPIMM,	/* Floating-point Immediate.  */
187*a9fa9459Szrj   AARCH64_OPND_IMMR,	/* Immediate #<immr> in e.g. BFM.  */
188*a9fa9459Szrj   AARCH64_OPND_IMMS,	/* Immediate #<imms> in e.g. BFM.  */
189*a9fa9459Szrj   AARCH64_OPND_WIDTH,	/* Immediate #<width> in e.g. BFI.  */
190*a9fa9459Szrj   AARCH64_OPND_IMM,	/* Immediate.  */
191*a9fa9459Szrj   AARCH64_OPND_UIMM3_OP1,/* Unsigned 3-bit immediate in the op1 field.  */
192*a9fa9459Szrj   AARCH64_OPND_UIMM3_OP2,/* Unsigned 3-bit immediate in the op2 field.  */
193*a9fa9459Szrj   AARCH64_OPND_UIMM4,	/* Unsigned 4-bit immediate in the CRm field.  */
194*a9fa9459Szrj   AARCH64_OPND_UIMM7,	/* Unsigned 7-bit immediate in the CRm:op2 fields.  */
195*a9fa9459Szrj   AARCH64_OPND_BIT_NUM,	/* Immediate.  */
196*a9fa9459Szrj   AARCH64_OPND_EXCEPTION,/* imm16 operand in exception instructions.  */
197*a9fa9459Szrj   AARCH64_OPND_CCMP_IMM,/* Immediate in conditional compare instructions.  */
198*a9fa9459Szrj   AARCH64_OPND_NZCV,	/* Flag bit specifier giving an alternative value for
199*a9fa9459Szrj 			   each condition flag.  */
200*a9fa9459Szrj 
201*a9fa9459Szrj   AARCH64_OPND_LIMM,	/* Logical Immediate.  */
202*a9fa9459Szrj   AARCH64_OPND_AIMM,	/* Arithmetic immediate.  */
203*a9fa9459Szrj   AARCH64_OPND_HALF,	/* #<imm16>{, LSL #<shift>} operand in move wide.  */
204*a9fa9459Szrj   AARCH64_OPND_FBITS,	/* FP #<fbits> operand in e.g. SCVTF */
205*a9fa9459Szrj   AARCH64_OPND_IMM_MOV,	/* Immediate operand for the MOV alias.  */
206*a9fa9459Szrj 
207*a9fa9459Szrj   AARCH64_OPND_COND,	/* Standard condition as the last operand.  */
208*a9fa9459Szrj   AARCH64_OPND_COND1,	/* Same as the above, but excluding AL and NV.  */
209*a9fa9459Szrj 
210*a9fa9459Szrj   AARCH64_OPND_ADDR_ADRP,	/* Memory address for ADRP */
211*a9fa9459Szrj   AARCH64_OPND_ADDR_PCREL14,	/* 14-bit PC-relative address for e.g. TBZ.  */
212*a9fa9459Szrj   AARCH64_OPND_ADDR_PCREL19,	/* 19-bit PC-relative address for e.g. LDR.  */
213*a9fa9459Szrj   AARCH64_OPND_ADDR_PCREL21,	/* 21-bit PC-relative address for e.g. ADR.  */
214*a9fa9459Szrj   AARCH64_OPND_ADDR_PCREL26,	/* 26-bit PC-relative address for e.g. BL.  */
215*a9fa9459Szrj 
216*a9fa9459Szrj   AARCH64_OPND_ADDR_SIMPLE,	/* Address of ld/st exclusive.  */
217*a9fa9459Szrj   AARCH64_OPND_ADDR_REGOFF,	/* Address of register offset.  */
218*a9fa9459Szrj   AARCH64_OPND_ADDR_SIMM7,	/* Address of signed 7-bit immediate.  */
219*a9fa9459Szrj   AARCH64_OPND_ADDR_SIMM9,	/* Address of signed 9-bit immediate.  */
220*a9fa9459Szrj   AARCH64_OPND_ADDR_SIMM9_2,	/* Same as the above, but the immediate is
221*a9fa9459Szrj 				   negative or unaligned and there is
222*a9fa9459Szrj 				   no writeback allowed.  This operand code
223*a9fa9459Szrj 				   is only used to support the programmer-
224*a9fa9459Szrj 				   friendly feature of using LDR/STR as the
225*a9fa9459Szrj 				   the mnemonic name for LDUR/STUR instructions
226*a9fa9459Szrj 				   wherever there is no ambiguity.  */
227*a9fa9459Szrj   AARCH64_OPND_ADDR_UIMM12,	/* Address of unsigned 12-bit immediate.  */
228*a9fa9459Szrj   AARCH64_OPND_SIMD_ADDR_SIMPLE,/* Address of ld/st multiple structures.  */
229*a9fa9459Szrj   AARCH64_OPND_SIMD_ADDR_POST,	/* Address of ld/st multiple post-indexed.  */
230*a9fa9459Szrj 
231*a9fa9459Szrj   AARCH64_OPND_SYSREG,		/* System register operand.  */
232*a9fa9459Szrj   AARCH64_OPND_PSTATEFIELD,	/* PSTATE field name operand.  */
233*a9fa9459Szrj   AARCH64_OPND_SYSREG_AT,	/* System register <at_op> operand.  */
234*a9fa9459Szrj   AARCH64_OPND_SYSREG_DC,	/* System register <dc_op> operand.  */
235*a9fa9459Szrj   AARCH64_OPND_SYSREG_IC,	/* System register <ic_op> operand.  */
236*a9fa9459Szrj   AARCH64_OPND_SYSREG_TLBI,	/* System register <tlbi_op> operand.  */
237*a9fa9459Szrj   AARCH64_OPND_BARRIER,		/* Barrier operand.  */
238*a9fa9459Szrj   AARCH64_OPND_BARRIER_ISB,	/* Barrier operand for ISB.  */
239*a9fa9459Szrj   AARCH64_OPND_PRFOP,		/* Prefetch operation.  */
240*a9fa9459Szrj   AARCH64_OPND_BARRIER_PSB,	/* Barrier operand for PSB.  */
241*a9fa9459Szrj };
242*a9fa9459Szrj 
243*a9fa9459Szrj /* Qualifier constrains an operand.  It either specifies a variant of an
244*a9fa9459Szrj    operand type or limits values available to an operand type.
245*a9fa9459Szrj 
246*a9fa9459Szrj    N.B. Order is important; keep aarch64_opnd_qualifiers synced.  */
247*a9fa9459Szrj 
248*a9fa9459Szrj enum aarch64_opnd_qualifier
249*a9fa9459Szrj {
250*a9fa9459Szrj   /* Indicating no further qualification on an operand.  */
251*a9fa9459Szrj   AARCH64_OPND_QLF_NIL,
252*a9fa9459Szrj 
253*a9fa9459Szrj   /* Qualifying an operand which is a general purpose (integer) register;
254*a9fa9459Szrj      indicating the operand data size or a specific register.  */
255*a9fa9459Szrj   AARCH64_OPND_QLF_W,	/* Wn, WZR or WSP.  */
256*a9fa9459Szrj   AARCH64_OPND_QLF_X,	/* Xn, XZR or XSP.  */
257*a9fa9459Szrj   AARCH64_OPND_QLF_WSP,	/* WSP.  */
258*a9fa9459Szrj   AARCH64_OPND_QLF_SP,	/* SP.  */
259*a9fa9459Szrj 
260*a9fa9459Szrj   /* Qualifying an operand which is a floating-point register, a SIMD
261*a9fa9459Szrj      vector element or a SIMD vector element list; indicating operand data
262*a9fa9459Szrj      size or the size of each SIMD vector element in the case of a SIMD
263*a9fa9459Szrj      vector element list.
264*a9fa9459Szrj      These qualifiers are also used to qualify an address operand to
265*a9fa9459Szrj      indicate the size of data element a load/store instruction is
266*a9fa9459Szrj      accessing.
267*a9fa9459Szrj      They are also used for the immediate shift operand in e.g. SSHR.  Such
268*a9fa9459Szrj      a use is only for the ease of operand encoding/decoding and qualifier
269*a9fa9459Szrj      sequence matching; such a use should not be applied widely; use the value
270*a9fa9459Szrj      constraint qualifiers for immediate operands wherever possible.  */
271*a9fa9459Szrj   AARCH64_OPND_QLF_S_B,
272*a9fa9459Szrj   AARCH64_OPND_QLF_S_H,
273*a9fa9459Szrj   AARCH64_OPND_QLF_S_S,
274*a9fa9459Szrj   AARCH64_OPND_QLF_S_D,
275*a9fa9459Szrj   AARCH64_OPND_QLF_S_Q,
276*a9fa9459Szrj 
277*a9fa9459Szrj   /* Qualifying an operand which is a SIMD vector register or a SIMD vector
278*a9fa9459Szrj      register list; indicating register shape.
279*a9fa9459Szrj      They are also used for the immediate shift operand in e.g. SSHR.  Such
280*a9fa9459Szrj      a use is only for the ease of operand encoding/decoding and qualifier
281*a9fa9459Szrj      sequence matching; such a use should not be applied widely; use the value
282*a9fa9459Szrj      constraint qualifiers for immediate operands wherever possible.  */
283*a9fa9459Szrj   AARCH64_OPND_QLF_V_8B,
284*a9fa9459Szrj   AARCH64_OPND_QLF_V_16B,
285*a9fa9459Szrj   AARCH64_OPND_QLF_V_2H,
286*a9fa9459Szrj   AARCH64_OPND_QLF_V_4H,
287*a9fa9459Szrj   AARCH64_OPND_QLF_V_8H,
288*a9fa9459Szrj   AARCH64_OPND_QLF_V_2S,
289*a9fa9459Szrj   AARCH64_OPND_QLF_V_4S,
290*a9fa9459Szrj   AARCH64_OPND_QLF_V_1D,
291*a9fa9459Szrj   AARCH64_OPND_QLF_V_2D,
292*a9fa9459Szrj   AARCH64_OPND_QLF_V_1Q,
293*a9fa9459Szrj 
294*a9fa9459Szrj   /* Constraint on value.  */
295*a9fa9459Szrj   AARCH64_OPND_QLF_imm_0_7,
296*a9fa9459Szrj   AARCH64_OPND_QLF_imm_0_15,
297*a9fa9459Szrj   AARCH64_OPND_QLF_imm_0_31,
298*a9fa9459Szrj   AARCH64_OPND_QLF_imm_0_63,
299*a9fa9459Szrj   AARCH64_OPND_QLF_imm_1_32,
300*a9fa9459Szrj   AARCH64_OPND_QLF_imm_1_64,
301*a9fa9459Szrj 
302*a9fa9459Szrj   /* Indicate whether an AdvSIMD modified immediate operand is shift-zeros
303*a9fa9459Szrj      or shift-ones.  */
304*a9fa9459Szrj   AARCH64_OPND_QLF_LSL,
305*a9fa9459Szrj   AARCH64_OPND_QLF_MSL,
306*a9fa9459Szrj 
307*a9fa9459Szrj   /* Special qualifier helping retrieve qualifier information during the
308*a9fa9459Szrj      decoding time (currently not in use).  */
309*a9fa9459Szrj   AARCH64_OPND_QLF_RETRIEVE,
310*a9fa9459Szrj };
311*a9fa9459Szrj 
312*a9fa9459Szrj /* Instruction class.  */
313*a9fa9459Szrj 
314*a9fa9459Szrj enum aarch64_insn_class
315*a9fa9459Szrj {
316*a9fa9459Szrj   addsub_carry,
317*a9fa9459Szrj   addsub_ext,
318*a9fa9459Szrj   addsub_imm,
319*a9fa9459Szrj   addsub_shift,
320*a9fa9459Szrj   asimdall,
321*a9fa9459Szrj   asimddiff,
322*a9fa9459Szrj   asimdelem,
323*a9fa9459Szrj   asimdext,
324*a9fa9459Szrj   asimdimm,
325*a9fa9459Szrj   asimdins,
326*a9fa9459Szrj   asimdmisc,
327*a9fa9459Szrj   asimdperm,
328*a9fa9459Szrj   asimdsame,
329*a9fa9459Szrj   asimdshf,
330*a9fa9459Szrj   asimdtbl,
331*a9fa9459Szrj   asisddiff,
332*a9fa9459Szrj   asisdelem,
333*a9fa9459Szrj   asisdlse,
334*a9fa9459Szrj   asisdlsep,
335*a9fa9459Szrj   asisdlso,
336*a9fa9459Szrj   asisdlsop,
337*a9fa9459Szrj   asisdmisc,
338*a9fa9459Szrj   asisdone,
339*a9fa9459Szrj   asisdpair,
340*a9fa9459Szrj   asisdsame,
341*a9fa9459Szrj   asisdshf,
342*a9fa9459Szrj   bitfield,
343*a9fa9459Szrj   branch_imm,
344*a9fa9459Szrj   branch_reg,
345*a9fa9459Szrj   compbranch,
346*a9fa9459Szrj   condbranch,
347*a9fa9459Szrj   condcmp_imm,
348*a9fa9459Szrj   condcmp_reg,
349*a9fa9459Szrj   condsel,
350*a9fa9459Szrj   cryptoaes,
351*a9fa9459Szrj   cryptosha2,
352*a9fa9459Szrj   cryptosha3,
353*a9fa9459Szrj   dp_1src,
354*a9fa9459Szrj   dp_2src,
355*a9fa9459Szrj   dp_3src,
356*a9fa9459Szrj   exception,
357*a9fa9459Szrj   extract,
358*a9fa9459Szrj   float2fix,
359*a9fa9459Szrj   float2int,
360*a9fa9459Szrj   floatccmp,
361*a9fa9459Szrj   floatcmp,
362*a9fa9459Szrj   floatdp1,
363*a9fa9459Szrj   floatdp2,
364*a9fa9459Szrj   floatdp3,
365*a9fa9459Szrj   floatimm,
366*a9fa9459Szrj   floatsel,
367*a9fa9459Szrj   ldst_immpost,
368*a9fa9459Szrj   ldst_immpre,
369*a9fa9459Szrj   ldst_imm9,	/* immpost or immpre */
370*a9fa9459Szrj   ldst_pos,
371*a9fa9459Szrj   ldst_regoff,
372*a9fa9459Szrj   ldst_unpriv,
373*a9fa9459Szrj   ldst_unscaled,
374*a9fa9459Szrj   ldstexcl,
375*a9fa9459Szrj   ldstnapair_offs,
376*a9fa9459Szrj   ldstpair_off,
377*a9fa9459Szrj   ldstpair_indexed,
378*a9fa9459Szrj   loadlit,
379*a9fa9459Szrj   log_imm,
380*a9fa9459Szrj   log_shift,
381*a9fa9459Szrj   lse_atomic,
382*a9fa9459Szrj   movewide,
383*a9fa9459Szrj   pcreladdr,
384*a9fa9459Szrj   ic_system,
385*a9fa9459Szrj   testbranch,
386*a9fa9459Szrj };
387*a9fa9459Szrj 
388*a9fa9459Szrj /* Opcode enumerators.  */
389*a9fa9459Szrj 
390*a9fa9459Szrj enum aarch64_op
391*a9fa9459Szrj {
392*a9fa9459Szrj   OP_NIL,
393*a9fa9459Szrj   OP_STRB_POS,
394*a9fa9459Szrj   OP_LDRB_POS,
395*a9fa9459Szrj   OP_LDRSB_POS,
396*a9fa9459Szrj   OP_STRH_POS,
397*a9fa9459Szrj   OP_LDRH_POS,
398*a9fa9459Szrj   OP_LDRSH_POS,
399*a9fa9459Szrj   OP_STR_POS,
400*a9fa9459Szrj   OP_LDR_POS,
401*a9fa9459Szrj   OP_STRF_POS,
402*a9fa9459Szrj   OP_LDRF_POS,
403*a9fa9459Szrj   OP_LDRSW_POS,
404*a9fa9459Szrj   OP_PRFM_POS,
405*a9fa9459Szrj 
406*a9fa9459Szrj   OP_STURB,
407*a9fa9459Szrj   OP_LDURB,
408*a9fa9459Szrj   OP_LDURSB,
409*a9fa9459Szrj   OP_STURH,
410*a9fa9459Szrj   OP_LDURH,
411*a9fa9459Szrj   OP_LDURSH,
412*a9fa9459Szrj   OP_STUR,
413*a9fa9459Szrj   OP_LDUR,
414*a9fa9459Szrj   OP_STURV,
415*a9fa9459Szrj   OP_LDURV,
416*a9fa9459Szrj   OP_LDURSW,
417*a9fa9459Szrj   OP_PRFUM,
418*a9fa9459Szrj 
419*a9fa9459Szrj   OP_LDR_LIT,
420*a9fa9459Szrj   OP_LDRV_LIT,
421*a9fa9459Szrj   OP_LDRSW_LIT,
422*a9fa9459Szrj   OP_PRFM_LIT,
423*a9fa9459Szrj 
424*a9fa9459Szrj   OP_ADD,
425*a9fa9459Szrj   OP_B,
426*a9fa9459Szrj   OP_BL,
427*a9fa9459Szrj 
428*a9fa9459Szrj   OP_MOVN,
429*a9fa9459Szrj   OP_MOVZ,
430*a9fa9459Szrj   OP_MOVK,
431*a9fa9459Szrj 
432*a9fa9459Szrj   OP_MOV_IMM_LOG,	/* MOV alias for moving bitmask immediate.  */
433*a9fa9459Szrj   OP_MOV_IMM_WIDE,	/* MOV alias for moving wide immediate.  */
434*a9fa9459Szrj   OP_MOV_IMM_WIDEN,	/* MOV alias for moving wide immediate (negated).  */
435*a9fa9459Szrj 
436*a9fa9459Szrj   OP_MOV_V,		/* MOV alias for moving vector register.  */
437*a9fa9459Szrj 
438*a9fa9459Szrj   OP_ASR_IMM,
439*a9fa9459Szrj   OP_LSR_IMM,
440*a9fa9459Szrj   OP_LSL_IMM,
441*a9fa9459Szrj 
442*a9fa9459Szrj   OP_BIC,
443*a9fa9459Szrj 
444*a9fa9459Szrj   OP_UBFX,
445*a9fa9459Szrj   OP_BFXIL,
446*a9fa9459Szrj   OP_SBFX,
447*a9fa9459Szrj   OP_SBFIZ,
448*a9fa9459Szrj   OP_BFI,
449*a9fa9459Szrj   OP_BFC,		/* ARMv8.2.  */
450*a9fa9459Szrj   OP_UBFIZ,
451*a9fa9459Szrj   OP_UXTB,
452*a9fa9459Szrj   OP_UXTH,
453*a9fa9459Szrj   OP_UXTW,
454*a9fa9459Szrj 
455*a9fa9459Szrj   OP_CINC,
456*a9fa9459Szrj   OP_CINV,
457*a9fa9459Szrj   OP_CNEG,
458*a9fa9459Szrj   OP_CSET,
459*a9fa9459Szrj   OP_CSETM,
460*a9fa9459Szrj 
461*a9fa9459Szrj   OP_FCVT,
462*a9fa9459Szrj   OP_FCVTN,
463*a9fa9459Szrj   OP_FCVTN2,
464*a9fa9459Szrj   OP_FCVTL,
465*a9fa9459Szrj   OP_FCVTL2,
466*a9fa9459Szrj   OP_FCVTXN_S,		/* Scalar version.  */
467*a9fa9459Szrj 
468*a9fa9459Szrj   OP_ROR_IMM,
469*a9fa9459Szrj 
470*a9fa9459Szrj   OP_SXTL,
471*a9fa9459Szrj   OP_SXTL2,
472*a9fa9459Szrj   OP_UXTL,
473*a9fa9459Szrj   OP_UXTL2,
474*a9fa9459Szrj 
475*a9fa9459Szrj   OP_TOTAL_NUM,		/* Pseudo.  */
476*a9fa9459Szrj };
477*a9fa9459Szrj 
478*a9fa9459Szrj /* Maximum number of operands an instruction can have.  */
479*a9fa9459Szrj #define AARCH64_MAX_OPND_NUM 6
480*a9fa9459Szrj /* Maximum number of qualifier sequences an instruction can have.  */
481*a9fa9459Szrj #define AARCH64_MAX_QLF_SEQ_NUM 10
482*a9fa9459Szrj /* Operand qualifier typedef; optimized for the size.  */
483*a9fa9459Szrj typedef unsigned char aarch64_opnd_qualifier_t;
484*a9fa9459Szrj /* Operand qualifier sequence typedef.  */
485*a9fa9459Szrj typedef aarch64_opnd_qualifier_t	\
486*a9fa9459Szrj 	  aarch64_opnd_qualifier_seq_t [AARCH64_MAX_OPND_NUM];
487*a9fa9459Szrj 
488*a9fa9459Szrj /* FIXME: improve the efficiency.  */
489*a9fa9459Szrj static inline bfd_boolean
empty_qualifier_sequence_p(const aarch64_opnd_qualifier_t * qualifiers)490*a9fa9459Szrj empty_qualifier_sequence_p (const aarch64_opnd_qualifier_t *qualifiers)
491*a9fa9459Szrj {
492*a9fa9459Szrj   int i;
493*a9fa9459Szrj   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
494*a9fa9459Szrj     if (qualifiers[i] != AARCH64_OPND_QLF_NIL)
495*a9fa9459Szrj       return FALSE;
496*a9fa9459Szrj   return TRUE;
497*a9fa9459Szrj }
498*a9fa9459Szrj 
499*a9fa9459Szrj /* This structure holds information for a particular opcode.  */
500*a9fa9459Szrj 
501*a9fa9459Szrj struct aarch64_opcode
502*a9fa9459Szrj {
503*a9fa9459Szrj   /* The name of the mnemonic.  */
504*a9fa9459Szrj   const char *name;
505*a9fa9459Szrj 
506*a9fa9459Szrj   /* The opcode itself.  Those bits which will be filled in with
507*a9fa9459Szrj      operands are zeroes.  */
508*a9fa9459Szrj   aarch64_insn opcode;
509*a9fa9459Szrj 
510*a9fa9459Szrj   /* The opcode mask.  This is used by the disassembler.  This is a
511*a9fa9459Szrj      mask containing ones indicating those bits which must match the
512*a9fa9459Szrj      opcode field, and zeroes indicating those bits which need not
513*a9fa9459Szrj      match (and are presumably filled in by operands).  */
514*a9fa9459Szrj   aarch64_insn mask;
515*a9fa9459Szrj 
516*a9fa9459Szrj   /* Instruction class.  */
517*a9fa9459Szrj   enum aarch64_insn_class iclass;
518*a9fa9459Szrj 
519*a9fa9459Szrj   /* Enumerator identifier.  */
520*a9fa9459Szrj   enum aarch64_op op;
521*a9fa9459Szrj 
522*a9fa9459Szrj   /* Which architecture variant provides this instruction.  */
523*a9fa9459Szrj   const aarch64_feature_set *avariant;
524*a9fa9459Szrj 
525*a9fa9459Szrj   /* An array of operand codes.  Each code is an index into the
526*a9fa9459Szrj      operand table.  They appear in the order which the operands must
527*a9fa9459Szrj      appear in assembly code, and are terminated by a zero.  */
528*a9fa9459Szrj   enum aarch64_opnd operands[AARCH64_MAX_OPND_NUM];
529*a9fa9459Szrj 
530*a9fa9459Szrj   /* A list of operand qualifier code sequence.  Each operand qualifier
531*a9fa9459Szrj      code qualifies the corresponding operand code.  Each operand
532*a9fa9459Szrj      qualifier sequence specifies a valid opcode variant and related
533*a9fa9459Szrj      constraint on operands.  */
534*a9fa9459Szrj   aarch64_opnd_qualifier_seq_t qualifiers_list[AARCH64_MAX_QLF_SEQ_NUM];
535*a9fa9459Szrj 
536*a9fa9459Szrj   /* Flags providing information about this instruction */
537*a9fa9459Szrj   uint32_t flags;
538*a9fa9459Szrj 
539*a9fa9459Szrj   /* If non-NULL, a function to verify that a given instruction is valid.  */
540*a9fa9459Szrj   bfd_boolean (* verifier) (const struct aarch64_opcode *, const aarch64_insn);
541*a9fa9459Szrj };
542*a9fa9459Szrj 
543*a9fa9459Szrj typedef struct aarch64_opcode aarch64_opcode;
544*a9fa9459Szrj 
545*a9fa9459Szrj /* Table describing all the AArch64 opcodes.  */
546*a9fa9459Szrj extern aarch64_opcode aarch64_opcode_table[];
547*a9fa9459Szrj 
548*a9fa9459Szrj /* Opcode flags.  */
549*a9fa9459Szrj #define F_ALIAS (1 << 0)
550*a9fa9459Szrj #define F_HAS_ALIAS (1 << 1)
551*a9fa9459Szrj /* Disassembly preference priority 1-3 (the larger the higher).  If nothing
552*a9fa9459Szrj    is specified, it is the priority 0 by default, i.e. the lowest priority.  */
553*a9fa9459Szrj #define F_P1 (1 << 2)
554*a9fa9459Szrj #define F_P2 (2 << 2)
555*a9fa9459Szrj #define F_P3 (3 << 2)
556*a9fa9459Szrj /* Flag an instruction that is truly conditional executed, e.g. b.cond.  */
557*a9fa9459Szrj #define F_COND (1 << 4)
558*a9fa9459Szrj /* Instruction has the field of 'sf'.  */
559*a9fa9459Szrj #define F_SF (1 << 5)
560*a9fa9459Szrj /* Instruction has the field of 'size:Q'.  */
561*a9fa9459Szrj #define F_SIZEQ (1 << 6)
562*a9fa9459Szrj /* Floating-point instruction has the field of 'type'.  */
563*a9fa9459Szrj #define F_FPTYPE (1 << 7)
564*a9fa9459Szrj /* AdvSIMD scalar instruction has the field of 'size'.  */
565*a9fa9459Szrj #define F_SSIZE (1 << 8)
566*a9fa9459Szrj /* AdvSIMD vector register arrangement specifier encoded in "imm5<3:0>:Q".  */
567*a9fa9459Szrj #define F_T (1 << 9)
568*a9fa9459Szrj /* Size of GPR operand in AdvSIMD instructions encoded in Q.  */
569*a9fa9459Szrj #define F_GPRSIZE_IN_Q (1 << 10)
570*a9fa9459Szrj /* Size of Rt load signed instruction encoded in opc[0], i.e. bit 22.  */
571*a9fa9459Szrj #define F_LDS_SIZE (1 << 11)
572*a9fa9459Szrj /* Optional operand; assume maximum of 1 operand can be optional.  */
573*a9fa9459Szrj #define F_OPD0_OPT (1 << 12)
574*a9fa9459Szrj #define F_OPD1_OPT (2 << 12)
575*a9fa9459Szrj #define F_OPD2_OPT (3 << 12)
576*a9fa9459Szrj #define F_OPD3_OPT (4 << 12)
577*a9fa9459Szrj #define F_OPD4_OPT (5 << 12)
578*a9fa9459Szrj /* Default value for the optional operand when omitted from the assembly.  */
579*a9fa9459Szrj #define F_DEFAULT(X) (((X) & 0x1f) << 15)
580*a9fa9459Szrj /* Instruction that is an alias of another instruction needs to be
581*a9fa9459Szrj    encoded/decoded by converting it to/from the real form, followed by
582*a9fa9459Szrj    the encoding/decoding according to the rules of the real opcode.
583*a9fa9459Szrj    This compares to the direct coding using the alias's information.
584*a9fa9459Szrj    N.B. this flag requires F_ALIAS to be used together.  */
585*a9fa9459Szrj #define F_CONV (1 << 20)
586*a9fa9459Szrj /* Use together with F_ALIAS to indicate an alias opcode is a programmer
587*a9fa9459Szrj    friendly pseudo instruction available only in the assembly code (thus will
588*a9fa9459Szrj    not show up in the disassembly).  */
589*a9fa9459Szrj #define F_PSEUDO (1 << 21)
590*a9fa9459Szrj /* Instruction has miscellaneous encoding/decoding rules.  */
591*a9fa9459Szrj #define F_MISC (1 << 22)
592*a9fa9459Szrj /* Instruction has the field of 'N'; used in conjunction with F_SF.  */
593*a9fa9459Szrj #define F_N (1 << 23)
594*a9fa9459Szrj /* Opcode dependent field.  */
595*a9fa9459Szrj #define F_OD(X) (((X) & 0x7) << 24)
596*a9fa9459Szrj /* Instruction has the field of 'sz'.  */
597*a9fa9459Szrj #define F_LSE_SZ (1 << 27)
598*a9fa9459Szrj /* Next bit is 28.  */
599*a9fa9459Szrj 
600*a9fa9459Szrj static inline bfd_boolean
alias_opcode_p(const aarch64_opcode * opcode)601*a9fa9459Szrj alias_opcode_p (const aarch64_opcode *opcode)
602*a9fa9459Szrj {
603*a9fa9459Szrj   return (opcode->flags & F_ALIAS) ? TRUE : FALSE;
604*a9fa9459Szrj }
605*a9fa9459Szrj 
606*a9fa9459Szrj static inline bfd_boolean
opcode_has_alias(const aarch64_opcode * opcode)607*a9fa9459Szrj opcode_has_alias (const aarch64_opcode *opcode)
608*a9fa9459Szrj {
609*a9fa9459Szrj   return (opcode->flags & F_HAS_ALIAS) ? TRUE : FALSE;
610*a9fa9459Szrj }
611*a9fa9459Szrj 
612*a9fa9459Szrj /* Priority for disassembling preference.  */
613*a9fa9459Szrj static inline int
opcode_priority(const aarch64_opcode * opcode)614*a9fa9459Szrj opcode_priority (const aarch64_opcode *opcode)
615*a9fa9459Szrj {
616*a9fa9459Szrj   return (opcode->flags >> 2) & 0x3;
617*a9fa9459Szrj }
618*a9fa9459Szrj 
619*a9fa9459Szrj static inline bfd_boolean
pseudo_opcode_p(const aarch64_opcode * opcode)620*a9fa9459Szrj pseudo_opcode_p (const aarch64_opcode *opcode)
621*a9fa9459Szrj {
622*a9fa9459Szrj   return (opcode->flags & F_PSEUDO) != 0lu ? TRUE : FALSE;
623*a9fa9459Szrj }
624*a9fa9459Szrj 
625*a9fa9459Szrj static inline bfd_boolean
optional_operand_p(const aarch64_opcode * opcode,unsigned int idx)626*a9fa9459Szrj optional_operand_p (const aarch64_opcode *opcode, unsigned int idx)
627*a9fa9459Szrj {
628*a9fa9459Szrj   return (((opcode->flags >> 12) & 0x7) == idx + 1)
629*a9fa9459Szrj     ? TRUE : FALSE;
630*a9fa9459Szrj }
631*a9fa9459Szrj 
632*a9fa9459Szrj static inline aarch64_insn
get_optional_operand_default_value(const aarch64_opcode * opcode)633*a9fa9459Szrj get_optional_operand_default_value (const aarch64_opcode *opcode)
634*a9fa9459Szrj {
635*a9fa9459Szrj   return (opcode->flags >> 15) & 0x1f;
636*a9fa9459Szrj }
637*a9fa9459Szrj 
638*a9fa9459Szrj static inline unsigned int
get_opcode_dependent_value(const aarch64_opcode * opcode)639*a9fa9459Szrj get_opcode_dependent_value (const aarch64_opcode *opcode)
640*a9fa9459Szrj {
641*a9fa9459Szrj   return (opcode->flags >> 24) & 0x7;
642*a9fa9459Szrj }
643*a9fa9459Szrj 
644*a9fa9459Szrj static inline bfd_boolean
opcode_has_special_coder(const aarch64_opcode * opcode)645*a9fa9459Szrj opcode_has_special_coder (const aarch64_opcode *opcode)
646*a9fa9459Szrj {
647*a9fa9459Szrj   return (opcode->flags & (F_SF | F_LSE_SZ | F_SIZEQ | F_FPTYPE | F_SSIZE | F_T
648*a9fa9459Szrj 	  | F_GPRSIZE_IN_Q | F_LDS_SIZE | F_MISC | F_N | F_COND)) ? TRUE
649*a9fa9459Szrj     : FALSE;
650*a9fa9459Szrj }
651*a9fa9459Szrj 
652*a9fa9459Szrj struct aarch64_name_value_pair
653*a9fa9459Szrj {
654*a9fa9459Szrj   const char *  name;
655*a9fa9459Szrj   aarch64_insn	value;
656*a9fa9459Szrj };
657*a9fa9459Szrj 
658*a9fa9459Szrj extern const struct aarch64_name_value_pair aarch64_operand_modifiers [];
659*a9fa9459Szrj extern const struct aarch64_name_value_pair aarch64_barrier_options [16];
660*a9fa9459Szrj extern const struct aarch64_name_value_pair aarch64_prfops [32];
661*a9fa9459Szrj extern const struct aarch64_name_value_pair aarch64_hint_options [];
662*a9fa9459Szrj 
663*a9fa9459Szrj typedef struct
664*a9fa9459Szrj {
665*a9fa9459Szrj   const char *  name;
666*a9fa9459Szrj   aarch64_insn	value;
667*a9fa9459Szrj   uint32_t	flags;
668*a9fa9459Szrj } aarch64_sys_reg;
669*a9fa9459Szrj 
670*a9fa9459Szrj extern const aarch64_sys_reg aarch64_sys_regs [];
671*a9fa9459Szrj extern const aarch64_sys_reg aarch64_pstatefields [];
672*a9fa9459Szrj extern bfd_boolean aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *);
673*a9fa9459Szrj extern bfd_boolean aarch64_sys_reg_supported_p (const aarch64_feature_set,
674*a9fa9459Szrj 						const aarch64_sys_reg *);
675*a9fa9459Szrj extern bfd_boolean aarch64_pstatefield_supported_p (const aarch64_feature_set,
676*a9fa9459Szrj 						    const aarch64_sys_reg *);
677*a9fa9459Szrj 
678*a9fa9459Szrj typedef struct
679*a9fa9459Szrj {
680*a9fa9459Szrj   const char *name;
681*a9fa9459Szrj   uint32_t value;
682*a9fa9459Szrj   uint32_t flags ;
683*a9fa9459Szrj } aarch64_sys_ins_reg;
684*a9fa9459Szrj 
685*a9fa9459Szrj extern bfd_boolean aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *);
686*a9fa9459Szrj extern bfd_boolean
687*a9fa9459Szrj aarch64_sys_ins_reg_supported_p (const aarch64_feature_set,
688*a9fa9459Szrj 				 const aarch64_sys_ins_reg *);
689*a9fa9459Szrj 
690*a9fa9459Szrj extern const aarch64_sys_ins_reg aarch64_sys_regs_ic [];
691*a9fa9459Szrj extern const aarch64_sys_ins_reg aarch64_sys_regs_dc [];
692*a9fa9459Szrj extern const aarch64_sys_ins_reg aarch64_sys_regs_at [];
693*a9fa9459Szrj extern const aarch64_sys_ins_reg aarch64_sys_regs_tlbi [];
694*a9fa9459Szrj 
695*a9fa9459Szrj /* Shift/extending operator kinds.
696*a9fa9459Szrj    N.B. order is important; keep aarch64_operand_modifiers synced.  */
697*a9fa9459Szrj enum aarch64_modifier_kind
698*a9fa9459Szrj {
699*a9fa9459Szrj   AARCH64_MOD_NONE,
700*a9fa9459Szrj   AARCH64_MOD_MSL,
701*a9fa9459Szrj   AARCH64_MOD_ROR,
702*a9fa9459Szrj   AARCH64_MOD_ASR,
703*a9fa9459Szrj   AARCH64_MOD_LSR,
704*a9fa9459Szrj   AARCH64_MOD_LSL,
705*a9fa9459Szrj   AARCH64_MOD_UXTB,
706*a9fa9459Szrj   AARCH64_MOD_UXTH,
707*a9fa9459Szrj   AARCH64_MOD_UXTW,
708*a9fa9459Szrj   AARCH64_MOD_UXTX,
709*a9fa9459Szrj   AARCH64_MOD_SXTB,
710*a9fa9459Szrj   AARCH64_MOD_SXTH,
711*a9fa9459Szrj   AARCH64_MOD_SXTW,
712*a9fa9459Szrj   AARCH64_MOD_SXTX,
713*a9fa9459Szrj };
714*a9fa9459Szrj 
715*a9fa9459Szrj bfd_boolean
716*a9fa9459Szrj aarch64_extend_operator_p (enum aarch64_modifier_kind);
717*a9fa9459Szrj 
718*a9fa9459Szrj enum aarch64_modifier_kind
719*a9fa9459Szrj aarch64_get_operand_modifier (const struct aarch64_name_value_pair *);
720*a9fa9459Szrj /* Condition.  */
721*a9fa9459Szrj 
722*a9fa9459Szrj typedef struct
723*a9fa9459Szrj {
724*a9fa9459Szrj   /* A list of names with the first one as the disassembly preference;
725*a9fa9459Szrj      terminated by NULL if fewer than 3.  */
726*a9fa9459Szrj   const char *names[3];
727*a9fa9459Szrj   aarch64_insn value;
728*a9fa9459Szrj } aarch64_cond;
729*a9fa9459Szrj 
730*a9fa9459Szrj extern const aarch64_cond aarch64_conds[16];
731*a9fa9459Szrj 
732*a9fa9459Szrj const aarch64_cond* get_cond_from_value (aarch64_insn value);
733*a9fa9459Szrj const aarch64_cond* get_inverted_cond (const aarch64_cond *cond);
734*a9fa9459Szrj 
735*a9fa9459Szrj /* Structure representing an operand.  */
736*a9fa9459Szrj 
737*a9fa9459Szrj struct aarch64_opnd_info
738*a9fa9459Szrj {
739*a9fa9459Szrj   enum aarch64_opnd type;
740*a9fa9459Szrj   aarch64_opnd_qualifier_t qualifier;
741*a9fa9459Szrj   int idx;
742*a9fa9459Szrj 
743*a9fa9459Szrj   union
744*a9fa9459Szrj     {
745*a9fa9459Szrj       struct
746*a9fa9459Szrj 	{
747*a9fa9459Szrj 	  unsigned regno;
748*a9fa9459Szrj 	} reg;
749*a9fa9459Szrj       struct
750*a9fa9459Szrj 	{
751*a9fa9459Szrj 	  unsigned int regno;
752*a9fa9459Szrj 	  int64_t index;
753*a9fa9459Szrj 	} reglane;
754*a9fa9459Szrj       /* e.g. LVn.  */
755*a9fa9459Szrj       struct
756*a9fa9459Szrj 	{
757*a9fa9459Szrj 	  unsigned first_regno : 5;
758*a9fa9459Szrj 	  unsigned num_regs : 3;
759*a9fa9459Szrj 	  /* 1 if it is a list of reg element.  */
760*a9fa9459Szrj 	  unsigned has_index : 1;
761*a9fa9459Szrj 	  /* Lane index; valid only when has_index is 1.  */
762*a9fa9459Szrj 	  int64_t index;
763*a9fa9459Szrj 	} reglist;
764*a9fa9459Szrj       /* e.g. immediate or pc relative address offset.  */
765*a9fa9459Szrj       struct
766*a9fa9459Szrj 	{
767*a9fa9459Szrj 	  int64_t value;
768*a9fa9459Szrj 	  unsigned is_fp : 1;
769*a9fa9459Szrj 	} imm;
770*a9fa9459Szrj       /* e.g. address in STR (register offset).  */
771*a9fa9459Szrj       struct
772*a9fa9459Szrj 	{
773*a9fa9459Szrj 	  unsigned base_regno;
774*a9fa9459Szrj 	  struct
775*a9fa9459Szrj 	    {
776*a9fa9459Szrj 	      union
777*a9fa9459Szrj 		{
778*a9fa9459Szrj 		  int imm;
779*a9fa9459Szrj 		  unsigned regno;
780*a9fa9459Szrj 		};
781*a9fa9459Szrj 	      unsigned is_reg;
782*a9fa9459Szrj 	    } offset;
783*a9fa9459Szrj 	  unsigned pcrel : 1;		/* PC-relative.  */
784*a9fa9459Szrj 	  unsigned writeback : 1;
785*a9fa9459Szrj 	  unsigned preind : 1;		/* Pre-indexed.  */
786*a9fa9459Szrj 	  unsigned postind : 1;		/* Post-indexed.  */
787*a9fa9459Szrj 	} addr;
788*a9fa9459Szrj       const aarch64_cond *cond;
789*a9fa9459Szrj       /* The encoding of the system register.  */
790*a9fa9459Szrj       aarch64_insn sysreg;
791*a9fa9459Szrj       /* The encoding of the PSTATE field.  */
792*a9fa9459Szrj       aarch64_insn pstatefield;
793*a9fa9459Szrj       const aarch64_sys_ins_reg *sysins_op;
794*a9fa9459Szrj       const struct aarch64_name_value_pair *barrier;
795*a9fa9459Szrj       const struct aarch64_name_value_pair *hint_option;
796*a9fa9459Szrj       const struct aarch64_name_value_pair *prfop;
797*a9fa9459Szrj     };
798*a9fa9459Szrj 
799*a9fa9459Szrj   /* Operand shifter; in use when the operand is a register offset address,
800*a9fa9459Szrj      add/sub extended reg, etc. e.g. <R><m>{, <extend> {#<amount>}}.  */
801*a9fa9459Szrj   struct
802*a9fa9459Szrj     {
803*a9fa9459Szrj       enum aarch64_modifier_kind kind;
804*a9fa9459Szrj       int amount;
805*a9fa9459Szrj       unsigned operator_present: 1;	/* Only valid during encoding.  */
806*a9fa9459Szrj       /* Value of the 'S' field in ld/st reg offset; used only in decoding.  */
807*a9fa9459Szrj       unsigned amount_present: 1;
808*a9fa9459Szrj     } shifter;
809*a9fa9459Szrj 
810*a9fa9459Szrj   unsigned skip:1;	/* Operand is not completed if there is a fixup needed
811*a9fa9459Szrj 			   to be done on it.  In some (but not all) of these
812*a9fa9459Szrj 			   cases, we need to tell libopcodes to skip the
813*a9fa9459Szrj 			   constraint checking and the encoding for this
814*a9fa9459Szrj 			   operand, so that the libopcodes can pick up the
815*a9fa9459Szrj 			   right opcode before the operand is fixed-up.  This
816*a9fa9459Szrj 			   flag should only be used during the
817*a9fa9459Szrj 			   assembling/encoding.  */
818*a9fa9459Szrj   unsigned present:1;	/* Whether this operand is present in the assembly
819*a9fa9459Szrj 			   line; not used during the disassembly.  */
820*a9fa9459Szrj };
821*a9fa9459Szrj 
822*a9fa9459Szrj typedef struct aarch64_opnd_info aarch64_opnd_info;
823*a9fa9459Szrj 
824*a9fa9459Szrj /* Structure representing an instruction.
825*a9fa9459Szrj 
826*a9fa9459Szrj    It is used during both the assembling and disassembling.  The assembler
827*a9fa9459Szrj    fills an aarch64_inst after a successful parsing and then passes it to the
828*a9fa9459Szrj    encoding routine to do the encoding.  During the disassembling, the
829*a9fa9459Szrj    disassembler calls the decoding routine to decode a binary instruction; on a
830*a9fa9459Szrj    successful return, such a structure will be filled with information of the
831*a9fa9459Szrj    instruction; then the disassembler uses the information to print out the
832*a9fa9459Szrj    instruction.  */
833*a9fa9459Szrj 
834*a9fa9459Szrj struct aarch64_inst
835*a9fa9459Szrj {
836*a9fa9459Szrj   /* The value of the binary instruction.  */
837*a9fa9459Szrj   aarch64_insn value;
838*a9fa9459Szrj 
839*a9fa9459Szrj   /* Corresponding opcode entry.  */
840*a9fa9459Szrj   const aarch64_opcode *opcode;
841*a9fa9459Szrj 
842*a9fa9459Szrj   /* Condition for a truly conditional-executed instrutions, e.g. b.cond.  */
843*a9fa9459Szrj   const aarch64_cond *cond;
844*a9fa9459Szrj 
845*a9fa9459Szrj   /* Operands information.  */
846*a9fa9459Szrj   aarch64_opnd_info operands[AARCH64_MAX_OPND_NUM];
847*a9fa9459Szrj };
848*a9fa9459Szrj 
849*a9fa9459Szrj typedef struct aarch64_inst aarch64_inst;
850*a9fa9459Szrj 
851*a9fa9459Szrj /* Diagnosis related declaration and interface.  */
852*a9fa9459Szrj 
853*a9fa9459Szrj /* Operand error kind enumerators.
854*a9fa9459Szrj 
855*a9fa9459Szrj    AARCH64_OPDE_RECOVERABLE
856*a9fa9459Szrj      Less severe error found during the parsing, very possibly because that
857*a9fa9459Szrj      GAS has picked up a wrong instruction template for the parsing.
858*a9fa9459Szrj 
859*a9fa9459Szrj    AARCH64_OPDE_SYNTAX_ERROR
860*a9fa9459Szrj      General syntax error; it can be either a user error, or simply because
861*a9fa9459Szrj      that GAS is trying a wrong instruction template.
862*a9fa9459Szrj 
863*a9fa9459Szrj    AARCH64_OPDE_FATAL_SYNTAX_ERROR
864*a9fa9459Szrj      Definitely a user syntax error.
865*a9fa9459Szrj 
866*a9fa9459Szrj    AARCH64_OPDE_INVALID_VARIANT
867*a9fa9459Szrj      No syntax error, but the operands are not a valid combination, e.g.
868*a9fa9459Szrj      FMOV D0,S0
869*a9fa9459Szrj 
870*a9fa9459Szrj    AARCH64_OPDE_OUT_OF_RANGE
871*a9fa9459Szrj      Error about some immediate value out of a valid range.
872*a9fa9459Szrj 
873*a9fa9459Szrj    AARCH64_OPDE_UNALIGNED
874*a9fa9459Szrj      Error about some immediate value not properly aligned (i.e. not being a
875*a9fa9459Szrj      multiple times of a certain value).
876*a9fa9459Szrj 
877*a9fa9459Szrj    AARCH64_OPDE_REG_LIST
878*a9fa9459Szrj      Error about the register list operand having unexpected number of
879*a9fa9459Szrj      registers.
880*a9fa9459Szrj 
881*a9fa9459Szrj    AARCH64_OPDE_OTHER_ERROR
882*a9fa9459Szrj      Error of the highest severity and used for any severe issue that does not
883*a9fa9459Szrj      fall into any of the above categories.
884*a9fa9459Szrj 
885*a9fa9459Szrj    The enumerators are only interesting to GAS.  They are declared here (in
886*a9fa9459Szrj    libopcodes) because that some errors are detected (and then notified to GAS)
887*a9fa9459Szrj    by libopcodes (rather than by GAS solely).
888*a9fa9459Szrj 
889*a9fa9459Szrj    The first three errors are only deteced by GAS while the
890*a9fa9459Szrj    AARCH64_OPDE_INVALID_VARIANT error can only be spotted by libopcodes as
891*a9fa9459Szrj    only libopcodes has the information about the valid variants of each
892*a9fa9459Szrj    instruction.
893*a9fa9459Szrj 
894*a9fa9459Szrj    The enumerators have an increasing severity.  This is helpful when there are
895*a9fa9459Szrj    multiple instruction templates available for a given mnemonic name (e.g.
896*a9fa9459Szrj    FMOV); this mechanism will help choose the most suitable template from which
897*a9fa9459Szrj    the generated diagnostics can most closely describe the issues, if any.  */
898*a9fa9459Szrj 
899*a9fa9459Szrj enum aarch64_operand_error_kind
900*a9fa9459Szrj {
901*a9fa9459Szrj   AARCH64_OPDE_NIL,
902*a9fa9459Szrj   AARCH64_OPDE_RECOVERABLE,
903*a9fa9459Szrj   AARCH64_OPDE_SYNTAX_ERROR,
904*a9fa9459Szrj   AARCH64_OPDE_FATAL_SYNTAX_ERROR,
905*a9fa9459Szrj   AARCH64_OPDE_INVALID_VARIANT,
906*a9fa9459Szrj   AARCH64_OPDE_OUT_OF_RANGE,
907*a9fa9459Szrj   AARCH64_OPDE_UNALIGNED,
908*a9fa9459Szrj   AARCH64_OPDE_REG_LIST,
909*a9fa9459Szrj   AARCH64_OPDE_OTHER_ERROR
910*a9fa9459Szrj };
911*a9fa9459Szrj 
912*a9fa9459Szrj /* N.B. GAS assumes that this structure work well with shallow copy.  */
913*a9fa9459Szrj struct aarch64_operand_error
914*a9fa9459Szrj {
915*a9fa9459Szrj   enum aarch64_operand_error_kind kind;
916*a9fa9459Szrj   int index;
917*a9fa9459Szrj   const char *error;
918*a9fa9459Szrj   int data[3];	/* Some data for extra information.  */
919*a9fa9459Szrj };
920*a9fa9459Szrj 
921*a9fa9459Szrj typedef struct aarch64_operand_error aarch64_operand_error;
922*a9fa9459Szrj 
923*a9fa9459Szrj /* Encoding entrypoint.  */
924*a9fa9459Szrj 
925*a9fa9459Szrj extern int
926*a9fa9459Szrj aarch64_opcode_encode (const aarch64_opcode *, const aarch64_inst *,
927*a9fa9459Szrj 		       aarch64_insn *, aarch64_opnd_qualifier_t *,
928*a9fa9459Szrj 		       aarch64_operand_error *);
929*a9fa9459Szrj 
930*a9fa9459Szrj extern const aarch64_opcode *
931*a9fa9459Szrj aarch64_replace_opcode (struct aarch64_inst *,
932*a9fa9459Szrj 			const aarch64_opcode *);
933*a9fa9459Szrj 
934*a9fa9459Szrj /* Given the opcode enumerator OP, return the pointer to the corresponding
935*a9fa9459Szrj    opcode entry.  */
936*a9fa9459Szrj 
937*a9fa9459Szrj extern const aarch64_opcode *
938*a9fa9459Szrj aarch64_get_opcode (enum aarch64_op);
939*a9fa9459Szrj 
940*a9fa9459Szrj /* Generate the string representation of an operand.  */
941*a9fa9459Szrj extern void
942*a9fa9459Szrj aarch64_print_operand (char *, size_t, bfd_vma, const aarch64_opcode *,
943*a9fa9459Szrj 		       const aarch64_opnd_info *, int, int *, bfd_vma *);
944*a9fa9459Szrj 
945*a9fa9459Szrj /* Miscellaneous interface.  */
946*a9fa9459Szrj 
947*a9fa9459Szrj extern int
948*a9fa9459Szrj aarch64_operand_index (const enum aarch64_opnd *, enum aarch64_opnd);
949*a9fa9459Szrj 
950*a9fa9459Szrj extern aarch64_opnd_qualifier_t
951*a9fa9459Szrj aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *, int,
952*a9fa9459Szrj 				const aarch64_opnd_qualifier_t, int);
953*a9fa9459Szrj 
954*a9fa9459Szrj extern int
955*a9fa9459Szrj aarch64_num_of_operands (const aarch64_opcode *);
956*a9fa9459Szrj 
957*a9fa9459Szrj extern int
958*a9fa9459Szrj aarch64_stack_pointer_p (const aarch64_opnd_info *);
959*a9fa9459Szrj 
960*a9fa9459Szrj extern int
961*a9fa9459Szrj aarch64_zero_register_p (const aarch64_opnd_info *);
962*a9fa9459Szrj 
963*a9fa9459Szrj extern int
964*a9fa9459Szrj aarch64_decode_insn (aarch64_insn, aarch64_inst *, bfd_boolean);
965*a9fa9459Szrj 
966*a9fa9459Szrj /* Given an operand qualifier, return the expected data element size
967*a9fa9459Szrj    of a qualified operand.  */
968*a9fa9459Szrj extern unsigned char
969*a9fa9459Szrj aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t);
970*a9fa9459Szrj 
971*a9fa9459Szrj extern enum aarch64_operand_class
972*a9fa9459Szrj aarch64_get_operand_class (enum aarch64_opnd);
973*a9fa9459Szrj 
974*a9fa9459Szrj extern const char *
975*a9fa9459Szrj aarch64_get_operand_name (enum aarch64_opnd);
976*a9fa9459Szrj 
977*a9fa9459Szrj extern const char *
978*a9fa9459Szrj aarch64_get_operand_desc (enum aarch64_opnd);
979*a9fa9459Szrj 
980*a9fa9459Szrj #ifdef DEBUG_AARCH64
981*a9fa9459Szrj extern int debug_dump;
982*a9fa9459Szrj 
983*a9fa9459Szrj extern void
984*a9fa9459Szrj aarch64_verbose (const char *, ...) __attribute__ ((format (printf, 1, 2)));
985*a9fa9459Szrj 
986*a9fa9459Szrj #define DEBUG_TRACE(M, ...)					\
987*a9fa9459Szrj   {								\
988*a9fa9459Szrj     if (debug_dump)						\
989*a9fa9459Szrj       aarch64_verbose ("%s: " M ".", __func__, ##__VA_ARGS__);	\
990*a9fa9459Szrj   }
991*a9fa9459Szrj 
992*a9fa9459Szrj #define DEBUG_TRACE_IF(C, M, ...)				\
993*a9fa9459Szrj   {								\
994*a9fa9459Szrj     if (debug_dump && (C))					\
995*a9fa9459Szrj       aarch64_verbose ("%s: " M ".", __func__, ##__VA_ARGS__);	\
996*a9fa9459Szrj   }
997*a9fa9459Szrj #else  /* !DEBUG_AARCH64 */
998*a9fa9459Szrj #define DEBUG_TRACE(M, ...) ;
999*a9fa9459Szrj #define DEBUG_TRACE_IF(C, M, ...) ;
1000*a9fa9459Szrj #endif /* DEBUG_AARCH64 */
1001*a9fa9459Szrj 
1002*a9fa9459Szrj #ifdef __cplusplus
1003*a9fa9459Szrj }
1004*a9fa9459Szrj #endif
1005*a9fa9459Szrj 
1006*a9fa9459Szrj #endif /* OPCODE_AARCH64_H */
1007