aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTejas Belagod <tejas.belagod@arm.com>2014-11-20 13:58:23 +0000
committerTejas Belagod <belagod@gcc.gnu.org>2014-11-20 13:58:23 +0000
commitf8b756b74c2ef815ab2d6164ccc97dc32578cf8c (patch)
tree9ea2abe70a6cbe692f694d574b7bd7fd6257181d /gcc
parent1b6b13f3eeae79e4ba9b0888f623bdf30467ad46 (diff)
downloadgcc-f8b756b74c2ef815ab2d6164ccc97dc32578cf8c.zip
gcc-f8b756b74c2ef815ab2d6164ccc97dc32578cf8c.tar.gz
gcc-f8b756b74c2ef815ab2d6164ccc97dc32578cf8c.tar.bz2
aarch64-protos.h (aarch64_classify_symbol): Fixup prototype.
2014-11-20 Tejas Belagod <tejas.belagod@arm.com> gcc/ * 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. testsuite/ * gcc.target/aarch64/symbol-range.c: New. * gcc.target/aarch64/symbol-range-tiny.c: New. From-SVN: r217852
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/aarch64/aarch64-protos.h2
-rw-r--r--gcc/config/aarch64/aarch64.c27
-rw-r--r--gcc/testsuite/ChangeLog4
-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, 62 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2a4d009..9aaac25 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
2014-11-20 Richard Biener <rguenther@suse.de>
PR middle-end/63962
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a9985b5..8ef6401 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -218,7 +218,7 @@ const char *aarch64_mangle_builtin_type (const_tree);
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 3832123..2d8f48d 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1339,7 +1339,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:
@@ -3024,7 +3024,7 @@ aarch64_cannot_force_const_mem (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
@@ -3438,7 +3438,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. */
@@ -3495,7 +3495,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);
}
@@ -6834,7 +6834,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)
@@ -6868,12 +6868,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 b/gcc/testsuite/ChangeLog
index 853a83b..61f8a49 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-20 Tejas Belagod <tejas.belagod@arm.com>
+
+ * gcc.target/aarch64/symbol-range.c: New.
+ * gcc.target/aarch64/symbol-range-tiny.c: New.
2014-11-20 Richard Biener <rguenther@suse.de>
PR middle-end/63962
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 0000000..d7d2039
--- /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 0000000..f999bb3
--- /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 } } */