diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/config/tc-riscv.c | 38 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/c-ld.d | 17 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/c-ld.s | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/c-lw.d | 17 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/c-lw.s | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/riscv/riscv.exp | 2 |
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" } |