Commit acd17ae6 by Alan Modra Committed by Alan Modra

rs6000.c (rs6000_option_override_internal): Don't override user -mfp-in-toc.

	* config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
	override user -mfp-in-toc.
	(offsettable_ok_by_alignment): Consider just the current access
	rather than the whole object, unless BLKmode.  Handle
	CONSTANT_POOL_ADDRESS_P constants that lack a decl too.
	(use_toc_relative_ref): Allow CONSTANT_POOL_ADDRESS_P constants
	for -mcmodel=medium.
	* config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Don't
	override user -mfp-in-toc or -msum-in-toc.  Default to
	-mno-fp-in-toc for -mcmodel=medium.

From-SVN: r199781
parent a9429737
2013-06-07 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
override user -mfp-in-toc.
(offsettable_ok_by_alignment): Consider just the current access
rather than the whole object, unless BLKmode. Handle
CONSTANT_POOL_ADDRESS_P constants that lack a decl too.
(use_toc_relative_ref): Allow CONSTANT_POOL_ADDRESS_P constants
for -mcmodel=medium.
* config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Don't
override user -mfp-in-toc or -msum-in-toc. Default to
-mno-fp-in-toc for -mcmodel=medium.
2013-06-06 DJ Delorie <dj@redhat.com> 2013-06-06 DJ Delorie <dj@redhat.com>
* config/rl78/rl78.c (rl78_valid_pointer_mode): New, implements * config/rl78/rl78.c (rl78_valid_pointer_mode): New, implements
......
...@@ -136,8 +136,11 @@ extern int dot_symbols; ...@@ -136,8 +136,11 @@ extern int dot_symbols;
SET_CMODEL (CMODEL_MEDIUM); \ SET_CMODEL (CMODEL_MEDIUM); \
if (rs6000_current_cmodel != CMODEL_SMALL) \ if (rs6000_current_cmodel != CMODEL_SMALL) \
{ \ { \
TARGET_NO_FP_IN_TOC = 0; \ if (!global_options_set.x_TARGET_NO_FP_IN_TOC) \
TARGET_NO_SUM_IN_TOC = 0; \ TARGET_NO_FP_IN_TOC \
= rs6000_current_cmodel == CMODEL_MEDIUM; \
if (!global_options_set.x_TARGET_NO_SUM_IN_TOC) \
TARGET_NO_SUM_IN_TOC = 0; \
} \ } \
} \ } \
} \ } \
......
...@@ -3052,7 +3052,8 @@ rs6000_option_override_internal (bool global_init_p) ...@@ -3052,7 +3052,8 @@ rs6000_option_override_internal (bool global_init_p)
/* Place FP constants in the constant pool instead of TOC /* Place FP constants in the constant pool instead of TOC
if section anchors enabled. */ if section anchors enabled. */
if (flag_section_anchors) if (flag_section_anchors
&& !global_options_set.x_TARGET_NO_FP_IN_TOC)
TARGET_NO_FP_IN_TOC = 1; TARGET_NO_FP_IN_TOC = 1;
if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
...@@ -5519,91 +5520,102 @@ virtual_stack_registers_memory_p (rtx op) ...@@ -5519,91 +5520,102 @@ virtual_stack_registers_memory_p (rtx op)
&& regnum <= LAST_VIRTUAL_POINTER_REGISTER); && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
} }
/* Return true if memory accesses to OP are known to never straddle /* Return true if a MODE sized memory accesses to OP plus OFFSET
a 32k boundary. */ is known to not straddle a 32k boundary. */
static bool static bool
offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset, offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
enum machine_mode mode) enum machine_mode mode)
{ {
tree decl, type; tree decl, type;
unsigned HOST_WIDE_INT dsize, dalign; unsigned HOST_WIDE_INT dsize, dalign, lsb, mask;
if (GET_CODE (op) != SYMBOL_REF) if (GET_CODE (op) != SYMBOL_REF)
return false; return false;
dsize = GET_MODE_SIZE (mode);
decl = SYMBOL_REF_DECL (op); decl = SYMBOL_REF_DECL (op);
if (!decl) if (!decl)
{ {
if (GET_MODE_SIZE (mode) == 0) if (dsize == 0)
return false; return false;
/* -fsection-anchors loses the original SYMBOL_REF_DECL when /* -fsection-anchors loses the original SYMBOL_REF_DECL when
replacing memory addresses with an anchor plus offset. We replacing memory addresses with an anchor plus offset. We
could find the decl by rummaging around in the block->objects could find the decl by rummaging around in the block->objects
VEC for the given offset but that seems like too much work. */ VEC for the given offset but that seems like too much work. */
dalign = 1; dalign = BITS_PER_UNIT;
if (SYMBOL_REF_HAS_BLOCK_INFO_P (op) if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
&& SYMBOL_REF_ANCHOR_P (op) && SYMBOL_REF_ANCHOR_P (op)
&& SYMBOL_REF_BLOCK (op) != NULL) && SYMBOL_REF_BLOCK (op) != NULL)
{ {
struct object_block *block = SYMBOL_REF_BLOCK (op); struct object_block *block = SYMBOL_REF_BLOCK (op);
HOST_WIDE_INT lsb, mask;
/* Given the alignment of the block.. */
dalign = block->alignment; dalign = block->alignment;
mask = dalign / BITS_PER_UNIT - 1;
/* ..and the combined offset of the anchor and any offset
to this block object.. */
offset += SYMBOL_REF_BLOCK_OFFSET (op); offset += SYMBOL_REF_BLOCK_OFFSET (op);
lsb = offset & -offset; }
else if (CONSTANT_POOL_ADDRESS_P (op))
{
/* It would be nice to have get_pool_align().. */
enum machine_mode cmode = get_pool_mode (op);
/* ..find how many bits of the alignment we know for the dalign = GET_MODE_ALIGNMENT (cmode);
object. */
mask &= lsb - 1;
dalign = mask + 1;
} }
return dalign >= GET_MODE_SIZE (mode);
} }
else if (DECL_P (decl))
if (DECL_P (decl))
{ {
if (TREE_CODE (decl) == FUNCTION_DECL) dalign = DECL_ALIGN (decl);
return true;
if (!DECL_SIZE_UNIT (decl)) if (dsize == 0)
return false; {
/* Allow BLKmode when the entire object is known to not
cross a 32k boundary. */
if (!DECL_SIZE_UNIT (decl))
return false;
if (!host_integerp (DECL_SIZE_UNIT (decl), 1)) if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
return false; return false;
dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1); dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
if (dsize > 32768) if (dsize > 32768)
return false; return false;
dalign = DECL_ALIGN_UNIT (decl); return dalign / BITS_PER_UNIT >= dsize;
return dalign >= dsize; }
} }
else
{
type = TREE_TYPE (decl);
type = TREE_TYPE (decl); dalign = TYPE_ALIGN (type);
if (CONSTANT_CLASS_P (decl))
dalign = CONSTANT_ALIGNMENT (decl, dalign);
else
dalign = DATA_ALIGNMENT (decl, dalign);
if (TREE_CODE (decl) == STRING_CST) if (dsize == 0)
dsize = TREE_STRING_LENGTH (decl); {
else if (TYPE_SIZE_UNIT (type) /* BLKmode, check the entire object. */
&& host_integerp (TYPE_SIZE_UNIT (type), 1)) if (TREE_CODE (decl) == STRING_CST)
dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1); dsize = TREE_STRING_LENGTH (decl);
else else if (TYPE_SIZE_UNIT (type)
return false; && host_integerp (TYPE_SIZE_UNIT (type), 1))
if (dsize > 32768) dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
return false; else
return false;
if (dsize > 32768)
return false;
return dalign / BITS_PER_UNIT >= dsize;
}
}
/* Find how many bits of the alignment we know for this access. */
mask = dalign / BITS_PER_UNIT - 1;
lsb = offset & -offset;
mask &= lsb - 1;
dalign = mask + 1;
dalign = TYPE_ALIGN (type);
if (CONSTANT_CLASS_P (decl))
dalign = CONSTANT_ALIGNMENT (decl, dalign);
else
dalign = DATA_ALIGNMENT (decl, dalign);
dalign /= BITS_PER_UNIT;
return dalign >= dsize; return dalign >= dsize;
} }
...@@ -6549,7 +6561,6 @@ use_toc_relative_ref (rtx sym) ...@@ -6549,7 +6561,6 @@ use_toc_relative_ref (rtx sym)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
get_pool_mode (sym))) get_pool_mode (sym)))
|| (TARGET_CMODEL == CMODEL_MEDIUM || (TARGET_CMODEL == CMODEL_MEDIUM
&& !CONSTANT_POOL_ADDRESS_P (sym)
&& SYMBOL_REF_LOCAL_P (sym))); && SYMBOL_REF_LOCAL_P (sym)));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment