OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.h
index 5f6cc48..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 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).
 
@@ -8,7 +9,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -17,13 +18,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #ifndef GCC_SH_H
 #define GCC_SH_H
 
+#include "config/vxworks-dummy.h"
+
 #define TARGET_VERSION \
   fputs (" (Hitachi SH)", stderr);
 
@@ -84,19 +86,25 @@ do { \
          builtin_define ("__SH4_NOFPU__"); \
       } \
     } \
+  if (TARGET_FPU_ANY) \
+    builtin_define ("__SH_FPU_ANY__"); \
+  if (TARGET_FPU_DOUBLE) \
+    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__"); \
-  if (flag_pic) \
-    { \
-      builtin_define ("__pic__"); \
-      builtin_define ("__PIC__"); \
-    } \
 } 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                                  \
 {                                                                      \
@@ -144,104 +152,50 @@ do { \
        SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);     \
 } while (0)
 \f
-/* ??? Need to write documentation for all SH options and add it to the
-   invoke.texi file.  */
-
-/* Run-time compilation parameters selecting different hardware subsets.  */
-
-extern int target_flags;
-#define ISIZE_BIT              (1<<1)
-#define DALIGN_BIT             (1<<6)
-#define SH1_BIT                (1<<8)
-#define SH2_BIT                (1<<9)
-#define SH3_BIT                (1<<10)
-#define SH_E_BIT       (1<<11)
-#define HARD_SH4_BIT   (1<<5)
-#define FPU_SINGLE_BIT (1<<7)
-#define SH4_BIT                (1<<12)
-#define SH4A_BIT       (1<<3)
-#define FMOVD_BIT      (1<<4)
-#define SH5_BIT                (1<<0)
-#define SPACE_BIT      (1<<13)
-#define BIGTABLE_BIT   (1<<14)
-#define RELAX_BIT      (1<<15)
-#define USERMODE_BIT   (1<<16)
-#define HITACHI_BIT     (1<<22)
-#define NOMACSAVE_BIT   (1<<23)
-#define PREFERGOT_BIT  (1<<24)
-#define PADSTRUCT_BIT  (1<<28)
-#define LITTLE_ENDIAN_BIT (1<<29)
-#define IEEE_BIT (1<<30)
-#define SAVE_ALL_TR_BIT (1<<2)
-#define HARD_SH2A_BIT  (1<<17)
-#define HARD_SH2A_DOUBLE_BIT   (1<<18)
-
 /* Nonzero if this is an ELF target - compile time only */
 #define TARGET_ELF 0
 
-/* Nonzero if we should dump out instruction size info.  */
-#define TARGET_DUMPISIZE  (target_flags & ISIZE_BIT)
-
-/* Nonzero to align doubles on 64 bit boundaries.  */
-#define TARGET_ALIGN_DOUBLE (target_flags & DALIGN_BIT)
-
-/* Nonzero if we should generate code using type 1 insns.  */
-#define TARGET_SH1 (target_flags & SH1_BIT)
-
-/* Nonzero if we should generate code using type 2 insns.  */
-#define TARGET_SH2 (target_flags & SH2_BIT)
-
 /* Nonzero if we should generate code using type 2E insns.  */
-#define TARGET_SH2E ((target_flags & SH_E_BIT) && TARGET_SH2)
+#define TARGET_SH2E (TARGET_SH2 && TARGET_SH_E)
 
 /* Nonzero if we should generate code using type 2A insns.  */
-#define TARGET_SH2A (target_flags & HARD_SH2A_BIT)
+#define TARGET_SH2A TARGET_HARD_SH2A
 /* Nonzero if we should generate code using type 2A SF insns.  */
-#define TARGET_SH2A_SINGLE ((target_flags & HARD_SH2A_BIT) && TARGET_SH2E)
+#define TARGET_SH2A_SINGLE (TARGET_SH2A && TARGET_SH2E)
 /* Nonzero if we should generate code using type 2A DF insns.  */
-#define TARGET_SH2A_DOUBLE ((target_flags & HARD_SH2A_DOUBLE_BIT) && TARGET_SH2A)
-
-/* Nonzero if we should generate code using type 3 insns.  */
-#define TARGET_SH3 (target_flags & SH3_BIT)
+#define TARGET_SH2A_DOUBLE (TARGET_HARD_SH2A_DOUBLE && TARGET_SH2A)
 
 /* Nonzero if we should generate code using type 3E insns.  */
-#define TARGET_SH3E ((target_flags & SH_E_BIT) && TARGET_SH3)
+#define TARGET_SH3E (TARGET_SH3 && TARGET_SH_E)
 
 /* Nonzero if the cache line size is 32.  */
-#define TARGET_CACHE32 (target_flags & HARD_SH4_BIT || TARGET_SH5)
+#define TARGET_CACHE32 (TARGET_HARD_SH4 || TARGET_SH5)
 
 /* Nonzero if we schedule for a superscalar implementation.  */
-#define TARGET_SUPERSCALAR (target_flags & HARD_SH4_BIT)
+#define TARGET_SUPERSCALAR TARGET_HARD_SH4
 
 /* Nonzero if the target has separate instruction and data caches.  */
-#define TARGET_HARVARD (target_flags & HARD_SH4_BIT)
-
-/* Nonzero if compiling for SH4 hardware (to be used for insn costs etc.)  */
-#define TARGET_HARD_SH4 (target_flags & HARD_SH4_BIT)
-
-/* Nonzero if the default precision of th FPU is single */
-#define TARGET_FPU_SINGLE (target_flags & FPU_SINGLE_BIT)
+#define TARGET_HARVARD (TARGET_HARD_SH4 || TARGET_SH5)
 
 /* Nonzero if a double-precision FPU is available.  */
-#define TARGET_FPU_DOUBLE ((target_flags & SH4_BIT) || TARGET_SH2A_DOUBLE)
+#define TARGET_FPU_DOUBLE \
+  ((target_flags & MASK_SH4) != 0 || TARGET_SH2A_DOUBLE)
 
 /* Nonzero if an FPU is available.  */
 #define TARGET_FPU_ANY (TARGET_SH2E || TARGET_FPU_DOUBLE)
 
 /* Nonzero if we should generate code using type 4 insns.  */
-#define TARGET_SH4 ((target_flags & SH4_BIT) && (target_flags & SH1_BIT))
+#undef TARGET_SH4
+#define TARGET_SH4 ((target_flags & MASK_SH4) != 0 && TARGET_SH1)
 
 /* Nonzero if we're generating code for the common subset of
    instructions present on both SH4a and SH4al-dsp.  */
-#define TARGET_SH4A_ARCH (target_flags & SH4A_BIT)
+#define TARGET_SH4A_ARCH TARGET_SH4A
 
 /* Nonzero if we're generating code for SH4a, unless the use of the
    FPU is disabled (which makes it compatible with SH4al-dsp).  */
 #define TARGET_SH4A_FP (TARGET_SH4A_ARCH && TARGET_FPU_ANY)
 
-/* Nonzero if we should generate code for a SH5 CPU (either ISA).  */
-#define TARGET_SH5 (target_flags & SH5_BIT)
-
 /* Nonzero if we should generate code using the SHcompact instruction
    set and 32-bit ABI.  */
 #define TARGET_SHCOMPACT (TARGET_SH5 && TARGET_SH1)
@@ -252,55 +206,14 @@ extern int target_flags;
 
 /* Nonzero if we should generate code using the SHmedia ISA and 32-bit
    ABI.  */
-#define TARGET_SHMEDIA32 (TARGET_SH5 && ! TARGET_SH1 \
-                         && (target_flags & SH_E_BIT))
+#define TARGET_SHMEDIA32 (TARGET_SH5 && ! TARGET_SH1 && TARGET_SH_E)
 
 /* Nonzero if we should generate code using the SHmedia ISA and 64-bit
    ABI.  */
-#define TARGET_SHMEDIA64 (TARGET_SH5 && ! TARGET_SH1 \
-                         && ! (target_flags & SH_E_BIT))
+#define TARGET_SHMEDIA64 (TARGET_SH5 && ! TARGET_SH1 && ! TARGET_SH_E)
 
 /* Nonzero if we should generate code using SHmedia FPU instructions.  */
 #define TARGET_SHMEDIA_FPU (TARGET_SHMEDIA && TARGET_FPU_DOUBLE)
-/* Nonzero if we should generate fmovd.  */
-#define TARGET_FMOVD (target_flags & FMOVD_BIT)
-
-/* Nonzero if we respect NANs.  */
-#define TARGET_IEEE (target_flags & IEEE_BIT)
-
-/* Nonzero if we should generate smaller code rather than faster code.  */
-#define TARGET_SMALLCODE   (target_flags & SPACE_BIT)
-
-/* Nonzero to use long jump tables.  */
-#define TARGET_BIGTABLE     (target_flags & BIGTABLE_BIT)
-
-/* Nonzero to generate pseudo-ops needed by the assembler and linker
-   to do function call relaxing.  */
-#define TARGET_RELAX (target_flags & RELAX_BIT)
-
-/* Nonzero if using Renesas's calling convention.  */
-#define TARGET_HITACHI                 (target_flags & HITACHI_BIT)
-
-/* Nonzero if not saving macl/mach when using -mhitachi */
-#define TARGET_NOMACSAVE       (target_flags & NOMACSAVE_BIT)
-
-/* Nonzero if padding structures to a multiple of 4 bytes.  This is
-   incompatible with Renesas's compiler, and gives unusual structure layouts
-   which confuse programmers.
-   ??? This option is not useful, but is retained in case there are people
-   who are still relying on it.  It may be deleted in the future.  */
-#define TARGET_PADSTRUCT       (target_flags & PADSTRUCT_BIT)
-
-/* Nonzero if generating code for a little endian SH.  */
-#define TARGET_LITTLE_ENDIAN     (target_flags & LITTLE_ENDIAN_BIT)
-
-/* Nonzero if we should do everything in userland.  */
-#define TARGET_USERMODE                (target_flags & USERMODE_BIT)
-
-/* Nonzero if we should prefer @GOT calls when generating PIC.  */
-#define TARGET_PREFERGOT       (target_flags & PREFERGOT_BIT)
-
-#define TARGET_SAVE_ALL_TARGET_REGS (target_flags & SAVE_ALL_TR_BIT)
 
 /* This is not used by the SH2E calling convention  */
 #define TARGET_VARARGS_PRETEND_ARGS(FUN_DECL) \
@@ -309,289 +222,127 @@ extern int target_flags;
 
 #ifndef TARGET_CPU_DEFAULT
 #define TARGET_CPU_DEFAULT SELECT_SH1
-#define SUPPORT_SH1
-#define SUPPORT_SH2E
-#define SUPPORT_SH4
-#define SUPPORT_SH4_SINGLE
-#define SUPPORT_SH2A
-#define SUPPORT_SH2A_SINGLE
-#endif
-
-#define SELECT_SH1               (SH1_BIT)
-#define SELECT_SH2               (SH2_BIT | SELECT_SH1)
-#define SELECT_SH2E              (SH_E_BIT | SH2_BIT | SH1_BIT | FPU_SINGLE_BIT)
-#define SELECT_SH2A              (SH_E_BIT | HARD_SH2A_BIT | HARD_SH2A_DOUBLE_BIT | SH2_BIT | SH1_BIT)
-#define SELECT_SH2A_NOFPU        (HARD_SH2A_BIT | SH2_BIT | SH1_BIT)
-#define SELECT_SH2A_SINGLE_ONLY  (SH_E_BIT | HARD_SH2A_BIT | SH2_BIT | SH1_BIT | FPU_SINGLE_BIT)
-#define SELECT_SH2A_SINGLE       (SH_E_BIT | HARD_SH2A_BIT | FPU_SINGLE_BIT \
-                                 | HARD_SH2A_DOUBLE_BIT | SH2_BIT | SH1_BIT)
-#define SELECT_SH3               (SH3_BIT | SELECT_SH2)
-#define SELECT_SH3E              (SH_E_BIT | FPU_SINGLE_BIT | SELECT_SH3)
-#define SELECT_SH4_NOFPU         (HARD_SH4_BIT | SELECT_SH3)
-#define SELECT_SH4_SINGLE_ONLY   (HARD_SH4_BIT | SELECT_SH3E)
-#define SELECT_SH4               (SH4_BIT | SH_E_BIT | HARD_SH4_BIT | SELECT_SH3)
-#define SELECT_SH4_SINGLE        (FPU_SINGLE_BIT | SELECT_SH4)
-#define SELECT_SH4A_NOFPU        (SH4A_BIT | SELECT_SH4_NOFPU)
-#define SELECT_SH4A_SINGLE_ONLY  (SH4A_BIT | SELECT_SH4_SINGLE_ONLY)
-#define SELECT_SH4A              (SH4A_BIT | SELECT_SH4)
-#define SELECT_SH4A_SINGLE       (SH4A_BIT | SELECT_SH4_SINGLE)
-#define SELECT_SH5_64MEDIA       (SH5_BIT | SH4_BIT)
-#define SELECT_SH5_64MEDIA_NOFPU (SH5_BIT)
-#define SELECT_SH5_32MEDIA       (SH5_BIT | SH4_BIT | SH_E_BIT)
-#define SELECT_SH5_32MEDIA_NOFPU (SH5_BIT | SH_E_BIT)
-#define SELECT_SH5_COMPACT       (SH5_BIT | SH4_BIT | SELECT_SH3E)
-#define SELECT_SH5_COMPACT_NOFPU (SH5_BIT | SELECT_SH3)
-
-/* Disable processor switches for which we have no suitable multilibs.  */
-#ifndef SUPPORT_SH1
-#define TARGET_SWITCH_SH1
-#ifndef SUPPORT_SH2
-#define TARGET_SWITCH_SH2
-#ifndef SUPPORT_SH3
-#define TARGET_SWITCH_SH3
-#ifndef SUPPORT_SH4_NOFPU
-#define TARGET_SWITCH_SH4_NOFPU
-#endif
-#ifndef SUPPORT_SH4A_NOFPU
-#define TARGET_SWITCH_SH4A_NOFPU
-#endif
-#ifndef SUPPORT_SH4AL
-#define TARGET_SWITCH_SH4AL
-#endif
-#ifndef SUPPORT_SH2A_NOFPU
-#define TARGET_SWITCH_SH2A_NOFPU
-#endif
-#endif
-#endif
+#define SUPPORT_SH1 1
+#define SUPPORT_SH2E 1
+#define SUPPORT_SH4 1
+#define SUPPORT_SH4_SINGLE 1
+#define SUPPORT_SH2A 1
+#define SUPPORT_SH2A_SINGLE 1
 #endif
 
-#ifndef SUPPORT_SH2E
-#define TARGET_SWITCH_SH2E
-#ifndef SUPPORT_SH3E
-#define TARGET_SWITCH_SH3E
-#ifndef SUPPORT_SH4_SINGLE_ONLY
-#define TARGET_SWITCH_SH4_SINGLE_ONLY
+#define TARGET_DIVIDE_INV \
+  (sh_div_strategy == SH_DIV_INV || sh_div_strategy == SH_DIV_INV_MINLAT \
+   || sh_div_strategy == SH_DIV_INV20U || sh_div_strategy == SH_DIV_INV20L \
+   || sh_div_strategy == SH_DIV_INV_CALL \
+   || sh_div_strategy == SH_DIV_INV_CALL2 || sh_div_strategy == SH_DIV_INV_FP)
+#define TARGET_DIVIDE_FP (sh_div_strategy == SH_DIV_FP)
+#define TARGET_DIVIDE_INV_FP (sh_div_strategy == SH_DIV_INV_FP)
+#define TARGET_DIVIDE_CALL2 (sh_div_strategy == SH_DIV_CALL2)
+#define TARGET_DIVIDE_INV_MINLAT (sh_div_strategy == SH_DIV_INV_MINLAT)
+#define TARGET_DIVIDE_INV20U (sh_div_strategy == SH_DIV_INV20U)
+#define TARGET_DIVIDE_INV20L (sh_div_strategy == SH_DIV_INV20L)
+#define TARGET_DIVIDE_INV_CALL (sh_div_strategy == SH_DIV_INV_CALL)
+#define TARGET_DIVIDE_INV_CALL2 (sh_div_strategy == SH_DIV_INV_CALL2)
+#define TARGET_DIVIDE_CALL_DIV1 (sh_div_strategy == SH_DIV_CALL_DIV1)
+#define TARGET_DIVIDE_CALL_FP (sh_div_strategy == SH_DIV_CALL_FP)
+#define TARGET_DIVIDE_CALL_TABLE (sh_div_strategy == SH_DIV_CALL_TABLE)
+
+#define SELECT_SH1               (MASK_SH1)
+#define SELECT_SH2               (MASK_SH2 | SELECT_SH1)
+#define SELECT_SH2E              (MASK_SH_E | MASK_SH2 | MASK_SH1 \
+                                 | MASK_FPU_SINGLE)
+#define SELECT_SH2A              (MASK_SH_E | MASK_HARD_SH2A \
+                                 | MASK_HARD_SH2A_DOUBLE \
+                                 | MASK_SH2 | MASK_SH1)
+#define SELECT_SH2A_NOFPU        (MASK_HARD_SH2A | MASK_SH2 | MASK_SH1)
+#define SELECT_SH2A_SINGLE_ONLY  (MASK_SH_E | MASK_HARD_SH2A | MASK_SH2 \
+                                 | MASK_SH1 | MASK_FPU_SINGLE)
+#define SELECT_SH2A_SINGLE       (MASK_SH_E | MASK_HARD_SH2A \
+                                 | MASK_FPU_SINGLE | MASK_HARD_SH2A_DOUBLE \
+                                 | MASK_SH2 | MASK_SH1)
+#define SELECT_SH3               (MASK_SH3 | SELECT_SH2)
+#define SELECT_SH3E              (MASK_SH_E | MASK_FPU_SINGLE | SELECT_SH3)
+#define SELECT_SH4_NOFPU         (MASK_HARD_SH4 | SELECT_SH3)
+#define SELECT_SH4_SINGLE_ONLY   (MASK_HARD_SH4 | SELECT_SH3E)
+#define SELECT_SH4               (MASK_SH4 | MASK_SH_E | MASK_HARD_SH4 \
+                                 | SELECT_SH3)
+#define SELECT_SH4_SINGLE        (MASK_FPU_SINGLE | SELECT_SH4)
+#define SELECT_SH4A_NOFPU        (MASK_SH4A | SELECT_SH4_NOFPU)
+#define SELECT_SH4A_SINGLE_ONLY  (MASK_SH4A | SELECT_SH4_SINGLE_ONLY)
+#define SELECT_SH4A              (MASK_SH4A | SELECT_SH4)
+#define SELECT_SH4A_SINGLE       (MASK_SH4A | SELECT_SH4_SINGLE)
+#define SELECT_SH5_64MEDIA       (MASK_SH5 | MASK_SH4)
+#define SELECT_SH5_64MEDIA_NOFPU (MASK_SH5)
+#define SELECT_SH5_32MEDIA       (MASK_SH5 | MASK_SH4 | MASK_SH_E)
+#define SELECT_SH5_32MEDIA_NOFPU (MASK_SH5 | MASK_SH_E)
+#define SELECT_SH5_COMPACT       (MASK_SH5 | MASK_SH4 | SELECT_SH3E)
+#define SELECT_SH5_COMPACT_NOFPU (MASK_SH5 | SELECT_SH3)
+
+#if SUPPORT_SH1
+#define SUPPORT_SH2 1
 #endif
-#ifndef SUPPORT_SH4A_SINGLE_ONLY
-#define TARGET_SWITCH_SH4A_SINGLE_ONLY
-#endif
-#ifndef SUPPORT_SH2A_SINGLE_ONLY
-#define TARGET_SWITCH_SH2A_SINGLE_ONLY
+#if SUPPORT_SH2
+#define SUPPORT_SH3 1
+#define SUPPORT_SH2A_NOFPU 1
 #endif
+#if SUPPORT_SH3
+#define SUPPORT_SH4_NOFPU 1
 #endif
+#if SUPPORT_SH4_NOFPU
+#define SUPPORT_SH4A_NOFPU 1
+#define SUPPORT_SH4AL 1
 #endif
 
-#ifndef SUPPORT_SH4
-#define TARGET_SWITCH_SH4
-#ifndef SUPPORT_SH4A
-#define TARGET_SWITCH_SH4A
-#endif
+#if SUPPORT_SH2E
+#define SUPPORT_SH3E 1
+#define SUPPORT_SH2A_SINGLE_ONLY 1
 #endif
-
-#ifndef SUPPORT_SH4_SINGLE
-#define TARGET_SWITCH_SH4_SINGLE
-#ifndef SUPPORT_SH4A_SINGLE
-#define TARGET_SWITCH_SH4A_SINGLE
+#if SUPPORT_SH3E
+#define SUPPORT_SH4_SINGLE_ONLY 1
 #endif
+#if SUPPORT_SH4_SINGLE_ONLY
+#define SUPPORT_SH4A_SINGLE_ONLY 1
 #endif
 
-#ifndef SUPPORT_SH2A
-#define TARGET_SWITCH_SH2A
+#if SUPPORT_SH4
+#define SUPPORT_SH4A 1
 #endif
 
-#ifndef SUPPORT_SH2A_SINGLE
-#define TARGET_SWITCH_SH2A_SINGLE
+#if SUPPORT_SH4_SINGLE
+#define SUPPORT_SH4A_SINGLE 1
 #endif
 
-#ifndef SUPPORT_SH5_64MEDIA
-#define TARGET_SWITCH_SH5_64MEDIA
+#if SUPPORT_SH5_COMPAT
+#define SUPPORT_SH5_32MEDIA 1
 #endif
 
-#ifndef SUPPORT_SH5_64MEDIA_NOFPU
-#define TARGET_SWITCH_SH5_64MEDIA_NOFPU
+#if SUPPORT_SH5_COMPACT_NOFPU
+#define SUPPORT_SH5_32MEDIA_NOFPU 1
 #endif
 
-#if !defined(SUPPORT_SH5_32MEDIA) && !defined (SUPPORT_SH5_COMPACT)
-#define TARGET_SWITCHES_SH5_32MEDIA
-#endif
-
-#if !defined(SUPPORT_SH5_32MEDIA_NOFPU) && !defined (SUPPORT_SH5_COMPACT_NOFPU)
-#define TARGET_SWITCHES_SH5_32MEDIA_NOFPU
-#endif
+#define SUPPORT_ANY_SH5_32MEDIA \
+  (SUPPORT_SH5_32MEDIA || SUPPORT_SH5_32MEDIA_NOFPU)
+#define SUPPORT_ANY_SH5_64MEDIA \
+  (SUPPORT_SH5_64MEDIA || SUPPORT_SH5_64MEDIA_NOFPU)
+#define SUPPORT_ANY_SH5 \
+  (SUPPORT_ANY_SH5_32MEDIA || SUPPORT_ANY_SH5_64MEDIA)
 
 /* Reset all target-selection flags.  */
-#define TARGET_NONE -(SH1_BIT | SH2_BIT | SH3_BIT | SH_E_BIT | SH4_BIT \
-                     | HARD_SH2A_BIT | HARD_SH2A_DOUBLE_BIT \
-                     | SH4A_BIT | HARD_SH4_BIT | FPU_SINGLE_BIT | SH5_BIT)
-
-#ifndef TARGET_SWITCH_SH1
-#define TARGET_SWITCH_SH1 \
-  {"1",                TARGET_NONE, "" }, \
-  {"1",                SELECT_SH1, "Generate SH1 code" },
-#endif
-#ifndef TARGET_SWITCH_SH2
-#define TARGET_SWITCH_SH2 \
-  {"2",                TARGET_NONE, "" }, \
-  {"2",                SELECT_SH2, "Generate SH2 code" },
-#endif
-#ifndef TARGET_SWITCH_SH2E
-#define TARGET_SWITCH_SH2E \
-  {"2e",       TARGET_NONE, "" }, \
-  {"2e",       SELECT_SH2E, "Generate SH2e code" },
-#endif
-#ifndef TARGET_SWITCH_SH2A
-#define TARGET_SWITCH_SH2A \
-  {"2a",       TARGET_NONE, "" }, \
-  {"2a",       SELECT_SH2A, "Generate SH2a code" },
-#endif
-#ifndef TARGET_SWITCH_SH2A_SINGLE_ONLY
-#define TARGET_SWITCH_SH2A_SINGLE_ONLY \
-  {"2a-single-only", TARGET_NONE, "" },        \
-  {"2a-single-only", SELECT_SH2A_SINGLE_ONLY, "Generate only single-precision SH2a code" },
-#endif
-#ifndef TARGET_SWITCH_SH2A_SINGLE
-#define TARGET_SWITCH_SH2A_SINGLE \
-  {"2a-single", TARGET_NONE, "" },     \
-  {"2a-single", SELECT_SH2A_SINGLE, "Generate default single-precision SH2a code" },
-#endif
-#ifndef TARGET_SWITCH_SH2A_NOFPU
-#define TARGET_SWITCH_SH2A_NOFPU \
-  {"2a-nofpu",  TARGET_NONE, "" },     \
-  {"2a-nofpu",  SELECT_SH2A_NOFPU, "Generate SH2a FPU-less code" },
-#endif
-#ifndef TARGET_SWITCH_SH3
-#define TARGET_SWITCH_SH3 \
-  {"3",                TARGET_NONE, "" }, \
-  {"3",                SELECT_SH3, "Generate SH3 code" },
-#endif
-#ifndef TARGET_SWITCH_SH3E
-#define TARGET_SWITCH_SH3E \
-  {"3e",       TARGET_NONE, "" }, \
-  {"3e",       SELECT_SH3E, "Generate SH3e code" },
-#endif
-#ifndef TARGET_SWITCH_SH4_SINGLE_ONLY
-#define TARGET_SWITCH_SH4_SINGLE_ONLY \
-  {"4-single-only",    TARGET_NONE, "" }, \
-  {"4-single-only",    SELECT_SH4_SINGLE_ONLY, "Generate only single-precision SH4 code" },
-#endif
-#ifndef TARGET_SWITCH_SH4_SINGLE
-#define TARGET_SWITCH_SH4_SINGLE \
-  {"4-single", TARGET_NONE, "" }, \
-  {"4-single", SELECT_SH4_SINGLE, "Generate default single-precision SH4 code" },
-#endif
-#ifndef TARGET_SWITCH_SH4_NOFPU
-#define TARGET_SWITCH_SH4_NOFPU \
-  {"4-nofpu",  TARGET_NONE, "" }, \
-  {"4-nofpu",  SELECT_SH4_NOFPU, "Generate SH4 FPU-less code" },
-#endif
-#ifndef TARGET_SWITCH_SH4
-#define TARGET_SWITCH_SH4 \
-  {"4",                TARGET_NONE, "" }, \
-  {"4",                SELECT_SH4, "Generate SH4 code" },
-#endif
-#ifndef TARGET_SWITCH_SH4A
-#define TARGET_SWITCH_SH4A \
-  {"4a",       TARGET_NONE, "" }, \
-  {"4a",       SELECT_SH4A, "Generate SH4a code" },
-#endif
-#ifndef TARGET_SWITCH_SH4A_SINGLE_ONLY
-#define TARGET_SWITCH_SH4A_SINGLE_ONLY \
-  {"4a-single-only",   TARGET_NONE, "" },      \
-  {"4a-single-only",   SELECT_SH4A_SINGLE_ONLY, "Generate only single-precision SH4a code" },
-#endif
-#ifndef TARGET_SWITCH_SH4A_SINGLE
-#define TARGET_SWITCH_SH4A_SINGLE \
-  {"4a-single",        TARGET_NONE, "" },\
-  {"4a-single",        SELECT_SH4A_SINGLE, "Generate default single-precision SH4a code" },
-#endif
-#ifndef TARGET_SWITCH_SH4A_NOFPU
-#define TARGET_SWITCH_SH4A_NOFPU \
-  {"4a-nofpu", TARGET_NONE, "" },\
-  {"4a-nofpu", SELECT_SH4A_NOFPU, "Generate SH4a FPU-less code" },
-#endif
-#ifndef TARGET_SWITCH_SH4AL
-#define TARGET_SWITCH_SH4AL \
-  {"4al",      TARGET_NONE, "" },\
-  {"4al",      SELECT_SH4A_NOFPU, "Generate SH4al-dsp code" },
-#endif
-#ifndef TARGET_SWITCH_SH5_64MEDIA
-#define TARGET_SWITCH_SH5_64MEDIA \
-  {"5-64media",        TARGET_NONE, "" },              \
-  {"5-64media", SELECT_SH5_64MEDIA, "Generate 64-bit SHmedia code" },
-#endif
-#ifndef TARGET_SWITCH_SH5_64MEDIA_NOFPU
-#define TARGET_SWITCH_SH5_64MEDIA_NOFPU \
-  {"5-64media-nofpu", TARGET_NONE, "" },       \
-  {"5-64media-nofpu", SELECT_SH5_64MEDIA_NOFPU, "Generate 64-bit FPU-less SHmedia code" },
-#endif
-#ifndef TARGET_SWITCHES_SH5_32MEDIA
-#define TARGET_SWITCHES_SH5_32MEDIA \
-  {"5-32media",        TARGET_NONE, "" },              \
-  {"5-32media", SELECT_SH5_32MEDIA, "Generate 32-bit SHmedia code" }, \
-  {"5-compact",        TARGET_NONE, "" },              \
-  {"5-compact",        SELECT_SH5_COMPACT, "Generate SHcompact code" },
-#endif
-#ifndef TARGET_SWITCHES_SH5_32MEDIA_NOFPU
-#define TARGET_SWITCHES_SH5_32MEDIA_NOFPU \
-  {"5-32media-nofpu", TARGET_NONE, "" },       \
-  {"5-32media-nofpu", SELECT_SH5_32MEDIA_NOFPU, "Generate 32-bit FPU-less SHmedia code" }, \
-  {"5-compact-nofpu", TARGET_NONE, "" },       \
-  {"5-compact-nofpu", SELECT_SH5_COMPACT_NOFPU, "Generate FPU-less SHcompact code" },
-#endif
-
-#define TARGET_SWITCHES \
-{ TARGET_SWITCH_SH1 \
-  TARGET_SWITCH_SH2 \
-  TARGET_SWITCH_SH2A_SINGLE_ONLY \
-  TARGET_SWITCH_SH2A_SINGLE \
-  TARGET_SWITCH_SH2A_NOFPU \
-  TARGET_SWITCH_SH2A \
-  TARGET_SWITCH_SH2E \
-  TARGET_SWITCH_SH3 \
-  TARGET_SWITCH_SH3E \
-  TARGET_SWITCH_SH4_SINGLE_ONLY \
-  TARGET_SWITCH_SH4_SINGLE \
-  TARGET_SWITCH_SH4_NOFPU \
-  TARGET_SWITCH_SH4 \
-  TARGET_SWITCH_SH4A_SINGLE_ONLY \
-  TARGET_SWITCH_SH4A_SINGLE \
-  TARGET_SWITCH_SH4A_NOFPU \
-  TARGET_SWITCH_SH4A \
-  TARGET_SWITCH_SH4AL \
-  TARGET_SWITCH_SH5_64MEDIA \
-  TARGET_SWITCH_SH5_64MEDIA_NOFPU \
-  TARGET_SWITCHES_SH5_32MEDIA \
-  TARGET_SWITCHES_SH5_32MEDIA_NOFPU \
-  {"b",                -LITTLE_ENDIAN_BIT, "Generate code in big endian mode" },       \
-  {"bigtable",         BIGTABLE_BIT, "Generate 32-bit offsets in switch tables" },             \
-  {"dalign",   DALIGN_BIT, "Aligns doubles at 64-bit boundaries" },            \
-  {"fmovd",    FMOVD_BIT, "" },                \
-  {"hitachi",  HITACHI_BIT, "Follow Renesas (formerly Hitachi) / SuperH calling conventions" },                \
-  {"renesas",  HITACHI_BIT, "Follow Renesas (formerly Hitachi) / SuperH calling conventions" },                \
-  {"no-renesas",-HITACHI_BIT,"Follow the GCC calling conventions" },   \
-  {"nomacsave", NOMACSAVE_BIT, "Mark MAC register as call-clobbered" },                \
-  {"ieee",     IEEE_BIT, "Increase the IEEE compliance for floating-point code" },                     \
-  {"isize",    ISIZE_BIT, "" },                \
-  {"l",                LITTLE_ENDIAN_BIT, "Generate code in little endian mode" },     \
-  {"no-ieee",          -IEEE_BIT, "" },                \
-  {"padstruct", PADSTRUCT_BIT, "" },           \
-  {"prefergot",        PREFERGOT_BIT, "Emit function-calls using global offset table when generating PIC" },           \
-  {"relax",    RELAX_BIT, "Shorten address references during linking" },               \
-  {"space",    SPACE_BIT, "Deprecated. Use -Os instead" },             \
-  {"usermode", USERMODE_BIT, "Generate library function call to invalidate instruction cache entries after fixing trampoline" },               \
-  SUBTARGET_SWITCHES                            \
-  {"",         TARGET_DEFAULT, "" }            \
-}
-
-/* This are meant to be redefined in the host dependent files */
-#define SUBTARGET_SWITCHES
+#define MASK_ARCH (MASK_SH1 | MASK_SH2 | MASK_SH3 | MASK_SH_E | MASK_SH4 \
+                  | MASK_HARD_SH2A | MASK_HARD_SH2A_DOUBLE | MASK_SH4A \
+                  | MASK_HARD_SH4 | MASK_FPU_SINGLE | MASK_SH5)
 
 /* This defaults us to big-endian.  */
 #ifndef TARGET_ENDIAN_DEFAULT
 #define TARGET_ENDIAN_DEFAULT 0
 #endif
 
-#define TARGET_DEFAULT  (TARGET_CPU_DEFAULT|TARGET_ENDIAN_DEFAULT)
+#ifndef TARGET_OPT_DEFAULT
+#define TARGET_OPT_DEFAULT  MASK_ADJUST_UNROLL
+#endif
+
+#define TARGET_DEFAULT \
+  (TARGET_CPU_DEFAULT | TARGET_ENDIAN_DEFAULT | TARGET_OPT_DEFAULT)
 
 #ifndef SH_MULTILIB_CPU_DEFAULT
 #define SH_MULTILIB_CPU_DEFAULT "m1"
@@ -621,51 +372,80 @@ extern int target_flags;
   { "subtarget_link_spec", SUBTARGET_LINK_SPEC },              \
   { "subtarget_asm_endian_spec", SUBTARGET_ASM_ENDIAN_SPEC },  \
   { "subtarget_asm_relax_spec", SUBTARGET_ASM_RELAX_SPEC },    \
-  { "subtarget_asm_isa_spec", SUBTARGET_ASM_ISA_SPEC },        \
+  { "subtarget_asm_isa_spec", SUBTARGET_ASM_ISA_SPEC },                \
+  { "subtarget_asm_spec", SUBTARGET_ASM_SPEC },                        \
   SUBTARGET_EXTRA_SPECS
 
-#if TARGET_CPU_DEFAULT & HARD_SH4_BIT
-#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*:%{!m5*:-isa=sh4}}}}"
+#if TARGET_CPU_DEFAULT & MASK_HARD_SH4
+#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*:%{!m5*:-isa=sh4-up}}}}"
 #else
-#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4}"
+#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4-up}"
 #endif
 
 #define SH_ASM_SPEC \
  "%(subtarget_asm_endian_spec) %{mrelax:-relax %(subtarget_asm_relax_spec)}\
-%(subtarget_asm_isa_spec) %{m4al:-dsp}"
+%(subtarget_asm_isa_spec) %(subtarget_asm_spec)\
+%{m2a:--isa=sh2a} \
+%{m2a-single:--isa=sh2a} \
+%{m2a-single-only:--isa=sh2a} \
+%{m2a-nofpu:--isa=sh2a-nofpu} \
+%{m5-compact*:--isa=SHcompact} \
+%{m5-32media*:--isa=SHmedia --abi=32} \
+%{m5-64media*:--isa=SHmedia --abi=64} \
+%{m4al:-dsp} %{mcut2-workaround:-cut2-workaround}"
 
 #define ASM_SPEC SH_ASM_SPEC
 
 #ifndef SUBTARGET_ASM_ENDIAN_SPEC
-#if TARGET_ENDIAN_DEFAULT == LITTLE_ENDIAN_BIT
+#if TARGET_ENDIAN_DEFAULT == MASK_LITTLE_ENDIAN
 #define SUBTARGET_ASM_ENDIAN_SPEC "%{mb:-big} %{!mb:-little}"
 #else
 #define SUBTARGET_ASM_ENDIAN_SPEC "%{ml:-little} %{!ml:-big}"
 #endif
 #endif
 
-#define SUBTARGET_ASM_ISA_SPEC ""
+#if STRICT_NOFPU == 1
+/* Strict nofpu means that the compiler should tell the assembler
+   to reject FPU instructions. E.g. from ASM inserts.  */
+#if TARGET_CPU_DEFAULT & MASK_HARD_SH4 && !(TARGET_CPU_DEFAULT & MASK_SH_E)
+#define SUBTARGET_ASM_ISA_SPEC "%{!m1:%{!m2:%{!m3*:%{m4-nofpu|!m4*:%{!m5:-isa=sh4-nofpu}}}}}"
+#else
+/* If there were an -isa option for sh5-nofpu then it would also go here. */
+#define SUBTARGET_ASM_ISA_SPEC \
+ "%{m4-nofpu:-isa=sh4-nofpu} " ASM_ISA_DEFAULT_SPEC
+#endif
+#else /* ! STRICT_NOFPU */
+#define SUBTARGET_ASM_ISA_SPEC ASM_ISA_DEFAULT_SPEC
+#endif
+
+#ifndef SUBTARGET_ASM_SPEC
+#define SUBTARGET_ASM_SPEC ""
+#endif
 
+#if TARGET_ENDIAN_DEFAULT == MASK_LITTLE_ENDIAN
+#define LINK_EMUL_PREFIX "sh%{!mb:l}"
+#else
 #define LINK_EMUL_PREFIX "sh%{ml:l}"
+#endif
 
-#if TARGET_CPU_DEFAULT & SH5_BIT
-#if TARGET_CPU_DEFAULT & SH_E_BIT
+#if TARGET_CPU_DEFAULT & MASK_SH5
+#if TARGET_CPU_DEFAULT & MASK_SH_E
 #define LINK_DEFAULT_CPU_EMUL "32"
-#if TARGET_CPU_DEFAULT & SH1_BIT
+#if TARGET_CPU_DEFAULT & MASK_SH1
 #define ASM_ISA_SPEC_DEFAULT "--isa=SHcompact"
 #else
 #define ASM_ISA_SPEC_DEFAULT "--isa=SHmedia --abi=32"
