OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.h
index 0ec9ac9..0dfdd3a 100644 (file)
@@ -1,6 +1,7 @@
 /* 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, 2010
+   Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com).
    Improved by Jim Wilson (wilson@cygnus.com).
 
@@ -91,12 +92,19 @@ do { \
     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)
 
-/* We can not debug without a frame pointer.  */
-/* #define CAN_DEBUG_WITHOUT_FP */
+/* 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.  */
+
+#ifndef SUBTARGET_FRAME_POINTER_REQUIRED
+#define SUBTARGET_FRAME_POINTER_REQUIRED 0
+#endif
 
 #define CONDITIONAL_REGISTER_USAGE do                                  \
 {                                                                      \
@@ -459,49 +467,6 @@ do { \
 #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;                                           \
-  /* Likewise for flag_ira_share_spill_slots.  */                      \
-  if (flag_ira_share_spill_slots > 0)                                  \
-    flag_ira_share_spill_slots = 2;                                    \
-                                                                       \
-  set_param_value ("simultaneous-prefetches", 2);                      \
-} while (0)
 
 #define ASSEMBLER_DIALECT assembler_dialect
 
@@ -536,241 +501,6 @@ extern enum sh_divide_strategy_e sh_div_strategy;
 
 #define SUBTARGET_OVERRIDE_OPTIONS (void) 0
 
-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;                                      \
-       }                                                               \
-    }                                                                  \
-                                                                       \
-  /* FIXME.  Currently -fira-share-spill-slots causes a wrong code     \
-     problem PR 37514, though the compiler generates lengthy codes     \
-     in some cases without it.  */                                     \
-  if (flag_ira_share_spill_slots == 2)                                 \
-    flag_ira_share_spill_slots = 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)
 \f
 /* Target machine storage layout.  */
 
@@ -786,14 +516,6 @@ do {                                                                       \
    numbered.  */
 #define WORDS_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
 
-/* Define this to set the endianness to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#if defined(__LITTLE_ENDIAN__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#endif
-
 #define MAX_BITS_PER_WORD 64
 
 /* Width in bits of an `int'.  We want just 32-bits, even if words are
@@ -891,13 +613,13 @@ do {                                                                      \
   barrier_align (LABEL_AFTER_BARRIER)
 
 #define LOOP_ALIGN(A_LABEL) \
-  ((! optimize || TARGET_HARD_SH4 || TARGET_SMALLCODE) \
+  ((! optimize || TARGET_HARD_SH4 || optimize_size) \
    ? 0 : sh_loop_align (A_LABEL))
 
 #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.  */                  \
@@ -909,9 +631,9 @@ do {                                                                        \
 
 /* 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)
 \f
@@ -1271,12 +993,6 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 
 #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
@@ -1309,11 +1025,6 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
  { 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.  */
 
@@ -1482,11 +1193,12 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
   FPUL_REGS, LIM_REG_CLASSES                                                \
 }
 
-/* When defined, the compiler allows registers explicitly used in the
-   rtl to be used as spill registers but prevents the compiler from
-   extending the lifetime of these registers.  */
-
-#define SMALL_REGISTER_CLASSES (! TARGET_SHMEDIA)
+/* When this hook returns true for MODE, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers
+   but prevents the compiler from extending the lifetime of these
+   registers.  */
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+  sh_small_register_classes_for_mode_p
 
 /* The order in which register should be allocated.  */
 /* Sometimes FP0_REGS becomes the preferred class of a floating point pseudo,
@@ -1562,12 +1274,12 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 #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))                         \
@@ -1575,8 +1287,8 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
    : (((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)))))               \
@@ -1584,13 +1296,13 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
    : (((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))
 
@@ -1605,7 +1317,7 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
          && (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))                                     \
@@ -1615,8 +1327,8 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
       ? 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                                                        \
@@ -1695,17 +1407,6 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 /* Offset of first parameter from the argument pointer register value.  */
 #define FIRST_PARM_OFFSET(FNDECL)  0
 
-/* Value is the number of byte of arguments automatically
-   popped when returning from a subroutine call.
-   FUNDECL is the declaration node of the function (as a tree),
-   FUNTYPE is the data type of the function (as a tree),
-   or for a library call it is an identifier node for the subroutine name.
-   SIZE is the number of bytes of arguments passed on the stack.
-
-   On the SH, the caller does not pop any of its arguments that were passed
-   on the stack.  */
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE)  0
-
 /* Value is the number of bytes of arguments automatically popped when
    calling a subroutine.
    CUM is the accumulated argument list.
@@ -1734,38 +1435,6 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
    ? 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))
-
 /* 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
    it as unsigned.  We get warnings unless we do casts everywhere.  */
@@ -1938,17 +1607,12 @@ struct sh_args {
 #define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
   sh_init_cumulative_args (& (CUM), NULL_TREE, (LIBNAME), NULL_TREE, 0, (MODE))
 
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
-       sh_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)   \
-       sh_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
-
 /* Return boolean indicating arg of mode MODE will be passed in a reg.
    This macro is only used in this file.  */
 
 #define PASS_IN_REG_P(CUM, MODE, TYPE) \
   (((TYPE) == 0 \
-    || (! TREE_ADDRESSABLE ((tree)(TYPE)) \
+    || (! TREE_ADDRESSABLE ((TYPE)) \
        && (! (TARGET_HITACHI || (CUM).renesas_abi) \
            || ! (AGGREGATE_TYPE_P (TYPE) \
                  || (!TARGET_FPU_ANY \
@@ -2107,26 +1771,9 @@ struct sh_args {
 
 /* Alignment required for a trampoline in bits .  */
 #define TRAMPOLINE_ALIGNMENT \
-  ((CACHE_LOG < 3 || (TARGET_SMALLCODE && ! TARGET_HARVARD)) ? 32 \
+  ((CACHE_LOG < 3 || (optimize_size && ! 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
@@ -2156,11 +1803,11 @@ struct sh_args {
 
 #define MOVE_BY_PIECES_P(SIZE, ALIGN) \
   (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
-   < (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
+   < (optimize_size ? 2 : ((ALIGN >= 32) ? 16 : 2)))
 
 #define STORE_BY_PIECES_P(SIZE, ALIGN) \
   (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
-   < (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
+   < (optimize_size ? 2 : ((ALIGN >= 32) ? 16 : 2)))
 
 #define SET_BY_PIECES_P(SIZE, ALIGN) STORE_BY_PIECES_P(SIZE, ALIGN)
 
@@ -2206,45 +1853,25 @@ struct sh_args {
 
 /* 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.  */
 
@@ -2253,11 +1880,11 @@ struct sh_args {
    || (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)                               \
@@ -2287,7 +1914,7 @@ struct sh_args {
    && (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 \
@@ -2308,7 +1935,7 @@ struct sh_args {
        && (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) \
@@ -2320,299 +1947,51 @@ struct sh_args {
       || PCREL_SYMOFF_P (OP)) \
    : NON_PIC_REFERENCE_P (OP))
 \f
-/* 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))))
+       && REG_P (SUBREG_REG (X))               \
+       && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X), STRICT)))
 
-/* 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)
+#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)
 \f
-/* 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.
-
-   Like for LEGITIMIZE_ADDRESS, for the SH we try to get a normal form
-   of the address.  That will allow inheritance of the address reloads.  */
+   mode MODE.  WIN is a C statement label elsewhere in the code.  */
 
 #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)    \
-{                                                                      \
-  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 && (MODE) == DFmode)                            \
-      && ! ((MODE) == PSImode && (TYPE) == RELOAD_FOR_INPUT_ADDRESS)   \
-      && (ALLOW_INDEXED_ADDRESS                                                \
-         || XEXP ((X), 0) == stack_pointer_rtx                         \
-         || XEXP ((X), 0) == hard_frame_pointer_rtx))                  \
-    {                                                                  \
-      rtx index_rtx = XEXP (X, 1);                                     \
-      HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;          \
-      rtx sum;                                                         \
-                                                                       \
-      if (TARGET_SH2A && (MODE) == DFmode && (offset & 0x7))           \
-       {                                                               \
-         push_reload (X, NULL_RTX, &X, NULL,                           \
-                      BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM),  \
-                      (TYPE));                                         \
-         goto WIN;                                                     \
-       }                                                               \
-      if (TARGET_SH2E && MODE == SFmode)                               \
-       {                                                               \
-         X = copy_rtx (X);                                             \
-         push_reload (X, NULL_RTX, &X, NULL,                           \
-                      BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM),  \
-                      (TYPE));                                         \
-         goto WIN;                                                     \
-       }                                                               \
-      /* 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 = gen_rtx_PLUS (Pmode, XEXP (X, 0),                       \
-                        GEN_INT (offset_base));                        \
-         X = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));\
-         push_reload (sum, NULL_RTX, &XEXP (X, 0), NULL,               \
-                      BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM),  \
-                      (TYPE));                                         \
-         goto WIN;                                                     \
-       }                                                               \
-    }                                                                  \
-  /* We must re-recognize what we created before.  */                  \
-  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             \
-          && BASE_REGISTER_RTX_P (XEXP (XEXP (X, 0), 0))               \
-          && GET_CODE (XEXP (X, 1)) == CONST_INT                       \
-          && ! TARGET_SHMEDIA                                          \
-          && ! (TARGET_SH2E && MODE == SFmode))                        \
-    {                                                                  \
-      /* Because this address is so complex, we know it must have      \
-        been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,        \
-        it is already unshared, and needs no further unsharing.  */    \
-      push_reload (XEXP ((X), 0), NULL_RTX, &XEXP ((X), 0), NULL,      \
-                  BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), (TYPE));\
+  do {                                                                 \
+    if (sh_legitimize_reload_address (&(X), (MODE), (OPNUM), (TYPE)))  \
       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)
+  } while (0)
 \f
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
@@ -2639,12 +2018,6 @@ struct sh_args {
    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__)
-#define LIBGCC2_DOUBLE_TYPE_SIZE 32
-#else
-#define LIBGCC2_DOUBLE_TYPE_SIZE 64
-#endif
-
 /* 'char' is signed by default.  */
 #define DEFAULT_SIGNED_CHAR  1
 
@@ -2733,14 +2106,14 @@ struct sh_args {
    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       \
@@ -2777,9 +2150,6 @@ struct sh_args {
   ((CLASS) == FP0_REGS || (CLASS) == FP_REGS \
    || (CLASS) == DF_REGS || (CLASS) == DF_HI_REGS)
 
-#define REGISTER_MOVE_COST(MODE, SRCCLASS, DSTCLASS) \
-  sh_register_move_cost ((MODE), (SRCCLASS), (DSTCLASS))
-
 /* ??? Perhaps make MEMORY_MOVE_COST depend on compiler option?  This
    would be so that people with slow memory systems could generate
    different code that does fewer memory accesses.  */
@@ -3028,20 +2398,6 @@ struct sh_args {
 #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
   final_prescan_insn ((INSN), (OPVEC), (NOPERANDS))
 
-/* Print operand X (an rtx) in assembler syntax to file FILE.
-   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
-   For `%' followed by punctuation, CODE is the punctuation and X is null.  */
-
-#define PRINT_OPERAND(STREAM, X, CODE)  print_operand ((STREAM), (X), (CODE))
-
-/* Print a memory address as an operand to reference that memory location.  */
-
-#define PRINT_OPERAND_ADDRESS(STREAM,X)  print_operand_address ((STREAM), (X))
-
-#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
-  ((CHAR) == '.' || (CHAR) == '#' || (CHAR) == '@' || (CHAR) == ','    \
-   || (CHAR) == '$' || (CHAR) == '\'' || (CHAR) == '>')
-
 /* Recognize machine-specific patterns that may appear within
    constants.  Used for PIC-specific UNSPECs.  */
 #define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
@@ -3172,8 +2528,6 @@ enum processor_type {
 #define sh_cpu_attr ((enum attr_cpu)sh_cpu)
 extern enum processor_type sh_cpu;
 
-extern int optimize; /* needed for gen_casesi.  */
-
 enum mdep_reorg_phase_e
 {
   SH_BEFORE_MDEP_REORG,
@@ -3228,14 +2582,12 @@ extern int current_function_interrupt;
 
 #define SIDI_OFF (TARGET_LITTLE_ENDIAN ? 0 : 4)
 
-/* ??? Define ACCUMULATE_OUTGOING_ARGS?  This is more efficient than pushing
-   and popping arguments.  However, we do have push/pop instructions, and
-   rather limited offsets (4 bits) in load/store instructions, so it isn't
-   clear if this would give better code.  If implemented, should check for
-   compatibility problems.  */
+/* Better to allocate once the maximum space for outgoing args in the
+   prologue rather than duplicate around each call.  */
+#define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
 
 #define SH_DYNAMIC_SHIFT_COST \
-  (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
+  (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (optimize_size ? 1 : 2) : 20)
 
 
 #define NUM_MODES_FOR_MODE_SWITCHING { FP_MODE_NONE }