This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH v2] RISC-V: Fix disassembly of c.addi4spn, c.addi16sp, c.lui when imm=0
- From: Palmer Dabbelt <palmer at dabbelt dot com>
- To: Nick Clifton <nickc at redhat dot com>, binutils at sourceware dot org
- Cc: Andrew Waterman <andrew at sifive dot com>
- Date: Tue, 24 Oct 2017 09:34:30 -0700
- Subject: [PATCH v2] RISC-V: Fix disassembly of c.addi4spn, c.addi16sp, c.lui when imm=0
- Authentication-results: sourceware.org; auth=none
From: Andrew Waterman <andrew@sifive.com>
These are all invalid instructions, so they should not disassemble.
opcodes/ChangeLog
2017-10-20 Andrew Waterman <andrew@sifive.com>
* riscv-opc.c (match_c_addi16sp) : New function.
(match_c_addi4spn): New function.
(match_c_lui): Don't allow 0-immediate encodings.
(riscv_opcodes) <addi>: Use the above functions.
<add>: Likewise.
<c.addi4spn>: Likewise.
<c.addi16sp>: Likewise.
gas/ChangeLog
2017-10-24 Andrew Waterman <andrew@sifive.com>
* gas/testsuite/gas/riscv/c-addi16sp-fail.d: New test.
gas/testsuite/gas/riscv/c-addi16sp-fail.l: Likewise.
gas/testsuite/gas/riscv/c-addi16sp-fail.s: Likewise.
gas/testsuite/gas/riscv/c-addi4spn-fail.d: Likewise.
gas/testsuite/gas/riscv/c-addi4spn-fail.l: Likewise.
gas/testsuite/gas/riscv/c-addi4spn-fail.s: Likewise.
testsuite/gas/riscv/riscv.exp: Add new tests.
---
gas/testsuite/gas/riscv/c-addi16sp-fail.d | 3 +++
gas/testsuite/gas/riscv/c-addi16sp-fail.l | 2 ++
gas/testsuite/gas/riscv/c-addi16sp-fail.s | 2 ++
gas/testsuite/gas/riscv/c-addi4spn-fail.d | 3 +++
gas/testsuite/gas/riscv/c-addi4spn-fail.l | 2 ++
gas/testsuite/gas/riscv/c-addi4spn-fail.s | 2 ++
gas/testsuite/gas/riscv/riscv.exp | 2 ++
opcodes/riscv-opc.c | 30 +++++++++++++++++++++++-------
8 files changed, 39 insertions(+), 7 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/c-addi16sp-fail.d
create mode 100644 gas/testsuite/gas/riscv/c-addi16sp-fail.l
create mode 100644 gas/testsuite/gas/riscv/c-addi16sp-fail.s
create mode 100644 gas/testsuite/gas/riscv/c-addi4spn-fail.d
create mode 100644 gas/testsuite/gas/riscv/c-addi4spn-fail.l
create mode 100644 gas/testsuite/gas/riscv/c-addi4spn-fail.s
diff --git a/gas/testsuite/gas/riscv/c-addi16sp-fail.d b/gas/testsuite/gas/riscv/c-addi16sp-fail.d
new file mode 100644
index 000000000000..cc20923daf6d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-addi16sp-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv32ic
+#source: c-addi16sp-fail.s
+#error-output: c-addi16sp-fail.l
diff --git a/gas/testsuite/gas/riscv/c-addi16sp-fail.l b/gas/testsuite/gas/riscv/c-addi16sp-fail.l
new file mode 100644
index 000000000000..15f91fd93d09
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-addi16sp-fail.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*: Error: illegal operands `c.addi16sp x1,0'
diff --git a/gas/testsuite/gas/riscv/c-addi16sp-fail.s b/gas/testsuite/gas/riscv/c-addi16sp-fail.s
new file mode 100644
index 000000000000..c0d3918a7a8e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-addi16sp-fail.s
@@ -0,0 +1,2 @@
+target:
+ c.addi16sp x1, 0
diff --git a/gas/testsuite/gas/riscv/c-addi4spn-fail.d b/gas/testsuite/gas/riscv/c-addi4spn-fail.d
new file mode 100644
index 000000000000..b3c0af44c9bf
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-addi4spn-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv32ic
+#source: c-addi4spn-fail.s
+#error-output: c-addi4spn-fail.l
diff --git a/gas/testsuite/gas/riscv/c-addi4spn-fail.l b/gas/testsuite/gas/riscv/c-addi4spn-fail.l
new file mode 100644
index 000000000000..2a8a5935f105
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-addi4spn-fail.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*: Error: illegal operands `c.addi4spn x1,0'
diff --git a/gas/testsuite/gas/riscv/c-addi4spn-fail.s b/gas/testsuite/gas/riscv/c-addi4spn-fail.s
new file mode 100644
index 000000000000..6963bebf6304
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-addi4spn-fail.s
@@ -0,0 +1,2 @@
+target:
+ c.addi4spn x1, 0
diff --git a/gas/testsuite/gas/riscv/riscv.exp b/gas/testsuite/gas/riscv/riscv.exp
index f411335bfbec..b2eaec1f5750 100644
--- a/gas/testsuite/gas/riscv/riscv.exp
+++ b/gas/testsuite/gas/riscv/riscv.exp
@@ -22,4 +22,6 @@ if [istarget riscv*-*-*] {
run_dump_test "t_insns"
run_dump_test "fmv.x"
run_dump_test "c-lui-fail"
+ run_dump_test "c-addi4spn-fail"
+ run_dump_test "c-addi16sp-fail"
}
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 27b4b9fb513c..84cdea8fca8f 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -114,9 +114,25 @@ match_c_add (const struct riscv_opcode *op, insn_t insn)
}
static int
+match_c_addi16sp (const struct riscv_opcode *op, insn_t insn)
+{
+ return (match_opcode (op, insn)
+ && (((insn & MASK_RD) >> OP_SH_RD) == 2)
+ && EXTRACT_RVC_ADDI16SP_IMM (insn) != 0);
+}
+
+static int
match_c_lui (const struct riscv_opcode *op, insn_t insn)
{
- return match_rd_nonzero (op, insn) && (((insn & MASK_RD) >> OP_SH_RD) != 2);
+ return (match_rd_nonzero (op, insn)
+ && (((insn & MASK_RD) >> OP_SH_RD) != 2)
+ && EXTRACT_RVC_LUI_IMM (insn) != 0);
+}
+
+static int
+match_c_addi4spn (const struct riscv_opcode *op, insn_t insn)
+{
+ return match_opcode (op, insn) && EXTRACT_RVC_ADDI4SPN_IMM (insn) != 0;
}
const struct riscv_opcode riscv_opcodes[] =
@@ -188,15 +204,15 @@ const struct riscv_opcode riscv_opcodes[] =
{"bnez", "C", "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS },
{"bnez", "I", "s,p", MATCH_BNE, MASK_BNE | MASK_RS2, match_opcode, INSN_ALIAS },
{"bne", "I", "s,t,p", MATCH_BNE, MASK_BNE, match_opcode, 0 },
-{"addi", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, INSN_ALIAS },
+{"addi", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
{"addi", "C", "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
-{"addi", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, INSN_ALIAS },
+{"addi", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
{"addi", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, 0 },
{"add", "C", "d,CU,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
{"add", "C", "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
{"add", "C", "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
-{"add", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, INSN_ALIAS },
-{"add", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, INSN_ALIAS },
+{"add", "C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
+{"add", "C", "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
{"add", "I", "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, 0 },
{"add", "I", "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, 0 },
{"add", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS },
@@ -628,8 +644,8 @@ const struct riscv_opcode riscv_opcodes[] =
{"c.mv", "C", "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, 0 },
{"c.lui", "C", "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, 0 },
{"c.li", "C", "d,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, 0 },
-{"c.addi4spn","C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_opcode, 0 },
-{"c.addi16sp","C", "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_opcode, 0 },
+{"c.addi4spn","C", "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, 0 },
+{"c.addi16sp","C", "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, 0 },
{"c.addi", "C", "d,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 },
{"c.add", "C", "d,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, 0 },
{"c.sub", "C", "Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 },
--
2.13.6