This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [AArch64][SVE 23/32] Add SVE pattern and prfop operands


On 23/08/16 10:19, Richard Sandiford wrote:
> The SVE instructions have two enumerated operands: one to select a
> vector pattern and another to select a prefetch operation.  The latter
> is a cut-down version of the base AArch64 prefetch operation.
> 
> Both types of operand can also be specified as raw enum values such as #31.
> Reserved values can only be specified this way.
> 
> If it hadn't been for the pattern operand, I would have been tempted
> to use the existing parsing for prefetch operations and add extra
> checks for SVE.  However, since the patterns needed new enum parsing
> code anyway, it seeemed cleaner to reuse it for the prefetches too.
> 
> Because of the small number of enum values, I don't think we'd gain
> anything by using hash tables.
> 
> OK to install?
> 
> Thanks,
> Richard
> 
> 
> include/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.
> 
> opcodes/
> 	* 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.
> 
> gas/
> 	* 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.
> 

OK.

R.

> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index ed4933b..9d1e3ec 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -3634,6 +3634,52 @@ parse_adrp (char **str)
>  
>  /* 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.  */
>  
> @@ -3844,6 +3890,12 @@ parse_sys_ins_reg (char **str, struct hash_control *sys_ins_regs)
>        }								\
>    } 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;						\
> @@ -4857,6 +4909,8 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
>      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;
>  
> @@ -5365,6 +5419,16 @@ parse_operands (char *str, const aarch64_opcode *opcode)
>  	  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;
> diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
> index 8eae0b9..dd191cf 100644
> --- a/include/opcode/aarch64.h
> +++ b/include/opcode/aarch64.h
> @@ -244,6 +244,8 @@ enum aarch64_opnd
>    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].  */
> @@ -1037,6 +1039,9 @@ aarch64_verbose (const char *, ...) __attribute__ ((format (printf, 1, 2)));
>  #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
> diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
> index 9c797b2..0a6e476 100644
> --- a/opcodes/aarch64-asm-2.c
> +++ b/opcodes/aarch64-asm-2.c
> @@ -480,8 +480,6 @@ aarch64_insert_operand (const aarch64_operand *self,
>      case 27:
>      case 35:
>      case 36:
> -    case 89:
> -    case 90:
>      case 91:
>      case 92:
>      case 93:
> @@ -494,7 +492,9 @@ aarch64_insert_operand (const aarch64_operand *self,
>      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);
> @@ -531,6 +531,8 @@ aarch64_insert_operand (const aarch64_operand *self,
>      case 68:
>      case 69:
>      case 70:
> +    case 89:
> +    case 90:
>        return aarch64_ins_imm (self, info, code, inst);
>      case 38:
>      case 39:
> @@ -581,10 +583,10 @@ aarch64_insert_operand (const aarch64_operand *self,
>        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 ();
>      }
> diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
> index 6ea010b..9f936f0 100644
> --- a/opcodes/aarch64-dis-2.c
> +++ b/opcodes/aarch64-dis-2.c
> @@ -10426,8 +10426,6 @@ aarch64_extract_operand (const aarch64_operand *self,
>      case 27:
>      case 35:
>      case 36:
> -    case 89:
> -    case 90:
>      case 91:
>      case 92:
>      case 93:
> @@ -10440,7 +10438,9 @@ aarch64_extract_operand (const aarch64_operand *self,
>      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);
> @@ -10482,6 +10482,8 @@ aarch64_extract_operand (const aarch64_operand *self,
>      case 68:
>      case 69:
>      case 70:
> +    case 89:
> +    case 90:
>        return aarch64_ext_imm (self, info, code, inst);
>      case 38:
>      case 39:
> @@ -10534,10 +10536,10 @@ aarch64_extract_operand (const aarch64_operand *self,
>        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 ();
>      }
> diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
> index f8a7079..3905053 100644
> --- a/opcodes/aarch64-opc-2.c
> +++ b/opcodes/aarch64-opc-2.c
> @@ -113,6 +113,8 @@ const struct aarch64_operand aarch64_operands[] =
>    {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"},
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 41c058f..934c14d 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -27,6 +27,7 @@
>  #include <inttypes.h>
>  
>  #include "opintl.h"
> +#include "libiberty.h"
>  
>  #include "aarch64-opc.h"
>  
> @@ -34,6 +35,70 @@
>  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.  */
>  
> @@ -214,6 +279,8 @@ const aarch64_field fields[] =
>      { 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].  */
>  };
>  
> @@ -2489,7 +2556,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>    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)
> @@ -2681,6 +2748,27 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>        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))
>  	{
> diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
> index cc3dbef..b54f35e 100644
> --- a/opcodes/aarch64-opc.h
> +++ b/opcodes/aarch64-opc.h
> @@ -106,6 +106,8 @@ enum aarch64_field_kind
>    FLD_SVE_Zm_16,
>    FLD_SVE_Zn,
>    FLD_SVE_Zt,
> +  FLD_SVE_pattern,
> +  FLD_SVE_prfop,
>    FLD_SVE_tszh,
>  };
>  
> diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
> index 9dbe0c0..73415f7 100644
> --- a/opcodes/aarch64-tbl.h
> +++ b/opcodes/aarch64-tbl.h
> @@ -2820,6 +2820,10 @@ struct aarch64_opcode aarch64_opcode_table[] =
>        "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),			\
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]