diff gcc/config/sh/sh.h @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
line wrap: on
line diff
--- a/gcc/config/sh/sh.h	Sun Feb 07 18:28:00 2010 +0900
+++ b/gcc/config/sh/sh.h	Fri Feb 12 23:39:51 2010 +0900
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com).
    Improved by Jim Wilson (wilson@cygnus.com).
 
@@ -91,6 +91,8 @@
     builtin_define ("__SH_FPU_DOUBLE__"); \
   if (TARGET_HITACHI) \
     builtin_define ("__HITACHI__"); \
+  if (TARGET_FMOVD) \
+    builtin_define ("__FMOVD_ENABLED__"); \
   builtin_define (TARGET_LITTLE_ENDIAN \
 		  ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
 } while (0)
@@ -459,46 +461,8 @@
 #endif
 
 #define DRIVER_SELF_SPECS "%{m2a:%{ml:%eSH2a does not support little-endian}}"
-#define OPTIMIZATION_OPTIONS(LEVEL,SIZE)				\
-do {									\
-  if (LEVEL)								\
-    {									\
-      flag_omit_frame_pointer = 2;					\
-      if (! SIZE)							\
-	sh_div_str = "inv:minlat";					\
-    }									\
-  if (SIZE)								\
-    {									\
-      target_flags |= MASK_SMALLCODE;					\
-      sh_div_str = SH_DIV_STR_FOR_SIZE ;				\
-    }									\
-  else									\
-    {									\
-      TARGET_CBRANCHDI4 = 1;						\
-      TARGET_EXPAND_CBRANCHDI4 = 1;					\
-    }									\
-  /* We can't meaningfully test TARGET_SHMEDIA here, because -m options	\
-     haven't been parsed yet, hence we'd read only the default.	\
-     sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so	\
-     it's OK to always set flag_branch_target_load_optimize.  */	\
-  if (LEVEL > 1)							\
-    {									\
-      flag_branch_target_load_optimize = 1;				\
-      if (! (SIZE))							\
-	target_flags |= MASK_SAVE_ALL_TARGET_REGS;			\
-    }									\
-  /* Likewise, we can't meaningfully test TARGET_SH2E / TARGET_IEEE	\
-     here, so leave it to OVERRIDE_OPTIONS to set			\
-    flag_finite_math_only.  We set it to 2 here so we know if the user	\
-    explicitly requested this to be on or off.  */			\
-  flag_finite_math_only = 2;						\
-  /* If flag_schedule_insns is 1, we set it to 2 here so we know if	\
-     the user explicitly requested this to be on or off.  */		\
-  if (flag_schedule_insns > 0)						\
-    flag_schedule_insns = 2;						\
-									\
-  set_param_value ("simultaneous-prefetches", 2);			\
-} while (0)
+
+#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) sh_optimization_options (LEVEL, SIZE)
 
 #define ASSEMBLER_DIALECT assembler_dialect
 
@@ -535,233 +499,8 @@
 
 extern const char *sh_fixed_range_str;
 
