2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+ * config/tc-aarch64.c (parse_enum_string): New function.
+ (po_enum_or_fail): New macro.
+ (parse_operands): Handle AARCH64_OPND_SVE_PATTERN and
+ AARCH64_OPND_SVE_PRFOP.
+
+2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
* config/tc-aarch64.c (vector_el_type): Add NT_zero and NT_merge.
(parse_vector_type_for_operand): Assert that the skipped character
is a '.'.
/* Miscellaneous. */
+/* Parse a symbolic operand such as "pow2" at *STR. ARRAY is an array
+ of SIZE tokens in which index I gives the token for field value I,
+ or is null if field value I is invalid. REG_TYPE says which register
+ names should be treated as registers rather than as symbolic immediates.
+
+ Return true on success, moving *STR past the operand and storing the
+ field value in *VAL. */
+
+static int
+parse_enum_string (char **str, int64_t *val, const char *const *array,
+ size_t size, aarch64_reg_type reg_type)
+{
+ expressionS exp;
+ char *p, *q;
+ size_t i;
+
+ /* Match C-like tokens. */
+ p = q = *str;
+ while (ISALNUM (*q))
+ q++;
+
+ for (i = 0; i < size; ++i)
+ if (array[i]
+ && strncasecmp (array[i], p, q - p) == 0
+ && array[i][q - p] == 0)
+ {
+ *val = i;
+ *str = q;
+ return TRUE;
+ }
+
+ if (!parse_immediate_expression (&p, &exp, reg_type))
+ return FALSE;
+
+ if (exp.X_op == O_constant
+ && (uint64_t) exp.X_add_number < size)
+ {
+ *val = exp.X_add_number;
+ *str = p;
+ return TRUE;
+ }
+
+ /* Use the default error for this operand. */
+ return FALSE;
+}
+
/* Parse an option for a preload instruction. Returns the encoding for the
option, or PARSE_FAIL. */
} \
} while (0)
+#define po_enum_or_fail(array) do { \
+ if (!parse_enum_string (&str, &val, array, \
+ ARRAY_SIZE (array), imm_reg_type)) \
+ goto failure; \
+ } while (0)
+
#define po_misc_or_fail(expr) do { \
if (!expr) \
goto failure; \
case AARCH64_OPND_WIDTH:
case AARCH64_OPND_UIMM7:
case AARCH64_OPND_NZCV:
+ case AARCH64_OPND_SVE_PATTERN:
+ case AARCH64_OPND_SVE_PRFOP:
operand->imm.value = default_value;
break;
info->imm.value = val;
break;
+ case AARCH64_OPND_SVE_PATTERN:
+ po_enum_or_fail (aarch64_sve_pattern_array);
+ info->imm.value = val;
+ break;
+
+ case AARCH64_OPND_SVE_PRFOP:
+ po_enum_or_fail (aarch64_sve_prfop_array);
+ info->imm.value = val;
+ break;
+
case AARCH64_OPND_UIMM7:
po_imm_or_fail (0, 127);
info->imm.value = val;
2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+ * opcode/aarch64.h (AARCH64_OPND_SVE_PATTERN): New aarch64_opnd.
+ (AARCH64_OPND_SVE_PRFOP): Likewise.
+ (aarch64_sve_pattern_array): Declare.
+ (aarch64_sve_prfop_array): Likewise.
+
+2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
* opcode/aarch64.h (AARCH64_OPND_QLF_P_Z): New aarch64_opnd_qualifier.
(AARCH64_OPND_QLF_P_M): Likewise.
AARCH64_OPND_PRFOP, /* Prefetch operation. */
AARCH64_OPND_BARRIER_PSB, /* Barrier operand for PSB. */
+ AARCH64_OPND_SVE_PATTERN, /* SVE vector pattern enumeration. */
+ AARCH64_OPND_SVE_PRFOP, /* SVE prefetch operation. */
AARCH64_OPND_SVE_Pd, /* SVE p0-p15 in Pd. */
AARCH64_OPND_SVE_Pg3, /* SVE p0-p7 in Pg. */
AARCH64_OPND_SVE_Pg4_5, /* SVE p0-p15 in Pg, bits [8,5]. */
#define DEBUG_TRACE_IF(C, M, ...) ;
#endif /* DEBUG_AARCH64 */
+extern const char *const aarch64_sve_pattern_array[32];
+extern const char *const aarch64_sve_prfop_array[16];
+
#ifdef __cplusplus
}
#endif
2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+ * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for
+ AARCH64_OPND_SVE_PATTERN and AARCH64_OPND_SVE_PRFOP.
+ * aarch64-opc.h (FLD_SVE_pattern): New aarch64_field_kind.
+ (FLD_SVE_prfop): Likewise.
+ * aarch64-opc.c: Include libiberty.h.
+ (aarch64_sve_pattern_array): New variable.
+ (aarch64_sve_prfop_array): Likewise.
+ (fields): Add entries for FLD_SVE_pattern and FLD_SVE_prfop.
+ (aarch64_print_operand): Handle AARCH64_OPND_SVE_PATTERN and
+ AARCH64_OPND_SVE_PRFOP.
+ * aarch64-asm-2.c: Regenerate.
+ * aarch64-dis-2.c: Likewise.
+ * aarch64-opc-2.c: Likewise.
+
+2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
* aarch64-opc.c (aarch64_opnd_qualifiers): Add entries for
AARCH64_OPND_QLF_P_[ZM].
(aarch64_print_operand): Print /z and /m where appropriate.
case 27:
case 35:
case 36:
- case 89:
- case 90:
case 91:
case 92:
case 93:
case 100:
case 101:
case 102:
- case 105:
+ case 103:
+ case 104:
+ case 107:
return aarch64_ins_regno (self, info, code, inst);
case 12:
return aarch64_ins_reg_extended (self, info, code, inst);
case 68:
case 69:
case 70:
+ case 89:
+ case 90:
return aarch64_ins_imm (self, info, code, inst);
case 38:
case 39:
return aarch64_ins_prfop (self, info, code, inst);
case 88:
return aarch64_ins_hint (self, info, code, inst);
- case 103:
+ case 105:
return aarch64_ins_sve_index (self, info, code, inst);
- case 104:
case 106:
+ case 108:
return aarch64_ins_sve_reglist (self, info, code, inst);
default: assert (0); abort ();
}
case 27:
case 35:
case 36:
- case 89:
- case 90:
case 91:
case 92:
case 93:
case 100:
case 101:
case 102:
- case 105:
+ case 103:
+ case 104:
+ case 107:
return aarch64_ext_regno (self, info, code, inst);
case 8:
return aarch64_ext_regrt_sysins (self, info, code, inst);
case 68:
case 69:
case 70:
+ case 89:
+ case 90:
return aarch64_ext_imm (self, info, code, inst);
case 38:
case 39:
return aarch64_ext_prfop (self, info, code, inst);
case 88:
return aarch64_ext_hint (self, info, code, inst);
- case 103:
+ case 105:
return aarch64_ext_sve_index (self, info, code, inst);
- case 104:
case 106:
+ case 108:
return aarch64_ext_sve_reglist (self, info, code, inst);
default: assert (0); abort ();
}
{AARCH64_OPND_CLASS_SYSTEM, "BARRIER_ISB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the ISB option name SY or an optional 4-bit unsigned immediate"},
{AARCH64_OPND_CLASS_SYSTEM, "PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a prefetch operation specifier"},
{AARCH64_OPND_CLASS_SYSTEM, "BARRIER_PSB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the PSB option name CSYNC"},
+ {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PATTERN", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_pattern}, "an enumeration value such as POW2"},
+ {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_prfop}, "an enumeration value such as PLDL1KEEP"},
{AARCH64_OPND_CLASS_PRED_REG, "SVE_Pd", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pd}, "an SVE predicate register"},
{AARCH64_OPND_CLASS_PRED_REG, "SVE_Pg3", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pg3}, "an SVE predicate register"},
{AARCH64_OPND_CLASS_PRED_REG, "SVE_Pg4_5", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pg4_5}, "an SVE predicate register"},
#include <inttypes.h>
#include "opintl.h"
+#include "libiberty.h"
#include "aarch64-opc.h"
int debug_dump = FALSE;
#endif /* DEBUG_AARCH64 */
+/* The enumeration strings associated with each value of a 5-bit SVE
+ pattern operand. A null entry indicates a reserved meaning. */
+const char *const aarch64_sve_pattern_array[32] = {
+ /* 0-7. */
+ "pow2",
+ "vl1",
+ "vl2",
+ "vl3",
+ "vl4",
+ "vl5",
+ "vl6",
+ "vl7",
+ /* 8-15. */
+ "vl8",
+ "vl16",
+ "vl32",
+ "vl64",
+ "vl128",
+ "vl256",
+ 0,
+ 0,
+ /* 16-23. */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ /* 24-31. */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ "mul4",
+ "mul3",
+ "all"
+};
+
+/* The enumeration strings associated with each value of a 4-bit SVE
+ prefetch operand. A null entry indicates a reserved meaning. */
+const char *const aarch64_sve_prfop_array[16] = {
+ /* 0-7. */
+ "pldl1keep",
+ "pldl1strm",
+ "pldl2keep",
+ "pldl2strm",
+ "pldl3keep",
+ "pldl3strm",
+ 0,
+ 0,
+ /* 8-15. */
+ "pstl1keep",
+ "pstl1strm",
+ "pstl2keep",
+ "pstl2strm",
+ "pstl3keep",
+ "pstl3strm",
+ 0,
+ 0
+};
+
/* Helper functions to determine which operand to be used to encode/decode
the size:Q fields for AdvSIMD instructions. */
{ 16, 5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
{ 5, 5 }, /* SVE_Zn: SVE vector register, bits [9,5]. */
{ 0, 5 }, /* SVE_Zt: SVE vector register, bits [4,0]. */
+ { 5, 5 }, /* SVE_pattern: vector pattern enumeration. */
+ { 0, 4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD]. */
{ 22, 2 }, /* SVE_tszh: triangular size select high, bits [23,22]. */
};
const char *name = NULL;
const aarch64_opnd_info *opnd = opnds + idx;
enum aarch64_modifier_kind kind;
- uint64_t addr;
+ uint64_t addr, enum_value;
buf[0] = '\0';
if (pcrel_p)
snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
break;
+ case AARCH64_OPND_SVE_PATTERN:
+ if (optional_operand_p (opcode, idx)
+ && opnd->imm.value == get_optional_operand_default_value (opcode))
+ break;
+ enum_value = opnd->imm.value;
+ assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
+ if (aarch64_sve_pattern_array[enum_value])
+ snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
+ else
+ snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+ break;
+
+ case AARCH64_OPND_SVE_PRFOP:
+ enum_value = opnd->imm.value;
+ assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
+ if (aarch64_sve_prfop_array[enum_value])
+ snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
+ else
+ snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+ break;
+
case AARCH64_OPND_IMM_MOV:
switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
{
FLD_SVE_Zm_16,
FLD_SVE_Zn,
FLD_SVE_Zt,
+ FLD_SVE_pattern,
+ FLD_SVE_prfop,
FLD_SVE_tszh,
};
"a prefetch operation specifier") \
Y (SYSTEM, hint, "BARRIER_PSB", 0, F (), \
"the PSB option name CSYNC") \
+ Y(IMMEDIATE, imm, "SVE_PATTERN", 0, F(FLD_SVE_pattern), \
+ "an enumeration value such as POW2") \
+ Y(IMMEDIATE, imm, "SVE_PRFOP", 0, F(FLD_SVE_prfop), \
+ "an enumeration value such as PLDL1KEEP") \
Y(PRED_REG, regno, "SVE_Pd", 0, F(FLD_SVE_Pd), \
"an SVE predicate register") \
Y(PRED_REG, regno, "SVE_Pg3", 0, F(FLD_SVE_Pg3), \