[AArch64][SVE 28/32] Add SVE FP immediate operands
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:57:22 +0000 (16:57 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:57:22 +0000 (16:57 +0100)
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.

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.

15 files changed:
gas/ChangeLog
gas/config/tc-aarch64.c
include/ChangeLog
include/opcode/aarch64.h
opcodes/ChangeLog
opcodes/aarch64-asm-2.c
opcodes/aarch64-asm.c
opcodes/aarch64-asm.h
opcodes/aarch64-dis-2.c
opcodes/aarch64-dis.c
opcodes/aarch64-dis.h
opcodes/aarch64-opc-2.c
opcodes/aarch64-opc.c
opcodes/aarch64-opc.h
opcodes/aarch64-tbl.h

index a1467996212292616e65f629f972dd6137a87592..53faa4e206c72c5eac7c4b1d38e2afd8805c27a7 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * 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.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/tc-aarch64.c (parse_operands): Handle the new SVE integer
index 6b9ae29f85c0233cd2f4faaf9e04c46ffed08593..01c8000d0a7e779092dcc3e02c5ec1cfef8bc0e9 100644 (file)
@@ -2232,6 +2232,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
@@ -5655,11 +5669,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))
              {
@@ -5673,6 +5688,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));
index 6c9c9194952f35fd63d22dd4f8861f7661862007..80016dca5f5a979f7ed6331ecc77637f486e5066 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * 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.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * opcode/aarch64.h (AARCH64_OPND_SIMM5): New aarch64_opnd.
index 36e95b4567216d3249af7de136f410ccbf11ac3d..9e7f5b554de0c9379407a614991a25ff708f5e1e 100644 (file)
@@ -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.  */
index 10fdd1fe0fff38e45b92c4b25c5ad84c882f3173..c94752cbd56f8c62ab96a770f5f8b031f5a73267 100644 (file)
@@ -1,3 +1,26 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * 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.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for the new SVE
index 491ea53dc0961b33ff3c32ddf6d206e2e4779a8c..d9d19816236ae1d32f0a87e6af3f899e237b5632 100644 (file)
@@ -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 ();
     }
index 61d0d95dce31bb281fe0e98c707ba2780ca8504b..fd356f44691093c205640c8d3b5f579df9c58cc1 100644 (file)
@@ -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
index bbd320eb8eb1ef657c31a828fa11d4dc7db40408..0cce71c42a853f6bdd8c383308fe614fc87c1a61 100644 (file)
@@ -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);
index 45274565dcded0466e6a449c6f1b92dbda8ad161..110cf2e9470f727496d8443cb93e23b2344c0fb3 100644 (file)
@@ -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 ();
     }
index ed050cd3e04eaa1f201995cce9cda9b9a5dff7e7..385286c0c8760cfa901fee13b165d4db357b73bf 100644 (file)
@@ -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
index 10983d124f40a3f189b4d99dee65c3420c09e623..474bc454346f8060ad7c63a5b3cfbd528e06037a 100644 (file)
@@ -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);
index d86e7dc241de0593561b44943b341161c2090baf..58c3aedc6eb84b1706a04aeb0f8997436c82f41e 100644 (file)
@@ -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"},
index b264bdb4f0a22df3dcffe5739cd0c03debbca073..db744af48b0960964917996bc3af15ea4f214d0c 100644 (file)
@@ -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>.  */
index 087376e09c054f5f50ec003bab476cebf5d64b3f..6c67786c67bf20ec4c4972a85efafca9ec20d58d 100644 (file)
@@ -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,
index edb2d7936b2655d61164a260e32a4ccecb152933..367e42bc3ab812e42f4b45a135ec1050e0eaadc1 100644 (file)
@@ -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")                          \