-#define OVERRIDE_OPTIONS 						\
-do {									\
-  int regno;								\
-									\
-  SUBTARGET_OVERRIDE_OPTIONS;						\
-  if (flag_finite_math_only == 2)					\
-    flag_finite_math_only						\
-      = !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE;		\
-  if (TARGET_SH2E && !flag_finite_math_only)				\
-    target_flags |= MASK_IEEE;						\
-  sh_cpu = CPU_SH1;							\
-  assembler_dialect = 0;						\
-  if (TARGET_SH2)							\
-    sh_cpu = CPU_SH2;							\
-  if (TARGET_SH2E)							\
-    sh_cpu = CPU_SH2E;							\
-  if (TARGET_SH2A)							\
-    {									\
-      sh_cpu = CPU_SH2A;						\
-      if (TARGET_SH2A_DOUBLE)						\
-        target_flags |= MASK_FMOVD;					\
-    }									\
-  if (TARGET_SH3)							\
-    sh_cpu = CPU_SH3;							\
-  if (TARGET_SH3E)							\
-    sh_cpu = CPU_SH3E;							\
-  if (TARGET_SH4)							\
-    {									\
-      assembler_dialect = 1;						\
-      sh_cpu = CPU_SH4;							\
-    }									\
-  if (TARGET_SH4A_ARCH)							\
-    {									\
-      assembler_dialect = 1;						\
-      sh_cpu = CPU_SH4A;						\
-    }									\
-  if (TARGET_SH5)							\
-    {									\
-      sh_cpu = CPU_SH5;							\
-      target_flags |= MASK_ALIGN_DOUBLE;				\
-      if (TARGET_SHMEDIA_FPU)						\
-	target_flags |= MASK_FMOVD;					\
-      if (TARGET_SHMEDIA)						\
-	{								\
-	  /* There are no delay slots on SHmedia.  */			\
-	  flag_delayed_branch = 0;					\
-	  /* Relaxation isn't yet supported for SHmedia */		\
-	  target_flags &= ~MASK_RELAX;					\
-	  /* After reload, if conversion does little good but can cause \
-	     ICEs:							\
-	     - find_if_block doesn't do anything for SH because we don't\
-	       have conditional execution patterns.  (We use conditional\
-	       move patterns, which are handled differently, and only	\
-	       before reload).						\
-	     - find_cond_trap doesn't do anything for the SH because we \	
-	       don't have conditional traps.				\
-	     - find_if_case_1 uses redirect_edge_and_branch_force in	\
-	       the only path that does an optimization, and this causes	\
-	       an ICE when branch targets are in registers.		\
-	     - find_if_case_2 doesn't do anything for the SHmedia after	\
-	       reload except when it can redirect a tablejump - and	\
-	       that's rather rare.  */					\
-	  flag_if_conversion2 = 0;					\
-	  if (! strcmp (sh_div_str, "call"))				\
-	    sh_div_strategy = SH_DIV_CALL;				\
-	  else if (! strcmp (sh_div_str, "call2"))			\
-	    sh_div_strategy = SH_DIV_CALL2;				\
-	  if (! strcmp (sh_div_str, "fp") && TARGET_FPU_ANY)		\
-	    sh_div_strategy = SH_DIV_FP;				\
-	  else if (! strcmp (sh_div_str, "inv"))			\
-	    sh_div_strategy = SH_DIV_INV;				\
-	  else if (! strcmp (sh_div_str, "inv:minlat"))			\
-	    sh_div_strategy = SH_DIV_INV_MINLAT;			\
-	  else if (! strcmp (sh_div_str, "inv20u"))			\
-	    sh_div_strategy = SH_DIV_INV20U;				\
-	  else if (! strcmp (sh_div_str, "inv20l"))			\
-	    sh_div_strategy = SH_DIV_INV20L;				\
-	  else if (! strcmp (sh_div_str, "inv:call2"))			\
-	    sh_div_strategy = SH_DIV_INV_CALL2;				\
-	  else if (! strcmp (sh_div_str, "inv:call"))			\
-	    sh_div_strategy = SH_DIV_INV_CALL;				\
-	  else if (! strcmp (sh_div_str, "inv:fp"))			\
-	    {								\
-	      if (TARGET_FPU_ANY)					\
-		sh_div_strategy = SH_DIV_INV_FP;			\
-	      else							\
-		sh_div_strategy = SH_DIV_INV;				\
-	    }								\
-	  TARGET_CBRANCHDI4 = 0;					\
-	  /* Assembler CFI isn't yet fully supported for SHmedia.  */	\
-	  flag_dwarf2_cfi_asm = 0;					\
-	}								\
-    }									\
-  else									\
-    {									\
-       /* Only the sh64-elf assembler fully supports .quad properly.  */\
-       targetm.asm_out.aligned_op.di = NULL;				\
-       targetm.asm_out.unaligned_op.di = NULL;				\
-    }									\
-  if (TARGET_SH1)							\
-    {									\
-      if (! strcmp (sh_div_str, "call-div1"))				\
-	sh_div_strategy = SH_DIV_CALL_DIV1;				\
-      else if (! strcmp (sh_div_str, "call-fp")				\
-	       && (TARGET_FPU_DOUBLE					\
-		   || (TARGET_HARD_SH4 && TARGET_SH2E)			\
-		   || (TARGET_SHCOMPACT && TARGET_FPU_ANY)))		\
-	sh_div_strategy = SH_DIV_CALL_FP;				\
-      else if (! strcmp (sh_div_str, "call-table") && TARGET_SH2)	\
-	sh_div_strategy = SH_DIV_CALL_TABLE;				\
-      else								\
-	/* Pick one that makes most sense for the target in general.	\
-	   It is not much good to use different functions depending	\
-	   on -Os, since then we'll end up with two different functions	\
-	   when some of the code is compiled for size, and some for	\
-	   speed.  */							\
-									\
-	/* SH4 tends to emphasize speed.  */				\
-	if (TARGET_HARD_SH4)						\
-	  sh_div_strategy = SH_DIV_CALL_TABLE;				\
-	/* These have their own way of doing things.  */		\
-	else if (TARGET_SH2A)						\
-	  sh_div_strategy = SH_DIV_INTRINSIC;				\
-	/* ??? Should we use the integer SHmedia function instead?  */	\
-	else if (TARGET_SHCOMPACT && TARGET_FPU_ANY)			\
-	  sh_div_strategy = SH_DIV_CALL_FP;				\
-        /* SH1 .. SH3 cores often go into small-footprint systems, so	\
-	   default to the smallest implementation available.  */	\
-	else if (TARGET_SH2)	/* ??? EXPERIMENTAL */			\
-	  sh_div_strategy = SH_DIV_CALL_TABLE;				\
-	else								\
-	  sh_div_strategy = SH_DIV_CALL_DIV1;				\
-    }									\
-  if (!TARGET_SH1)							\
-    TARGET_PRETEND_CMOVE = 0;						\
-  if (sh_divsi3_libfunc[0])						\
-    ; /* User supplied - leave it alone.  */				\
-  else if (TARGET_DIVIDE_CALL_FP)					\
-    sh_divsi3_libfunc = "__sdivsi3_i4";					\
-  else if (TARGET_DIVIDE_CALL_TABLE)					\
-    sh_divsi3_libfunc = "__sdivsi3_i4i";				\
-  else if (TARGET_SH5)							\
-    sh_divsi3_libfunc = "__sdivsi3_1";					\
-  else									\
-    sh_divsi3_libfunc = "__sdivsi3";					\
-  if (sh_branch_cost == -1)						\
-    sh_branch_cost							\
-      = TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1;	\
-									\
-  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)		\
-    if (! VALID_REGISTER_P (regno))					\
-      sh_register_names[regno][0] = '\0';				\
-									\
-  for (regno = 0; regno < ADDREGNAMES_SIZE; regno++)			\
-    if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno)))			\
-      sh_additional_register_names[regno][0] = '\0';			\
-									\
-  if (flag_omit_frame_pointer == 2)					\
-   {									\
-     /* The debugging information is sufficient,			\
-        but gdb doesn't implement this yet */				\
-     if (0)								\
-      flag_omit_frame_pointer						\
-        = (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG);			\
-     else								\
-      flag_omit_frame_pointer = 0;					\
-   }									\
-									\
-  if ((flag_pic && ! TARGET_PREFERGOT)					\
-      || (TARGET_SHMEDIA && !TARGET_PT_FIXED))				\
-    flag_no_function_cse = 1;						\
-									\
-  if (SMALL_REGISTER_CLASSES)						\
-    {									\
-      /* Never run scheduling before reload, since that can		\
-	 break global alloc, and generates slower code anyway due	\
-	 to the pressure on R0.  */					\
-      /* Enable sched1 for SH4; ready queue will be reordered by	\
-	 the target hooks when pressure is high. We can not do this for \
-	 PIC, SH3 and lower as they give spill failures for R0.  */	\
-      if (!TARGET_HARD_SH4 || flag_pic)					\
-        flag_schedule_insns = 0;		 			\
-      /* ??? Current exception handling places basic block boundaries	\
-	 after call_insns.  It causes the high pressure on R0 and gives	\
-	 spill failures for R0 in reload.  See PR 22553 and the thread	\
-	 on gcc-patches							\
-         <http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00816.html>.  */	\
-      else if (flag_exceptions)						\
-	{								\
-	  if (flag_schedule_insns == 1)		 			\
-	    warning (0, "ignoring -fschedule-insns because of exception handling bug");	\
-	  flag_schedule_insns = 0;		 			\
-	}								\
-    }									\
-									\
-  if (align_loops == 0)							\
-    align_loops =  1 << (TARGET_SH5 ? 3 : 2);				\
-  if (align_jumps == 0)							\
-    align_jumps = 1 << CACHE_LOG;					\
-  else if (align_jumps < (TARGET_SHMEDIA ? 4 : 2))			\
-    align_jumps = TARGET_SHMEDIA ? 4 : 2;				\
-									\
-  /* Allocation boundary (in *bytes*) for the code of a function.	\
-     SH1: 32 bit alignment is faster, because instructions are always	\
-     fetched as a pair from a longword boundary.			\
-     SH2 .. SH5 : align to cache line start.  */			\
-  if (align_functions == 0)						\
-    align_functions							\
-      = TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);	\
-  /* The linker relaxation code breaks when a function contains		\
-     alignments that are larger than that at the start of a		\
-     compilation unit.  */						\
-  if (TARGET_RELAX)							\
-    {									\
-      int min_align							\
-	= align_loops > align_jumps ? align_loops : align_jumps;	\
-									\
-      /* Also take possible .long constants / mova tables int account.	*/\
-      if (min_align < 4)						\
-	min_align = 4;							\
-      if (align_functions < min_align)					\
-	align_functions = min_align;					\
-    }									\
-									\
-  if (sh_fixed_range_str)						\
-    sh_fix_range (sh_fixed_range_str);					\
-} while (0)
+#define OVERRIDE_OPTIONS sh_override_options ()
+
 
 /* Target machine storage layout.  */
 
@@ -888,7 +627,7 @@
 #define LABEL_ALIGN(A_LABEL) \
 (									\
   (PREV_INSN (A_LABEL)							\
-   && GET_CODE (PREV_INSN (A_LABEL)) == INSN				\
+   && NONJUMP_INSN_P (PREV_INSN (A_LABEL))				\
    && GET_CODE (PATTERN (PREV_INSN (A_LABEL))) == UNSPEC_VOLATILE	\
    && XINT (PATTERN (PREV_INSN (A_LABEL)), 1) == UNSPECV_ALIGN)		\
    /* explicit alignment insn in constant tables.  */			\
@@ -900,9 +639,9 @@
 
 /* The base two logarithm of the known minimum alignment of an insn length.  */
 #define INSN_LENGTH_ALIGNMENT(A_INSN)					\
-  (GET_CODE (A_INSN) == INSN						\
+  (NONJUMP_INSN_P (A_INSN)						\
    ? 1 << TARGET_SHMEDIA						\
-   : GET_CODE (A_INSN) == JUMP_INSN || GET_CODE (A_INSN) == CALL_INSN	\
+   : JUMP_P (A_INSN) || CALL_P (A_INSN)					\
    ? 1 << TARGET_SHMEDIA						\
    : CACHE_LOG)
 
@@ -1262,12 +1001,6 @@
 
 #define GOT_SYMBOL_NAME "*_GLOBAL_OFFSET_TABLE_"
 
-/* Value should be nonzero if functions must have frame pointers.
-   Zero means the frame pointer need not be set up (and parms may be accessed
-   via the stack pointer) in functions that seem suitable.  */
-
-#define FRAME_POINTER_REQUIRED	0
-
 /* Definitions for register eliminations.
 
    We have three registers that can be eliminated on the SH.  First, the
@@ -1300,11 +1033,6 @@
  { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},			\
  { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},}
 
-/* Given FROM and TO register numbers, say whether this elimination
-   is allowed.  */
-#define CAN_ELIMINATE(FROM, TO) \
-  (!((FROM) == HARD_FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED))
-
 /* Define the offset between two registers, one to be eliminated, and the other
    its replacement, at the start of a routine.  */
 
@@ -1553,12 +1281,12 @@
 #if 0
 #define SECONDARY_INOUT_RELOAD_CLASS(CLASS,MODE,X,ELSE) \
   ((((REGCLASS_HAS_FP_REG (CLASS) 					\
-      && (GET_CODE (X) == REG						\
+      && (REG_P (X)							\
       && (GENERAL_OR_AP_REGISTER_P (REGNO (X))				\
 	  || (FP_REGISTER_P (REGNO (X)) && (MODE) == SImode		\
 	      && TARGET_FMOVD))))					\
      || (REGCLASS_HAS_GENERAL_REG (CLASS) 				\
-	 && GET_CODE (X) == REG						\
+	 && REG_P (X)							\
 	 && FP_REGISTER_P (REGNO (X))))					\
     && ! TARGET_SHMEDIA							\
     && ((MODE) == SFmode || (MODE) == SImode))				\
@@ -1566,8 +1294,8 @@
    : (((CLASS) == FPUL_REGS						\
        || (REGCLASS_HAS_FP_REG (CLASS)					\
 	   && ! TARGET_SHMEDIA && MODE == SImode))			\
-      && (GET_CODE (X) == MEM						\
-	  || (GET_CODE (X) == REG					\
+      && (MEM_P (X)							\
+	  || (REG_P (X)							\
 	      && (REGNO (X) >= FIRST_PSEUDO_REGISTER			\
 		  || REGNO (X) == T_REG					\
 		  || system_reg_operand (X, VOIDmode)))))		\
@@ -1575,13 +1303,13 @@
    : (((CLASS) == TARGET_REGS						\
        || (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS))			\
       && !satisfies_constraint_Csy (X)					\
-      && (GET_CODE (X) != REG || ! GENERAL_REGISTER_P (REGNO (X))))	\
+      && (!REG_P (X) || ! GENERAL_REGISTER_P (REGNO (X))))		\
    ? GENERAL_REGS							\
    : (((CLASS) == MAC_REGS || (CLASS) == PR_REGS)			\
-      && GET_CODE (X) == REG && ! GENERAL_REGISTER_P (REGNO (X))	\
+      && REG_P (X) && ! GENERAL_REGISTER_P (REGNO (X))			\
       && (CLASS) != REGNO_REG_CLASS (REGNO (X)))			\
    ? GENERAL_REGS							\
-   : ((CLASS) != GENERAL_REGS && GET_CODE (X) == REG			\
+   : ((CLASS) != GENERAL_REGS && REG_P (X)				\
       && TARGET_REGISTER_P (REGNO (X)))					\
    ? GENERAL_REGS : (ELSE))
 
@@ -1596,7 +1324,7 @@
 	  && (MODE) == SFmode && fldi_ok ()))				\
    ? R0_REGS								\
    : ((CLASS) == FPUL_REGS						\
-      && ((GET_CODE (X) == REG						\
+      && ((REG_P (X)							\
 	   && (REGNO (X) == MACL_REG || REGNO (X) == MACH_REG		\
 	       || REGNO (X) == T_REG))					\
 	  || GET_CODE (X) == PLUS))					\
@@ -1606,8 +1334,8 @@
       ? GENERAL_REGS							\
       : R0_REGS)							\
    : ((CLASS) == FPSCR_REGS						\
-      && ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER)	\
-	  || (GET_CODE (X) == MEM && GET_CODE (XEXP ((X), 0)) == PLUS)))\
+      && ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER)		\
+	  || (MEM_P (X) && GET_CODE (XEXP ((X), 0)) == PLUS)))		\
    ? GENERAL_REGS							\
    : (REGCLASS_HAS_FP_REG (CLASS) 					\
       && TARGET_SHMEDIA							\
@@ -1725,37 +1453,7 @@
    ? FIRST_FP_PARM_REG					\
    : FIRST_PARM_REG)
 
