+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * config/tc-aarch64.c (AARCH64_REG_TYPES,
+ get_reg_expected_msg, aarch64_addr_reg_parse, parse_address,
+ reg_names): Add capability registers.
+ (parse_operands): Identify capability register based address.
+ (aarch64_archs): Add morello.
+ (aarch64_features): Add a64c and c64.
+ * doc/c-aarch64.texi: Document -march flags.
+ * testsuite/gas/aarch64/morello_insn.d: New file
+ * testsuite/gas/aarch64/morello_insn-c64.d: New file
+ * testsuite/gas/aarch64/morello_insn.s: New file.
+
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
* config/tc-aarch64.c (output_operand_error_report): Account
BASIC_REG_TYPE(FP_S) /* s[0-31] */ \
BASIC_REG_TYPE(FP_D) /* d[0-31] */ \
BASIC_REG_TYPE(FP_Q) /* q[0-31] */ \
+ BASIC_REG_TYPE(CA_N) /* c[0-30] */ \
+ BASIC_REG_TYPE(CA_SP) /* csp */ \
+ BASIC_REG_TYPE(CA_Z) /* czr */ \
+ BASIC_REG_TYPE(CA_D) /* ddc */ \
BASIC_REG_TYPE(VN) /* v[0-31] */ \
BASIC_REG_TYPE(ZN) /* z[0-31] */ \
BASIC_REG_TYPE(PN) /* p[0-15] */ \
MULTI_REG_TYPE(R_N, REG_TYPE(R_32) | REG_TYPE(R_64) \
| REG_TYPE(SP_32) | REG_TYPE(SP_64) \
| REG_TYPE(Z_32) | REG_TYPE(Z_64)) \
+ /* Typecheck: any capability register (inc CSP) */ \
+ MULTI_REG_TYPE(CA_N_SP, REG_TYPE(CA_N) | REG_TYPE(CA_SP)) \
+ MULTI_REG_TYPE(CA_N_Z, REG_TYPE(CA_N) | REG_TYPE(CA_Z)) \
/* Pseudo type to mark the end of the enumerator sequence. */ \
BASIC_REG_TYPE(MAX)
case REG_TYPE_PN:
msg = N_("SVE predicate register expected");
break;
+ case REG_TYPE_CA_N:
+ msg = N_("Capability register C0 - C30 expected");
+ break;
+ case REG_TYPE_CA_SP:
+ msg = N_("Capability register CSP expected");
+ break;
+ case REG_TYPE_CA_N_SP:
+ msg = N_("Capability register C0 - C30 or CSP expected");
+ break;
+ case REG_TYPE_CA_Z:
+ msg = N_("Capability register CZR expected");
+ break;
default:
as_fatal (_("invalid register type %d"), reg_type);
}
str += 2;
break;
+ case REG_TYPE_CA_N:
+ case REG_TYPE_CA_SP:
+ *qualifier = AARCH64_OPND_QLF_CA;
+ break;
+
default:
return NULL;
}
parse_address (char **str, aarch64_opnd_info *operand)
{
aarch64_opnd_qualifier_t base_qualifier, offset_qualifier;
+
+ aarch64_reg_type base;
+
+ if (AARCH64_CPU_HAS_FEATURE (cpu_variant, AARCH64_FEATURE_C64))
+ base = REG_TYPE_CA_N_SP;
+ else
+ base = REG_TYPE_R64_SP;
+
return parse_address_main (str, operand, &base_qualifier, &offset_qualifier,
- REG_TYPE_R64_SP, REG_TYPE_R_Z, SHIFTED_NONE);
+ base, REG_TYPE_R_Z, SHIFTED_NONE);
}
/* Parse an address in which SVE vector registers and MUL VL are allowed.
/* Then retry, matching the specific syntax of these addresses. */
str = start;
po_char_or_fail ('[');
- po_reg_or_fail (REG_TYPE_R64_SP);
+ po_reg_or_fail (AARCH64_CPU_HAS_FEATURE (cpu_variant,
+ AARCH64_FEATURE_C64)
+ ? REG_TYPE_CA_N_SP : REG_TYPE_R64_SP);
+
/* Accept optional ", #0". */
if (operands[i] == AARCH64_OPND_ADDR_SIMPLE
&& skip_past_char (&str, ','))
REGDEF (wzr, 31, Z_32), REGDEF (WZR, 31, Z_32),
REGDEF (xzr, 31, Z_64), REGDEF (XZR, 31, Z_64),
+ /* Capability Registers. */
+ REGSET31 (c, CA_N), REGSET31 (C, CA_N),
+ REGDEF (csp, 31, CA_SP), REGDEF (CSP, 31, CA_SP),
+ REGDEF (czr, 31, CA_Z), REGDEF (CZR, 31, CA_Z),
+ REGDEF (ddc, 33, CA_D), REGDEF (DDC, 33, CA_D),
+ REGDEF_ALIAS (clr, 30, CA_N), REGDEF_ALIAS (CLR, 30, CA_N),
+
/* Floating-point single precision registers. */
REGSET (s, FP_S), REGSET (S, FP_S),
{"armv8.5-a", AARCH64_ARCH_V8_5},
{"armv8.6-a", AARCH64_ARCH_V8_6},
{"armv8-r", AARCH64_ARCH_V8_R},
+ {"morello", AARCH64_ARCH_MORELLO},
{NULL, AARCH64_ARCH_NONE}
};
AARCH64_FEATURE (AARCH64_FEATURE_SVE, 0)},
{"f64mm", AARCH64_FEATURE (AARCH64_FEATURE_F64MM, 0),
AARCH64_FEATURE (AARCH64_FEATURE_SVE, 0)},
+ {"a64c", AARCH64_FEATURE (AARCH64_FEATURE_A64C, 0),
+ AARCH64_ARCH_NONE},
+ {"c64", AARCH64_FEATURE (AARCH64_FEATURE_C64, 0),
+ AARCH64_FEATURE (AARCH64_FEATURE_A64C, 0)},
{NULL, AARCH64_ARCH_NONE, AARCH64_ARCH_NONE},
};
instruction which will not execute on the target architecture. The
following architecture names are recognized: @code{armv8-a},
@code{armv8.1-a}, @code{armv8.2-a}, @code{armv8.3-a}, @code{armv8.4-a}
-@code{armv8.5-a}, @code{armv8.6-a}, and @code{armv8-r}.
+@code{armv8.5-a}, @code{armv8.6-a}, @code{armv8-r}, @code{a64c},
+@code{c64} and @code{morello}.
If both @option{-mcpu} and @option{-march} are specified, the
assembler will use the setting for @option{-mcpu}. If neither are
--- /dev/null
+#as: -march=morello+c64
+#objdump: -dr
+#source: morello_insn.s
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <.text>:
+.*: d503201f nop
--- /dev/null
+#as: -march=morello
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <.text>:
+.*: d503201f nop
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * opcode/aarch64.h (AARCH64_FEATURE_A64C,
+ AARCH64_FEATURE_C64): New feature macros.
+ (AARCH64_ARCH_MORELLO): New architecture macro.
+ (aarch64_operand_class): Add AARCH64_OPND_CLASS_CAP_REG.
+ (aarch64_opnd): New capability operands.
+ (aarch64_opnd_qualifier): New capability qualifier.
+ (aarch64_insn_class): Add a64c instruction class.
+
2020-10-16 Nelson Chu <nelson.chu@sifive.com>
* elf/riscv.h: Add R_RISCV_IRELATIVE to 58.
#define AARCH64_FEATURE_F32MM (1ULL << 53)
#define AARCH64_FEATURE_F64MM (1ULL << 54)
+/* Capability extensions. */
+#define AARCH64_FEATURE_A64C (1ULL << 56)
+#define AARCH64_FEATURE_C64 (1ULL << 57)
+
/* Crypto instructions are the combination of AES and SHA2. */
#define AARCH64_FEATURE_CRYPTO (AARCH64_FEATURE_SHA2 | AARCH64_FEATURE_AES)
AARCH64_FEATURE_V8_R) \
& ~(AARCH64_FEATURE_V8_A | AARCH64_FEATURE_LOR))
+#define AARCH64_ARCH_MORELLO AARCH64_FEATURE (AARCH64_ARCH_V8_2, \
+ AARCH64_FEATURE_A64C \
+ | AARCH64_FEATURE_F16_FML \
+ | AARCH64_FEATURE_DOTPROD \
+ | AARCH64_FEATURE_RCPC \
+ | AARCH64_FEATURE_SSBS)
+
#define AARCH64_ARCH_NONE AARCH64_FEATURE (0, 0)
#define AARCH64_ANY AARCH64_FEATURE (-1, 0) /* Any basic core. */
AARCH64_OPND_CLASS_IMMEDIATE,
AARCH64_OPND_CLASS_SYSTEM,
AARCH64_OPND_CLASS_COND,
+ AARCH64_OPND_CLASS_CAP_REG,
};
/* Operand code that helps both parsing and coding.
AARCH64_OPND_SVE_ZtxN, /* SVE vector register list in Zt. */
AARCH64_OPND_TME_UIMM16, /* TME unsigned 16-bit immediate. */
AARCH64_OPND_SM3_IMM2, /* SM3 encodes lane in bits [13, 14]. */
+
+ AARCH64_OPND_Cad, /* A capability register as destination. */
+ AARCH64_OPND_Cam, /* Capability register as source. */
+ AARCH64_OPND_Can, /* Capability register as source. */
+ AARCH64_OPND_Cas, /* A capability register. */
+ AARCH64_OPND_Cat, /* Capability register destination in load
+ store instructions. */
+ AARCH64_OPND_Cat2, /* Capability register destination 2 in load
+ store instructions. */
+ AARCH64_OPND_Cad_SP, /* Capability register or Cap SP as
+ destination. */
+ AARCH64_OPND_Can_SP, /* Capability register or Cap SP as source. */
};
/* Qualifier constrains an operand. It either specifies a variant of an
like in stg, st2g, etc. */
AARCH64_OPND_QLF_imm_tag,
+ /* Capability Registers. */
+ AARCH64_OPND_QLF_CA,
+
/* Constraint on value. */
AARCH64_OPND_QLF_CR, /* CRn, CRm. */
AARCH64_OPND_QLF_imm_0_7,
cryptosm4,
dotproduct,
bfloat16,
+ a64c,
};
/* Opcode enumerators. */
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
+ * aarch64-opc.c (fields): New capability register fields.
+ (aarch64_opnd_qualifiers): Capability operand qualifiers.
+ (int_reg): Add capability register bank.
+ (get_int_reg_name): Adjust for capability registers.
+ (get_cap_reg_name): New function.
+ (aarch64_print_operand): Support printing capability operands.
+ * aarch64-opc.h (aarch64_field_kind): Add capability operand
+ fields.
+ (OPD_F_MAYBE_CSP): New macro.
+ (operand_maybe_cap_stack_pointer): New function.
+ * aarch64-tbl.h (QL2_A64C_CA_CA, A64C, A64C_INSN): New macros.
+ (aarch64_feature_a64c): New feature set.
+
2020-10-16 Lili Cui <lili.cui@intel.com>
* i386-opc.tbl: Rename CpuVEX_PREFIX to PseudoVexPrefix
{ 12, 1 }, /* rotate3: FCADD immediate rotate. */
{ 12, 2 }, /* SM3: Indexed element SM3 2 bits index immediate. */
{ 22, 1 }, /* sz: 1-bit element size select. */
+ { 0, 5 }, /* Cad: Capability Destination register. */
+ { 5, 5 }, /* Can, Capability source register. */
+ { 16, 5 }, /* Cam, Capability register in load / store and other cap
+ instructions. */
+ { 16, 5 }, /* Cas, Capability register in some memory / load store
+ instructions. */
+ { 0, 5 }, /* Cat, Capability register in load store pair type
+ instructions. */
+ { 10, 5 }, /* Cat2, Capability register in destination for load store pair
+ type instructions. */
};
enum aarch64_operand_class
/* Qualifier for scaled immediate for Tag granule (stg,st2g,etc). */
{16, 0, 0, "tag", OQK_OPD_VARIANT},
+ {16, 1, 0, "c", OQK_OPD_VARIANT},
/* Qualifiers constraining the value range.
First 3 fields:
R (24), R (25), R (26), R (27), R (28), R (29), R (30), FOR31 }
/* [0][0] 32-bit integer regs with sp Wn
[0][1] 64-bit integer regs with sp Xn sf=1
+ [0][2] 129-bit cap regs with sp Cn
[1][0] 32-bit integer regs with #0 Wn
- [1][1] 64-bit integer regs with #0 Xn sf=1 */
-static const char *int_reg[2][2][32] = {
+ [1][1] 64-bit integer regs with #0 Xn sf=1
+ [1][2] 129-bit cap regs with #0 Cn */
+static const char *int_reg[2][3][32] = {
#define R32(X) "w" #X
#define R64(X) "x" #X
- { BANK (R32, "wsp"), BANK (R64, "sp") },
- { BANK (R32, "wzr"), BANK (R64, "xzr") }
+#define CAP(X) "c" #X
+ { BANK (R32, "wsp"), BANK (R64, "sp"), BANK (CAP, "csp") },
+ { BANK (R32, "wzr"), BANK (R64, "xzr"), BANK (CAP, "czr") }
+#undef CAP
#undef R64
#undef R32
};
get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
{
const int has_zr = sp_reg_p ? 0 : 1;
- const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
- return int_reg[has_zr][is_64][regno];
+ const int bank = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
+ return int_reg[has_zr][bank][regno];
}
-/* Like get_int_reg_name, but IS_64 is always 1. */
+/* Like get_int_reg_name, but BANK is always 1. */
static inline const char *
get_64bit_int_reg_name (int regno, int sp_reg_p)
return int_reg[has_zr][1][regno];
}
+/* Like get_int_reg_name, but BANK is always 2. */
+static inline const char *
+get_cap_reg_name (int regno, int sp_reg_p)
+{
+ const int has_zr = sp_reg_p ? 0 : 1;
+ return int_reg[has_zr][2][regno];
+}
+
/* Get the name of the integer offset register in OPND, using the shift type
to decide whether it's a word or doubleword. */
snprintf (buf, size, "%s", opnd->hint_option->name);
break;
+ case AARCH64_OPND_Cad_SP:
+ case AARCH64_OPND_Can_SP:
+ snprintf (buf, size, "%s", get_cap_reg_name (opnd->reg.regno, 1));
+ break;
+
+ case AARCH64_OPND_Cat:
+ case AARCH64_OPND_Cat2:
+ case AARCH64_OPND_Can:
+ case AARCH64_OPND_Cam:
+ case AARCH64_OPND_Cad:
+ case AARCH64_OPND_Cas:
+ snprintf (buf, size, "%s", get_cap_reg_name (opnd->reg.regno, 0));
+ break;
+
default:
assert (0);
}
FLD_rotate2,
FLD_rotate3,
FLD_SM3_imm2,
- FLD_sz
+ FLD_sz,
+ FLD_Cad,
+ FLD_Can,
+ FLD_Cam,
+ FLD_Cas,
+ FLD_Cat,
+ FLD_Cat2,
};
/* Field description. */
value by 2 to get the value
of an immediate operand. */
#define OPD_F_MAYBE_SP 0x00000010 /* May potentially be SP. */
+#define OPD_F_MAYBE_CSP 0x00000020 /* May potentially be CSP. */
#define OPD_F_OD_MASK 0x000000e0 /* Operand-dependent data. */
#define OPD_F_OD_LSB 5
#define OPD_F_NO_ZR 0x00000100 /* ZR index not allowed. */
return (operand->flags & OPD_F_SHIFT_BY_4) ? TRUE : FALSE;
}
+static inline bfd_boolean
+operand_maybe_cap_stack_pointer (const aarch64_operand *operand)
+{
+ return (operand->flags & OPD_F_MAYBE_CSP) ? TRUE : FALSE;
+}
+
static inline bfd_boolean
operand_maybe_stack_pointer (const aarch64_operand *operand)
{
{ \
QLF3(V_4S, V_8H, S_H), \
}
+
+#define QL2_A64C_CA_CA \
+{ \
+ QLF2(CA, CA), \
+}
\f
/* Opcode table. */
| AARCH64_FEATURE_SVE, 0);
static const aarch64_feature_set aarch64_feature_v8_r =
AARCH64_FEATURE (AARCH64_FEATURE_V8_R, 0);
+static const aarch64_feature_set aarch64_feature_a64c =
+ AARCH64_FEATURE (AARCH64_FEATURE_A64C, 0);
#define CORE &aarch64_feature_v8
#define F64MM_SVE &aarch64_feature_f64mm_sve
#define I8MM &aarch64_feature_i8mm
#define ARMV8_R &aarch64_feature_v8_r
+#define A64C &aarch64_feature_a64c
#define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
{ NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL }
{ NAME, OPCODE, MASK, CLASS, 0, F32MM_SVE, OPS, QUALS, FLAGS, CONSTRAINTS, TIED, NULL }
#define V8_R_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
{ NAME, OPCODE, MASK, CLASS, 0, ARMV8_R, OPS, QUALS, FLAGS, 0, 0, NULL }
+#define A64C_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
+ { NAME, OPCODE, MASK, CLASS, OP, A64C, OPS, QUALS, FLAGS, 0, 0, NULL }
struct aarch64_opcode aarch64_opcode_table[] =
{