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 28/32] Add SVE FP immediate operands


On 23/08/16 10:25, Richard Sandiford wrote:
> This patch adds support for the new SVE floating-point immediate
> operands.  One operand uses the same 8-bit encoding as base AArch64,
> but in a different position.  The others use a single bit to select
> between two values.
> 
> One of the single-bit operands is a choice between 0 and 1, where 0
> is not a valid 8-bit encoding.  I think the cleanest way of handling
> these single-bit immediates is therefore to use the IEEE float encoding
> itself as the immediate value and select between the two possible values
> when encoding and decoding.
> 
> As described in the covering note for the patch that added F_STRICT,
> we get better error messages by accepting unsuffixed vector registers
> and leaving the qualifier matching code to report an error.  This means
> that we carry on parsing the other operands, and so can try to parse FP
> immediates for invalid instructions like:
> 
> 	fcpy	z0, #2.5
> 
> In this case there is no suffix to tell us whether the immediate should
> be treated as single or double precision.  Again, we get better error
> messages by picking one (arbitrary) immediate size and reporting an error
> for the missing suffix later.
> 
> OK to install?
> 
> Thanks,
> Richard
> 
> 
> include/opcode/
> 	* aarch64.h (AARCH64_OPND_SVE_FPIMM8): New aarch64_opnd.
> 	(AARCH64_OPND_SVE_I1_HALF_ONE, AARCH64_OPND_SVE_I1_HALF_TWO)
> 	(AARCH64_OPND_SVE_I1_ZERO_ONE): Likewise.
> 
> opcodes/
> 	* aarch64-tbl.h (AARCH64_OPERANDS): Add entries for the new SVE FP
> 	immediate operands.
> 	* aarch64-opc.h (FLD_SVE_i1): New aarch64_field_kind.
> 	* aarch64-opc.c (fields): Add corresponding entry.
> 	(operand_general_constraint_met_p): Handle the new SVE FP immediate
> 	operands.
> 	(aarch64_print_operand): Likewise.
> 	* aarch64-opc-2.c: Regenerate.
> 	* aarch64-asm.h (ins_sve_float_half_one, ins_sve_float_half_two)
> 	(ins_sve_float_zero_one): New inserters.
> 	* aarch64-asm.c (aarch64_ins_sve_float_half_one): New function.
> 	(aarch64_ins_sve_float_half_two): Likewise.
> 	(aarch64_ins_sve_float_zero_one): Likewise.
> 	* aarch64-asm-2.c: Regenerate.
> 	* aarch64-dis.h (ext_sve_float_half_one, ext_sve_float_half_two)
> 	(ext_sve_float_zero_one): New extractors.
> 	* aarch64-dis.c (aarch64_ext_sve_float_half_one): New function.
> 	(aarch64_ext_sve_float_half_two): Likewise.
> 	(aarch64_ext_sve_float_zero_one): Likewise.
> 	* aarch64-dis-2.c: Regenerate.
> 
> gas/
> 	* config/tc-aarch64.c (double_precision_operand_p): New function.
> 	(parse_operands): Use it to calculate the dp_p input to
> 	parse_aarch64_imm_float.  Handle the new SVE FP immediate operands.

OK.

R.