-/* Define how to find the value returned by a function.
-   VALTYPE is the data type of the value (as a tree).
-   If the precise function being called is known, FUNC is its FUNCTION_DECL;
-   otherwise, FUNC is 0.
-   For the SH, this is like LIBCALL_VALUE, except that we must change the
-   mode like PROMOTE_MODE does.
-   ??? PROMOTE_MODE is ignored for non-scalar types.  The set of types
-   tested here has to be kept in sync with the one in explow.c:promote_mode.  */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC)					\
-  gen_rtx_REG (								\
-	   ((GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_INT		\
-	     && GET_MODE_SIZE (TYPE_MODE (VALTYPE)) < 4                 \
-	     && (TREE_CODE (VALTYPE) == INTEGER_TYPE			\
-		 || TREE_CODE (VALTYPE) == ENUMERAL_TYPE		\
-		 || TREE_CODE (VALTYPE) == BOOLEAN_TYPE			\
-		 || TREE_CODE (VALTYPE) == REAL_TYPE			\
-		 || TREE_CODE (VALTYPE) == OFFSET_TYPE))		\
-             && sh_promote_prototypes (VALTYPE)				\
-	    ? (TARGET_SHMEDIA64 ? DImode : SImode) : TYPE_MODE (VALTYPE)), \
-	   BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
-
-/* Define how to find the value returned by a library function
-   assuming the value has mode MODE.  */
-#define LIBCALL_VALUE(MODE) \
-  gen_rtx_REG ((MODE), BASE_RETURN_VALUE_REG (MODE));
-
-/* 1 if N is a possible register number for a function value.  */
-#define FUNCTION_VALUE_REGNO_P(REGNO) \
-  ((REGNO) == FIRST_RET_REG || (TARGET_SH2E && (REGNO) == FIRST_FP_RET_REG) \
-   || (TARGET_SHMEDIA_FPU && (REGNO) == FIRST_FP_RET_REG))
+#define FUNCTION_VALUE_REGNO_P(REGNO) sh_function_value_regno_p (REGNO)
 
 /* 1 if N is a possible register number for function argument passing.  */
 /* ??? There are some callers that pass REGNO as int, and others that pass
@@ -2101,23 +1799,6 @@
   ((CACHE_LOG < 3 || (TARGET_SMALLCODE && ! TARGET_HARVARD)) ? 32 \
    : TARGET_SHMEDIA ? 256 : 64)
 
-/* Emit RTL insns to initialize the variable parts of a trampoline.
-   FNADDR is an RTX for the address of the function's pure code.
-   CXT is an RTX for the static chain value for the function.  */
-
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-  sh_initialize_trampoline ((TRAMP), (FNADDR), (CXT))
-
-/* On SH5, trampolines are SHmedia code, so add 1 to the address.  */
-
-#define TRAMPOLINE_ADJUST_ADDRESS(TRAMP) do				\
-{									\
-  if (TARGET_SHMEDIA)							\
-    (TRAMP) = expand_simple_binop (Pmode, PLUS, (TRAMP), const1_rtx,	\
-				   gen_reg_rtx (Pmode), 0,		\
-				   OPTAB_LIB_WIDEN);			\
-} while (0)
-
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame.
    FRAMEADDR is already the frame pointer of the COUNT frame, so we
@@ -2197,45 +1878,25 @@
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
-   We have two alternate definitions for each of them.
-   The usual definition accepts all pseudo regs; the other rejects
-   them unless they have been allocated suitable hard regs.
-   The symbol REG_OK_STRICT causes the latter definition to be used.  */
-
-#ifndef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as a base reg
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X) \
-  (GENERAL_OR_AP_REGISTER_P (REGNO (X)) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X is a hard reg that can be used as an index
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_INDEX_P(X) \
-  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
-    : REGNO (X) == R0_REG) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X/OFFSET is a hard reg that can be used as an index
-   or if X is a pseudo reg.  */
-#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
-  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
-    : REGNO (X) == R0_REG && OFFSET == 0) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as a base reg.  */
-#define REG_OK_FOR_BASE_P(X) \
-  REGNO_OK_FOR_BASE_P (REGNO (X))
-
-/* Nonzero if X is a hard reg that can be used as an index.  */
-#define REG_OK_FOR_INDEX_P(X) \
-  REGNO_OK_FOR_INDEX_P (REGNO (X))
-
-/* Nonzero if X/OFFSET is a hard reg that can be used as an index.  */
-#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
-  (REGNO_OK_FOR_INDEX_P (REGNO (X)) && (OFFSET) == 0)
-
-#endif
+   The suitable hard regs are always accepted and all pseudo regs
+   are also accepted if STRICT is not set.  */
+
+/* Nonzero if X is a reg that can be used as a base reg.  */
+#define REG_OK_FOR_BASE_P(X, STRICT)			\
+  (GENERAL_OR_AP_REGISTER_P (REGNO (X))			\
+   || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
+/* Nonzero if X is a reg that can be used as an index.  */
+#define REG_OK_FOR_INDEX_P(X, STRICT)			\
+  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X))	\
+    : REGNO (X) == R0_REG)				\
+   || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
+/* Nonzero if X/OFFSET is a reg that can be used as an index.  */
+#define SUBREG_OK_FOR_INDEX_P(X, OFFSET, STRICT)	\
+  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X))	\
+    : REGNO (X) == R0_REG && OFFSET == 0)		\
+   || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
 
 /* Macros for extra constraints.  */
 
@@ -2244,11 +1905,11 @@
    || (GET_CODE ((OP)) == CONST						\
        && GET_CODE (XEXP ((OP), 0)) == PLUS				\
        && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF		\
-       && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
+       && CONST_INT_P (XEXP (XEXP ((OP), 0), 1))))
 
 #define IS_NON_EXPLICIT_CONSTANT_P(OP)					\
   (CONSTANT_P (OP)							\
-   && GET_CODE (OP) != CONST_INT					\
+   && !CONST_INT_P (OP)					\
    && GET_CODE (OP) != CONST_DOUBLE					\
    && (!flag_pic							\
        || (LEGITIMATE_PIC_OPERAND_P (OP)				\
@@ -2278,7 +1939,7 @@
    && (UNSPEC_GOTOFF_P (XEXP ((OP), 0)) \
        || (GET_CODE (XEXP ((OP), 0)) == PLUS \
            && UNSPEC_GOTOFF_P (XEXP (XEXP ((OP), 0), 0)) \
-	   && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT)))
+	   && CONST_INT_P (XEXP (XEXP ((OP), 0), 1)))))
 
 #define PIC_ADDR_P(OP) \
   (GET_CODE (OP) == CONST && GET_CODE (XEXP ((OP), 0)) == UNSPEC \
@@ -2299,7 +1960,7 @@
        && (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == SYMBOL_REF \
 	   || GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF \
 	   || DATALABEL_REF_NO_CONST_P (XEXP (XEXP ((OP), 0), 0))) \
-       && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
+       && CONST_INT_P (XEXP (XEXP ((OP), 0), 1))))
 
 #define PIC_REFERENCE_P(OP) \
   (GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP) \