-#endif /* SH1_BIT */
-#else /* !SH_E_BIT */
+#endif /* MASK_SH1 */
+#else /* !MASK_SH_E */
 #define LINK_DEFAULT_CPU_EMUL "64"
 #define ASM_ISA_SPEC_DEFAULT "--isa=SHmedia --abi=64"
-#endif /* SH_E_BIT */
+#endif /* MASK_SH_E */
 #define ASM_ISA_DEFAULT_SPEC \
 " %{!m1:%{!m2*:%{!m3*:%{!m4*:%{!m5*:" ASM_ISA_SPEC_DEFAULT "}}}}}"
-#else /* !SH5_BIT */
+#else /* !MASK_SH5 */
 #define LINK_DEFAULT_CPU_EMUL ""
 #define ASM_ISA_DEFAULT_SPEC ""
-#endif /* SH5_BIT */
+#endif /* MASK_SH5 */
 
 #define SUBTARGET_LINK_EMUL_SUFFIX ""
 #define SUBTARGET_LINK_SPEC ""
@@ -682,151 +462,45 @@ extern int target_flags;
 %(subtarget_link_emul_suffix) \
 %{mrelax:-relax} %(subtarget_link_spec)"
 
+#ifndef SH_DIV_STR_FOR_SIZE
+#define SH_DIV_STR_FOR_SIZE "call"
+#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 = -1;                                      \
-  if (SIZE)                                                            \
-    target_flags |= SPACE_BIT;                                         \
-  if (TARGET_SHMEDIA && LEVEL > 1)                                     \
-    {                                                                  \
-      flag_branch_target_load_optimize = 1;                            \
-      if (! (SIZE))                                                    \
-       target_flags |= SAVE_ALL_TR_BIT;                                \
-    }                                                                  \
-} while (0)
 
 #define ASSEMBLER_DIALECT assembler_dialect
 
 extern int assembler_dialect;
 
-#define OVERRIDE_OPTIONS                                               \
-do {                                                                   \
-  int regno;                                                           \
-                                                                       \
-  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 |= FMOVD_BIT;                                     \
-    }                                                                  \
-  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 |= DALIGN_BIT;                                      \
-      if (TARGET_FPU_ANY                                               \
-         && ! (TARGET_SHCOMPACT && TARGET_LITTLE_ENDIAN))              \
-       target_flags |= FMOVD_BIT;                                      \
-      if (TARGET_SHMEDIA)                                              \
-       {                                                               \
-         /* There are no delay slots on SHmedia.  */                   \
-         flag_delayed_branch = 0;                                      \
-         /* Relaxation isn't yet supported for SHmedia */              \
-         target_flags &= ~RELAX_BIT;                                   \
-       }                                                               \
-      /* -fprofile-arcs needs a working libgcov .  In unified tree     \
-        configurations with newlib, this requires to configure with    \
-        --with-newlib --with-headers.  But there is no way to check    \
-        here we have a working libgcov, so just assume that we have.  */\
-      if (profile_flag)                                                        \
-       {                                                               \
-         warning ("Profiling is not supported on this target.");       \
-         profile_flag = profile_arc_flag = 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_FMOVD)                                                    \
-    reg_class_from_letter['e' - 'a'] = NO_REGS;                                \
-                                                                       \
-  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 < 0)                                     \
-   {                                                                   \
-     /* 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)                                  \
-    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 \
-        SH3 and lower as they give spill failures for R0.  */          \
-      if (!TARGET_HARD_SH4)                                            \
-        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;                                    \
-    }                                                                  \
-} while (0)
+enum sh_divide_strategy_e {
+  /* SH5 strategies.  */
+  SH_DIV_CALL,
+  SH_DIV_CALL2,
+  SH_DIV_FP, /* We could do this also for SH4.  */
+  SH_DIV_INV,
+  SH_DIV_INV_MINLAT,
+  SH_DIV_INV20U,
+  SH_DIV_INV20L,
+  SH_DIV_INV_CALL,
+  SH_DIV_INV_CALL2,
+  SH_DIV_INV_FP,
+  /* SH1 .. SH4 strategies.  Because of the small number of registers
+     available, the compiler uses knowledge of the actual set of registers
+     being clobbered by the different functions called.  */
+  SH_DIV_CALL_DIV1, /* No FPU, medium size, highest latency.  */
+  SH_DIV_CALL_FP,     /* FPU needed, small size, high latency.  */
+  SH_DIV_CALL_TABLE,  /* No FPU, large size, medium latency. */
+  SH_DIV_INTRINSIC
+};
+
+extern enum sh_divide_strategy_e sh_div_strategy;
+
+#ifndef SH_DIV_STRATEGY_DEFAULT
+#define SH_DIV_STRATEGY_DEFAULT SH_DIV_CALL
+#endif
+
+#define SUBTARGET_OVERRIDE_OPTIONS (void) 0
+
 \f
 /* Target machine storage layout.  */
 
@@ -842,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
@@ -925,7 +591,7 @@ do {                                                                        \
   ((GET_MODE_CLASS (TYPE_MODE (TYPE)) == MODE_COMPLEX_INT \
     || GET_MODE_CLASS (TYPE_MODE (TYPE)) == MODE_COMPLEX_FLOAT) \
    ? (unsigned) MIN (BIGGEST_ALIGNMENT, GET_MODE_BITSIZE (TYPE_MODE (TYPE))) \
-   : (unsigned) ALIGN)
+   : (unsigned) DATA_ALIGNMENT(TYPE, ALIGN))
 
 /* Make arrays of chars word-aligned for the same reasons.  */
 #define DATA_ALIGNMENT(TYPE, ALIGN)            \
@@ -947,13 +613,13 @@ do {                                                                      \
   barrier_align (LABEL_AFTER_BARRIER)
 
 #define LOOP_ALIGN(A_LABEL) \
-  ((! optimize || TARGET_HARVARD || 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.  */                  \
@@ -965,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
@@ -1017,7 +683,7 @@ extern char sh_register_names[][MAX_REGISTER_NAME_LENGTH + 1];
   "tr0",  "tr1",  "tr2",  "tr3",  "tr4",  "tr5",  "tr6",  "tr7",       \
   "xd0",  "xd2",  "xd4",  "xd6",  "xd8",  "xd10", "xd12", "xd14",      \
   "gbr",  "ap",          "pr",   "t",    "mach", "macl", "fpul", "fpscr",      \
-  "rap"                                                                        \
+  "rap",  "sfp"                                                                \
 }
 
 #define REGNAMES_ARR_INDEX_1(index) \
@@ -1042,7 +708,7 @@ extern char sh_register_names[][MAX_REGISTER_NAME_LENGTH + 1];
   REGNAMES_ARR_INDEX_8 (128), \
   REGNAMES_ARR_INDEX_8 (136), \
   REGNAMES_ARR_INDEX_8 (144), \
-  REGNAMES_ARR_INDEX_1 (152) \
+  REGNAMES_ARR_INDEX_2 (152) \
 }
 
 #define ADDREGNAMES_SIZE 32
@@ -1098,13 +764,24 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 #define FIRST_TARGET_REG TR0_REG
 #define LAST_TARGET_REG  (FIRST_TARGET_REG + (TARGET_SHMEDIA ? 7 : -1))
 
+/* Registers that can be accessed through bank0 or bank1 depending on sr.md.  */
+
+#define FIRST_BANKED_REG R0_REG
+#define LAST_BANKED_REG R7_REG
+
+#define BANKED_REGISTER_P(REGNO)                       \
+  IN_RANGE ((REGNO),                                   \
+           (unsigned HOST_WIDE_INT) FIRST_BANKED_REG, \
+           (unsigned HOST_WIDE_INT) LAST_BANKED_REG)
+
 #define GENERAL_REGISTER_P(REGNO) \
   IN_RANGE ((REGNO), \
            (unsigned HOST_WIDE_INT) FIRST_GENERAL_REG, \
            (unsigned HOST_WIDE_INT) LAST_GENERAL_REG)
 
 #define GENERAL_OR_AP_REGISTER_P(REGNO) \
-  (GENERAL_REGISTER_P (REGNO) || ((REGNO) == AP_REG))
+  (GENERAL_REGISTER_P (REGNO) || ((REGNO) == AP_REG)   \
+   || ((REGNO) == FRAME_POINTER_REGNUM))
 
 #define FP_REGISTER_P(REGNO) \
   ((int) (REGNO) >= FIRST_FP_REG && (int) (REGNO) <= LAST_FP_REG)
@@ -1134,6 +811,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 #define VALID_REGISTER_P(REGNO) \
   (SHMEDIA_REGISTER_P (REGNO) || XD_REGISTER_P (REGNO) \
    || (REGNO) == AP_REG || (REGNO) == RAP_REG \
+   || (REGNO) == FRAME_POINTER_REGNUM \
    || (TARGET_SH1 && (SPECIAL_REGISTER_P (REGNO) || (REGNO) == PR_REG)) \
    || (TARGET_SH2E && (REGNO) == FPUL_REG))
 
@@ -1146,7 +824,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
    ? DImode \
    : SImode)
 
-#define FIRST_PSEUDO_REGISTER 153
+#define FIRST_PSEUDO_REGISTER 154
+
+/* Don't count soft frame pointer.  */
+#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER - 1)
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
@@ -1183,8 +864,8 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
   0,      0,      0,      0,      0,      0,      0,      0,           \
 /*"gbr",  "ap",          "pr",   "t",    "mach", "macl", "fpul", "fpscr", */   \
   1,      1,      1,      1,      1,      1,      0,      1,           \
-/*"rap" */                                                             \
-  1,                                                                   \
+/*"rap",  "sfp" */                                                     \
+  1,     1,                                                            \
 }
 
 /* 1 for registers not available across function calls.
@@ -1223,8 +904,8 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
   1,      1,      1,      1,      1,      1,      0,      0,           \
 /*"gbr",  "ap",          "pr",   "t",    "mach", "macl", "fpul", "fpscr", */   \
   1,      1,      1,      1,      1,      1,      1,      1,           \
-/*"rap" */                                                             \
-  1,                                                                   \
+/*"rap",  "sfp" */                                                     \
+  1,     1,                                                            \
 }
 
 /* CONDITIONAL_REGISTER_USAGE might want to make a register call-used, yet
@@ -1258,49 +939,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
     ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD/2 - 1) / (UNITS_PER_WORD/2)) \
     : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   We can allow any mode in any general register.  The special registers
-   only allow SImode.  Don't allow any mode in the PR.  */
-
-/* We cannot hold DCmode values in the XD registers because alter_reg
-   handles subregs of them incorrectly.  We could work around this by
-   spacing the XD registers like the DR registers, but this would require
-   additional memory in every compilation to hold larger register vectors.
-   We could hold SFmode / SCmode values in XD registers, but that
-   would require a tertiary reload when reloading from / to memory,
-   and a secondary reload to reload from / to general regs; that
-   seems to be a loosing proposition.  */
-/* We want to allow TImode FP regs so that when V4SFmode is loaded as TImode,
-   it won't be ferried through GP registers first.  */
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.  */
+
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                \
-  (SPECIAL_REGISTER_P (REGNO) ? (MODE) == SImode \
-   : (REGNO) == FPUL_REG ? (MODE) == SImode || (MODE) == SFmode        \
-   : FP_REGISTER_P (REGNO) && (MODE) == SFmode \
-   ? 1 \
-   : (MODE) == V2SFmode \
-   ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
-      || GENERAL_REGISTER_P (REGNO)) \
-   : (MODE) == V4SFmode \
-   ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
-      || (! TARGET_SHMEDIA && GENERAL_REGISTER_P (REGNO))) \
-   : (MODE) == V16SFmode \
-   ? (TARGET_SHMEDIA \
-      ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 16 == 0) \
-      : (REGNO) == FIRST_XD_REG) \
-   : FP_REGISTER_P (REGNO) \
-   ? ((MODE) == SFmode || (MODE) == SImode \
-      || ((TARGET_SH2E || TARGET_SHMEDIA) && (MODE) == SCmode) \
-      || ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) || (MODE) == DCmode \
-          || (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
-                                 || (MODE) == V2SFmode || (MODE) == TImode))) \
-         && (((REGNO) - FIRST_FP_REG) & 1) == 0)) \
-   : XD_REGISTER_P (REGNO) \
-   ? (MODE) == DFmode \
-   : TARGET_REGISTER_P (REGNO) \
-   ? ((MODE) == DImode || (MODE) == SImode) \
-   : (REGNO) == PR_REG ? (MODE) == SImode \
-   : (REGNO) == FPSCR_REG ? (MODE) == PSImode \
-   : 1)
+  sh_hard_regno_mode_ok ((REGNO), (MODE))
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
@@ -1312,6 +954,9 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 
 #define MODES_TIEABLE_P(MODE1, MODE2) \
   ((MODE1) == (MODE2) \
+   || (TARGET_SHMEDIA \
+       && GET_MODE_SIZE (MODE1) == GET_MODE_SIZE (MODE2) \
+       && INTEGRAL_MODE_P (MODE1) && INTEGRAL_MODE_P (MODE2)) \
    || (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \
        && (TARGET_SHMEDIA ? ((GET_MODE_SIZE (MODE1) <= 4) \
                              && (GET_MODE_SIZE (MODE2) <= 4)) \
@@ -1333,7 +978,10 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 #define STACK_POINTER_REGNUM   SP_REG
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM   FP_REG
+#define HARD_FRAME_POINTER_REGNUM      FP_REG
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM   153
 
 /* Fake register that holds the address on the stack of the
    current function's return address.  */
@@ -1345,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
@@ -1375,16 +1017,13 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
    of elimination fail.  */
 
 #define ELIMINABLE_REGS                                                \
-{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                        \
+{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},           \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                        \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},           \
  { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},       \
- { RETURN_ADDRESS_POINTER_REGNUM, FRAME_POINTER_REGNUM},       \
+ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},  \
  { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},                  \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},}
