RISC-V: Add .insn CA support.

Message ID 20181121225504.32402-1-jimw@sifive.com
State New
Headers show
Series
  • RISC-V: Add .insn CA support.
Related show

Commit Message

Jim Wilson Nov. 21, 2018, 10:55 p.m.
The v2.3 ISA draft adds a new CA compressed instruction format.  There are no
new or changed instruction encodings.  Just a new instruction format to better
match some existing instructions which didn't exactly match the previously
defined encodings.

This patch adds support for this new instruction format to the .insn pseudo
op, updates the docs to include it, and updates the testcase to use it.

This has been tested with riscv{32,64}-{elf,linux} cross tools against the
binutils testsuite, and there are no regressions.

I'll hold off on the patch for a few work days before I commit it, in case
anyone wants to comment on it.

Jim

	gas/
	* config/tc-riscv.c (validate_riscv_insn) <'F'>: Add support for CF6
	and CF2 operands.
	(riscv_ip) <'F'>: Likewise.
	* doc/c-riscv.texi (RISC-V-Formats): Add func6 abbreviation.  Use rs2
	instead of rs1 in CR description.  Add CA docs.
	* gas/testsuite/riscv/insn.s: Add use of .insn ca.
	* gas/testsuite/riscv/insn.d: Update to match.
	include/
	* opcode/riscv.h (OP_MASK_CFUNCT6, OP_SH_CFUNCT6): New.
	(OP_MASK_CFUNCT2, OP_SH_CFUNCT2): New.
	opcodes/
	* riscv-opc.c (ciw): Fix whitespace to align columns.
	(ca): New.
---
 gas/config/tc-riscv.c          | 31 +++++++++++++++++++++++++++++++
 gas/doc/c-riscv.texi           | 11 ++++++++++-
 gas/testsuite/gas/riscv/insn.d | 25 +++++++++++++------------
 gas/testsuite/gas/riscv/insn.s |  1 +
 include/opcode/riscv.h         |  4 ++++
 opcodes/riscv-opc.c            |  9 +++++++--
 6 files changed, 66 insertions(+), 15 deletions(-)

-- 
2.17.1

Comments

Jim Wilson Nov. 27, 2018, 7:32 p.m. | #1
On Wed, Nov 21, 2018 at 2:55 PM Jim Wilson <jimw@sifive.com> wrote:
> The v2.3 ISA draft adds a new CA compressed instruction format.  There are no

> new or changed instruction encodings.  Just a new instruction format to better

> match some existing instructions which didn't exactly match the previously

> defined encodings.

>

> This patch adds support for this new instruction format to the .insn pseudo

> op, updates the docs to include it, and updates the testcase to use it.


Almost a week and no comments, so I went ahead and committed and
pushed this patch.

Jim

