OSDN Git Service

Patch from Nick Clifton.
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.h
index 3ab2120..32cbb2c 100644 (file)
@@ -1,23 +1,23 @@
 /* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2004 Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com).
    Improved by Jim Wilson (wilson@cygnus.com).
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+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)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 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 GNU CC; see the file COPYING.  If not, write to
+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.  */
 
@@ -319,6 +319,7 @@ extern int target_flags;
   {"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" },                \
   {"nomacsave", NOMACSAVE_BIT, "Mark MAC register as call-clobbered" },                \
   {"ieee",     IEEE_BIT, "Increase the IEEE compliance for floating-point code" },                     \
   {"isize",    ISIZE_BIT, "" },                \
@@ -515,7 +516,11 @@ do {                                                                       \
       /* Never run scheduling before reload, since that can            \
         break global alloc, and generates slower code anyway due       \
         to the pressure on R0.  */                                     \
-      flag_schedule_insns = 0;                                         \
+      /* 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)                                                        \
@@ -572,10 +577,8 @@ do {                                                                       \
 
 #define MAX_BITS_PER_WORD 64
 
-#define MAX_LONG_TYPE_SIZE MAX_BITS_PER_WORD
-
 /* Width in bits of an `int'.  We want just 32-bits, even if words are
-   longer. */
+   longer.  */
 #define INT_TYPE_SIZE 32
 
 /* Width in bits of a `long'.  */
@@ -742,8 +745,6 @@ extern char sh_register_names[][MAX_REGISTER_NAME_LENGTH + 1];
   "rap"                                                                        \
 }
 
-#define DEBUG_REGISTER_NAMES SH_REGISTER_NAMES_INITIALIZER
-
 #define REGNAMES_ARR_INDEX_1(index) \
   (sh_register_names[index])
 #define REGNAMES_ARR_INDEX_2(index) \
@@ -1126,31 +1127,9 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 /* Register in which the static-chain is passed to a function.  */
 #define STATIC_CHAIN_REGNUM    (TARGET_SH5 ? 1 : 3)
 
-/* The register in which a struct value address is passed.  */
-
-#define STRUCT_VALUE_REGNUM 2
-
-/* If the structure value address is not passed in a register, define
-   `STRUCT_VALUE' as an expression returning an RTX for the place
-   where the address is passed.  If it returns 0, the address is
-   passed as an "invisible" first argument.  */
-
-/* The Renesas calling convention doesn't quite fit into this scheme since
-   the address is passed like an invisible argument, but one that is always
-   passed in memory.  */
-#define STRUCT_VALUE \
-  (TARGET_HITACHI ? 0 : gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM))
-
-#define RETURN_IN_MEMORY(TYPE) \
-  (TARGET_SH5 \
-   ? ((TYPE_MODE (TYPE) == BLKmode \
-       ? (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) \
-       : GET_MODE_SIZE (TYPE_MODE (TYPE))) > 8) \
-   : (TYPE_MODE (TYPE) == BLKmode \
-      || (TARGET_HITACHI && TREE_CODE (TYPE) == RECORD_TYPE)))
-
 /* Don't default to pcc-struct-return, because we have already specified
-   exactly how to return structures in the RETURN_IN_MEMORY macro.  */
+   exactly how to return structures in the TARGET_RETURN_IN_MEMORY
+   target hook.  */
 
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
@@ -1276,7 +1255,7 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff },      \
 /* ALL_REGS:  */                                                       \
   { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff },      \
-}                                                                       
+}
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -1656,7 +1635,7 @@ extern enum reg_class reg_class_from_letter[];
    tested here has to be kept in sync with the one in explow.c:promote_mode.  */
 
 #define FUNCTION_VALUE(VALTYPE, FUNC)                                  \
-  gen_rtx (REG,                                                                \
+  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                    \
@@ -1665,9 +1644,10 @@ extern enum reg_class reg_class_from_letter[];
                 || 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) \
@@ -1797,6 +1777,10 @@ struct sh_args {
 #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
@@ -1839,17 +1823,18 @@ struct sh_args {
 
    For TARGET_HITACHI, the structure value pointer is passed in memory.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+#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 && FNTYPE                              \
-        && aggregate_value_p (TREE_TYPE (FNTYPE)));            \
+      = ((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)));            \
+        && aggregate_value_p (TREE_TYPE (FNTYPE), (FNDECL)));  \
     (CUM).free_single_fp_reg = 0;                              \
     (CUM).outgoing = 1;                                                \
     (CUM).stack_regs = 0;                                      \
@@ -1869,7 +1854,7 @@ struct sh_args {
 
 #define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
   do {                                                         \
-    INIT_CUMULATIVE_ARGS ((CUM), NULL_TREE, (LIBNAME), 0);     \
+    INIT_CUMULATIVE_ARGS ((CUM), NULL_TREE, (LIBNAME), 0, 0);  \
     (CUM).call_cookie                                          \
       = (CALL_COOKIE_RET_TRAMP                                 \
         (TARGET_SHCOMPACT && GET_MODE_SIZE (MODE) > 4          \
@@ -1878,131 +1863,14 @@ struct sh_args {
 
 #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
   do {                                                         \
-    INIT_CUMULATIVE_ARGS ((CUM), (FNTYPE), (LIBNAME), 0);      \
+    INIT_CUMULATIVE_ARGS ((CUM), (FNTYPE), (LIBNAME), 0, 0);   \
     (CUM).outgoing = 0;                                                \
   } while (0)
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be
-   available.)  */
 
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
- if ((CUM).force_mem)                                  \
-   (CUM).force_mem = 0;                                        \
- else if (TARGET_SH5)                                  \
-   {                                                   \
-     tree TYPE_ = ((CUM).byref && (TYPE)               \
-                  ? TREE_TYPE (TYPE)                   \
-                  : (TYPE));                           \
-     enum machine_mode MODE_ = ((CUM).byref && (TYPE)  \
-                               ? TYPE_MODE (TYPE_)     \
-                               : (MODE));              \
-     int dwords = (((CUM).byref                                \
-                   ? (CUM).byref                       \
-                   : (MODE_) == BLKmode                \
-                   ? int_size_in_bytes (TYPE_)         \
-                   : GET_MODE_SIZE (MODE_)) + 7) / 8;  \
-     int numregs = MIN (dwords, NPARM_REGS (SImode)    \
-                       - (CUM).arg_count[(int) SH_ARG_INT]); \
-                                                       \
-     if (numregs)                                      \
-       {                                               \
-        (CUM).arg_count[(int) SH_ARG_INT] += numregs;  \
-        if (TARGET_SHCOMPACT                           \
-            && SHCOMPACT_FORCE_ON_STACK (MODE_, TYPE_)) \
-          {                                            \
-            (CUM).call_cookie                          \
-              |= CALL_COOKIE_INT_REG (((CUM).arg_count[(int) SH_ARG_INT] \
-                                       - numregs), 1); \
-            /* N.B. We want this also for outgoing.   */\
-            (CUM).stack_regs += numregs;               \
-          }                                            \
-        else if ((CUM).byref)                          \
-          {                                            \
-            if (! (CUM).outgoing)                      \
-              (CUM).stack_regs += numregs;             \
-            (CUM).byref_regs += numregs;               \
-            (CUM).byref = 0;                           \
-            do                                         \
-              (CUM).call_cookie                        \
-                |= CALL_COOKIE_INT_REG (((CUM).arg_count[(int) SH_ARG_INT] \
-                                         - numregs), 2); \
-            while (--numregs);                         \
-            (CUM).call_cookie                          \
-              |= CALL_COOKIE_INT_REG (((CUM).arg_count[(int) SH_ARG_INT] \
-                                       - 1), 1); \
-          }                                            \
-        else if (dwords > numregs)                     \
-          {                                            \
-            int pushregs = numregs;                    \
-                                                       \
-            if (TARGET_SHCOMPACT)                      \
-              (CUM).stack_regs += numregs;             \
-            while (pushregs < NPARM_REGS (SImode) - 1  \
-                   && (CALL_COOKIE_INT_REG_GET         \
-                       ((CUM).call_cookie,             \
-                       NPARM_REGS (SImode) - pushregs) \
-                       == 1))                          \
-              {                                        \
-                (CUM).call_cookie                      \
-                  &= ~ CALL_COOKIE_INT_REG (NPARM_REGS (SImode) \
-                                            - pushregs, 1); \
-                pushregs++;                            \
-              }                                        \
-            if (numregs == NPARM_REGS (SImode))        \
-              (CUM).call_cookie                        \
-                |= CALL_COOKIE_INT_REG (0, 1)          \
-                   | CALL_COOKIE_STACKSEQ (numregs - 1); \
-            else                                       \
-              (CUM).call_cookie                        \
-                |= CALL_COOKIE_STACKSEQ (numregs);     \
-          }                                            \
-       }                                               \
-     if (GET_SH_ARG_CLASS (MODE_) == SH_ARG_FLOAT      \
-        && ((NAMED) || ! (CUM).prototype_p))           \
-       {                                               \
-        if ((MODE_) == SFmode && (CUM).free_single_fp_reg) \
-          (CUM).free_single_fp_reg = 0;                \
-        else if ((CUM).arg_count[(int) SH_ARG_FLOAT]   \
-                 < NPARM_REGS (SFmode))                \
-          {                                            \
-            int numfpregs                              \
-              = MIN ((GET_MODE_SIZE (MODE_) + 7) / 8 * 2, \
-                     NPARM_REGS (SFmode)               \
-                     - (CUM).arg_count[(int) SH_ARG_FLOAT]); \
-                                                       \
-            (CUM).arg_count[(int) SH_ARG_FLOAT] += numfpregs; \
-                                                       \
-            if (TARGET_SHCOMPACT && ! (CUM).prototype_p) \
-              {                                        \
-                if ((CUM).outgoing && numregs > 0)     \
-                  do                                   \
-                    {                                  \
-                      (CUM).call_cookie                \
-                        |= (CALL_COOKIE_INT_REG        \
-                            ((CUM).arg_count[(int) SH_ARG_INT] \
-                             - numregs + ((numfpregs - 2) / 2), \
-                             4 + ((CUM).arg_count[(int) SH_ARG_FLOAT] \
-                                  - numfpregs) / 2));  \
-                    }                                  \
-                  while (numfpregs -= 2);              \
-              }                                        \
-            else if ((MODE_) == SFmode && (NAMED)      \
-                     && ((CUM).arg_count[(int) SH_ARG_FLOAT] \
-                         < NPARM_REGS (SFmode)))       \
-              (CUM).free_single_fp_reg                 \
-                = FIRST_FP_PARM_REG - numfpregs        \
-                + (CUM).arg_count[(int) SH_ARG_FLOAT] + 1; \
-          }                                            \
-       }                                               \
-   }                                                   \
- else if (! TARGET_SH4 || PASS_IN_REG_P ((CUM), (MODE), (TYPE))) \
-   ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)]     \
-    = (ROUND_REG ((CUM), (MODE))                       \
-       + ((MODE) == BLKmode                            \
-         ? ROUND_ADVANCE (int_size_in_bytes (TYPE))    \
-         : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))))
+       sh_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)   \
+       sh_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
 
 /* Return boolean indicating arg of mode MODE will be passed in a reg.
    This macro is only used in this file.  */
@@ -2010,7 +1878,11 @@ struct sh_args {
 #define PASS_IN_REG_P(CUM, MODE, TYPE) \
   (((TYPE) == 0 \
     || (! TREE_ADDRESSABLE ((tree)(TYPE)) \
-       && (! TARGET_HITACHI || ! AGGREGATE_TYPE_P (TYPE)))) \
+       && (! (TARGET_HITACHI || (CUM).renesas_abi) \
+           || ! (AGGREGATE_TYPE_P (TYPE) \
+                 || (!TARGET_FPU_ANY \
+                     && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+                         && GET_MODE_SIZE (MODE) > GET_MODE_SIZE (SFmode))))))) \
    && ! (CUM).force_mem \
    && (TARGET_SH2E \
        ? ((MODE) == BLKmode \
@@ -2040,75 +1912,6 @@ struct sh_args {
    foo (float a, __complex float b); a: fr5 b.real: fr4 b.imag: fr7  */
 #define FUNCTION_ARG_SCmode_WART 1
 
-/* Define where to put the arguments to a function.
-   Value is zero to push the argument on the stack,
-   or a hard register in which to store the argument.
-
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-    This is null for libcalls where that information may
-    not be available.
-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
-    the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-    (otherwise it is an extra parameter matching an ellipsis).
-
-   On SH the first args are normally in registers
-   and the rest are pushed.  Any arg that starts within the first
-   NPARM_REGS words is at least partially passed in a register unless
-   its data type forbids.  */
-
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-  ((! TARGET_SH5 \
-    && PASS_IN_REG_P ((CUM), (MODE), (TYPE))                           \
-    && ((NAMED) || !TARGET_HITACHI))                                   \
-   ? (((MODE) == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN          \
-       && (! FUNCTION_ARG_SCmode_WART || (ROUND_REG ((CUM), (MODE)) & 1)))\
-      ? (gen_rtx_PARALLEL                                              \
-        (SCmode,                                                       \
-         (gen_rtvec                                                    \
-          (2,                                                          \
-           (gen_rtx_EXPR_LIST                                          \
-            (VOIDmode,                                                 \
-             gen_rtx_REG (SFmode,                                      \
-                          BASE_ARG_REG (MODE)                          \
-                          + (ROUND_REG ((CUM), (MODE)) ^ 1)),          \
-             const0_rtx)),                                             \
-           (gen_rtx_EXPR_LIST                                          \
-            (VOIDmode,                                                 \
-             gen_rtx_REG (SFmode,                                      \
-                          BASE_ARG_REG (MODE)                          \
-                          + ((ROUND_REG ((CUM), (MODE)) + 1) ^ 1)),    \
-             GEN_INT (4)))))))                                         \
-      : gen_rtx_REG ((MODE),                                           \
-                    ((BASE_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE))) \
-                     ^ ((MODE) == SFmode && TARGET_SH4                 \
-                        && TARGET_LITTLE_ENDIAN != 0))))               \
-   : TARGET_SH5                                                                \
-   ? ((MODE) == VOIDmode && TARGET_SHCOMPACT                           \
-      ? GEN_INT ((CUM).call_cookie)                                    \
-      /* The following test assumes unnamed arguments are promoted to  \
-        DFmode.  */                                                    \
-      : (MODE) == SFmode && (CUM).free_single_fp_reg                   \
-      ? SH5_PROTOTYPED_FLOAT_ARG ((CUM), (MODE), (CUM).free_single_fp_reg) \
-      : (GET_SH_ARG_CLASS (MODE) == SH_ARG_FLOAT                       \
-         && ((NAMED) || ! (CUM).prototype_p)                           \
-         && (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (SFmode)) \
-      ? ((! (CUM).prototype_p && TARGET_SHMEDIA)                       \
-        ? SH5_PROTOTYPELESS_FLOAT_ARG ((CUM), (MODE))                  \
-        : SH5_PROTOTYPED_FLOAT_ARG ((CUM), (MODE),                     \
-                                    FIRST_FP_PARM_REG                  \
-                                    + (CUM).arg_count[(int) SH_ARG_FLOAT])) \
-      : ((CUM).arg_count[(int) SH_ARG_INT] < NPARM_REGS (SImode)       \
-        && (! TARGET_SHCOMPACT                                         \
-            || (! SHCOMPACT_FORCE_ON_STACK ((MODE), (TYPE))            \
-                && ! SH5_WOULD_BE_PARTIAL_NREGS ((CUM), (MODE),        \
-                                                 (TYPE), (NAMED)))))   \
-      ? gen_rtx_REG ((MODE), (FIRST_PARM_REG                           \
-                             + (CUM).arg_count[(int) SH_ARG_INT]))     \
-      : 0)                                                             \
-   : 0)
-
 /* Whether an argument must be passed by reference.  On SHcompact, we
    pretend arguments wider than 32-bits that would have been passed in
    registers are passed by reference, so that an SHmedia trampoline
@@ -2203,10 +2006,6 @@ struct sh_args {
                                                          (REG)),       \
                                   const0_rtx))))
 
-#define STRICT_ARGUMENT_NAMING TARGET_SH5
-
-#define PRETEND_OUTGOING_VARARGS_NAMED (! TARGET_HITACHI && ! TARGET_SH5)
-
 /* 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.
@@ -2238,20 +2037,6 @@ struct sh_args {
 /* Perform any needed actions needed for a function that is receiving a
    variable number of arguments.  */
 
-/* We actually emit the code in sh_expand_prologue.  We used to use
-   a static variable to flag that we need to emit this code, but that
-   doesn't when inlining, when functions are deferred and then emitted
-   later.  Fortunately, we already have two flags that are part of struct
-   function that tell if a function uses varargs or stdarg.  */
-#define SETUP_INCOMING_VARARGS(ASF, MODE, TYPE, PAS, ST)  do \
-  if (! current_function_stdarg) \
-    abort (); \
-while (0)
-
-/* Define the `__builtin_va_list' type for the ABI.  */
-#define BUILD_VA_LIST_TYPE(VALIST) \
-  (VALIST) = sh_build_va_list ()
-
 /* Implement `va_start' for varargs and stdarg.  */
 #define EXPAND_BUILTIN_VA_START(valist, nextarg) \
   sh_va_start (valist, nextarg)
@@ -2286,7 +2071,7 @@ while (0)
 
 #define EXIT_IGNORE_STACK 1
 
-/* 
+/*
    On the SH, the trampoline looks like
    2 0002 D202                 mov.l   l2,r2
    1 0000 D301                 mov.l   l1,r3
@@ -2315,7 +2100,7 @@ while (0)
 #define TRAMPOLINE_ADJUST_ADDRESS(TRAMP) do                            \
 {                                                                      \
   if (TARGET_SHMEDIA)                                                  \
-    (TRAMP) = expand_simple_binop (Pmode, PLUS, (TRAMP), GEN_INT (1),  \
+    (TRAMP) = expand_simple_binop (Pmode, PLUS, (TRAMP), const1_rtx,   \
                                   gen_reg_rtx (Pmode), 0,              \
                                   OPTAB_LIB_WIDEN);                    \
 } while (0)
@@ -2336,9 +2121,6 @@ while (0)
 #define INCOMING_RETURN_ADDR_RTX \
   gen_rtx_REG (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG)
 \f
-/* Generate necessary RTL for __builtin_saveregs().  */
-#define EXPAND_BUILTIN_SAVEREGS() sh_builtin_saveregs ()
-\f
 /* Addressing modes, and classification of registers for them.  */
 #define HAVE_POST_INCREMENT  TARGET_SH1
 #define HAVE_PRE_DECREMENT   TARGET_SH1
@@ -2782,9 +2564,9 @@ while (0)
         prevalent.  */                                                 \
       if (GET_MODE_SIZE (MODE) + offset - offset_base <= 64)           \
        {                                                               \
-         sum = gen_rtx (PLUS, Pmode, XEXP (X, 0),                      \
+         sum = gen_rtx_PLUS (Pmode, XEXP (X, 0),                       \
                         GEN_INT (offset_base));                        \
-         X = gen_rtx (PLUS, Pmode, sum, GEN_INT (offset - 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));                                         \
@@ -2919,9 +2701,6 @@ while (0)
    but a CALL with constant address is cheap.  */
 /*#define NO_FUNCTION_CSE 1*/
 
-/* Chars and shorts should be passed as ints.  */
-#define PROMOTE_PROTOTYPES 1
-
 /* The machine modes of pointers and functions.  */
 #define Pmode  (TARGET_SHMEDIA64 ? DImode : SImode)
 #define FUNCTION_MODE  Pmode
@@ -3100,7 +2879,7 @@ while (0)
    used to use the encodings 245..260, but that doesn't make sense:
    PR_REG and PR_MEDIA_REG are actually the same register, and likewise
    the FP registers stay the same when switching between compact and media
-   mode.  Hence, we also need to use the same dwarf frame coloumns.
+   mode.  Hence, we also need to use the same dwarf frame columns.
    Likewise, we need to support unwind information for SHmedia registers
    even in compact code.  */
 #define SH_DBX_REGISTER_NUMBER(REGNO) \
@@ -3370,6 +3149,7 @@ extern int rtx_equal_function_value_matters;
   {"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}},                     \
@@ -3408,7 +3188,7 @@ extern int rtx_equal_function_value_matters;
 #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, 
+   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
    type, but kept valid in the wider mode.  The signedness of the
    extension may differ from that of the type.
@@ -3422,17 +3202,10 @@ extern int rtx_equal_function_value_matters;
     (UNSIGNEDP) = ((MODE) == SImode ? 0 : (UNSIGNEDP)),        \
     (MODE) = (TARGET_SH1 ? SImode : DImode);
 
-/* Defining PROMOTE_FUNCTION_ARGS eliminates some unnecessary zero/sign
-   extensions applied to char/short functions arguments.  Defining
-   PROMOTE_FUNCTION_RETURN does the same for function returns.  */
-
-#define PROMOTE_FUNCTION_ARGS
-#define PROMOTE_FUNCTION_RETURN
-
 #define MAX_FIXED_MODE_SIZE (TARGET_SH5 ? 128 : 64)
 
 /* ??? Define ACCUMULATE_OUTGOING_ARGS?  This is more efficient than pushing
-   and poping arguments.  However, we do have push/pop instructions, and
+   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.  */
@@ -3453,6 +3226,11 @@ extern int rtx_equal_function_value_matters;
    ? (TARGET_FMOVD ? FP_MODE_DOUBLE : FP_MODE_NONE) \
    : ACTUAL_NORMAL_MODE (ENTITY))
 
+#define MODE_ENTRY(ENTITY) NORMAL_MODE (ENTITY)
+
+#define MODE_EXIT(ENTITY) \
+  (sh_cfun_attr_renesas_p () ? FP_MODE_NONE : NORMAL_MODE (ENTITY))
+
 #define EPILOGUE_USES(REGNO)       ((TARGET_SH2E || TARGET_SH4)                \
                                    && (REGNO) == FPSCR_REG)
 
@@ -3461,6 +3239,13 @@ extern int rtx_equal_function_value_matters;
    ? get_attr_fp_mode (INSN)                                           \
    : FP_MODE_NONE)
 
+#define MODE_AFTER(MODE, INSN)                  \
+     (TARGET_HITACHI                           \
+      && recog_memoized (INSN) >= 0            \
+      && get_attr_fp_set (INSN) != FP_SET_NONE  \
+      ? get_attr_fp_set (INSN)                  \
+      : (MODE))
+
 #define MODE_PRIORITY_TO_MODE(ENTITY, N) \
   ((TARGET_FPU_SINGLE != 0) ^ (N) ? FP_MODE_SINGLE : FP_MODE_DOUBLE)