aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-riscv.c38
-rw-r--r--gas/testsuite/gas/riscv/c-ld.d17
-rw-r--r--gas/testsuite/gas/riscv/c-ld.s9
-rw-r--r--gas/testsuite/gas/riscv/c-lw.d17
-rw-r--r--gas/testsuite/gas/riscv/c-lw.s9
-rw-r--r--gas/testsuite/gas/riscv/riscv.exp2
7 files changed, 99 insertions, 6 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 81f9f83..e54872d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2017-11-27 Andrew Waterman <andrew@sifive.com>
+ Palmer Dabbelt <palmer@sifive.com>
+ Jim Wilson <jimw@sifive.com>
+
+ 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.
+
2017-11-27 Max Filippov <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (find_trampoline_seg): Add static variable
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index bdaf270..8bb400e 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 0000000..29315e6
--- /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 0000000..11b9e55
--- /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 0000000..f3ea3b2
--- /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 0000000..3cf58f9
--- /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 8a128ac..5ef92f5 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"
}