diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index c89b1e53e92..fca56b2512b 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1168,6 +1168,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] = {"zihintpause", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 }, {"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {"zawrs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, + {"zfb", ISA_SPEC_CLASS_DRAFT, 0, 1, 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 }, @@ -2361,6 +2362,14 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, && riscv_subset_supports (rps, "q")) || (riscv_subset_supports (rps, "zhinxmin") && riscv_subset_supports (rps, "zqinx"))); + case INSN_CLASS_ZFB: + return riscv_subset_supports (rps, "zfb"); + case INSN_CLASS_D_AND_ZFB: + return riscv_subset_supports (rps, "d") + && riscv_subset_supports (rps, "zfb"); + case INSN_CLASS_Q_AND_ZFB: + return riscv_subset_supports (rps, "q") + && riscv_subset_supports (rps, "zfb"); case INSN_CLASS_ZBA: return riscv_subset_supports (rps, "zba"); case INSN_CLASS_ZBB: @@ -2523,6 +2532,24 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "zhinxmin"; else return _("zfhmin' and `q', or `zhinxmin' and `zqinx"); + case INSN_CLASS_ZFB: + return "zfb"; + case INSN_CLASS_D_AND_ZFB: + if (!riscv_subset_supports (rps, "d") + && !riscv_subset_supports (rps, "zfb")) + return _("d' and `zfb"); + else if (!riscv_subset_supports (rps, "d")) + return "d"; + else + return "zfb"; + case INSN_CLASS_Q_AND_ZFB: + if (!riscv_subset_supports (rps, "q") + && !riscv_subset_supports (rps, "zfb")) + return _("q' and `zfb"); + else if (!riscv_subset_supports (rps, "q")) + return "q"; + else + return "zfb"; case INSN_CLASS_ZBA: return "zba"; case INSN_CLASS_ZBB: diff --git a/gas/testsuite/gas/riscv/zfb-32.d b/gas/testsuite/gas/riscv/zfb-32.d new file mode 100644 index 00000000000..847780c269c --- /dev/null +++ b/gas/testsuite/gas/riscv/zfb-32.d @@ -0,0 +1,11 @@ +#as: -march=rv32id_zfb +#source: zfb-32.s +#objdump: -dr + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+e2108553[ ]+fmvh\.x\.d[ ]+a0,ft1 +[ ]+[0-9a-f]+:[ ]+b2b500d3[ ]+fmvp\.d\.x[ ]+ft1,a0,a1 diff --git a/gas/testsuite/gas/riscv/zfb-32.s b/gas/testsuite/gas/riscv/zfb-32.s new file mode 100644 index 00000000000..da95441cdc7 --- /dev/null +++ b/gas/testsuite/gas/riscv/zfb-32.s @@ -0,0 +1,3 @@ +target: + fmvh.x.d a0, ft1 + fmvp.d.x ft1, a0, a1 diff --git a/gas/testsuite/gas/riscv/zfb-64.d b/gas/testsuite/gas/riscv/zfb-64.d new file mode 100644 index 00000000000..d49b16c8ac9 --- /dev/null +++ b/gas/testsuite/gas/riscv/zfb-64.d @@ -0,0 +1,11 @@ +#as: -march=rv64iq_zfb +#source: zfb-64.s +#objdump: -dr + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+e6108553[ ]+fmvh\.x\.q[ ]+a0,ft1 +[ ]+[0-9a-f]+:[ ]+b6b500d3[ ]+fmvp\.q\.x[ ]+ft1,a0,a1 diff --git a/gas/testsuite/gas/riscv/zfb-64.s b/gas/testsuite/gas/riscv/zfb-64.s new file mode 100644 index 00000000000..dc8129dae3e --- /dev/null +++ b/gas/testsuite/gas/riscv/zfb-64.s @@ -0,0 +1,3 @@ +target: + fmvh.x.q a0, ft1 + fmvp.q.x ft1, a0, a1 diff --git a/gas/testsuite/gas/riscv/zfb.d b/gas/testsuite/gas/riscv/zfb.d new file mode 100644 index 00000000000..93764c61aac --- /dev/null +++ b/gas/testsuite/gas/riscv/zfb.d @@ -0,0 +1,33 @@ +#as: -march=rv64iq_zfb +#source: zfb.s +#objdump: -dr + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+283100d3[ ]+fmin\.s[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+283120d3[ ]+fmini\.s[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2a3100d3[ ]+fmin\.d[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2a3120d3[ ]+fmini\.d[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2e3100d3[ ]+fmin\.q[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2e3120d3[ ]+fmini\.q[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+283110d3[ ]+fmax\.s[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+283130d3[ ]+fmaxi\.s[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2a3110d3[ ]+fmax\.d[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2a3130d3[ ]+fmaxi\.d[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2e3110d3[ ]+fmax\.q[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+2e3130d3[ ]+fmaxi\.q[ ]+ft1,ft2,ft3 +[ ]+[0-9a-f]+:[ ]+a0209553[ ]+flt\.s[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a020d553[ ]+fltq\.s[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a2209553[ ]+flt\.d[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a220d553[ ]+fltq\.d[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a6209553[ ]+flt\.q[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a620d553[ ]+fltq\.q[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a0208553[ ]+fle\.s[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a020c553[ ]+fleq\.s[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a2208553[ ]+fle\.d[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a220c553[ ]+fleq\.d[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a6208553[ ]+fle\.q[ ]+a0,ft1,ft2 +[ ]+[0-9a-f]+:[ ]+a620c553[ ]+fleq\.q[ ]+a0,ft1,ft2 diff --git a/gas/testsuite/gas/riscv/zfb.s b/gas/testsuite/gas/riscv/zfb.s new file mode 100644 index 00000000000..6a4f6573e17 --- /dev/null +++ b/gas/testsuite/gas/riscv/zfb.s @@ -0,0 +1,27 @@ +target: + # fmini/fmaxi (Zfb): same as fmin/fmax (F/D/Q) except bit 13 set + fmin.s ft1, ft2, ft3 + fmini.s ft1, ft2, ft3 + fmin.d ft1, ft2, ft3 + fmini.d ft1, ft2, ft3 + fmin.q ft1, ft2, ft3 + fmini.q ft1, ft2, ft3 + fmax.s ft1, ft2, ft3 + fmaxi.s ft1, ft2, ft3 + fmax.d ft1, ft2, ft3 + fmaxi.d ft1, ft2, ft3 + fmax.q ft1, ft2, ft3 + fmaxi.q ft1, ft2, ft3 + # fltq/fleq (Zfb): same as flt/fle (F/D/Q) except bit 14 set + flt.s a0, ft1, ft2 + fltq.s a0, ft1, ft2 + flt.d a0, ft1, ft2 + fltq.d a0, ft1, ft2 + flt.q a0, ft1, ft2 + fltq.q a0, ft1, ft2 + fle.s a0, ft1, ft2 + fleq.s a0, ft1, ft2 + fle.d a0, ft1, ft2 + fleq.d a0, ft1, ft2 + fle.q a0, ft1, ft2 + fleq.q a0, ft1, ft2 diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index e40592159cd..cb703db39a3 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -419,6 +419,38 @@ #define MASK_FCVT_Q_L 0xfff0007f #define MATCH_FCVT_Q_LU 0xd6300053 #define MASK_FCVT_Q_LU 0xfff0007f +#define MATCH_FMINI_S 0x28002053 +#define MASK_FMINI_S 0xfe00707f +#define MATCH_FMAXI_S 0x28003053 +#define MASK_FMAXI_S 0xfe00707f +#define MATCH_FLTQ_S 0xa0005053 +#define MASK_FLTQ_S 0xfe00707f +#define MATCH_FLEQ_S 0xa0004053 +#define MASK_FLEQ_S 0xfe00707f +#define MATCH_FMINI_D 0x2a002053 +#define MASK_FMINI_D 0xfe00707f +#define MATCH_FMAXI_D 0x2a003053 +#define MASK_FMAXI_D 0xfe00707f +#define MATCH_FLTQ_D 0xa2005053 +#define MASK_FLTQ_D 0xfe00707f +#define MATCH_FLEQ_D 0xa2004053 +#define MASK_FLEQ_D 0xfe00707f +#define MATCH_FMINI_Q 0x2e002053 +#define MASK_FMINI_Q 0xfe00707f +#define MATCH_FMAXI_Q 0x2e003053 +#define MASK_FMAXI_Q 0xfe00707f +#define MATCH_FLTQ_Q 0xa6005053 +#define MASK_FLTQ_Q 0xfe00707f +#define MATCH_FLEQ_Q 0xa6004053 +#define MASK_FLEQ_Q 0xfe00707f +#define MATCH_FMVH_X_D 0xe2100053 +#define MASK_FMVH_X_D 0xfff0707f +#define MATCH_FMVH_X_Q 0xe6100053 +#define MASK_FMVH_X_Q 0xfff0707f +#define MATCH_FMVP_D_X 0xb2000053 +#define MASK_FMVP_D_X 0xfe00707f +#define MATCH_FMVP_Q_X 0xb6000053 +#define MASK_FMVP_Q_X 0xfe00707f #define MATCH_CLZ 0x60001013 #define MASK_CLZ 0xfff0707f #define MATCH_CTZ 0x60101013 @@ -2937,6 +2969,22 @@ DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W) DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU) DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) +DECLARE_INSN(fmini_s, MATCH_FMINI_S, MASK_FMINI_S) +DECLARE_INSN(fmaxi_s, MATCH_FMAXI_S, MASK_FMAXI_S) +DECLARE_INSN(fltq_s, MATCH_FLTQ_S, MASK_FLTQ_S) +DECLARE_INSN(fleq_s, MATCH_FLEQ_S, MASK_FLEQ_S) +DECLARE_INSN(fmini_d, MATCH_FMINI_D, MASK_FMINI_D) +DECLARE_INSN(fmaxi_d, MATCH_FMAXI_D, MASK_FMAXI_D) +DECLARE_INSN(fltq_d, MATCH_FLTQ_D, MASK_FLTQ_D) +DECLARE_INSN(fleq_d, MATCH_FLEQ_D, MASK_FLEQ_D) +DECLARE_INSN(fmini_q, MATCH_FMINI_Q, MASK_FMINI_Q) +DECLARE_INSN(fmaxi_q, MATCH_FMAXI_Q, MASK_FMAXI_Q) +DECLARE_INSN(fltq_q, MATCH_FLTQ_Q, MASK_FLTQ_Q) +DECLARE_INSN(fleq_q, MATCH_FLEQ_Q, MASK_FLEQ_Q) +DECLARE_INSN(fmvh_x_d, MATCH_FMVH_X_D, MASK_FMVH_X_D) +DECLARE_INSN(fmvh_x_q, MATCH_FMVH_X_Q, MASK_FMVH_X_Q) +DECLARE_INSN(fmvp_d_x, MATCH_FMVP_D_X, MASK_FMVP_D_X) +DECLARE_INSN(fmvp_q_x, MATCH_FMVP_Q_X, MASK_FMVP_Q_X) DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ) DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ) DECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP) diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index dddabfdd415..2fe7cb85421 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -388,6 +388,9 @@ enum riscv_insn_class INSN_CLASS_ZFHMIN_INX, INSN_CLASS_ZFHMIN_AND_D_INX, INSN_CLASS_ZFHMIN_AND_Q_INX, + INSN_CLASS_ZFB, + INSN_CLASS_D_AND_ZFB, + INSN_CLASS_Q_AND_ZFB, INSN_CLASS_ZBA, INSN_CLASS_ZBB, INSN_CLASS_ZBC, diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 4029c1881b8..03cd1e1a36b 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -760,6 +760,10 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.s.l", 64, INSN_CLASS_F_INX, "D,s,m", MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, 0 }, {"fcvt.s.lu", 64, INSN_CLASS_F_INX, "D,s", MATCH_FCVT_S_LU|MASK_RM, MASK_FCVT_S_LU|MASK_RM, match_opcode, 0 }, {"fcvt.s.lu", 64, INSN_CLASS_F_INX, "D,s,m", MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 }, +{"fmini.s", 0, INSN_CLASS_ZFB, "D,S,T", MATCH_FMINI_S, MASK_FMINI_S, match_opcode, 0 }, +{"fmaxi.s", 0, INSN_CLASS_ZFB, "D,S,T", MATCH_FMAXI_S, MASK_FMAXI_S, match_opcode, 0 }, +{"fltq.s", 0, INSN_CLASS_ZFB, "d,S,T", MATCH_FLTQ_S, MASK_FLTQ_S, match_opcode, 0 }, +{"fleq.s", 0, INSN_CLASS_ZFB, "d,S,T", MATCH_FLEQ_S, MASK_FLEQ_S, match_opcode, 0 }, /* Double-precision floating-point instruction subset. */ {"fld", 0, INSN_CLASS_D_AND_C, "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE }, @@ -821,6 +825,12 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.d.l", 64, INSN_CLASS_D_INX, "D,s,m", MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, 0 }, {"fcvt.d.lu", 64, INSN_CLASS_D_INX, "D,s", MATCH_FCVT_D_LU|MASK_RM, MASK_FCVT_D_LU|MASK_RM, match_opcode, 0 }, {"fcvt.d.lu", 64, INSN_CLASS_D_INX, "D,s,m", MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, 0 }, +{"fmini.d", 0, INSN_CLASS_D_AND_ZFB, "D,S,T", MATCH_FMINI_D, MASK_FMINI_D, match_opcode, 0 }, +{"fmaxi.d", 0, INSN_CLASS_D_AND_ZFB, "D,S,T", MATCH_FMAXI_D, MASK_FMAXI_D, match_opcode, 0 }, +{"fltq.d", 0, INSN_CLASS_D_AND_ZFB, "d,S,T", MATCH_FLTQ_D, MASK_FLTQ_D, match_opcode, 0 }, +{"fleq.d", 0, INSN_CLASS_D_AND_ZFB, "d,S,T", MATCH_FLEQ_D, MASK_FLEQ_D, match_opcode, 0 }, +{"fmvh.x.d", 32, INSN_CLASS_D_AND_ZFB, "d,S", MATCH_FMVH_X_D, MASK_FMVH_X_D, match_opcode, 0}, +{"fmvp.d.x", 32, INSN_CLASS_D_AND_ZFB, "D,s,t", MATCH_FMVP_D_X, MASK_FMVP_D_X, match_opcode, 0}, /* Quad-precision floating-point instruction subset. */ {"flq", 0, INSN_CLASS_Q, "D,o(s)", MATCH_FLQ, MASK_FLQ, match_opcode, INSN_DREF|INSN_16_BYTE }, @@ -879,6 +889,12 @@ const struct riscv_opcode riscv_opcodes[] = {"fcvt.q.l", 64, INSN_CLASS_Q_INX, "D,s,m", MATCH_FCVT_Q_L, MASK_FCVT_Q_L, match_opcode, 0 }, {"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU|MASK_RM, match_opcode, 0 }, {"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s,m", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 }, +{"fmini.q", 0, INSN_CLASS_Q_AND_ZFB, "D,S,T", MATCH_FMINI_Q, MASK_FMINI_Q, match_opcode, 0 }, +{"fmaxi.q", 0, INSN_CLASS_Q_AND_ZFB, "D,S,T", MATCH_FMAXI_Q, MASK_FMAXI_Q, match_opcode, 0 }, +{"fltq.q", 0, INSN_CLASS_Q_AND_ZFB, "d,S,T", MATCH_FLTQ_Q, MASK_FLTQ_Q, match_opcode, 0 }, +{"fleq.q", 0, INSN_CLASS_Q_AND_ZFB, "d,S,T", MATCH_FLEQ_Q, MASK_FLEQ_Q, match_opcode, 0 }, +{"fmvh.x.q", 64, INSN_CLASS_Q_AND_ZFB, "d,S", MATCH_FMVH_X_Q, MASK_FMVH_X_Q, match_opcode, 0}, +{"fmvp.q.x", 64, INSN_CLASS_Q_AND_ZFB, "D,s,t", MATCH_FMVP_Q_X, MASK_FMVP_Q_X, match_opcode, 0}, /* Compressed instructions. */ {"c.unimp", 0, INSN_CLASS_C, "", 0, 0xffffU, match_opcode, 0 },