Patch

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 987377ae81..426343c693 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -707,8 +707,10 @@  validate_riscv_insn (const struct riscv_opcode *opc, int length)
 	  case 'F': /* funct */
 	    switch (c = *p++)
 	      {
+		case '6': USE_BITS (OP_MASK_CFUNCT6, OP_SH_CFUNCT6); break;
 		case '4': USE_BITS (OP_MASK_CFUNCT4, OP_SH_CFUNCT4); break;
 		case '3': USE_BITS (OP_MASK_CFUNCT3, OP_SH_CFUNCT3); break;
+		case '2': USE_BITS (OP_MASK_CFUNCT2, OP_SH_CFUNCT2); break;
 		default:
 		  as_bad (_("internal: bad RISC-V opcode"
 			    " (unknown operand type `CF%c'): %s %s"),
@@ -1741,6 +1743,21 @@  rvc_lui:
 		case 'F':
 		  switch (*++args)
 		    {
+		      case '6':
+		        if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
+			    || imm_expr->X_op != O_constant
+			    || imm_expr->X_add_number < 0
+			    || imm_expr->X_add_number >= 64)
+			  {
+			    as_bad (_("bad value for funct6 field, "
+				      "value must be 0...64"));
+			    break;
+			  }
+
+			INSERT_OPERAND (CFUNCT6, *ip, imm_expr->X_add_number);
+			imm_expr->X_op = O_absent;
+			s = expr_end;
+			continue;
 		      case '4':
 		        if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 			    || imm_expr->X_op != O_constant
@@ -1770,6 +1787,20 @@  rvc_lui:
 			imm_expr->X_op = O_absent;
 			s = expr_end;
 			continue;
+		      case '2':
+			if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
+			    || imm_expr->X_op != O_constant
+			    || imm_expr->X_add_number < 0
+			    || imm_expr->X_add_number >= 4)
+			  {
+			    as_bad (_("bad value for funct2 field, "
+				      "value must be 0...3"));
+			    break;
+			  }
+			INSERT_OPERAND (CFUNCT2, *ip, imm_expr->X_add_number);
+			imm_expr->X_op = O_absent;
+			s = expr_end;
+			continue;
 		      default:
 			as_bad (_("bad compressed FUNCT field"
 				  " specifier 'CF%c'\n"),
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index 045c33a3aa..938c96e14e 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -190,6 +190,7 @@  instruction formats:
 @item opcode @tab Unsigned immediate or opcode name for 7-bits opcode.
 @item opcode2 @tab Unsigned immediate or opcode name for 2-bits opcode.
 @item func7 @tab Unsigned immediate for 7-bits function code.
+@item func6 @tab Unsigned immediate for 6-bits function code.
 @item func4 @tab Unsigned immediate for 4-bits function code.
 @item func3 @tab Unsigned immediate for 3-bits function code.
 @item func2 @tab Unsigned immediate for 2-bits function code.
@@ -355,7 +356,7 @@  with the @samp{.insn} pseudo directive:
 31           30             21           20              12   7             0
 @end verbatim
 
-@item CR type: .insn cr opcode2, func4, rd, rs1
+@item CR type: .insn cr opcode2, func4, rd, rs2
 @verbatim
 +---------+--------+-----+---------+
 |   func4 | rd/rs1 | rs2 | opcode2 |
@@ -379,6 +380,14 @@  with the @samp{.insn} pseudo directive:
 15        13             7     2         0
 @end verbatim
 
+@item CA type: .insn ca opcode2, func6, func2, rd, rs2
+@verbatim
++---------+----------+-------+------+--------+
+|   func6 | rd'/rs1' | func2 | rs2' | opcode |
++---------+----------+-------+------+--------+
+15        10         7       5      2        0
+@end verbatim
+
 @item CB type: .insn cb opcode2, func3, rs1, symbol
 @verbatim
 +---------+--------+------+--------+---------+
diff --git a/gas/testsuite/gas/riscv/insn.d b/gas/testsuite/gas/riscv/insn.d
index 3d1049b09e..a1474c91e1 100644
--- a/gas/testsuite/gas/riscv/insn.d
+++ b/gas/testsuite/gas/riscv/insn.d
@@ -37,15 +37,16 @@  Disassembly of section .text:
 [ 	]+4a:[ 	]+0511[ 	]+addi[ 	]+a0,a0,4
 [ 	]+4c:[ 	]+852e[ 	]+mv[ 	]+a0,a1
 [ 	]+4e:[ 	]+002c[ 	]+addi[ 	]+a1,sp,8
-[ 	]+50:[ 	]+d9c5[ 	]+beqz[ 	]+a1,0 \<target\>
-[	]+50: R_RISCV_RVC_BRANCH[	]+target
-[ 	]+52:[ 	]+b77d[ 	]+j[ 	]+0 \<target\>
-[	]+52: R_RISCV_RVC_JUMP[	]+target
-[ 	]+54:[ 	]+68c58543[ 	]+fmadd.s[ 	]+fa0,fa1,fa2,fa3,rne
-[ 	]+58:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
-[ 	]+5c:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
-[ 	]+60:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
-[ 	]+64:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
-[ 	]+68:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
-[ 	]+6c:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
-[ 	]+70:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+50:[ 	]+8d6d[ 	]+and[ 	]+a0,a0,a1
+[ 	]+52:[ 	]+d5dd[ 	]+beqz[ 	]+a1,0 \<target\>
+[	]+52: R_RISCV_RVC_BRANCH[	]+target
+[ 	]+54:[ 	]+b775[ 	]+j[ 	]+0 \<target\>
+[	]+54: R_RISCV_RVC_JUMP[	]+target
+[ 	]+56:[ 	]+68c58543[ 	]+fmadd.s[ 	]+fa0,fa1,fa2,fa3,rne
+[ 	]+5a:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+5e:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+62:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+66:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+6a:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+6e:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[ 	]+72:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
diff --git a/gas/testsuite/gas/riscv/insn.s b/gas/testsuite/gas/riscv/insn.s
index 7ad1753e43..13e5417f7b 100644
--- a/gas/testsuite/gas/riscv/insn.s
+++ b/gas/testsuite/gas/riscv/insn.s
@@ -26,6 +26,7 @@  target:
 	.insn ci C1, 0x0, a0, 4
 	.insn cr C2, 0x8, a0, a1
 	.insn ciw C0, 0x0, a1, 1
+	.insn ca C1, 0x23, 0x3, a0, a1
 	.insn cb C1, 0x6, a1, target
 	.insn cj C1, 0x5, target
 
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 68047a5605..10c5f3d6e6 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -247,10 +247,14 @@  static const char * const riscv_pred_succ[16] =
 #define OP_MASK_CRS2S 0x7
 #define OP_SH_CRS2S 2
 
+#define OP_MASK_CFUNCT6                0x3f
+#define OP_SH_CFUNCT6          10
 #define OP_MASK_CFUNCT4                0xf
 #define OP_SH_CFUNCT4          12
 #define OP_MASK_CFUNCT3                0x7
 #define OP_SH_CFUNCT3          13
+#define OP_MASK_CFUNCT2                0x3
+#define OP_SH_CFUNCT2          5
 
 /* ABI names for selected x-registers.  */
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index b6843f2437..a272e29fee 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -842,8 +842,13 @@  const struct riscv_opcode riscv_insn_types[] =
 {"ci",      0, {"C", 0},  "O2,CF3,d,Co",        0,    0,  match_opcode, 0 },
 {"ci",      0, {"C", 0},  "O2,CF3,D,Co",        0,    0,  match_opcode, 0 },
 
-{"ciw",     0, {"C", 0},  "O2,CF3,Ct,C8",        0,    0,  match_opcode, 0 },
-{"ciw",     0, {"C", 0},  "O2,CF3,CD,C8",        0,    0,  match_opcode, 0 },
+{"ciw",     0, {"C", 0},  "O2,CF3,Ct,C8",       0,    0,  match_opcode, 0 },
+{"ciw",     0, {"C", 0},  "O2,CF3,CD,C8",       0,    0,  match_opcode, 0 },
+
+{"ca",      0, {"C", 0},  "O2,CF6,CF2,Cs,Ct",   0,    0,  match_opcode, 0 },
+{"ca",      0, {"C", 0},  "O2,CF6,CF2,CS,Ct",   0,    0,  match_opcode, 0 },
+{"ca",      0, {"C", 0},  "O2,CF6,CF2,Cs,CD",   0,    0,  match_opcode, 0 },
+{"ca",      0, {"C", 0},  "O2,CF6,CF2,CS,CD",   0,    0,  match_opcode, 0 },
 
 {"cb",      0, {"C", 0},  "O2,CF3,Cs,Cp",       0,    0,  match_opcode, 0 },
 {"cb",      0, {"C", 0},  "O2,CF3,CS,Cp",       0,    0,  match_opcode, 0 },