X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Fcris%2Fcris.h;h=a7b7e4d1e6291998ab8416843a90ad41e6d531b2;hp=da5ab7f9c46c845b6c22baa0c33383d21d8e164e;hb=13c3046411bee2b5dec8db03f3d2ee4fa79274bc;hpb=9ebd0bb279b2574fc5826c5e785331cb69d6f19b diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index da5ab7f9c46..a7b7e4d1e62 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -1,13 +1,13 @@ /* Definitions for GCC. Part of the machine description for CRIS. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, + 2009, 2010 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, @@ -16,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 @@ -38,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) \ @@ -50,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 @@ -68,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 @@ -105,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)" @@ -159,19 +172,16 @@ 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_MUL_BUG_ABORT_OPTION +#ifdef HAVE_AS_NO_MUL_BUG_ABORT_OPTION #define MAYBE_AS_NO_MUL_BUG_ABORT \ "%{mno-mul-bug-workaround:-no-mul-bug-abort} " #else @@ -183,10 +193,13 @@ extern const char *cris_elinux_stacksize_str; #define ASM_SPEC \ MAYBE_AS_NO_MUL_BUG_ABORT \ "%{v:-v}\ - %(asm_subtarget)" + %(asm_subtarget)\ + %{march=*:%{cpu=*:%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=*:%{!cpu=*:" 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 @@ -211,35 +224,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}, \ @@ -265,238 +270,50 @@ extern const char *cris_elinux_stacksize_str; } \ while (0) -/* This needs to be at least 32 bits. */ -extern int target_flags; - -/* Currently this just affects alignment. 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) - -/* Whether or not to work around multiplication instruction hardware bug - when generating code for models where it may be present. From the - trouble report for Etrax 100 LX: "A multiply operation may cause - incorrect cache behaviour under some specific circumstances. The - problem can occur if the instruction following the multiply instruction - causes a cache miss, and multiply operand 1 (source operand) bits - [31:27] matches the logical mapping of the mode register address - (0xb0....), and bits [9:2] of operand 1 matches the TLB register - address (0x258-0x25f). There is such a mapping in kernel mode or when - the MMU is off. Normally there is no such mapping in user mode, and - the problem will therefore probably not occur in Linux user mode - programs." - - We have no sure-fire way to know from within GCC that we're compiling a - user program. For example, -fpic/PIC is used in libgcc which is linked - into the kernel. However, the workaround option -mno-mul-bug can be - safely used per-package when compiling programs. The same goes for - general user-only libraries such as glibc, since there's no user-space - driver-like program that gets a mapping of I/O registers (all on the - same page, including the TLB registers). */ -#define TARGET_MASK_MUL_BUG 16384 -#define TARGET_MUL_BUG (target_flags & TARGET_MASK_MUL_BUG) - -#define TARGET_SWITCHES \ - { \ - {"mul-bug-workaround", TARGET_MASK_MUL_BUG, \ - N_("Work around bug in multiplication instruction")}, \ - {"no-mul-bug-workaround", -TARGET_MASK_MUL_BUG, ""}, \ - /* 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 + TARGET_MASK_MUL_BUG) -#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, "", 0}, \ - {"arch=", &cris_cpu_str, \ - N_("Generate code for the specified chip or CPU version"), 0}, \ - {"tune=", &cris_tune_str, \ - N_("Tune alignment for the specified chip or CPU version"), 0}, \ - {"max-stackframe=", &cris_max_stackframe_str, \ - N_("Warn when a stackframe is larger than the specified size"), 0}, \ - CRIS_SUBTARGET_LONG_OPTIONS \ - {"ax-stackframe=", &cris_max_stackframe_str, "", 0} } - -#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) +#ifndef TARGET_CPU_DEFAULT +#define TARGET_CPU_DEFAULT CRIS_CPU_BASE +#endif -/* For the cris-*-elf subtarget. */ -#define CRIS_SUBTARGET_VERSION " - generic ELF" +/* 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 -#define OVERRIDE_OPTIONS cris_override_options () +/* Local, providing a default for cris_cpu_version. */ +#define CRIS_DEFAULT_CPU_VERSION TARGET_CPU_DEFAULT -/* 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) +#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) +#define CRIS_SUBTARGET_HANDLE_OPTION(x, y, z) /* Node: Storage Layout */ @@ -511,25 +328,10 @@ extern int target_flags; #define UNITS_PER_WORD 4 -/* A combination of defining PROMOTE_MODE, - TARGET_PROMOTE_FUNCTION_ARGS that always returns true, - PROMOTE_FOR_CALL_ONLY and *not* defining TARGET_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) - -/* 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 - TARGET_PROMOTE_FUNCTION_RETURN that always returns true. */ -#define PROMOTE_FOR_CALL_ONLY - /* We will be using prototype promotion, so they will be 32 bit. */ #define PARM_BOUNDARY 32 @@ -612,9 +414,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 @@ -622,12 +424,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} + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1} #define CONDITIONAL_REGISTER_USAGE cris_conditional_register_usage () @@ -653,7 +455,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 */ @@ -664,10 +473,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 */ @@ -679,32 +497,79 @@ 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 IRA_COVER_CLASSES { GENERAL_REGS, SPECIAL_REGS, LIM_REG_CLASSES } + +#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. */ @@ -714,15 +579,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 @@ -738,7 +637,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 : \ @@ -761,6 +660,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) \ @@ -778,18 +687,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) \ @@ -805,8 +714,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]? */ \ @@ -816,34 +725,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. */ @@ -894,34 +802,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) @@ -935,45 +835,9 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES}; #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%), @@ -991,13 +855,6 @@ struct cum_args {int regs;}; #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)) @@ -1005,26 +862,12 @@ 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 CRIS_STRUCT_VALUE_REGNUM ((CRIS_FIRST_ARG_REG) - 1) @@ -1036,13 +879,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) \ @@ -1052,62 +888,13 @@ struct cum_args {int regs;}; documentation. */ -/* Node: Varargs */ - -/* 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 */ /* If you change this, you have to check whatever libraries and systems @@ -1119,8 +906,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 @@ -1137,22 +924,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)))) @@ -1163,16 +953,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 @@ -1182,15 +966,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); \ @@ -1206,7 +990,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). */ \ @@ -1238,90 +1022,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 @@ -1336,14 +1045,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. */ @@ -1354,7 +1055,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 */ @@ -1368,31 +1069,21 @@ 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. */ + +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) #define LEGITIMATE_PIC_OPERAND_P(X) cris_legitimate_pic_operand (X) @@ -1414,7 +1105,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,9 +1168,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. */ @@ -1484,6 +1175,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) \ @@ -1499,20 +1196,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) == '#' || (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) \ @@ -1532,17 +1219,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) @@ -1557,19 +1254,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 */ @@ -1584,8 +1269,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. */ @@ -1613,40 +1301,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_mem_op", \ - {MEM}}, \ - {"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. @@ -1671,12 +1325,18 @@ call_ ## FUNC (void) \ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 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 #define FUNCTION_MODE QImode #define NO_IMPLICIT_EXTERN_C +/* No specific purpose other than warningless compatibility. */ +#define HANDLE_PRAGMA_PACK_PUSH_POP 1 + /* * Local variables: * eval: (c-set-style "gnu")