From f8b756b74c2ef815ab2d6164ccc97dc32578cf8c Mon Sep 17 00:00:00 2001 From: Tejas Belagod Date: Thu, 20 Nov 2014 13:58:23 +0000 Subject: [PATCH] aarch64-protos.h (aarch64_classify_symbol): Fixup prototype. 2014-11-20 Tejas Belagod 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 | 11 ++++++++ gcc/config/aarch64/aarch64-protos.h | 2 +- gcc/config/aarch64/aarch64.c | 27 ++++++++++++++----- gcc/testsuite/ChangeLog | 4 +++ .../gcc.target/aarch64/symbol-range-tiny.c | 13 +++++++++ .../gcc.target/aarch64/symbol-range.c | 13 +++++++++ 6 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c create mode 100644 gcc/testsuite/gcc.target/aarch64/symbol-range.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a4d0099884..9aaac254e9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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. + 2014-11-20 Richard Biener PR middle-end/63962 diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index a9985b5ab76..8ef6401ab3c 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 38321237eb3..2d8f48d1199 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 853a83b52bc..61f8a495a42 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-11-20 Tejas Belagod + + * gcc.target/aarch64/symbol-range.c: New. + * gcc.target/aarch64/symbol-range-tiny.c: New. 2014-11-20 Richard Biener 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 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 } } */ -- 2.30.2