/* AArch64 assembler/disassembler support.
- Copyright 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2016 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of GNU Binutils.
#include <assert.h>
#include <stdlib.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* The offset for pc-relative addressing is currently defined to be 0. */
#define AARCH64_PCREL_OFFSET 0
/* The following bitmasks control CPU features. */
#define AARCH64_FEATURE_V8 0x00000001 /* All processors. */
+#define AARCH64_FEATURE_V8_2 0x00000020 /* ARMv8.2 processors. */
#define AARCH64_FEATURE_CRYPTO 0x00010000 /* Crypto instructions. */
#define AARCH64_FEATURE_FP 0x00020000 /* FP instructions. */
#define AARCH64_FEATURE_SIMD 0x00040000 /* SIMD instructions. */
#define AARCH64_FEATURE_CRC 0x00080000 /* CRC instructions. */
+#define AARCH64_FEATURE_LSE 0x00100000 /* LSE instructions. */
+#define AARCH64_FEATURE_PAN 0x00200000 /* PAN instructions. */
+#define AARCH64_FEATURE_LOR 0x00400000 /* LOR instructions. */
+#define AARCH64_FEATURE_RDMA 0x00800000 /* v8.1 SIMD instructions. */
+#define AARCH64_FEATURE_V8_1 0x01000000 /* v8.1 features. */
+#define AARCH64_FEATURE_F16 0x02000000 /* v8.2 FP16 instructions. */
+#define AARCH64_FEATURE_RAS 0x04000000 /* RAS Extensions. */
+#define AARCH64_FEATURE_PROFILE 0x08000000 /* Statistical Profiling. */
/* Architectures are the sum of the base and extensions. */
#define AARCH64_ARCH_V8 AARCH64_FEATURE (AARCH64_FEATURE_V8, \
AARCH64_FEATURE_FP \
| AARCH64_FEATURE_SIMD)
+#define AARCH64_ARCH_V8_1 AARCH64_FEATURE (AARCH64_FEATURE_V8, \
+ AARCH64_FEATURE_FP \
+ | AARCH64_FEATURE_SIMD \
+ | AARCH64_FEATURE_CRC \
+ | AARCH64_FEATURE_V8_1 \
+ | AARCH64_FEATURE_LSE \
+ | AARCH64_FEATURE_PAN \
+ | AARCH64_FEATURE_LOR \
+ | AARCH64_FEATURE_RDMA)
+#define AARCH64_ARCH_V8_2 AARCH64_FEATURE (AARCH64_FEATURE_V8, \
+ AARCH64_FEATURE_V8_2 \
+ | AARCH64_FEATURE_F16 \
+ | AARCH64_FEATURE_RAS \
+ | AARCH64_FEATURE_FP \
+ | AARCH64_FEATURE_SIMD \
+ | AARCH64_FEATURE_CRC \
+ | AARCH64_FEATURE_V8_1 \
+ | AARCH64_FEATURE_LSE \
+ | AARCH64_FEATURE_PAN \
+ | AARCH64_FEATURE_LOR \
+ | AARCH64_FEATURE_RDMA)
+
#define AARCH64_ARCH_NONE AARCH64_FEATURE (0, 0)
#define AARCH64_ANY AARCH64_FEATURE (-1, 0) /* Any basic core. */
/* CPU-specific features. */
typedef unsigned long aarch64_feature_set;
-#define AARCH64_CPU_HAS_FEATURE(CPU,FEAT) \
+#define AARCH64_CPU_HAS_ALL_FEATURES(CPU,FEAT) \
+ ((~(CPU) & (FEAT)) == 0)
+
+#define AARCH64_CPU_HAS_ANY_FEATURES(CPU,FEAT) \
(((CPU) & (FEAT)) != 0)
+#define AARCH64_CPU_HAS_FEATURE(CPU,FEAT) \
+ AARCH64_CPU_HAS_ALL_FEATURES (CPU,FEAT)
+
#define AARCH64_MERGE_FEATURE_SETS(TARG,F1,F2) \
do \
{ \
#define AARCH64_FEATURE(core,coproc) ((core) | (coproc))
-#define AARCH64_OPCODE_HAS_FEATURE(OPC,FEAT) \
- (((OPC) & (FEAT)) != 0)
-
enum aarch64_operand_class
{
AARCH64_OPND_CLASS_NIL,
AARCH64_OPND_Rd_SP, /* Integer Rd or SP. */
AARCH64_OPND_Rn_SP, /* Integer Rn or SP. */
+ AARCH64_OPND_PAIRREG, /* Paired register operand. */
AARCH64_OPND_Rm_EXT, /* Integer Rm extended. */
AARCH64_OPND_Rm_SFT, /* Integer Rm shifted. */
AARCH64_OPND_BARRIER, /* Barrier operand. */
AARCH64_OPND_BARRIER_ISB, /* Barrier operand for ISB. */
AARCH64_OPND_PRFOP, /* Prefetch operation. */
+ AARCH64_OPND_BARRIER_PSB, /* Barrier operand for PSB. */
};
/* Qualifier constrains an operand. It either specifies a variant of an
constraint qualifiers for immediate operands wherever possible. */
AARCH64_OPND_QLF_V_8B,
AARCH64_OPND_QLF_V_16B,
+ AARCH64_OPND_QLF_V_2H,
AARCH64_OPND_QLF_V_4H,
AARCH64_OPND_QLF_V_8H,
AARCH64_OPND_QLF_V_2S,
loadlit,
log_imm,
log_shift,
+ lse_atomic,
movewide,
pcreladdr,
ic_system,
OP_SBFX,
OP_SBFIZ,
OP_BFI,
+ OP_BFC, /* ARMv8.2. */
OP_UBFIZ,
OP_UXTB,
OP_UXTH,
/* Flags providing information about this instruction */
uint32_t flags;
+
+ /* If non-NULL, a function to verify that a given instruction is valid. */
+ bfd_boolean (* verifier) (const struct aarch64_opcode *, const aarch64_insn);
};
typedef struct aarch64_opcode aarch64_opcode;
#define F_N (1 << 23)
/* Opcode dependent field. */
#define F_OD(X) (((X) & 0x7) << 24)
-/* Next bit is 27. */
+/* Instruction has the field of 'sz'. */
+#define F_LSE_SZ (1 << 27)
+/* Next bit is 28. */
static inline bfd_boolean
alias_opcode_p (const aarch64_opcode *opcode)
static inline bfd_boolean
opcode_has_special_coder (const aarch64_opcode *opcode)
{
- return (opcode->flags & (F_SF | F_SIZEQ | F_FPTYPE | F_SSIZE | F_T
+ return (opcode->flags & (F_SF | F_LSE_SZ | F_SIZEQ | F_FPTYPE | F_SSIZE | F_T
| F_GPRSIZE_IN_Q | F_LDS_SIZE | F_MISC | F_N | F_COND)) ? TRUE
: FALSE;
}
extern const struct aarch64_name_value_pair aarch64_operand_modifiers [];
extern const struct aarch64_name_value_pair aarch64_barrier_options [16];
extern const struct aarch64_name_value_pair aarch64_prfops [32];
+extern const struct aarch64_name_value_pair aarch64_hint_options [];
typedef struct
{
extern const aarch64_sys_reg aarch64_sys_regs [];
extern const aarch64_sys_reg aarch64_pstatefields [];
extern bfd_boolean aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *);
+extern bfd_boolean aarch64_sys_reg_supported_p (const aarch64_feature_set,
+ const aarch64_sys_reg *);
+extern bfd_boolean aarch64_pstatefield_supported_p (const aarch64_feature_set,
+ const aarch64_sys_reg *);
typedef struct
{
- const char *template;
+ const char *name;
uint32_t value;
- int has_xt;
+ uint32_t flags ;
} aarch64_sys_ins_reg;
+extern bfd_boolean aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *);
+extern bfd_boolean
+aarch64_sys_ins_reg_supported_p (const aarch64_feature_set,
+ const aarch64_sys_ins_reg *);
+
extern const aarch64_sys_ins_reg aarch64_sys_regs_ic [];
extern const aarch64_sys_ins_reg aarch64_sys_regs_dc [];
extern const aarch64_sys_ins_reg aarch64_sys_regs_at [];
} reg;
struct
{
- unsigned regno : 5;
- unsigned index : 4;
+ unsigned int regno;
+ int64_t index;
} reglane;
/* e.g. LVn. */
struct
/* 1 if it is a list of reg element. */
unsigned has_index : 1;
/* Lane index; valid only when has_index is 1. */
- unsigned index : 4;
+ int64_t index;
} reglist;
/* e.g. immediate or pc relative address offset. */
struct
aarch64_insn pstatefield;
const aarch64_sys_ins_reg *sysins_op;
const struct aarch64_name_value_pair *barrier;
+ const struct aarch64_name_value_pair *hint_option;
const struct aarch64_name_value_pair *prfop;
};
extern int
aarch64_stack_pointer_p (const aarch64_opnd_info *);
-extern
-int aarch64_zero_register_p (const aarch64_opnd_info *);
+extern int
+aarch64_zero_register_p (const aarch64_opnd_info *);
+
+extern int
+aarch64_decode_insn (aarch64_insn, aarch64_inst *, bfd_boolean);
/* Given an operand qualifier, return the expected data element size
of a qualified operand. */
#define DEBUG_TRACE_IF(C, M, ...) ;
#endif /* DEBUG_AARCH64 */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* OPCODE_AARCH64_H */