RISC-V: Emit better warning for unknown CSR.

Message ID 20180316170541.31036-1-jimw@sifive.com
State New
Headers show
Series
  • RISC-V: Emit better warning for unknown CSR.
Related show

Commit Message

Jim Wilson March 16, 2018, 5:05 p.m.
The assembler currently gives a confusing error message for unknown CSR names.
rohan:2077$ cat tmp.s
	csrr a0, nonexistent
rohan:2078$ ./as-new tmp.s
tmp.s: Assembler messages:
tmp.s:1: Error: Instruction csrr requires absolute expression
rohan:2079$ 

With this patch, we now get
tmp.s:1: Error: unknown CSR `nonexistent'
which is easier to understand.

This was tested with riscv{32,64}-{elf,linux} make check for binutils, gas, and
ld.  There were no regressions.  It was also tested with gcc build and make
check, and a linux/buildroot build and boot.

Committed.

Jim

	gas/
	* config/tc-riscv.c (check_absolute_expr): Expand comment.  New
	parameter maybe_csr.  If maybe_csr and O_symbol, print CSR name.
	(riscv_ip): Add new argument to check_absolute_expr calls.
	* testsuite/gas/riscv/bad-csr.d: New.
	* testsuite/gas/riscv/bad-csr.l: New.
	* testsuite/gas/riscv/bad-csr.s: New.
---
 gas/config/tc-riscv.c             | 17 +++++++++++------
 gas/testsuite/gas/riscv/bad-csr.d |  3 +++
 gas/testsuite/gas/riscv/bad-csr.l |  2 ++
 gas/testsuite/gas/riscv/bad-csr.s |  1 +
 4 files changed, 17 insertions(+), 6 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/bad-csr.d
 create mode 100644 gas/testsuite/gas/riscv/bad-csr.l
 create mode 100644 gas/testsuite/gas/riscv/bad-csr.s

-- 
2.14.1

Patch

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 454f2831ea..f65702383c 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -993,13 +993,18 @@  normalize_constant_expr (expressionS *ex)
 			- 0x80000000);
 }
 
-/* Fail if an expression is not a constant.  */
+/* Fail if an expression EX is not a constant.  IP is the instruction using EX.
+   MAYBE_CSR is true if the symbol may be an unrecognized CSR name.  */
 
 static void
-check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex)
+check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex,
+		     bfd_boolean maybe_csr)
 {
   if (ex->X_op == O_big)
     as_bad (_("unsupported large constant"));
+  else if (maybe_csr && ex->X_op == O_symbol)
+    as_bad (_("unknown CSR `%s'"),
+	    S_GET_NAME (ex->X_add_symbol));
   else if (ex->X_op != O_constant)
     as_bad (_("Instruction %s requires absolute expression"),
 	    ip->insn_mo->name);
@@ -1744,7 +1749,7 @@  rvc_lui:
 
 	    case '<':		/* Shift amount, 0 - 31.  */
 	      my_getExpression (imm_expr, s);
-	      check_absolute_expr (ip, imm_expr);
+	      check_absolute_expr (ip, imm_expr, FALSE);
 	      if ((unsigned long) imm_expr->X_add_number > 31)
 		as_bad (_("Improper shift amount (%lu)"),
 			(unsigned long) imm_expr->X_add_number);
@@ -1755,7 +1760,7 @@  rvc_lui:
 
 	    case '>':		/* Shift amount, 0 - (XLEN-1).  */
 	      my_getExpression (imm_expr, s);
-	      check_absolute_expr (ip, imm_expr);
+	      check_absolute_expr (ip, imm_expr, FALSE);
 	      if ((unsigned long) imm_expr->X_add_number >= xlen)
 		as_bad (_("Improper shift amount (%lu)"),
 			(unsigned long) imm_expr->X_add_number);
@@ -1766,7 +1771,7 @@  rvc_lui:
 
 	    case 'Z':		/* CSRRxI immediate.  */
 	      my_getExpression (imm_expr, s);
-	      check_absolute_expr (ip, imm_expr);
+	      check_absolute_expr (ip, imm_expr, FALSE);
 	      if ((unsigned long) imm_expr->X_add_number > 31)
 		as_bad (_("Improper CSRxI immediate (%lu)"),
 			(unsigned long) imm_expr->X_add_number);
@@ -1781,7 +1786,7 @@  rvc_lui:
 	      else
 		{
 		  my_getExpression (imm_expr, s);
-		  check_absolute_expr (ip, imm_expr);
+		  check_absolute_expr (ip, imm_expr, TRUE);
 		  if ((unsigned long) imm_expr->X_add_number > 0xfff)
 		    as_bad (_("Improper CSR address (%lu)"),
 			    (unsigned long) imm_expr->X_add_number);
diff --git a/gas/testsuite/gas/riscv/bad-csr.d b/gas/testsuite/gas/riscv/bad-csr.d
new file mode 100644
index 0000000000..b4f0c38c2b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bad-csr.d
@@ -0,0 +1,3 @@ 
+#as:
+#source: bad-csr.s
+#error-output: bad-csr.l
diff --git a/gas/testsuite/gas/riscv/bad-csr.l b/gas/testsuite/gas/riscv/bad-csr.l
new file mode 100644
index 0000000000..a0bb8a6e92
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bad-csr.l
@@ -0,0 +1,2 @@ 
+.*: Assembler messages:
+.*: Error: unknown CSR `nonexistent'
diff --git a/gas/testsuite/gas/riscv/bad-csr.s b/gas/testsuite/gas/riscv/bad-csr.s
new file mode 100644
index 0000000000..6e6d27e44a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bad-csr.s
@@ -0,0 +1 @@ 
+	csrr a0, nonexistent