RISC-V: Add missing hint instructions from RV128I.

Message ID 20180508225154.31878-1-jimw@sifive.com
State New
Headers show
Series
  • RISC-V: Add missing hint instructions from RV128I.
Related show

Commit Message

Jim Wilson May 8, 2018, 10:51 p.m.
This adds the last few hint instructions, not added earlier because I wanted to
look at possible interactions with future RV128 support.  Mostly this is adding
new instructions, but testing showed that we were accidentally disassembling
the new instructions incorrectly, so I also needed fixes to some existing
instructions to get the disassembly right.  I also added testcases for the
new instructions, and some old instructions that accidentally matched the new
instructions on disassembly.

This was tested with builds and make checks, there were no regressions.  It
was also tested by building libstdc++ and disassembling it to verify no
changes.  It was also tested by building kernel/buildroot and booting them on
simulators.

Committed.

Jim

	gas/
	* testsuite/gas/riscv/c-zero-imm.d: Add more tests.
	* testsuite/gas/riscv/c-zero-imm.s: Likewise.
	* testsuite/gas/riscv/c-zero-reg.d: Fix typo in test.  Add disabled
	future test for RV128 support.
	* testsuite/gas/riscv/c-zero-reg.s: Likewise.

	include/
	* opcode/riscv-opc.h (MATCH_C_SRLI64, MASK_C_SRLI64): New.
	(MATCH_C_SRAI64, MASK_C_SRAI64): New.
	(MATCH_C_SLLI64, MASK_C_SLLI64): New.

	opcodes/
	* riscv-opc.c (match_c_slli, match_slli_as_c_slli): New.
	(match_c_slli64, match_srxi_as_c_srxi): New.
	(riscv_opcodes) <slli, sll>: Use match_slli_as_c_slli.
	<srli, srl, srai, sra>: Use match_srxi_as_c_srxi.
	<c.slli, c.srli, c.srai>: Use match_s_slli.
	<c.slli64, c.srli64, c.srai64>: New.
---
 gas/testsuite/gas/riscv/c-zero-imm.d |  6 ++++
 gas/testsuite/gas/riscv/c-zero-imm.s |  8 ++++++
 gas/testsuite/gas/riscv/c-zero-reg.d |  2 +-
 gas/testsuite/gas/riscv/c-zero-reg.s |  4 ++-
 include/opcode/riscv-opc.h           |  6 ++++
 opcodes/riscv-opc.c                  | 54 ++++++++++++++++++++++++++++++------
 6 files changed, 69 insertions(+), 11 deletions(-)

-- 
2.14.1

Patch

diff --git a/gas/testsuite/gas/riscv/c-zero-imm.d b/gas/testsuite/gas/riscv/c-zero-imm.d
index c1389662e8..97b845dea0 100644
--- a/gas/testsuite/gas/riscv/c-zero-imm.d
+++ b/gas/testsuite/gas/riscv/c-zero-imm.d
@@ -14,4 +14,10 @@  Disassembly of section .text:
 [ 	]+8:[ 	]+0001[ 	]+nop
 [ 	]+a:[ 	]+00070713[ 	]+mv[ 	]+a4,a4
 [ 	]+e:[ 	]+0781[ 	]+addi[ 	]+a5,a5,0
+[ 	]+10:[ 	]+00051513[ 	]+slli[ 	]+a0,a0,0x0
+[ 	]+14:[ 	]+0005d593[ 	]+srli[ 	]+a1,a1,0x0
+[ 	]+18:[ 	]+40065613[ 	]+srai[ 	]+a2,a2,0x0
+[ 	]+1c:[ 	]+0682[ 	]+c.slli64[ 	]+a3
+[ 	]+1e:[ 	]+8301[ 	]+c.srli64[ 	]+a4
+[ 	]+20:[ 	]+8781[ 	]+c.srai64[ 	]+a5
 #...
diff --git a/gas/testsuite/gas/riscv/c-zero-imm.s b/gas/testsuite/gas/riscv/c-zero-imm.s
index a07baa4995..b0f4710cfc 100644
--- a/gas/testsuite/gas/riscv/c-zero-imm.s
+++ b/gas/testsuite/gas/riscv/c-zero-imm.s
@@ -9,3 +9,11 @@ 
 	addi a4,a4,0
 	# These are hints.
 	c.addi a5,0