-
-/* Given FROM and TO register numbers, say whether this elimination
-   is allowed.  */
-#define CAN_ELIMINATE(FROM, TO) \
-  (!((FROM) == FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED))
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},}
 
 /* Define the offset between two registers, one to be eliminated, and the other
    its replacement, at the start of a routine.  */
@@ -1405,7 +1044,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
 #define SHMEDIA_REGS_STACK_ADJUST() \
-  (TARGET_SHCOMPACT && current_function_has_nonlocal_label \
+  (TARGET_SHCOMPACT && crtl->saves_all_registers \
    ? (8 * (/* r28-r35 */ 8 + /* r44-r59 */ 16 + /* tr5-tr7 */ 3) \
       + (TARGET_FPU_ANY ? 4 * (/* fr36 - fr63 */ 28) : 0)) \
    : 0)
@@ -1460,6 +1099,7 @@ enum reg_class
   DF_REGS,
   FPSCR_REGS,
   GENERAL_FP_REGS,
+  GENERAL_DF_REGS,
   TARGET_REGS,
   ALL_REGS,
   LIM_REG_CLASSES
@@ -1484,6 +1124,7 @@ enum reg_class
   "DF_REGS",           \
   "FPSCR_REGS",                \
   "GENERAL_FP_REGS",   \
+  "GENERAL_DF_REGS",   \
   "TARGET_REGS",       \
   "ALL_REGS",          \
 }
@@ -1505,11 +1146,11 @@ enum reg_class
 /* MAC_REGS:  */                                                       \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00300000 },      \
 /* FPUL_REGS:  */                                                      \
-  { 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00400000 },      \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00400000 },      \
 /* SIBCALL_REGS: Initialized in CONDITIONAL_REGISTER_USAGE.  */        \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },      \
 /* GENERAL_REGS:  */                                                   \
-  { 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x01020000 },      \
+  { 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x03020000 },      \
 /* FP0_REGS:  */                                                       \
   { 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000 },      \
 /* FP_REGS:  */                                                                \
@@ -1521,11 +1162,13 @@ enum reg_class
 /* FPSCR_REGS:  */                                                     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800000 },      \
 /* GENERAL_FP_REGS:  */                                                        \
-  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0102ff00 },      \
+  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03020000 },      \
+/* GENERAL_DF_REGS:  */                                                        \
+  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0302ff00 },      \
 /* TARGET_REGS:  */                                                    \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff },      \
 /* ALL_REGS:  */                                                       \
-  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff },      \
+  { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ffffff },      \
 }
 
 /* The same information, inverted:
@@ -1536,11 +1179,26 @@ enum reg_class
 extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 #define REGNO_REG_CLASS(REGNO) regno_reg_class[(REGNO)]
 
-/* 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.  */
+/* The following macro defines cover classes for Integrated Register
+   Allocator.  Cover classes is a set of non-intersected register
+   classes covering all hard registers used for register allocation
+   purpose.  Any move between two registers of a cover class should be
+   cheaper than load or store of the registers.  The macro value is
+   array of register classes with LIM_REG_CLASSES used as the end
+   marker.  */
+
+#define IRA_COVER_CLASSES                                                   \
+{                                                                           \
+  GENERAL_REGS, FP_REGS, PR_REGS, T_REGS, MAC_REGS, TARGET_REGS,            \
+  FPUL_REGS, LIM_REG_CLASSES                                                \
+}
 
-#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,
@@ -1575,89 +1233,14 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
    128,129,130,131,132,133,134,135, \
    /* Fixed registers */ \
     15, 16, 24, 25, 26, 27, 63,144, \
-   145,146,147,148,149,152 }
+   145,146,147,148,149,152,153 }
 
 /* The class value for index registers, and the one for base regs.  */
-#define INDEX_REG_CLASS  (TARGET_SHMEDIA ? GENERAL_REGS : R0_REGS)
+#define INDEX_REG_CLASS \
+  (!ALLOW_INDEXED_ADDRESS ? NO_REGS : TARGET_SHMEDIA ? GENERAL_REGS : R0_REGS)
 #define BASE_REG_CLASS  GENERAL_REGS
-
-/* Get reg_class from a letter such as appears in the machine
-   description.  */
-extern enum reg_class reg_class_from_letter[];
-
-/* We might use 'Rxx' constraints in the future for exotic reg classes.*/
-#define REG_CLASS_FROM_CONSTRAINT(C, STR) \
-  (ISLOWER (C) ? reg_class_from_letter[(C)-'a'] : NO_REGS )
 \f
-/* Overview of uppercase letter constraints:
-   A: Addresses (constraint len == 3)
-    Ac4: sh4 cache operations
-    Ac5: sh5 cache operations
-   Bxx: miscellaneous constraints
-    Bsc: SCRATCH - for the scratch register in movsi_ie in the
-        fldi0 / fldi0 cases
-   C: Constants other than only CONST_INT (constraint len == 3)
-    C16: 16 bit constant, literal or symbolic
-    Csy: label or symbol
-    Cpg: non-explicit constants that can be directly loaded into a general
-        purpose register in PIC code.  like 's' except we don't allow
-        PIC_DIRECT_ADDR_P
-   IJKLMNOP: CONT_INT constants
-    Ixx: signed xx bit
-    J16: 0xffffffff00000000 | 0x00000000ffffffff
-    Kxx: unsigned xx bit
-    M: 1
-    N: 0
-    P27: 1 | 2 | 8 | 16
-   Q: pc relative load operand
-   Rxx: reserved for exotic register classes.
-   S: extra memory (storage) constraints (constraint len == 3)
-    Sua: unaligned memory operations
-   W: vector
-   Z: zero in any mode
-
-   unused CONST_INT constraint letters: LO
-   unused EXTRA_CONSTRAINT letters: D T U Y */
-
-#if 1 /* check that the transition went well.  */
-#define CONSTRAINT_LEN(C,STR) \
-  (((C) == 'L' || (C) == 'O' || (C) == 'D' || (C) == 'T' || (C) == 'U' \
-    || (C) == 'Y' \
-    || ((C) == 'I' \
-        && (((STR)[1] != '0' && (STR)[1] != '1' && (STR)[1] != '2') \
-           || (STR)[2] < '0' || (STR)[2] > '9')) \
-    || ((C) == 'B' && ((STR)[1] != 's' || (STR)[2] != 'c')) \
-    || ((C) == 'J' && ((STR)[1] != '1' || (STR)[2] != '6')) \
-    || ((C) == 'K' && ((STR)[1] != '0' || (STR)[2] != '8')) \
-    || ((C) == 'P' && ((STR)[1] != '2' || (STR)[2] != '7'))) \
-   ? -1 \
-   : ((C) == 'A' || (C) == 'B' || (C) == 'C' \
-      || (C) == 'I' || (C) == 'J' || (C) == 'K' || (C) == 'P' \
-      || (C) == 'R' || (C) == 'S') \
-   ? 3 \
-   : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
-#else
-#define CONSTRAINT_LEN(C,STR) \
-  (((C) == 'A' || (C) == 'B' || (C) == 'C' \
-    || (C) == 'I' || (C) == 'J' || (C) == 'K' || (C) == 'P' \
-    || (C) == 'R' || (C) == 'S') \
-   ? 3 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
-#endif
-
-/* The letters I, J, K, L and M in a register constraint string
-   can be used to stand for particular ranges of immediate operands.
-   This macro defines what the ranges are.
-   C is the letter, and VALUE is a constant value.
-   Return 1 if VALUE is in the range specified by C.
-       I08: arithmetic operand -127..128, as used in add, sub, etc
-       I16: arithmetic operand -32768..32767, as used in SHmedia movi and shori
-       P27: shift operand 1,2,8 or 16
-       K08: logical operand 0..255, as used in and, or, etc.
-       M: constant 1
-       N: constant 0
-       I06: arithmetic operand -32..31, as used in SHmedia beqi, bnei and xori
-       I10: arithmetic operand -512..511, as used in SHmedia andi, ori
-*/
+/* Defines for sh.md and constraints.md.  */
 
 #define CONST_OK_FOR_I06(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -32 \
                                 && ((HOST_WIDE_INT)(VALUE)) <= 31)
@@ -1667,52 +1250,13 @@ extern enum reg_class reg_class_from_letter[];
                                 && ((HOST_WIDE_INT)(VALUE)) <= 511)
 #define CONST_OK_FOR_I16(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -32768 \
                                 && ((HOST_WIDE_INT)(VALUE)) <= 32767)
-#define CONST_OK_FOR_I20(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -524288 \
-                                && ((HOST_WIDE_INT)(VALUE)) <= 524287 \
-                                && TARGET_SH2A)
-#define CONST_OK_FOR_I(VALUE, STR) \
-  ((STR)[1] == '0' && (STR)[2] == 6 ? CONST_OK_FOR_I06 (VALUE) \
-   : (STR)[1] == '0' && (STR)[2] == '8' ? CONST_OK_FOR_I08 (VALUE) \
-   : (STR)[1] == '1' && (STR)[2] == '0' ? CONST_OK_FOR_I10 (VALUE) \
-   : (STR)[1] == '1' && (STR)[2] == '6' ? CONST_OK_FOR_I16 (VALUE) \
-   : (STR)[1] == '2' && (STR)[2] == '0' ? CONST_OK_FOR_I20 (VALUE) \
-   : 0)
 
 #define CONST_OK_FOR_J16(VALUE) \
   ((HOST_BITS_PER_WIDE_INT >= 64 && (VALUE) == (HOST_WIDE_INT) 0xffffffff) \
    || (HOST_BITS_PER_WIDE_INT >= 64 && (VALUE) == (HOST_WIDE_INT) -1 << 32))
-#define CONST_OK_FOR_J(VALUE, STR) \
-  ((STR)[1] == '1' && (STR)[2] == '6' ? CONST_OK_FOR_J16 (VALUE) \
-   : 0)
 
 #define CONST_OK_FOR_K08(VALUE) (((HOST_WIDE_INT)(VALUE))>= 0 \
                                 && ((HOST_WIDE_INT)(VALUE)) <= 255)
-#define CONST_OK_FOR_K(VALUE, STR) \
-  ((STR)[1] == '0' && (STR)[2] == '8' ? CONST_OK_FOR_K08 (VALUE) \
-   : 0)
-#define CONST_OK_FOR_P27(VALUE) \
-  ((VALUE)==1||(VALUE)==2||(VALUE)==8||(VALUE)==16)
-#define CONST_OK_FOR_P(VALUE, STR) \
-  ((STR)[1] == '2' && (STR)[2] == '7' ? CONST_OK_FOR_P27 (VALUE) \
-   : 0)
-#define CONST_OK_FOR_M(VALUE) ((VALUE)==1)
-#define CONST_OK_FOR_N(VALUE) ((VALUE)==0)
-#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR)       \
-     ((C) == 'I' ? CONST_OK_FOR_I ((VALUE), (STR))     \
-    : (C) == 'J' ? CONST_OK_FOR_J ((VALUE), (STR))     \
-    : (C) == 'K' ? CONST_OK_FOR_K ((VALUE), (STR))     \
-    : (C) == 'M' ? CONST_OK_FOR_M (VALUE)              \
-    : (C) == 'N' ? CONST_OK_FOR_N (VALUE)              \
-    : (C) == 'P' ? CONST_OK_FOR_P ((VALUE), (STR))     \
-    : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.  */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)         \
-((C) == 'G' ? (fp_zero_operand (VALUE) && fldi_ok ())  \
- : (C) == 'H' ? (fp_one_operand (VALUE) && fldi_ok ()) \
- : (C) == 'F')
 
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
@@ -1722,18 +1266,20 @@ extern enum reg_class reg_class_from_letter[];
 #define PREFERRED_RELOAD_CLASS(X, CLASS) \
   ((CLASS) == NO_REGS && TARGET_SHMEDIA \
    && (GET_CODE (X) == CONST_DOUBLE \
-       || GET_CODE (X) == SYMBOL_REF) \
+       || GET_CODE (X) == SYMBOL_REF \
+       || PIC_ADDR_P (X)) \
    ? GENERAL_REGS \
    : (CLASS)) \
 
-#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \
+#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))                         \
@@ -1741,24 +1287,27 @@ extern enum reg_class reg_class_from_letter[];
    : (((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)))))               \
    ? GENERAL_REGS                                                      \
