This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, riscv] Compress loads/stores with implicit 0 offset.


Loads and stores with an explcit 0 offset were compressed, but loads and
stores with an implicit 0 offset were not compressed.  This patch fixes this
by handling a missing offset same as a zero offset.  This also adds tests
to check every case.  Verified on riscv32-elf and riscv64-elf, with check-gas,
check-binutils, and check-ld.  Committed.

	gas/
	* config/tc-riscv.c (riscv_handle_implicit_zero_offset): New.
	(riscv_ip): Cases 'k', 'l', 'm', 'n', 'M', 'N', add call to
	riscv_handle_implicit_zero_offset.  At label load_store, replace
	existing code with call to riscv_handle_implicit_zero_offset.
	* testsuite/gas/riscv/c-ld.d, testsuite/gas/riscv/c-ld.s: New.
	* testsuite/gas/riscv/c-lw.d, testsuite/gas/riscv/c-lw.s: New.
	* testsuite/gas/riscv/riscv.exp: Run new tests.
---
 gas/config/tc-riscv.c             | 38 ++++++++++++++++++++++++++++++++------
 gas/testsuite/gas/riscv/c-ld.d    | 17 +++++++++++++++++
 gas/testsuite/gas/riscv/c-ld.s    |  9 +++++++++
 gas/testsuite/gas/riscv/c-lw.d    | 17 +++++++++++++++++
 gas/testsuite/gas/riscv/c-lw.s    |  9 +++++++++
 gas/testsuite/gas/riscv/riscv.exp |  2 ++
 6 files changed, 86 insertions(+), 6 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/c-ld.d
 create mode 100644 gas/testsuite/gas/riscv/c-ld.s
 create mode 100644 gas/testsuite/gas/riscv/c-lw.d
 create mode 100644 gas/testsuite/gas/riscv/c-lw.s

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index bdaf270470..8bb400e100 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1185,6 +1185,25 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
   return reloc_index;
 }
 
+/* Detect and handle implicitly zero load-store offsets.  For example,
+   "lw t0, (t1)" is shorthand for "lw t0, 0(t1)".  Return TRUE iff such
+   an implicit offset was detected.  */
+
+static bfd_boolean
+riscv_handle_implicit_zero_offset (expressionS *expr, const char *s)
+{
+  /* Check whether there is only a single bracketed expression left.
+     If so, it must be the base register and the constant must be zero.  */
+  if (*s == '(' && strchr (s + 1, '(') == 0)
+    {
+      expr->X_op = O_constant;
+      expr->X_add_number = 0;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 /* This routine assembles an instruction into its binary format.  As a
    side effect, it sets the global variable imm_reloc to the type of
    relocation to do if one of the operands is an address expression.  */
@@ -1325,6 +1344,8 @@ rvc_imm_done:
 		  ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number);
 		  goto rvc_imm_done;
 		case 'k':
+		  if (riscv_handle_implicit_zero_offset (imm_expr, s))
+		    continue;
 		  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 		      || imm_expr->X_op != O_constant
 		      || !VALID_RVC_LW_IMM (imm_expr->X_add_number))
@@ -1332,6 +1353,8 @@ rvc_imm_done:
 		  ip->insn_opcode |= ENCODE_RVC_LW_IMM (imm_expr->X_add_number);
 		  goto rvc_imm_done;
 		case 'l':
+		  if (riscv_handle_implicit_zero_offset (imm_expr, s))
+		    continue;
 		  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 		      || imm_expr->X_op != O_constant
 		      || !VALID_RVC_LD_IMM (imm_expr->X_add_number))
@@ -1339,6 +1362,8 @@ rvc_imm_done:
 		  ip->insn_opcode |= ENCODE_RVC_LD_IMM (imm_expr->X_add_number);
 		  goto rvc_imm_done;
 		case 'm':
+		  if (riscv_handle_implicit_zero_offset (imm_expr, s))
+		    continue;
 		  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 		      || imm_expr->X_op != O_constant
 		      || !VALID_RVC_LWSP_IMM (imm_expr->X_add_number))
@@ -1347,6 +1372,8 @@ rvc_imm_done:
 		    ENCODE_RVC_LWSP_IMM (imm_expr->X_add_number);
 		  goto rvc_imm_done;
 		case 'n':
+		  if (riscv_handle_implicit_zero_offset (imm_expr, s))
+		    continue;
 		  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 		      || imm_expr->X_op != O_constant
 		      || !VALID_RVC_LDSP_IMM (imm_expr->X_add_number))
@@ -1380,6 +1407,8 @@ rvc_imm_done:
 		    ENCODE_RVC_ADDI16SP_IMM (imm_expr->X_add_number);
 		  goto rvc_imm_done;
 		case 'M':
+		  if (riscv_handle_implicit_zero_offset (imm_expr, s))
+		    continue;
 		  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 		      || imm_expr->X_op != O_constant
 		      || !VALID_RVC_SWSP_IMM (imm_expr->X_add_number))
@@ -1388,6 +1417,8 @@ rvc_imm_done:
 		    ENCODE_RVC_SWSP_IMM (imm_expr->X_add_number);
 		  goto rvc_imm_done;
 		case 'N':
