RISC-V: Fix lui argument parsing.

Message ID 20190530222512.6176-1-jimw@sifive.com
State New
Headers show
Series
  • RISC-V: Fix lui argument parsing.
Related show

Commit Message

Jim Wilson May 30, 2019, 10:25 p.m.
This fixes a bug reported on the riscv.org sw-dev mailing list.  This
rejects "lui x1,symbol", as a symbol should only be accepted here when
used inside %hi().  Without the fix, this gets assembled as "lui x1,0"
with no relocation which is clearly wrong.

Tested with cross riscv{32,64}-{elf,linux} binutils and gcc builds and checks.
There were no regressions.  The new checks fail without the patch and work
with the patch.

Committed.

Jim

	gas/
	* config/tc-riscv.c (riscv_ip) <'u'>: Move O_constant check inside if
	statement.  Delete O_symbol and O_constant check after if statement.
	* testsuite/gas/riscv/auipc-parsing.s: Test lui with missing %hi.
	* testsuite/gas/riscv/auipc-parsing.l: Update.
---
 gas/config/tc-riscv.c                   | 9 ++++-----
 gas/testsuite/gas/riscv/auipc-parsing.l | 2 ++
 gas/testsuite/gas/riscv/auipc-parsing.s | 3 +++
 3 files changed, 9 insertions(+), 5 deletions(-)

-- 
2.17.1

Patch

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 99b007f59f..f0c1f4ca75 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1952,9 +1952,11 @@  branch:
 
 	    case 'u':		/* Upper 20 bits.  */
 	      p = percent_op_utype;
-	      if (!my_getSmallExpression (imm_expr, imm_reloc, s, p)
-		  && imm_expr->X_op == O_constant)
+	      if (!my_getSmallExpression (imm_expr, imm_reloc, s, p))
 		{
+		  if (imm_expr->X_op != O_constant)
+		    break;
+
 		  if (imm_expr->X_add_number < 0
 		      || imm_expr->X_add_number >= (signed)RISCV_BIGIMM_REACH)
 		    as_bad (_("lui expression not in range 0..1048575"));
@@ -1962,9 +1964,6 @@  branch:
 		  *imm_reloc = BFD_RELOC_RISCV_HI20;
 		  imm_expr->X_add_number <<= RISCV_IMM_BITS;
 		}
-	      /* The 'u' format specifier must be a symbol or a constant.  */
-	      if (imm_expr->X_op != O_symbol && imm_expr->X_op != O_constant)
-	        break;
 	      s = expr_end;
 	      continue;
 
diff --git a/gas/testsuite/gas/riscv/auipc-parsing.l b/gas/testsuite/gas/riscv/auipc-parsing.l
index df41e0e2f9..54eedcbf04 100644
--- a/gas/testsuite/gas/riscv/auipc-parsing.l
+++ b/gas/testsuite/gas/riscv/auipc-parsing.l
@@ -1,3 +1,5 @@ 
 .*: Assembler messages:
 .*: Error: illegal operands `auipc x8,x9'
 .*: Error: illegal operands `lui x10,x11'
+.*: Error: illegal operands `auipc x12,symbol'
+.*: Error: illegal operands `lui x13,symbol'
diff --git a/gas/testsuite/gas/riscv/auipc-parsing.s b/gas/testsuite/gas/riscv/auipc-parsing.s
index f580869cbe..7af4df9ede 100644
--- a/gas/testsuite/gas/riscv/auipc-parsing.s
+++ b/gas/testsuite/gas/riscv/auipc-parsing.s
@@ -1,3 +1,6 @@ 
 # Don't accept a register for 'u' operands.
 	auipc	x8,x9
 	lui	x10,x11
+# Don't accept a symbol without %hi() for 'u' operands.
+	auipc	x12,symbol
+	lui	x13,symbol