> 
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index cb39cf8..eddc6f8 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -2252,6 +2252,20 @@ can_convert_double_to_float (uint64_t imm, uint32_t *fpword)
>    return TRUE;
>  }
>  
> +/* Return true if we should treat OPERAND as a double-precision
> +   floating-point operand rather than a single-precision one.  */
> +static bfd_boolean
> +double_precision_operand_p (const aarch64_opnd_info *operand)
> +{
> +  /* Check for unsuffixed SVE registers, which are allowed
> +     for LDR and STR but not in instructions that require an
> +     immediate.  We get better error messages if we arbitrarily
> +     pick one size, parse the immediate normally, and then
> +     report the match failure in the normal way.  */
> +  return (operand->qualifier == AARCH64_OPND_QLF_NIL
> +	  || aarch64_get_qualifier_esize (operand->qualifier) == 8);
> +}
> +
>  /* Parse a floating-point immediate.  Return TRUE on success and return the
>     value in *IMMED in the format of IEEE754 single-precision encoding.
>     *CCP points to the start of the string; DP_P is TRUE when the immediate
> @@ -5707,11 +5721,12 @@ parse_operands (char *str, const aarch64_opcode *opcode)
>  
>  	case AARCH64_OPND_FPIMM:
>  	case AARCH64_OPND_SIMD_FPIMM:
> +	case AARCH64_OPND_SVE_FPIMM8:
>  	  {
>  	    int qfloat;
> -	    bfd_boolean dp_p
> -	      = (aarch64_get_qualifier_esize (inst.base.operands[0].qualifier)
> -		 == 8);
> +	    bfd_boolean dp_p;
> +
> +	    dp_p = double_precision_operand_p (&inst.base.operands[0]);
>  	    if (!parse_aarch64_imm_float (&str, &qfloat, dp_p, imm_reg_type)
>  		|| !aarch64_imm_float_p (qfloat))
>  	      {
> @@ -5725,6 +5740,26 @@ parse_operands (char *str, const aarch64_opcode *opcode)
>  	  }
>  	  break;
>  
> +	case AARCH64_OPND_SVE_I1_HALF_ONE:
> +	case AARCH64_OPND_SVE_I1_HALF_TWO:
> +	case AARCH64_OPND_SVE_I1_ZERO_ONE:
> +	  {
> +	    int qfloat;
> +	    bfd_boolean dp_p;
> +
> +	    dp_p = double_precision_operand_p (&inst.base.operands[0]);
> +	    if (!parse_aarch64_imm_float (&str, &qfloat, dp_p, imm_reg_type))
> +	      {
> +		if (!error_p ())
> +		  set_fatal_syntax_error (_("invalid floating-point"
> +					    " constant"));
> +		goto failure;
> +	      }
> +	    inst.base.operands[i].imm.value = qfloat;
> +	    inst.base.operands[i].imm.is_fp = 1;
> +	  }
> +	  break;
> +
>  	case AARCH64_OPND_LIMM:
>  	  po_misc_or_fail (parse_shifter_operand (&str, info,
>  						  SHIFTED_LOGIC_IMM));
> diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
> index 36e95b4..9e7f5b5 100644
> --- a/include/opcode/aarch64.h
> +++ b/include/opcode/aarch64.h
> @@ -292,6 +292,10 @@ enum aarch64_opnd
>    AARCH64_OPND_SVE_ADDR_ZZ_UXTW,    /* SVE [Zn.<T>, Zm,<T>, UXTW #<msz>].  */
>    AARCH64_OPND_SVE_AIMM,	/* SVE unsigned arithmetic immediate.  */
>    AARCH64_OPND_SVE_ASIMM,	/* SVE signed arithmetic immediate.  */
> +  AARCH64_OPND_SVE_FPIMM8,	/* SVE 8-bit floating-point immediate.  */
> +  AARCH64_OPND_SVE_I1_HALF_ONE,	/* SVE choice between 0.5 and 1.0.  */
> +  AARCH64_OPND_SVE_I1_HALF_TWO,	/* SVE choice between 0.5 and 2.0.  */
> +  AARCH64_OPND_SVE_I1_ZERO_ONE,	/* SVE choice between 0.0 and 1.0.  */
>    AARCH64_OPND_SVE_INV_LIMM,	/* SVE inverted logical immediate.  */
>    AARCH64_OPND_SVE_LIMM,	/* SVE logical immediate.  */
>    AARCH64_OPND_SVE_LIMM_MOV,	/* SVE logical immediate for MOV.  */
> diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
> index 491ea53..d9d1981 100644
> --- a/opcodes/aarch64-asm-2.c
> +++ b/opcodes/aarch64-asm-2.c
> @@ -480,21 +480,21 @@ aarch64_insert_operand (const aarch64_operand *self,
>      case 27:
>      case 35:
>      case 36:
> -    case 135:
> -    case 136:
> -    case 137:
> -    case 138:
>      case 139:
>      case 140:
>      case 141:
>      case 142:
> -    case 155:
> -    case 156:
> -    case 157:
> -    case 158:
> +    case 143:
> +    case 144:
> +    case 145:
> +    case 146:
>      case 159:
>      case 160:
> +    case 161:
> +    case 162:
>      case 163:
> +    case 164:
> +    case 167:
>        return aarch64_ins_regno (self, info, code, inst);
>      case 12:
>        return aarch64_ins_reg_extended (self, info, code, inst);
> @@ -532,16 +532,16 @@ aarch64_insert_operand (const aarch64_operand *self,
>      case 69:
>      case 70:
>      case 71:
> -    case 132:
> -    case 134:
> -    case 147:
> -    case 148:
> -    case 149:
> -    case 150:
> +    case 136:
> +    case 138:
>      case 151:
>      case 152:
>      case 153:
>      case 154:
> +    case 155:
> +    case 156:
> +    case 157:
> +    case 158:
>        return aarch64_ins_imm (self, info, code, inst);
>      case 38:
>      case 39:
> @@ -551,9 +551,10 @@ aarch64_insert_operand (const aarch64_operand *self,
>      case 42:
>        return aarch64_ins_advsimd_imm_modified (self, info, code, inst);
>      case 46:
> +    case 129:
>        return aarch64_ins_fpimm (self, info, code, inst);
>      case 60:
> -    case 130:
> +    case 134:
>        return aarch64_ins_limm (self, info, code, inst);
>      case 61:
>        return aarch64_ins_aimm (self, info, code, inst);
> @@ -644,22 +645,28 @@ aarch64_insert_operand (const aarch64_operand *self,
>        return aarch64_ins_sve_aimm (self, info, code, inst);
>      case 128:
>        return aarch64_ins_sve_asimm (self, info, code, inst);
> -    case 129:
> -      return aarch64_ins_inv_limm (self, info, code, inst);
> +    case 130:
> +      return aarch64_ins_sve_float_half_one (self, info, code, inst);
>      case 131:
> -      return aarch64_ins_sve_limm_mov (self, info, code, inst);
> +      return aarch64_ins_sve_float_half_two (self, info, code, inst);
> +    case 132:
> +      return aarch64_ins_sve_float_zero_one (self, info, code, inst);
>      case 133:
> +      return aarch64_ins_inv_limm (self, info, code, inst);
> +    case 135:
> +      return aarch64_ins_sve_limm_mov (self, info, code, inst);
> +    case 137:
>        return aarch64_ins_sve_scale (self, info, code, inst);
> -    case 143:
> -    case 144:
> +    case 147:
> +    case 148:
>        return aarch64_ins_sve_shlimm (self, info, code, inst);
> -    case 145:
> -    case 146:
> +    case 149:
> +    case 150:
>        return aarch64_ins_sve_shrimm (self, info, code, inst);
> -    case 161:
> +    case 165:
>        return aarch64_ins_sve_index (self, info, code, inst);
> -    case 162:
> -    case 164:
> +    case 166:
> +    case 168:
>        return aarch64_ins_sve_reglist (self, info, code, inst);
>      default: assert (0); abort ();
>      }
> diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
> index 61d0d95..fd356f4 100644
> --- a/opcodes/aarch64-asm.c
> +++ b/opcodes/aarch64-asm.c
> @@ -1028,6 +1028,51 @@ aarch64_ins_sve_shrimm (const aarch64_operand *self,
>    return NULL;
>  }
>  
> +/* Encode a single-bit immediate that selects between #0.5 and #1.0.
> +   The fields array specifies which field to use.  */
> +const char *
> +aarch64_ins_sve_float_half_one (const aarch64_operand *self,
> +				const aarch64_opnd_info *info,
> +				aarch64_insn *code,
> +				const aarch64_inst *inst ATTRIBUTE_UNUSED)
> +{
> +  if (info->imm.value == 0x3f000000)
> +    insert_field (self->fields[0], code, 0, 0);
> +  else
> +    insert_field (self->fields[0], code, 1, 0);
> +  return NULL;
> +}
> +
> +/* Encode a single-bit immediate that selects between #0.5 and #2.0.
> +   The fields array specifies which field to use.  */
> +const char *
> +aarch64_ins_sve_float_half_two (const aarch64_operand *self,
> +				const aarch64_opnd_info *info,
> +				aarch64_insn *code,
> +				const aarch64_inst *inst ATTRIBUTE_UNUSED)
> +{
> +  if (info->imm.value == 0x3f000000)
> +    insert_field (self->fields[0], code, 0, 0);
> +  else
> +    insert_field (self->fields[0], code, 1, 0);
> +  return NULL;
> +}
> +
> +/* Encode a single-bit immediate that selects between #0.0 and #1.0.
> +   The fields array specifies which field to use.  */
> +const char *
> +aarch64_ins_sve_float_zero_one (const aarch64_operand *self,
> +				const aarch64_opnd_info *info,
> +				aarch64_insn *code,
> +				const aarch64_inst *inst ATTRIBUTE_UNUSED)
> +{
> +  if (info->imm.value == 0)
> +    insert_field (self->fields[0], code, 0, 0);
> +  else
> +    insert_field (self->fields[0], code, 1, 0);
> +  return NULL;
> +}
> +
>  /* Miscellaneous encoding functions.  */
>  
>  /* Encode size[0], i.e. bit 22, for
> diff --git a/opcodes/aarch64-asm.h b/opcodes/aarch64-asm.h
> index bbd320e..0cce71c 100644
> --- a/opcodes/aarch64-asm.h
> +++ b/opcodes/aarch64-asm.h
> @@ -82,6 +82,9 @@ AARCH64_DECL_OPD_INSERTER (ins_sve_addr_zz_sxtw);
>  AARCH64_DECL_OPD_INSERTER (ins_sve_addr_zz_uxtw);
>  AARCH64_DECL_OPD_INSERTER (ins_sve_aimm);
>  AARCH64_DECL_OPD_INSERTER (ins_sve_asimm);
> +AARCH64_DECL_OPD_INSERTER (ins_sve_float_half_one);
> +AARCH64_DECL_OPD_INSERTER (ins_sve_float_half_two);
> +AARCH64_DECL_OPD_INSERTER (ins_sve_float_zero_one);
>  AARCH64_DECL_OPD_INSERTER (ins_sve_index);
>  AARCH64_DECL_OPD_INSERTER (ins_sve_limm_mov);
>  AARCH64_DECL_OPD_INSERTER (ins_sve_reglist);
> diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
> index 4527456..110cf2e 100644
> --- a/opcodes/aarch64-dis-2.c
> +++ b/opcodes/aarch64-dis-2.c
> @@ -10426,21 +10426,21 @@ aarch64_extract_operand (const aarch64_operand *self,
>      case 27:
>      case 35:
>      case 36:
> -    case 135:
> -    case 136:
> -    case 137:
> -    case 138:
>      case 139:
>      case 140:
>      case 141:
>      case 142:
> -    case 155:
> -    case 156:
> -    case 157:
> -    case 158:
> +    case 143:
> +    case 144:
> +    case 145:
> +    case 146:
>      case 159:
>      case 160:
> +    case 161:
> +    case 162:
>      case 163:
> +    case 164:
> +    case 167:
>        return aarch64_ext_regno (self, info, code, inst);
>      case 8:
>        return aarch64_ext_regrt_sysins (self, info, code, inst);
> @@ -10483,16 +10483,16 @@ aarch64_extract_operand (const aarch64_operand *self,
>      case 69:
>      case 70:
>      case 71:
> -    case 132:
> -    case 134:
> -    case 147:
> -    case 148:
> -    case 149:
> -    case 150:
> +    case 136:
> +    case 138:
>      case 151:
>      case 152:
>      case 153:
>      case 154:
> +    case 155:
> +    case 156:
> +    case 157:
> +    case 158:
>        return aarch64_ext_imm (self, info, code, inst);
>      case 38:
>      case 39:
> @@ -10504,9 +10504,10 @@ aarch64_extract_operand (const aarch64_operand *self,
>      case 43:
>        return aarch64_ext_shll_imm (self, info, code, inst);
>      case 46:
> +    case 129:
>        return aarch64_ext_fpimm (self, info, code, inst);
>      case 60:
> -    case 130:
> +    case 134:
>        return aarch64_ext_limm (self, info, code, inst);
>      case 61:
>        return aarch64_ext_aimm (self, info, code, inst);
> @@ -10597,22 +10598,28 @@ aarch64_extract_operand (const aarch64_operand *self,
>        return aarch64_ext_sve_aimm (self, info, code, inst);
>      case 128:
>        return aarch64_ext_sve_asimm (self, info, code, inst);
> -    case 129:
> -      return aarch64_ext_inv_limm (self, info, code, inst);
> +    case 130:
> +      return aarch64_ext_sve_float_half_one (self, info, code, inst);
>      case 131:
> -      return aarch64_ext_sve_limm_mov (self, info, code, inst);
> +      return aarch64_ext_sve_float_half_two (self, info, code, inst);
> +    case 132:
> +      return aarch64_ext_sve_float_zero_one (self, info, code, inst);
>      case 133:
> +      return aarch64_ext_inv_limm (self, info, code, inst);
> +    case 135:
> +      return aarch64_ext_sve_limm_mov (self, info, code, inst);
> +    case 137:
>        return aarch64_ext_sve_scale (self, info, code, inst);
> -    case 143:
> -    case 144:
> +    case 147:
> +    case 148:
>        return aarch64_ext_sve_shlimm (self, info, code, inst);
> -    case 145:
> -    case 146:
> +    case 149:
> +    case 150:
>        return aarch64_ext_sve_shrimm (self, info, code, inst);
> -    case 161:
> +    case 165:
>        return aarch64_ext_sve_index (self, info, code, inst);
> -    case 162:
> -    case 164:
> +    case 166:
> +    case 168:
>        return aarch64_ext_sve_reglist (self, info, code, inst);
>      default: assert (0); abort ();
>      }
> diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
> index ed050cd..385286c 100644
> --- a/opcodes/aarch64-dis.c
> +++ b/opcodes/aarch64-dis.c
> @@ -1465,6 +1465,51 @@ aarch64_ext_sve_asimm (const aarch64_operand *self,
>  	  && decode_sve_aimm (info, (int8_t) info->imm.value));
>  }
>  
> +/* Decode a single-bit immediate that selects between #0.5 and #1.0.
> +   The fields array specifies which field to use.  */
> +int
> +aarch64_ext_sve_float_half_one (const aarch64_operand *self,
> +				aarch64_opnd_info *info, aarch64_insn code,
> +				const aarch64_inst *inst ATTRIBUTE_UNUSED)
> +{
> +  if (extract_field (self->fields[0], code, 0))
> +    info->imm.value = 0x3f800000;
> +  else
> +    info->imm.value = 0x3f000000;
> +  info->imm.is_fp = TRUE;
> +  return 1;
> +}
> +
> +/* Decode a single-bit immediate that selects between #0.5 and #2.0.
> +   The fields array specifies which field to use.  */
> +int
> +aarch64_ext_sve_float_half_two (const aarch64_operand *self,
> +				aarch64_opnd_info *info, aarch64_insn code,
> +				const aarch64_inst *inst ATTRIBUTE_UNUSED)
> +{
> +  if (extract_field (self->fields[0], code, 0))
> +    info->imm.value = 0x40000000;
> +  else
> +    info->imm.value = 0x3f000000;
> +  info->imm.is_fp = TRUE;
> +  return 1;
> +}
> +
> +/* Decode a single-bit immediate that selects between #0.0 and #1.0.
> +   The fields array specifies which field to use.  */
> +int
> +aarch64_ext_sve_float_zero_one (const aarch64_operand *self,
> +				aarch64_opnd_info *info, aarch64_insn code,
> +				const aarch64_inst *inst ATTRIBUTE_UNUSED)
> +{
> +  if (extract_field (self->fields[0], code, 0))
> +    info->imm.value = 0x3f800000;
> +  else
> +    info->imm.value = 0x0;
> +  info->imm.is_fp = TRUE;
> +  return 1;
> +}
> +
>  /* Decode Zn[MM], where MM has a 7-bit triangular encoding.  The fields
>     array specifies which field to use for Zn.  MM is encoded in the
>     concatenation of imm5 and SVE_tszh, with imm5 being the less
> diff --git a/opcodes/aarch64-dis.h b/opcodes/aarch64-dis.h
> index 10983d1..474bc45 100644
> --- a/opcodes/aarch64-dis.h
> +++ b/opcodes/aarch64-dis.h
> @@ -104,6 +104,9 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sve_addr_zz_sxtw);
>  AARCH64_DECL_OPD_EXTRACTOR (ext_sve_addr_zz_uxtw);
>  AARCH64_DECL_OPD_EXTRACTOR (ext_sve_aimm);
>  AARCH64_DECL_OPD_EXTRACTOR (ext_sve_asimm);
> +AARCH64_DECL_OPD_EXTRACTOR (ext_sve_float_half_one);
> +AARCH64_DECL_OPD_EXTRACTOR (ext_sve_float_half_two);
> +AARCH64_DECL_OPD_EXTRACTOR (ext_sve_float_zero_one);
>  AARCH64_DECL_OPD_EXTRACTOR (ext_sve_index);
>  AARCH64_DECL_OPD_EXTRACTOR (ext_sve_limm_mov);
>  AARCH64_DECL_OPD_EXTRACTOR (ext_sve_reglist);
> diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
> index d86e7dc..58c3aed 100644
> --- a/opcodes/aarch64-opc-2.c
> +++ b/opcodes/aarch64-opc-2.c
> @@ -153,6 +153,10 @@ const struct aarch64_operand aarch64_operands[] =
>    {AARCH64_OPND_CLASS_ADDRESS, "SVE_ADDR_ZZ_UXTW", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zn,FLD_SVE_Zm_16}, "an address with a vector register offset"},
>    {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_AIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm9}, "a 9-bit unsigned arithmetic operand"},
>    {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_ASIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm9}, "a 9-bit signed arithmetic operand"},
> +  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_FPIMM8", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_imm8}, "an 8-bit floating-point immediate"},
> +  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_I1_HALF_ONE", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_i1}, "either 0.5 or 1.0"},
> +  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_I1_HALF_TWO", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_i1}, "either 0.5 or 2.0"},
> +  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_I1_ZERO_ONE", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_i1}, "either 0.0 or 1.0"},
>    {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_INV_LIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms}, "an inverted 13-bit logical immediate"},
>    {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_LIMM", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms}, "a 13-bit logical immediate"},
>    {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_LIMM_MOV", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms}, "a 13-bit logical move immediate"},
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index dec7e06..3b0279c 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -280,6 +280,7 @@ 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,  1 }, /* SVE_i1: single-bit immediate.  */
>      { 16,  3 }, /* SVE_imm3: 3-bit immediate field.  */
>      { 16,  4 }, /* SVE_imm4: 4-bit immediate field.  */
>      {  5,  5 }, /* SVE_imm5: 5-bit immediate field.  */
> @@ -2178,6 +2179,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
>  
>  	case AARCH64_OPND_FPIMM:
>  	case AARCH64_OPND_SIMD_FPIMM:
> +	case AARCH64_OPND_SVE_FPIMM8:
>  	  if (opnd->imm.is_fp == 0)
>  	    {
>  	      set_other_error (mismatch_detail, idx,
> @@ -2254,6 +2256,36 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
>  	  min_value = -128;
>  	  goto sve_aimm;
>  
> +	case AARCH64_OPND_SVE_I1_HALF_ONE:
> +	  assert (opnd->imm.is_fp);
> +	  if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x3f800000)
> +	    {
> +	      set_other_error (mismatch_detail, idx,
> +			       _("floating-point value must be 0.5 or 1.0"));
> +	      return 0;
> +	    }
> +	  break;
> +
> +	case AARCH64_OPND_SVE_I1_HALF_TWO:
> +	  assert (opnd->imm.is_fp);
> +	  if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x40000000)
> +	    {
> +	      set_other_error (mismatch_detail, idx,
> +			       _("floating-point value must be 0.5 or 2.0"));
> +	      return 0;
> +	    }
> +	  break;
> +
> +	case AARCH64_OPND_SVE_I1_ZERO_ONE:
> +	  assert (opnd->imm.is_fp);
> +	  if (opnd->imm.value != 0 && opnd->imm.value != 0x3f800000)
> +	    {
> +	      set_other_error (mismatch_detail, idx,
> +			       _("floating-point value must be 0.0 or 1.0"));
> +	      return 0;
> +	    }
> +	  break;
> +
>  	case AARCH64_OPND_SVE_INV_LIMM:
>  	  {
>  	    int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
> @@ -3105,6 +3137,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>        snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
>        break;
>  
> +    case AARCH64_OPND_SVE_I1_HALF_ONE:
> +    case AARCH64_OPND_SVE_I1_HALF_TWO:
> +    case AARCH64_OPND_SVE_I1_ZERO_ONE:
> +      {
> +	single_conv_t c;
> +	c.i = opnd->imm.value;
> +	snprintf (buf, size, "#%.1f", c.f);
> +	break;
> +      }
> +
>      case AARCH64_OPND_SVE_PATTERN:
>        if (optional_operand_p (opcode, idx)
>  	  && opnd->imm.value == get_optional_operand_default_value (opcode))
> @@ -3202,6 +3244,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
>  
>      case AARCH64_OPND_FPIMM:
>      case AARCH64_OPND_SIMD_FPIMM:
> +    case AARCH64_OPND_SVE_FPIMM8:
>        switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
>  	{
>  	case 2:	/* e.g. FMOV <Hd>, #<imm>.  */
> diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
> index 087376e..6c67786 100644
> --- a/opcodes/aarch64-opc.h
> +++ b/opcodes/aarch64-opc.h
> @@ -107,6 +107,7 @@ enum aarch64_field_kind
>    FLD_SVE_Zm_16,
>    FLD_SVE_Zn,
>    FLD_SVE_Zt,
> +  FLD_SVE_i1,
>    FLD_SVE_imm3,
>    FLD_SVE_imm4,
>    FLD_SVE_imm5,
> diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
> index d743e3b..562eea7 100644
> --- a/opcodes/aarch64-tbl.h
> +++ b/opcodes/aarch64-tbl.h
> @@ -2931,6 +2931,14 @@ struct aarch64_opcode aarch64_opcode_table[] =
>        "a 9-bit unsigned arithmetic operand")				\
>      Y(IMMEDIATE, sve_asimm, "SVE_ASIMM", 0, F(FLD_SVE_imm9),		\
>        "a 9-bit signed arithmetic operand")				\
> +    Y(IMMEDIATE, fpimm, "SVE_FPIMM8", 0, F(FLD_SVE_imm8),		\
> +      "an 8-bit floating-point immediate")				\
> +    Y(IMMEDIATE, sve_float_half_one, "SVE_I1_HALF_ONE", 0,		\
> +      F(FLD_SVE_i1), "either 0.5 or 1.0")				\
> +    Y(IMMEDIATE, sve_float_half_two, "SVE_I1_HALF_TWO", 0,		\
> +      F(FLD_SVE_i1), "either 0.5 or 2.0")				\
> +    Y(IMMEDIATE, sve_float_zero_one, "SVE_I1_ZERO_ONE", 0,		\
> +      F(FLD_SVE_i1), "either 0.0 or 1.0")				\
>      Y(IMMEDIATE, inv_limm, "SVE_INV_LIMM", 0,				\
>        F(FLD_SVE_N,FLD_SVE_immr,FLD_SVE_imms),				\
>        "an inverted 13-bit logical immediate")				\
> 


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