OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / cris / cris.h
index 98a27a6..57bdd46 100644 (file)
@@ -1,12 +1,13 @@
 /* Definitions for GCC.  Part of the machine description for CRIS.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
+   2009, 2010, 2011 Free Software Foundation, Inc.
    Contributed by Axis Communications.  Written by Hans-Peter Nilsson.
 
 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,
@@ -15,9 +16,8 @@ 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/>.  */
 
 /* After the first "Node:" comment comes all preprocessor directives and
    attached declarations described in the info files, the "Using and
@@ -37,6 +37,11 @@ Boston, MA 02111-1307, USA.  */
    settings not repeated below.  This file contains general CRIS
    definitions and definitions for the cris-*-elf subtarget.  */
 
+/* We don't want to use gcc_assert for everything, as that can be
+   compiled out.  */
+#define CRIS_ASSERT(x) \
+ do { if (!(x)) internal_error ("CRIS-port assertion failed: " #x); } while (0)
+
 /* Replacement for REG_P since it does not match SUBREGs.  Happens for
    testcase Axis-20000320 with gcc-2.9x.  */
 #define REG_S_P(x) \
@@ -49,14 +54,16 @@ Boston, MA 02111-1307, USA.  */
 #define CRIS_FIRST_ARG_REG 10
 #define CRIS_MAX_ARGS_IN_REGS 4
 
-/* Other convenience definitions.  */
-#define CRIS_PC_REGNUM 15
-#define CRIS_SRP_REGNUM 16
+/* See also *_REGNUM constants in cris.md.  */
 
 /* Most of the time, we need the index into the register-names array.
-   When passing debug-info, we need the real register number.  */
+   When passing debug-info, we need the real hardware register number.  */
 #define CRIS_CANONICAL_SRP_REGNUM (16 + 11)
 #define CRIS_CANONICAL_MOF_REGNUM (16 + 7)
+/* We have CCR in all models including v10, but that's 16 bits, so let's
+   prefer the DCCR number, which is a DMA pointer in pre-v8, so we'll
+   never clash with it for GCC purposes.  */
+#define CRIS_CANONICAL_CC0_REGNUM (16 + 13)
 
 /* When generating PIC, these suffixes are added to the names of non-local
    functions when being output.  Contrary to other ports, we have offsets
@@ -67,28 +74,13 @@ Boston, MA 02111-1307, USA.  */
 #define CRIS_PLT_GOTOFFSET_SUFFIX ":PLTG"
 #define CRIS_PLT_PCOFFSET_SUFFIX ":PLT"
 
-/* If you tweak this, don't forget to check cris_expand_builtin_va_arg.  */
 #define CRIS_FUNCTION_ARG_SIZE(MODE, TYPE)     \
   ((MODE) != BLKmode ? GET_MODE_SIZE (MODE)    \
    : (unsigned) int_size_in_bytes (TYPE))
 
-/* Check for max allowed stackframe. A "const char *" to be parsed.  */
-extern const char *cris_max_stackframe_str;
-
-/* Which CPU version this is.  A "const char *" to be parsed.  */
-extern const char *cris_cpu_str;
-
 /* Which CPU version this is.  The parsed and adjusted cris_cpu_str.  */
 extern int cris_cpu_version;
 
-/* Which CPU version to tune for.  A "const char *" to be parsed.  */
-extern const char *cris_tune_str;
-
-/* The argument to "-melinux-stacksize=".  We don't parse it currently;
-   it's just passed on to the linker.  We might want to do something
-   here someday.  */
-extern const char *cris_elinux_stacksize_str;
-
 /* Changing the order used to be necessary to put the fourth __make_dp
    argument (a DImode parameter) in registers, to fit with the libfunc
    parameter passing scheme used for intrinsic functions.  FIXME: Check
@@ -104,52 +96,74 @@ extern const char *cris_elinux_stacksize_str;
 
 /* Node: Driver */
 
-/* When using make with defaults.mak for Sun this will handily remove
-   any "-target sun*" switches.  */
-/* We need to override any previous definitions (linux.h) */
-#undef WORD_SWITCH_TAKES_ARG
-#define WORD_SWITCH_TAKES_ARG(STR)             \
- (DEFAULT_WORD_SWITCH_TAKES_ARG (STR)          \
-  || !strcmp (STR, "target"))
-
 /* Also provide canonical vN definitions when user specifies an alias.
    Note that -melf overrides -maout.  */
 
 #define CPP_SPEC \
- "%{mtune=*:-D__tune_%* %{mtune=v*:-D__CRIS_arch_tune=%*}}\
+ "%{mtune=*:-D__tune_%* %{mtune=v*:-D__CRIS_arch_tune=%*}\
    %{mtune=etrax4:-D__tune_v3 -D__CRIS_arch_tune=3}\
    %{mtune=etrax100:-D__tune_v8 -D__CRIS_arch_tune=8}\
    %{mtune=svinto:-D__tune_v8 -D__CRIS_arch_tune=8}\
    %{mtune=etrax100lx:-D__tune_v10 -D__CRIS_arch_tune=10}\
-   %{mtune=ng:-D__tune_v10 -D__CRIS_arch_tune=10}\
-  %{mcpu=*:-D__arch_%* %{mcpu=v*:-D__CRIS_arch_version=%*}}\
+   %{mtune=ng:-D__tune_v10 -D__CRIS_arch_tune=10}}\
+  %{mcpu=*:-D__arch_%* %{mcpu=v*:-D__CRIS_arch_version=%*}\
    %{mcpu=etrax4:-D__arch_v3 -D__CRIS_arch_version=3}\
    %{mcpu=etrax100:-D__arch_v8 -D__CRIS_arch_version=8}\
    %{mcpu=svinto:-D__arch_v8 -D__CRIS_arch_version=8}\
    %{mcpu=etrax100lx:-D__arch_v10 -D__CRIS_arch_version=10}\
-   %{mcpu=ng:-D__arch_v10 -D__CRIS_arch_version=10}\
-  %{march=*:-D__arch_%* %{march=v*:-D__CRIS_arch_version=%*}}\
+   %{mcpu=ng:-D__arch_v10 -D__CRIS_arch_version=10}}\
+  %{march=*:-D__arch_%* %{march=v*:-D__CRIS_arch_version=%*}\
    %{march=etrax4:-D__arch_v3 -D__CRIS_arch_version=3}\
    %{march=etrax100:-D__arch_v8 -D__CRIS_arch_version=8}\
    %{march=svinto:-D__arch_v8 -D__CRIS_arch_version=8}\
    %{march=etrax100lx:-D__arch_v10 -D__CRIS_arch_version=10}\
-   %{march=ng:-D__arch_v10 -D__CRIS_arch_version=10}\
+   %{march=ng:-D__arch_v10 -D__CRIS_arch_version=10}}\
   %{metrax100:-D__arch__v8 -D__CRIS_arch_version=8}\
   %{metrax4:-D__arch__v3 -D__CRIS_arch_version=3}\
   %(cpp_subtarget)"
 
 /* For the cris-*-elf subtarget.  */
+
+#define CRIS_DEFAULT_TUNE "10"
+#define CRIS_ARCH_CPP_DEFAULT
+#define CRIS_DEFAULT_ASM_ARCH_OPTION ""
+
+#ifdef TARGET_CPU_DEFAULT
+#if TARGET_CPU_DEFAULT != 32 && TARGET_CPU_DEFAULT != 10
+ #error "Due to '()'; e.g. '#define TARGET_CPU_DEFAULT (10)', stringize TARGET_CPU_DEFAULT isn't useful: update manually."
+#endif
+
+#if TARGET_CPU_DEFAULT == 32
+#undef CRIS_DEFAULT_TUNE
+#define CRIS_DEFAULT_TUNE "32"
+/* To enable use of "generic" cris-axis-elf binutils, always pass the
+   architecture option to GAS.  (We don't do this for non-v32.)  */
+#undef CRIS_DEFAULT_ASM_ARCH_OPTION
+#define CRIS_DEFAULT_ASM_ARCH_OPTION "--march=v32"
+#endif
+
+#undef CRIS_ARCH_CPP_DEFAULT
+#define CRIS_ARCH_CPP_DEFAULT \
+ "%{!march=*:\
+   %{!metrax*:\
+    %{!mcpu=*:\
+     %{!mtune=*:-D__tune_v" CRIS_DEFAULT_TUNE "}\
+     -D__arch_v"CRIS_DEFAULT_TUNE\
+   " -D__CRIS_arch_version=" CRIS_DEFAULT_TUNE "}}}"
+#endif
+
 #define CRIS_CPP_SUBTARGET_SPEC \
  "%{mbest-lib-options:\
    %{!moverride-best-lib-options:\
-    %{!march=*:%{!metrax*:%{!mcpu=*:-D__tune_v10 -D__CRIS_arch_tune=10}}}}}"
+   %{!march=*:%{!metrax*:%{!mcpu=*:\
+      -D__tune_v" CRIS_DEFAULT_TUNE \
+    " -D__CRIS_arch_tune=" CRIS_DEFAULT_TUNE "}}}}}"\
+ CRIS_ARCH_CPP_DEFAULT
 
-/* Remove those Sun-make "target" switches.  */
 /* Override previous definitions (linux.h).  */
 #undef CC1_SPEC
 #define CC1_SPEC \
- "%{target*:}\
-  %{metrax4:-march=v3}\
+ "%{metrax4:-march=v3}\
   %{metrax100:-march=v8}\
   %(cc1_subtarget)"
 
@@ -158,26 +172,33 @@ extern const char *cris_elinux_stacksize_str;
  "-melf\
   %{mbest-lib-options:\
    %{!moverride-best-lib-options:\
-    %{!march=*:%{!mcpu=*:-mtune=v10 -D__CRIS_arch_tune=10}}\
+   %{!march=*:%{!mcpu=*:-mtune=v" CRIS_DEFAULT_TUNE\
+       " -D__CRIS_arch_tune=" CRIS_DEFAULT_TUNE "}}\
     %{!finhibit-size-directive:\
       %{!fno-function-sections: -ffunction-sections}\
       %{!fno-data-sections: -fdata-sections}}}}"
 
