[AArch64][SVE 22/32] Add qualifiers for merging and zeroing predication

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Thu Aug 25 14:08:00 GMT 2016


On 23/08/16 10:19, Richard Sandiford wrote:
> This patch adds qualifiers to represent /z and /m suffixes on
> predicate registers.
> 
> OK to install?
> 
> Thanks,
> Richard
> 
> 
> 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.
> 

OK.

R.


> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index 53e602f..ed4933b 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.  */
> @@ -780,6 +782,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))
> @@ -846,6 +849,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
> @@ -890,10 +925,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;
> @@ -4706,6 +4749,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/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/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));
> 



More information about the Binutils mailing list