+	# Don't let these compress to hints.
+	slli a0, a0, 0
+	srli a1, a1, 0
+	srai a2, a2, 0
+	# These are hints.
+	c.slli64 a3
+	c.srli64 a4
+	c.srai64 a5
diff --git a/gas/testsuite/gas/riscv/c-zero-reg.d b/gas/testsuite/gas/riscv/c-zero-reg.d
index 2daf8963eb..02d597838d 100644
--- a/gas/testsuite/gas/riscv/c-zero-reg.d
+++ b/gas/testsuite/gas/riscv/c-zero-reg.d
@@ -14,7 +14,7 @@  Disassembly of section .text:
 [ 	]+8:[ 	]+9006[ 	]+c.add[ 	]+zero,ra
 [ 	]+a:[ 	]+00500013[ 	]+li[ 	]+zero,5
 [ 	]+e:[ 	]+00006037[ 	]+lui[ 	]+zero,0x6
-[ 	]+12:[ 	]+00709013[ 	]+slli[ 	]+zero,ra,0x7
+[ 	]+12:[ 	]+00701013[ 	]+slli[ 	]+zero,zero,0x7
 [ 	]+16:[ 	]+00008013[ 	]+mv[ 	]+zero,ra
 [ 	]+1a:[ 	]+00100033[ 	]+add[ 	]+zero,zero,ra
 #...
diff --git a/gas/testsuite/gas/riscv/c-zero-reg.s b/gas/testsuite/gas/riscv/c-zero-reg.s
index 414c8a490e..4e3903039e 100644
--- a/gas/testsuite/gas/riscv/c-zero-reg.s
+++ b/gas/testsuite/gas/riscv/c-zero-reg.s
@@ -8,6 +8,8 @@ 
 	# Don't let these compress to hints.
 	li x0, 5
 	lui x0, 6
-	slli x0, x1, 7
+	slli x0, x0, 7
 	mv x0, x1
 	add x0, x0, x1
+# RV128 support not implemented yet.
+#	slli x0, x0, 64
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index f966fb6a50..60bd2f999e 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -459,8 +459,12 @@ 
 #define MASK_C_LUI  0xe003
 #define MATCH_C_SRLI 0x8001
 #define MASK_C_SRLI  0xec03
+#define MATCH_C_SRLI64 0x8001
+#define MASK_C_SRLI64  0xfc7f
 #define MATCH_C_SRAI 0x8401
 #define MASK_C_SRAI  0xec03
+#define MATCH_C_SRAI64 0x8401
+#define MASK_C_SRAI64  0xfc7f
 #define MATCH_C_ANDI 0x8801
 #define MASK_C_ANDI  0xec03
 #define MATCH_C_SUB 0x8c01
@@ -483,6 +487,8 @@ 
 #define MASK_C_BNEZ  0xe003
 #define MATCH_C_SLLI 0x2
 #define MASK_C_SLLI  0xe003
+#define MATCH_C_SLLI64 0x2
+#define MASK_C_SLLI64 0xf07f
 #define MATCH_C_FLDSP 0x2002
 #define MASK_C_FLDSP  0xe003
 #define MATCH_C_LWSP 0x4002
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index a285b147b4..47e9659c97 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -162,6 +162,39 @@  match_c_addi4spn (const struct riscv_opcode *op, insn_t insn)
   return match_opcode (op, insn) && EXTRACT_RVC_ADDI4SPN_IMM (insn) != 0;
 }
 
+/* This requires a non-zero shift.  A zero rd is a hint, so is allowed.  */
+
+static int
+match_c_slli (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_opcode (op, insn) && EXTRACT_RVC_IMM (insn) != 0;
+}
+
+/* This requires a non-zero rd, and a non-zero shift.  */
+
+static int
+match_slli_as_c_slli (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_rd_nonzero (op, insn) && EXTRACT_RVC_IMM (insn) != 0;
+}
+
+/* This requires a zero shift.  A zero rd is a hint, so is allowed.  */
+
+static int
+match_c_slli64 (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_opcode (op, insn) && EXTRACT_RVC_IMM (insn) == 0;
+}
+
+/* This is used for both srli and srai.  This requires a non-zero shift.
+   A zero rd is not possible.  */
+
+static int
+match_srxi_as_c_srxi (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_opcode (op, insn) && EXTRACT_RVC_IMM (insn) != 0;
+}
+
 const struct riscv_opcode riscv_opcodes[] =
 {
 /* name,      isa,   operands, match, mask, match_func, pinfo.  */
@@ -250,19 +283,19 @@  const struct riscv_opcode riscv_opcodes[] =
 {"la.tls.gd", "I",   "d,A",  0,    (int) M_LA_TLS_GD,  match_never, INSN_MACRO },
 {"la.tls.ie", "I",   "d,A",  0,    (int) M_LA_TLS_IE,  match_never, INSN_MACRO },
 {"neg",       "I",   "d,t",  MATCH_SUB, MASK_SUB | MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */
-{"slli",      "C",   "d,CU,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS },
+{"slli",      "C",   "d,CU,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
 {"slli",      "I",   "d,s,>",   MATCH_SLLI, MASK_SLLI, match_opcode, 0 },
-{"sll",       "C",   "d,CU,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_rd_nonzero, INSN_ALIAS },
+{"sll",       "C",   "d,CU,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
 {"sll",       "I",   "d,s,t",   MATCH_SLL, MASK_SLL, match_opcode, 0 },
 {"sll",       "I",   "d,s,>",   MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS },
-{"srli",      "C",   "Cs,Cw,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_opcode, INSN_ALIAS },
+{"srli",      "C",   "Cs,Cw,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
 {"srli",      "I",   "d,s,>",   MATCH_SRLI, MASK_SRLI, match_opcode, 0 },
-{"srl",       "C",   "Cs,Cw,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_opcode, INSN_ALIAS },
+{"srl",       "C",   "Cs,Cw,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
 {"srl",       "I",   "d,s,t",   MATCH_SRL, MASK_SRL, match_opcode, 0 },
 {"srl",       "I",   "d,s,>",   MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS },
-{"srai",      "C",   "Cs,Cw,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_opcode, INSN_ALIAS },
+{"srai",      "C",   "Cs,Cw,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
 {"srai",      "I",   "d,s,>",   MATCH_SRAI, MASK_SRAI, match_opcode, 0 },
-{"sra",       "C",   "Cs,Cw,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_opcode, INSN_ALIAS },
+{"sra",       "C",   "Cs,Cw,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
 {"sra",       "I",   "d,s,t",   MATCH_SRA, MASK_SRA, match_opcode, 0 },
 {"sra",       "I",   "d,s,>",   MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS },
 {"sub",       "C",   "Cs,Cw,Ct",  MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS },
@@ -686,9 +719,12 @@  const struct riscv_opcode riscv_opcodes[] =
 {"c.and",     "C",   "Cs,Ct",  MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
 {"c.or",      "C",   "Cs,Ct",  MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
 {"c.xor",     "C",   "Cs,Ct",  MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
-{"c.slli",    "C",   "d,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_opcode, 0 },
-{"c.srli",    "C",   "Cs,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_opcode, 0 },
-{"c.srai",    "C",   "Cs,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_opcode, 0 },
+{"c.slli",    "C",   "d,C>",  MATCH_C_SLLI, MASK_C_SLLI, match_c_slli, 0 },
+{"c.srli",    "C",   "Cs,C>",  MATCH_C_SRLI, MASK_C_SRLI, match_c_slli, 0 },
+{"c.srai",    "C",   "Cs,C>",  MATCH_C_SRAI, MASK_C_SRAI, match_c_slli, 0 },
+{"c.slli64",  "C",   "d",  MATCH_C_SLLI64, MASK_C_SLLI64, match_c_slli64, 0 },
+{"c.srli64",  "C",   "Cs",  MATCH_C_SRLI64, MASK_C_SRLI64, match_c_slli64, 0 },
+{"c.srai64",  "C",   "Cs",  MATCH_C_SRAI64, MASK_C_SRAI64, match_c_slli64, 0 },
 {"c.andi",    "C",   "Cs,Co",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
 {"c.addiw",   "64C", "d,Co",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
 {"c.addw",    "64C", "Cs,Ct",  MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },