Skip to content

Commit

Permalink
RISC-V: Add support for XCValu extension in CV32E40P
Browse files Browse the repository at this point in the history
Spec: https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html

Contributors: @nandgate, @CharKeaney, @jessicamills, @MaryBennett,
@pietraferreira.

bfd/ChangeLog:

	* elfxx-riscv.c (riscv_multi_subset_supports): Added `xcvalu`
          instruction class.
	(riscv_multi_subset_supports_ext): Likewise.

gas/ChangeLog:

	* config/tc-riscv.c (validate_riscv_insn): Added the necessary
          operands for the extension.
	(riscv_ip): Likewise.
	* doc/c-riscv.texi: Noted XCValu as an additional ISA extension
          for CORE-V.
	* testsuite/gas/riscv/cv-alu-boundaries.d: New test.
	* testsuite/gas/riscv/cv-alu-boundaries.l: New test.
	* testsuite/gas/riscv/cv-alu-boundaries.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-march.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-march.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-march.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-01.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-01.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-01.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-02.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-02.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-02.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-03.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-03.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-03.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-04.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-04.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-04.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-05.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-05.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-05.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-06.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-06.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-06.s: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-07.d: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-07.l: New test.
	* testsuite/gas/riscv/cv-alu-fail-operand-07.s: New test.
	* testsuite/gas/riscv/cv-alu-insns.d: New test.
	* testsuite/gas/riscv/cv-alu-insns.s: New test.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Disassemble information with
          the EXTRACT macro implemented.
	* riscv-opc.c: Defined the MASK and added XCValu instructions.

include/ChangeLog:

	* opcode/riscv-opc.h: Added corresponding MATCH and MASK macros
          for XCValu.
	* opcode/riscv.h: Added corresponding EXTRACT and ENCODE macros
          for XCValu.
	(enum riscv_insn_class): Added the XCValu instruction class.
  • Loading branch information
jessicamills authored and pietraferreira committed Sep 1, 2023
1 parent 05fbbea commit 8930f90
Show file tree
Hide file tree
Showing 36 changed files with 825 additions and 0 deletions.
6 changes: 6 additions & 0 deletions bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,8 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{"xtheadsync", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
/* XVentanaCondOps: https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.0/ventana-custom-extensions-v1.0.0.pdf */
{"xventanacondops", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
/* CORE-V ISA extension spec: https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html */
{"xcvalu", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -2539,6 +2541,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "svinval");
case INSN_CLASS_H:
return riscv_subset_supports (rps, "h");
case INSN_CLASS_XCVALU:
return riscv_subset_supports (rps, "xcvalu");
case INSN_CLASS_XTHEADBA:
return riscv_subset_supports (rps, "xtheadba");
case INSN_CLASS_XTHEADBB:
Expand Down Expand Up @@ -2779,6 +2783,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "svinval";
case INSN_CLASS_H:
return _("h");
case INSN_CLASS_XCVALU:
return "xcvalu";
case INSN_CLASS_XTHEADBA:
return "xtheadba";
case INSN_CLASS_XTHEADBB:
Expand Down
60 changes: 60 additions & 0 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,30 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
}
}
break;
case 'x': /* Vendor-specific operands. */
switch (*++oparg)
{
/* Vendor-specific (CORE-V) operands. */
case 'c':
switch (*++oparg)
{
case '2':
/* ls2[4:0] */
used_bits |= ENCODE_CV_IS2_UIMM5 (-1U);
break;
case '3':
/* ls3[4:0] */
used_bits |= ENCODE_CV_IS3_UIMM5 (-1U);
break;
default:
goto unknown_validate_operand;
}
break;
default:
goto unknown_validate_operand;
}
break;

default:
unknown_validate_operand:
as_bad (_("internal: bad RISC-V opcode "
Expand Down Expand Up @@ -3669,6 +3693,42 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
}
break;

case 'x': /* Vendor-specific operands. */
switch (*++oparg)
{
/* Vendor-specific (CORE-V) operands. */
case 'c':
switch (*++oparg)
{
case '2':
my_getExpression (imm_expr, asarg);
check_absolute_expr (ip, imm_expr, FALSE);
asarg = expr_parse_end;
if (imm_expr->X_add_number<0
|| imm_expr->X_add_number>31)
break;
ip->insn_opcode
|= ENCODE_CV_IS2_UIMM5 (imm_expr->X_add_number);
continue;
case '3':
my_getExpression (imm_expr, asarg);
check_absolute_expr (ip, imm_expr, FALSE);
asarg = expr_parse_end;
if (imm_expr->X_add_number<0
|| imm_expr->X_add_number>31)
break;
ip->insn_opcode
|= ENCODE_CV_IS3_UIMM5 (imm_expr->X_add_number);
continue;
default:
goto unknown_riscv_ip_operand;
}
break;
default:
goto unknown_riscv_ip_operand;
}
break;

default:
unknown_riscv_ip_operand:
as_fatal (_("internal: unknown argument type `%s'"),
Expand Down
6 changes: 6 additions & 0 deletions gas/doc/c-riscv.texi
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,12 @@ extensions supported and provides the location of their
publicly-released documentation:

@table @r
@item Xcvalu

The Xcvalu extension provides instructions for general ALU 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.

Expand Down
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-boundaries.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32i_xcvalu
#source: cv-alu-boundaries.s
#error_output: cv-alu-boundaries.l
14 changes: 14 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-boundaries.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.*: Assembler messages:
.*: Error: illegal operands `cv.subnr 10,t3,t6'
.*: Error: illegal operands `cv.addrnr t4,26,t6'
.*: Error: illegal operands `cv.subunr t6,t3,15'
.*: Error: instruction cv.clipu requires absolute expression
.*: Error: instruction cv.addn requires absolute expression
.*: Error: illegal operands `cv.clipu t0,t3,-10'
.*: Error: illegal operands `cv.clipu t0,t3,500'
.*: Error: illegal operands `cv.addn t0,t3,t6,-60'
.*: Error: illegal operands `cv.addn t0,t3,t6,302'
.*: Error: illegal operands `cv.clipu t0,t3,-1'
.*: Error: illegal operands `cv.clipu t0,t3,32'
.*: Error: illegal operands `cv.addn t0,t3,t6,-1'
.*: Error: illegal operands `cv.addn t0,t3,t6,32'
27 changes: 27 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-boundaries.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Destination must be of type register
target:
cv.subnr 10, t3, t6
# Source 1 must be of type register
cv.addrnr t4, 26, t6
# Source 2 must be of type register
cv.subunr t6, t3, 15
# Five bit immediate must be an absolute value
cv.clipu t0, t3, t6
# Five bit immediate must be an absolute value
cv.addn t0, t3, t6, t2
# Five bit immediate must be an absolute value in range [0, 31]
cv.clipu t0, t3, -10
# Five bit immediate must be an absolute value in range [0, 31]
cv.clipu t0, t3, 500
# Five bit immediate must be an absolute value in range [0, 31]
cv.addn t0, t3, t6, -60
# Five bit immediate must be an absolute value in range [0, 31]
cv.addn t0, t3, t6, 302
# Five bit immediate must be an absolute value in range [0, 31]
cv.clipu t0, t3, -1
# Five bit immediate must be an absolute value in range [0, 31]
cv.clipu t0, t3, 32
# Five bit immediate must be an absolute value in range [0, 31]
cv.addn t0, t3, t6, -1
# Five bit immediate must be an absolute value in range [0, 31]
cv.addn t0, t3, t6, 32
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-march.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32i
#source: cv-alu-fail-march.s
#error_output: cv-alu-fail-march.l
32 changes: 32 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-march.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.*: Assembler messages:
.*: Error: unrecognized opcode `cv.abs t4,t2', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.slet t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.sletu t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.min t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.minu t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.max t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.maxu t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.exths t4,t2', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.exthz t4,t2', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.extbs t4,t2', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.extbz t4,t2', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.clip t4,t2,5', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.clipu t4,t2,5', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.clipr t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.clipur t4,t2,t6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addn t4,t2,t0,4', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addun t4,t2,t0,4', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addrn t6,t0,t3,9', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addurn t6,t0,t3,14', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addnr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addunr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addrnr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.addurnr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.subn t6,t0,t3,6', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.subun t6,t0,t3,24', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.subrn t6,t0,t3,21', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.suburn t6,t0,t3,3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.subnr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.subunr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.subrnr t6,t0,t3', extension `xcvalu' required
.*: Error: unrecognized opcode `cv.suburnr t6,t0,t3', extension `xcvalu' required
33 changes: 33 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-march.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Absence of xcv or xcvalu march option disables all CORE-V general ALU ops extensions
target:
cv.abs t4,t2
cv.slet t4,t2,t6
cv.sletu t4,t2,t6
cv.min t4,t2,t6
cv.minu t4,t2,t6
cv.max t4,t2,t6
cv.maxu t4,t2,t6
cv.exths t4,t2
cv.exthz t4,t2
cv.extbs t4,t2
cv.extbz t4,t2
cv.clip t4,t2,5
cv.clipu t4,t2,5
cv.clipr t4,t2,t6
cv.clipur t4,t2,t6
cv.addn t4, t2, t0, 4
cv.addun t4, t2, t0, 4
cv.addrn t6, t0, t3, 9
cv.addurn t6, t0, t3, 14
cv.addnr t6, t0, t3
cv.addunr t6, t0, t3
cv.addrnr t6, t0, t3
cv.addurnr t6, t0, t3
cv.subn t6, t0, t3, 6
cv.subun t6, t0, t3, 24
cv.subrn t6, t0, t3, 21
cv.suburn t6, t0, t3, 3
cv.subnr t6, t0, t3
cv.subunr t6, t0, t3
cv.subrnr t6, t0, t3
cv.suburnr t6, t0, t3
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-01.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32i_xcvalu
#source: cv-alu-fail-operand-01.s
#error_output: cv-alu-fail-operand-01.l
32 changes: 32 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-01.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.*: Assembler messages:
.*: Error: illegal operands `cv.abs 5,t2'
.*: Error: illegal operands `cv.slet 10,t2,t6'
.*: Error: illegal operands `cv.sletu 11,t2,t6'
.*: Error: illegal operands `cv.min 15,t2,t6'
.*: Error: illegal operands `cv.minu 16,t2,t6'
.*: Error: illegal operands `cv.max 8,t2,t6'
.*: Error: illegal operands `cv.maxu 3,t2,t6'
.*: Error: illegal operands `cv.exths 2,t2'
.*: Error: illegal operands `cv.exthz 6,t2'
.*: Error: illegal operands `cv.extbs 4,t2'
.*: Error: illegal operands `cv.extbz 7,t2'
.*: Error: illegal operands `cv.clip 17,t2,5'
.*: Error: illegal operands `cv.clipu 11,t2,5'
.*: Error: illegal operands `cv.clipr 16,t2,t6'
.*: Error: illegal operands `cv.clipur 15,t2,t6'
.*: Error: illegal operands `cv.addn 9,t2,t0,4'
.*: Error: illegal operands `cv.addun 30,t2,t0,4'
.*: Error: illegal operands `cv.addrn 21,t0,t3,9'
.*: Error: illegal operands `cv.addurn 6,t0,t3,14'
.*: Error: illegal operands `cv.addnr 2,t0,t3'
.*: Error: illegal operands `cv.addunr 26,t0,t3'
.*: Error: illegal operands `cv.addrnr 3,t0,t3'
.*: Error: illegal operands `cv.addurnr 14,t0,t3'
.*: Error: illegal operands `cv.subn 15,t0,t3,6'
.*: Error: illegal operands `cv.subun 9,t0,t3,24'
.*: Error: illegal operands `cv.subrn 24,t0,t3,21'
.*: Error: illegal operands `cv.suburn 25,t0,t3,3'
.*: Error: illegal operands `cv.subnr 3,t0,t3'
.*: Error: illegal operands `cv.subunr 12,t0,t3'
.*: Error: illegal operands `cv.subrnr 13,t0,t3'
.*: Error: illegal operands `cv.suburnr 8,t0,t3'
33 changes: 33 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-01.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Destination must be of type register
target:
cv.abs 5,t2
cv.slet 10,t2,t6
cv.sletu 11,t2,t6
cv.min 15,t2,t6
cv.minu 16,t2,t6
cv.max 8,t2,t6
cv.maxu 3,t2,t6
cv.exths 2,t2
cv.exthz 6,t2
cv.extbs 4,t2
cv.extbz 7,t2
cv.clip 17,t2,5
cv.clipu 11,t2,5
cv.clipr 16,t2,t6
cv.clipur 15,t2,t6
cv.addn 9,t2,t0,4
cv.addun 30,t2,t0,4
cv.addrn 21,t0,t3,9
cv.addurn 6,t0,t3,14
cv.addnr 2,t0,t3
cv.addunr 26,t0,t3
cv.addrnr 3,t0,t3
cv.addurnr 14,t0,t3
cv.subn 15,t0,t3,6
cv.subun 9,t0,t3,24
cv.subrn 24,t0,t3,21
cv.suburn 25,t0,t3,3
cv.subnr 3,t0,t3
cv.subunr 12,t0,t3
cv.subrnr 13,t0,t3
cv.suburnr 8,t0,t3
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-02.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32i_xcvalu
#source: cv-alu-fail-operand-02.s
#error_output: cv-alu-fail-operand-02.l
32 changes: 32 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-02.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.*: Assembler messages:
.*: Error: illegal operands `cv.abs t4,5'
.*: Error: illegal operands `cv.slet t4,7,t6'
.*: Error: illegal operands `cv.sletu t4,3,t6'
.*: Error: illegal operands `cv.min t4,5,t6'
.*: Error: illegal operands `cv.minu t4,3,t6'
.*: Error: illegal operands `cv.max t4,4,t6'
.*: Error: illegal operands `cv.maxu t4,6,t6'
.*: Error: illegal operands `cv.exths t4,30'
.*: Error: illegal operands `cv.exthz t4,23'
.*: Error: illegal operands `cv.extbs t4,25'
.*: Error: illegal operands `cv.extbz t4,21'
.*: Error: illegal operands `cv.clip t4,2,5'
.*: Error: illegal operands `cv.clipu t4,16,5'
.*: Error: illegal operands `cv.clipr t4,17,t6'
.*: Error: illegal operands `cv.clipur t4,14,t6'
.*: Error: illegal operands `cv.addn t4,5,t0,4'
.*: Error: illegal operands `cv.addun t4,18,t0,4'
.*: Error: illegal operands `cv.addrn t6,19,t3,9'
.*: Error: illegal operands `cv.addurn t6,4,t3,14'
.*: Error: illegal operands `cv.addnr t6,6,t3'
.*: Error: illegal operands `cv.addunr t6,7,t3'
.*: Error: illegal operands `cv.addrnr t6,9,t3'
.*: Error: illegal operands `cv.addurnr t6,5,t3'
.*: Error: illegal operands `cv.subn t6,11,t3,6'
.*: Error: illegal operands `cv.subun t6,14,t3,24'
.*: Error: illegal operands `cv.subrn t6,15,t3,21'
.*: Error: illegal operands `cv.suburn t6,24,t3,3'
.*: Error: illegal operands `cv.subnr t6,4,t3'
.*: Error: illegal operands `cv.subunr t6,8,t3'
.*: Error: illegal operands `cv.subrnr t6,7,t3'
.*: Error: illegal operands `cv.suburnr t6,6,t3'
33 changes: 33 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-02.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Source 1 must be of type register
target:
cv.abs t4,5
cv.slet t4,7,t6
cv.sletu t4,3,t6
cv.min t4,5,t6
cv.minu t4,3,t6
cv.max t4,4,t6
cv.maxu t4,6,t6
cv.exths t4,30
cv.exthz t4,23
cv.extbs t4,25
cv.extbz t4,21
cv.clip t4,2,5
cv.clipu t4,16,5
cv.clipr t4,17,t6
cv.clipur t4,14,t6
cv.addn t4,5,t0,4
cv.addun t4,18,t0,4
cv.addrn t6,19,t3,9
cv.addurn t6,4,t3,14
cv.addnr t6,6,t3
cv.addunr t6,7,t3
cv.addrnr t6,9,t3
cv.addurnr t6,5,t3
cv.subn t6,11,t3,6
cv.subun t6,14,t3,24
cv.subrn t6,15,t3,21
cv.suburn t6,24,t3,3
cv.subnr t6,4,t3
cv.subunr t6,8,t3
cv.subrnr t6,7,t3
cv.suburnr t6,6,t3
3 changes: 3 additions & 0 deletions gas/testsuite/gas/riscv/cv-alu-fail-operand-03.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#as: -march=rv32i_xcvalu
#source: cv-alu-fail-operand-03.s
#error_output: cv-alu-fail-operand-03.l
Loading

0 comments on commit 8930f90

Please sign in to comment.