Skip to content

Commit e2afe97

Browse files
rearnshaemsr
authored andcommitted
[arm] Avoid using negative offsets for 'immediate' addresses when compiling for Thumb2
Thumb2 code now uses the Arm implementation of legitimize_address. That code has a case to handle addresses that are absolute CONST_INT values, which is a common use case in deeply embedded targets (eg: void *p = (void*)0x12345678). Since thumb has very limited negative offsets from a constant, we want to avoid forming a CSE base that will then be used with a negative value. This was reported upstream originally in https://gcc.gnu.org/ml/gcc-help/2019-10/msg00122.html For example, void test1(void) { volatile uint32_t * const p = (uint32_t *) 0x43fe1800; p[3] = 1; p[4] = 2; p[1] = 3; p[7] = 4; p[0] = 6; } With the new code, instead of ldr r3, .L2 subw r2, r3, #2035 movs r1, gcc-mirror#1 str r1, [r2] subw r2, r3, #2031 movs r1, gcc-mirror#2 str r1, [r2] subw r2, r3, #2043 movs r1, gcc-mirror#3 str r1, [r2] subw r2, r3, #2019 movs r1, gcc-mirror#4 subw r3, r3, #2047 str r1, [r2] movs r2, gcc-mirror#6 str r2, [r3] bx lr We now get ldr r3, .L2 movs r2, gcc-mirror#1 str r2, [r3, #2060] movs r2, gcc-mirror#2 str r2, [r3, #2064] movs r2, gcc-mirror#3 str r2, [r3, #2052] movs r2, gcc-mirror#4 str r2, [r3, #2076] movs r2, gcc-mirror#6 str r2, [r3, #2048] bx lr * config/arm/arm.c (arm_legitimize_address): Don't form negative offsets from a CONST_INT address when TARGET_THUMB2. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277677 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent e76ee7f commit e2afe97

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

gcc/ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2019-10-31 Richard Earnshaw <[email protected]>
2+
3+
* config/arm/arm.c (arm_legitimize_address): Don't form negative offsets
4+
from a CONST_INT address when TARGET_THUMB2.
5+
16
2019-10-31 Richard Earnshaw <[email protected]>
27

38
* config/arm/arm.md (add_not_cin): New insn.

gcc/config/arm/arm.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9039,17 +9039,20 @@ arm_legitimize_address (rtx x, rtx orig_x, machine_mode mode)
90399039
HOST_WIDE_INT mask, base, index;
90409040
rtx base_reg;
90419041

9042-
/* ldr and ldrb can use a 12-bit index, ldrsb and the rest can only
9043-
use a 8-bit index. So let's use a 12-bit index for SImode only and
9044-
hope that arm_gen_constant will enable ldrb to use more bits. */
9042+
/* LDR and LDRB can use a 12-bit index, ldrsb and the rest can
9043+
only use a 8-bit index. So let's use a 12-bit index for
9044+
SImode only and hope that arm_gen_constant will enable LDRB
9045+
to use more bits. */
90459046
bits = (mode == SImode) ? 12 : 8;
90469047
mask = (1 << bits) - 1;
90479048
base = INTVAL (x) & ~mask;
90489049
index = INTVAL (x) & mask;
9049-
if (bit_count (base & 0xffffffff) > (32 - bits)/2)
9050-
{
9051-
/* It'll most probably be more efficient to generate the base
9052-
with more bits set and use a negative index instead. */
9050+
if (TARGET_ARM && bit_count (base & 0xffffffff) > (32 - bits)/2)
9051+
{
9052+
/* It'll most probably be more efficient to generate the
9053+
base with more bits set and use a negative index instead.
9054+
Don't do this for Thumb as negative offsets are much more
9055+
limited. */
90539056
base |= mask;
90549057
index -= mask;
90559058
}

0 commit comments

Comments
 (0)