@@ -1239,8 +1239,13 @@ static const struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zvfhmin", "+zve32f", check_implicit_always},
{"zvfbfwma", "+zve32f,+zfbfmin", check_implicit_always},
{"zvfbfmin", "+zve32f", check_implicit_always},
+ {"zvfbdota32f", "+zve32f", check_implicit_always},
+ {"zvfqwbdota8f", "+zve32f", check_implicit_always},
{"zvfqwdota8f", "+zve32f", check_implicit_always},
+ {"zvfwbdota16bf", "+zve32f", check_implicit_always},
{"zvfwdota16bf", "+zve32f", check_implicit_always},
+ {"zvqwbdota8i", "+zve32x", check_implicit_always},
+ {"zvqwbdota16i", "+zve64x", check_implicit_always},
{"zvqwdota8i", "+zve32x", check_implicit_always},
{"zvqwdota16i", "+zve64x", check_implicit_always},
{"zve64d", "+d,+zve64f", check_implicit_always},
@@ -1524,11 +1529,14 @@ static const struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zvabd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvfbdota32f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvfbfmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvfbfwma", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvfqwbdota8f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvfqwdota8f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvfwbdota16bf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvfwdota16bf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvkb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvkg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
@@ -1544,6 +1552,8 @@ static const struct riscv_supported_ext riscv_supported_std_z_ext[] =
{"zvksg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvksc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvqwbdota8i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvqwbdota16i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvqwdota8i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvqwdota16i", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl32b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
@@ -2993,8 +3003,14 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "zvfbfmin");
case INSN_CLASS_ZVFBFWMA:
return riscv_subset_supports (rps, "zvfbfwma");
+ case INSN_CLASS_ZVFBDOTA32F:
+ return riscv_subset_supports (rps, "zvfbdota32f");
+ case INSN_CLASS_ZVFQWBDOTA8F:
+ return riscv_subset_supports (rps, "zvfqwbdota8f");
case INSN_CLASS_ZVFQWDOTA8F:
return riscv_subset_supports (rps, "zvfqwdota8f");
+ case INSN_CLASS_ZVFWBDOTA16BF:
+ return riscv_subset_supports (rps, "zvfwbdota16bf");
case INSN_CLASS_ZVFWDOTA16BF:
return riscv_subset_supports (rps, "zvfwdota16bf");
case INSN_CLASS_ZVKB:
@@ -3010,6 +3026,13 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "zvksed");
case INSN_CLASS_ZVKSH:
return riscv_subset_supports (rps, "zvksh");
+ case INSN_CLASS_ZVQWBDOTA8I:
+ return riscv_subset_supports (rps, "zvqwbdota8i");
+ case INSN_CLASS_ZVQWBDOTA16I:
+ return riscv_subset_supports (rps, "zvqwbdota16i");
+ case INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I:
+ return (riscv_subset_supports (rps, "zvqwbdota8i")
+ || riscv_subset_supports (rps, "zvqwbdota16i"));
case INSN_CLASS_ZVQWDOTA8I:
return riscv_subset_supports (rps, "zvqwdota8i");
case INSN_CLASS_ZVQWDOTA16I:
@@ -3331,8 +3354,14 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "zvfbfmin";
case INSN_CLASS_ZVFBFWMA:
return "zvfbfwma";
+ case INSN_CLASS_ZVFBDOTA32F:
+ return "zvfbdota32f";
+ case INSN_CLASS_ZVFQWBDOTA8F:
+ return "zvfqwbdota8f";
case INSN_CLASS_ZVFQWDOTA8F:
return "zvfqwdota8f";
+ case INSN_CLASS_ZVFWBDOTA16BF:
+ return "zvfwbdota16bf";
case INSN_CLASS_ZVFWDOTA16BF:
return "zvfwdota16bf";
case INSN_CLASS_ZVKB:
@@ -3347,6 +3376,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return _("zvksed");
case INSN_CLASS_ZVKSH:
return _("zvksh");
+ case INSN_CLASS_ZVQWBDOTA8I:
+ return "zvqwbdota8i";
+ case INSN_CLASS_ZVQWBDOTA16I:
+ return "zvqwbdota16i";
+ case INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I:
+ return _("zvqwbdota8i' or `zvqwbdota16i");
case INSN_CLASS_ZVQWDOTA8I:
return "zvqwdota8i";
case INSN_CLASS_ZVQWDOTA16I:
@@ -7,7 +7,9 @@
* Add support for RISC-V standard extensions:
zalasr v1.0, svrsw60t59b v1.0, zvabd v1.0, smpmpmt v1.0,
- zvqwdota8i, zvqwdota16i, zvfwdota16bf and zvfqwdota8f v1.0.
+ zvqwdota8i, zvqwdota16i, zvfwdota16bf and zvfqwdota8f v1.0,
+ zvqwbdota8i, zvqwbdota16i, zvfwbdota16bf, zvfqwbdota8f and
+ zvfbdota32f v1.0.
* Add support for RISC-V vendor extensions:
SpacemiT: xsmtvdot v1.0, xsmtvdotii v1.0.
@@ -1568,6 +1568,8 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
case 'e': USE_BITS (OP_MASK_VWD, OP_SH_VWD); break;
case 's': USE_BITS (OP_MASK_VS1, OP_SH_VS1); break;
case 't': USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
+ case 'q': USE_BITS (0x3, OP_SH_VS2 + 3); break;
+ case 'r': USE_BITS (0x7, OP_SH_VS2); break;
case 'u': USE_BITS (OP_MASK_VS1, OP_SH_VS1);
USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
case 'v': USE_BITS (OP_MASK_VD, OP_SH_VD);
@@ -2697,8 +2699,12 @@ riscv_vtype_altfmt_supported (void)
{
return (riscv_subset_supports (&riscv_rps_as, "zvfbfa")
|| riscv_subset_supports (&riscv_rps_as, "zvfofp8min")
+ || riscv_subset_supports (&riscv_rps_as, "zvfqwbdota8f")
|| riscv_subset_supports (&riscv_rps_as, "zvfqwdota8f")
+ || riscv_subset_supports (&riscv_rps_as, "zvfwbdota16bf")
|| riscv_subset_supports (&riscv_rps_as, "zvfwdota16bf")
+ || riscv_subset_supports (&riscv_rps_as, "zvqwbdota8i")
+ || riscv_subset_supports (&riscv_rps_as, "zvqwbdota16i")
|| riscv_subset_supports (&riscv_rps_as, "zvqwdota8i")
|| riscv_subset_supports (&riscv_rps_as, "zvqwdota16i"));
}
@@ -2720,7 +2726,7 @@ my_getVsetvliExpression (expressionS *ep, char *str)
as_bad (_("multiple vsew constants"));
if (!riscv_vtype_altfmt_supported ())
as_bad (_("symbolic vtype altfmt requires `zvfbfa', "
- "`zvfofp8min' or a `zvdota' extension"));
+ "`zvfofp8min' or an altfmt dot-product extension"));
altfmt_value = 1 << OP_SH_VTYPE_ALTFMT;
vsew_found = true;
}
@@ -3376,6 +3382,35 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
INSERT_OPERAND (VS2, *ip, regno);
continue;
+ case 'q': /* Zvbdota VS2 group base. */
+ if (!reg_lookup (&asarg, RCLASS_VECR, ®no))
+ break;
+ if (regno & 0x7)
+ as_bad (_("vector register must be aligned to an "
+ "EMUL=8 group"));
+ INSERT_BITS (ip->insn_opcode, regno & 0x18, 0x18,
+ OP_SH_VS2);
+ continue;
+
+ case 'r': /* Zvbdota ci immediate in VS2. */
+ {
+ offsetT ci;
+
+ my_getExpression (imm_expr, asarg, force_reloc);
+ check_absolute_expr (ip, imm_expr, false);
+ ci = imm_expr->X_add_number;
+ if (ci < 0 || ci > 56 || (ci & 0x7))
+ {
+ as_bad (_("bad value for Zvbdota ci immediate field, "
+ "value must be a multiple of 8 in 0..56"));
+ ci = 0;
+ }
+ INSERT_BITS (ip->insn_opcode, ci / 8, 0x7, OP_SH_VS2);
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+ }
+
case 'u': /* VS1 == VS2 */
if (!reg_lookup (&asarg, RCLASS_VECR, ®no))
break;
@@ -72,11 +72,14 @@ All available -march extensions for RISC-V:
zvabd 1.0
zvbb 1.0
zvbc 1.0
+ zvfbdota32f 1.0
zvfbfmin 1.0
zvfbfwma 1.0
zvfh 1.0
zvfhmin 1.0
+ zvfqwbdota8f 1.0
zvfqwdota8f 1.0
+ zvfwbdota16bf 1.0
zvfwdota16bf 1.0
zvkb 1.0
zvkg 1.0
@@ -92,6 +95,8 @@ All available -march extensions for RISC-V:
zvksg 1.0
zvksc 1.0
zvkt 1.0
+ zvqwbdota8i 1.0
+ zvqwbdota16i 1.0
zvqwdota8i 1.0
zvqwdota16i 1.0
zvl32b 1.0
new file mode 100644
@@ -0,0 +1,3 @@
+#as: -march=rv64gc_zvqwbdota8i
+#source: zvbdota-operands-fail.s
+#error_output: zvbdota-operands-fail.l
new file mode 100644
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*: Error: vector register must be aligned to an EMUL=8 group
+.*: Error: bad value for Zvbdota ci immediate field, value must be a multiple of 8 in 0..56
+.*: Error: bad value for Zvbdota ci immediate field, value must be a multiple of 8 in 0..56
new file mode 100644
@@ -0,0 +1,4 @@
+target:
+ vqwbdotas.vv v16, v9, v31, 0
+ vqwbdotas.vv v16, v8, v31, 4
+ vqwbdotas.vv v16, v8, v31, 64
new file mode 100644
@@ -0,0 +1,11 @@
+#as: -march=rv64gc_zvqwbdota16i
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+ba8f8877[ ]+vqwbdotau.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+be9f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,8
new file mode 100644
@@ -0,0 +1,3 @@
+target:
+ vqwbdotau.vv v16, v8, v31, 0
+ vqwbdotas.vv v16, v8, v31, 8
new file mode 100644
@@ -0,0 +1,23 @@
+#as: -march=rv64gc_zvqwbdota8i_zvqwbdota16i_zvfwbdota16bf_zvfqwbdota8f_zvfbdota32f
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ ]+[0-9a-f]+:[ ]+ba8f8877[ ]+vqwbdotau.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+ba9f8877[ ]+vqwbdotau.vv[ ]+v16,v8,v31,8
+[ ]+[0-9a-f]+:[ ]+be8f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+be9f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,8
+[ ]+[0-9a-f]+:[ ]+b28f9877[ ]+vfwbdota.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+b29f9877[ ]+vfwbdota.vv[ ]+v16,v8,v31,8
+[ ]+[0-9a-f]+:[ ]+ba8f9877[ ]+vfqwbdota.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+ba9f9877[ ]+vfqwbdota.vv[ ]+v16,v8,v31,8
+[ ]+[0-9a-f]+:[ ]+be8f9877[ ]+vfqwbdota.alt.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+be9f9877[ ]+vfqwbdota.alt.vv[ ]+v16,v8,v31,8
+[ ]+[0-9a-f]+:[ ]+ae8f9877[ ]+vfbdota.vv[ ]+v16,v8,v31,0
+[ ]+[0-9a-f]+:[ ]+ae9f9877[ ]+vfbdota.vv[ ]+v16,v8,v31,8
+[ ]+[0-9a-f]+:[ ]+bc8f8877[ ]+vqwbdotas.vv[ ]+v16,v8,v31,0,v0.t
+[ ]+[0-9a-f]+:[ ]+b89f9877[ ]+vfqwbdota.vv[ ]+v16,v8,v31,8,v0.t
new file mode 100644
@@ -0,0 +1,15 @@
+target:
+ vqwbdotau.vv v16, v8, v31, 0
+ vqwbdotau.vv v16, v8, v31, 8
+ vqwbdotas.vv v16, v8, v31, 0
+ vqwbdotas.vv v16, v8, v31, 8
+ vfwbdota.vv v16, v8, v31, 0
+ vfwbdota.vv v16, v8, v31, 8
+ vfqwbdota.vv v16, v8, v31, 0
+ vfqwbdota.vv v16, v8, v31, 8
+ vfqwbdota.alt.vv v16, v8, v31, 0
+ vfqwbdota.alt.vv v16, v8, v31, 8
+ vfbdota.vv v16, v8, v31, 0
+ vfbdota.vv v16, v8, v31, 8
+ vqwbdotas.vv v16, v8, v31, 0, v0.t
+ vfqwbdota.vv v16, v8, v31, 8, v0.t
@@ -2588,6 +2588,19 @@
#define MASK_VFQWDOTA_VV 0xfc00707f
#define MATCH_VFQWDOTA_ALT_VV 0x9c001077
#define MASK_VFQWDOTA_ALT_VV 0xfc00707f
+/* Zvbdota instructions. */
+#define MATCH_VQWBDOTAU_VV 0xb8000077
+#define MASK_VQWBDOTAU_VV 0xfc00707f
+#define MATCH_VQWBDOTAS_VV 0xbc000077
+#define MASK_VQWBDOTAS_VV 0xfc00707f
+#define MATCH_VFWBDOTA_VV 0xb0001077
+#define MASK_VFWBDOTA_VV 0xfc00707f
+#define MATCH_VFQWBDOTA_VV 0xb8001077
+#define MASK_VFQWBDOTA_VV 0xfc00707f
+#define MATCH_VFQWBDOTA_ALT_VV 0xbc001077
+#define MASK_VFQWBDOTA_ALT_VV 0xfc00707f
+#define MATCH_VFBDOTA_VV 0xac001077
+#define MASK_VFBDOTA_VV 0xfc00707f
/* Vendor-specific (CORE-V) Xcvmac instructions. */
#define MATCH_CV_MAC 0x9000302b
#define MASK_CV_MAC 0xfe00707f
@@ -4919,6 +4932,13 @@ DECLARE_INSN(vqwdotas_vv, MATCH_VQWDOTAS_VV, MASK_VQWDOTAS_VV)
DECLARE_INSN(vfwdota_vv, MATCH_VFWDOTA_VV, MASK_VFWDOTA_VV)
DECLARE_INSN(vfqwdota_vv, MATCH_VFQWDOTA_VV, MASK_VFQWDOTA_VV)
DECLARE_INSN(vfqwdota_alt_vv, MATCH_VFQWDOTA_ALT_VV, MASK_VFQWDOTA_ALT_VV)
+/* Zvbdota instructions. */
+DECLARE_INSN(vqwbdotau_vv, MATCH_VQWBDOTAU_VV, MASK_VQWBDOTAU_VV)
+DECLARE_INSN(vqwbdotas_vv, MATCH_VQWBDOTAS_VV, MASK_VQWBDOTAS_VV)
+DECLARE_INSN(vfwbdota_vv, MATCH_VFWBDOTA_VV, MASK_VFWBDOTA_VV)
+DECLARE_INSN(vfqwbdota_vv, MATCH_VFQWBDOTA_VV, MASK_VFQWBDOTA_VV)
+DECLARE_INSN(vfqwbdota_alt_vv, MATCH_VFQWBDOTA_ALT_VV, MASK_VFQWBDOTA_ALT_VV)
+DECLARE_INSN(vfbdota_vv, MATCH_VFBDOTA_VV, MASK_VFBDOTA_VV)
/* Zvbb/Zvkb instructions. */
DECLARE_INSN(vandn_vv, MATCH_VANDN_VV, MASK_VANDN_VV)
DECLARE_INSN(vandn_vx, MATCH_VANDN_VX, MASK_VANDN_VX)
@@ -562,7 +562,10 @@ enum riscv_insn_class
INSN_CLASS_ZVBC,
INSN_CLASS_ZVFBFMIN,
INSN_CLASS_ZVFBFWMA,
+ INSN_CLASS_ZVFBDOTA32F,
+ INSN_CLASS_ZVFQWBDOTA8F,
INSN_CLASS_ZVFQWDOTA8F,
+ INSN_CLASS_ZVFWBDOTA16BF,
INSN_CLASS_ZVFWDOTA16BF,
INSN_CLASS_ZVKB,
INSN_CLASS_ZVKG,
@@ -571,6 +574,9 @@ enum riscv_insn_class
INSN_CLASS_ZVKSED,
INSN_CLASS_ZVKSH,
INSN_CLASS_ZVABD,
+ INSN_CLASS_ZVQWBDOTA8I,
+ INSN_CLASS_ZVQWBDOTA16I,
+ INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I,
INSN_CLASS_ZVQWDOTA8I,
INSN_CLASS_ZVQWDOTA16I,
INSN_CLASS_ZVQWDOTA8I_OR_ZVQWDOTA16I,
@@ -440,6 +440,17 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
print (info->stream, dis_style_register, "%s",
riscv_vecr_names_numeric[EXTRACT_OPERAND (VS2, l)]);
break;
+ case 'q':
+ {
+ unsigned int vs2 = EXTRACT_OPERAND (VS2, l);
+ print (info->stream, dis_style_register, "%s",
+ riscv_vecr_names_numeric[vs2 & 0x18]);
+ }
+ break;
+ case 'r':
+ print (info->stream, dis_style_immediate, "%u",
+ (unsigned int) (EXTRACT_OPERAND (VS2, l) & 0x7) * 8);
+ break;
case '0':
print (info->stream, dis_style_register, "%s",
riscv_vecr_names_numeric[0]);
@@ -2257,6 +2257,14 @@ const struct riscv_opcode riscv_opcodes[] =
{"vfqwdota.vv", 0, INSN_CLASS_ZVFQWDOTA8F, "Vd,Vt,VsVm", MATCH_VFQWDOTA_VV, MASK_VFQWDOTA_VV, match_opcode, 0},
{"vfqwdota.alt.vv", 0, INSN_CLASS_ZVFQWDOTA8F, "Vd,Vt,VsVm", MATCH_VFQWDOTA_ALT_VV, MASK_VFQWDOTA_ALT_VV, match_opcode, 0},
+/* Zvbdota instructions. */
+{"vqwbdotau.vv", 0, INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I, "Vd,Vq,Vs,VrVm", MATCH_VQWBDOTAU_VV, MASK_VQWBDOTAU_VV, match_opcode, 0},
+{"vqwbdotas.vv", 0, INSN_CLASS_ZVQWBDOTA8I_OR_ZVQWBDOTA16I, "Vd,Vq,Vs,VrVm", MATCH_VQWBDOTAS_VV, MASK_VQWBDOTAS_VV, match_opcode, 0},
+{"vfwbdota.vv", 0, INSN_CLASS_ZVFWBDOTA16BF, "Vd,Vq,Vs,VrVm", MATCH_VFWBDOTA_VV, MASK_VFWBDOTA_VV, match_opcode, 0},
+{"vfqwbdota.vv", 0, INSN_CLASS_ZVFQWBDOTA8F, "Vd,Vq,Vs,VrVm", MATCH_VFQWBDOTA_VV, MASK_VFQWBDOTA_VV, match_opcode, 0},
+{"vfqwbdota.alt.vv", 0, INSN_CLASS_ZVFQWBDOTA8F, "Vd,Vq,Vs,VrVm", MATCH_VFQWBDOTA_ALT_VV, MASK_VFQWBDOTA_ALT_VV, match_opcode, 0},
+{"vfbdota.vv", 0, INSN_CLASS_ZVFBDOTA32F, "Vd,Vq,Vs,VrVm", MATCH_VFBDOTA_VV, MASK_VFBDOTA_VV, match_opcode, 0},
+
/* Zvbb/Zvkb instructions. */
{"vandn.vv", 0, INSN_CLASS_ZVKB, "Vd,Vt,VsVm", MATCH_VANDN_VV, MASK_VANDN_VV, match_opcode, 0},
{"vandn.vx", 0, INSN_CLASS_ZVKB, "Vd,Vt,sVm", MATCH_VANDN_VX, MASK_VANDN_VX, match_opcode, 0},