@@ -1362,6 +1362,7 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{"xcvmac", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xcvalu", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xcvelw", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xcvbi", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xtheadba", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xtheadbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"xtheadbs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
@@ -2559,6 +2560,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "xcvalu");
case INSN_CLASS_XCVELW:
return riscv_subset_supports (rps, "xcvelw");
+ case INSN_CLASS_XCVBI:
+ return riscv_subset_supports (rps, "xcvbi");
case INSN_CLASS_XTHEADBA:
return riscv_subset_supports (rps, "xtheadba");
case INSN_CLASS_XTHEADBB:
@@ -2805,6 +2808,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "xcvalu";
case INSN_CLASS_XCVELW:
return "xcvelw";
+ case INSN_CLASS_XCVBI:
+ return "xcvbi";
case INSN_CLASS_XTHEADBA:
return "xtheadba";
case INSN_CLASS_XTHEADBB:
@@ -1485,7 +1485,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
switch (*++oparg)
{
case '2':
- /* ls2[4:0] */
+ case '4':
used_bits |= ENCODE_CV_IS2_UIMM5 (-1U);
break;
case '3':
@@ -3618,6 +3618,16 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
ip->insn_opcode
|= ENCODE_CV_IS3_UIMM5 (imm_expr->X_add_number);
continue;
+ case '4':
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ asarg = expr_parse_end;
+ if (imm_expr->X_add_number < -16
+ || imm_expr->X_add_number > 15)
+ break;
+ ip->insn_opcode
+ |= ENCODE_CV_IS2_UIMM5 (imm_expr->X_add_number);
+ continue;
default:
goto unknown_riscv_ip_operand;
}
@@ -759,6 +759,11 @@ The Xcvelw extension provides instructions for event load word operations.
It is documented in @url{https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html}
+@item Xcvbi
+The Xcvbi extension provides instructions for branch immediate operations.
+
+It is documented in @url{https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html}
+
@item XTheadBa
The XTheadBa extension provides instructions for address calculations.
new file mode 100644
@@ -0,0 +1,12 @@
+#as: -march=rv32i_xcvbi
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+[ ]+0:[ ]+0102e00b[ ]+cv.beqimm[ ]+t0,-16,0 +<foo>
+[ ]+4:[ ]+fe5eee8b[ ]+cv.beqimm[ ]+t4,5,0 +<foo>
+[ ]+8:[ ]+fef3ec8b[ ]+cv.beqimm[ ]+t2,15,0 +<foo>
new file mode 100644
@@ -0,0 +1,4 @@
+foo:
+ cv.beqimm t0, -16, foo
+ cv.beqimm t4, 5, foo
+ cv.beqimm t2, 15, foo
new file mode 100644
@@ -0,0 +1,12 @@
+#as: -march=rv32i_xcvbi
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+[ ]+0:[ ]+0102f00b[ ]+cv.bneimm[ ]+t0,-16,0 +<foo>
+[ ]+4:[ ]+fe5efe8b[ ]+cv.bneimm[ ]+t4,5,0 +<foo>
+[ ]+8:[ ]+fef3fc8b[ ]+cv.bneimm[ ]+t2,15,0 +<foo>
new file mode 100644
@@ -0,0 +1,4 @@
+foo:
+ cv.bneimm t0, -16, foo
+ cv.bneimm t4, 5, foo
+ cv.bneimm t2, 15, foo
new file mode 100644
@@ -0,0 +1,3 @@
+#as: -march=rv32i
+#source: cv-bi-fail-march.s
+#error_output: cv-bi-fail-march.l
new file mode 100644
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*: Error: unrecognized opcode `cv.beqimm t2,1,foo', extension `xcvbi' required
+.*: Error: unrecognized opcode `cv.bneimm t2,1,foo', extension `xcvbi' required
new file mode 100644
@@ -0,0 +1,5 @@
+# Absence of xcorev or xcorevbi march option disables all CORE-V
+# immediate branching extensions.
+foo:
+ cv.beqimm t2, 1, foo
+ cv.bneimm t2, 1, foo
new file mode 100644
@@ -0,0 +1,3 @@
+#as: -march=rv32i_xcvbi
+#source: cv-bi-fail-operand-01.s
+#error_output: cv-bi-fail-operand-01.l
new file mode 100644
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*: Error: illegal operands `cv.beqimm 20,10,foo'
+.*: Error: illegal operands `cv.bneimm 8,-4,foo'
new file mode 100644
@@ -0,0 +1,4 @@
+# Comparison target must be a register
+foo:
+ cv.beqimm 20, 10, foo
+ cv.bneimm 8, -4, foo
new file mode 100644
@@ -0,0 +1,3 @@
+#as: -march=rv32i_xcvbi
+#source: cv-bi-fail-operand-02.s
+#error_output: cv-bi-fail-operand-02.l
new file mode 100644
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*: Error: instruction cv.beqimm requires absolute expression
+.*: Error: instruction cv.bneimm requires absolute expression
new file mode 100644
@@ -0,0 +1,4 @@
+# Comparison value must be an immediate
+foo:
+ cv.beqimm t0, t1, foo
+ cv.bneimm t3, t4, foo
new file mode 100644
@@ -0,0 +1,3 @@
+#as: -march=rv32i_xcvbi
+#source: cv-bi-fail-operand-03.s
+#error_output: cv-bi-fail-operand-03.l
new file mode 100644
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*: Error: illegal operands `cv.beqimm t0,-17,foo'
+.*: Error: illegal operands `cv.beqimm t2,-32,foo'
+.*: Error: illegal operands `cv.beqimm t4,16,foo'
+.*: Error: illegal operands `cv.beqimm t3,44,foo'
+.*: Error: illegal operands `cv.bneimm t0,-17,foo'
+.*: Error: illegal operands `cv.bneimm t2,-32,foo'
+.*: Error: illegal operands `cv.bneimm t4,16,foo'
+.*: Error: illegal operands `cv.bneimm t3,44,foo'
new file mode 100644
@@ -0,0 +1,10 @@
+# Comparison value must be an immediate in range [-16, +15]
+foo:
+ cv.beqimm t0, -17, foo
+ cv.beqimm t2, -32, foo
+ cv.beqimm t4, 16, foo
+ cv.beqimm t3, 44, foo
+ cv.bneimm t0, -17, foo
+ cv.bneimm t2, -32, foo
+ cv.bneimm t4, 16, foo
+ cv.bneimm t3, 44, foo
@@ -2427,6 +2427,11 @@
/* Vendor-specific (CORE-V) Xcvelw instructions. */
#define MATCH_CV_ELW 0x6003
#define MASK_CV_ELW 0x707f
+/* Vendor-specific (CORE-V) Xcvbi instructions. */
+#define MATCH_CV_BNEIMM 0x700b
+#define MASK_CV_BNEIMM 0x707f
+#define MATCH_CV_BEQIMM 0x600b
+#define MASK_CV_BEQIMM 0x707f
/* Vendor-specific (T-Head) XTheadBa instructions. */
#define MATCH_TH_ADDSL 0x0000100b
#define MASK_TH_ADDSL 0xf800707f
@@ -55,6 +55,7 @@ static inline unsigned int riscv_insn_length (insn_t insn)
#define RV_X(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1))
#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
#define RV_X_SIGNED(x, s, n) (RV_X(x, s, n) | ((-(RV_X(x, (s + n - 1), 1))) << (n)))
+#define RV_IMM_SIGN_N(x, s, n) (-(((x) >> ((s) + (n) - 1)) & 1))
#define EXTRACT_ITYPE_IMM(x) \
(RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
@@ -117,6 +118,8 @@ static inline unsigned int riscv_insn_length (insn_t insn)
(RV_X(x, 20, 5))
#define EXTRACT_CV_IS3_UIMM5(x) \
(RV_X(x, 25, 5))
+#define EXTRACT_CV_BI_IMM5(x) \
+ (RV_X(x, 20, 5) | (RV_IMM_SIGN_N(x, 20, 5) << 5))
#define ENCODE_ITYPE_IMM(x) \
(RV_X(x, 0, 12) << 20)
@@ -456,6 +459,7 @@ enum riscv_insn_class
INSN_CLASS_XCVMAC,
INSN_CLASS_XCVALU,
INSN_CLASS_XCVELW,
+ INSN_CLASS_XCVBI,
INSN_CLASS_XTHEADBA,
INSN_CLASS_XTHEADBB,
INSN_CLASS_XTHEADBS,
new file mode 100644
@@ -0,0 +1,21 @@
+#name: beqimm relocation
+#source: cv-bi-beqimm.s
+#as: -march=rv32i_xcvbi
+#ld: -melf32lriscv
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <func>:
+.*:[[:space:]]+00008067[[:space:]]+ret
+
+.* <_start>:
+.*:[[:space:]]+0102e40b[[:space:]]+cv.beqimm[[:space:]]+t0,-16,.*[[:space:]]+<L2>
+.*:[[:space:]]+ff9ff0ef[[:space:]]+jal[[:space:]]+10074[[:space:]]+<func>
+
+.* <L2>:
+.*:[[:space:]]+00000013[[:space:]]+nop
+#pass
new file mode 100644
@@ -0,0 +1,11 @@
+ .option nopic
+ .text
+ .align 1
+ .globl _start
+ .type _start, @function
+
+func: ret
+_start:
+ cv.beqimm t0, -16, L2
+ call func
+L2: nop
new file mode 100644
@@ -0,0 +1,21 @@
+#name: bneimm relocation
+#source: cv-bi-bneimm.s
+#as: -march=rv32i_xcvbi
+#ld: -melf32lriscv
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <func>:
+.*:[[:space:]]+00008067[[:space:]]+ret
+
+.* <_start>:
+.*:[[:space:]]+0102f40b[[:space:]]+cv.bneimm[[:space:]]+t0,-16,.*[[:space:]]+<L2>
+.*:[[:space:]]+ff9ff0ef[[:space:]]+jal[[:space:]]+10074[[:space:]]+<func>
+
+.* <L2>:
+.*:[[:space:]]+00000013[[:space:]]+nop
+#pass
new file mode 100644
@@ -0,0 +1,11 @@
+ .option nopic
+ .text
+ .align 1
+ .globl _start
+ .type _start, @function
+
+func: ret
+_start:
+ cv.bneimm t0, -16, L2
+ call func
+L2: nop
@@ -173,6 +173,8 @@ if [istarget "riscv*-*-*"] {
run_dump_test "attr-phdr"
run_dump_test "relax-max-align-gp"
run_dump_test "uleb128"
+ run_dump_test "cv-bi-bneimm"
+ run_dump_test "cv-bi-beqimm"
run_ld_link_tests [list \
[list "Weak reference 32" "-T weakref.ld -m[riscv_choose_ilp32_emul]" "" \
"-march=rv32i -mabi=ilp32" {weakref32.s} \
@@ -688,6 +688,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
print (info->stream, dis_style_immediate, "%d",
((int) EXTRACT_CV_IS3_UIMM5 (l)));
break;
+ case '4':
+ print (info->stream, dis_style_immediate, "%d",
+ ((int) EXTRACT_CV_BI_IMM5 (l)));
+ break;
default:
goto undefined_modifier;
}
@@ -2103,6 +2103,10 @@ const struct riscv_opcode riscv_opcodes[] =
/* Vendor-specific (CORE-V) Xcvelw instructions. */
{"cv.elw", 0, INSN_CLASS_XCVELW, "d,o(s)", MATCH_CV_ELW, MASK_CV_ELW, match_opcode, 0},
+/* Vendor-specific (CORE-V) Xcvbi instructions. */
+{"cv.beqimm", 0, INSN_CLASS_XCVBI, "s,Xc4,p", MATCH_CV_BEQIMM, MASK_CV_BEQIMM, match_opcode, 0},
+{"cv.bneimm", 0, INSN_CLASS_XCVBI, "s,Xc4,p", MATCH_CV_BNEIMM, MASK_CV_BNEIMM, match_opcode, 0},
+
/* Vendor-specific (T-Head) XTheadBa instructions. */
{"th.addsl", 0, INSN_CLASS_XTHEADBA, "d,s,t,Xtu2@25", MATCH_TH_ADDSL, MASK_TH_ADDSL, match_opcode, 0},