@@ -2311,207 +1972,42 @@
       || PCREL_SYMOFF_P (OP)) \
    : NON_PIC_REFERENCE_P (OP))
 
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
-   that is a valid memory address for an instruction.
-   The MODE argument is the machine mode for the MEM expression
-   that wants to use this address.  */
-
-#define MODE_DISP_OK_4(X,MODE) \
-(GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64	\
- && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode))
-
-#define MODE_DISP_OK_8(X,MODE) \
-((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60)	\
- && ! (INTVAL(X) & 3) && ! (TARGET_SH4 && (MODE) == DFmode))
-
-#undef MODE_DISP_OK_4
-#define MODE_DISP_OK_4(X,MODE) \
-((GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64	\
-  && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode)) \
-  || ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<16383)	\
-  && ! (INTVAL(X) & 3) && TARGET_SH2A))
-
-#undef MODE_DISP_OK_8
-#define MODE_DISP_OK_8(X,MODE) \
-(((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60)	\
-  && ! (INTVAL(X) & 3) && ! ((TARGET_SH4 || TARGET_SH2A) && (MODE) == DFmode)) \
- || ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<8192)	\
-  && ! (INTVAL(X) & (TARGET_SH2A_DOUBLE ? 7 : 3)) && (TARGET_SH2A && (MODE) == DFmode)))
-
-#define BASE_REGISTER_RTX_P(X)				\
-  ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))	\
-   || (GET_CODE (X) == SUBREG				\
-       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
+#define MAYBE_BASE_REGISTER_RTX_P(X, STRICT)			\
+  ((REG_P (X) && REG_OK_FOR_BASE_P (X, STRICT))	\
+   || (GET_CODE (X) == SUBREG					\
+       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))),	\
 				 GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
-       && GET_CODE (SUBREG_REG (X)) == REG		\
-       && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+       && REG_P (SUBREG_REG (X))			\
+       && REG_OK_FOR_BASE_P (SUBREG_REG (X), STRICT)))
 
 /* Since this must be r0, which is a single register class, we must check
    SUBREGs more carefully, to be sure that we don't accept one that extends
    outside the class.  */
