From: rth Date: Mon, 10 Sep 2012 13:08:18 +0000 (+0000) Subject: * config/alpha/predicates.md (small_symbolic_operand): Disallow large offsets. X-Git-Tag: upstream/4.9.2~10736 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ee6dc489b8ba6dcc8c8f13cd827185a7d88669d;p=platform%2Fupstream%2Flinaro-gcc.git * config/alpha/predicates.md (small_symbolic_operand): Disallow large offsets. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191138 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c53ed7b..6e7175a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-09-10 Richard Henderson + + * config/alpha/predicates.md (small_symbolic_operand): Disallow + large offsets. + 2012-09-10 Georg-Johann Lay PR target/54536 diff --git a/gcc/config/alpha/predicates.md b/gcc/config/alpha/predicates.md index 598742f..0a1885b 100644 --- a/gcc/config/alpha/predicates.md +++ b/gcc/config/alpha/predicates.md @@ -328,26 +328,50 @@ (define_predicate "small_symbolic_operand" (match_code "const,symbol_ref") { + HOST_WIDE_INT ofs = 0, max_ofs = 0; + if (! TARGET_SMALL_DATA) - return 0; + return false; if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS && CONST_INT_P (XEXP (XEXP (op, 0), 1))) - op = XEXP (XEXP (op, 0), 0); + { + ofs = INTVAL (XEXP (XEXP (op, 0), 1)); + op = XEXP (XEXP (op, 0), 0); + } if (GET_CODE (op) != SYMBOL_REF) - return 0; + return false; /* ??? There's no encode_section_info equivalent for the rtl constant pool, so SYMBOL_FLAG_SMALL never gets set. */ if (CONSTANT_POOL_ADDRESS_P (op)) - return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value; + { + max_ofs = GET_MODE_SIZE (get_pool_mode (op)); + if (max_ofs > g_switch_value) + return false; + } + else if (SYMBOL_REF_LOCAL_P (op) + && SYMBOL_REF_SMALL_P (op) + && !SYMBOL_REF_WEAK (op) + && !SYMBOL_REF_TLS_MODEL (op)) + { + if (SYMBOL_REF_DECL (op)) + max_ofs = tree_low_cst (DECL_SIZE_UNIT (SYMBOL_REF_DECL (op)), 1); + } + else + return false; - return (SYMBOL_REF_LOCAL_P (op) - && SYMBOL_REF_SMALL_P (op) - && !SYMBOL_REF_WEAK (op) - && !SYMBOL_REF_TLS_MODEL (op)); + /* Given that we know that the GP is always 8 byte aligned, we can + always adjust by 7 without overflowing. */ + if (max_ofs < 8) + max_ofs = 8; + + /* Since we know this is an object in a small data section, we know the + entire section is addressable via GP. We don't know where the section + boundaries are, but we know the entire object is within. */ + return IN_RANGE (ofs, 0, max_ofs - 1); }) ;; Return true if OP is a SYMBOL_REF or CONST referencing a variable