From: Tejas Belagod Date: Tue, 28 Apr 2015 16:24:36 +0000 (+0100) Subject: backport: aarch64-protos.h (aarch64_classify_symbol): Fixup prototype. X-Git-Tag: releases/gcc-4.9.3~179 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c615f700e6975d4b1e356f0d1aec415dd452bda;p=thirdparty%2Fgcc.git backport: aarch64-protos.h (aarch64_classify_symbol): Fixup prototype. 2015-04-28 Tejas Belagod Backport from Mainline 2014-11-20 Tejas Belagod * 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. Backport from mainline 2014-11-20 Tejas Belagod * gcc.target/aarch64/symbol-range.c: New. * gcc.target/aarch64/symbol-range-tiny.c: New. From-SVN: r222534 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 31f084d1c6c8..dfc4425b399c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-04-28 Tejas Belagod + + Backport from Mainline + 2014-11-20 Tejas Belagod + + * 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-04-24 Michael Meissner Backport from mainline diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index bef58bf71194..11132118bf15 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -195,7 +195,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 408d8cb7797a..c0296fa2aa2d 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -919,7 +919,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: @@ -2787,7 +2787,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 @@ -3186,7 +3186,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. */ @@ -3243,7 +3243,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); } @@ -5374,7 +5374,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) @@ -5408,12 +5408,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 cfbbe5f5c952..09d3521ea7f6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-04-28 Tejas Belagod + + Backport from mainline + 2014-11-20 Tejas Belagod + + * gcc.target/aarch64/symbol-range.c: New. + * gcc.target/aarch64/symbol-range-tiny.c: New. + 2015-04-24 Bill Schmidt Backport from mainline r222362 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 000000000000..d7d2039694ff --- /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 000000000000..f999bb38102f --- /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 } } */