-#define INDEX_REGISTER_RTX_P(X)				\
-  ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))	\
-   || (GET_CODE (X) == SUBREG				\
+#define MAYBE_INDEX_REGISTER_RTX_P(X, STRICT)				\
+  ((REG_P (X) && REG_OK_FOR_INDEX_P (X, STRICT))	\
+   || (GET_CODE (X) == SUBREG					\
        && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
 				 GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
-       && GET_CODE (SUBREG_REG (X)) == REG		\
-       && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X))))
-
-/* Jump to LABEL if X is a valid address RTX.  This must also take
-   REG_OK_STRICT into account when deciding about valid registers, but it uses
-   the above macros so we are in luck.
-
-   Allow  REG
-	  REG+disp
-	  REG+r0
-	  REG++
-	  --REG  */
-
-/* ??? The SH2e does not have the REG+disp addressing mode when loading values
-   into the FRx registers.  We implement this by setting the maximum offset
-   to zero when the value is SFmode.  This also restricts loading of SFmode
-   values into the integer registers, but that can't be helped.  */
-
-/* The SH allows a displacement in a QI or HI amode, but only when the
-   other operand is R0. GCC doesn't handle this very well, so we forgo
-   all of that.
-
-   A legitimate index for a QI or HI is 0, SI can be any number 0..63,
-   DI can be any number 0..60.  */
-
-#define GO_IF_LEGITIMATE_INDEX(MODE, OP, LABEL)  			\
-  do {									\
-    if (GET_CODE (OP) == CONST_INT) 					\
-      {									\
-	if (TARGET_SHMEDIA)						\
-	  {								\
-	    int MODE_SIZE;						\
-	    /* Check if this the address of an unaligned load / store.  */\
-	    if ((MODE) == VOIDmode)					\
-	      {								\
-		if (CONST_OK_FOR_I06 (INTVAL (OP)))			\
-		  goto LABEL;						\
-		break;							\
-	      }								\
-	    MODE_SIZE = GET_MODE_SIZE (MODE);				\
-	    if (! (INTVAL (OP) & (MODE_SIZE - 1))			\
-		&& INTVAL (OP) >= -512 * MODE_SIZE			\
-		&& INTVAL (OP) < 512 * MODE_SIZE)			\
-	      goto LABEL;						\
-	    else							\
-	      break;							\
-	  }								\
-	if (TARGET_SH2A)						\
-	  {								\
-	    if (GET_MODE_SIZE (MODE) == 1				\
-		&& (unsigned) INTVAL (OP) < 4096)			\
-	    goto LABEL;							\
-	  }								\
-	if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;		      	\
-	if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;		      	\
-      }									\
-  } while(0)
+       && REG_P (SUBREG_REG (X))		\
+       && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X), STRICT)))
+
+#ifdef REG_OK_STRICT
+#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, true)
+#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, true)
+#else
+#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, false)
+#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, false)
+#endif
 
 #define ALLOW_INDEXED_ADDRESS \
   ((!TARGET_SHMEDIA32 && !TARGET_SHCOMPACT) || TARGET_ALLOW_INDEXED_ADDRESS)
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)			\
-{									\
-  if (BASE_REGISTER_RTX_P (X))						\
-    goto LABEL;								\
-  else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)	\
-	   && ! TARGET_SHMEDIA						\
-	   && BASE_REGISTER_RTX_P (XEXP ((X), 0)))			\
-    goto LABEL;								\
-  else if (GET_CODE (X) == PLUS						\
-	   && ((MODE) != PSImode || reload_completed))			\
-    {									\
-      rtx xop0 = XEXP ((X), 0);						\
-      rtx xop1 = XEXP ((X), 1);						\
-      if (GET_MODE_SIZE (MODE) <= 8 && BASE_REGISTER_RTX_P (xop0))	\
-	GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL);			\
-      if ((ALLOW_INDEXED_ADDRESS || GET_MODE (X) == DImode		\
-	   || ((xop0 == stack_pointer_rtx				\
-		|| xop0 == hard_frame_pointer_rtx)			\
-	       && REG_P (xop1) && REGNO (xop1) == R0_REG)		\
-	   || ((xop1 == stack_pointer_rtx				\
-		|| xop1 == hard_frame_pointer_rtx)			\
-	       && REG_P (xop0) && REGNO (xop0) == R0_REG))		\
-	  && ((!TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 4)		\
-	      || (TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 8)		\
-	      || ((TARGET_SH4 || TARGET_SH2A_DOUBLE)			\
-		  && TARGET_FMOVD && MODE == DFmode)))			\
-	{								\
-	  if (BASE_REGISTER_RTX_P (xop1) && INDEX_REGISTER_RTX_P (xop0))\
-	    goto LABEL;							\
-	  if (INDEX_REGISTER_RTX_P (xop1) && BASE_REGISTER_RTX_P (xop0))\
-	    goto LABEL;							\
-	}								\
-    }									\
-}
+#define GO_IF_LEGITIMATE_INDEX(MODE, OP, WIN)	\
+  do {						\
+    if (sh_legitimate_index_p ((MODE), (OP)))	\
+      goto WIN;					\
+  } while (0)
 
