mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 12:23:31 +08:00
Compress loads/stores with implicit 0 offset.
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.
This commit is contained in:
@ -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>
|
2017-11-27 Max Filippov <jcmvbkbc@gmail.com>
|
||||||
|
|
||||||
* config/tc-xtensa.c (find_trampoline_seg): Add static variable
|
* config/tc-xtensa.c (find_trampoline_seg): Add static variable
|
||||||
|
@ -1185,6 +1185,25 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
|
|||||||
return reloc_index;
|
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
|
/* This routine assembles an instruction into its binary format. As a
|
||||||
side effect, it sets the global variable imm_reloc to the type of
|
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. */
|
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);
|
ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number);
|
||||||
goto rvc_imm_done;
|
goto rvc_imm_done;
|
||||||
case 'k':
|
case 'k':
|
||||||
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
|
continue;
|
||||||
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
||||||
|| imm_expr->X_op != O_constant
|
|| imm_expr->X_op != O_constant
|
||||||
|| !VALID_RVC_LW_IMM (imm_expr->X_add_number))
|
|| !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);
|
ip->insn_opcode |= ENCODE_RVC_LW_IMM (imm_expr->X_add_number);
|
||||||
goto rvc_imm_done;
|
goto rvc_imm_done;
|
||||||
case 'l':
|
case 'l':
|
||||||
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
|
continue;
|
||||||
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
||||||
|| imm_expr->X_op != O_constant
|
|| imm_expr->X_op != O_constant
|
||||||
|| !VALID_RVC_LD_IMM (imm_expr->X_add_number))
|
|| !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);
|
ip->insn_opcode |= ENCODE_RVC_LD_IMM (imm_expr->X_add_number);
|
||||||
goto rvc_imm_done;
|
goto rvc_imm_done;
|
||||||
case 'm':
|
case 'm':
|
||||||
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
|
continue;
|
||||||
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
||||||
|| imm_expr->X_op != O_constant
|
|| imm_expr->X_op != O_constant
|
||||||
|| !VALID_RVC_LWSP_IMM (imm_expr->X_add_number))
|
|| !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);
|
ENCODE_RVC_LWSP_IMM (imm_expr->X_add_number);
|
||||||
goto rvc_imm_done;
|
goto rvc_imm_done;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
|
continue;
|
||||||
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
||||||
|| imm_expr->X_op != O_constant
|
|| imm_expr->X_op != O_constant
|
||||||
|| !VALID_RVC_LDSP_IMM (imm_expr->X_add_number))
|
|| !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);
|
ENCODE_RVC_ADDI16SP_IMM (imm_expr->X_add_number);
|
||||||
goto rvc_imm_done;
|
goto rvc_imm_done;
|
||||||
case 'M':
|
case 'M':
|
||||||
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
|
continue;
|
||||||
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
||||||
|| imm_expr->X_op != O_constant
|
|| imm_expr->X_op != O_constant
|
||||||
|| !VALID_RVC_SWSP_IMM (imm_expr->X_add_number))
|
|| !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);
|
ENCODE_RVC_SWSP_IMM (imm_expr->X_add_number);
|
||||||
goto rvc_imm_done;
|
goto rvc_imm_done;
|
||||||
case 'N':
|
case 'N':
|
||||||
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
|
continue;
|
||||||
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
|
||||||
|| imm_expr->X_op != O_constant
|
|| imm_expr->X_op != O_constant
|
||||||
|| !VALID_RVC_SDSP_IMM (imm_expr->X_add_number))
|
|| !VALID_RVC_SDSP_IMM (imm_expr->X_add_number))
|
||||||
@ -1618,12 +1649,7 @@ rvc_lui:
|
|||||||
p = percent_op_rtype;
|
p = percent_op_rtype;
|
||||||
*imm_reloc = BFD_RELOC_UNUSED;
|
*imm_reloc = BFD_RELOC_UNUSED;
|
||||||
load_store:
|
load_store:
|
||||||
/* Check whether there is only a single bracketed expression
|
if (riscv_handle_implicit_zero_offset (imm_expr, s))
|
||||||
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)
|
|
||||||
continue;
|
continue;
|
||||||
alu_op:
|
alu_op:
|
||||||
/* If this value won't fit into a 16 bit offset, then go
|
/* If this value won't fit into a 16 bit offset, then go
|
||||||
|
17
gas/testsuite/gas/riscv/c-ld.d
Normal file
17
gas/testsuite/gas/riscv/c-ld.d
Normal file
@ -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\)
|
9
gas/testsuite/gas/riscv/c-ld.s
Normal file
9
gas/testsuite/gas/riscv/c-ld.s
Normal file
@ -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'
|
17
gas/testsuite/gas/riscv/c-lw.d
Normal file
17
gas/testsuite/gas/riscv/c-lw.d
Normal file
@ -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\)
|
9
gas/testsuite/gas/riscv/c-lw.s
Normal file
9
gas/testsuite/gas/riscv/c-lw.s
Normal file
@ -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'
|
@ -26,4 +26,6 @@ if [istarget riscv*-*-*] {
|
|||||||
run_dump_test "c-addi16sp-fail"
|
run_dump_test "c-addi16sp-fail"
|
||||||
run_dump_test "satp"
|
run_dump_test "satp"
|
||||||
run_dump_test "eh-relocs"
|
run_dump_test "eh-relocs"
|
||||||
|
run_dump_test "c-lw"
|
||||||
|
run_dump_test "c-ld"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user