-   : ((CLASS) == TARGET_REGS                                           \
-      || (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS))                  \
-   ? ((target_operand ((X), (MODE))                                    \
-       && ! target_reg_operand ((X), (MODE)))                          \
-      ? NO_REGS : GENERAL_REGS)                                                \
+   : (((CLASS) == TARGET_REGS                                          \
+       || (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS))                 \
+      && !satisfies_constraint_Csy (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 : NO_REGS)
+   ? GENERAL_REGS : (ELSE))
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \
+ SECONDARY_INOUT_RELOAD_CLASS(CLASS,MODE,X,NO_REGS)
 
 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,X)  \
   ((REGCLASS_HAS_FP_REG (CLASS)                                        \
@@ -1767,19 +1316,19 @@ extern enum reg_class reg_class_from_letter[];
     && ! ((fp_zero_operand (X) || fp_one_operand (X))                  \
          && (MODE) == SFmode && fldi_ok ()))                           \
    ? R0_REGS                                                           \
-   : (CLASS == FPUL_REGS                                               \
-      && ((GET_CODE (X) == REG                                         \
+   : ((CLASS) == FPUL_REGS                                             \
+      && ((REG_P (X)                                                   \
           && (REGNO (X) == MACL_REG || REGNO (X) == MACH_REG           \
               || REGNO (X) == T_REG))                                  \
          || GET_CODE (X) == PLUS))                                     \
    ? GENERAL_REGS                                                      \
-   : CLASS == FPUL_REGS && immediate_operand ((X), (MODE))             \
-   ? (GET_CODE (X) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (X))       \
+   : (CLASS) == FPUL_REGS && immediate_operand ((X), (MODE))           \
+   ? (satisfies_constraint_I08 (X)                                     \
       ? 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)))\
+   : ((CLASS) == FPSCR_REGS                                            \
+      && ((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                                                        \
@@ -1787,7 +1336,14 @@ extern enum reg_class reg_class_from_letter[];
       && (X) != CONST0_RTX (GET_MODE (X))                              \
       && GET_MODE (X) != V4SFmode)                                     \
    ? GENERAL_REGS                                                      \
-   : SECONDARY_OUTPUT_RELOAD_CLASS((CLASS),(MODE),(X)))
+   : (((MODE) == QImode || (MODE) == HImode)                           \
+      && TARGET_SHMEDIA && inqhi_operand ((X), (MODE)))                        \
+   ? GENERAL_REGS                                                      \
+   : (TARGET_SHMEDIA && (CLASS) == GENERAL_REGS                                \
+      && (GET_CODE (X) == LABEL_REF || PIC_ADDR_P (X)))                        \
+   ? TARGET_REGS                                                       \
+   : SECONDARY_INOUT_RELOAD_CLASS((CLASS),(MODE),(X), NO_REGS))
+#endif
 
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.
@@ -1831,11 +1387,9 @@ extern enum reg_class reg_class_from_letter[];
    makes the stack pointer a smaller address.  */
 #define STACK_GROWS_DOWNWARD
 
-/*  Define this macro if the addresses of local variable slots are at
-    negative offsets from the frame pointer.
-
-    The SH only has positive indexes, so grow the frame up.  */
-/* #define FRAME_GROWS_DOWNWARD */
+/*  Define this macro to nonzero if the addresses of local variable slots
+    are at negative offsets from the frame pointer.  */
+#define FRAME_GROWS_DOWNWARD 1
 
 /* Offset from the frame pointer to the first local variable slot to
    be allocated.  */
@@ -1853,17 +1407,6 @@ extern enum reg_class reg_class_from_letter[];
 /* 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.
@@ -1892,39 +1435,6 @@ extern enum reg_class reg_class_from_letter[];
    ? 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)) < UNITS_PER_WORD    \
-            && (TREE_CODE (VALTYPE) == INTEGER_TYPE                    \
-                || TREE_CODE (VALTYPE) == ENUMERAL_TYPE                \
-                || TREE_CODE (VALTYPE) == BOOLEAN_TYPE                 \
-                || TREE_CODE (VALTYPE) == CHAR_TYPE                    \
-                || TREE_CODE (VALTYPE) == REAL_TYPE                    \
-                || TREE_CODE (VALTYPE) == OFFSET_TYPE))                \
-             && sh_promote_prototypes (VALTYPE)                                \
-           ? (TARGET_SHMEDIA ? 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.  */
@@ -2031,6 +1541,13 @@ struct sh_args {
 
      - If T is set, a return trampoline will be set up for 64-bit
      return values to be split into 2 32-bit registers.  */
+    long call_cookie;
+
+  /* This is set to nonzero when the call in question must use the Renesas ABI,
+     even without the -mrenesas option.  */
+    int renesas_abi;
+};
+
 #define CALL_COOKIE_RET_TRAMP_SHIFT 0
 #define CALL_COOKIE_RET_TRAMP(VAL) ((VAL) << CALL_COOKIE_RET_TRAMP_SHIFT)
 #define CALL_COOKIE_STACKSEQ_SHIFT 1
@@ -2043,12 +1560,6 @@ struct sh_args {
   ((VAL) << CALL_COOKIE_INT_REG_SHIFT (REG))
 #define CALL_COOKIE_INT_REG_GET(COOKIE, REG) \
   (((COOKIE) >> CALL_COOKIE_INT_REG_SHIFT (REG)) & ((REG) < 4 ? 7 : 15))
-    long call_cookie;
-
-  /* This is set to nonzero when the call in question must use the Renesas ABI,
-     even without the -mrenesas option.  */
-    int renesas_abi;
-};
 
 #define CUMULATIVE_ARGS  struct sh_args
 
@@ -2091,60 +1602,17 @@ struct sh_args {
    For TARGET_HITACHI, the structure value pointer is passed in memory.  */
 
 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
-  do {                                                         \
-    (CUM).arg_count[(int) SH_ARG_INT] = 0;                     \
-    (CUM).arg_count[(int) SH_ARG_FLOAT] = 0;                   \
-    (CUM).renesas_abi = sh_attr_renesas_p (FNTYPE) ? 1 : 0;    \
-    (CUM).force_mem                                            \
-      = ((TARGET_HITACHI || (CUM).renesas_abi) && (FNTYPE)     \
-        && aggregate_value_p (TREE_TYPE (FNTYPE), (FNDECL)));  \
-    (CUM).prototype_p = (FNTYPE) && TYPE_ARG_TYPES (FNTYPE);   \
-    (CUM).arg_count[(int) SH_ARG_INT]                          \
-      = (TARGET_SH5 && (FNTYPE)                                        \
-        && aggregate_value_p (TREE_TYPE (FNTYPE), (FNDECL)));  \
-    (CUM).free_single_fp_reg = 0;                              \
-    (CUM).outgoing = 1;                                                \
-    (CUM).stack_regs = 0;                                      \
-    (CUM).byref_regs = 0;                                      \
-    (CUM).byref = 0;                                           \
-    (CUM).call_cookie                                          \
-      = (CALL_COOKIE_RET_TRAMP                                 \
-        (TARGET_SHCOMPACT && (FNTYPE)                          \
-         && (CUM).arg_count[(int) SH_ARG_INT] == 0             \
-         && (TYPE_MODE (TREE_TYPE (FNTYPE)) == BLKmode         \
-             ? int_size_in_bytes (TREE_TYPE (FNTYPE))          \
-             : GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (FNTYPE)))) > 4 \
-         && (BASE_RETURN_VALUE_REG (TYPE_MODE (TREE_TYPE       \
-                                               (FNTYPE)))      \
-             == FIRST_RET_REG)));                              \
-  } while (0)
+  sh_init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL), (N_NAMED_ARGS), VOIDmode)
 
 #define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
-  do {                                                         \
-    INIT_CUMULATIVE_ARGS ((CUM), NULL_TREE, (LIBNAME), 0, 0);  \
-    (CUM).call_cookie                                          \
-      = (CALL_COOKIE_RET_TRAMP                                 \
-        (TARGET_SHCOMPACT && GET_MODE_SIZE (MODE) > 4          \
-         && BASE_RETURN_VALUE_REG (MODE) == FIRST_RET_REG));   \
-  } while (0)
-
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
-  do {                                                         \
-    INIT_CUMULATIVE_ARGS ((CUM), (FNTYPE), (LIBNAME), 0, 0);   \
-    (CUM).outgoing = 0;                                                \
-  } while (0)
-
-#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))
+  sh_init_cumulative_args (& (CUM), NULL_TREE, (LIBNAME), NULL_TREE, 0, (MODE))
 
 /* 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 \
@@ -2197,12 +1665,6 @@ struct sh_args {
    boundaries, because they'll be loaded using quad loads.  */
 #define SH_MIN_ALIGN_FOR_CALLEE_COPY (8 * BITS_PER_UNIT)
 
-#define FUNCTION_ARG_CALLEE_COPIES(CUM,MODE,TYPE,NAMED) \
-  ((CUM).outgoing                                                      \
-   && (((MODE) == BLKmode ? TYPE_ALIGN (TYPE)                          \
-       : GET_MODE_ALIGNMENT (MODE))                                    \
-       % SH_MIN_ALIGN_FOR_CALLEE_COPY == 0))
-
 /* The SH5 ABI requires floating-point arguments to be passed to
    functions without a prototype in both an FP register and a regular
    register or the stack.  When passing the argument in both FP and
@@ -2248,41 +1710,18 @@ struct sh_args {
                                                          (REG)),       \
                                   const0_rtx))))
 
-/* For an arg passed partly in registers and partly in memory,
-   this is the number of registers used.
-   For args passed entirely in registers or entirely in memory, zero.
-
-   We sometimes split args.  */
-
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
-  ((! TARGET_SH5 \
-    && PASS_IN_REG_P ((CUM), (MODE), (TYPE))                   \
-    && ! (TARGET_SH4 || TARGET_SH2A_DOUBLE)                                            \
-    && (ROUND_REG ((CUM), (MODE))                              \
-       + ((MODE) != BLKmode                                    \
-          ? ROUND_ADVANCE (GET_MODE_SIZE (MODE))               \
-          : ROUND_ADVANCE (int_size_in_bytes (TYPE)))          \
-       > NPARM_REGS (MODE)))                                   \
-   ? NPARM_REGS (MODE) - ROUND_REG ((CUM), (MODE))             \
-   : (SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE), (TYPE), (NAMED)) \
-      && ! TARGET_SHCOMPACT)                                   \
-   ? NPARM_REGS (SImode) - (CUM).arg_count[(int) SH_ARG_INT]   \
-   : 0)
-
 #define SH5_WOULD_BE_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
   (TARGET_SH5                                                  \
    && ((MODE) == BLKmode || (MODE) == TImode || (MODE) == CDImode \
        || (MODE) == DCmode) \
    && ((CUM).arg_count[(int) SH_ARG_INT]                       \
-       + (int_size_in_bytes (TYPE) + 7) / 8) > NPARM_REGS (SImode))
+       + (((MODE) == BLKmode ? int_size_in_bytes (TYPE)                \
+                            : GET_MODE_SIZE (MODE))            \
+         + 7) / 8) > NPARM_REGS (SImode))
 
 /* Perform any needed actions needed for a function that is receiving a
    variable number of arguments.  */
 
-/* Implement `va_start' for varargs and stdarg.  */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
-  sh_va_start (valist, nextarg)
-
 /* Call the function profiler with a given profile label.
    We use two .aligns, so as to make sure that both the .long is aligned
    on a 4 byte boundary, and that the .long is a fixed distance (2 bytes)
@@ -2290,10 +1729,19 @@ struct sh_args {
 
 #define FUNCTION_PROFILER(STREAM,LABELNO)                      \
 {                                                              \
-       fprintf((STREAM), "\t.align\t2\n");                     \
-       fprintf((STREAM), "\ttrapa\t#33\n");                    \
-       fprintf((STREAM), "\t.align\t2\n");                     \
-       asm_fprintf((STREAM), "\t.long\t%LLP%d\n", (LABELNO));  \
+  if (TARGET_SHMEDIA)                                          \
+    {                                                          \
+      fprintf((STREAM), "\tmovi\t33,r0\n");                    \
+      fprintf((STREAM), "\ttrapa\tr0\n");                      \
+      asm_fprintf((STREAM), "\t.long\t%LLP%d\n", (LABELNO));   \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      fprintf((STREAM), "\t.align\t2\n");                      \
+      fprintf((STREAM), "\ttrapa\t#33\n");                     \
+      fprintf((STREAM), "\t.align\t2\n");                      \
+      asm_fprintf((STREAM), "\t.long\t%LLP%d\n", (LABELNO));   \
+    }                                                          \
 }
 
 /* Define this macro if the code for function profiling should come
@@ -2323,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
@@ -2372,11 +1803,13 @@ 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)
 
 /* Macros to check register numbers against specific register classes.  */
 
@@ -2405,6 +1838,7 @@ struct sh_args {
 #define CONSTANT_ADDRESS_P(X)  (GET_CODE (X) == LABEL_REF)
 
 /* Nonzero if the constant value X is a legitimate general operand.  */
+/* can_store_by_pieces constructs VOIDmode CONST_DOUBLEs.  */
 
 #define LEGITIMATE_CONSTANT_P(X) \
   (TARGET_SHMEDIA                                                      \
@@ -2415,97 +1849,54 @@ struct sh_args {
       || TARGET_SHMEDIA64)                                             \
    : (GET_CODE (X) != CONST_DOUBLE                                     \
       || GET_MODE (X) == DFmode || GET_MODE (X) == SFmode              \
-      || (TARGET_SH2E && (fp_zero_operand (X) || fp_one_operand (X)))))
+      || GET_MODE (X) == DImode || GET_MODE (X) == VOIDmode))
 
 /* 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 'Q' constraint is a pc relative load operand.  */