-/* Try machine-dependent ways of modifying an illegitimate address
-   to be legitimate.  If we find one, return the new, valid address.
-   This macro is used in only one place: `memory_address' in explow.c.
-
-   OLDX is the address as it was before break_out_memory_refs was called.
-   In some cases it is useful to look at this to decide what needs to be done.
-
-   MODE and WIN are passed so that this macro can use
-   GO_IF_LEGITIMATE_ADDRESS.
-
-   It is always safe for this macro to do nothing.  It exists to recognize
-   opportunities to optimize the output.
-
-   For the SH, if X is almost suitable for indexing, but the offset is
-   out of range, convert it into a normal form so that cse has a chance
-   of reducing the number of address registers used.  */
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)			\
-{								\
-  if (flag_pic)							\
-    (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);	\
-  if (GET_CODE (X) == PLUS					\
-      && (GET_MODE_SIZE (MODE) == 4				\
-	  || GET_MODE_SIZE (MODE) == 8)				\
-      && GET_CODE (XEXP ((X), 1)) == CONST_INT			\
-      && BASE_REGISTER_RTX_P (XEXP ((X), 0))			\
-      && ! TARGET_SHMEDIA					\
-      && ! ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode)			\
-      && ! (TARGET_SH2E && (MODE) == SFmode))			\
-    {								\
-      rtx index_rtx = XEXP ((X), 1);				\
-      HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;	\
-      rtx sum;							\
-								\
-      GO_IF_LEGITIMATE_INDEX ((MODE), index_rtx, WIN);		\
-      /* On rare occasions, we might get an unaligned pointer	\
-	 that is indexed in a way to give an aligned address.	\
-	 Therefore, keep the lower two bits in offset_base.  */ \
-      /* Instead of offset_base 128..131 use 124..127, so that	\
-	 simple add suffices.  */				\
-      if (offset > 127)						\
-	{							\
-	  offset_base = ((offset + 4) & ~60) - 4;		\
-	}							\
-      else							\
-	offset_base = offset & ~60;				\
-      /* Sometimes the normal form does not suit DImode.  We	\
-	 could avoid that by using smaller ranges, but that	\
-	 would give less optimized code when SImode is		\
-	 prevalent.  */						\
-      if (GET_MODE_SIZE (MODE) + offset - offset_base <= 64)	\
-	{							\
-	  sum = expand_binop (Pmode, add_optab, XEXP ((X), 0),	\
-			      GEN_INT (offset_base), NULL_RTX, 0, \
-			      OPTAB_LIB_WIDEN);			\
-                                                                \
-	  (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base)); \
-	  goto WIN;						\
-	}							\
-    }								\
-}
-
 /* A C compound statement that attempts to replace X, which is an address
    that needs reloading, with a valid memory address for an operand of
    mode MODE.  WIN is a C statement label elsewhere in the code.
@@ -2523,7 +2019,7 @@
 {									\
   if (GET_CODE (X) == PLUS						\
       && (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8)	\
-      && GET_CODE (XEXP (X, 1)) == CONST_INT				\
+      && CONST_INT_P (XEXP (X, 1))					\
       && BASE_REGISTER_RTX_P (XEXP (X, 0))				\
       && ! TARGET_SHMEDIA						\
       && ! (TARGET_SH4 && (MODE) == DFmode)				\
@@ -2578,9 +2074,9 @@
   else if (GET_CODE (X) == PLUS						\
 	   && (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8)	\
 	   && GET_CODE (XEXP (X, 0)) == PLUS				\
-	   && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT		\
+	   && CONST_INT_P (XEXP (XEXP (X, 0), 1))			\
 	   && BASE_REGISTER_RTX_P (XEXP (XEXP (X, 0), 0))		\
-	   && GET_CODE (XEXP (X, 1)) == CONST_INT			\
+	   && CONST_INT_P (XEXP (X, 1))					\
 	   && ! TARGET_SHMEDIA						\
 	   && ! (TARGET_SH2E && MODE == SFmode))			\
     {									\
@@ -2592,18 +2088,6 @@
       goto WIN;								\
     }									\
 }
-
-/* Go to LABEL if ADDR (a legitimate address expression)
-   has an effect that depends on the machine mode it is used for.
-
-   ??? Strictly speaking, we should also include all indexed addressing,
-   because the index scale factor is the length of the operand.
-   However, the impact of GO_IF_MODE_DEPENDENT_ADDRESS would be to
-   high if we did that.  So we rely on reload to fix things up.
-
-   Auto-increment addressing is now treated in recog.c.  */
-
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
 
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
@@ -2630,7 +2114,7 @@
    floating point types equivalent to `float'.  */
 #define DOUBLE_TYPE_SIZE ((TARGET_SH2E && ! TARGET_SH4 && ! TARGET_SH2A_DOUBLE) ? 32 : 64)
 
-#if defined(__SH2E__) || defined(__SH3E__) || defined( __SH4_SINGLE_ONLY__)
+#if defined(__SH2E__) || defined(__SH3E__) || defined( __SH2A_SINGLE_ONLY__) || defined( __SH4_SINGLE_ONLY__)
 #define LIBGCC2_DOUBLE_TYPE_SIZE 32
 #else
 #define LIBGCC2_DOUBLE_TYPE_SIZE 64
@@ -2724,14 +2208,14 @@
    in particular.  */
 
 #define INSN_SETS_ARE_DELAYED(X) 		\
-  ((GET_CODE (X) == INSN			\
+  ((NONJUMP_INSN_P (X)			\
     && GET_CODE (PATTERN (X)) != SEQUENCE	\
     && GET_CODE (PATTERN (X)) != USE		\
     && GET_CODE (PATTERN (X)) != CLOBBER	\
     && get_attr_is_sfunc (X)))
 
 #define INSN_REFERENCES_ARE_DELAYED(X) 		\
-  ((GET_CODE (X) == INSN			\
+  ((NONJUMP_INSN_P (X)			\
     && GET_CODE (PATTERN (X)) != SEQUENCE	\
     && GET_CODE (PATTERN (X)) != USE		\
     && GET_CODE (PATTERN (X)) != CLOBBER	\