summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-aarch64.c41
-rw-r--r--include/ChangeLog6
-rw-r--r--include/opcode/aarch64.h4
-rw-r--r--opcodes/ChangeLog23
-rw-r--r--opcodes/aarch64-asm-2.c57
-rw-r--r--opcodes/aarch64-asm.c45
-rw-r--r--opcodes/aarch64-asm.h3
-rw-r--r--opcodes/aarch64-dis-2.c57
-rw-r--r--opcodes/aarch64-dis.c45
-rw-r--r--opcodes/aarch64-dis.h3
-rw-r--r--opcodes/aarch64-opc-2.c4
-rw-r--r--opcodes/aarch64-opc.c43
-rw-r--r--opcodes/aarch64-opc.h1
-rw-r--r--opcodes/aarch64-tbl.h8
15 files changed, 293 insertions, 53 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a1467996212..53faa4e206c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,11 @@
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
immediate operands.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 6b9ae29f85c..01c8000d0a7 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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));
diff --git a/include/ChangeLog b/include/ChangeLog
index 6c9c9194952..80016dca5f5 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,5 +1,11 @@
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.
(AARCH64_OPND_SVE_AIMM, AARCH64_OPND_SVE_ASIMM)
(AARCH64_OPND_SVE_INV_LIMM, AARCH64_OPND_SVE_LIMM)
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 36e95b45672..9e7f5b554de 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/ChangeLog b/opcodes/ChangeLog
index 10fdd1fe0ff..c94752cbd56 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,28 @@
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
integer immediate operands.
* aarch64-opc.h (FLD_SVE_immN, FLD_SVE_imm3, FLD_SVE_imm5)
diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
index 491ea53dc09..d9d19816236 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 61d0d95dce3..fd356f44691 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 bbd320eb8eb..0cce71c42a8 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 45274565dcd..110cf2e9470 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 ed050cd3e04..385286c0c87 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 10983d124f4..474bc454346 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 d86e7dc241d..58c3aedc6eb 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 b264bdb4f0a..db744af48b0 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 087376e09c0..6c67786c67b 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 edb2d7936b2..367e42bc3ab 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") \