diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-22 19:58:18 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-22 19:58:18 +0000 |
commit | 17b3d2a812c7aab15d23d75634a9306cacd345a1 (patch) | |
tree | 7a705196fcad24a1f78dbe66d931764447a4198f /gcc/config/crx | |
parent | bae8bb65d842d7ffefe990c1f0ac004491f3c105 (diff) | |
download | gcc-17b3d2a812c7aab15d23d75634a9306cacd345a1.tar.gz |
* MAINTAINERS (crx port, m68hc11 port): Remove. Move maintainers
to Write After Approval.
* config-ml.in: Don't handle arc-*-elf*.
* configure.ac (arc-*-*, crx-*-*, i[[3456789]]86-*-pe,
m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*, mcore-*-pe*): Don't
handle GCC libraries.
* configure: Regenerate.
contrib:
* compare-all-tests (all_targets): Remove crx and m68hc11.
fixincludes:
* mkfixinc.sh: Don't handle i?86-moss-msdos* or i?86-*-pe.
gcc:
* config/alpha/gnu.h: Remove.
* config/arc: Remove directory.
* config/arm/netbsd.h: Remove.
* config/arm/t-pe: Remove.
* config/crx: Remove directory.
* config/i386/netbsd.h: Remove.
* config/m68hc11: Remove directory.
* config/m68k/uclinux-oldabi.h: Remove.
* config/mcore/mcore-pe.h: Remove.
* config/mcore/t-mcore-pe: Remove.
* config/netbsd-aout.h: Remove.
* config/rs6000/gnu.h: Remove.
* config/sh/sh-symbian.h: Remove.
* config/sh/symbian-base.c: Remove.
* config/sh/symbian-c.c: Remove.
* config/sh/symbian-cxx.c: Remove.
* config/sh/symbian-post.h: Remove.
* config/sh/symbian-pre.h: Remove.
* config/sh/t-symbian: Remove.
* config/svr3.h: Remove.
* config/vax/netbsd.h: Remove.
* config.build: Don't handle i[34567]86-*-pe.
* config.gcc: Remove handling of deprecations for most deprecated
targets.
(m68k-*-uclinuxoldabi*): Add to second deprecated list.
(alpha*-*-gnu*, arc-*-elf*, arm*-*-netbsd*, arm-*-pe*, crx-*-elf,
i[34567]86-*-netbsd*, i[34567]86-*-pe, m68hc11-*-*|m6811-*-*,
m68hc12-*-*|m6812-*-*, m68k-*-uclinuxoldabi*, mcore-*-pe*,
powerpc64-*-gnu*, powerpc-*-gnu-gnualtivec*, powerpc-*-gnu*,
sh-*-symbianelf* | sh[12346l]*-*-symbianelf*, vax-*-netbsd*):
Remove cases.
* config.host: Don't handle i[34567]86-*-pe.
* config/rs6000/linux64.h (LINK_OS_GNU_SPEC): Remove.
(ASM_SPEC32): Don't handle -mcall-gnu.
* config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Don't handle
-mcall-gnu.
(ASM_SPEC, CC1_SPEC, LINK_START_SPEC, LINK_OS_SPEC, CPP_SPEC,
STARTFILE_SPEC, LIB_SPEC, ENDFILE_SPEC): Don't handle -mcall-gnu.
(LIB_GNU_SPEC, STARTFILE_GNU_SPEC, ENDFILE_GNU_SPEC,
LINK_START_GNU_SPEC, LINK_OS_GNU_SPEC, CPP_OS_GNU_SPEC): Remove.
(SUBTARGET_EXTRA_SPECS): Remove *_gnu specs.
* config/sh/sh-protos.h, config/sh/sh.c: Remove all code
conditional on SYMBIAN.
* configure.ac: Don't handle powerpc*-*-gnu*.
* configure: Regenerate.
* doc/extend.texi (interrupt attribute): Don't mention CRX.
* doc/install-old.texi (m6811, m6812): Don't mention.
* doc/install.texi (arc-*-elf*): Don't document multilib option.
(arc-*-elf, CRX, m6811-elf, m6812-elf): Remove.
(m68k-uclinuxoldabi): Don't mention.
* doc/invoke.texi (ARC Options, CRX Options, M68hc1x Options):
Remove.
(-mcall-gnu): Remove.
* doc/md.texi (CRX Architecture, Motorola 68HC11 & 68HC12
families): Remove constraint documentation.
gcc/testsuite:
* gcc.c-torture/execute/920501-8.x: Remove.
* gcc.c-torture/execute/930513-1.x: Remove.
* gcc.c-torture/execute/960312-1.x: Remove.
* gcc.c-torture/compile/20000804-1.c,
gcc.c-torture/compile/20001205-1.c,
gcc.c-torture/compile/20001226-1.c,
gcc.c-torture/compile/20010518-2.c,
gcc.c-torture/compile/20020312-1.c,
gcc.c-torture/compile/20020604-1.c,
gcc.c-torture/compile/920501-12.c,
gcc.c-torture/compile/920501-4.c,
gcc.c-torture/compile/920520-1.c,
gcc.c-torture/compile/980506-1.c,
gcc.c-torture/execute/980709-1.x,
gcc.c-torture/execute/990826-0.x: Don't XFAIL or use special
options for m68hc11.
* gcc.dg/cpp/assert4.c: Don't handle ARC.
* gcc.dg/sibcall-3.c, gcc.dg/sibcall-4.c: Don't XFAIL for arc or
m68hc11.
libgcc:
* config.host (alpha*-*-gnu*, arc-*-elf*, arm*-*-netbsd*,
arm-*-pe*, crx-*-elf, i[34567]86-*-netbsd*, i[34567]86-*-pe,
m68hc11-*-*|m6811-*-*, m68hc12-*-*|m6812-*-*, mcore-*-pe*,
powerpc64-*-gnu*, powerpc-*-gnu-gnualtivec*, powerpc-*-gnu*,
sh-*-symbianelf* | sh[12346l]*-*-symbianelf*, vax-*-netbsd*):
Remove cases.
libstdc++-v3:
* configure.ac: Don't handle powerpc*-*-gnu*.
* configure: Regenerate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171302 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/crx')
-rw-r--r-- | gcc/config/crx/crx-protos.h | 79 | ||||
-rw-r--r-- | gcc/config/crx/crx.c | 1466 | ||||
-rw-r--r-- | gcc/config/crx/crx.h | 478 | ||||
-rw-r--r-- | gcc/config/crx/crx.md | 899 | ||||
-rw-r--r-- | gcc/config/crx/crx.opt | 34 | ||||
-rw-r--r-- | gcc/config/crx/t-crx | 37 |
6 files changed, 0 insertions, 2993 deletions
diff --git a/gcc/config/crx/crx-protos.h b/gcc/config/crx/crx-protos.h deleted file mode 100644 index aeb4bdd594a..00000000000 --- a/gcc/config/crx/crx-protos.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Prototypes for exported functions defined in crx.c - Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2007, 2010 Free Software Foundation, Inc. - - 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 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#ifndef GCC_CRX_PROTOS_H -#define GCC_CRX_PROTOS_H - - -/* Register usage. */ -extern enum reg_class crx_regno_reg_class (int); -extern int crx_hard_regno_mode_ok (int regno, enum machine_mode); -#ifdef RTX_CODE -extern enum reg_class crx_secondary_reload_class (enum reg_class, enum machine_mode, rtx); -#endif /* RTX_CODE */ - -/* Passing function arguments. */ -extern int crx_function_arg_regno_p (int); -#ifdef TREE_CODE -#ifdef RTX_CODE -extern void crx_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx); -#endif /* RTX_CODE */ -#endif /* TREE_CODE */ - -#ifdef RTX_CODE -/* Addressing Modes. */ -struct crx_address -{ - rtx base, index, disp, side_effect; - int scale; -}; - -enum crx_addrtype -{ - CRX_INVALID, CRX_REG_REL, CRX_POST_INC, CRX_SCALED_INDX, CRX_ABSOLUTE -}; - -extern enum crx_addrtype crx_decompose_address (rtx addr, struct crx_address *out); - -extern int crx_const_double_ok (rtx op); - -/* Instruction output. */ -extern void crx_print_operand (FILE *, rtx, int); -extern void crx_print_operand_address (FILE *, rtx); - -/* Misc functions called from crx.md. */ -extern void crx_expand_movmem_single (rtx, rtx, rtx, rtx, rtx, unsigned HOST_WIDE_INT *); -extern int crx_expand_movmem (rtx, rtx, rtx, rtx); -#endif /* RTX_CODE */ - -/* Routines to compute costs. */ -extern int crx_memory_move_cost (enum machine_mode, enum reg_class, int); - -/* Prologue/Epilogue functions. */ -extern int crx_initial_elimination_offset (int, int); -extern char *crx_prepare_push_pop_string (int); -extern void crx_expand_prologue (void); -extern void crx_expand_epilogue (void); - - -/* Handling the "interrupt" attribute */ -extern int crx_interrupt_function_p (void); - -#endif /* GCC_CRX_PROTOS_H */ diff --git a/gcc/config/crx/crx.c b/gcc/config/crx/crx.c deleted file mode 100644 index 8f635d5a171..00000000000 --- a/gcc/config/crx/crx.c +++ /dev/null @@ -1,1466 +0,0 @@ -/* Output routines for GCC for CRX. - Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - 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 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/*****************************************************************************/ -/* HEADER INCLUDES */ -/*****************************************************************************/ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "tree.h" -#include "tm_p.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "insn-config.h" -#include "conditions.h" -#include "output.h" -#include "insn-codes.h" -#include "insn-attr.h" -#include "flags.h" -#include "except.h" -#include "function.h" -#include "recog.h" -#include "expr.h" -#include "optabs.h" -#include "diagnostic-core.h" -#include "basic-block.h" -#include "df.h" -#include "target.h" -#include "target-def.h" - -/*****************************************************************************/ -/* DEFINITIONS */ -/*****************************************************************************/ - -/* Maximum number of register used for passing parameters. */ -#define MAX_REG_FOR_PASSING_ARGS 6 - -/* Minimum number register used for passing parameters. */ -#define MIN_REG_FOR_PASSING_ARGS 2 - -/* The maximum count of words supported in the assembly of the architecture in - * a push/pop instruction. */ -#define MAX_COUNT 8 - -/* Predicate is true if the current function is a 'noreturn' function, i.e. it - * is qualified as volatile. */ -#define FUNC_IS_NORETURN_P(decl) (TREE_THIS_VOLATILE (decl)) - -/* The following macros are used in crx_decompose_address () */ - -/* Returns the factor of a scaled index address or -1 if invalid. */ -#define SCALE_FOR_INDEX_P(X) \ - (GET_CODE (X) == CONST_INT ? \ - (INTVAL (X) == 1 ? 1 : \ - INTVAL (X) == 2 ? 2 : \ - INTVAL (X) == 4 ? 4 : \ - INTVAL (X) == 8 ? 8 : \ - -1) : \ - -1) - -/* Nonzero if the rtx X is a signed const int of n bits */ -#define RTX_SIGNED_INT_FITS_N_BITS(X,n) \ - ((GET_CODE (X) == CONST_INT \ - && SIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0) - -/* Nonzero if the rtx X is an unsigned const int of n bits. */ -#define RTX_UNSIGNED_INT_FITS_N_BITS(X, n) \ - ((GET_CODE (X) == CONST_INT \ - && UNSIGNED_INT_FITS_N_BITS (INTVAL (X), n)) ? 1 : 0) - -/*****************************************************************************/ -/* STATIC VARIABLES */ -/*****************************************************************************/ - -/* Nonzero if the last param processed is passed in a register. */ -static int last_parm_in_reg; - -/* Will hold the number of the last register the prologue saves, -1 if no - * register is saved. */ -static int last_reg_to_save; - -/* Each object in the array is a register number. Mark 1 for registers that - * need to be saved. */ -static int save_regs[FIRST_PSEUDO_REGISTER]; - -/* Number of bytes saved on the stack for non-scratch registers */ -static int sum_regs = 0; - -/* Number of bytes saved on the stack for local variables. */ -static int local_vars_size; - -/* The sum of 2 sizes: locals vars and padding byte for saving the registers. - * Used in expand_prologue () and expand_epilogue (). */ -static int size_for_adjusting_sp; - -/* In case of a POST_INC or POST_DEC memory reference, we must report the mode - * of the memory reference from PRINT_OPERAND to PRINT_OPERAND_ADDRESS. */ -static enum machine_mode output_memory_reference_mode; - -/*****************************************************************************/ -/* TARGETM FUNCTION PROTOTYPES */ -/*****************************************************************************/ - -static bool crx_fixed_condition_code_regs (unsigned int *, unsigned int *); -static rtx crx_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, - int incoming ATTRIBUTE_UNUSED); -static bool crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED); -static int crx_address_cost (rtx, bool); -static bool crx_legitimate_address_p (enum machine_mode, rtx, bool); -static bool crx_can_eliminate (const int, const int); -static rtx crx_function_arg (CUMULATIVE_ARGS *, enum machine_mode, - const_tree, bool); -static void crx_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, - const_tree, bool); - -/*****************************************************************************/ -/* RTL VALIDITY */ -/*****************************************************************************/ - -#undef TARGET_LEGITIMATE_ADDRESS_P -#define TARGET_LEGITIMATE_ADDRESS_P crx_legitimate_address_p - -#undef TARGET_CAN_ELIMINATE -#define TARGET_CAN_ELIMINATE crx_can_eliminate - -/*****************************************************************************/ -/* STACK LAYOUT AND CALLING CONVENTIONS */ -/*****************************************************************************/ - -#undef TARGET_FIXED_CONDITION_CODE_REGS -#define TARGET_FIXED_CONDITION_CODE_REGS crx_fixed_condition_code_regs - -#undef TARGET_STRUCT_VALUE_RTX -#define TARGET_STRUCT_VALUE_RTX crx_struct_value_rtx - -#undef TARGET_RETURN_IN_MEMORY -#define TARGET_RETURN_IN_MEMORY crx_return_in_memory - -/*****************************************************************************/ -/* PASSING FUNCTION ARGUMENTS */ -/*****************************************************************************/ - -#undef TARGET_FUNCTION_ARG -#define TARGET_FUNCTION_ARG crx_function_arg - -#undef TARGET_FUNCTION_ARG_ADVANCE -#define TARGET_FUNCTION_ARG_ADVANCE crx_function_arg_advance - -/*****************************************************************************/ -/* RELATIVE COSTS OF OPERATIONS */ -/*****************************************************************************/ - -#undef TARGET_ADDRESS_COST -#define TARGET_ADDRESS_COST crx_address_cost - -/*****************************************************************************/ -/* TARGET-SPECIFIC USES OF `__attribute__' */ -/*****************************************************************************/ - -#undef TARGET_ATTRIBUTE_TABLE -#define TARGET_ATTRIBUTE_TABLE crx_attribute_table - -static const struct attribute_spec crx_attribute_table[] = { - /* ISRs have special prologue and epilogue requirements. */ - {"interrupt", 0, 0, false, true, true, NULL, false}, - {NULL, 0, 0, false, false, false, NULL, false} -}; - -/* Option handling. */ - -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE crx_option_optimization_table - -static const struct default_options crx_option_optimization_table[] = - { - /* Put each function in its own section so that PAGE-instruction - relaxation can do its best. */ - { OPT_LEVELS_1_PLUS, OPT_ffunction_sections, NULL, 1 }, - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - -/* Initialize 'targetm' variable which contains pointers to functions and data - * relating to the target machine. */ - -struct gcc_target targetm = TARGET_INITIALIZER; - - -/*****************************************************************************/ -/* TARGET HOOK IMPLEMENTATIONS */ -/*****************************************************************************/ - -/* Return the fixed registers used for condition codes. */ - -static bool -crx_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2) -{ - *p1 = CC_REGNUM; - *p2 = INVALID_REGNUM; - return true; -} - -/* Implements hook TARGET_STRUCT_VALUE_RTX. */ - -static rtx -crx_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, - int incoming ATTRIBUTE_UNUSED) -{ - return gen_rtx_REG (Pmode, CRX_STRUCT_VALUE_REGNUM); -} - -/* Implements hook TARGET_RETURN_IN_MEMORY. */ - -static bool -crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) -{ - if (TYPE_MODE (type) == BLKmode) - { - HOST_WIDE_INT size = int_size_in_bytes (type); - return (size == -1 || size > 8); - } - else - return false; -} - - -/*****************************************************************************/ -/* MACRO IMPLEMENTATIONS */ -/*****************************************************************************/ - -/* STACK LAYOUT AND CALLING CONVENTIONS ROUTINES */ -/* --------------------------------------------- */ - -/* Return nonzero if the current function being compiled is an interrupt - * function as specified by the "interrupt" attribute. */ - -int -crx_interrupt_function_p (void) -{ - tree attributes; - - attributes = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)); - return lookup_attribute ("interrupt", attributes) != NULL_TREE; -} - -/* Compute values for the array save_regs and the variable sum_regs. The index - * of save_regs is numbers of register, each will get 1 if we need to save it - * in the current function, 0 if not. sum_regs is the total sum of the - * registers being saved. */ - -static void -crx_compute_save_regs (void) -{ - unsigned int regno; - - /* initialize here so in case the function is no-return it will be -1. */ - last_reg_to_save = -1; - - /* No need to save any registers if the function never returns. */ - if (FUNC_IS_NORETURN_P (current_function_decl)) - return; - - /* Initialize the number of bytes to be saved. */ - sum_regs = 0; - - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - { - if (fixed_regs[regno]) - { - save_regs[regno] = 0; - continue; - } - - /* If this reg is used and not call-used (except RA), save it. */ - if (crx_interrupt_function_p ()) - { - if (!current_function_is_leaf && call_used_regs[regno]) - /* this is a volatile reg in a non-leaf interrupt routine - save it - * for the sake of its sons. */ - save_regs[regno] = 1; - - else if (df_regs_ever_live_p (regno)) - /* This reg is used - save it. */ - save_regs[regno] = 1; - else - /* This reg is not used, and is not a volatile - don't save. */ - save_regs[regno] = 0; - } - else - { - /* If this reg is used and not call-used (except RA), save it. */ - if (df_regs_ever_live_p (regno) - && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM)) - save_regs[regno] = 1; - else - save_regs[regno] = 0; - } - } - - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (save_regs[regno] == 1) - { - last_reg_to_save = regno; - sum_regs += UNITS_PER_WORD; - } -} - -/* Compute the size of the local area and the size to be adjusted by the - * prologue and epilogue. */ - -static void -crx_compute_frame (void) -{ - /* For aligning the local variables. */ - int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT; - int padding_locals; - - /* Padding needed for each element of the frame. */ - local_vars_size = get_frame_size (); - - /* Align to the stack alignment. */ - padding_locals = local_vars_size % stack_alignment; - if (padding_locals) - padding_locals = stack_alignment - padding_locals; - - local_vars_size += padding_locals; - - size_for_adjusting_sp = local_vars_size + (ACCUMULATE_OUTGOING_ARGS ? - crtl->outgoing_args_size : 0); -} - -/* Worker function for TARGET_CAN_ELIMINATE. */ - -bool -crx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) -{ - return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); -} - -/* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */ - -int -crx_initial_elimination_offset (int from, int to) -{ - /* Compute this since we need to use sum_regs. */ - crx_compute_save_regs (); - - /* Compute this since we need to use local_vars_size. */ - crx_compute_frame (); - - if ((from) == FRAME_POINTER_REGNUM && (to) == STACK_POINTER_REGNUM) - return (ACCUMULATE_OUTGOING_ARGS ? - crtl->outgoing_args_size : 0); - else if ((from) == ARG_POINTER_REGNUM && (to) == FRAME_POINTER_REGNUM) - return (sum_regs + local_vars_size); - else if ((from) == ARG_POINTER_REGNUM && (to) == STACK_POINTER_REGNUM) - return (sum_regs + local_vars_size + - (ACCUMULATE_OUTGOING_ARGS ? - crtl->outgoing_args_size : 0)); - else - abort (); -} - -/* REGISTER USAGE */ -/* -------------- */ - -/* Return the class number of the smallest class containing reg number REGNO. - * This could be a conditional expression or could index an array. */ - -enum reg_class -crx_regno_reg_class (int regno) -{ - if (regno >= 0 && regno < SP_REGNUM) - return NOSP_REGS; - - if (regno == SP_REGNUM) - return GENERAL_REGS; - - if (regno == LO_REGNUM) - return LO_REGS; - if (regno == HI_REGNUM) - return HI_REGS; - - return NO_REGS; -} - -/* Transfer between HILO_REGS and memory via secondary reloading. */ - -enum reg_class -crx_secondary_reload_class (enum reg_class rclass, - enum machine_mode mode ATTRIBUTE_UNUSED, - rtx x ATTRIBUTE_UNUSED) -{ - if (reg_classes_intersect_p (rclass, HILO_REGS) - && true_regnum (x) == -1) - return GENERAL_REGS; - - return NO_REGS; -} - -/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */ - -int -crx_hard_regno_mode_ok (int regno, enum machine_mode mode) -{ - /* CC can only hold CCmode values. */ - if (regno == CC_REGNUM) - return GET_MODE_CLASS (mode) == MODE_CC; - if (GET_MODE_CLASS (mode) == MODE_CC) - return 0; - /* HILO registers can only hold SImode and DImode */ - if (HILO_REGNO_P (regno)) - return mode == SImode || mode == DImode; - return 1; -} - -/* PASSING FUNCTION ARGUMENTS */ -/* -------------------------- */ - -/* If enough param regs are available for passing the param of type TYPE return - * the number of registers needed else 0. */ - -static int -enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type, - enum machine_mode mode) -{ - int type_size; - int remaining_size; - - if (mode != BLKmode) - type_size = GET_MODE_BITSIZE (mode); - else - type_size = int_size_in_bytes (type) * BITS_PER_UNIT; - - remaining_size = - BITS_PER_WORD * (MAX_REG_FOR_PASSING_ARGS - - (MIN_REG_FOR_PASSING_ARGS + cum->ints) + 1); - - /* Any variable which is too big to pass in two registers, will pass on - * stack. */ - if ((remaining_size >= type_size) && (type_size <= 2 * BITS_PER_WORD)) - return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD; - - return 0; -} - -/* Implements TARGET_FUNCTION_ARG. */ - -static rtx -crx_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, - const_tree type, bool named ATTRIBUTE_UNUSED) -{ - last_parm_in_reg = 0; - - /* Function_arg () is called with this type just after all the args have had - * their registers assigned. The rtx that function_arg returns from this type - * is supposed to pass to 'gen_call' but currently it is not implemented (see - * macro GEN_CALL). */ - if (type == void_type_node) - return NULL_RTX; - - if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0)) - return NULL_RTX; - - if (mode == BLKmode) - { - /* Enable structures that need padding bytes at the end to pass to a - * function in registers. */ - if (enough_regs_for_param (cum, type, mode) != 0) - { - last_parm_in_reg = 1; - return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints); - } - } - - if (MIN_REG_FOR_PASSING_ARGS + cum->ints > MAX_REG_FOR_PASSING_ARGS) - return NULL_RTX; - else - { - if (enough_regs_for_param (cum, type, mode) != 0) - { - last_parm_in_reg = 1; - return gen_rtx_REG (mode, MIN_REG_FOR_PASSING_ARGS + cum->ints); - } - } - - return NULL_RTX; -} - -/* Implements the macro INIT_CUMULATIVE_ARGS defined in crx.h. */ - -void -crx_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype, - rtx libfunc ATTRIBUTE_UNUSED) -{ - tree param, next_param; - - cum->ints = 0; - - /* Determine if this function has variable arguments. This is indicated by - * the last argument being 'void_type_mode' if there are no variable - * arguments. Change here for a different vararg. */ - for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0; - param != (tree) 0; param = next_param) - { - next_param = TREE_CHAIN (param); - if (next_param == (tree) 0 && TREE_VALUE (param) != void_type_node) - { - cum->ints = -1; - return; - } - } -} - -/* Implements TARGET_FUNCTION_ARG_ADVANCE. */ - -static void -crx_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, - const_tree type, bool named ATTRIBUTE_UNUSED) -{ - /* l holds the number of registers required */ - int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD; - - /* If the parameter isn't passed on a register don't advance cum. */ - if (!last_parm_in_reg) - return; - - if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0)) - return; - - if (mode == SImode || mode == HImode || mode == QImode || mode == DImode) - { - if (l <= 1) - cum->ints += 1; - else - cum->ints += l; - } - else if (mode == SFmode || mode == DFmode) - cum->ints += l; - else if ((mode) == BLKmode) - { - if ((l = enough_regs_for_param (cum, type, mode)) != 0) - cum->ints += l; - } - -} - -/* Implements the macro FUNCTION_ARG_REGNO_P defined in crx.h. Return nonzero - * if N is a register used for passing parameters. */ - -int -crx_function_arg_regno_p (int n) -{ - return (n <= MAX_REG_FOR_PASSING_ARGS && n >= MIN_REG_FOR_PASSING_ARGS); -} - -/* ADDRESSING MODES */ -/* ---------------- */ - -/* Implements the hook for TARGET_LEGITIMATE_ADDRESS_P defined in crx.h. - * The following addressing modes are supported on CRX: - * - * Relocations --> const | symbol_ref | label_ref - * Absolute address --> 32-bit absolute - * Post increment --> reg + 12-bit disp. - * Post modify --> reg + 12-bit disp. - * Register relative --> reg | 32-bit disp. + reg | 4 bit + reg - * Scaled index --> reg + reg | 22-bit disp. + reg + reg | - * 22-disp. + reg + reg + (2 | 4 | 8) */ - -static rtx -crx_addr_reg (rtx addr_reg) -{ - if (GET_MODE (addr_reg) != Pmode) - return NULL_RTX; - - if (REG_P (addr_reg)) - return addr_reg; - else if (GET_CODE (addr_reg) == SUBREG - && REG_P (SUBREG_REG (addr_reg)) - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg))) - <= UNITS_PER_WORD)) - return SUBREG_REG (addr_reg); - else - return NULL_RTX; -} - -enum crx_addrtype -crx_decompose_address (rtx addr, struct crx_address *out) -{ - rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX; - rtx scale_rtx = NULL_RTX, side_effect = NULL_RTX; - int scale = -1; - - enum crx_addrtype retval = CRX_INVALID; - - switch (GET_CODE (addr)) - { - case CONST_INT: - /* Absolute address (known at compile time) */ - retval = CRX_ABSOLUTE; - disp = addr; - if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), GET_MODE_BITSIZE (Pmode))) - return CRX_INVALID; - break; - - case CONST: - case SYMBOL_REF: - case LABEL_REF: - /* Absolute address (known at link time) */ - retval = CRX_ABSOLUTE; - disp = addr; - break; - - case REG: - case SUBREG: - /* Register relative address */ - retval = CRX_REG_REL; - base = addr; - break; - - case PLUS: - switch (GET_CODE (XEXP (addr, 0))) - { - case REG: - case SUBREG: - if (REG_P (XEXP (addr, 1))) - { - /* Scaled index with scale = 1 and disp. = 0 */ - retval = CRX_SCALED_INDX; - base = XEXP (addr, 1); - index = XEXP (addr, 0); - scale = 1; - } - else if (RTX_SIGNED_INT_FITS_N_BITS (XEXP (addr, 1), 28)) - { - /* Register relative address and <= 28-bit disp. */ - retval = CRX_REG_REL; - base = XEXP (addr, 0); - disp = XEXP (addr, 1); - } - else - return CRX_INVALID; - break; - - case PLUS: - /* Scaled index and <= 22-bit disp. */ - retval = CRX_SCALED_INDX; - base = XEXP (XEXP (addr, 0), 1); - disp = XEXP (addr, 1); - if (!RTX_SIGNED_INT_FITS_N_BITS (disp, 22)) - return CRX_INVALID; - switch (GET_CODE (XEXP (XEXP (addr, 0), 0))) - { - case REG: - /* Scaled index with scale = 0 and <= 22-bit disp. */ - index = XEXP (XEXP (addr, 0), 0); - scale = 1; - break; - - case MULT: - /* Scaled index with scale >= 0 and <= 22-bit disp. */ - index = XEXP (XEXP (XEXP (addr, 0), 0), 0); - scale_rtx = XEXP (XEXP (XEXP (addr, 0), 0), 1); - if ((scale = SCALE_FOR_INDEX_P (scale_rtx)) == -1) - return CRX_INVALID; - break; - - default: - return CRX_INVALID; - } - break; - - case MULT: - /* Scaled index with scale >= 0 */ - retval = CRX_SCALED_INDX; - base = XEXP (addr, 1); - index = XEXP (XEXP (addr, 0), 0); - scale_rtx = XEXP (XEXP (addr, 0), 1); - /* Scaled index with scale >= 0 and <= 22-bit disp. */ - if ((scale = SCALE_FOR_INDEX_P (scale_rtx)) == -1) - return CRX_INVALID; - break; - - default: - return CRX_INVALID; - } - break; - - case POST_INC: - case POST_DEC: - /* Simple post-increment */ - retval = CRX_POST_INC; - base = XEXP (addr, 0); - side_effect = addr; - break; - - case POST_MODIFY: - /* Generic post-increment with <= 12-bit disp. */ - retval = CRX_POST_INC; - base = XEXP (addr, 0); - side_effect = XEXP (addr, 1); - if (base != XEXP (side_effect, 0)) - return CRX_INVALID; - switch (GET_CODE (side_effect)) - { - case PLUS: - case MINUS: - disp = XEXP (side_effect, 1); - if (!RTX_SIGNED_INT_FITS_N_BITS (disp, 12)) - return CRX_INVALID; - break; - - default: - /* CRX only supports PLUS and MINUS */ - return CRX_INVALID; - } - break; - - default: - return CRX_INVALID; - } - - if (base) - { - base = crx_addr_reg (base); - if (!base) - return CRX_INVALID; - } - if (index) - { - index = crx_addr_reg (index); - if (!index) - return CRX_INVALID; - } - - out->base = base; - out->index = index; - out->disp = disp; - out->scale = scale; - out->side_effect = side_effect; - - return retval; -} - -bool -crx_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, - rtx addr, bool strict) -{ - enum crx_addrtype addrtype; - struct crx_address address; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, - "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n", - GET_MODE_NAME (mode), strict); - debug_rtx (addr); - } - - addrtype = crx_decompose_address (addr, &address); - - if (addrtype == CRX_POST_INC && GET_MODE_SIZE (mode) > UNITS_PER_WORD) - return FALSE; - - if (TARGET_DEBUG_ADDR) - { - const char *typestr; - switch (addrtype) - { - case CRX_INVALID: - typestr = "Invalid"; - break; - case CRX_REG_REL: - typestr = "Register relative"; - break; - case CRX_POST_INC: - typestr = "Post-increment"; - break; - case CRX_SCALED_INDX: - typestr = "Scaled index"; - break; - case CRX_ABSOLUTE: - typestr = "Absolute"; - break; - default: - abort (); - } - fprintf (stderr, "CRX Address type: %s\n", typestr); - } - - if (addrtype == CRX_INVALID) - return FALSE; - - if (strict) - { - if (address.base && !REGNO_OK_FOR_BASE_P (REGNO (address.base))) - { - if (TARGET_DEBUG_ADDR) - fprintf (stderr, "Base register not strict\n"); - return FALSE; - } - if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index))) - { - if (TARGET_DEBUG_ADDR) - fprintf (stderr, "Index register not strict\n"); - return FALSE; - } - } - - return TRUE; -} - -/* ROUTINES TO COMPUTE COSTS */ -/* ------------------------- */ - -/* Return cost of the memory address x. */ - -static int -crx_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED) -{ - enum crx_addrtype addrtype; - struct crx_address address; - - int cost = 2; - - addrtype = crx_decompose_address (addr, &address); - - gcc_assert (addrtype != CRX_INVALID); - - /* An absolute address causes a 3-word instruction */ - if (addrtype == CRX_ABSOLUTE) - cost+=2; - - /* Post-modifying addresses are more powerful. */ - if (addrtype == CRX_POST_INC) - cost-=2; - - /* Attempt to minimize number of registers in the address. */ - if (address.base) - cost++; - - if (address.index && address.scale == 1) - cost+=5; - - if (address.disp && !INT_CST4 (INTVAL (address.disp))) - cost+=2; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\n======\nTARGET_ADDRESS_COST = %d\n", cost); - debug_rtx (addr); - } - - return cost; -} - -/* Return the cost of moving data of mode MODE between a register of class - * RCLASS and memory; IN is zero if the value is to be written to memory, - * nonzero if it is to be read in. This cost is relative to those in - * REGISTER_MOVE_COST. */ - -int -crx_memory_move_cost (enum machine_mode mode, - enum reg_class rclass ATTRIBUTE_UNUSED, - int in ATTRIBUTE_UNUSED) -{ - /* One LD or ST takes twice the time of a simple reg-reg move */ - if (reg_classes_intersect_p (rclass, GENERAL_REGS)) - { - /* printf ("GENERAL_REGS LD/ST = %d\n", 4 * HARD_REGNO_NREGS (0, mode));*/ - return 4 * HARD_REGNO_NREGS (0, mode); - } - else if (reg_classes_intersect_p (rclass, HILO_REGS)) - { - /* HILO to memory and vice versa */ - /* printf ("HILO_REGS %s = %d\n", in ? "LD" : "ST", - (REGISTER_MOVE_COST (mode, - in ? GENERAL_REGS : HILO_REGS, - in ? HILO_REGS : GENERAL_REGS) + 4) - * HARD_REGNO_NREGS (0, mode)); */ - return (REGISTER_MOVE_COST (mode, - in ? GENERAL_REGS : HILO_REGS, - in ? HILO_REGS : GENERAL_REGS) + 4) - * HARD_REGNO_NREGS (0, mode); - } - else /* default (like in i386) */ - { - /* printf ("ANYREGS = 100\n"); */ - return 100; - } -} - -/* INSTRUCTION OUTPUT */ -/* ------------------ */ - -/* Check if a const_double is ok for crx store-immediate instructions */ - -int -crx_const_double_ok (rtx op) -{ - if (GET_MODE (op) == DFmode) - { - REAL_VALUE_TYPE r; - long l[2]; - REAL_VALUE_FROM_CONST_DOUBLE (r, op); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); - return (UNSIGNED_INT_FITS_N_BITS (l[0], 4) && - UNSIGNED_INT_FITS_N_BITS (l[1], 4)) ? 1 : 0; - } - - if (GET_MODE (op) == SFmode) - { - REAL_VALUE_TYPE r; - long l; - REAL_VALUE_FROM_CONST_DOUBLE (r, op); - REAL_VALUE_TO_TARGET_SINGLE (r, l); - return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0; - } - - return (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4) && - UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4)) ? 1 : 0; -} - -/* Implements the macro PRINT_OPERAND defined in crx.h. */ - -void -crx_print_operand (FILE * file, rtx x, int code) -{ - switch (code) - { - case 'p' : - if (GET_CODE (x) == REG) { - if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode) - { - int regno = REGNO (x); - if (regno + 1 >= SP_REGNUM) abort (); - fprintf (file, "{%s, %s}", reg_names[regno], reg_names[regno + 1]); - return; - } - else - { - if (REGNO (x) >= SP_REGNUM) abort (); - fprintf (file, "%s", reg_names[REGNO (x)]); - return; - } - } - - case 'd' : - { - const char *crx_cmp_str; - switch (GET_CODE (x)) - { /* MD: compare (reg, reg or imm) but CRX: cmp (reg or imm, reg) - * -> swap all non symmetric ops */ - case EQ : crx_cmp_str = "eq"; break; - case NE : crx_cmp_str = "ne"; break; - case GT : crx_cmp_str = "lt"; break; - case GTU : crx_cmp_str = "lo"; break; - case LT : crx_cmp_str = "gt"; break; - case LTU : crx_cmp_str = "hi"; break; - case GE : crx_cmp_str = "le"; break; - case GEU : crx_cmp_str = "ls"; break; - case LE : crx_cmp_str = "ge"; break; - case LEU : crx_cmp_str = "hs"; break; - default : abort (); - } - fprintf (file, "%s", crx_cmp_str); - return; - } - - case 'H': - /* Print high part of a double precision value. */ - switch (GET_CODE (x)) - { - case CONST_DOUBLE: - if (GET_MODE (x) == SFmode) abort (); - if (GET_MODE (x) == DFmode) - { - /* High part of a DF const. */ - REAL_VALUE_TYPE r; - long l[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); - - fprintf (file, "$0x%lx", l[1]); - return; - } - - /* -- Fallthrough to handle DI consts -- */ - - case CONST_INT: - { - rtx high, low; - split_double (x, &low, &high); - putc ('$', file); - output_addr_const (file, high); - return; - } - - case REG: - if (REGNO (x) + 1 >= FIRST_PSEUDO_REGISTER) abort (); - fprintf (file, "%s", reg_names[REGNO (x) + 1]); - return; - - case MEM: - /* Adjust memory address to high part. */ - { - rtx adj_mem = x; - adj_mem = adjust_address (adj_mem, GET_MODE (adj_mem), 4); - - output_memory_reference_mode = GET_MODE (adj_mem); - output_address (XEXP (adj_mem, 0)); - return; - } - - default: - abort (); - } - - case 'L': - /* Print low part of a double precision value. */ - switch (GET_CODE (x)) - { - case CONST_DOUBLE: - if (GET_MODE (x) == SFmode) abort (); - if (GET_MODE (x) == DFmode) - { - /* High part of a DF const. */ - REAL_VALUE_TYPE r; - long l[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); - - fprintf (file, "$0x%lx", l[0]); - return; - } - - /* -- Fallthrough to handle DI consts -- */ - - case CONST_INT: - { - rtx high, low; - split_double (x, &low, &high); - putc ('$', file); - output_addr_const (file, low); - return; - } - - case REG: - fprintf (file, "%s", reg_names[REGNO (x)]); - return; - - case MEM: - output_memory_reference_mode = GET_MODE (x); - output_address (XEXP (x, 0)); - return; - - default: - abort (); - } - - case 0 : /* default */ - switch (GET_CODE (x)) - { - case REG: - fprintf (file, "%s", reg_names[REGNO (x)]); - return; - - case MEM: - output_memory_reference_mode = GET_MODE (x); - output_address (XEXP (x, 0)); - return; - - case CONST_DOUBLE: - { - REAL_VALUE_TYPE r; - long l; - - /* Always use H and L for double precision - see above */ - gcc_assert (GET_MODE (x) == SFmode); - - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_TARGET_SINGLE (r, l); - - fprintf (file, "$0x%lx", l); - return; - } - - default: - putc ('$', file); - output_addr_const (file, x); - return; - } - - default: - output_operand_lossage ("invalid %%xn code"); - } - - abort (); -} - -/* Implements the macro PRINT_OPERAND_ADDRESS defined in crx.h. */ - -void -crx_print_operand_address (FILE * file, rtx addr) -{ - enum crx_addrtype addrtype; - struct crx_address address; - - int offset; - - addrtype = crx_decompose_address (addr, &address); - - if (address.disp) - offset = INTVAL (address.disp); - else - offset = 0; - - switch (addrtype) - { - case CRX_REG_REL: - fprintf (file, "%d(%s)", offset, reg_names[REGNO (address.base)]); - return; - - case CRX_POST_INC: - switch (GET_CODE (address.side_effect)) - { - case PLUS: - break; - case MINUS: - offset = -offset; - break; - case POST_INC: - offset = GET_MODE_SIZE (output_memory_reference_mode); - break; - case POST_DEC: - offset = -GET_MODE_SIZE (output_memory_reference_mode); - break; - default: - abort (); - } - fprintf (file, "%d(%s)+", offset, reg_names[REGNO (address.base)]); - return; - - case CRX_SCALED_INDX: - fprintf (file, "%d(%s, %s, %d)", offset, reg_names[REGNO (address.base)], - reg_names[REGNO (address.index)], address.scale); - return; - - case CRX_ABSOLUTE: - output_addr_const (file, address.disp); - return; - - default: - abort (); - } -} - - -/*****************************************************************************/ -/* MACHINE DESCRIPTION HELPER-FUNCTIONS */ -/*****************************************************************************/ - -void crx_expand_movmem_single (rtx src, rtx srcbase, rtx dst, rtx dstbase, - rtx tmp_reg, unsigned HOST_WIDE_INT *offset_p) -{ - rtx addr, mem; - unsigned HOST_WIDE_INT offset = *offset_p; - - /* Load */ - addr = plus_constant (src, offset); - mem = adjust_automodify_address (srcbase, SImode, addr, offset); - emit_move_insn (tmp_reg, mem); - - /* Store */ - addr = plus_constant (dst, offset); - mem = adjust_automodify_address (dstbase, SImode, addr, offset); - emit_move_insn (mem, tmp_reg); - - *offset_p = offset + 4; -} - -int -crx_expand_movmem (rtx dstbase, rtx srcbase, rtx count_exp, rtx align_exp) -{ - unsigned HOST_WIDE_INT count = 0, offset, si_moves, i; - HOST_WIDE_INT align = 0; - - rtx src, dst; - rtx tmp_reg; - - if (GET_CODE (align_exp) == CONST_INT) - { /* Only if aligned */ - align = INTVAL (align_exp); - if (align & 3) - return 0; - } - - if (GET_CODE (count_exp) == CONST_INT) - { /* No more than 16 SImode moves */ - count = INTVAL (count_exp); - if (count > 64) - return 0; - } - - tmp_reg = gen_reg_rtx (SImode); - - /* Create psrs for the src and dest pointers */ - dst = copy_to_mode_reg (Pmode, XEXP (dstbase, 0)); - if (dst != XEXP (dstbase, 0)) - dstbase = replace_equiv_address_nv (dstbase, dst); - src = copy_to_mode_reg (Pmode, XEXP (srcbase, 0)); - if (src != XEXP (srcbase, 0)) - srcbase = replace_equiv_address_nv (srcbase, src); - - offset = 0; - - /* Emit SImode moves */ - si_moves = count >> 2; - for (i = 0; i < si_moves; i++) - crx_expand_movmem_single (src, srcbase, dst, dstbase, tmp_reg, &offset); - - /* Special cases */ - if (count & 3) - { - offset = count - 4; - crx_expand_movmem_single (src, srcbase, dst, dstbase, tmp_reg, &offset); - } - - gcc_assert (offset == count); - - return 1; -} - -static void -mpushpop_str (char *stringbuffer, const char *mnemonic, char *mask) -{ - if (strlen (mask) > 2 || crx_interrupt_function_p ()) /* needs 2-word instr. */ - sprintf (stringbuffer, "\n\t%s\tsp, {%s}", mnemonic, mask); - else /* single word instruction */ - sprintf (stringbuffer, "\n\t%s\t%s", mnemonic, mask); -} - -/* Called from crx.md. The return value depends on the parameter push_or_pop: - * When push_or_pop is zero -> string for push instructions of prologue. - * When push_or_pop is nonzero -> string for pop/popret/retx in epilogue. - * Relies on the assumptions: - * 1. RA is the last register to be saved. - * 2. The maximal value of the counter is MAX_COUNT. */ - -char * -crx_prepare_push_pop_string (int push_or_pop) -{ - /* j is the number of registers being saved, takes care that there won't be - * more than 8 in one push/pop instruction */ - - /* For the register mask string */ - static char mask_str[50]; - - /* i is the index of save_regs[], going from 0 until last_reg_to_save */ - int i = 0; - - int ra_in_bitmask = 0; - - char *return_str; - - /* For reversing on the push instructions if there are more than one. */ - char *temp_str; - - return_str = (char *) xmalloc (120); - temp_str = (char *) xmalloc (120); - - /* Initialize */ - memset (return_str, 0, 3); - - while (i <= last_reg_to_save) - { - /* Prepare mask for one instruction. */ - mask_str[0] = 0; - - if (i <= SP_REGNUM) - { /* Add regs unit full or SP register reached */ - int j = 0; - while (j < MAX_COUNT && i <= SP_REGNUM) - { - if (save_regs[i]) - { - /* TODO to use ra_in_bitmask for detecting last pop is not - * smart it prevents things like: popret r5 */ - if (i == RETURN_ADDRESS_REGNUM) ra_in_bitmask = 1; - if (j > 0) strcat (mask_str, ", "); - strcat (mask_str, reg_names[i]); - ++j; - } - ++i; - } - } - else - { - /* Handle hi/lo savings */ - while (i <= last_reg_to_save) - { - if (save_regs[i]) - { - strcat (mask_str, "lo, hi"); - i = last_reg_to_save + 1; - break; - } - ++i; - } - } - - if (strlen (mask_str) == 0) continue; - - if (push_or_pop == 1) - { - if (crx_interrupt_function_p ()) - mpushpop_str (temp_str, "popx", mask_str); - else - { - if (ra_in_bitmask) - { - mpushpop_str (temp_str, "popret", mask_str); - ra_in_bitmask = 0; - } - else mpushpop_str (temp_str, "pop", mask_str); - } - - strcat (return_str, temp_str); - } - else - { - /* push - We need to reverse the order of the instructions if there - * are more than one. (since the pop will not be reversed in the - * epilogue */ - if (crx_interrupt_function_p ()) - mpushpop_str (temp_str, "pushx", mask_str); - else - mpushpop_str (temp_str, "push", mask_str); - strcat (temp_str, return_str); - strcpy (strcat (return_str, "\t"), temp_str); - } - - } - - if (push_or_pop == 1) - { - /* pop */ - if (crx_interrupt_function_p ()) - strcat (return_str, "\n\tretx\n"); - - else if (!FUNC_IS_NORETURN_P (current_function_decl) - && !save_regs[RETURN_ADDRESS_REGNUM]) - strcat (return_str, "\n\tjump\tra\n"); - } - - /* Skip the newline and the tab in the start of return_str. */ - return_str += 2; - return return_str; -} - -/* CompactRISC CRX Architecture stack layout: - - 0 +--------------------- - | - . - . - | - +==================== Sp(x)=Ap(x+1) - A | Args for functions - | | called by X and Dynamically - | | Dynamic allocations allocated and - | | (alloca, variable deallocated - Stack | length arrays). - grows +-------------------- Fp(x) - down| | Local variables of X - ward| +-------------------- - | | Regs saved for X-1 - | +==================== Sp(x-1)=Ap(x) - | Args for func X - | pushed by X-1 - +-------------------- Fp(x-1) - | - | - V - -*/ - -void -crx_expand_prologue (void) -{ - crx_compute_frame (); - crx_compute_save_regs (); - - /* If there is no need in push and adjustment to sp, return. */ - if (size_for_adjusting_sp + sum_regs == 0) - return; - - if (last_reg_to_save != -1) - /* If there are registers to push. */ - emit_insn (gen_push_for_prologue (GEN_INT (sum_regs))); - - if (size_for_adjusting_sp > 0) - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-size_for_adjusting_sp))); - - if (frame_pointer_needed) - /* Initialize the frame pointer with the value of the stack pointer - * pointing now to the locals. */ - emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); -} - -/* Generate insn that updates the stack for local variables and padding for - * registers we save. - Generate the appropriate return insn. */ - -void -crx_expand_epilogue (void) -{ - /* Nonzero if we need to return and pop only RA. This will generate a - * different insn. This differentiate is for the peepholes for call as last - * statement in function. */ - int only_popret_RA = (save_regs[RETURN_ADDRESS_REGNUM] - && (sum_regs == UNITS_PER_WORD)); - - if (frame_pointer_needed) - /* Restore the stack pointer with the frame pointers value */ - emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); - - if (size_for_adjusting_sp > 0) - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (size_for_adjusting_sp))); - - if (crx_interrupt_function_p ()) - emit_jump_insn (gen_interrupt_return ()); - else if (last_reg_to_save == -1) - /* Nothing to pop */ - /* Don't output jump for interrupt routine, only retx. */ - emit_jump_insn (gen_indirect_jump_return ()); - else if (only_popret_RA) - emit_jump_insn (gen_popret_RA_return ()); - else - emit_jump_insn (gen_pop_and_popret_return (GEN_INT (sum_regs))); -} diff --git a/gcc/config/crx/crx.h b/gcc/config/crx/crx.h deleted file mode 100644 index da6e263ca52..00000000000 --- a/gcc/config/crx/crx.h +++ /dev/null @@ -1,478 +0,0 @@ -/* Definitions of target machine for GNU compiler, for CRX. - Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - - 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 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#ifndef GCC_CRX_H -#define GCC_CRX_H - -/*****************************************************************************/ -/* CONTROLLING THE DRIVER */ -/*****************************************************************************/ - -#define CC1PLUS_SPEC "%{!frtti:-fno-rtti} \ - %{!fenforce-eh-specs:-fno-enforce-eh-specs} \ - %{!fexceptions:-fno-exceptions} \ - %{!fthreadsafe-statics:-fno-threadsafe-statics}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "crti.o%s crtbegin.o%s" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtend.o%s crtn.o%s" - -#undef MATH_LIBRARY -#define MATH_LIBRARY "" - -/*****************************************************************************/ -/* RUN-TIME TARGET SPECIFICATION */ -/*****************************************************************************/ - -#ifndef TARGET_CPU_CPP_BUILTINS -#define TARGET_CPU_CPP_BUILTINS() \ -do { \ - builtin_define("__CRX__"); \ - builtin_define("__CR__"); \ -} while (0) -#endif - -#define TARGET_VERSION fputs (" (CRX/ELF)", stderr); - -/*****************************************************************************/ -/* STORAGE LAYOUT */ -/*****************************************************************************/ - -#define BITS_BIG_ENDIAN 0 - -#define BYTES_BIG_ENDIAN 0 - -#define WORDS_BIG_ENDIAN 0 - -#define UNITS_PER_WORD 4 - -#define POINTER_SIZE 32 - -#define PARM_BOUNDARY 32 - -#define STACK_BOUNDARY 32 - -#define FUNCTION_BOUNDARY 32 - -#define STRUCTURE_SIZE_BOUNDARY 32 - -#define BIGGEST_ALIGNMENT 32 - -/* In CRX arrays of chars are word-aligned, so strcpy() will be faster. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == ARRAY_TYPE && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD \ - ? (BITS_PER_WORD) : (ALIGN)) - -/* In CRX strings are word-aligned so strcpy from constants will be faster. */ -#define CONSTANT_ALIGNMENT(CONSTANT, ALIGN) \ - (TREE_CODE (CONSTANT) == STRING_CST && (ALIGN) < BITS_PER_WORD \ - ? (BITS_PER_WORD) : (ALIGN)) - -#define STRICT_ALIGNMENT 0 - -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/*****************************************************************************/ -/* LAYOUT OF SOURCE LANGUAGE DATA TYPES */ -/*****************************************************************************/ - -#define INT_TYPE_SIZE 32 - -#define SHORT_TYPE_SIZE 16 - -#define LONG_TYPE_SIZE 32 - -#define LONG_LONG_TYPE_SIZE 64 - -#define FLOAT_TYPE_SIZE 32 - -#define DOUBLE_TYPE_SIZE 64 - -#define LONG_DOUBLE_TYPE_SIZE 64 - -#define DEFAULT_SIGNED_CHAR 1 - -#define SIZE_TYPE "unsigned int" - -#define PTRDIFF_TYPE "int" - -/*****************************************************************************/ -/* REGISTER USAGE. */ -/*****************************************************************************/ - -#define FIRST_PSEUDO_REGISTER 19 - -/* On the CRX, only the stack pointer (r15) is such. */ -#define FIXED_REGISTERS \ - { \ - /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 */ \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - /* r11 r12 r13 ra sp r16 r17 cc */ \ - 0, 0, 0, 0, 1, 0, 0, 1 \ - } - -/* On the CRX, calls clobbers r0-r6 (scratch registers), ra (the return address) - * and sp - (the stack pointer which is fixed). */ -#define CALL_USED_REGISTERS \ - { \ - /* r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 */ \ - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \ - /* r11 r12 r13 ra sp r16 r17 cc */ \ - 0, 0, 0, 1, 1, 1, 1, 1 \ - } - -#define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - -/* On the CRX architecture, HILO regs can only hold SI mode. */ -#define HARD_REGNO_MODE_OK(REGNO, MODE) crx_hard_regno_mode_ok(REGNO, MODE) - -/* So far no patterns for moving CCMODE data are available */ -#define AVOID_CCMODE_COPIES - -/* Interrupt functions can only use registers that have already been saved by - * the prologue, even if they would normally be call-clobbered. */ -#define HARD_REGNO_RENAME_OK(SRC, DEST) \ - (!crx_interrupt_function_p () || df_regs_ever_live_p (DEST)) - -#define MODES_TIEABLE_P(MODE1, MODE2) 1 - -enum reg_class -{ - NO_REGS, - LO_REGS, - HI_REGS, - HILO_REGS, - NOSP_REGS, - GENERAL_REGS, - ALL_REGS, - LIM_REG_CLASSES -}; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* The following macro defines cover classes for Integrated Register - Allocator. Cover classes is a set of non-intersected register - classes covering all hard registers used for register allocation - purpose. Any move between two registers of a cover class should be - cheaper than load or store of the registers. The macro value is - array of register classes with LIM_REG_CLASSES used as the end - marker. */ - -#define IRA_COVER_CLASSES \ -{ \ - GENERAL_REGS, LIM_REG_CLASSES \ -} - -#define REG_CLASS_NAMES \ - { \ - "NO_REGS", \ - "LO_REGS", \ - "HI_REGS", \ - "HILO_REGS", \ - "NOSP_REGS", \ - "GENERAL_REGS", \ - "ALL_REGS" \ - } - -#define REG_CLASS_CONTENTS \ - { \ - {0x00000000}, /* NO_REGS */ \ - {0x00010000}, /* LO_REGS : 16 */ \ - {0x00020000}, /* HI_REGS : 17 */ \ - {0x00030000}, /* HILO_REGS : 16, 17 */ \ - {0x00007fff}, /* NOSP_REGS : 0 - 14 */ \ - {0x0000ffff}, /* GENERAL_REGS : 0 - 15 */ \ - {0x0007ffff} /* ALL_REGS : 0 - 18 */ \ - } - -#define REGNO_REG_CLASS(REGNO) crx_regno_reg_class(REGNO) - -#define BASE_REG_CLASS GENERAL_REGS - -#define INDEX_REG_CLASS GENERAL_REGS - -#define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'b' ? NOSP_REGS : \ - (C) == 'l' ? LO_REGS : \ - (C) == 'h' ? HI_REGS : \ - (C) == 'k' ? HILO_REGS : \ - NO_REGS) - -#define REGNO_OK_FOR_BASE_P(REGNO) \ - ((REGNO) < 16 \ - || (reg_renumber && (unsigned)reg_renumber[REGNO] < 16)) - -#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO) - -#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \ - crx_secondary_reload_class (CLASS, MODE, X) - -#define CLASS_MAX_NREGS(CLASS, MODE) \ - (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD - -#define SIGNED_INT_FITS_N_BITS(imm, N) \ - ((((imm) < ((long long)1<<((N)-1))) && ((imm) >= -((long long)1<<((N)-1)))) ? 1 : 0) - -#define UNSIGNED_INT_FITS_N_BITS(imm, N) \ - (((imm) < ((long long)1<<(N)) && (imm) >= (long long)0) ? 1 : 0) - -#define HILO_REGNO_P(regno) \ - (reg_classes_intersect_p(REGNO_REG_CLASS(regno), HILO_REGS)) - -#define INT_CST4(VALUE) \ - (((VALUE) >= -1 && (VALUE) <= 4) || (VALUE) == -4 \ - || (VALUE) == 7 || (VALUE) == 8 || (VALUE) == 16 || (VALUE) == 32 \ - || (VALUE) == 20 || (VALUE) == 12 || (VALUE) == 48) - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - /* Legal const for store immediate instructions */ \ - ((C) == 'I' ? UNSIGNED_INT_FITS_N_BITS(VALUE, 3) : \ - (C) == 'J' ? UNSIGNED_INT_FITS_N_BITS(VALUE, 4) : \ - (C) == 'K' ? UNSIGNED_INT_FITS_N_BITS(VALUE, 5) : \ - (C) == 'L' ? INT_CST4(VALUE) : \ - 0) - -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? crx_const_double_ok (VALUE) : \ - 0) - -/*****************************************************************************/ -/* STACK LAYOUT AND CALLING CONVENTIONS. */ -/*****************************************************************************/ - -#define STACK_GROWS_DOWNWARD - -#define STARTING_FRAME_OFFSET 0 - -#define STACK_POINTER_REGNUM 15 - -#define FRAME_POINTER_REGNUM 13 - -#define ARG_POINTER_REGNUM 12 - -#define STATIC_CHAIN_REGNUM 1 - -#define RETURN_ADDRESS_REGNUM 14 - -#define FIRST_PARM_OFFSET(FNDECL) 0 - -#define ELIMINABLE_REGS \ - { \ - { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ - } - -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ - do { \ - (OFFSET) = crx_initial_elimination_offset ((FROM), (TO)); \ - } while (0) - -/*****************************************************************************/ -/* PASSING FUNCTION ARGUMENTS */ -/*****************************************************************************/ - -#define ACCUMULATE_OUTGOING_ARGS (TARGET_NO_PUSH_ARGS) - -#define PUSH_ARGS (!TARGET_NO_PUSH_ARGS) - -#define PUSH_ROUNDING(BYTES) (((BYTES) + 3) & ~3) - -#ifndef CUMULATIVE_ARGS -struct cumulative_args -{ - int ints; -}; - -#define CUMULATIVE_ARGS struct cumulative_args -#endif - -/* On the CRX architecture, Varargs routines should receive their parameters on - * the stack. */ - -#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ - crx_init_cumulative_args(&(CUM), (FNTYPE), (LIBNAME)) - -#define FUNCTION_ARG_REGNO_P(REGNO) crx_function_arg_regno_p(REGNO) - -/*****************************************************************************/ -/* RETURNING FUNCTION VALUE */ -/*****************************************************************************/ - -/* On the CRX, the return value is in R0 */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - gen_rtx_REG(TYPE_MODE (VALTYPE), 0) - -#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, 0) - -#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0) - -#define CRX_STRUCT_VALUE_REGNUM 0 - -/*****************************************************************************/ -/* GENERATING CODE FOR PROFILING - NOT IMPLEMENTED */ -/*****************************************************************************/ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(STREAM, LABELNO) \ -{ \ - sorry ("profiler support for CRX"); \ -} - -/*****************************************************************************/ -/* TRAMPOLINES FOR NESTED FUNCTIONS - NOT SUPPORTED */ -/*****************************************************************************/ - -#define TRAMPOLINE_SIZE 32 - -/*****************************************************************************/ -/* ADDRESSING MODES */ -/*****************************************************************************/ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF \ - || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST \ - || GET_CODE (X) == CONST_INT) - -#define MAX_REGS_PER_ADDRESS 2 - -#define HAVE_POST_INCREMENT 1 -#define HAVE_POST_DECREMENT 1 -#define HAVE_POST_MODIFY_DISP 1 -#define HAVE_POST_MODIFY_REG 0 - -#ifdef REG_OK_STRICT -#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) -#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) -#else -#define REG_OK_FOR_BASE_P(X) 1 -#define REG_OK_FOR_INDEX_P(X) 1 -#endif /* REG_OK_STRICT */ - -#define LEGITIMATE_CONSTANT_P(X) 1 - -/*****************************************************************************/ -/* CONDITION CODE STATUS */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* RELATIVE COSTS OF OPERATIONS */ -/*****************************************************************************/ - -#define MEMORY_MOVE_COST(MODE, CLASS, IN) crx_memory_move_cost(MODE, CLASS, IN) -/* Moving to processor register flushes pipeline - thus asymmetric */ -#define REGISTER_MOVE_COST(MODE, FROM, TO) ((TO != GENERAL_REGS) ? 8 : 2) -/* Assume best case (branch predicted) */ -#define BRANCH_COST(speed_p, predictable_p) 2 - -#define SLOW_BYTE_ACCESS 1 - -/*****************************************************************************/ -/* DIVIDING THE OUTPUT INTO SECTIONS */ -/*****************************************************************************/ - -#define TEXT_SECTION_ASM_OP "\t.section\t.text" - -#define DATA_SECTION_ASM_OP "\t.section\t.data" - -#define BSS_SECTION_ASM_OP "\t.section\t.bss" - -/*****************************************************************************/ -/* POSITION INDEPENDENT CODE */ -/*****************************************************************************/ - -#define PIC_OFFSET_TABLE_REGNUM 12 - -#define LEGITIMATE_PIC_OPERAND_P(X) 1 - -/*****************************************************************************/ -/* ASSEMBLER FORMAT */ -/*****************************************************************************/ - -#define GLOBAL_ASM_OP "\t.globl\t" - -#undef USER_LABEL_PREFIX -#define USER_LABEL_PREFIX "_" - -#undef ASM_OUTPUT_LABELREF -#define ASM_OUTPUT_LABELREF(STREAM, NAME) \ - asm_fprintf (STREAM, "%U%s", (*targetm.strip_name_encoding) (NAME)); - -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/*****************************************************************************/ -/* INSTRUCTION OUTPUT */ -/*****************************************************************************/ - -#define REGISTER_NAMES \ - { \ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "r12", "r13", "ra", "sp", \ - "lo", "hi", "cc" \ - } - -#define PRINT_OPERAND(STREAM, X, CODE) \ - crx_print_operand(STREAM, X, CODE) - -#define PRINT_OPERAND_ADDRESS(STREAM, ADDR) \ - crx_print_operand_address(STREAM, ADDR) - -/*****************************************************************************/ -/* OUTPUT OF DISPATCH TABLES */ -/*****************************************************************************/ - -#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ - asm_fprintf ((STREAM), "\t.long\t.L%d\n", (VALUE)) - -/*****************************************************************************/ -/* ALIGNMENT IN ASSEMBLER FILE */ -/*****************************************************************************/ - -#define ASM_OUTPUT_ALIGN(STREAM, POWER) \ - asm_fprintf ((STREAM), "\t.align\t%d\n", 1 << (POWER)) - -/*****************************************************************************/ -/* MISCELLANEOUS PARAMETERS */ -/*****************************************************************************/ - -#define CASE_VECTOR_MODE Pmode - -#define MOVE_MAX 4 - -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -#define STORE_FLAG_VALUE 1 - -#define Pmode SImode - -#define FUNCTION_MODE QImode - -#endif /* ! GCC_CRX_H */ diff --git a/gcc/config/crx/crx.md b/gcc/config/crx/crx.md deleted file mode 100644 index 229e345d32f..00000000000 --- a/gcc/config/crx/crx.md +++ /dev/null @@ -1,899 +0,0 @@ -;; GCC machine description for CRX. -;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -;; 2001, 2002, 2003, 2004, 2007 -;; Free Software Foundation, Inc. -;; -;; 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 3, or (at your option) -;; any later version. -;; -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. */ - -;; Register numbers - -(define_constants - [(SP_REGNUM 15) ; Stack pointer - (RA_REGNUM 14) ; Return address - (LO_REGNUM 16) ; LO register - (HI_REGNUM 17) ; HI register - (CC_REGNUM 18) ; Condition code register - ] -) - -(define_attr "length" "" ( const_int 6 )) - -(define_asm_attributes - [(set_attr "length" "6")] -) - -;; Predicates - -(define_predicate "u4bits_operand" - (match_code "const_int,const_double") - { - if (GET_CODE (op) == CONST_DOUBLE) - return crx_const_double_ok (op); - return (UNSIGNED_INT_FITS_N_BITS(INTVAL(op), 4)) ? 1 : 0; - } -) - -(define_predicate "cst4_operand" - (and (match_code "const_int") - (match_test "INT_CST4(INTVAL(op))"))) - -(define_predicate "reg_or_u4bits_operand" - (ior (match_operand 0 "u4bits_operand") - (match_operand 0 "register_operand"))) - -(define_predicate "reg_or_cst4_operand" - (ior (match_operand 0 "cst4_operand") - (match_operand 0 "register_operand"))) - -(define_predicate "reg_or_sym_operand" - (ior (match_code "symbol_ref") - (match_operand 0 "register_operand"))) - -(define_predicate "cc_reg_operand" - (and (match_code "reg") - (match_test "REGNO (op) == CC_REGNUM"))) - -(define_predicate "nosp_reg_operand" - (and (match_operand 0 "register_operand") - (match_test "REGNO (op) != SP_REGNUM"))) - -(define_predicate "store_operand" - (and (match_operand 0 "memory_operand") - (not (match_operand 0 "push_operand")))) - -;; Mode Macro Definitions - -(define_mode_iterator ALLMT [QI HI SI SF DI DF]) -(define_mode_iterator CRXMM [QI HI SI SF]) -(define_mode_iterator CRXIM [QI HI SI]) -(define_mode_iterator DIDFM [DI DF]) -(define_mode_iterator SISFM [SI SF]) -(define_mode_iterator SHORT [QI HI]) - -(define_mode_attr tIsa [(QI "b") (HI "w") (SI "d") (SF "d")]) -(define_mode_attr lImmArith [(QI "4") (HI "4") (SI "6")]) -(define_mode_attr lImmRotl [(QI "2") (HI "2") (SI "4")]) -(define_mode_attr IJK [(QI "I") (HI "J") (SI "K")]) -(define_mode_attr iF [(QI "i") (HI "i") (SI "i") (DI "i") (SF "F") (DF "F")]) -(define_mode_attr JG [(QI "J") (HI "J") (SI "J") (DI "J") (SF "G") (DF "G")]) -; In HI or QI mode we push 4 bytes. -(define_mode_attr pushCnstr [(QI "X") (HI "X") (SI "<") (SF "<") (DI "<") (DF "<")]) -(define_mode_attr tpush [(QI "") (HI "") (SI "") (SF "") (DI "sp, ") (DF "sp, ")]) -(define_mode_attr lpush [(QI "2") (HI "2") (SI "2") (SF "2") (DI "4") (DF "4")]) - - -;; Code Macro Definitions - -(define_code_iterator sz_xtnd [sign_extend zero_extend]) -(define_code_attr sIsa [(sign_extend "") (zero_extend "u")]) -(define_code_attr sPat [(sign_extend "s") (zero_extend "u")]) -(define_code_attr szPat [(sign_extend "") (zero_extend "zero_")]) -(define_code_attr szIsa [(sign_extend "s") (zero_extend "z")]) - -(define_code_iterator sh_oprnd [ashift ashiftrt lshiftrt]) -(define_code_attr shIsa [(ashift "ll") (ashiftrt "ra") (lshiftrt "rl")]) -(define_code_attr shPat [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")]) - -(define_code_iterator mima_oprnd [smax umax smin umin]) -(define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")]) - -;; Addition Instructions - -(define_insn "adddi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (plus:DI (match_operand:DI 1 "register_operand" "%0,0") - (match_operand:DI 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "addd\t%L2, %L1\;addcd\t%H2, %H1" - [(set_attr "length" "4,12")] -) - -(define_insn "add<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (plus:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "add<tIsa>\t%2, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -;; Subtract Instructions - -(define_insn "subdi3" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "subd\t%L2, %L1\;subcd\t%H2, %H1" - [(set_attr "length" "4,12")] -) - -(define_insn "sub<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (minus:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "sub<tIsa>\t%2, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -;; Multiply Instructions - -(define_insn "mul<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (mult:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "mul<tIsa>\t%2, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -;; Widening-multiplication Instructions - -(define_insn "<sIsa>mulsidi3" - [(set (match_operand:DI 0 "register_operand" "=k") - (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r")) - (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r")))) - (clobber (reg:CC CC_REGNUM))] - "" - "mull<sPat>d\t%2, %1" - [(set_attr "length" "4")] -) - -(define_insn "<sIsa>mulhisi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%0")) - (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r")))) - (clobber (reg:CC CC_REGNUM))] - "" - "mul<sPat>wd\t%2, %0" - [(set_attr "length" "4")] -) - -(define_insn "<sIsa>mulqihi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%0")) - (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r")))) - (clobber (reg:CC CC_REGNUM))] - "" - "mul<sPat>bw\t%2, %0" - [(set_attr "length" "4")] -) - -;; Logical Instructions - and - -(define_insn "and<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (and:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "and<tIsa>\t%2, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -;; Logical Instructions - or - -(define_insn "ior<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (ior:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "or<tIsa>\t%2, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -;; Logical Instructions - xor - -(define_insn "xor<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (xor:CRXIM (match_operand:CRXIM 1 "register_operand" "%0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,i"))) - (clobber (reg:CC CC_REGNUM))] - "" - "xor<tIsa>\t%2, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -;; Sign and Zero Extend Instructions - -(define_insn "<szPat>extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (sz_xtnd:SI (match_operand:HI 1 "register_operand" "r"))) - (clobber (reg:CC CC_REGNUM))] - "" - "<szIsa>extwd\t%1, %0" - [(set_attr "length" "4")] -) - -(define_insn "<szPat>extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (sz_xtnd:SI (match_operand:QI 1 "register_operand" "r"))) - (clobber (reg:CC CC_REGNUM))] - "" - "<szIsa>extbd\t%1, %0" - [(set_attr "length" "4")] -) - -(define_insn "<szPat>extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (sz_xtnd:HI (match_operand:QI 1 "register_operand" "r"))) - (clobber (reg:CC CC_REGNUM))] - "" - "<szIsa>extbw\t%1, %0" - [(set_attr "length" "4")] -) - -;; Negation Instructions - -(define_insn "neg<mode>2" - [(set (match_operand:CRXIM 0 "register_operand" "=r") - (neg:CRXIM (match_operand:CRXIM 1 "register_operand" "r"))) - (clobber (reg:CC CC_REGNUM))] - "" - "neg<tIsa>\t%1, %0" - [(set_attr "length" "4")] -) - -;; Absolute Instructions - -(define_insn "abs<mode>2" - [(set (match_operand:CRXIM 0 "register_operand" "=r") - (abs:CRXIM (match_operand:CRXIM 1 "register_operand" "r"))) - (clobber (reg:CC CC_REGNUM))] - "" - "abs<tIsa>\t%1, %0" - [(set_attr "length" "4")] -) - -;; Max and Min Instructions - -(define_insn "<code><mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r") - (mima_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "%0") - (match_operand:CRXIM 2 "register_operand" "r")))] - "" - "<mimaIsa><tIsa>\t%2, %0" - [(set_attr "length" "4")] -) - -;; One's Complement - -(define_insn "one_cmpl<mode>2" - [(set (match_operand:CRXIM 0 "register_operand" "=r") - (not:CRXIM (match_operand:CRXIM 1 "register_operand" "0"))) - (clobber (reg:CC CC_REGNUM))] - "" - "xor<tIsa>\t$-1, %0" - [(set_attr "length" "2")] -) - -;; Rotate Instructions - -(define_insn "rotl<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (rotate:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0") - (match_operand:CRXIM 2 "nonmemory_operand" "r,<IJK>"))) - (clobber (reg:CC CC_REGNUM))] - "" - "@ - rotl<tIsa>\t%2, %0 - rot<tIsa>\t%2, %0" - [(set_attr "length" "4,<lImmRotl>")] -) - -(define_insn "rotr<mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r") - (rotatert:CRXIM (match_operand:CRXIM 1 "register_operand" "0") - (match_operand:CRXIM 2 "register_operand" "r"))) - (clobber (reg:CC CC_REGNUM))] - "" - "rotr<tIsa>\t%2, %0" - [(set_attr "length" "4")] -) - -;; Arithmetic Left and Right Shift Instructions - -(define_insn "<shPat><mode>3" - [(set (match_operand:CRXIM 0 "register_operand" "=r,r") - (sh_oprnd:CRXIM (match_operand:CRXIM 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "r,<IJK>"))) - (clobber (reg:CC CC_REGNUM))] - "" - "s<shIsa><tIsa>\t%2, %0" - [(set_attr "length" "2,2")] -) - -;; Bit Set Instructions - -(define_insn "extv" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "n") - (match_operand:SI 3 "const_int_operand" "n")))] - "" - { - static char buf[100]; - int strpntr; - int size = INTVAL (operands[2]); - int pos = INTVAL (operands[3]); - strpntr = sprintf (buf, "ram\t$%d, $31, $%d, %%1, %%0\;", - BITS_PER_WORD - (size + pos), BITS_PER_WORD - size); - sprintf (buf + strpntr, "srad\t$%d, %%0", BITS_PER_WORD - size); - return buf; - } - [(set_attr "length" "6")] -) - -(define_insn "extzv" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "const_int_operand" "n") - (match_operand:SI 3 "const_int_operand" "n")))] - "" - { - static char buf[40]; - int size = INTVAL (operands[2]); - int pos = INTVAL (operands[3]); - sprintf (buf, "ram\t$%d, $%d, $0, %%1, %%0", - (BITS_PER_WORD - pos) % BITS_PER_WORD, size - 1); - return buf; - } - [(set_attr "length" "4")] -) - -(define_insn "insv" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n")) - (match_operand:SI 3 "register_operand" "r"))] - "" - { - static char buf[40]; - int size = INTVAL (operands[1]); - int pos = INTVAL (operands[2]); - sprintf (buf, "rim\t$%d, $%d, $%d, %%3, %%0", - pos, size + pos - 1, pos); - return buf; - } - [(set_attr "length" "4")] -) - -;; Move Instructions - -(define_expand "mov<mode>" - [(set (match_operand:ALLMT 0 "nonimmediate_operand" "") - (match_operand:ALLMT 1 "general_operand" ""))] - "" - { - if (!(reload_in_progress || reload_completed)) - { - if (!register_operand (operands[0], <MODE>mode)) - { - if (push_operand (operands[0], <MODE>mode) ? - !nosp_reg_operand (operands[1], <MODE>mode) : - !reg_or_u4bits_operand (operands[1], <MODE>mode)) - { - operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]); - } - } - } - } -) - -(define_insn "push<mode>_internal" - [(set (match_operand:ALLMT 0 "push_operand" "=<pushCnstr>") - (match_operand:ALLMT 1 "nosp_reg_operand" "b"))] - "" - "push\t<tpush>%p1" - [(set_attr "length" "<lpush>")] -) - -(define_insn "mov<mode>_regs" - [(set (match_operand:SISFM 0 "register_operand" "=r, r, r, k") - (match_operand:SISFM 1 "nonmemory_operand" "r, <iF>, k, r"))] - "" - "@ - movd\t%1, %0 - movd\t%1, %0 - mfpr\t%1, %0 - mtpr\t%1, %0" - [(set_attr "length" "2,6,4,4")] -) - -(define_insn "mov<mode>_regs" - [(set (match_operand:DIDFM 0 "register_operand" "=r, r, r, k") - (match_operand:DIDFM 1 "nonmemory_operand" "r, <iF>, k, r"))] - "" - { - switch (which_alternative) - { - case 0: if (REGNO (operands[0]) > REGNO (operands[1])) - return "movd\t%H1, %H0\;movd\t%L1, %L0"; - else - return "movd\t%L1, %L0\;movd\t%H1, %H0"; - case 1: return "movd\t%H1, %H0\;movd\t%L1, %L0"; - case 2: return "mfpr\t%H1, %H0\;mfpr\t%L1, %L0"; - case 3: return "mtpr\t%H1, %H0\;mtpr\t%L1, %L0"; - default: gcc_unreachable (); - } - } - [(set_attr "length" "4,12,8,8")] -) - -(define_insn "mov<mode>_regs" ; no HI/QI mode in HILO regs - [(set (match_operand:SHORT 0 "register_operand" "=r, r") - (match_operand:SHORT 1 "nonmemory_operand" "r, i"))] - "" - "mov<tIsa>\t%1, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -(define_insn "mov<mode>_load" - [(set (match_operand:CRXMM 0 "register_operand" "=r") - (match_operand:CRXMM 1 "memory_operand" "m"))] - "" - "load<tIsa>\t%1, %0" - [(set_attr "length" "6")] -) - -(define_insn "mov<mode>_load" - [(set (match_operand:DIDFM 0 "register_operand" "=r") - (match_operand:DIDFM 1 "memory_operand" "m"))] - "" - { - rtx first_dest_reg = gen_rtx_REG (SImode, REGNO (operands[0])); - if (reg_overlap_mentioned_p (first_dest_reg, operands[1])) - return "loadd\t%H1, %H0\;loadd\t%L1, %L0"; - return "loadd\t%L1, %L0\;loadd\t%H1, %H0"; - } - [(set_attr "length" "12")] -) - -(define_insn "mov<mode>_store" - [(set (match_operand:CRXMM 0 "store_operand" "=m, m") - (match_operand:CRXMM 1 "reg_or_u4bits_operand" "r, <JG>"))] - "" - "stor<tIsa>\t%1, %0" - [(set_attr "length" "6")] -) - -(define_insn "mov<mode>_store" - [(set (match_operand:DIDFM 0 "store_operand" "=m, m") - (match_operand:DIDFM 1 "reg_or_u4bits_operand" "r, <JG>"))] - "" - "stord\t%H1, %H0\;stord\t%L1, %L0" - [(set_attr "length" "12")] -) - -;; Movmem Instruction - -(define_expand "movmemsi" - [(use (match_operand:BLK 0 "memory_operand" "")) - (use (match_operand:BLK 1 "memory_operand" "")) - (use (match_operand:SI 2 "nonmemory_operand" "")) - (use (match_operand:SI 3 "const_int_operand" ""))] - "" - { - if (crx_expand_movmem (operands[0], operands[1], operands[2], operands[3])) - DONE; - else - FAIL; - } -) - -;; Compare and Branch Instructions - -(define_insn "cbranchcc4" - [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(match_operand:CC 1 "cc_reg_operand" "r") - (match_operand 2 "cst4_operand" "L")]) - (label_ref (match_operand 3 "")) - (pc)))] - "" - "b%d0\t%l3" - [(set_attr "length" "6")] -) - -(define_insn "cbranch<mode>4" - [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(match_operand:CRXIM 1 "register_operand" "r") - (match_operand:CRXIM 2 "reg_or_cst4_operand" "rL")]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (reg:CC CC_REGNUM))] - "" - "cmpb%d0<tIsa>\t%2, %1, %l3" - [(set_attr "length" "6")] -) - - -;; Scond Instructions - -(define_expand "cstore<mode>4" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:CRXIM 2 "register_operand" "") - (match_operand:CRXIM 3 "nonmemory_operand" ""))) - (set (match_operand:SI 0 "register_operand") - (match_operator:SI 1 "ordered_comparison_operator" - [(reg:CC CC_REGNUM) (const_int 0)]))] - "" - "" -) - -(define_insn "cmp<mode>_internal" - [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:CRXIM 0 "register_operand" "r,r") - (match_operand:CRXIM 1 "nonmemory_operand" "r,i")))] - "" - "cmp<tIsa>\t%1, %0" - [(set_attr "length" "2,<lImmArith>")] -) - -(define_insn "sCOND_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 1 "ordered_comparison_operator" - [(reg:CC CC_REGNUM) (const_int 0)]))] - "" - "s%d1\t%0" - [(set_attr "length" "2")] -) - -;; Jumps and Branches - -(define_insn "indirect_jump_return" - [(parallel - [(set (pc) - (reg:SI RA_REGNUM)) - (return)]) - ] - "reload_completed" - "jump\tra" - [(set_attr "length" "2")] -) - -(define_insn "indirect_jump" - [(set (pc) - (match_operand:SI 0 "reg_or_sym_operand" "r,i"))] - "" - "@ - jump\t%0 - br\t%a0" - [(set_attr "length" "2,6")] -) - -(define_insn "interrupt_return" - [(parallel - [(unspec_volatile [(const_int 0)] 0) - (return)])] - "" - { - return crx_prepare_push_pop_string (1); - } - [(set_attr "length" "14")] -) - -(define_insn "jump_to_imm" - [(set (pc) - (match_operand 0 "immediate_operand" "i"))] - "" - "br\t%c0" - [(set_attr "length" "6")] -) - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "br\t%l0" - [(set_attr "length" "6")] -) - -;; Function Prologue and Epilogue - -(define_expand "prologue" - [(const_int 0)] - "" - { - crx_expand_prologue (); - DONE; - } -) - -(define_insn "push_for_prologue" - [(parallel - [(set (reg:SI SP_REGNUM) - (minus:SI (reg:SI SP_REGNUM) - (match_operand:SI 0 "immediate_operand" "i")))])] - "reload_completed" - { - return crx_prepare_push_pop_string (0); - } - [(set_attr "length" "4")] -) - -(define_expand "epilogue" - [(return)] - "" - { - crx_expand_epilogue (); - DONE; - } -) - -(define_insn "pop_and_popret_return" - [(parallel - [(set (reg:SI SP_REGNUM) - (plus:SI (reg:SI SP_REGNUM) - (match_operand:SI 0 "immediate_operand" "i"))) - (use (reg:SI RA_REGNUM)) - (return)]) - ] - "reload_completed" - { - return crx_prepare_push_pop_string (1); - } - [(set_attr "length" "4")] -) - -(define_insn "popret_RA_return" - [(parallel - [(use (reg:SI RA_REGNUM)) - (return)]) - ] - "reload_completed" - "popret\tra" - [(set_attr "length" "2")] -) - -;; Table Jump - -(define_insn "tablejump" - [(set (pc) - (match_operand:SI 0 "register_operand" "r")) - (use (label_ref:SI (match_operand 1 "" "" )))] - "" - "jump\t%0" - [(set_attr "length" "2")] -) - -;; Call Instructions - -(define_expand "call" - [(call (match_operand:QI 0 "memory_operand" "") - (match_operand 1 "" ""))] - "" - { - emit_call_insn (gen_crx_call (operands[0], operands[1])); - DONE; - } -) - -(define_expand "crx_call" - [(parallel - [(call (match_operand:QI 0 "memory_operand" "") - (match_operand 1 "" "")) - (clobber (reg:SI RA_REGNUM))])] - "" - "" -) - -(define_insn "crx_call_insn_branch" - [(call (mem:QI (match_operand:SI 0 "immediate_operand" "i")) - (match_operand 1 "" "")) - (clobber (match_operand:SI 2 "register_operand" "+r"))] - "" - "bal\tra, %a0" - [(set_attr "length" "6")] -) - -(define_insn "crx_call_insn_jump" - [(call (mem:QI (match_operand:SI 0 "register_operand" "r")) - (match_operand 1 "" "")) - (clobber (match_operand:SI 2 "register_operand" "+r"))] - "" - "jal\t%0" - [(set_attr "length" "2")] -) - -(define_insn "crx_call_insn_jalid" - [(call (mem:QI (mem:SI (plus:SI - (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "register_operand" "r")))) - (match_operand 2 "" "")) - (clobber (match_operand:SI 3 "register_operand" "+r"))] - "" - "jalid\t%0, %1" - [(set_attr "length" "4")] -) - -;; Call Value Instructions - -(define_expand "call_value" - [(set (match_operand 0 "general_operand" "") - (call (match_operand:QI 1 "memory_operand" "") - (match_operand 2 "" "")))] - "" - { - emit_call_insn (gen_crx_call_value (operands[0], operands[1], operands[2])); - DONE; - } -) - -(define_expand "crx_call_value" - [(parallel - [(set (match_operand 0 "general_operand" "") - (call (match_operand 1 "memory_operand" "") - (match_operand 2 "" ""))) - (clobber (reg:SI RA_REGNUM))])] - "" - "" -) - -(define_insn "crx_call_value_insn_branch" - [(set (match_operand 0 "" "=g") - (call (mem:QI (match_operand:SI 1 "immediate_operand" "i")) - (match_operand 2 "" ""))) - (clobber (match_operand:SI 3 "register_operand" "+r"))] - "" - "bal\tra, %a1" - [(set_attr "length" "6")] -) - -(define_insn "crx_call_value_insn_jump" - [(set (match_operand 0 "" "=g") - (call (mem:QI (match_operand:SI 1 "register_operand" "r")) - (match_operand 2 "" ""))) - (clobber (match_operand:SI 3 "register_operand" "+r"))] - "" - "jal\t%1" - [(set_attr "length" "2")] -) - -(define_insn "crx_call_value_insn_jalid" - [(set (match_operand 0 "" "=g") - (call (mem:QI (mem:SI (plus:SI - (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "register_operand" "r")))) - (match_operand 3 "" ""))) - (clobber (match_operand:SI 4 "register_operand" "+r"))] - "" - "jalid\t%0, %1" - [(set_attr "length" "4")] -) - -;; Nop - -(define_insn "nop" - [(const_int 0)] - "" - "" -) - -;; Multiply and Accumulate Instructions - -(define_insn "<sPat>madsidi3" - [(set (match_operand:DI 0 "register_operand" "+k") - (plus:DI - (mult:DI (sz_xtnd:DI (match_operand:SI 1 "register_operand" "%r")) - (sz_xtnd:DI (match_operand:SI 2 "register_operand" "r"))) - (match_dup 0))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_MAC" - "mac<sPat>d\t%2, %1" - [(set_attr "length" "4")] -) - -(define_insn "<sPat>madhisi3" - [(set (match_operand:SI 0 "register_operand" "+l") - (plus:SI - (mult:SI (sz_xtnd:SI (match_operand:HI 1 "register_operand" "%r")) - (sz_xtnd:SI (match_operand:HI 2 "register_operand" "r"))) - (match_dup 0))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_MAC" - "mac<sPat>w\t%2, %1" - [(set_attr "length" "4")] -) - -(define_insn "<sPat>madqihi3" - [(set (match_operand:HI 0 "register_operand" "+l") - (plus:HI - (mult:HI (sz_xtnd:HI (match_operand:QI 1 "register_operand" "%r")) - (sz_xtnd:HI (match_operand:QI 2 "register_operand" "r"))) - (match_dup 0))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_MAC" - "mac<sPat>b\t%2, %1" - [(set_attr "length" "4")] -) - -;; Loop Instructions - -(define_expand "doloop_end" - [(use (match_operand 0 "" "")) ; loop pseudo - (use (match_operand 1 "" "")) ; iterations; zero if unknown - (use (match_operand 2 "" "")) ; max iterations - (use (match_operand 3 "" "")) ; loop level - (use (match_operand 4 "" ""))] ; label - "" - { - if (INTVAL (operands[3]) > crx_loop_nesting) - FAIL; - switch (GET_MODE (operands[0])) - { - case SImode: - emit_jump_insn (gen_doloop_end_si (operands[4], operands[0])); - break; - case HImode: - emit_jump_insn (gen_doloop_end_hi (operands[4], operands[0])); - break; - case QImode: - emit_jump_insn (gen_doloop_end_qi (operands[4], operands[0])); - break; - default: - FAIL; - } - DONE; - } -) - -; CRX dbnz[bwd] used explicitly (see above) but also by the combiner. - -(define_insn "doloop_end_<mode>" - [(set (pc) - (if_then_else (ne (match_operand:CRXIM 1 "register_operand" "+r,!m") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_dup 1) (plus:CRXIM (match_dup 1) (const_int -1))) - (clobber (match_scratch:CRXIM 2 "=X,r")) - (clobber (reg:CC CC_REGNUM))] - "" - "@ - dbnz<tIsa>\t%1, %l0 - load<tIsa>\t%1, %2\;add<tIsa>\t$-1, %2\;stor<tIsa>\t%2, %1\;bne\t%l0" - [(set_attr "length" "6, 12")] -) diff --git a/gcc/config/crx/crx.opt b/gcc/config/crx/crx.opt deleted file mode 100644 index 7ff0be0e3a9..00000000000 --- a/gcc/config/crx/crx.opt +++ /dev/null @@ -1,34 +0,0 @@ -; Options for the National Semiconductor CRX port of the compiler. - -; Copyright (C) 2005, 2007 Free Software Foundation, Inc. -; -; 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 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -mmac -Target Report Mask(MAC) -Support multiply accumulate instructions - -mno-push-args -Target Report RejectNegative Mask(NO_PUSH_ARGS) -Do not use push to store function arguments - -mloop-nesting= -Common RejectNegative Joined UInteger Var(crx_loop_nesting) Init(12) -Restrict doloop to the given nesting level - -mdebug-addr -Target RejectNegative Var(TARGET_DEBUG_ADDR) Undocumented diff --git a/gcc/config/crx/t-crx b/gcc/config/crx/t-crx deleted file mode 100644 index 8bb62c6525f..00000000000 --- a/gcc/config/crx/t-crx +++ /dev/null @@ -1,37 +0,0 @@ -# CRX Target Makefile -# -# Copyright (C) 2005 Free Software Foundation, Inc. -# -# 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 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Mingw specific compilation fixes -USE_COLLECT2 = -STMP_FIXINC = - -# Software emulation for integer div and mod -LIB2FUNCS_EXTRA = $(srcdir)/config/udivmodsi4.c $(srcdir)/config/udivmod.c $(srcdir)/config/divmod.c - -# Build the floating point emulation libraries. -FPBIT = fp-bit.c -DPBIT = dp-bit.c - -fp-bit.c: $(srcdir)/config/fp-bit.c - echo '#define FLOAT' > fp-bit.c - cat $(srcdir)/config/fp-bit.c >> fp-bit.c - -dp-bit.c: $(srcdir)/config/fp-bit.c - cat $(srcdir)/config/fp-bit.c > dp-bit.c |