-/* This adds to CC1_SPEC.  When bugs are removed from -fvtable-gc
-   (-fforce-addr causes invalid .vtable_entry asm in tinfo.cc and
-   nothing at all works in GCC 3.0-pre), add this line:
-   "%{mbest-lib-options:%{!moverride-best-lib-options:\
-   %{!melinux:%{!maout|melf:%{!fno-vtable-gc:-fvtable-gc}}}}}".  */
+/* This adds to CC1_SPEC.  */
 #define CC1PLUS_SPEC ""
 
+#ifdef HAVE_AS_NO_MUL_BUG_ABORT_OPTION
+#define MAYBE_AS_NO_MUL_BUG_ABORT \
+ "%{mno-mul-bug-workaround:-no-mul-bug-abort} "
+#else
+#define MAYBE_AS_NO_MUL_BUG_ABORT
+#endif
+
 /* Override previous definitions (linux.h).  */
 #undef ASM_SPEC
 #define ASM_SPEC \
- "%{v:-v}\
-  %(asm_subtarget)"
+ MAYBE_AS_NO_MUL_BUG_ABORT \
+ "%(asm_subtarget)\
+ %{march=*:%{mcpu=*:%edo not specify both -march=... and -mcpu=...}}\
+ %{march=v32:--march=v32} %{mcpu=v32:--march=v32}"
 
 /* For the cris-*-elf subtarget.  */
-#define CRIS_ASM_SUBTARGET_SPEC "--em=criself"
+#define CRIS_ASM_SUBTARGET_SPEC \
+ "--em=criself %{!march=*:%{!mcpu=*:" CRIS_DEFAULT_ASM_ARCH_OPTION "}}"
 
 /* FIXME: We should propagate the -melf option to make the criself
    "emulation" unless a linker script is provided (-T*), but I don't know
@@ -186,11 +207,8 @@ extern const char *cris_elinux_stacksize_str;
    time being.
 
    Note that -melf overrides -maout except that a.out-compiled libraries
-   are linked in (multilibbing).  The somewhat cryptic -rpath-link pair is
-   to avoid *only* picking up the linux multilib subdir from the "-B./"
-   option during build, while still giving it preference.  We'd need some
-   %s-variant that checked for existence of some specific file.  */
-/* Override previous definitions (svr4.h).  */
+   are linked in (multilibbing).  We'd need some %s-variant that
+   checked for existence of some specific file.  */
 #undef LINK_SPEC
 #define LINK_SPEC \
  "%{v:--verbose}\
@@ -202,35 +220,27 @@ extern const char *cris_elinux_stacksize_str;
   %{sim2:%{!T*:-Tdata 0x4000000 -Tbss 0x8000000}}\
   %{!r:%{O2|O3: --gc-sections}}"
 
-/* Which library to get.  The only difference from the default is to get
-   libsc.a if -sim is given to the driver.  Repeat -lc -lsysX
-   {X=sim,linux}, because libsysX needs (at least) errno from libc, and
-   then we want to resolve new unknowns in libc against libsysX, not
-   libnosys.  */
+/* Which library to get.  The simulator uses a different library for
+   the low-level syscalls (implementing the Linux syscall ABI instead
+   of direct-iron accesses).  Default everything with the stub "nosys"
+   library.  */
 /* Override previous definitions (linux.h).  */
 #undef LIB_SPEC
 #define LIB_SPEC \
- "%{sim*:-lc -lsyssim -lc -lsyssim}\
+ "%{sim*:--start-group -lc -lsyslinux --end-group}\
   %{!sim*:%{g*:-lg}\
     %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} -lbsp}\
   -lnosys"
 
 /* Linker startfile options; crt0 flavors.
-
-   At the moment there are no gcrt0.o or mcrt0.o, but keep them here and
-   link them to crt0.o to be prepared.  Use scrt0.c if running the
-   simulator, linear style, or s2crt0.c if fixed style.  */
-/* We need to remove any previous definition (elfos.h).  */
+   We need to remove any previous definition (elfos.h).  */
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC \
- "%{sim2:s2crt0.o%s}\
-  %{!sim2:%{sim:scrt0.o%s}\
-   %{!sim:%{pg:gcrt0.o%s}\
-    %{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}\
-  crtbegin.o%s"
+ "%{sim*:crt1.o%s}%{!sim*:crt0.o%s}\
+  crti.o%s crtbegin.o%s"
 
 #undef ENDFILE_SPEC
-#define ENDFILE_SPEC "crtend.o%s"
+#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
 
 #define EXTRA_SPECS                            \
   {"cpp_subtarget", CRIS_CPP_SUBTARGET_SPEC},  \
@@ -251,223 +261,53 @@ extern const char *cris_elinux_stacksize_str;
       builtin_define_std ("CRIS");             \
       builtin_define_std ("GNU_CRIS");         \
       builtin_define ("__CRIS_ABI_version=2"); \
+      builtin_assert ("cpu=cris");             \
+      builtin_assert ("machine=cris");         \
     }                                          \
   while (0)
 
-#define TARGET_OS_CPP_BUILTINS()               \
-  do                                           \
-    {                                          \
-      builtin_define ("__ELF__");              \
-    }                                          \
-  while (0)
-
-
-/* This needs to be at least 32 bits.  */
-extern int target_flags;
-
-/* Currently this just affects aligment.  FIXME:  Redundant with
-   TARGET_ALIGN_BY_32, or put machine stuff here?  */
-#define TARGET_MASK_SVINTO 1
-#define TARGET_SVINTO (target_flags & TARGET_MASK_SVINTO)
-
-/* If to use condition-codes generated by insns other than the
-   immediately preceding compare/test insn.
-    Used to check for errors in notice_update_cc.  */
-#define TARGET_MASK_CCINIT 2
-#define TARGET_CCINIT (target_flags & TARGET_MASK_CCINIT)
-
-/* Debug option.  */
-#define TARGET_MASK_PDEBUG 4
-#define TARGET_PDEBUG (target_flags & TARGET_MASK_PDEBUG)
-
-/* If to use side-effect patterns.  Used to debug the [rx=ry+i] type
-   patterns.  */
-#define TARGET_MASK_SIDE_EFFECT_PREFIXES 8
-#define TARGET_SIDE_EFFECT_PREFIXES \
- (target_flags & TARGET_MASK_SIDE_EFFECT_PREFIXES)
-
-/* If to expand mul into mstep.  Only used when making libc.a.  */
-#define TARGET_MASK_EXPAND_MUL 16
-#define TARGET_EXPAND_MUL (target_flags & TARGET_MASK_EXPAND_MUL)
-
-/* If to *keep* (not force) alignment of stack at 16 bits.  */
-#define TARGET_MASK_STACK_ALIGN 32
-#define TARGET_STACK_ALIGN (target_flags & TARGET_MASK_STACK_ALIGN)
-
-/* If to do alignment on individual non-modifiable objects.  */
-#define TARGET_MASK_CONST_ALIGN 64
-#define TARGET_CONST_ALIGN (target_flags & TARGET_MASK_CONST_ALIGN)
-
-/* If to do alignment on individual modifiable objects.  */
-#define TARGET_MASK_DATA_ALIGN 128
-#define TARGET_DATA_ALIGN (target_flags & TARGET_MASK_DATA_ALIGN)
-
-/* If not to omit function prologue and epilogue.  */
-#define TARGET_MASK_PROLOGUE_EPILOGUE 256
-#define TARGET_PROLOGUE_EPILOGUE (target_flags & TARGET_MASK_PROLOGUE_EPILOGUE)
-
-/* Instructions additions from Etrax 4 and up.
-   (Just "lz", which we don't really generate from GCC -- yet).  */
-#define TARGET_MASK_ETRAX4_ADD 512
-#define TARGET_ETRAX4_ADD (target_flags & TARGET_MASK_ETRAX4_ADD)
-
-/* Say that all alignment specifications say to prefer 32 rather
-   than 16 bits.  */
-#define TARGET_MASK_ALIGN_BY_32 1024
-#define TARGET_ALIGN_BY_32 (target_flags & TARGET_MASK_ALIGN_BY_32)
-
-/* This condition is of limited use, as gcc is riddled with #ifdef:s
-   controlling this, rather than if (...):s.  */
-#define TARGET_MASK_ELF 2048
-#define TARGET_ELF (target_flags & TARGET_MASK_ELF)
-
-/* Currently just used to error-check other options.  Note that this is
-   *not* set for -melinux.  */
-#define TARGET_MASK_LINUX 4096
-#define TARGET_LINUX (target_flags & TARGET_MASK_LINUX)
-
-/* There's a small setup cost with using GOTPLT references, but should
-   in total be a win both in code-size and execution-time.  */
-#define TARGET_MASK_AVOID_GOTPLT 8192
-#define TARGET_AVOID_GOTPLT (target_flags & TARGET_MASK_AVOID_GOTPLT)
-
-#define TARGET_SWITCHES                                                        \
- {                                                                     \
-  /* No "no-etrax" as it does not really imply any model.              \
-     On the other hand, "etrax" implies the common (and large)         \
-     subset matching all models.  */                                   \
-  {"etrax4",                            TARGET_MASK_ETRAX4_ADD,        \
-   N_("Compile for ETRAX 4 (CRIS v3)")},                               \
-  {"no-etrax4",                                -TARGET_MASK_ETRAX4_ADD, ""},   \
-  {"etrax100",                      (TARGET_MASK_SVINTO                \
-                                     + TARGET_MASK_ETRAX4_ADD          \
-                                     + TARGET_MASK_ALIGN_BY_32),       \
-   N_("Compile for ETRAX 100 (CRIS v8)")},                             \
-  {"no-etrax100",                  -(TARGET_MASK_SVINTO                \
-                                     + TARGET_MASK_ETRAX4_ADD), ""},   \
-  {"pdebug",                                TARGET_MASK_PDEBUG,        \
-   N_("Emit verbose debug information in assembly code")},             \
-  {"no-pdebug",                                    -TARGET_MASK_PDEBUG, ""},   \
-  {"cc-init",                               TARGET_MASK_CCINIT,        \
-   N_("Do not use condition codes from normal instructions")},         \
-  {"no-cc-init",                           -TARGET_MASK_CCINIT, ""},   \
-  {"side-effects",            TARGET_MASK_SIDE_EFFECT_PREFIXES, ""},   \
-  {"no-side-effects",        -TARGET_MASK_SIDE_EFFECT_PREFIXES,        \
-   N_("Do not emit addressing modes with side-effect assignment")},    \
-  {"stack-align",                      TARGET_MASK_STACK_ALIGN, ""},   \
-  {"no-stack-align",                  -TARGET_MASK_STACK_ALIGN,        \
-   N_("Do not tune stack alignment")},                                 \
-  {"data-align",                        TARGET_MASK_DATA_ALIGN, ""},   \
-  {"no-data-align",                    -TARGET_MASK_DATA_ALIGN,        \
-   N_("Do not tune writable data alignment")},                         \
-  {"const-align",                      TARGET_MASK_CONST_ALIGN, ""},   \
-  {"no-const-align",                  -TARGET_MASK_CONST_ALIGN,        \
-   N_("Do not tune code and read-only data alignment")},               \
-  {"32-bit",                       (TARGET_MASK_STACK_ALIGN            \
-                                    + TARGET_MASK_CONST_ALIGN          \
-                                    + TARGET_MASK_DATA_ALIGN           \
-                                    + TARGET_MASK_ALIGN_BY_32), ""},   \
-  {"32bit",                        (TARGET_MASK_STACK_ALIGN            \
-                                    + TARGET_MASK_CONST_ALIGN          \
-                                    + TARGET_MASK_DATA_ALIGN           \
-                                    + TARGET_MASK_ALIGN_BY_32),        \
-   N_("Align code and data to 32 bits")},                              \
-  {"16-bit",                        (TARGET_MASK_STACK_ALIGN           \
-                                     + TARGET_MASK_CONST_ALIGN         \
-                                     + TARGET_MASK_DATA_ALIGN), ""},   \
-  {"16bit",                         (TARGET_MASK_STACK_ALIGN           \
-                                     + TARGET_MASK_CONST_ALIGN         \
-                                     + TARGET_MASK_DATA_ALIGN), ""},   \
-  {"8-bit",                        -(TARGET_MASK_STACK_ALIGN           \
-                                     + TARGET_MASK_CONST_ALIGN         \
-                                     + TARGET_MASK_DATA_ALIGN), ""},   \
-  {"8bit",                         -(TARGET_MASK_STACK_ALIGN           \
-                                     + TARGET_MASK_CONST_ALIGN         \
-                                     + TARGET_MASK_DATA_ALIGN),        \
-   N_("Don't align items in code or data")},                           \
-  {"prologue-epilogue",                  TARGET_MASK_PROLOGUE_EPILOGUE, ""},   \
-  {"no-prologue-epilogue",      -TARGET_MASK_PROLOGUE_EPILOGUE,        \
-   N_("Do not emit function prologue or epilogue")},                   \
-  /* We have to handle this m-option here since we can't wash it off in \
-     both CC1_SPEC and CC1PLUS_SPEC.  */                               \
-  {"best-lib-options",                                       0,        \
- N_("Use the most feature-enabling options allowed by other options")},        \
-                                                                       \
-  /* We must call it "override-" since calling it "no-" will cause     \
-     gcc.c to forget it, if there's a "later" -mbest-lib-options.      \
-     Kludgy, but needed for some multilibbed files.  */                        \
-  {"override-best-lib-options",                                      0,        \
-   N_("Override -mbest-lib-options")},                                 \
-  CRIS_SUBTARGET_SWITCHES                                              \
-  {"",                 TARGET_DEFAULT | CRIS_SUBTARGET_DEFAULT, ""}}   \
-
-/* For the cris-*-elf subtarget.  */
-#define CRIS_SUBTARGET_SWITCHES \
- {"elf", 0, ""},
+/* Previously controlled by target_flags.  */
+#define TARGET_ELF 1
 
