diff mbox

[RS6000] -mfp-in-toc

Message ID 20130604141512.GC6878@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra June 4, 2013, 2:15 p.m. UTC
This patch allows the user to specify -mfp-in-toc/-msum-in-toc options
without being overridden when -fsection-anchors or -mcmodel != small
is in effect.  I also change the default to -mno-fp-in-toc for
-mcmodel=medium, because -mcmodel=medium ought to be able to address
constants anywhere from the toc pointer, and putting them in their
usual constant sections (.rodata.cst4 and .rodata.cst8) allow them to
be merged at link time.  For -mcmodel=large we keep the default as
-mfp-in-toc because large code model requires a toc entry to address
any constant outside the TOC.

The patch also allows -mcmodel=medium toc relative addressing for
CONSTANT_POOL_ADDRESS_P constants (the very sort we get from
force_const_mem when -mno-fp-in-toc), and allows combine to merge the
low-part of the address calculation with the load/store from memory.
I'm not sure now why I had this disabled, perhaps there was a problem
when we split toc refs early.  Bootstrapped and regression tested
powerpc64-linux.  OK to apply?

	* config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
	override user -mfp-in-toc.
	(legitimate_constant_pool_address_p): Assume sufficent alignment
	on all CONSTANT_POOL_ADDRESS_P constants, not just those put in
	the TOC.
	(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.
diff mbox

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 199646)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3042,7 +3042,8 @@  rs6000_option_override_internal (bool global_init_
 
   /* Place FP constants in the constant pool instead of TOC
      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;
 
   if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
@@ -5617,7 +5618,8 @@  legitimate_constant_pool_address_p (const_rtx x, e
 {
   return (toc_relative_expr_p (x, strict)
 	  && (TARGET_CMODEL != CMODEL_MEDIUM
-	      || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
+	      || (GET_CODE (XVECEXP (tocrel_base, 0, 0)) == SYMBOL_REF
+		  && CONSTANT_POOL_ADDRESS_P (XVECEXP (tocrel_base, 0, 0)))
 	      || mode == QImode
 	      || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
 					      INTVAL (tocrel_offset), mode)));
@@ -6504,7 +6506,6 @@  use_toc_relative_ref (rtx sym)
 	   && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
 					       get_pool_mode (sym)))
 	  || (TARGET_CMODEL == CMODEL_MEDIUM
-	      && !CONSTANT_POOL_ADDRESS_P (sym)
 	      && SYMBOL_REF_LOCAL_P (sym)));
 }
 
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h	(revision 199644)
+++ gcc/config/rs6000/linux64.h	(working copy)
@@ -136,8 +136,11 @@  extern int dot_symbols;
 		SET_CMODEL (CMODEL_MEDIUM);			\
 	      if (rs6000_current_cmodel != CMODEL_SMALL)	\
 		{						\
-		  TARGET_NO_FP_IN_TOC = 0;			\
-		  TARGET_NO_SUM_IN_TOC = 0;			\
+		  if (!global_options_set.x_TARGET_NO_FP_IN_TOC) \
+		    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;			\
 		}						\
 	    }							\
 	}							\