aarch64-protos.h (aarch64_classify_symbol): Fixup prototype.
authorTejas Belagod <tejas.belagod@arm.com>
Thu, 20 Nov 2014 13:58:23 +0000 (13:58 +0000)
committerTejas Belagod <belagod@gcc.gnu.org>
Thu, 20 Nov 2014 13:58:23 +0000 (13:58 +0000)
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

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/symbol-range.c [new file with mode: 0644]

index 2a4d0099884f5f65add01321f13ee3060791c414..9aaac254e9da540ed58462c3f537af9044530fea 100644 (file)
@@ -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
index a9985b5ab76ec1823271adddea6805a9ad78490b..8ef6401ab3cc4d0f33c3bad6e97f7a228b9560fb 100644 (file)
@@ -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);
index 38321237eb3e4d2ea3e5120b4a5863dea40a807b..2d8f48d11990e2cbc91cbda8015a51bad4089b4e 100644 (file)
@@ -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;
 
index 853a83b52bcb6096141427ec53cf9b84c54ac22c..61f8a495a42d8978293b3315a7960f5010208be1 100644 (file)
@@ -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 (file)
index 0000000..d7d2039
--- /dev/null
@@ -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 (file)
index 0000000..f999bb3
--- /dev/null
@@ -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 } } */