-#define EXTRA_CONSTRAINT_Q(OP)                                         \
-  (GET_CODE (OP) == MEM                                                \
-   && ((GET_CODE (XEXP ((OP), 0)) == LABEL_REF)                                \
-       || (GET_CODE (XEXP ((OP), 0)) == CONST                          \
-          && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == PLUS               \
-          && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 0)) == LABEL_REF \
-          && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
-
-/* Extra address constraints.  */
-#define EXTRA_CONSTRAINT_A(OP, STR) 0
-
-/* Constraint for selecting FLDI0 or FLDI1 instruction. If the clobber
-   operand is not SCRATCH (i.e. REG) then R0 is probably being
-   used, hence mova is being used, hence do not select this pattern */
-#define EXTRA_CONSTRAINT_Bsc(OP)    (GET_CODE(OP) == SCRATCH)
-#define EXTRA_CONSTRAINT_B(OP, STR) \
-  ((STR)[1] == 's' && (STR)[2] == 'c' ? EXTRA_CONSTRAINT_Bsc (OP) \
-   : 0)
-
-/* The `C16' constraint is a 16-bit constant, literal or symbolic.  */
-#define EXTRA_CONSTRAINT_C16(OP) \
-  (GET_CODE (OP) == CONST \
-   && GET_CODE (XEXP ((OP), 0)) == SIGN_EXTEND \
-   && GET_MODE (XEXP ((OP), 0)) == DImode \
-   && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == TRUNCATE \
-   && GET_MODE (XEXP (XEXP ((OP), 0), 0)) == HImode \
-   && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP (XEXP ((OP), 0), 0), 0)) \
-       || (GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 0)) == ASHIFTRT \
-          && (MOVI_SHORI_BASE_OPERAND_P \
-              (XEXP (XEXP (XEXP (XEXP ((OP), 0), 0), 0), 0))) \
-          && GET_CODE (XEXP (XEXP (XEXP (XEXP ((OP), 0), 0), 0), \
-                             1)) == CONST_INT)))
+   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.  */
+
+#define IS_PC_RELATIVE_LOAD_ADDR_P(OP)                                 \
+  ((GET_CODE ((OP)) == LABEL_REF)                                      \
+   || (GET_CODE ((OP)) == CONST                                                \
+       && GET_CODE (XEXP ((OP), 0)) == PLUS                            \
+       && GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF             \
+       && CONST_INT_P (XEXP (XEXP ((OP), 0), 1))))
+
+#define IS_NON_EXPLICIT_CONSTANT_P(OP)                                 \
+  (CONSTANT_P (OP)                                                     \
+   && !CONST_INT_P (OP)                                        \
+   && GET_CODE (OP) != CONST_DOUBLE                                    \
+   && (!flag_pic                                                       \
+       || (LEGITIMATE_PIC_OPERAND_P (OP)                               \
+          && !PIC_ADDR_P (OP)                                          \
+          && GET_CODE (OP) != LABEL_REF)))
 
 /* Check whether OP is a datalabel unspec.  */
 #define DATALABEL_REF_NO_CONST_P(OP) \
   (GET_CODE (OP) == UNSPEC \
    && XINT ((OP), 1) == UNSPEC_DATALABEL \
    && XVECLEN ((OP), 0) == 1 \
-   && (GET_CODE (XVECEXP ((OP), 0, 0)) == SYMBOL_REF \
-       || GET_CODE (XVECEXP ((OP), 0, 0)) == LABEL_REF))
-
-/* Check whether OP is a datalabel unspec, possibly enclosed within a
-   CONST.  */
-#define DATALABEL_REF_P(OP) \
-  ((GET_CODE (OP) == CONST && DATALABEL_REF_NO_CONST_P (XEXP ((OP), 0))) \
-   || DATALABEL_REF_NO_CONST_P (OP))
+   && GET_CODE (XVECEXP ((OP), 0, 0)) == LABEL_REF)
 
 #define GOT_ENTRY_P(OP) \
   (GET_CODE (OP) == CONST && GET_CODE (XEXP ((OP), 0)) == UNSPEC \
@@ -2523,27 +1914,28 @@ 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 \
    && XINT (XEXP ((OP), 0), 1) == UNSPEC_PIC)
 
-#define PIC_OFFSET_P(OP) \
-  (PIC_ADDR_P (OP) \
-   && GET_CODE (XVECEXP (XEXP ((OP), 0), 0, 0)) == MINUS \
-   && reg_mentioned_p (pc_rtx, XEXP (XVECEXP (XEXP ((OP), 0), 0, 0), 1)))
-
-#define PIC_DIRECT_ADDR_P(OP) \
-  (PIC_ADDR_P (OP) && GET_CODE (XVECEXP (XEXP ((OP), 0), 0, 0)) != MINUS)
+#define PCREL_SYMOFF_P(OP) \
+  (GET_CODE (OP) == CONST \
+   && GET_CODE (XEXP ((OP), 0)) == UNSPEC \
+   && XINT (XEXP ((OP), 0), 1) == UNSPEC_PCREL_SYMOFF)
 
 #define NON_PIC_REFERENCE_P(OP) \
   (GET_CODE (OP) == LABEL_REF || GET_CODE (OP) == SYMBOL_REF \
-   || DATALABEL_REF_P (OP) \
+   || (GET_CODE (OP) == CONST \
+       && (GET_CODE (XEXP ((OP), 0)) == LABEL_REF \
+          || GET_CODE (XEXP ((OP), 0)) == SYMBOL_REF \
+          || DATALABEL_REF_NO_CONST_P (XEXP ((OP), 0)))) \
    || (GET_CODE (OP) == CONST && GET_CODE (XEXP ((OP), 0)) == PLUS \
        && (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == SYMBOL_REF \
-          || DATALABEL_REF_P (XEXP (XEXP ((OP), 0), 0))) \
-       && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
+          || GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF \
+          || DATALABEL_REF_NO_CONST_P (XEXP (XEXP ((OP), 0), 0))) \
+       && CONST_INT_P (XEXP (XEXP ((OP), 0), 1))))
 
 #define PIC_REFERENCE_P(OP) \
   (GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP) \
@@ -2552,326 +1944,54 @@ struct sh_args {
 #define MOVI_SHORI_BASE_OPERAND_P(OP) \
   (flag_pic \
    ? (GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP)  || GOTOFF_P (OP) \
-      || PIC_OFFSET_P (OP)) \
+      || PCREL_SYMOFF_P (OP)) \
    : NON_PIC_REFERENCE_P (OP))
-
-/* The `Csy' constraint is a label or a symbol.  */
-#define EXTRA_CONSTRAINT_Csy(OP) \
-  (NON_PIC_REFERENCE_P (OP) || PIC_DIRECT_ADDR_P (OP))
-
-/* A zero in any shape or form.  */
-#define EXTRA_CONSTRAINT_Z(OP) \
-  ((OP) == CONST0_RTX (GET_MODE (OP)))
-
-/* Any vector constant we can handle.  */
-#define EXTRA_CONSTRAINT_W(OP) \
-  (GET_CODE (OP) == CONST_VECTOR \
-   && (sh_rep_vec ((OP), VOIDmode) \
-       || (HOST_BITS_PER_WIDE_INT >= 64 \
-          ? sh_const_vec ((OP), VOIDmode) \
-          : sh_1el_vec ((OP), VOIDmode))))
-
-/* A non-explicit constant that can be loaded directly into a general purpose
-   register.  This is like 's' except we don't allow PIC_DIRECT_ADDR_P.  */
-#define EXTRA_CONSTRAINT_Cpg(OP) \
-  (CONSTANT_P (OP) \
-   && GET_CODE (OP) != CONST_INT \
-   && GET_CODE (OP) != CONST_DOUBLE \
-   && (!flag_pic \
-       || (LEGITIMATE_PIC_OPERAND_P (OP) \
-        && (! PIC_ADDR_P (OP) || PIC_OFFSET_P (OP)) \
-        && GET_CODE (OP) != LABEL_REF)))
-#define EXTRA_CONSTRAINT_C(OP, STR) \
-  ((STR)[1] == '1' && (STR)[2] == '6' ? EXTRA_CONSTRAINT_C16 (OP) \
-   : (STR)[1] == 's' && (STR)[2] == 'y' ? EXTRA_CONSTRAINT_Csy (OP) \
-   : (STR)[1] == 'p' && (STR)[2] == 'g' ? EXTRA_CONSTRAINT_Cpg (OP) \
-   : 0)
-
-#define EXTRA_MEMORY_CONSTRAINT(C,STR) ((C) == 'S')
-#define EXTRA_CONSTRAINT_Sr0(OP) \
-  (memory_operand((OP), GET_MODE (OP)) \
-   && ! refers_to_regno_p (R0_REG, R0_REG + 1, OP, (rtx *)0))
-#define EXTRA_CONSTRAINT_Sua(OP) \
-  (memory_operand((OP), GET_MODE (OP)) \
-   && GET_CODE (XEXP (OP, 0)) != PLUS)
-#define EXTRA_CONSTRAINT_S(OP, STR) \
-  ((STR)[1] == 'r' && (STR)[2] == '0' ? EXTRA_CONSTRAINT_Sr0 (OP) \
-   : (STR)[1] == 'u' && (STR)[2] == 'a' ? EXTRA_CONSTRAINT_Sua (OP) \
-   : 0)
-
-#define EXTRA_CONSTRAINT_STR(OP, C, STR)               \
-  ((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP)        \
-   : (C) == 'A' ? EXTRA_CONSTRAINT_A ((OP), (STR)) \
-   : (C) == 'B' ? EXTRA_CONSTRAINT_B ((OP), (STR)) \
-   : (C) == 'C' ? EXTRA_CONSTRAINT_C ((OP), (STR)) \
-   : (C) == 'S' ? EXTRA_CONSTRAINT_S ((OP), (STR)) \
-   : (C) == 'W' ? EXTRA_CONSTRAINT_W (OP) \
-   : (C) == 'Z' ? EXTRA_CONSTRAINT_Z (OP) \
-   : 0)
 \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                          \
-       && GET_CODE (SUBREG_REG (X)) == REG             \
-       && REG_OK_FOR_BASE_P (SUBREG_REG (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)))) \
+       && 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                          \
-       && 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 = 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 (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;                 \
-       if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;                 \
-      }                                                                        \
-  } while(0)
-
-#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 (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;                                                 \
-       }                                                               \
-    }                                                                  \
-}
-\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 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)))) \
+       && 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 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;                                             \
-       }                                                       \
-    }                                                          \
-}
+#define ALLOW_INDEXED_ADDRESS \
+  ((!TARGET_SHMEDIA32 && !TARGET_SHCOMPACT) || TARGET_ALLOW_INDEXED_ADDRESS)
 
