aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2016-09-21 16:54:30 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2016-09-21 16:54:30 +0100
commitd50c751e00b5336b4604b92271ab84615fdb0d27 (patch)
treea03ccbb9798577e978217f1c9639300afb0fec2a
parentf11ad6bc0fc44b94c6970115bb6984b497b967e7 (diff)
downloadgdb-d50c751e00b5336b4604b92271ab84615fdb0d27.zip
gdb-d50c751e00b5336b4604b92271ab84615fdb0d27.tar.gz
gdb-d50c751e00b5336b4604b92271ab84615fdb0d27.tar.bz2
[AArch64][SVE 22/32] Add qualifiers for merging and zeroing predication
This patch adds qualifiers to represent /z and /m suffixes on predicate registers. include/ * opcode/aarch64.h (AARCH64_OPND_QLF_P_Z): New aarch64_opnd_qualifier. (AARCH64_OPND_QLF_P_M): Likewise. opcodes/ * aarch64-opc.c (aarch64_opnd_qualifiers): Add entries for AARCH64_OPND_QLF_P_[ZM]. (aarch64_print_operand): Print /z and /m where appropriate. gas/ * 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 '.'. (parse_predication_for_operand): New function. (parse_typed_reg): Parse /z and /m suffixes for predicate registers. (vectype_to_qualifier): Handle NT_zero and NT_merge.
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-aarch64.c56
-rw-r--r--include/ChangeLog5
-rw-r--r--include/opcode/aarch64.h3
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/aarch64-opc.c7
6 files changed, 82 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index ac1bb54..589b2cf 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,14 @@
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 '.'.
+ (parse_predication_for_operand): New function.
+ (parse_typed_reg): Parse /z and /m suffixes for predicate registers.
+ (vectype_to_qualifier): Handle NT_zero and NT_merge.
+
+2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
* config/tc-aarch64.c (NTA_HASVARWIDTH): New macro.
(AARCH64_REG_TYPES): Add ZN and PN.
(get_reg_expected_msg): Handle them.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index be88d29..f877262 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -83,7 +83,9 @@ enum vector_el_type
NT_h,
NT_s,
NT_d,
- NT_q
+ NT_q,
+ NT_zero,
+ NT_merge
};
/* Bits for DEFINED field in vector_type_el. */
@@ -750,6 +752,7 @@ parse_vector_type_for_operand (aarch64_reg_type reg_type,
enum vector_el_type type;
/* skip '.' */
+ gas_assert (*ptr == '.');
ptr++;
if (reg_type == REG_TYPE_ZN || reg_type == REG_TYPE_PN || !ISDIGIT (*ptr))
@@ -816,6 +819,38 @@ elt_size:
return TRUE;
}
+/* *STR contains an SVE zero/merge predication suffix. Parse it into
+ *PARSED_TYPE and point *STR at the end of the suffix. */
+
+static bfd_boolean
+parse_predication_for_operand (struct vector_type_el *parsed_type, char **str)
+{
+ char *ptr = *str;
+
+ /* Skip '/'. */
+ gas_assert (*ptr == '/');
+ ptr++;
+ switch (TOLOWER (*ptr))
+ {
+ case 'z':
+ parsed_type->type = NT_zero;
+ break;
+ case 'm':
+ parsed_type->type = NT_merge;
+ break;
+ default:
+ if (*ptr != '\0' && *ptr != ',')
+ first_error_fmt (_("unexpected character `%c' in predication type"),
+ *ptr);
+ else
+ first_error (_("missing predication type"));
+ return FALSE;
+ }
+ parsed_type->width = 0;
+ *str = ptr + 1;
+ return TRUE;
+}
+
/* Parse a register of the type TYPE.
Return PARSE_FAIL if the string pointed by *CCP is not a valid register
@@ -860,10 +895,18 @@ parse_typed_reg (char **ccp, aarch64_reg_type type, aarch64_reg_type *rtype,
type = reg->type;
if ((type == REG_TYPE_VN || type == REG_TYPE_ZN || type == REG_TYPE_PN)
- && *str == '.')
+ && (*str == '.' || (type == REG_TYPE_PN && *str == '/')))
{
- if (!parse_vector_type_for_operand (type, &parsetype, &str))
- return PARSE_FAIL;
+ if (*str == '.')
+ {
+ if (!parse_vector_type_for_operand (type, &parsetype, &str))
+ return PARSE_FAIL;
+ }
+ else
+ {
+ if (!parse_predication_for_operand (&parsetype, &str))
+ return PARSE_FAIL;
+ }
/* Register if of the form Vn.[bhsdq]. */
is_typed_vecreg = TRUE;
@@ -4655,6 +4698,11 @@ vectype_to_qualifier (const struct vector_type_el *vectype)
if (!vectype->defined || vectype->type == NT_invtype)
goto vectype_conversion_fail;
+ if (vectype->type == NT_zero)
+ return AARCH64_OPND_QLF_P_Z;
+ if (vectype->type == NT_merge)
+ return AARCH64_OPND_QLF_P_M;
+
gas_assert (vectype->type >= NT_b && vectype->type <= NT_q);
if (vectype->defined & (NTA_HASINDEX | NTA_HASVARWIDTH))
diff --git a/include/ChangeLog b/include/ChangeLog
index 53d0ba0..175d1d5 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,5 +1,10 @@
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.
+
+2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
* opcode/aarch64.h (AARCH64_OPND_CLASS_SVE_REG): New
aarch64_operand_class.
(AARCH64_OPND_CLASS_PRED_REG): Likewise.
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index b0eb617..8eae0b9 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -315,6 +315,9 @@ enum aarch64_opnd_qualifier
AARCH64_OPND_QLF_V_2D,
AARCH64_OPND_QLF_V_1Q,
+ AARCH64_OPND_QLF_P_Z,
+ AARCH64_OPND_QLF_P_M,
+
/* Constraint on value. */
AARCH64_OPND_QLF_imm_0_7,
AARCH64_OPND_QLF_imm_0_15,
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 463837b..5d2ddb1 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,11 @@
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.
+
+2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
+
* aarch64-tbl.h (AARCH64_OPERANDS): Add entries for new SVE operands.
* aarch64-opc.h (FLD_SVE_Pd, FLD_SVE_Pg3, FLD_SVE_Pg4_5)
(FLD_SVE_Pg4_10, FLD_SVE_Pg4_16, FLD_SVE_Pm, FLD_SVE_Pn, FLD_SVE_Pt)
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 56a0169..41c058f 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -603,6 +603,9 @@ struct operand_qualifier_data aarch64_opnd_qualifiers[] =
{8, 2, 0x7, "2d", OQK_OPD_VARIANT},
{16, 1, 0x8, "1q", OQK_OPD_VARIANT},
+ {0, 0, 0, "z", OQK_OPD_VARIANT},
+ {0, 0, 0, "m", OQK_OPD_VARIANT},
+
/* Qualifiers constraining the value range.
First 3 fields:
Lower bound, higher bound, unused. */
@@ -2623,6 +2626,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SVE_Pt:
if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
snprintf (buf, size, "p%d", opnd->reg.regno);
+ else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
+ || opnd->qualifier == AARCH64_OPND_QLF_P_M)
+ snprintf (buf, size, "p%d/%s", opnd->reg.regno,
+ aarch64_get_qualifier_name (opnd->qualifier));
else
snprintf (buf, size, "p%d.%s", opnd->reg.regno,
aarch64_get_qualifier_name (opnd->qualifier));