+		  if (riscv_handle_implicit_zero_offset (imm_expr, s))
+		    continue;
 		  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
 		      || imm_expr->X_op != O_constant
 		      || !VALID_RVC_SDSP_IMM (imm_expr->X_add_number))
@@ -1618,12 +1649,7 @@ rvc_lui:
 	      p = percent_op_rtype;
 	      *imm_reloc = BFD_RELOC_UNUSED;
 load_store:
-	      /* Check whether there is only a single bracketed expression
-		 left.  If so, it must be the base register and the
-		 constant must be zero.  */
-	      imm_expr->X_op = O_constant;
-	      imm_expr->X_add_number = 0;
-	      if (*s == '(' && strchr (s + 1, '(') == 0)
+	      if (riscv_handle_implicit_zero_offset (imm_expr, s))
 		continue;
 alu_op:
 	      /* If this value won't fit into a 16 bit offset, then go
diff --git a/gas/testsuite/gas/riscv/c-ld.d b/gas/testsuite/gas/riscv/c-ld.d
new file mode 100644
index 0000000000..29315e6b68
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-ld.d
@@ -0,0 +1,17 @@
+#as: -march=rv64ic
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+0:[ 	]+6108[ 	]+ld[ 	]+a0,0\(a0\)
+[ 	]+2:[ 	]+6108[ 	]+ld[ 	]+a0,0\(a0\)
+[ 	]+4:[ 	]+e108[ 	]+sd[ 	]+a0,0\(a0\)
+[ 	]+6:[ 	]+e108[ 	]+sd[ 	]+a0,0\(a0\)
+[ 	]+8:[ 	]+6502[ 	]+ld[ 	]+a0,0\(sp\)
+[ 	]+a:[ 	]+6502[ 	]+ld[ 	]+a0,0\(sp\)
+[ 	]+c:[ 	]+e02a[ 	]+sd[ 	]+a0,0\(sp\)
+[ 	]+e:[ 	]+e02a[ 	]+sd[ 	]+a0,0\(sp\)
diff --git a/gas/testsuite/gas/riscv/c-ld.s b/gas/testsuite/gas/riscv/c-ld.s
new file mode 100644
index 0000000000..11b9e5574d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-ld.s
@@ -0,0 +1,9 @@
+target:
+	ld a0, (a0)  # 'Cl'
+	ld a0, 0(a0) # 'Cl'
+	sd a0, (a0)  # 'Cl'
+	sd a0, 0(a0) # 'Cl'
+	ld a0, (sp)  # 'Cn'
+	ld a0, 0(sp) # 'Cn'
+	sd a0, (sp)  # 'CN'
+	sd a0, 0(sp) # 'CN'
diff --git a/gas/testsuite/gas/riscv/c-lw.d b/gas/testsuite/gas/riscv/c-lw.d
new file mode 100644
index 0000000000..f3ea3b2d2d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-lw.d
@@ -0,0 +1,17 @@
+#as: -march=rv32ic
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+0:[ 	]+4108[ 	]+lw[ 	]+a0,0\(a0\)
+[ 	]+2:[ 	]+4108[ 	]+lw[ 	]+a0,0\(a0\)
+[ 	]+4:[ 	]+c108[ 	]+sw[ 	]+a0,0\(a0\)
+[ 	]+6:[ 	]+c108[ 	]+sw[ 	]+a0,0\(a0\)
+[ 	]+8:[ 	]+4502[ 	]+lw[ 	]+a0,0\(sp\)
+[ 	]+a:[ 	]+4502[ 	]+lw[ 	]+a0,0\(sp\)
+[ 	]+c:[ 	]+c02a[ 	]+sw[ 	]+a0,0\(sp\)
+[ 	]+e:[ 	]+c02a[ 	]+sw[ 	]+a0,0\(sp\)
diff --git a/gas/testsuite/gas/riscv/c-lw.s b/gas/testsuite/gas/riscv/c-lw.s
new file mode 100644
index 0000000000..3cf58f92f5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/c-lw.s
@@ -0,0 +1,9 @@
+target:
+	lw a0, (a0)  # 'Ck'
+	lw a0, 0(a0) # 'Ck'
+	sw a0, (a0)  # 'Ck'
+	sw a0, 0(a0) # 'Ck'
+	lw a0, (sp)  # 'Cm'
+	lw a0, 0(sp) # 'Cm'
+	sw a0, (sp)  # 'CM'
+	sw a0, 0(sp) # 'CM'
diff --git a/gas/testsuite/gas/riscv/riscv.exp b/gas/testsuite/gas/riscv/riscv.exp
index 8a128acdcf..5ef92f5006 100644
--- a/gas/testsuite/gas/riscv/riscv.exp
+++ b/gas/testsuite/gas/riscv/riscv.exp
@@ -26,4 +26,6 @@ if [istarget riscv*-*-*] {
     run_dump_test "c-addi16sp-fail"
     run_dump_test "satp"
     run_dump_test "eh-relocs"
+    run_dump_test "c-lw"
+    run_dump_test "c-ld"
 }
-- 
2.14.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]