-/* Default target_flags if no switches specified.  */
-#ifndef TARGET_DEFAULT
-# define TARGET_DEFAULT \
- (TARGET_MASK_SIDE_EFFECT_PREFIXES + TARGET_MASK_STACK_ALIGN \
-  + TARGET_MASK_CONST_ALIGN + TARGET_MASK_DATA_ALIGN \
-  + TARGET_MASK_PROLOGUE_EPILOGUE)
-#endif
+/* Previously controlled by target_flags.  Note that this is *not* set
+   for -melinux.  */
+#define TARGET_LINUX 0
 
 /* For the cris-*-elf subtarget.  */
-#define CRIS_SUBTARGET_DEFAULT TARGET_MASK_ELF
+#define CRIS_SUBTARGET_DEFAULT 0
 
 #define CRIS_CPU_BASE 0
 #define CRIS_CPU_ETRAX4 3      /* Just lz added.  */
 #define CRIS_CPU_SVINTO 8      /* Added swap, jsrc & Co., 32-bit accesses.  */
 #define CRIS_CPU_NG 10         /* Added mul[su].  */
+#define CRIS_CPU_V32 32                /* Major changes.  */
 
-/* Local, providing a default for cris_cpu_version.  */
-#define CRIS_DEFAULT_CPU_VERSION CRIS_CPU_BASE
-
-#define TARGET_HAS_MUL_INSNS (cris_cpu_version >= CRIS_CPU_NG)
-
-#define TARGET_OPTIONS                                                 \
- {{"cpu=", &cris_cpu_str, ""},                                         \
-  {"arch=", &cris_cpu_str,                                             \
-   N_("Generate code for the specified chip or CPU version")},         \
-  {"tune=", &cris_tune_str,                                            \
-   N_("Tune alignment for the specified chip or CPU version")},                \
-  {"max-stackframe=", &cris_max_stackframe_str,                                \
-   N_("Warn when a stackframe is larger than the specified size")},    \
-  CRIS_SUBTARGET_LONG_OPTIONS                                          \
-  {"ax-stackframe=", &cris_max_stackframe_str, ""}}
-
-#define CRIS_SUBTARGET_LONG_OPTIONS
-
-/* Print subsidiary information on the compiler version in use.
-   Do not use VD.D syntax (D=digit), since this will cause confusion
-   with the base gcc version among users, when we ask which version of
-   gcc-cris they are using.  Please use some flavor of "R<number>" for
-   the version (no need for major.minor versions, I believe).  */
-#define TARGET_VERSION \
- fprintf (stderr, " [Axis CRIS%s]", CRIS_SUBTARGET_VERSION)
-
-/* For the cris-*-elf subtarget.  */
-#define CRIS_SUBTARGET_VERSION " - generic ELF"
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT CRIS_CPU_BASE
+#endif
 
-#define OVERRIDE_OPTIONS cris_override_options ()
+/* Default target_flags if no switches specified.  */
+#ifndef TARGET_DEFAULT
+# if TARGET_CPU_DEFAULT == 32
+#  define TARGET_DEFAULT \
+ (MASK_STACK_ALIGN \
+  + MASK_CONST_ALIGN + MASK_DATA_ALIGN \
+  + MASK_PROLOGUE_EPILOGUE)
+# else  /* 10 */
+# define TARGET_DEFAULT \
+ (MASK_SIDE_EFFECT_PREFIXES + MASK_STACK_ALIGN \
+  + MASK_CONST_ALIGN + MASK_DATA_ALIGN \
+  + MASK_PROLOGUE_EPILOGUE + MASK_MUL_BUG)
+# endif
+#endif
 
-/* The following gives optimal code for gcc-2.7.2, but *may* be subject
-   to change.  Omitting flag_force_addr gives .1-.7% faster code for gcc
-   *only*, but 1.3% larger code.  On ipps it gives 5.3-10.6% slower
-   code(!) and 0.3% larger code.  For products, images gets .1-1.8%
-   larger.  Do not set strict aliasing from optimization options.  */
-#define OPTIMIZATION_OPTIONS(OPTIMIZE, SIZE)   \
-  do                                           \
-    {                                          \
-      if ((OPTIMIZE) >= 2 || (SIZE))           \
-       {                                       \
-         flag_force_addr = 1;                  \
-         flag_omit_frame_pointer = 1;          \
-       }                                       \
-    }                                          \
-  while (0)
+/* Local, providing a default for cris_cpu_version.  */
+#define CRIS_DEFAULT_CPU_VERSION TARGET_CPU_DEFAULT
 
+#define TARGET_HAS_MUL_INSNS (cris_cpu_version >= CRIS_CPU_NG)
+#define TARGET_HAS_LZ (cris_cpu_version >= CRIS_CPU_ETRAX4)
+#define TARGET_HAS_SWAP (cris_cpu_version >= CRIS_CPU_SVINTO)
+#define TARGET_V32 (cris_cpu_version >= CRIS_CPU_V32)
 
 /* Node: Storage Layout */
 
@@ -482,26 +322,10 @@ extern int target_flags;
 
 #define UNITS_PER_WORD 4
 
-/* A combination of defining PROMOTE_MODE, PROMOTE_FUNCTION_ARGS,
-   PROMOTE_FOR_CALL_ONLY and *not* defining PROMOTE_PROTOTYPES gives the
-   best code size and speed for gcc, ipps and products in gcc-2.7.2.  */
 #define CRIS_PROMOTED_MODE(MODE, UNSIGNEDP, TYPE) \
  (GET_MODE_CLASS (MODE) == MODE_INT && GET_MODE_SIZE (MODE) < 4) \
   ? SImode : MODE
 
-#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)  \
-  (MODE) = CRIS_PROMOTED_MODE (MODE, UNSIGNEDP, TYPE)
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovers bug 981110 (even
-   if defining FUNCTION_VALUE with MODE as PROMOTED_MODE ;-)
-
-   FIXME: Report this when cris.h is part of GCC, so others can easily
-   see the problem.  Maybe check other systems that define
-   PROMOTE_FUNCTION_RETURN.  */
-#define PROMOTE_FOR_CALL_ONLY
-
 /* We will be using prototype promotion, so they will be 32 bit.  */
 #define PARM_BOUNDARY 32
 
@@ -573,8 +397,6 @@ extern int target_flags;
 /* For compatibility and historical reasons, a char should be signed.  */
 #define DEFAULT_SIGNED_CHAR 1
 
-/* No DEFAULT_SHORT_ENUMS, please.  */
-
 /* Note that WCHAR_TYPE_SIZE is used in cexp.y,
    where TARGET_SHORT is not available.  */
 #undef WCHAR_TYPE
@@ -586,9 +408,9 @@ extern int target_flags;
 
 /* Node: Register Basics */
 
-/*  We count all 16 non-special registers, SRP and a faked argument
-    pointer register.  */
-#define FIRST_PSEUDO_REGISTER (16 + 1 + 1)
+/*  We count all 16 non-special registers, SRP, a faked argument
+    pointer register, MOF and CCR/DCCR.  */
+#define FIRST_PSEUDO_REGISTER (16 + 1 + 1 + 1 + 1)
 
 /* For CRIS, these are r15 (pc) and r14 (sp). Register r8 is used as a
    frame-pointer, but is not fixed.  SRP is not included in general
@@ -596,15 +418,12 @@ extern int target_flags;
    registers are fixed at the moment.  The faked argument pointer register
    is fixed too.  */
 #define FIXED_REGISTERS \
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1}
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0}
 
 /* Register r9 is used for structure-address, r10-r13 for parameters,
    r10- for return values.  */
 #define CALL_USED_REGISTERS \
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}
-
-#define CONDITIONAL_REGISTER_USAGE cris_conditional_register_usage ()
-
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}
 
 /* Node: Allocation Order */
 
@@ -627,7 +446,14 @@ extern int target_flags;
     Use struct-return address first, since very few functions use
    structure return values so it is likely to be available.  */
 #define REG_ALLOC_ORDER \
- {9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17}
+ {9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 17, 16, 18, 19}
+
+/* Use MOF and ACR.  Prefer ACR before any other register.  Prefer MOF
+   then SRP after saved registers.  The *after* is because they're only
+   useful for storage, not for things being computed, which is
+   apparently more common.  */
+#define REG_ALLOC_ORDER_V32 \
+ {15, 9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 17, 16, 14, 18, 19}
 
 
 /* Node: Values in Registers */
@@ -638,10 +464,19 @@ extern int target_flags;
  (MODE == VOIDmode \
   ? 1 : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
-/* CRIS permits all registers to hold all modes.  */
-#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+/* CRIS permits all registers to hold all modes.  Well, except for the
+   condition-code register.  And we can't hold larger-than-register size
+   modes in the last special register that can hold a full 32 bits.  */
+#define HARD_REGNO_MODE_OK(REGNO, MODE)                \
+ (((MODE) == CCmode                            \
+   || (REGNO) != CRIS_CC0_REGNUM)              \
+  && (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD   \
+      || ((REGNO) != CRIS_MOF_REGNUM && (REGNO) != CRIS_ACR_REGNUM)))
 
-#define MODES_TIEABLE_P(MODE1, MODE2)  1
+/* Because CCmode isn't covered by the "narrower mode" statement in
+   tm.texi, we can still say all modes are tieable despite not having an
+   always 1 HARD_REGNO_MODE_OK.  */
+#define MODES_TIEABLE_P(MODE1, MODE2) 1
 
 
 /* Node: Leaf Functions */
@@ -653,32 +488,77 @@ extern int target_flags;
 
 /* Node: Register Classes */
 
-/* CRIS has only one kind of registers, so NO_REGS and ALL_REGS
-   are the only classes.  FIXME: It actually makes sense to have another
-   class for special registers, and yet another class for the
-   multiply-overflow register in v10; then a class for the return
-   register also makes sense.  */
-enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
+/* FIXME: A separate class for the return register would make sense.
+
+   We need a separate register class to handle register allocation for
+   ACR, since it can't be used for post-increment.
+
+   It's not obvious, but having subunions of all movable-between
+   register classes does really help register allocation.  */
+enum reg_class
+  {
+    NO_REGS,
+    ACR_REGS, MOF_REGS, CC0_REGS, SPECIAL_REGS,
+    SPEC_ACR_REGS, GENNONACR_REGS,
+    SPEC_GENNONACR_REGS, GENERAL_REGS,
+    ALL_REGS,
+    LIM_REG_CLASSES
+  };
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
-#define REG_CLASS_NAMES {"NO_REGS", "ALL_REGS"}
+#define REG_CLASS_NAMES                                                \
+  {"NO_REGS",                                                  \
+   "ACR_REGS", "MOF_REGS", "CC0_REGS", "SPECIAL_REGS",         \
+   "SPEC_ACR_REGS", "GENNONACR_REGS", "SPEC_GENNONACR_REGS",   \
+   "GENERAL_REGS", "ALL_REGS"}
 
-#define GENERAL_REGS ALL_REGS
+#define CRIS_SPECIAL_REGS_CONTENTS                                     \
+ ((1 << CRIS_SRP_REGNUM) | (1 << CRIS_MOF_REGNUM) | (1 << CRIS_CC0_REGNUM))
 
 /* Count in the faked argument register in GENERAL_REGS.  Keep out SRP.  */
-#define REG_CLASS_CONTENTS {{0}, {0x2ffff}}
-
-#define REGNO_REG_CLASS(REGNO) GENERAL_REGS
+#define REG_CLASS_CONTENTS                     \
+  {                                            \
+   {0},                                                \
+   {1 << CRIS_ACR_REGNUM},                     \
+   {1 << CRIS_MOF_REGNUM},                     \
+   {1 << CRIS_CC0_REGNUM},                     \
+   {CRIS_SPECIAL_REGS_CONTENTS},               \
+   {CRIS_SPECIAL_REGS_CONTENTS                 \
+    | (1 << CRIS_ACR_REGNUM)},                 \
+   {(0xffff | (1 << CRIS_AP_REGNUM))           \
+    & ~(1 << CRIS_ACR_REGNUM)},                        \
+   {(0xffff | (1 << CRIS_AP_REGNUM)            \
+    | CRIS_SPECIAL_REGS_CONTENTS)              \
+    & ~(1 << CRIS_ACR_REGNUM)},                        \
+   {0xffff | (1 << CRIS_AP_REGNUM)},           \
+   {0xffff | (1 << CRIS_AP_REGNUM)             \
+    | CRIS_SPECIAL_REGS_CONTENTS}              \
+  }
+
+#define REGNO_REG_CLASS(REGNO)                 \
+  ((REGNO) == CRIS_ACR_REGNUM ? ACR_REGS :     \
+   (REGNO) == CRIS_MOF_REGNUM ? MOF_REGS :     \
+   (REGNO) == CRIS_CC0_REGNUM ? CC0_REGS :     \
+   (REGNO) == CRIS_SRP_REGNUM ? SPECIAL_REGS : \
+   GENERAL_REGS)
 
 #define BASE_REG_CLASS GENERAL_REGS
 
+#define MODE_CODE_BASE_REG_CLASS(MODE, OCODE, ICODE)   \
+  ((OCODE) != POST_INC ? BASE_REG_CLASS : GENNONACR_REGS)
+
 #define INDEX_REG_CLASS GENERAL_REGS
 
-/* Get reg_class from a letter such as appears in the machine
-   description.  No letters are used, since 'r' is used for any
-   register.  */
-#define REG_CLASS_FROM_LETTER(C) NO_REGS
+#define REG_CLASS_FROM_LETTER(C)               \
+  (                                            \
+   (C) == 'a' ? ACR_REGS :                     \
+   (C) == 'b' ? GENNONACR_REGS :               \
+   (C) == 'h' ? MOF_REGS :                     \
+   (C) == 'x' ? SPECIAL_REGS :                 \
+   (C) == 'c' ? CC0_REGS :                     \
+   NO_REGS                                     \
+  )
 
 /* Since it uses reg_renumber, it is safe only once reg_renumber
    has been allocated, which happens in local-alloc.c.  */
@@ -688,15 +568,49 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
   || (unsigned) reg_renumber[REGNO] <= CRIS_LAST_GENERAL_REGISTER      \
   || (unsigned) reg_renumber[REGNO] == ARG_POINTER_REGNUM)
 
+/* REGNO_OK_FOR_BASE_P seems to be obsolete wrt. this one, but not yet
+   documented as such.  */
+#define REGNO_MODE_CODE_OK_FOR_BASE_P(REGNO, MODE, OCODE, ICODE)       \
+ (REGNO_OK_FOR_BASE_P (REGNO)                                          \
+  && ((OCODE) != POST_INC                                              \
+      || !((REGNO) == CRIS_ACR_REGNUM                                  \
+          || (unsigned) reg_renumber[REGNO] == CRIS_ACR_REGNUM)))
+
 /* See REGNO_OK_FOR_BASE_P.  */
 #define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO)
 
 /* It seems like gcc (2.7.2 and 2.9x of 2000-03-22) may send "NO_REGS" as
    the class for a constant (testcase: __Mul in arit.c).  To avoid forcing
    out a constant into the constant pool, we will trap this case and
-   return something a bit more sane.  FIXME: Check if this is a bug.  */
-#define PREFERRED_RELOAD_CLASS(X, CLASS) \
- ((CLASS) == NO_REGS ? GENERAL_REGS : (CLASS))
+   return something a bit more sane.  FIXME: Check if this is a bug.
+   Beware that we must not "override" classes that can be specified as
+   constraint letters, or else asm operands using them will fail when
+   they need to be reloaded.  FIXME: Investigate whether that constitutes
+   a bug.  */
+#define PREFERRED_RELOAD_CLASS(X, CLASS)       \
+ ((CLASS) != ACR_REGS                          \
+  && (CLASS) != MOF_REGS                       \
+  && (CLASS) != CC0_REGS                       \
+  && (CLASS) != SPECIAL_REGS                   \
+  ? GENERAL_REGS : (CLASS))
+
+/* We can't move special registers to and from memory in smaller than
+   word_mode.  We also can't move between special registers.  Luckily,
+   -1, as returned by true_regnum for non-sub/registers, is valid as a
+   parameter to our REGNO_REG_CLASS, returning GENERAL_REGS, so we get
+   the effect that any X that isn't a special-register is treated as
+   a non-empty intersection with GENERAL_REGS.  */
+#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X)                         \
+ ((((CLASS) == SPECIAL_REGS || (CLASS) == MOF_REGS)                    \
+   && ((GET_MODE_SIZE (MODE) < 4 && MEM_P (X))                         \
+       || !reg_classes_intersect_p (REGNO_REG_CLASS (true_regnum (X)), \
+                                   GENERAL_REGS)))                     \
+   ? GENERAL_REGS : NO_REGS)
+
+/* FIXME: Fix regrename.c; it should check validity of replacements,
+   not just with a silly pass-specific macro.  We may miss some
+   opportunities, but we must stop regrename from creating acr++.  */
+#define HARD_REGNO_RENAME_OK(FROM, TO) ((TO) != CRIS_ACR_REGNUM)
 
 /* For CRIS, this is always the size of MODE in words,
    since all registers are the same size.  To use omitted modes in
@@ -712,7 +626,7 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 
 /* We are now out of letters; we could use ten more.  This forces us to
    use C-code in the 'md' file.  FIXME: Use some EXTRA_CONSTRAINTS.  */
-#define CONST_OK_FOR_LETTER_P(VALUE, C)                        \
+#define CRIS_CONST_OK_FOR_LETTER_P(VALUE, C)           \
  (                                                     \
   /* MOVEQ, CMPQ, ANDQ, ORQ.  */                       \
   (C) == 'I' ? (VALUE) >= -32 && (VALUE) <= 31 :       \
@@ -735,6 +649,16 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
   (C) == 'P' ? (VALUE) >= -32768 && (VALUE) <= 65535 : \
   0)
 
+#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, S) \
+ (                                             \
+  ((C) != 'K' || (S)[1] == 'c')                        \
+   ? CRIS_CONST_OK_FOR_LETTER_P (VALUE, C) :   \
+  ((C) == 'K' && (S)[1] == 'p')                        \
+   ? exact_log2 (VALUE) >= 0 :                 \
+  0)
+
+#define CONSTRAINT_LEN(C, S) ((C) == 'K' ? 2 : DEFAULT_CONSTRAINT_LEN (C, S))
+
 /* It is really simple to make up a 0.0; it is the same as int-0 in
    IEEE754.  */
 #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)                 \
@@ -752,18 +676,18 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
   (C) == 'S' ? EXTRA_CONSTRAINT_S (X) :                \
   /* A three-address addressing-mode?  */      \
   (C) == 'T' ? EXTRA_CONSTRAINT_T (X) :                \
-  /* A global PIC symbol?  */                  \
+  /* A PLT symbol?  */                         \
   (C) == 'U' ? EXTRA_CONSTRAINT_U (X) :                \
   0)
 
+#define EXTRA_MEMORY_CONSTRAINT(X, STR) ((X) == 'Q')
+
 #define EXTRA_CONSTRAINT_Q(X)                          \
  (                                                     \
-  /* Slottable addressing modes:                       \
-     A register?  FIXME: Unnecessary.  */              \
-  (BASE_P (X) && REGNO (X) != CRIS_PC_REGNUM)          \
-  /* Indirect register: [reg]?  */                     \
-  || (GET_CODE (X) == MEM && BASE_P (XEXP (X, 0))      \
-      && REGNO (XEXP (X, 0)) != CRIS_PC_REGNUM)                \
+  /* Just an indirect register (happens to also be     \
+     "all" slottable memory addressing modes not       \
+     covered by other constraints, i.e. '>').  */      \
+  MEM_P (X) && BASE_P (XEXP (X, 0))                    \
  )
 
 #define EXTRA_CONSTRAINT_R(X)                                  \
@@ -779,8 +703,8 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 #define EXTRA_CONSTRAINT_T(X)                                          \
  (                                                                     \
   /* Memory three-address operand.  All are indirect-memory:  */       \
-  GET_CODE (X) == MEM                                                  \
-  && ((GET_CODE (XEXP (X, 0)) == MEM                                   \
+  MEM_P (X)                                                            \
+  && ((MEM_P (XEXP (X, 0))                                             \
        /* Double indirect: [[reg]] or [[reg+]]?  */                    \
        && (BASE_OR_AUTOINCR_P (XEXP (XEXP (X, 0), 0))))                        \
       /* Just an explicit indirect reference: [const]?  */             \
@@ -790,34 +714,33 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
          /* A BDAP constant: [reg+(8|16|32)bit offset]?  */            \
          && ((BASE_P (XEXP (XEXP (X, 0), 0))                           \
               && CONSTANT_INDEX_P (XEXP (XEXP (X, 0), 1)))             \
-             /* Swap arguments to the above.  FIXME: gcc-2.9x? */      \
-             || (BASE_P (XEXP (XEXP (X, 0), 1))                        \
-                 && CONSTANT_INDEX_P (XEXP (XEXP (X, 0), 0)))          \
              /* A BDAP register: [reg+[reg(+)].S]?  */                 \
              || (BASE_P (XEXP (XEXP (X, 0), 0))                        \
                  && BDAP_INDEX_P(XEXP(XEXP(X, 0), 1)))                 \
-             /* Same, but with swapped arguments.  */                  \
+             /* Same, but with swapped arguments (no canonical         \
+                ordering between e.g. REG and MEM as of LAST_UPDATED   \
+                "Thu May 12 03:59:11 UTC 2005").  */                   \
              || (BASE_P (XEXP (XEXP (X, 0), 1))                        \
                  && BDAP_INDEX_P (XEXP (XEXP (X, 0), 0)))              \
-             /* A BIAP: [reg+reg.S].  */                               \
-             || (BASE_P (XEXP (XEXP (X, 0), 0))                        \
-                 && BIAP_INDEX_P (XEXP (XEXP (X, 0), 1)))              \
-             /* Same, but with swapped arguments.  */                  \
+             /* A BIAP: [reg+reg.S] (MULT comes first).  */            \
              || (BASE_P (XEXP (XEXP (X, 0), 1))                        \
                  && BIAP_INDEX_P (XEXP (XEXP (X, 0), 0))))))           \
  )
 
-#define EXTRA_CONSTRAINT_S(X) \
- (flag_pic && CONSTANT_P (X) && cris_gotless_symbol (X))
+/* PIC-constructs for symbols.  */
+#define EXTRA_CONSTRAINT_S(X)                                          \
+ (flag_pic && GET_CODE (X) == CONST && cris_valid_pic_const (X, false))
 
-#define EXTRA_CONSTRAINT_U(X) \
- (flag_pic && CONSTANT_P (X) && cris_got_symbol (X))
+#define EXTRA_CONSTRAINT_U(X)                                          \
+ (flag_pic                                                             \
+  && CONSTANT_P (X)                                                    \
+  && cris_nonmemory_operand_or_callable_symbol (X, VOIDmode))
 
 
 /* Node: Frame Layout */
 
 #define STACK_GROWS_DOWNWARD
-#define FRAME_GROWS_DOWNWARD
+#define FRAME_GROWS_DOWNWARD 1
 
 /* It seems to be indicated in the code (at least 2.1) that this is
    better a constant, and best 0.  */
@@ -828,7 +751,7 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 #define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
  cris_return_addr_rtx (COUNT, FRAMEADDR)
 
-#define INCOMING_RETURN_ADDR_RTX gen_rtx (REG, Pmode, CRIS_SRP_REGNUM)
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, CRIS_SRP_REGNUM)
 
 /* FIXME: Any __builtin_eh_return callers must not return anything and
    there must not be collisions with incoming parameters.  Luckily the
@@ -838,7 +761,7 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
   (IN_RANGE ((N), 0, 3) ? (CRIS_FIRST_ARG_REG + 3 - (N)) : INVALID_REGNUM)
 
 /* Store the stack adjustment in the structure-return-address register.  */
-#define CRIS_STACKADJ_REG STRUCT_VALUE_REGNUM
+#define CRIS_STACKADJ_REG CRIS_STRUCT_VALUE_REGNUM
 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (SImode, CRIS_STACKADJ_REG)
 
 #define EH_RETURN_HANDLER_RTX \
@@ -856,7 +779,7 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 
 /* If we would ever need an exact mapping between canonical register
    number and dwarf frame register, we would either need to include all
-   registers in the gcc decription (with some marked fixed of course), or
+   registers in the gcc description (with some marked fixed of course), or
    an inverse mapping from dwarf register to gcc register.  There is one
    need in dwarf2out.c:expand_builtin_init_dwarf_reg_sizes.  Right now, I
    don't see that we need exact correspondence between DWARF *frame*
@@ -868,34 +791,26 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 
 /* Node: Frame Registers */
 
-#define STACK_POINTER_REGNUM 14
+#define STACK_POINTER_REGNUM CRIS_SP_REGNUM
 
 /* Register used for frame pointer.  This is also the last of the saved
    registers, when a frame pointer is not used.  */
-#define FRAME_POINTER_REGNUM 8
+#define FRAME_POINTER_REGNUM CRIS_FP_REGNUM
 
 /* Faked register, is always eliminated.  We need it to eliminate
    allocating stack slots for the return address and the frame pointer.  */
-#define ARG_POINTER_REGNUM 17
+#define ARG_POINTER_REGNUM CRIS_AP_REGNUM
 
-#define STATIC_CHAIN_REGNUM 7
+#define STATIC_CHAIN_REGNUM CRIS_STATIC_CHAIN_REGNUM
 
 
 /* Node: Elimination */
 
-/* Really only needed if the stack frame has variable length (alloca
-   or variable sized local arguments (GNU C extension).  */
-#define FRAME_POINTER_REQUIRED 0
-
 #define ELIMINABLE_REGS                                \
  {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},  \
   {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},  \
   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
 
-/* We need not worry about when the frame-pointer is required for other
-   reasons.  */
-#define CAN_ELIMINATE(FROM, TO) 1
-
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
  (OFFSET) = cris_initial_elimination_offset (FROM, TO)
 
@@ -903,50 +818,15 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 /* Node: Stack Arguments */
 
 /* Since many parameters take up one register each in any case,
-   PROMOTE_PROTOTYPES would seem like a good idea, but measurements
-   indicate that a combination using PROMOTE_MODE is better.  */
+   defining TARGET_PROMOTE_PROTOTYPES that always returns true would
+   seem like a good idea, but measurements indicate that a combination
+   using PROMOTE_MODE is better.  */
 
 #define ACCUMULATE_OUTGOING_ARGS 1
 
-#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACKSIZE) 0
-
 
 /* Node: Register Arguments */
 
-/* The void_type_node is sent as a "closing" call.  We have to stop it
-   since it's invalid to FUNCTION_ARG_PASS_BY_REFERENCE (or was invalid at
-   some time).  */
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)                   \
- ((CUM).regs < CRIS_MAX_ARGS_IN_REGS                           \
-  && (TYPE) != void_type_node                                  \
-  && ! FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED) \
-  ? gen_rtx (REG, MODE, (CRIS_FIRST_ARG_REG) + (CUM).regs)     \
-  : NULL_RTX)
-
-/* The differences between this and the previous, is that this one checks
-   that an argument is named, since incoming stdarg/varargs arguments are
-   pushed onto the stack, and we don't have to check against the "closing"
-   void_type_node TYPE parameter.  */
-#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED)                  \
- (((NAMED) && (CUM).regs < CRIS_MAX_ARGS_IN_REGS                       \
-   && ! FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED))       \
-  ? gen_rtx (REG, MODE, CRIS_FIRST_ARG_REG + (CUM).regs)               \
-  : NULL_RTX)
-
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)     \
- (((CUM).regs == (CRIS_MAX_ARGS_IN_REGS - 1)                   \
-   && !MUST_PASS_IN_STACK (MODE, TYPE)                         \
-   && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 4                  \
-   && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) <= 8)                        \
-  ? 1 : 0)
-
-/* Structs may be passed by value, but they must not be more than 8
-   bytes long.  If you tweak this, don't forget to adjust
-   cris_expand_builtin_va_arg.  */
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)         \
- (MUST_PASS_IN_STACK (MODE, TYPE)                                      \
-  || CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 8)                          \
-
 /* Contrary to what you'd believe, defining FUNCTION_ARG_CALLEE_COPIES
    seems like a (small total) loss, at least for gcc-2.7.2 compiling and
    running gcc-2.1 (small win in size, small loss running -- 100.1%),
@@ -961,16 +841,9 @@ struct cum_args {int regs;};
 
 /* The regs member is an integer, the number of arguments got into
    registers so far.  */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL)       \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
  ((CUM).regs = 0)
 
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)           \
- ((CUM).regs                                                   \
-  = (FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)    \
-     ? (CRIS_MAX_ARGS_IN_REGS) + 1                             \
-     : ((CUM).regs                                             \
-       + (3 + (CRIS_FUNCTION_ARG_SIZE (MODE, TYPE))) / 4)))
-
 #define FUNCTION_ARG_REGNO_P(REGNO)                    \
  ((REGNO) >= CRIS_FIRST_ARG_REG                                \
   && (REGNO) < CRIS_FIRST_ARG_REG + (CRIS_MAX_ARGS_IN_REGS))
@@ -978,27 +851,13 @@ struct cum_args {int regs;};
 
 /* Node: Scalar Return */
 
-/* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the
-   time being.  */
-#define FUNCTION_VALUE(VALTYPE, FUNC)  \
- gen_rtx (REG, TYPE_MODE (VALTYPE), CRIS_FIRST_ARG_REG)
-
-#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, CRIS_FIRST_ARG_REG)
+#define FUNCTION_VALUE_REGNO_P(N) cris_function_value_regno_p (N)
 
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == CRIS_FIRST_ARG_REG)
 
 
 /* Node: Aggregate Return */
 
-#if 0
-/* FIXME: Let's try this some time, so we return structures in registers.
-   We would cast the result of int_size_in_bytes to unsigned, so we will
-   get a huge number for "structures" of variable size (-1).  */
-#define RETURN_IN_MEMORY(TYPE) \
- ((unsigned) int_size_in_bytes (TYPE) > CRIS_MAX_ARGS_IN_REGS * UNITS_PER_WORD)
-#endif
-
-#define STRUCT_VALUE_REGNUM ((CRIS_FIRST_ARG_REG) - 1)
+#define CRIS_STRUCT_VALUE_REGNUM ((CRIS_FIRST_ARG_REG) - 1)
 
 
 /* Node: Caller Saves */
@@ -1009,13 +868,6 @@ struct cum_args {int regs;};
 /* See cris.c for TARGET_ASM_FUNCTION_PROLOGUE and
    TARGET_ASM_FUNCTION_EPILOGUE.  */
 
-/* If the epilogue uses the "ret" insn, we need to fill the
-   delay slot.  */
-#define DELAY_SLOTS_FOR_EPILOGUE cris_delay_slots_for_epilogue ()
-
-#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN, N) \
-  cris_eligible_for_epilogue_delay (INSN)
-
 /* Node: Profiling */
 
 #define FUNCTION_PROFILER(FILE, LABELNO)  \
@@ -1025,92 +877,15 @@ struct cum_args {int regs;};
    documentation.  */
 
 
-/* Node: Varargs */
-
-/* We save the register number of the first anonymous argument in
-   first_vararg_reg, and take care of this in the function prologue.
-   This behavior is used by at least one more port (the ARM?), but
-   may be unsafe when compiling nested functions.  (With varargs? Hairy.)
-   Note that nested-functions is a GNU C extension.
-
-   FIXME: We can actually put the size in PRETEND and deduce the number
-   of registers from it in the prologue and epilogue.  */
-#define SETUP_INCOMING_VARARGS(ARGSSF, MODE, TYPE, PRETEND, SECOND)    \
-  do                                                                   \
-    {                                                                  \
-      if ((ARGSSF).regs < (CRIS_MAX_ARGS_IN_REGS))                     \
-       (PRETEND) = ((CRIS_MAX_ARGS_IN_REGS) - (ARGSSF).regs) * 4;      \
-      if (TARGET_PDEBUG)                                               \
-       {                                                               \
-         fprintf (asm_out_file,                                        \
-                  "\n; VA:: ANSI: %d args before, anon @ #%d, %dtime\n", \
-                  (ARGSSF).regs, PRETEND, SECOND);                     \
-       }                                                               \
-    }                                                                  \
-  while (0)
-
-/* FIXME: This and other EXPAND_BUILTIN_VA_... target macros are not
-   documented, although used by several targets.  */
-#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \
- cris_expand_builtin_va_arg (VALIST, TYPE)
-
-
 /* Node: Trampolines */
 
-/* This looks too complicated, and it is.  I assigned r7 to be the
-   static chain register, but it is call-saved, so we have to save it,
-   and come back to restore it after the call, so we have to save srp...
-   Anyway, trampolines are rare enough that we can cope with this
-   somewhat lack of elegance.
-    (Do not be tempted to "straighten up" whitespace in the asms; the
-   assembler #NO_APP state mandates strict spacing).  */
-#define TRAMPOLINE_TEMPLATE(FILE)              \
-  do                                           \
-    {                                          \
-      fprintf (FILE, "\tmove.d $%s,[$pc+20]\n",        \
-              reg_names[STATIC_CHAIN_REGNUM]); \
-      fprintf (FILE, "\tmove $srp,[$pc+22]\n");        \
-      fprintf (FILE, "\tmove.d 0,$%s\n",       \
-              reg_names[STATIC_CHAIN_REGNUM]); \
-      fprintf (FILE, "\tjsr 0\n");             \
-      fprintf (FILE, "\tmove.d 0,$%s\n",       \
-              reg_names[STATIC_CHAIN_REGNUM]); \
-      fprintf (FILE, "\tjump 0\n");            \
-    }                                          \
-  while (0)
-
-#define TRAMPOLINE_SIZE 32
+#define TRAMPOLINE_SIZE (TARGET_V32 ? 58 : 32)
 
-/* CRIS wants instructions on word-boundary.
-   Note that due to a bug (reported) in 2.7.2 and earlier, this is
-   actually treated as alignment in _bytes_, not _bits_.  (Obviously
-   this is not fatal, only a slight waste of stack space).  */
+/* CRIS wants instructions on word-boundary.  */
 #define TRAMPOLINE_ALIGNMENT 16
 
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)              \
-  do                                                           \
-    {                                                          \
-      emit_move_insn (gen_rtx (MEM, SImode,                    \
-                              plus_constant (TRAMP, 10)),      \
-                     CXT);                                     \
-      emit_move_insn (gen_rtx (MEM, SImode,                    \
-                              plus_constant (TRAMP, 16)),      \
-                     FNADDR);                                  \
-    }                                                          \
-  while (0)
-
-/* Note that there is no need to do anything with the cache for sake of
-   a trampoline.  */
-
-
 /* Node: Library Calls */
 
-#define MULSI3_LIBCALL "__Mul"
-#define DIVSI3_LIBCALL "__Div"
-#define UDIVSI3_LIBCALL "__Udiv"
-#define MODSI3_LIBCALL "__Mod"
-#define UMODSI3_LIBCALL "__Umod"
-
 /* If you change this, you have to check whatever libraries and systems
    that use it.  */
 #define TARGET_EDOM 33
@@ -1120,8 +895,8 @@ struct cum_args {int regs;};
 
 #define HAVE_POST_INCREMENT 1
 
-#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
-
+/* Must be a compile-time constant, so we go with the highest value
+   among all CRIS variants.  */
 #define MAX_REGS_PER_ADDRESS 2
 
 /* There are helper macros defined here which are used only in
@@ -1138,22 +913,25 @@ struct cum_args {int regs;};
 /* No symbol can be used as an index (or more correct, as a base) together
    with a register with PIC; the PIC register must be there.  */
 #define CONSTANT_INDEX_P(X) \
- (CONSTANT_P (X) && !(flag_pic && cris_symbol (X)))
+ (CONSTANT_P (X) && (!flag_pic || cris_valid_pic_const (X, true)))
 
 /* True if X is a valid base register.  */
 #define BASE_P(X) \
  (REG_P (X) && REG_OK_FOR_BASE_P (X))
 
 /* True if X is a valid base register with or without autoincrement.  */
-#define BASE_OR_AUTOINCR_P(X) \
- (BASE_P (X) || (GET_CODE (X) == POST_INC && BASE_P (XEXP (X, 0))))
+#define BASE_OR_AUTOINCR_P(X)                          \
+ (BASE_P (X)                                           \
+  || (GET_CODE (X) == POST_INC                         \
+      && BASE_P (XEXP (X, 0))                          \
+      && REGNO (XEXP (X, 0)) != CRIS_ACR_REGNUM))
 
 /* True if X is a valid (register) index for BDAP, i.e. [Rs].S or [Rs+].S.  */
 #define BDAP_INDEX_P(X)                                        \
- ((GET_CODE (X) == MEM && GET_MODE (X) == SImode       \
+ ((MEM_P (X) && GET_MODE (X) == SImode                 \
    && BASE_OR_AUTOINCR_P (XEXP (X, 0)))                        \
   || (GET_CODE (X) == SIGN_EXTEND                      \
-      && GET_CODE (XEXP (X, 0)) == MEM                 \
+      && MEM_P (XEXP (X, 0))                           \
       && (GET_MODE (XEXP (X, 0)) == HImode             \
          || GET_MODE (XEXP (X, 0)) == QImode)          \
       && BASE_OR_AUTOINCR_P (XEXP (XEXP (X, 0), 0))))
@@ -1164,16 +942,10 @@ struct cum_args {int regs;};
   || (GET_CODE (X) == MULT                     \
       && BASE_P (XEXP (X, 0))                  \
       && REG_OK_FOR_INDEX_P (XEXP (X, 0))      \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT   \
+      && CONST_INT_P (XEXP (X, 1))             \
       && (INTVAL (XEXP (X, 1)) == 2            \
          || INTVAL (XEXP (X, 1)) == 4)))
 
-/* True if X is an address that doesn't need a prefix i.e. [Rs] or [Rs+].  */
-#define SIMPLE_ADDRESS_P(X) \
- (BASE_P (X)                                           \
-  || (GET_CODE (X) == POST_INC                         \
-      && BASE_P (XEXP (X, 0))))
-
 /* A PIC operand looks like a normal symbol here.  At output we dress it
    in "[rPIC+symbol:GOT]" (global symbol) or "rPIC+symbol:GOTOFF" (local
    symbol) so we exclude all addressing modes where we can't replace a
@@ -1183,15 +955,15 @@ struct cum_args {int regs;};
 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                        \
  {                                                             \
    rtx x1, x2;                                                 \
-   if (SIMPLE_ADDRESS_P (X))                                   \
+   if (BASE_OR_AUTOINCR_P (X))                                 \
      goto ADDR;                                                        \
-   if (CONSTANT_P (X)                                          \
-       && (! flag_pic                                          \
-          || cris_gotless_symbol (X)                           \
-          || ! cris_symbol (X)))                               \
+   else if (TARGET_V32)                                                \
+     /* Nothing else is valid then.  */                                \
+     ;                                                         \
+   else if (CONSTANT_INDEX_P (X))                              \
      goto ADDR;                                                        \
    /* Indexed?  */                                             \
-   if (GET_CODE (X) == PLUS)                                   \
+   else if (GET_CODE (X) == PLUS)                              \
      {                                                         \
        x1 = XEXP (X, 0);                                       \
        x2 = XEXP (X, 1);                                       \
@@ -1207,7 +979,7 @@ struct cum_args {int regs;};
                   || (BASE_P (x2) && BIAP_INDEX_P (x1)))))     \
         goto ADDR;                                             \
      }                                                         \
-   else if (GET_CODE (X) == MEM)                               \
+   else if (MEM_P (X))                                         \
      {                                                         \
        /* DIP (Rs).  Reject [[reg+]] and [[reg]] for           \
          DImode (long long).  */                               \
@@ -1239,92 +1011,15 @@ struct cum_args {int regs;};
 # define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
 #endif
 
-/* For now, don't do anything.  GCC does a good job most often.
-
-    Maybe we could do something about gcc:s misbehavior when it
-   recalculates frame offsets for local variables, from fp+offs to
-   sp+offs.  The resulting address expression gets screwed up
-   sometimes, but I'm not sure that it may be fixed here, since it is
-   already split up in several instructions (Is this still true?).
-   FIXME: Check and adjust for gcc-2.9x.  */
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {}
-
-/* Kludge to solve Axis-990219: Work around imperfection in
-   reload_load_address1:
-    (plus (sign_extend (mem:qi (reg))) (reg))
-   should be reloaded as (plus (reg) (reg)), not
-    (plus (sign_extend (reg)) (reg)).
-   There are no checks that reload_load_address_1 "reloads"
-   addresses correctly, so invalidness is not caught or
-   corrected.
-    When the right thing happens in reload, the kludge can
-   be removed; still not as of 2003-02-27.  */
-
-#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
+/* Fix reloads known to cause suboptimal spilling.  */
+#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN)     \
   do                                                                   \
     {                                                                  \
-      if (GET_CODE (X) == PLUS                                         \
-         && REG_P (XEXP (X, 1))                                        \
-         && GET_CODE (XEXP (X, 0)) == SIGN_EXTEND                      \
-         && GET_CODE (XEXP (XEXP (X, 0), 0)) == MEM                    \
-         && (GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode                \
-             || GET_MODE (XEXP (XEXP (X, 0), 0)) == QImode)            \
-         && (REG_P (XEXP (XEXP (XEXP (X, 0), 0), 0))                   \
-             || (GET_CODE (XEXP (XEXP (XEXP (X, 0), 0), 0))            \
-                 == POST_INC                                           \
-                 && REG_P (XEXP (XEXP (XEXP (XEXP (X, 0), 0), 0),      \
-                                 0)))))                                \
-       {                                                               \
-         int something_reloaded = 0;                                   \
-                                                                       \
-         if (REGNO (XEXP (X, 1)) >= FIRST_PSEUDO_REGISTER)             \
-           {                                                           \
-             /* Second reg is pseudo, reload it.  */                   \
-             push_reload (XEXP (X, 1), NULL_RTX, &XEXP (X, 1),         \
-                          NULL,                                        \
-                          GENERAL_REGS, GET_MODE (X), VOIDmode, 0, 0,  \
-                          OPNUM, TYPE);                                \
-             something_reloaded = 1;                                   \
-           }                                                           \
-                                                                       \
-         if (REG_P (XEXP (XEXP (XEXP (X, 0), 0), 0))                   \
-             && (REGNO (XEXP (XEXP (XEXP (X, 0), 0), 0))               \
-                 >= FIRST_PSEUDO_REGISTER))                            \
-           {                                                           \
-             /* First one is a pseudo - reload that.  */               \
-             push_reload (XEXP (XEXP (XEXP (X, 0), 0), 0), NULL_RTX,   \
-                          &XEXP (XEXP (XEXP (X, 0), 0), 0), NULL,      \
-                          GENERAL_REGS,                                \
-                          GET_MODE (X), VOIDmode, 0, 0, OPNUM, TYPE);  \
-             something_reloaded = 1;                                   \
-           }                                                           \
-                                                                       \
-         if (! something_reloaded                                      \
-             || (GET_CODE (XEXP (XEXP (X, 0), 0)) == POST_INC          \
-                 && (REGNO (XEXP (XEXP (XEXP (X, 0), 0), 0))           \
-                     >= FIRST_PSEUDO_REGISTER)))                       \
-           /* Reload the sign_extend.  Happens if neither reg is a     \
-              pseudo, or the first one was inside post_increment.  */  \
-           push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,     \
-                        GENERAL_REGS, GET_MODE (X), VOIDmode, 0, 0,    \
-                        OPNUM, TYPE);                                  \
-         goto WIN;                                                     \
-       }                                                               \
+      if (cris_reload_address_legitimized (X, MODE, OPNUM, TYPE, INDL))        \
+       goto WIN;                                                       \
     }                                                                  \
   while (0)
 
-/* In CRIS, only the postincrement address mode depends thus,
-   since the increment depends on the size of the operand.  */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)      \
-  do                                                   \
-    {                                                  \
-      if (GET_CODE (ADDR) == POST_INC)                 \
-       goto LABEL;                                     \
-    }                                                  \
-  while (0)
-
-#define LEGITIMATE_CONSTANT_P(X) 1
-
 
 /* Node: Condition Code */
 
@@ -1337,14 +1032,6 @@ struct cum_args {int regs;};
 
 /* Node: Costs */
 
-/* FIXME: Need to define REGISTER_MOVE_COST when more register classes are
-   introduced.  */
-
-/* This isn't strictly correct for v0..3 in buswidth-8bit mode, but
-   should suffice.  */
-#define MEMORY_MOVE_COST(M, CLASS, IN) \
- (((M) == QImode) ? 4 : ((M) == HImode) ? 4 : 6)
-
 /* Regardless of the presence of delay slots, the default value of 1 for
    BRANCH_COST is the best in the range (1, 2, 3), tested with gcc-2.7.2
    with testcases ipps and gcc, giving smallest and fastest code.  */
@@ -1355,7 +1042,7 @@ struct cum_args {int regs;};
    word-length sizes will be emitted.  The "9" will translate to
    (9 - 1) * 4 = 32 bytes maximum moved, but using 16 instructions
    (8 instruction sequences) or less.  */
-#define MOVE_RATIO 9
+#define MOVE_RATIO(speed) 9
 
 
 /* Node: Sections */
@@ -1369,58 +1056,26 @@ struct cum_args {int regs;};
 /* The jump table is immediately connected to the preceding insn.  */
 #define JUMP_TABLES_IN_TEXT_SECTION 1
 
-/* We pull a little trick to register the _fini function with atexit,
-   after (presumably) registering the eh frame info, since we don't handle
-   _fini (a.k.a. ___fini_start) in crt0 or have a crti for "pure" ELF.  If
-   you change this, don't forget that you can't have library function
-   references (e.g. to atexit) in crtend.o, since those won't be resolved
-   to libraries; those are linked in *before* crtend.o.  */
-#ifdef CRT_BEGIN
-# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)            \
-static void __attribute__((__used__))                          \
-call_ ## FUNC (void)                                           \
-{                                                              \
-  asm (SECTION_OP);                                            \
-  FUNC ();                                                     \
-  if (__builtin_strcmp (#FUNC, "frame_dummy") == 0)            \
-   {                                                           \
-     extern void __fini__start (void);                         \
-     atexit (__fini__start);                                   \
-   }                                                           \
-  asm (TEXT_SECTION_ASM_OP);                                   \
-}
-#endif
 
 /* Node: PIC */
 
-#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 0 : INVALID_REGNUM)
+/* Helper type.  */
 
-#define LEGITIMATE_PIC_OPERAND_P(X) cris_legitimate_pic_operand (X)
+enum cris_pic_symbol_type
+  {
+    cris_no_symbol = 0,
+    cris_got_symbol = 1,
+    cris_rel_symbol = 2,
+    cris_got_symbol_needing_fixup = 3,
+    cris_invalid_pic_symbol = 4
+  };
 
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? CRIS_GOT_REGNUM : INVALID_REGNUM)
 
-/* Node: File Framework */
+#define LEGITIMATE_PIC_OPERAND_P(X) cris_legitimate_pic_operand (X)
 
-/* NO_APP *only at file start* means faster assembly.
-   It also means comments are not allowed.
-   In some cases comments will be output for debugging purposes.
-   Make sure they are allowed then.  */
-/* Override previous definitions (elfos.h).  */
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM)                                 \
-  do                                                           \
-    {                                                          \
-      if (TARGET_PDEBUG || flag_print_asm_name)                        \
-       fprintf ((STREAM), "#APP\n");                           \
-      else                                                     \
-       fprintf ((STREAM), "#NO_APP\n");                        \
-      if (TARGET_ELF)                                          \
-       output_file_directive ((STREAM), main_input_filename);  \
-    }                                                          \
-  while (0)
 
-/* Override previous definitions (elfos.h).  */
-#undef ASM_FILE_END
-#define ASM_FILE_END(STREAM)
+/* Node: File Framework */
 
 /* We don't want an .ident for gcc.  To avoid that but still support
    #ident, we override ASM_OUTPUT_IDENT and, since the gcc .ident is its
@@ -1437,7 +1092,10 @@ call_ ## FUNC (void)                                             \
 
 /* Node: Data Output */
 
-#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) (C) == '@'
+#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
+  do { if (!cris_output_addr_const_extra (STREAM, X)) goto FAIL; } while (0)
+
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) (C) == '@'
 
 /* Node: Uninitialized Data */
 
@@ -1474,7 +1132,7 @@ call_ ## FUNC (void)                                              \
            }                                                           \
          fprintf ((FILE), "%s", COMMON_ASM_OP);                        \
          assemble_name ((FILE), (NAME));                               \
-         fprintf ((FILE), ",%u,%u\n", (SIZE), align_);                 \
+         fprintf ((FILE), ",%u,%u\n", (int)(SIZE), align_);            \
        }                                                               \
       else                                                             \
        {                                                               \
@@ -1485,7 +1143,7 @@ call_ ## FUNC (void)                                              \
          fputs ("\t.lcomm ", (FILE));                                  \
          assemble_name ((FILE), (NAME));                               \
          fprintf ((FILE), ",%u\n",                                     \
-                  ((SIZE) + (align_ - 1)) & ~(align_ - 1));            \
+                  ((int)(SIZE) + (align_ - 1)) & ~(align_ - 1));       \
        }                                                               \
     }                                                                  \
   while (0)
@@ -1497,9 +1155,6 @@ call_ ## FUNC (void)                                              \
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
  CRIS_ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN, 1)
 
-/* FIXME: define ASM_OUTPUT_SHARED_COMMON and emit an error when it is
-   used with -melinux and a.out.  */
-
 /* Node: Label Output */
 
 /* Globalizing directive for a label.  */
@@ -1507,6 +1162,12 @@ call_ ## FUNC (void)                                             \
 
 #define SUPPORTS_WEAK 1
 
+#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYM) \
+ cris_asm_output_symbol_ref (STREAM, SYM)
+
+#define ASM_OUTPUT_LABEL_REF(STREAM, BUF) \
+ cris_asm_output_label_ref (STREAM, BUF)
+
 /* Remove any previous definition (elfos.h).  */
 #undef ASM_GENERATE_INTERNAL_LABEL
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)        \
@@ -1522,19 +1183,10 @@ call_ ## FUNC (void)                                            \
 
 #define REGISTER_NAMES                                 \
  {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",        \
-  "r9", "r10", "r11", "r12", "r13", "sp", "pc", "srp", "faked_ap"}
+  "r9", "r10", "r11", "r12", "r13", "sp", "acr", "srp", "mof", "faked_ap", "dccr"}
 
 #define ADDITIONAL_REGISTER_NAMES \
- {{"r14", 14}, {"r15", 15}}
-
-#define PRINT_OPERAND(FILE, X, CODE)           \
- cris_print_operand (FILE, X, CODE)
-
-/* For delay-slot handling.  */
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#')
-
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR)      \
-   cris_print_operand_address (FILE, ADDR)
+ {{"r14", 14}, {"r15", 15}, {"pc", 15}}
 
 /* Output an empty line to illustrate the presence of the delay slot.  */
 #define DBR_OUTPUT_SEQEND(FILE) \
@@ -1554,17 +1206,27 @@ call_ ## FUNC (void)                                            \
 #undef USER_LABEL_PREFIX
 #define USER_LABEL_PREFIX "_"
 
-#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \
-  fprintf (FILE, "\tpush $%s\n", reg_names[REGNO])
+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)                               \
+  fprintf (FILE,                                                       \
+          TARGET_V32                                                   \
+          ? "\tsubq 4,$sp\n\tmove $%s,[$sp]\n" : "\tpush $%s\n",       \
+          reg_names[REGNO])
 
 #define ASM_OUTPUT_REG_POP(FILE, REGNO) \
-  fprintf (FILE, "\tpop $%s\n", reg_names[REGNO])
+  fprintf (FILE, "\tmove [$sp+],$%s\n", reg_names[REGNO])
 
 
 /* Node: Dispatch Tables */
 
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)       \
-  asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL)
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)               \
+  do                                                                   \
+    {                                                                  \
+      if (TARGET_V32)                                                  \
+       asm_fprintf (FILE, "\t.word %LL%d-.\n", VALUE);                 \
+      else                                                             \
+       asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL);                \
+    }                                                                  \
+  while (0)
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
   asm_fprintf (FILE, "\t.dword %LL%d\n", VALUE)
@@ -1579,19 +1241,7 @@ call_ ## FUNC (void)                                             \
    the expanded casesi core-insn.
    FIXME: Check this construct when changing to new version of gcc.  */
 #define ASM_OUTPUT_CASE_END(STREAM, NUM, TABLE)                                \
-  do                                                                   \
-    {                                                                  \
-      asm_fprintf (STREAM, "\t.word %LL%d-%LL%d%s\n",                  \
-                  CODE_LABEL_NUMBER                                    \
-                   (XEXP (XEXP (XEXP                                   \
-                                 (XVECEXP                              \
-                                   (PATTERN (PREV_INSN (PREV_INSN      \
-                                                         (TABLE))),    \
-                                    0, 0), 1), 2), 0)),                \
-                  NUM,                                                 \
-                  (TARGET_PDEBUG ? "; default" : ""));                 \
-    }                                                                  \
-  while (0)
+  cris_asm_output_case_end (STREAM, NUM, TABLE)
 
 
 /* Node: Exception Region Output */
@@ -1606,8 +1256,11 @@ call_ ## FUNC (void)                                             \
 
 /* Node: All Debuggers */
 
-#define DBX_REGISTER_NUMBER(REGNO) \
- ((REGNO) == CRIS_SRP_REGNUM ? CRIS_CANONICAL_SRP_REGNUM : (REGNO))
+#define DBX_REGISTER_NUMBER(REGNO)                             \
+ ((REGNO) == CRIS_SRP_REGNUM ? CRIS_CANONICAL_SRP_REGNUM :     \
+  (REGNO) == CRIS_MOF_REGNUM ? CRIS_CANONICAL_MOF_REGNUM :     \
+  (REGNO) == CRIS_CC0_REGNUM ? CRIS_CANONICAL_CC0_REGNUM :     \
+ (REGNO))
 
 /* FIXME: Investigate DEBUGGER_AUTO_OFFSET, DEBUGGER_ARG_OFFSET.  */
 
@@ -1635,38 +1288,6 @@ call_ ## FUNC (void)                                             \
 
 /* Node: Misc */
 
-/* FIXME: Check this one more time.  */
-#define PREDICATE_CODES                                        \
- {"cris_orthogonal_operator",                          \
-  {PLUS, MINUS, IOR, AND, UMIN}},                      \
- {"cris_commutative_orth_op",                          \
-  {PLUS, IOR, AND, UMIN}},                             \
- {"cris_operand_extend_operator",                      \
-  {PLUS, MINUS, UMIN}},                                        \
- {"cris_additive_operand_extend_operator",             \
-  {PLUS, MINUS}},                                      \
- {"cris_extend_operator",                              \
-  {ZERO_EXTEND, SIGN_EXTEND}},                         \
- {"cris_plus_or_bound_operator",                       \
-  {PLUS, UMIN}},                                       \
- {"cris_bdap_operand",                                 \
-  {SUBREG, REG, LABEL_REF, SYMBOL_REF, MEM, CONST_INT, \
-   CONST_DOUBLE, CONST, SIGN_EXTEND}},                 \
- {"cris_bdap_biap_operand",                            \
-  {SUBREG, REG, LABEL_REF, SYMBOL_REF, MEM, CONST_INT, \
-   CONST_DOUBLE, CONST, SIGN_EXTEND, MULT}},           \
- {"cris_general_operand_or_gotless_symbol",            \
-  {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,         \
-   LABEL_REF, SUBREG, REG, MEM}},                      \
- {"cris_general_operand_or_symbol",                    \
-  {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,         \
-   LABEL_REF, SUBREG, REG, MEM}},                      \
- {"cris_general_operand_or_plt_symbol",                        \
-  {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,         \
-   LABEL_REF, SUBREG, REG, MEM}},                      \
- {"cris_mem_call_operand",                             \
-  {MEM}},
-
 /* A combination of the bound (umin) insn together with a
    sign-extended add via the table to PC seems optimal.
    If the table overflows, the assembler will take care of it.
@@ -1678,7 +1299,7 @@ call_ ## FUNC (void)                                              \
 #define CASE_VECTOR_PC_RELATIVE 1
 
 /* FIXME: Investigate CASE_VECTOR_SHORTEN_MODE to make sure HImode is not
-   used when broken-.word could possibly fail (plus test-case).  */
+   used when broken-.word could possibly fail (plus testcase).  */
 
 #define FIXUNS_TRUNC_LIKE_FIX_TRUNC
 
@@ -1691,7 +1312,8 @@ call_ ## FUNC (void)                                              \
 
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
 
-#define STORE_FLAG_VALUE 1
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
 
 #define Pmode SImode