+#define GO_IF_LEGITIMATE_INDEX(MODE, OP, WIN)  \
+  do {                                         \
+    if (sh_legitimate_index_p ((MODE), (OP)))  \
+      goto WIN;                                        \
+  } while (0)
+\f
 /* 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))  \
-    {                                                                  \
-      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 (index_rtx, NULL_RTX, &XEXP (X, 1), NULL,         \
-                      INDEX_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.  */
-
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)                       \
-{                                                                      \
-  if (GET_CODE(ADDR) == PRE_DEC || GET_CODE(ADDR) == POST_INC)         \
-    goto LABEL;                                                                \
-}
+  } while (0)
 \f
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
@@ -2957,7 +2077,9 @@ struct sh_args {
 #define SHIFT_COUNT_TRUNCATED (! TARGET_SH3 && ! TARGET_SH2A)
 
 /* All integers have the same format so truncation is easy.  */
-#define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC)  1
+/* But SHmedia must sign-extend DImode when truncating to SImode.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) \
+ (!TARGET_SHMEDIA || (INPREC) < 64 || (OUTPREC) >= 64)
 
 /* Define this if addresses of constant functions
    shouldn't be put through pseudo regs where they can be cse'd.
@@ -2984,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       \
@@ -3028,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.  */
@@ -3040,7 +2159,8 @@ struct sh_args {
    The SH1 does not have delay slots, hence we get a pipeline stall
    at every branch.  The SH4 is superscalar, so the single delay slot
    is not sufficient to keep both pipelines filled.  */
-#define BRANCH_COST (TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1)
+#define BRANCH_COST(speed_p, predictable_p) \
+       (TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1)
 \f
 /* Assembler output control.  */
 
@@ -3101,7 +2221,7 @@ struct sh_args {
 #undef DO_GLOBAL_CTORS_BODY
 #define DO_GLOBAL_CTORS_BODY                   \
 {                                              \
-  typedef (*pfunc)();                          \
+  typedef void (*pfunc) (void);                        \
   extern pfunc __ctors[];                      \
   extern pfunc __ctors_end[];                  \
   pfunc *p;                                    \
@@ -3114,7 +2234,7 @@ struct sh_args {
 #undef DO_GLOBAL_DTORS_BODY
 #define DO_GLOBAL_DTORS_BODY                   \
 {                                              \
-  typedef (*pfunc)();                          \
+  typedef void (*pfunc) (void);                        \
   extern pfunc __dtors[];                      \
   extern pfunc __dtors_end[];                  \
   pfunc *p;                                    \
@@ -3125,10 +2245,26 @@ struct sh_args {
 }
 
 #define ASM_OUTPUT_REG_PUSH(file, v) \
-  fprintf ((file), "\tmov.l\tr%d,@-r15\n", (v));
+{                                                      \
+  if (TARGET_SHMEDIA)                                  \
+    {                                                  \
+      fprintf ((file), "\taddi.l\tr15,-8,r15\n");      \
+      fprintf ((file), "\tst.q\tr15,0,r%d\n", (v));    \
+    }                                                  \
+  else                                                 \
+    fprintf ((file), "\tmov.l\tr%d,@-r15\n", (v));     \
+}
 
 #define ASM_OUTPUT_REG_POP(file, v) \
-  fprintf ((file), "\tmov.l\t@r15+,r%d\n", (v));
+{                                                      \
+  if (TARGET_SHMEDIA)                                  \
+    {                                                  \
+      fprintf ((file), "\tld.q\tr15,0,r%d\n", (v));    \
+      fprintf ((file), "\taddi.l\tr15,8,r15\n");       \
+    }                                                  \
+  else                                                 \
+    fprintf ((file), "\tmov.l\t@r15+,r%d\n", (v));     \
+}
 
 /* DBX register number for a given compiler register number.  */
 /* GDB has FPUL at 23 and FP0 at 25, so we must add one to all FP registers
@@ -3165,16 +2301,18 @@ struct sh_args {
    ? (TARGET_SH5 ? 18 : 17) \
    : (REGNO) == PR_MEDIA_REG \
    ? (TARGET_SH5 ? 18 : (unsigned) -1) \
-   : (REGNO) == T_REG \
-   ? (TARGET_SH5 ? 242 : 18) \
    : (REGNO) == GBR_REG \
-   ? (TARGET_SH5 ? 238 : 19) \
+   ? (TARGET_SH5 ? 238 : 18) \
    : (REGNO) == MACH_REG \
    ? (TARGET_SH5 ? 239 : 20) \
    : (REGNO) == MACL_REG \
    ? (TARGET_SH5 ? 240 : 21) \
+   : (REGNO) == T_REG \
+   ? (TARGET_SH5 ? 242 : 22) \
    : (REGNO) == FPUL_REG \
    ? (TARGET_SH5 ? 244 : 23) \
+   : (REGNO) == FPSCR_REG \
+   ? (TARGET_SH5 ? 243 : 24) \
    : (unsigned) -1)
 
 /* This is how to output a reference to a symbol_ref.  On SH5,
@@ -3260,25 +2398,11 @@ 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) == '\'')
-
 /* Recognize machine-specific patterns that may appear within
    constants.  Used for PIC-specific UNSPECs.  */
 #define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
   do                                                                   \
-    if (GET_CODE (X) == UNSPEC && XVECLEN ((X), 0) == 1)       \
+    if (GET_CODE (X) == UNSPEC)                                                \
       {                                                                        \
        switch (XINT ((X), 1))                                          \
          {                                                             \
@@ -3327,6 +2451,52 @@ struct sh_args {
              assemble_name ((STREAM), name);                           \
            }                                                           \
            break;                                                      \
+         case UNSPEC_EXTRACT_S16:                                      \
+         case UNSPEC_EXTRACT_U16:                                      \
+           {                                                           \
+             rtx val, shift;                                           \
+                                                                       \
+             val = XVECEXP (X, 0, 0);                                  \
+             shift = XVECEXP (X, 0, 1);                                \
+             fputc ('(', STREAM);                                      \
+             if (shift != const0_rtx)                                  \
+               fputc ('(', STREAM);                                    \
+             if (GET_CODE (val) == CONST                               \
+                 || GET_RTX_CLASS (GET_CODE (val)) != RTX_OBJ)         \
+               {                                                       \
+                 fputc ('(', STREAM);                                  \
+                 output_addr_const (STREAM, val);                      \
+                 fputc (')', STREAM);                                  \
+               }                                                       \
+             else                                                      \
+               output_addr_const (STREAM, val);                        \
+             if (shift != const0_rtx)                                  \
+               {                                                       \
+                 fputs (" >> ", STREAM);                               \
+                 output_addr_const (STREAM, shift);                    \
+                 fputc (')', STREAM);                                  \
+               }                                                       \
+             fputs (" & 65535)", STREAM);                              \
+           }                                                           \
+           break;                                                      \
+         case UNSPEC_SYMOFF:                                           \
+           output_addr_const (STREAM, XVECEXP (X, 0, 0));              \
+           fputc ('-', STREAM);                                        \
+           if (GET_CODE (XVECEXP (X, 0, 1)) == CONST)                  \
+             {                                                         \
+               fputc ('(', STREAM);                                    \
+               output_addr_const (STREAM, XVECEXP (X, 0, 1));          \
+               fputc (')', STREAM);                                    \
+             }                                                         \
+           else                                                        \
+             output_addr_const (STREAM, XVECEXP (X, 0, 1));            \
+           break;                                                      \
+         case UNSPEC_PCREL_SYMOFF:                                     \
+           output_addr_const (STREAM, XVECEXP (X, 0, 0));              \
+           fputs ("-(", STREAM);                                       \
+           output_addr_const (STREAM, XVECEXP (X, 0, 1));              \
+           fputs ("-.)", STREAM);                                      \
+           break;                                                      \
          default:                                                      \
            goto FAIL;                                                  \
          }                                                             \
@@ -3358,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,
@@ -3379,20 +2547,13 @@ extern enum mdep_reorg_phase_e mdep_reorg_phase;
   c_register_pragma (0, "nosave_low_regs", sh_pr_nosave_low_regs);     \
 } while (0)
 
-/* Set when processing a function with pragma interrupt turned on.  */
-
-extern int pragma_interrupt;
+extern tree sh_deferred_function_attributes;
+extern tree *sh_deferred_function_attributes_tail;
 
 /* Set when processing a function with interrupt attribute.  */
 
 extern int current_function_interrupt;
 
-/* Set to an RTX containing the address of the stack to switch to
-   for interrupt functions.  */
-extern struct rtx_def *sp_switch;
-
-extern int rtx_equal_function_value_matters;
-
 \f
 /* Instructions with unfilled delay slots take up an
    extra two bytes for the nop in the delay slot.
@@ -3401,54 +2562,6 @@ extern int rtx_equal_function_value_matters;
 #define ADJUST_INSN_LENGTH(X, LENGTH)                          \
   (LENGTH) += sh_insn_length_adjustment (X);
 \f
-/* Define the codes that are matched by predicates in sh.c.  */
-#define PREDICATE_CODES \
-  {"and_operand", {SUBREG, REG, CONST_INT}},                           \
-  {"any_register_operand", {SUBREG, REG}},                             \
-  {"arith_operand", {SUBREG, REG, CONST_INT}},                         \
-  {"arith_reg_dest", {SUBREG, REG}},                                   \
-  {"arith_reg_operand", {SUBREG, REG}},                                        \
-  {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}},  \
-  {"binary_float_operator", {PLUS, MINUS, MULT, DIV}},                 \
-  {"binary_logical_operator", {AND, IOR, XOR}},                                \
-  {"cmpsi_operand", {SUBREG, REG, CONST_INT}},                         \
-  {"commutative_float_operator", {PLUS, MULT}},                                \
-  {"equality_comparison_operator", {EQ,NE}},                           \
-  {"extend_reg_operand", {SUBREG, REG, TRUNCATE}},                     \
-  {"extend_reg_or_0_operand", {SUBREG, REG, TRUNCATE, CONST_INT}},     \
-  {"fp_arith_reg_operand", {SUBREG, REG}},                             \
-  {"fpscr_operand", {REG}},                                            \
-  {"fpul_operand", {REG}},                                             \
-  {"general_extend_operand", {SUBREG, REG, MEM, TRUNCATE}},            \
-  {"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \
-  {"general_movdst_operand", {SUBREG, REG, MEM}},                      \
-  {"unaligned_load_operand", {MEM}},                                   \
-  {"greater_comparison_operator", {GT,GE,GTU,GEU}},                    \
-  {"int_gpr_dest", {SUBREG, REG}},                                     \
-  {"inqhi_operand", {TRUNCATE}},                                       \
-  {"less_comparison_operator", {LT,LE,LTU,LEU}},                       \
-  {"logical_operand", {SUBREG, REG, CONST_INT}},                       \
-  {"mextr_bit_offset", {CONST_INT}},                                   \
-  {"noncommutative_float_operator", {MINUS, DIV}},                     \
-  {"shmedia_6bit_operand", {SUBREG, REG, CONST_INT}},                  \
-  {"sh_register_operand", {REG, SUBREG, CONST_INT}},                   \
-  {"target_reg_operand", {SUBREG, REG}},                               \
-  {"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
-  {"trunc_hi_operand", {SUBREG, REG, TRUNCATE}},                       \
-  {"sh_const_vec", {CONST_VECTOR}},                                    \
-  {"sh_1el_vec", {CONST_VECTOR, PARALLEL}},                            \
-  {"sh_rep_vec", {CONST_VECTOR, PARALLEL}},                            \
-  {"symbol_ref_operand", {SYMBOL_REF}},                                        \
-  {"unary_float_operator", {ABS, NEG, SQRT}},                          \
-
-#define SPECIAL_MODE_PREDICATES \
-  "any_register_operand", \
-  "int_gpr_dest", \
-  "trunc_hi_operand", \
-  /* This line intentionally left blank.  */
-
-#define any_register_operand register_operand
-
 /* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases,
    the value is constrained to be within the bounds of the declared
@@ -3460,20 +2573,21 @@ extern int rtx_equal_function_value_matters;
    load instructions.  */
 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
   if (GET_MODE_CLASS (MODE) == MODE_INT                        \
-      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD)                \
+      && GET_MODE_SIZE (MODE) < 4/* ! UNITS_PER_WORD */)\
     (UNSIGNEDP) = ((MODE) == SImode ? 0 : (UNSIGNEDP)),        \
-    (MODE) = (TARGET_SH1 ? SImode : DImode);
+    (MODE) = (TARGET_SH1 ? SImode \
+             : TARGET_SHMEDIA32 ? SImode : DImode);
 
 #define MAX_FIXED_MODE_SIZE (TARGET_SH5 ? 128 : 64)
 
-/* ??? 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.  */
+#define SIDI_OFF (TARGET_LITTLE_ENDIAN ? 0 : 4)
+
+/* 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 }
@@ -3527,21 +2641,20 @@ extern int rtx_equal_function_value_matters;
 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
 
 /* We have to distinguish between code and data, so that we apply
-   datalabel where and only where appropriate.  Use textrel for code.  */
+   datalabel where and only where appropriate.  Use sdataN for data.  */
 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
  ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \
-  | ((CODE) ? DW_EH_PE_textrel : flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr))
+  | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr) \
+  | ((CODE) ? 0 : (TARGET_SHMEDIA64 ? DW_EH_PE_sdata8 : DW_EH_PE_sdata4)))
 
 /* Handle special EH pointer encodings.  Absolute, pc-relative, and
    indirect are handled automatically.  */
 #define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
   do { \
-    if (((ENCODING) & 0x70) == DW_EH_PE_textrel) \
+    if (((ENCODING) & 0xf) != DW_EH_PE_sdata4 \
+       && ((ENCODING) & 0xf) != DW_EH_PE_sdata8) \
       { \
-       encoding &= ~DW_EH_PE_textrel; \
-       encoding |= flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr; \
-       if (GET_CODE (ADDR) != SYMBOL_REF) \
-         abort (); \
+       gcc_assert (GET_CODE (ADDR) == SYMBOL_REF); \
        SYMBOL_REF_FLAGS (ADDR) |= SYMBOL_FLAG_FUNCTION; \
        if (0) goto DONE; \
       } \
@@ -3561,16 +2674,7 @@ extern int rtx_equal_function_value_matters;
 2:\n" TEXT_SECTION_ASM_OP);
 #endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
 
-#define ALLOCATE_INITIAL_VALUE(hard_reg) \
-  (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG) \
-   ? (current_function_is_leaf \
-      && ! sh_pr_n_sets () \
-      && ! (TARGET_SHCOMPACT \
-           && ((current_function_args_info.call_cookie \
-                & ~ CALL_COOKIE_RET_TRAMP (1)) \
-               || current_function_has_nonlocal_label)) \
-      ? (hard_reg) \
-      : gen_rtx_MEM (Pmode, return_address_pointer_rtx)) \
-   : NULL_RTX)
+/* FIXME: middle-end support for highpart optimizations is missing.  */
+#define high_life_started reload_in_progress
 
 #endif /* ! GCC_SH_H */