diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index c070394a366..9c137c01bff 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1110,6 +1110,9 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"v", "d", check_implicit_always}, {"v", "zve64d", check_implicit_always}, {"v", "zvl128b", check_implicit_always}, + {"zvfbfwma", "zvfbfmin", check_implicit_always}, + {"zvfbfmin", "zfbfmin", check_implicit_always}, + {"zvfbfmin", "zve32f", check_implicit_always}, {"zvfh", "zvfhmin", check_implicit_always}, {"zvfh", "zfhmin", check_implicit_always}, {"zvfhmin", "zve32f", check_implicit_always}, @@ -1140,6 +1143,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] = {"zcf", "f", check_implicit_always}, {"zfa", "f", check_implicit_always}, {"d", "f", check_implicit_always}, + {"zfbfmin", "f", check_implicit_always}, {"zfh", "zfhmin", check_implicit_always}, {"zfhmin", "f", check_implicit_always}, {"f", "zicsr", check_implicit_always}, @@ -1261,6 +1265,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zawrs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zfa", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 }, + {"zfbfmin", ISA_SPEC_CLASS_DRAFT, 0, 8, 0 }, {"zfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zfinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, @@ -1292,6 +1297,8 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zve64d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zvfbfmin", ISA_SPEC_CLASS_DRAFT, 0, 8, 0 }, + {"zvfbfwma", ISA_SPEC_CLASS_DRAFT, 0, 8, 0 }, {"zvfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zvkg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, @@ -2437,11 +2444,14 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, case INSN_CLASS_Q_INX: return (riscv_subset_supports (rps, "q") || riscv_subset_supports (rps, "zqinx")); + case INSN_CLASS_ZFBFMIN: + return riscv_subset_supports (rps, "zfbfmin"); case INSN_CLASS_ZFH_INX: return (riscv_subset_supports (rps, "zfh") || riscv_subset_supports (rps, "zhinx")); case INSN_CLASS_ZFHMIN: - return riscv_subset_supports (rps, "zfhmin"); + return (riscv_subset_supports (rps, "zfhmin") + || riscv_subset_supports (rps, "zfbfmin")); case INSN_CLASS_ZFHMIN_INX: return (riscv_subset_supports (rps, "zfhmin") || riscv_subset_supports (rps, "zhinxmin")); @@ -2516,6 +2526,10 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "zvbb"); case INSN_CLASS_ZVBC: return riscv_subset_supports (rps, "zvbc"); + case INSN_CLASS_ZVFBFMIN: + return riscv_subset_supports (rps, "zvfbfmin"); + case INSN_CLASS_ZVFBFWMA: + return riscv_subset_supports (rps, "zvfbfwma"); case INSN_CLASS_ZVKG: return riscv_subset_supports (rps, "zvkg"); case INSN_CLASS_ZVKNED: @@ -2657,10 +2671,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return _("d' or `zdinx"); case INSN_CLASS_Q_INX: return _("q' or `zqinx"); + case INSN_CLASS_ZFBFMIN: + return "zfbfmin"; case INSN_CLASS_ZFH_INX: return _("zfh' or `zhinx"); case INSN_CLASS_ZFHMIN: - return "zfhmin"; + return _("zfhmin' or `zfbfmin"); case INSN_CLASS_ZFHMIN_INX: return _("zfhmin' or `zhinxmin"); case INSN_CLASS_ZFHMIN_AND_D_INX: @@ -2758,6 +2774,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return _("v' or `zve64d' or `zve64f' or `zve32f"); case INSN_CLASS_ZVBB: return _("zvbb"); + case INSN_CLASS_ZVFBFMIN: + return "zvfbfmin"; + case INSN_CLASS_ZVFBFWMA: + return "zvfbfwma"; case INSN_CLASS_ZVBC: return _("zvbc"); case INSN_CLASS_ZVKG: diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 5759d3a5fc4..f2963722fc6 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -439,7 +439,7 @@ const char EXP_CHARS[] = "eE"; /* Chars that mean this number is a floating point constant. As in 0f12.456 or 0d1.2345e12. */ -const char FLT_CHARS[] = "rRsSfFdDxXpPhH"; +const char FLT_CHARS[] = "rRsSfFdDxXpPhHb"; /* Indicate we are already assemble any instructions or not. */ static bool start_assemble = false; @@ -5174,6 +5174,7 @@ static const pseudo_typeS riscv_pseudo_table[] = {"attribute", s_riscv_attribute, 0}, {"variant_cc", s_variant_cc, 0}, {"float16", float_cons, 'h'}, + {"bfloat16", float_cons, 'b'}, { NULL, NULL, 0 }, }; diff --git a/gas/testsuite/gas/riscv/bfloat16-be.d b/gas/testsuite/gas/riscv/bfloat16-be.d new file mode 100644 index 00000000000..8775ab035f6 --- /dev/null +++ b/gas/testsuite/gas/riscv/bfloat16-be.d @@ -0,0 +1,10 @@ +# source: bfloat16.s +# objdump: -sj .data +# as: -mbig-endian + +.*: +file format .* + +Contents of section \.data: + 0000 41403dfc 000042f7 8000c2f7 7fff7f80 .* + 0010 ff807f7f ff7f0080 80800001 8001007f .* + 0020 807f3f80 bf804000 c000.* diff --git a/gas/testsuite/gas/riscv/bfloat16-le.d b/gas/testsuite/gas/riscv/bfloat16-le.d new file mode 100644 index 00000000000..4de8b2fed68 --- /dev/null +++ b/gas/testsuite/gas/riscv/bfloat16-le.d @@ -0,0 +1,10 @@ +# source: bfloat16.s +# objdump: -sj .data +# as: -mlittle-endian + +.*: +file format .* + +Contents of section \.data: + 0000 4041fc3d 0000f742 0080f7c2 ff7f807f .* + 0010 80ff7f7f 7fff8000 80800100 01807f00 .* + 0020 7f80803f 80bf0040 00c0.* diff --git a/gas/testsuite/gas/riscv/bfloat16.s b/gas/testsuite/gas/riscv/bfloat16.s new file mode 100644 index 00000000000..66e17e4fc7d --- /dev/null +++ b/gas/testsuite/gas/riscv/bfloat16.s @@ -0,0 +1,19 @@ +.data + .bfloat16 12.0 + .bfloat16 0.123 + .bfloat16 +0.0 + .bfloat16 123.4 + .bfloat16 -0.0 + .bfloat16 -123.4 + .bfloat16 NaN + .bfloat16 Inf + .bfloat16 -Inf + .bfloat16 3.390e+38 + .bfloat16 -3.390e+38 + .bfloat16 1.175e-38 + .bfloat16 -1.175e-38 + .bfloat16 9.194e-41 + .bfloat16 -9.194e-41 + .bfloat16 1.167e-38 + .bfloat16 -1.167e-38 + .bfloat16 1.0, -1, 2.0, -2 diff --git a/gas/testsuite/gas/riscv/zfbfmin.d b/gas/testsuite/gas/riscv/zfbfmin.d new file mode 100644 index 00000000000..28675457a0a --- /dev/null +++ b/gas/testsuite/gas/riscv/zfbfmin.d @@ -0,0 +1,15 @@ +#as: -march=rv32i_zfbfmin +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+4485f553[ ]+fcvt\.bf16\.s[ ]+fa0,fa1 +[ ]+[0-9a-f]+:[ ]+44859553[ ]+fcvt\.bf16\.s[ ]+fa0,fa1,rtz +[ ]+[0-9a-f]+:[ ]+40658553[ ]+fcvt\.s\.bf16[ ]+fa0,fa1 +[ ]+[0-9a-f]+:[ ]+00059507[ ]+flh[ ]+fa0,0\(a1\) +[ ]+[0-9a-f]+:[ ]+00a59027[ ]+fsh[ ]+fa0,0\(a1\) +[ ]+[0-9a-f]+:[ ]+e4058553[ ]+fmv\.x\.h[ ]+a0,fa1 +[ ]+[0-9a-f]+:[ ]+f4058553[ ]+fmv\.h\.x[ ]+fa0,a1 diff --git a/gas/testsuite/gas/riscv/zfbfmin.s b/gas/testsuite/gas/riscv/zfbfmin.s new file mode 100644 index 00000000000..a0670a33ce6 --- /dev/null +++ b/gas/testsuite/gas/riscv/zfbfmin.s @@ -0,0 +1,10 @@ +target: + # Zfbfmin only instructions + fcvt.bf16.s fa0, fa1 + fcvt.bf16.s fa0, fa1, rtz + fcvt.s.bf16 fa0, fa1 + # Instructions shared with Zfhmin + flh fa0, 0(a1) + fsh fa0, 0(a1) + fmv.x.h a0, fa1 + fmv.h.x fa0, a1 diff --git a/gas/testsuite/gas/riscv/zvfbfmin.d b/gas/testsuite/gas/riscv/zvfbfmin.d new file mode 100644 index 00000000000..b15cff81871 --- /dev/null +++ b/gas/testsuite/gas/riscv/zvfbfmin.d @@ -0,0 +1,12 @@ +#as: -march=rv32i_zvfbfmin +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+4a8e9257[ ]+vfncvtbf16\.f\.f\.w[ ]+v4,v8 +[ ]+[0-9a-f]+:[ ]+488e9257[ ]+vfncvtbf16\.f\.f\.w[ ]+v4,v8,v0\.t +[ ]+[0-9a-f]+:[ ]+4a869257[ ]+vfwcvtbf16\.f\.f\.v[ ]+v4,v8 +[ ]+[0-9a-f]+:[ ]+48869257[ ]+vfwcvtbf16\.f\.f\.v[ ]+v4,v8,v0\.t diff --git a/gas/testsuite/gas/riscv/zvfbfmin.s b/gas/testsuite/gas/riscv/zvfbfmin.s new file mode 100644 index 00000000000..e732e6ba99b --- /dev/null +++ b/gas/testsuite/gas/riscv/zvfbfmin.s @@ -0,0 +1,5 @@ +target: + vfncvtbf16.f.f.w v4, v8 + vfncvtbf16.f.f.w v4, v8, v0.t + vfwcvtbf16.f.f.v v4, v8 + vfwcvtbf16.f.f.v v4, v8, v0.t diff --git a/gas/testsuite/gas/riscv/zvfbfwma.d b/gas/testsuite/gas/riscv/zvfbfwma.d new file mode 100644 index 00000000000..3597bde0e4a --- /dev/null +++ b/gas/testsuite/gas/riscv/zvfbfwma.d @@ -0,0 +1,12 @@ +#as: -march=rv32i_zvfbfwma +#objdump: -d + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+ee861257[ ]+vfwmaccbf16.vv[ ]+v4,v8,v12 +[ ]+[0-9a-f]+:[ ]+ee865257[ ]+vfwmaccbf16.vf[ ]+v4,v8,fa2 +[ ]+[0-9a-f]+:[ ]+ec861257[ ]+vfwmaccbf16.vv[ ]+v4,v8,v12,v0.t +[ ]+[0-9a-f]+:[ ]+ec865257[ ]+vfwmaccbf16.vf[ ]+v4,v8,fa2,v0.t diff --git a/gas/testsuite/gas/riscv/zvfbfwma.s b/gas/testsuite/gas/riscv/zvfbfwma.s new file mode 100644 index 00000000000..d44c09c27f1 --- /dev/null +++ b/gas/testsuite/gas/riscv/zvfbfwma.s @@ -0,0 +1,5 @@ +target: + vfwmaccbf16.vv v4, v8, v12 + vfwmaccbf16.vf v4, v8, fa2 + vfwmaccbf16.vv v4, v8, v12, v0.t + vfwmaccbf16.vf v4, v8, fa2, v0.t diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 375483500e2..155ff3f16cf 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2121,6 +2121,11 @@ #define MASK_VDOTUVV 0xfc00707f #define MATCH_VFDOTVV 0xe4001057 #define MASK_VFDOTVV 0xfc00707f +/* Zfbfmin instructions. */ +#define MATCH_FCVT_BF16_S 0x44800053 +#define MASK_FCVT_BF16_S 0xfff0007f +#define MATCH_FCVT_S_BF16 0x40600053 +#define MASK_FCVT_S_BF16 0xfff0007f /* Zvbb instructions. */ #define MATCH_VANDN_VV 0x4000057 #define MASK_VANDN_VV 0xfc00707f @@ -2163,6 +2168,16 @@ #define MASK_VCLMULH_VV 0xfc00707f #define MATCH_VCLMULH_VX 0x34006057 #define MASK_VCLMULH_VX 0xfc00707f +/* Zvfbfmin instructions. */ +#define MATCH_VFNCVTBF16_F_F_W 0x480e9057 +#define MASK_VFNCVTBF16_F_F_W 0xfc0ff07f +#define MATCH_VFWCVTBF16_F_F_V 0x48069057 +#define MASK_VFWCVTBF16_F_F_V 0xfc0ff07f +/* Zvfbfwma instructions. */ +#define MATCH_VFWMACCBF16_VF 0xec005057 +#define MASK_VFWMACCBF16_VF 0xfc00707f +#define MATCH_VFWMACCBF16_VV 0xec001057 +#define MASK_VFWMACCBF16_VV 0xfc00707f /* Zvkg instructions. */ #define MATCH_VGHSH_VV 0xb2002077 #define MASK_VGHSH_VV 0xfe00707f @@ -3373,6 +3388,9 @@ DECLARE_INSN(c_ntl_all, MATCH_C_NTL_ALL, MASK_C_NTL_ALL) /* Zawrs instructions. */ DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO) DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO) +/* Zfbfmin instructions. */ +DECLARE_INSN(fcvt_bf16_s, MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S) +DECLARE_INSN(fcvt_s_bf16, MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16) /* Zvbb instructions. */ DECLARE_INSN(vandn_vv, MATCH_VANDN_VV, MASK_VANDN_VV) DECLARE_INSN(vandn_vx, MATCH_VANDN_VX, MASK_VANDN_VX) @@ -3395,6 +3413,12 @@ DECLARE_INSN(vclmul_vv, MATCH_VCLMUL_VV, MASK_VCLMUL_VV) DECLARE_INSN(vclmul_vx, MATCH_VCLMUL_VX, MASK_VCLMUL_VX) DECLARE_INSN(vclmulh_vv, MATCH_VCLMULH_VV, MASK_VCLMULH_VV) DECLARE_INSN(vclmulh_vx, MATCH_VCLMULH_VX, MASK_VCLMULH_VX) +/* Zvfbfmin instructions. */ +DECLARE_INSN(vfncvtbf16_f_f_w, MATCH_VFNCVTBF16_F_F_W, MASK_VFNCVTBF16_F_F_W) +DECLARE_INSN(vfwcvtbf16_f_f_v, MATCH_VFWCVTBF16_F_F_V, MASK_VFWCVTBF16_F_F_V) +/* Zvfbfwma instructions. */ +DECLARE_INSN(vfwmaccbf16_vf, MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF) +DECLARE_INSN(vfwmaccbf16_vv, MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV) /* Zvkg instructions. */ DECLARE_INSN(vghsh_vv, MATCH_VGHSH_VV, MASK_VGHSH_VV) DECLARE_INSN(vgmul_vv, MATCH_VGMUL_VV, MASK_VGMUL_VV) diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 93dd5169ebc..e810944f768 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -400,6 +400,7 @@ enum riscv_insn_class INSN_CLASS_F_INX, INSN_CLASS_D_INX, INSN_CLASS_Q_INX, + INSN_CLASS_ZFBFMIN, INSN_CLASS_ZFH_INX, INSN_CLASS_ZFHMIN, INSN_CLASS_ZFHMIN_INX, @@ -429,6 +430,8 @@ enum riscv_insn_class INSN_CLASS_ZVEF, INSN_CLASS_ZVBB, INSN_CLASS_ZVBC, + INSN_CLASS_ZVFBFMIN, + INSN_CLASS_ZVFBFWMA, INSN_CLASS_ZVKG, INSN_CLASS_ZVKNED, INSN_CLASS_ZVKNHA_OR_ZVKNHB, diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 8e0ae85eb06..b1324b275e2 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -986,6 +986,11 @@ const struct riscv_opcode riscv_opcodes[] = {"wrs.nto", 0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 }, {"wrs.sto", 0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 }, +/* Zfbfmin instructions. */ +{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN, "D,S", MATCH_FCVT_BF16_S|MASK_RM, MASK_FCVT_BF16_S|MASK_RM, match_opcode, 0 }, +{"fcvt.bf16.s", 0, INSN_CLASS_ZFBFMIN, "D,S,m", MATCH_FCVT_BF16_S, MASK_FCVT_BF16_S, match_opcode, 0 }, +{"fcvt.s.bf16", 0, INSN_CLASS_ZFBFMIN, "D,S", MATCH_FCVT_S_BF16, MASK_FCVT_S_BF16|MASK_RM, match_opcode, 0 }, + /* Zfa instructions. */ {"fli.s", 0, INSN_CLASS_ZFA, "D,Wfv", MATCH_FLI_S, MASK_FLI_S, match_opcode, 0 }, {"fli.d", 0, INSN_CLASS_D_AND_ZFA, "D,Wfv", MATCH_FLI_D, MASK_FLI_D, match_opcode, 0 }, @@ -1933,6 +1938,14 @@ const struct riscv_opcode riscv_opcodes[] = {"vclmulh.vv", 0, INSN_CLASS_ZVBC, "Vd,Vt,VsVm", MATCH_VCLMULH_VV, MASK_VCLMULH_VV, match_opcode, 0}, {"vclmulh.vx", 0, INSN_CLASS_ZVBC, "Vd,Vt,sVm", MATCH_VCLMULH_VX, MASK_VCLMULH_VX, match_opcode, 0}, +/* Zvfbfmin instructions. */ +{"vfncvtbf16.f.f.w", 0, INSN_CLASS_ZVFBFMIN, "Vd,VtVm", MATCH_VFNCVTBF16_F_F_W, MASK_VFNCVTBF16_F_F_W, match_opcode, 0}, +{"vfwcvtbf16.f.f.v", 0, INSN_CLASS_ZVFBFMIN, "Vd,VtVm", MATCH_VFWCVTBF16_F_F_V, MASK_VFWCVTBF16_F_F_V, match_opcode, 0}, + +/* Zvfbfwma instructions. */ +{"vfwmaccbf16.vv", 0, INSN_CLASS_ZVFBFWMA, "Vd,Vt,VsVm", MATCH_VFWMACCBF16_VV, MASK_VFWMACCBF16_VV, match_opcode, 0}, +{"vfwmaccbf16.vf", 0, INSN_CLASS_ZVFBFWMA, "Vd,Vt,SVm", MATCH_VFWMACCBF16_VF, MASK_VFWMACCBF16_VF, match_opcode, 0}, + /* Zvkg instructions. */ {"vghsh.vv", 0, INSN_CLASS_ZVKG, "Vd,Vt,Vs", MATCH_VGHSH_VV, MASK_VGHSH_VV, match_opcode, 0}, {"vgmul.vv", 0, INSN_CLASS_ZVKG, "Vd,Vt", MATCH_VGMUL_VV, MASK_VGMUL_VV, match_opcode, 0},