[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.
This commit is contained in:
parent
f11ad6bc0f
commit
d50c751e00
6 changed files with 82 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
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>
|
2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
|
||||||
|
|
||||||
* config/tc-aarch64.c (NTA_HASVARWIDTH): New macro.
|
* config/tc-aarch64.c (NTA_HASVARWIDTH): New macro.
|
||||||
|
|
|
@ -83,7 +83,9 @@ enum vector_el_type
|
||||||
NT_h,
|
NT_h,
|
||||||
NT_s,
|
NT_s,
|
||||||
NT_d,
|
NT_d,
|
||||||
NT_q
|
NT_q,
|
||||||
|
NT_zero,
|
||||||
|
NT_merge
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Bits for DEFINED field in vector_type_el. */
|
/* 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;
|
enum vector_el_type type;
|
||||||
|
|
||||||
/* skip '.' */
|
/* skip '.' */
|
||||||
|
gas_assert (*ptr == '.');
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
if (reg_type == REG_TYPE_ZN || reg_type == REG_TYPE_PN || !ISDIGIT (*ptr))
|
if (reg_type == REG_TYPE_ZN || reg_type == REG_TYPE_PN || !ISDIGIT (*ptr))
|
||||||
|
@ -816,6 +819,38 @@ elt_size:
|
||||||
return TRUE;
|
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.
|
/* Parse a register of the type TYPE.
|
||||||
|
|
||||||
Return PARSE_FAIL if the string pointed by *CCP is not a valid register
|
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;
|
type = reg->type;
|
||||||
|
|
||||||
if ((type == REG_TYPE_VN || type == REG_TYPE_ZN || type == REG_TYPE_PN)
|
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))
|
if (*str == '.')
|
||||||
return PARSE_FAIL;
|
{
|
||||||
|
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]. */
|
/* Register if of the form Vn.[bhsdq]. */
|
||||||
is_typed_vecreg = TRUE;
|
is_typed_vecreg = TRUE;
|
||||||
|
@ -4655,6 +4698,11 @@ vectype_to_qualifier (const struct vector_type_el *vectype)
|
||||||
if (!vectype->defined || vectype->type == NT_invtype)
|
if (!vectype->defined || vectype->type == NT_invtype)
|
||||||
goto vectype_conversion_fail;
|
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);
|
gas_assert (vectype->type >= NT_b && vectype->type <= NT_q);
|
||||||
|
|
||||||
if (vectype->defined & (NTA_HASINDEX | NTA_HASVARWIDTH))
|
if (vectype->defined & (NTA_HASINDEX | NTA_HASVARWIDTH))
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
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>
|
2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
|
||||||
|
|
||||||
* opcode/aarch64.h (AARCH64_OPND_CLASS_SVE_REG): New
|
* opcode/aarch64.h (AARCH64_OPND_CLASS_SVE_REG): New
|
||||||
|
|
|
@ -315,6 +315,9 @@ enum aarch64_opnd_qualifier
|
||||||
AARCH64_OPND_QLF_V_2D,
|
AARCH64_OPND_QLF_V_2D,
|
||||||
AARCH64_OPND_QLF_V_1Q,
|
AARCH64_OPND_QLF_V_1Q,
|
||||||
|
|
||||||
|
AARCH64_OPND_QLF_P_Z,
|
||||||
|
AARCH64_OPND_QLF_P_M,
|
||||||
|
|
||||||
/* Constraint on value. */
|
/* Constraint on value. */
|
||||||
AARCH64_OPND_QLF_imm_0_7,
|
AARCH64_OPND_QLF_imm_0_7,
|
||||||
AARCH64_OPND_QLF_imm_0_15,
|
AARCH64_OPND_QLF_imm_0_15,
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
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>
|
2016-09-21 Richard Sandiford <richard.sandiford@arm.com>
|
||||||
|
|
||||||
* aarch64-tbl.h (AARCH64_OPERANDS): Add entries for new SVE operands.
|
* aarch64-tbl.h (AARCH64_OPERANDS): Add entries for new SVE operands.
|
||||||
|
|
|
@ -603,6 +603,9 @@ struct operand_qualifier_data aarch64_opnd_qualifiers[] =
|
||||||
{8, 2, 0x7, "2d", OQK_OPD_VARIANT},
|
{8, 2, 0x7, "2d", OQK_OPD_VARIANT},
|
||||||
{16, 1, 0x8, "1q", 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.
|
/* Qualifiers constraining the value range.
|
||||||
First 3 fields:
|
First 3 fields:
|
||||||
Lower bound, higher bound, unused. */
|
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:
|
case AARCH64_OPND_SVE_Pt:
|
||||||
if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
|
if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
|
||||||
snprintf (buf, size, "p%d", opnd->reg.regno);
|
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
|
else
|
||||||
snprintf (buf, size, "p%d.%s", opnd->reg.regno,
|
snprintf (buf, size, "p%d.%s", opnd->reg.regno,
|
||||||
aarch64_get_qualifier_name (opnd->qualifier));
|
aarch64_get_qualifier_name (opnd->qualifier));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue