diff options
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-aarch64.c | 41 | ||||
-rw-r--r-- | include/ChangeLog | 6 | ||||
-rw-r--r-- | include/opcode/aarch64.h | 4 | ||||
-rw-r--r-- | opcodes/ChangeLog | 23 | ||||
-rw-r--r-- | opcodes/aarch64-asm-2.c | 57 | ||||
-rw-r--r-- | opcodes/aarch64-asm.c | 45 | ||||
-rw-r--r-- | opcodes/aarch64-asm.h | 3 | ||||
-rw-r--r-- | opcodes/aarch64-dis-2.c | 57 | ||||
-rw-r--r-- | opcodes/aarch64-dis.c | 45 | ||||
-rw-r--r-- | opcodes/aarch64-dis.h | 3 | ||||
-rw-r--r-- | opcodes/aarch64-opc-2.c | 4 | ||||
-rw-r--r-- | opcodes/aarch64-opc.c | 43 | ||||
-rw-r--r-- | opcodes/aarch64-opc.h | 1 | ||||
-rw-r--r-- | opcodes/aarch64-tbl.h | 8 |
15 files changed, 293 insertions, 53 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index a146799..53faa4e 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 6b9ae29..01c8000 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 6c9c919..80016dc 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 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/ChangeLog b/opcodes/ChangeLog index 10fdd1f..c94752c 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 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 bbd320eb..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 b264bdb..db744af 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 edb2d79..367e42b 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") \ |