aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcollison <collison@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-10 07:10:56 +0000
committercollison <collison@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-10 07:10:56 +0000
commit98688f43a4375c5d5e330029833fec9cafb88548 (patch)
treed56049842b781759800d7c1b4f6fa672c023b395
parentabb5761872044fdd1a3eeaa8edf8d6cecd8dbea4 (diff)
2015-03-10 Michael Collison <michael.collison@linaro.org>
Backport from trunk r217852. 2014-11-20 Tejas Belagod <tejas.belagod@arm.com> * config/aarch64/aarch64-protos.h (aarch64_classify_symbol): Fixup prototype. * config/aarch64/aarch64.c (aarch64_expand_mov_immediate, aarch64_cannot_force_const_mem, aarch64_classify_address, aarch64_classify_symbolic_expression): Fixup call to aarch64_classify_symbol. (aarch64_classify_symbol): Add range-checking for symbol + offset addressing for tiny and small models. 2015-03-10 Michael Collison <michael.collison@linaro.org> Backport from trunk r217852. 2014-11-20 Tejas Belagod <tejas.belagod@arm.com> * gcc.target/aarch64/symbol-range.c: New. * gcc.target/aarch64/symbol-range-tiny.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@221300 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.linaro14
-rw-r--r--gcc/config/aarch64/aarch64-protos.h2
-rw-r--r--gcc/config/aarch64/aarch64.c27
-rw-r--r--gcc/testsuite/ChangeLog.linaro8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c13
-rw-r--r--gcc/testsuite/gcc.target/aarch64/symbol-range.c13
6 files changed, 69 insertions, 8 deletions
diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro
index af134cf7bf3..c3008875183 100644
--- a/gcc/ChangeLog.linaro
+++ b/gcc/ChangeLog.linaro
@@ -1,3 +1,17 @@
+2015-03-10 Michael Collison <michael.collison@linaro.org>
+
+ Backport from trunk r217852.
+ 2014-11-20 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_classify_symbol):
+ Fixup prototype.
+ * config/aarch64/aarch64.c (aarch64_expand_mov_immediate,
+ aarch64_cannot_force_const_mem, aarch64_classify_address,
+ aarch64_classify_symbolic_expression): Fixup call to
+ aarch64_classify_symbol.
+ (aarch64_classify_symbol): Add range-checking for
+ symbol + offset addressing for tiny and small models.
+
2015-03-06 Christophe Lyon <christophe.lyon@linaro.org>
Backport from trunk r217707.
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 379df12031f..b0e5a31e3e7 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -216,7 +216,7 @@ bool aarch64_uimm12_shift (HOST_WIDE_INT);
const char *aarch64_output_casesi (rtx *);
const char *aarch64_rewrite_selected_cpu (const char *name);
-enum aarch64_symbol_type aarch64_classify_symbol (rtx,
+enum aarch64_symbol_type aarch64_classify_symbol (rtx, rtx,
enum aarch64_symbol_context);
enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
enum reg_class aarch64_regno_regclass (unsigned);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index eb4554bdd83..4bbcca74eb9 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1324,7 +1324,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
before we start classifying the symbol. */
split_const (imm, &base, &offset);
- sty = aarch64_classify_symbol (base, SYMBOL_CONTEXT_ADR);
+ sty = aarch64_classify_symbol (base, offset, SYMBOL_CONTEXT_ADR);
switch (sty)
{
case SYMBOL_FORCE_TO_MEM:
@@ -2994,7 +2994,7 @@ aarch64_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
split_const (x, &base, &offset);
if (GET_CODE (base) == SYMBOL_REF || GET_CODE (base) == LABEL_REF)
{
- if (aarch64_classify_symbol (base, SYMBOL_CONTEXT_ADR)
+ if (aarch64_classify_symbol (base, offset, SYMBOL_CONTEXT_ADR)
!= SYMBOL_FORCE_TO_MEM)
return true;
else
@@ -3408,7 +3408,7 @@ aarch64_classify_address (struct aarch64_address_info *info,
rtx sym, offs;
split_const (info->offset, &sym, &offs);
if (GET_CODE (sym) == SYMBOL_REF
- && (aarch64_classify_symbol (sym, SYMBOL_CONTEXT_MEM)
+ && (aarch64_classify_symbol (sym, offs, SYMBOL_CONTEXT_MEM)
== SYMBOL_SMALL_ABSOLUTE))
{
/* The symbol and offset must be aligned to the access size. */
@@ -3465,7 +3465,7 @@ aarch64_classify_symbolic_expression (rtx x,
rtx offset;
split_const (x, &x, &offset);
- return aarch64_classify_symbol (x, context);
+ return aarch64_classify_symbol (x, offset, context);
}
@@ -6607,7 +6607,7 @@ aarch64_classify_tls_symbol (rtx x)
LABEL_REF X in context CONTEXT. */
enum aarch64_symbol_type
-aarch64_classify_symbol (rtx x,
+aarch64_classify_symbol (rtx x, rtx offset,
enum aarch64_symbol_context context ATTRIBUTE_UNUSED)
{
if (GET_CODE (x) == LABEL_REF)
@@ -6641,12 +6641,25 @@ aarch64_classify_symbol (rtx x,
switch (aarch64_cmodel)
{
case AARCH64_CMODEL_TINY:
- if (SYMBOL_REF_WEAK (x))
+ /* When we retreive symbol + offset address, we have to make sure
+ the offset does not cause overflow of the final address. But
+ we have no way of knowing the address of symbol at compile time
+ so we can't accurately say if the distance between the PC and
+ symbol + offset is outside the addressible range of +/-1M in the
+ TINY code model. So we rely on images not being greater than
+ 1M and cap the offset at 1M and anything beyond 1M will have to
+ be loaded using an alternative mechanism. */
+ if (SYMBOL_REF_WEAK (x)
+ || INTVAL (offset) < -1048575 || INTVAL (offset) > 1048575)
return SYMBOL_FORCE_TO_MEM;
return SYMBOL_TINY_ABSOLUTE;
case AARCH64_CMODEL_SMALL:
- if (SYMBOL_REF_WEAK (x))
+ /* Same reasoning as the tiny code model, but the offset cap here is
+ 4G. */
+ if (SYMBOL_REF_WEAK (x)
+ || INTVAL (offset) < (HOST_WIDE_INT) -4294967263
+ || INTVAL (offset) > (HOST_WIDE_INT) 4294967264)
return SYMBOL_FORCE_TO_MEM;
return SYMBOL_SMALL_ABSOLUTE;
diff --git a/gcc/testsuite/ChangeLog.linaro b/gcc/testsuite/ChangeLog.linaro
index 93775f9b058..2dc587a6608 100644
--- a/gcc/testsuite/ChangeLog.linaro
+++ b/gcc/testsuite/ChangeLog.linaro
@@ -1,3 +1,11 @@
+2015-03-10 Michael Collison <michael.collison@linaro.org>
+
+ Backport from trunk r217852.
+ 2014-11-20 Tejas Belagod <tejas.belagod@arm.com>
+
+ * gcc.target/aarch64/symbol-range.c: New.
+ * gcc.target/aarch64/symbol-range-tiny.c: New.
+
2015-03-06 Christophe Lyon <christophe.lyon@linaro.org>
Backport from trunk r218463, r219764, r219765, r219767, r219914,
diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
new file mode 100644
index 00000000000..d7d2039694f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -save-temps -mcmodel=tiny" } */
+
+int fixed_regs[0x00200000];
+
+int
+foo()
+{
+ return fixed_regs[0x00080000];
+}
+
+/* { dg-final { scan-assembler-not "adr\tx\[0-9\]+, fixed_regs\\\+" } } */
+/* { dg-final {cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range.c b/gcc/testsuite/gcc.target/aarch64/symbol-range.c
new file mode 100644
index 00000000000..f999bb38102
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/symbol-range.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -save-temps -mcmodel=small" } */
+
+int fixed_regs[0x200000000ULL];
+
+int
+foo()
+{
+ return fixed_regs[0x100000000ULL];
+}
+
+/* { dg-final { scan-assembler-not "adrp\tx\[0-9\]+, fixed_regs\\\+" } } */
+/* { dg-final {cleanup-saved-temps } } */