From: Richard Henderson Date: Mon, 10 Sep 2012 13:08:18 +0000 (-0700) Subject: * config/alpha/predicates.md (small_symbolic_operand): Disallow large offsets. X-Git-Tag: misc/gccgo-go1_1_2~965 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d75171f35f62918f604ab856643cac9f691b237c;p=thirdparty%2Fgcc.git * config/alpha/predicates.md (small_symbolic_operand): Disallow large offsets. From-SVN: r191138 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c53ed7bb74ab..6e7175afd3fd 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 598742f81e7a..0a1885bd5f92 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