This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[BFD][AARCH64]Fix MOVW_SABS_G(0,1,2) relocation overflow check.
- From: Renlin Li <renlin dot li at foss dot arm dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: Nicholas Clifton <nickc at redhat dot com>, Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Date: Thu, 25 Feb 2016 10:45:09 +0000
- Subject: [BFD][AARCH64]Fix MOVW_SABS_G(0,1,2) relocation overflow check.
- Authentication-results: sourceware.org; auth=none
Hi all,
This patch fixes the overflow check for
R_AARCH64_MOVW_SABS_G0
R_AARCH64_MOVW_SABS_G1
R_AARCH64_MOVW_SABS_G2
According to the aarch64 elf specification, for those relocations with
overflow check, the following rule applies:
X > 0: Set the instruction to MOVZ and its immediate value to the
selected bits S;
for relocation R_..._Gn, check that X< {G0: 2^16 , G1 : 2^32 , G2 : 2^48
} (no check for R_..._G3).
X < 0: Set the instruction to MOVN and its immediate value to NOT
(selected bits of);
for relocation R_..._Gn , check that -{ G0 : 2^16 , G1 : 2^32 , G2 :
2^48 } ? X (no check for R_..._G3).
This rule indicates:
1, signed overflow check should be used.
2, For the allowed range, 17 bit signed value should be used, instead of
16 bit.
Here the bitsize field is changed from 16 to 17, this field in aarch64
backend is used for overflow check only.
the BFD already have the functions to re-encode the instruction into
movz/movn according to the sign of the value.
Only the overflow check needs to be fixed!
binutils regression test checked Okay, Okay for trunk?
Regards,
Renlin Li
bfd/ChangeLog:
2016-02-25 Renlin Li <renlin.li@arm.com>
* elfnn-aarch64.c (elfNN_aarch64_howto_table): Fix signed overflow
check for MOVW_SABS_G0, MOVW_SABS_G1, MOVW_SABS_G2.
ld/ChangeLog:
2016-02-25 Renlin Li <renlin.li@arm.com>
* testsuite/ld-aarch64/aarch64-elf.exp: Run new testcases.
* testsuite/ld-aarch64/emit-relocs-270.d: Update to use new boundary.
* testsuite/ld-aarch64/emit-relocs-271.d: Likewise.
* testsuite/ld-aarch64/emit-relocs-272.d: Likewise.
* testsuite/ld-aarch64/emit-relocs-270-overflow.d: New.
* testsuite/ld-aarch64/emit-relocs-270-overflow.s: New.
* testsuite/ld-aarch64/emit-relocs-271-overflow.d: New.
* testsuite/ld-aarch64/emit-relocs-271-overflow.s: New.
* testsuite/ld-aarch64/emit-relocs-272-overflow.d: New.
* testsuite/ld-aarch64/emit-relocs-272-overflow.s: New.
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 08cf0aa6c4208bb60ba5071bad1255d587f1cb4a..ef5809ff226cca69bb711bfc5dab55e24caba01a 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -3882,6 +3882,8 @@ curr_insn_transform (bool check_only_p)
}
*loc = new_reg;
if (type != OP_IN
+ /* Don't generate reload for output scratch operand. */
+ && GET_CODE (old) != SCRATCH
&& find_reg_note (curr_insn, REG_UNUSED, old) == NULL_RTX)
{
start_sequence ();