OSDN Git Service

* config/sh/sh.h (DO_GLOBAL_CTORS_BODY): Add void to prototype.
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.h
index 306da7a..0e99ce6 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com).
    Improved by Jim Wilson (wilson@cygnus.com).
 
@@ -24,6 +24,8 @@ Boston, MA 02110-1301, USA.  */
 #ifndef GCC_SH_H
 #define GCC_SH_H
 
+#include "config/vxworks-dummy.h"
+
 #define TARGET_VERSION \
   fputs (" (Hitachi SH)", stderr);
 
@@ -92,11 +94,6 @@ do { \
     builtin_define ("__HITACHI__"); \
   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.  */
@@ -239,6 +236,9 @@ do { \
 #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)
@@ -276,6 +276,7 @@ do { \
 #endif
 #if SUPPORT_SH2
 #define SUPPORT_SH3 1
+#define SUPPORT_SH2A_NOFPU 1
 #endif
 #if SUPPORT_SH3
 #define SUPPORT_SH4_NOFPU 1
@@ -283,16 +284,17 @@ do { \
 #if SUPPORT_SH4_NOFPU
 #define SUPPORT_SH4A_NOFPU 1
 #define SUPPORT_SH4AL 1
-#define SUPPORT_SH2A_NOFPU 1
 #endif
 
 #if SUPPORT_SH2E
 #define SUPPORT_SH3E 1
+#define SUPPORT_SH2A_SINGLE_ONLY 1
 #endif
 #if SUPPORT_SH3E
 #define SUPPORT_SH4_SINGLE_ONLY 1
+#endif
+#if SUPPORT_SH4_SINGLE_ONLY
 #define SUPPORT_SH4A_SINGLE_ONLY 1
-#define SUPPORT_SH2A_SINGLE_ONLY 1
 #endif
 
 #if SUPPORT_SH4
@@ -368,9 +370,9 @@ do { \
   SUBTARGET_EXTRA_SPECS
 
 #if TARGET_CPU_DEFAULT & MASK_HARD_SH4
-#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*:%{!m5*:-isa=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 \
@@ -471,8 +473,13 @@ do {                                                                       \
       target_flags |= MASK_SMALLCODE;                                  \
       sh_div_str = SH_DIV_STR_FOR_SIZE ;                               \
     }                                                                  \
+  else                                                                 \
+    {                                                                  \
+      TARGET_CBRANCHDI4 = 1;                                           \
+      TARGET_EXPAND_CBRANCHDI4 = 1;                                    \
+    }                                                                  \
   /* We can't meaningfully test TARGET_SHMEDIA here, because -m options        \
-     haven't been parsed yet, hence we';d read only the default.       \
+     haven't been parsed yet, hence we'd read only the default.        \
      sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so        \
      it's OK to always set flag_branch_target_load_optimize.  */       \
   if (LEVEL > 1)                                                       \
@@ -486,6 +493,12 @@ do {                                                                       \
     flag_finite_math_only.  We set it to 2 here so we know if the user \
     explicitly requested this to be on or off.  */                     \
   flag_finite_math_only = 2;                                           \
+  /* If flag_schedule_insns is 1, we set it to 2 here so we know if    \
+     the user explicitly requested this to be on or off.  */           \
+  if (flag_schedule_insns > 0)                                         \
+    flag_schedule_insns = 2;                                           \
+                                                                       \
+  set_param_value ("simultaneous-prefetches", 2);                      \
 } while (0)
 
 #define ASSEMBLER_DIALECT assembler_dialect
@@ -493,16 +506,24 @@ do {                                                                      \
 extern int assembler_dialect;
 
 enum sh_divide_strategy_e {
+  /* SH5 strategies.  */
   SH_DIV_CALL,
   SH_DIV_CALL2,
-  SH_DIV_FP,
+  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
+  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;
@@ -511,10 +532,13 @@ extern enum sh_divide_strategy_e sh_div_strategy;
 #define SH_DIV_STRATEGY_DEFAULT SH_DIV_CALL
 #endif
 
+#define SUBTARGET_OVERRIDE_OPTIONS (void) 0
+
 #define OVERRIDE_OPTIONS                                               \
 do {                                                                   \
   int regno;                                                           \
                                                                        \
+  SUBTARGET_OVERRIDE_OPTIONS;                                          \
   if (flag_finite_math_only == 2)                                      \
     flag_finite_math_only                                              \
       = !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE;          \
@@ -598,6 +622,7 @@ do {                                                                        \
              else                                                      \
                sh_div_strategy = SH_DIV_INV;                           \
            }                                                           \
+         TARGET_CBRANCHDI4 = 0;                                        \
        }                                                               \
       /* -fprofile-arcs needs a working libgcov .  In unified tree     \
         configurations with newlib, this requires to configure with    \
@@ -612,21 +637,55 @@ do {                                                                      \
        targetm.asm_out.aligned_op.di = NULL;                           \
        targetm.asm_out.unaligned_op.di = NULL;                         \
     }                                                                  \
+  if (TARGET_SH1)                                                      \
+    {                                                                  \
+      if (! strcmp (sh_div_str, "call-div1"))                          \
+       sh_div_strategy = SH_DIV_CALL_DIV1;                             \
+      else if (! strcmp (sh_div_str, "call-fp")                                \
+              && (TARGET_FPU_DOUBLE                                    \
+                  || (TARGET_HARD_SH4 && TARGET_SH2E)                  \
+                  || (TARGET_SHCOMPACT && TARGET_FPU_ANY)))            \
+       sh_div_strategy = SH_DIV_CALL_FP;                               \
+      else if (! strcmp (sh_div_str, "call-table") && TARGET_SH2)      \
+       sh_div_strategy = SH_DIV_CALL_TABLE;                            \
+      else                                                             \
+       /* Pick one that makes most sense for the target in general.    \
+          It is not much good to use different functions depending     \
+          on -Os, since then we'll end up with two different functions \
+          when some of the code is compiled for size, and some for     \
+          speed.  */                                                   \
+                                                                       \
+       /* SH4 tends to emphasize speed.  */                            \
+       if (TARGET_HARD_SH4)                                            \
+         sh_div_strategy = SH_DIV_CALL_TABLE;                          \
+       /* These have their own way of doing things.  */                \
+       else if (TARGET_SH2A)                                           \
+         sh_div_strategy = SH_DIV_INTRINSIC;                           \
+       /* ??? Should we use the integer SHmedia function instead?  */  \
+       else if (TARGET_SHCOMPACT && TARGET_FPU_ANY)                    \
+         sh_div_strategy = SH_DIV_CALL_FP;                             \
+        /* SH1 .. SH3 cores often go into small-footprint systems, so  \
+          default to the smallest implementation available.  */        \
+       else if (TARGET_SH2)    /* ??? EXPERIMENTAL */                  \
+         sh_div_strategy = SH_DIV_CALL_TABLE;                          \
+       else                                                            \
+         sh_div_strategy = SH_DIV_CALL_DIV1;                           \
+    }                                                                  \
+  if (!TARGET_SH1)                                                     \
+    TARGET_PRETEND_CMOVE = 0;                                          \
   if (sh_divsi3_libfunc[0])                                            \
     ; /* User supplied - leave it alone.  */                           \
-  else if (TARGET_HARD_SH4 && TARGET_SH2E)                             \
+  else if (TARGET_DIVIDE_CALL_FP)                                      \
     sh_divsi3_libfunc = "__sdivsi3_i4";                                        \
+  else if (TARGET_DIVIDE_CALL_TABLE)                                   \
+    sh_divsi3_libfunc = "__sdivsi3_i4i";                               \
   else if (TARGET_SH5)                                                 \
-    {                                                                  \
-      if (TARGET_FPU_ANY && TARGET_SH1)                                        \
-       sh_divsi3_libfunc = "__sdivsi3_i4";                             \
-      else                                                             \
-       sh_divsi3_libfunc = "__sdivsi3_1";                              \
-    }                                                                  \
+    sh_divsi3_libfunc = "__sdivsi3_1";                                 \
   else                                                                 \
     sh_divsi3_libfunc = "__sdivsi3";                                   \
-  if (TARGET_FMOVD)                                                    \
-    reg_class_from_letter['e' - 'a'] = NO_REGS;                                \
+  if (sh_branch_cost == -1)                                            \
+    sh_branch_cost                                                     \
+      = TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1;      \
                                                                        \
   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)              \
     if (! VALID_REGISTER_P (regno))                                    \
@@ -661,6 +720,17 @@ do {                                                                       \
         SH3 and lower as they give spill failures for R0.  */          \
       if (!TARGET_HARD_SH4)                                            \
         flag_schedule_insns = 0;                                       \
+      /* ??? Current exception handling places basic block boundaries  \
+        after call_insns.  It causes the high pressure on R0 and gives \
+        spill failures for R0 in reload.  See PR 22553 and the thread  \
+        on gcc-patches                                                 \
+         <http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00816.html>.  */        \
+      else if (flag_exceptions)                                                \
+       {                                                               \
+         if (flag_schedule_insns == 1)                                 \
+           warning (0, "ignoring -fschedule-insns because of exception handling bug"); \
+         flag_schedule_insns = 0;                                      \
+       }                                                               \
     }                                                                  \
                                                                        \
   if (align_loops == 0)                                                        \
@@ -790,7 +860,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)            \
@@ -963,6 +1033,16 @@ 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, \
@@ -1466,65 +1546,8 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
 #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 */
-
-#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)))
-
-/* 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)
@@ -1534,52 +1557,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.
@@ -1594,6 +1578,7 @@ extern enum reg_class reg_class_from_letter[];
    ? GENERAL_REGS \
    : (CLASS)) \
 
+#if 0
 #define SECONDARY_INOUT_RELOAD_CLASS(CLASS,MODE,X,ELSE) \
   ((((REGCLASS_HAS_FP_REG (CLASS)                                      \
       && (GET_CODE (X) == REG                                          \
@@ -1617,7 +1602,7 @@ extern enum reg_class reg_class_from_letter[];
    ? GENERAL_REGS                                                      \
    : (((CLASS) == TARGET_REGS                                          \
        || (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS))                 \
-      && !EXTRA_CONSTRAINT_Csy (X)                                     \
+      && !satisfies_constraint_Csy (X)                                 \
       && (GET_CODE (X) != REG || ! GENERAL_REGISTER_P (REGNO (X))))    \
    ? GENERAL_REGS                                                      \
    : (((CLASS) == MAC_REGS || (CLASS) == PR_REGS)                      \
@@ -1645,7 +1630,7 @@ extern enum reg_class reg_class_from_letter[];
          || GET_CODE (X) == PLUS))                                     \
    ? GENERAL_REGS                                                      \
    : (CLASS) == FPUL_REGS && immediate_operand ((X), (MODE))           \
-   ? (GET_CODE (X) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (X))       \
+   ? (satisfies_constraint_I08 (X)                                     \
       ? GENERAL_REGS                                                   \
       : R0_REGS)                                                       \
    : ((CLASS) == FPSCR_REGS                                            \
@@ -1665,6 +1650,7 @@ extern enum reg_class reg_class_from_letter[];
       && (GET_CODE (X) == LABEL_REF || PIC_DIRECT_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.
@@ -1783,7 +1769,6 @@ extern enum reg_class reg_class_from_letter[];
             && (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)                                \
@@ -1906,6 +1891,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
@@ -1918,12 +1910,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
 
@@ -2084,7 +2070,9 @@ struct sh_args {
    && ((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.  */
@@ -2224,6 +2212,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                                                      \
@@ -2234,7 +2223,7 @@ 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.
@@ -2278,40 +2267,47 @@ struct sh_args {
 
 #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)))
+/* Macros for extra constraints.  */
 
-/* Extra address constraints.  */
-#define EXTRA_CONSTRAINT_A(OP, STR) 0
+#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             \
+       && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
 
-/* 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)
+#define IS_LITERAL_OR_SYMBOLIC_S16_P(OP)                               \
+  (GET_CODE ((OP)) == SIGN_EXTEND                                      \
+   && (GET_MODE ((OP)) == DImode                                       \
+       || GET_MODE ((OP)) == SImode)                                   \
+   && GET_CODE (XEXP ((OP), 0)) == TRUNCATE                            \
+   && GET_MODE (XEXP ((OP), 0)) == HImode                              \
+   && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP ((OP), 0), 0))            \
+       || (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == ASHIFTRT             \
+          && (MOVI_SHORI_BASE_OPERAND_P                                \
+              (XEXP (XEXP (XEXP ((OP), 0), 0), 0)))                    \
+          && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
 
-/* 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_MODE (XEXP ((OP), 0)) == SImode) \
-   && 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)))
+#define IS_LITERAL_OR_SYMBOLIC_U16_P(OP)                               \
+  (GET_CODE ((OP)) == ZERO_EXTEND                                      \
+   && (GET_MODE ((OP)) == DImode                                       \
+       || GET_MODE ((OP)) == SImode)                                   \
+   && GET_CODE (XEXP ((OP), 0)) == TRUNCATE                            \
+   && GET_MODE (XEXP ((OP), 0)) == HImode                              \
+   && (MOVI_SHORI_BASE_OPERAND_P (XEXP (XEXP ((OP), 0), 0))            \
+       || (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == ASHIFTRT             \
+          && (MOVI_SHORI_BASE_OPERAND_P                                \
+              (XEXP (XEXP (XEXP ((OP), 0), 0), 0)))                    \
+          && GET_CODE (XEXP (XEXP (XEXP ((OP), 0), 0), 1)) == CONST_INT)))
+
+#define IS_NON_EXPLICIT_CONSTANT_P(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)))
 
 /* Check whether OP is a datalabel unspec.  */
 #define DATALABEL_REF_NO_CONST_P(OP) \
@@ -2371,60 +2367,6 @@ struct sh_args {
    ? (GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP)  || GOTOFF_P (OP) \
       || PIC_OFFSET_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.
@@ -2503,11 +2445,11 @@ struct sh_args {
            int MODE_SIZE;                                              \
            /* Check if this the address of an unaligned load / store.  */\
            if ((MODE) == VOIDmode)                                     \
-                                                                     \
-             if (CONST_OK_FOR_I06 (INTVAL (OP)))                       \
-               goto LABEL;                                             \
-             break;                                                    \
-                                                                     \
+             {                                                         \
+               if (CONST_OK_FOR_I06 (INTVAL (OP)))                     \
+                 goto LABEL;                                           \
+               break;                                                  \
+             }                                                         \
            MODE_SIZE = GET_MODE_SIZE (MODE);                           \
            if (! (INTVAL (OP) & (MODE_SIZE - 1))                       \
                && INTVAL (OP) >= -512 * MODE_SIZE                      \
@@ -2708,13 +2650,11 @@ struct sh_args {
    ??? 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.  */
+   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;                                                                \
-}
+   Auto-increment addressing is now treated in recog.c.  */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
 \f
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
@@ -2741,6 +2681,12 @@ struct sh_args {
    floating point types equivalent to `float'.  */
 #define DOUBLE_TYPE_SIZE ((TARGET_SH2E && ! TARGET_SH4 && ! TARGET_SH2A_DOUBLE) ? 32 : 64)
 
+#if defined(__SH2E__) || defined(__SH3E__) || defined( __SH4_SINGLE_ONLY__)
+#define LIBGCC2_DOUBLE_TYPE_SIZE 32
+#else
+#define LIBGCC2_DOUBLE_TYPE_SIZE 64
+#endif
+
 /* 'char' is signed by default.  */
 #define DEFAULT_SIGNED_CHAR  1
 
@@ -2946,7 +2892,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;                                    \
@@ -2959,7 +2905,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;                                    \
@@ -3240,18 +3186,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;
-
 \f
 /* Instructions with unfilled delay slots take up an
    extra two bytes for the nop in the delay slot.
@@ -3374,8 +3315,6 @@ extern struct rtx_def *sp_switch;
 2:\n" TEXT_SECTION_ASM_OP);
 #endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
 
-#define SIMULTANEOUS_PREFETCHES 2
-
 /* FIXME: middle-end support for highpart optimizations is missing.  */
 #define high_life_started reload_in_progress