X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Fcris%2Fcris.h;h=57bdd4677c20068f44993ccd78ba1512638b6dc1;hp=98a27a643b36643fa4327ebee61f05ba5e9bb449;hb=ca3163600e6f061e70fd1bf05ce1529e1b831dac;hpb=529825bde478a6e19140c1ee7b1676085aea0b2c
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 98a27a643b3..57bdd4677c2 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -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
+. */
/* 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" 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