summaryrefslogtreecommitdiff
path: root/gcc/config/arc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arc')
-rwxr-xr-xgcc/config/arc/arc.c2203
-rwxr-xr-xgcc/config/arc/arc.h1642
-rwxr-xr-xgcc/config/arc/arc.md1630
-rwxr-xr-xgcc/config/arc/initfini.c157
-rwxr-xr-xgcc/config/arc/lib1funcs.asm273
-rwxr-xr-xgcc/config/arc/t-arc72
-rwxr-xr-xgcc/config/arc/xm-arc.h47
7 files changed, 0 insertions, 6024 deletions
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
deleted file mode 100755
index 64aec44..0000000
--- a/gcc/config/arc/arc.c
+++ /dev/null
@@ -1,2203 +0,0 @@
-/* Subroutines used for code generation on the Argonaut ARC cpu.
- Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* ??? This is an old port, and is undoubtedly suffering from bit rot. */
-
-#include <stdio.h>
-#include "config.h"
-#include "tree.h"
-#include "rtl.h"
-#include "regs.h"
-#include "hard-reg-set.h"
-#include "real.h"
-#include "insn-config.h"
-#include "conditions.h"
-#include "insn-flags.h"
-#include "output.h"
-#include "insn-attr.h"
-#include "flags.h"
-#include "expr.h"
-#include "recog.h"
-
-/* Which cpu we're compiling for (NULL(=base), ???). */
-char *arc_cpu_string;
-int arc_cpu_type;
-
-/* Name of mangle string to add to symbols to separate code compiled for each
- cpu (or NULL). */
-char *arc_mangle_cpu;
-
-/* Save the operands last given to a compare for use when we
- generate a scc or bcc insn. */
-rtx arc_compare_op0, arc_compare_op1;
-
-/* Name of text, data, and rodata sections, as specified on command line.
- Selected by -m{text,data,rodata} flags. */
-char *arc_text_string = ARC_DEFAULT_TEXT_SECTION;
-char *arc_data_string = ARC_DEFAULT_DATA_SECTION;
-char *arc_rodata_string = ARC_DEFAULT_RODATA_SECTION;
-
-/* Name of text, data, and rodata sections used in varasm.c. */
-char *arc_text_section;
-char *arc_data_section;
-char *arc_rodata_section;
-
-/* Array of valid operand punctuation characters. */
-char arc_punct_chars[256];
-
-/* Variables used by arc_final_prescan_insn to implement conditional
- execution. */
-static int arc_ccfsm_state;
-static int arc_ccfsm_current_cc;
-static rtx arc_ccfsm_target_insn;
-static int arc_ccfsm_target_label;
-
-/* The maximum number of insns skipped which will be conditionalised if
- possible. */
-#define MAX_INSNS_SKIPPED 3
-
-/* A nop is needed between a 4 byte insn that sets the condition codes and
- a branch that uses them (the same isn't true for an 8 byte insn that sets
- the condition codes). Set by arc_final_prescan_insn. Used by
- arc_print_operand. */
-static int last_insn_set_cc_p;
-static int current_insn_set_cc_p;
-static void record_cc_ref ();
-
-void arc_init_reg_tables ();
-
-/* Called by OVERRIDE_OPTIONS to initialize various things. */
-
-void
-arc_init (void)
-{
- if (arc_cpu_string == 0
- || !strcmp (arc_cpu_string, "base"))
- {
- /* Ensure we have a printable value for the .cpu pseudo-op. */
- arc_cpu_string = "base";
- arc_cpu_type = 0;
- arc_mangle_cpu = NULL;
- }
- else if (ARC_EXTENSION_CPU (arc_cpu_string))
- ; /* nothing to do */
- else
- {
- error ("bad value (%s) for -mcpu switch", arc_cpu_string);
- arc_cpu_string = "base";
- arc_cpu_type = 0;
- arc_mangle_cpu = NULL;
- }
-
- /* Set the pseudo-ops for the various standard sections. */
- arc_text_section = xmalloc (strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
- sprintf (arc_text_section, ARC_SECTION_FORMAT, arc_text_string);
- arc_data_section = xmalloc (strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1);
- sprintf (arc_data_section, ARC_SECTION_FORMAT, arc_data_string);
- arc_rodata_section = xmalloc (strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1);
- sprintf (arc_rodata_section, ARC_SECTION_FORMAT, arc_rodata_string);
-
- arc_init_reg_tables ();
-
- /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
- memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
- arc_punct_chars['#'] = 1;
- arc_punct_chars['*'] = 1;
- arc_punct_chars['?'] = 1;
- arc_punct_chars['!'] = 1;
- arc_punct_chars['~'] = 1;
-}
-
-/* The condition codes of the ARC, and the inverse function. */
-static char *arc_condition_codes[] =
-{
- "al", 0, "eq", "ne", "p", "n", "c", "nc", "v", "nv",
- "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
-};
-
-#define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
-
-/* Returns the index of the ARC condition code string in
- `arc_condition_codes'. COMPARISON should be an rtx like
- `(eq (...) (...))'. */
-
-static int
-get_arc_condition_code (comparison)
- rtx comparison;
-{
- switch (GET_CODE (comparison))
- {
- case EQ : return 2;
- case NE : return 3;
- case GT : return 10;
- case LE : return 11;
- case GE : return 12;
- case LT : return 13;
- case GTU : return 14;
- case LEU : return 15;
- case LTU : return 6;
- case GEU : return 7;
- default : abort ();
- }
- /*NOTREACHED*/
- return (42);
-}
-
-/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
- return the mode to be used for the comparison. */
-
-enum machine_mode
-arc_select_cc_mode (op, x, y)
- enum rtx_code op;
- rtx x, y;
-{
- switch (op)
- {
- case EQ :
- case NE :
- return CCZNmode;
- default :
- switch (GET_CODE (x))
- {
- case AND :
- case IOR :
- case XOR :
- case SIGN_EXTEND :
- case ZERO_EXTEND :
- return CCZNmode;
- case ASHIFT :
- case ASHIFTRT :
- case LSHIFTRT :
- return CCZNCmode;
- }
- }
- return CCmode;
-}
-
-/* Vectors to keep interesting information about registers where it can easily
- be got. We use to use the actual mode value as the bit number, but there
- is (or may be) more than 32 modes now. Instead we use two tables: one
- indexed by hard register number, and one indexed by mode. */
-
-/* The purpose of arc_mode_class is to shrink the range of modes so that
- they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
- mapped into one arc_mode_class mode. */
-
-enum arc_mode_class {
- C_MODE,
- S_MODE, D_MODE, T_MODE, O_MODE,
- SF_MODE, DF_MODE, TF_MODE, OF_MODE
-};
-
-/* Modes for condition codes. */
-#define C_MODES (1 << (int) C_MODE)
-
-/* Modes for single-word and smaller quantities. */
-#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
-
-/* Modes for double-word and smaller quantities. */
-#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
-
-/* Modes for quad-word and smaller quantities. */
-#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
-
-/* Value is 1 if register/mode pair is acceptable on arc. */
-
-unsigned int arc_hard_regno_mode_ok[] = {
- T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
- T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
- T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
- D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
-
- /* ??? Leave these as S_MODES for now. */
- S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
- S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
- S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
- S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES
-};
-
-unsigned int arc_mode_class [NUM_MACHINE_MODES];
-
-enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
-
-void
-arc_init_reg_tables ()
-{
- int i;
-
- for (i = 0; i < NUM_MACHINE_MODES; i++)
- {
- switch (GET_MODE_CLASS (i))
- {
- case MODE_INT:
- case MODE_PARTIAL_INT:
- case MODE_COMPLEX_INT:
- if (GET_MODE_SIZE (i) <= 4)
- arc_mode_class[i] = 1 << (int) S_MODE;
- else if (GET_MODE_SIZE (i) == 8)
- arc_mode_class[i] = 1 << (int) D_MODE;
- else if (GET_MODE_SIZE (i) == 16)
- arc_mode_class[i] = 1 << (int) T_MODE;
- else if (GET_MODE_SIZE (i) == 32)
- arc_mode_class[i] = 1 << (int) O_MODE;
- else
- arc_mode_class[i] = 0;
- break;
- case MODE_FLOAT:
- case MODE_COMPLEX_FLOAT:
- if (GET_MODE_SIZE (i) <= 4)
- arc_mode_class[i] = 1 << (int) SF_MODE;
- else if (GET_MODE_SIZE (i) == 8)
- arc_mode_class[i] = 1 << (int) DF_MODE;
- else if (GET_MODE_SIZE (i) == 16)
- arc_mode_class[i] = 1 << (int) TF_MODE;
- else if (GET_MODE_SIZE (i) == 32)
- arc_mode_class[i] = 1 << (int) OF_MODE;
- else
- arc_mode_class[i] = 0;
- break;
- case MODE_CC:
- default:
- /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
- we must explicitly check for them here. */
- if (i == (int) CCmode || i == (int) CCZNmode || i == (int) CCZNCmode)
- arc_mode_class[i] = 1 << (int) C_MODE;
- else
- arc_mode_class[i] = 0;
- break;
- }
- }
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- {
- if (i < 60)
- arc_regno_reg_class[i] = GENERAL_REGS;
- else if (i == 60)
- arc_regno_reg_class[i] = LPCOUNT_REG;
- else if (i == 61)
- arc_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
- else
- arc_regno_reg_class[i] = NO_REGS;
- }
-}
-
-/* ARC specific attribute support.
-
- The ARC has these attributes:
- interrupt - for interrupt functions
-*/
-
-/* Return nonzero if IDENTIFIER is a valid decl attribute. */
-
-int
-arc_valid_machine_decl_attribute (type, attributes, identifier, args)
- tree type;
- tree attributes;
- tree identifier;
- tree args;
-{
- if (identifier == get_identifier ("__interrupt__")
- && list_length (args) == 1
- && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
- {
- tree value = TREE_VALUE (args);
-
- if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
- || !strcmp (TREE_STRING_POINTER (value), "ilink2"))
- return 1;
- }
- return 0;
-}
-
-/* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
- and two if they are nearly compatible (which causes a warning to be
- generated). */
-
-int
-arc_comp_type_attributes (type1, type2)
- tree type1, type2;
-{
- return 1;
-}
-
-/* Set the default attributes for TYPE. */
-
-void
-arc_set_default_type_attributes (type)
- tree type;
-{
-}
-
-/* Acceptable arguments to the call insn. */
-
-int
-call_address_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (symbolic_operand (op, mode)
- || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
- || (GET_CODE (op) == REG));
-}
-
-int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) != MEM)
- return 0;
- op = XEXP (op, 0);
- return call_address_operand (op, mode);
-}
-
-/* Returns 1 if OP is a symbol reference. */
-
-int
-symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- switch (GET_CODE (op))
- {
- case SYMBOL_REF:
- case LABEL_REF:
- case CONST :
- return 1;
- default:
- return 0;
- }
-}
-
-/* Return truth value of statement that OP is a symbolic memory
- operand of mode MODE. */
-
-int
-symbolic_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
- if (GET_CODE (op) != MEM)
- return 0;
- op = XEXP (op, 0);
- return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
- || GET_CODE (op) == LABEL_REF);
-}
-
-/* Return true if OP is a short immediate (shimm) value. */
-
-int
-short_immediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) != CONST_INT)
- return 0;
- return SMALL_INT (INTVAL (op));
-}
-
-/* Return true if OP will require a long immediate (limm) value.
- This is currently only used when calculating length attributes. */
-
-int
-long_immediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- switch (GET_CODE (op))
- {
- case SYMBOL_REF :
- case LABEL_REF :
- case CONST :
- return 1;
- case CONST_INT :
- return !SMALL_INT (INTVAL (op));
- case CONST_DOUBLE :
- /* These can happen because large unsigned 32 bit constants are
- represented this way (the multiplication patterns can cause these
- to be generated). They also occur for SFmode values. */
- return 1;
- }
- return 0;
-}
-
-/* Return true if OP is a MEM that when used as a load or store address will
- require an 8 byte insn.
- Load and store instructions don't allow the same possibilities but they're
- similar enough that this one function will do.
- This is currently only used when calculating length attributes. */
-
-int
-long_immediate_loadstore_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) != MEM)
- return 0;
-
- op = XEXP (op, 0);
- switch (GET_CODE (op))
- {
- case SYMBOL_REF :
- case LABEL_REF :
- case CONST :
- return 1;
- case CONST_INT :
- /* This must be handled as "st c,[limm]". Ditto for load.
- Technically, the assembler could translate some possibilities to
- "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't
- assume that it does. */
- return 1;
- case CONST_DOUBLE :
- /* These can happen because large unsigned 32 bit constants are
- represented this way (the multiplication patterns can cause these
- to be generated). They also occur for SFmode values. */
- return 1;
- case REG :
- return 0;
- case PLUS :
- if (GET_CODE (XEXP (op, 1)) == CONST_INT
- && !SMALL_INT (INTVAL (XEXP (op, 1))))
- return 1;
- return 0;
- }
- return 0;
-}
-
-/* Return true if OP is an acceptable argument for a single word
- move source. */
-
-int
-move_src_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- switch (GET_CODE (op))
- {
- case SYMBOL_REF :
- case LABEL_REF :
- case CONST :
- return 1;
- case CONST_INT :
- return (LARGE_INT (INTVAL (op)));
- case CONST_DOUBLE :
- /* We can handle DImode integer constants in SImode if the value
- (signed or unsigned) will fit in 32 bits. This is needed because
- large unsigned 32 bit constants are represented as CONST_DOUBLEs. */
- if (mode == SImode)
- return arc_double_limm_p (op);
- /* We can handle 32 bit floating point constants. */
- if (mode == SFmode)
- return GET_MODE (op) == SFmode;
- return 0;
- case REG :
- return register_operand (op, mode);
- case SUBREG :
- /* (subreg (mem ...) ...) can occur here if the inner part was once a
- pseudo-reg and is now a stack slot. */
- if (GET_CODE (SUBREG_REG (op)) == MEM)
- return address_operand (XEXP (SUBREG_REG (op), 0), mode);
- else
- return register_operand (op, mode);
- case MEM :
- return address_operand (XEXP (op, 0), mode);
- default :
- return 0;
- }
-}
-
-/* Return true if OP is an acceptable argument for a double word
- move source. */
-
-int
-move_double_src_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- switch (GET_CODE (op))
- {
- case REG :
- return register_operand (op, mode);
- case SUBREG :
- /* (subreg (mem ...) ...) can occur here if the inner part was once a
- pseudo-reg and is now a stack slot. */
- if (GET_CODE (SUBREG_REG (op)) == MEM)
- return move_double_src_operand (SUBREG_REG (op), mode);
- else
- return register_operand (op, mode);
- case MEM :
- /* Disallow auto inc/dec for now. */
- if (GET_CODE (XEXP (op, 0)) == PRE_DEC
- || GET_CODE (XEXP (op, 0)) == PRE_INC)
- return 0;
- return address_operand (XEXP (op, 0), mode);
- case CONST_INT :
- case CONST_DOUBLE :
- return 1;
- default :
- return 0;
- }
-}
-
-/* Return true if OP is an acceptable argument for a move destination. */
-
-int
-move_dest_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- switch (GET_CODE (op))
- {
- case REG :
- return register_operand (op, mode);
- case SUBREG :
- /* (subreg (mem ...) ...) can occur here if the inner part was once a
- pseudo-reg and is now a stack slot. */
- if (GET_CODE (SUBREG_REG (op)) == MEM)
- return address_operand (XEXP (SUBREG_REG (op), 0), mode);
- else
- return register_operand (op, mode);
- case MEM :
- return address_operand (XEXP (op, 0), mode);
- default :
- return 0;
- }
-}
-
-/* Return true if OP is valid load with update operand. */
-
-int
-load_update_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) != MEM
- || GET_MODE (op) != mode)
- return 0;
- op = XEXP (op, 0);
- if (GET_CODE (op) != PLUS
- || GET_MODE (op) != Pmode
- || !register_operand (XEXP (op, 0), Pmode)
- || !nonmemory_operand (XEXP (op, 1), Pmode))
- return 0;
- return 1;
-}
-
-/* Return true if OP is valid store with update operand. */
-
-int
-store_update_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) != MEM
- || GET_MODE (op) != mode)
- return 0;
- op = XEXP (op, 0);
- if (GET_CODE (op) != PLUS
- || GET_MODE (op) != Pmode
- || !register_operand (XEXP (op, 0), Pmode)
- || !(GET_CODE (XEXP (op, 1)) == CONST_INT
- && SMALL_INT (INTVAL (XEXP (op, 1)))))
- return 0;
- return 1;
-}
-
-/* Return true if OP is a non-volatile non-immediate operand.
- Volatile memory refs require a special "cache-bypass" instruction
- and only the standard movXX patterns are set up to handle them. */
-
-int
-nonvol_nonimm_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
- return 0;
- return nonimmediate_operand (op, mode);
-}
-
-/* Accept integer operands in the range -0x80000000..0x7fffffff. We have
- to check the range carefully since this predicate is used in DImode
- contexts. */
-
-int
-const_sint32_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- /* All allowed constants will fit a CONST_INT. */
- return (GET_CODE (op) == CONST_INT
- && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
-}
-
-/* Accept integer operands in the range 0..0xffffffff. We have to check the
- range carefully since this predicate is used in DImode contexts. Also, we
- need some extra crud to make it work when hosted on 64-bit machines. */
-
-int
-const_uint32_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
-#if HOST_BITS_PER_WIDE_INT > 32
- /* All allowed constants will fit a CONST_INT. */
- return (GET_CODE (op) == CONST_INT
- && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
-#else
- return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
- || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
-#endif
-}
-
-/* Return 1 if OP is a comparison operator valid for the mode of CC.
- This allows the use of MATCH_OPERATOR to recognize all the branch insns.
-
- Some insns only set a few bits in the condition code. So only allow those
- comparisons that use the bits that are valid. */
-
-int
-proper_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- enum rtx_code code = GET_CODE (op);
-
- if (GET_RTX_CLASS (code) != '<')
- return 0;
-
- if (GET_MODE (XEXP (op, 0)) == CCZNmode)
- return (code == EQ || code == NE);
- if (GET_MODE (XEXP (op, 0)) == CCZNCmode)
- return (code == EQ || code == NE
- || code == LTU || code == GEU || code == GTU || code == LEU);
- return 1;
-}
-
-/* Misc. utilities. */
-
-/* X and Y are two things to compare using CODE. Emit the compare insn and
- return the rtx for the cc reg in the proper mode. */
-
-rtx
-gen_compare_reg (code, x, y)
- enum rtx_code code;
- rtx x, y;
-{
- enum machine_mode mode = SELECT_CC_MODE (code, x, y);
- rtx cc_reg;
-
- cc_reg = gen_rtx (REG, mode, 61);
-
- emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
- gen_rtx (COMPARE, mode, x, y)));
-
- return cc_reg;
-}
-
-/* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
- We assume the value can be either signed or unsigned. */
-
-int
-arc_double_limm_p (value)
- rtx value;
-{
- HOST_WIDE_INT low, high;
-
- if (GET_CODE (value) != CONST_DOUBLE)
- abort ();
-
- low = CONST_DOUBLE_LOW (value);
- high = CONST_DOUBLE_HIGH (value);
-
- if (low & 0x80000000)
- {
- return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
- || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
- == - (unsigned HOST_WIDE_INT) 0x80000000)
- && high == -1));
- }
- else
- {
- return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
- }
-}
-
-/* Do any needed setup for a variadic function. For the ARC, we must
- create a register parameter block, and then copy any anonymous arguments
- in registers to memory.
-
- CUM has not been updated for the last named argument which has type TYPE
- and mode MODE, and we rely on this fact.
-
- We do things a little weird here. We're supposed to only allocate space
- for the anonymous arguments. However we need to keep the stack eight byte
- aligned. So we round the space up if necessary, and leave it to va-arc.h
- to compensate. */
-
-void
-arc_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int *pretend_size;
- int no_rtl;
-{
- int first_anon_arg;
-
- /* All BLKmode values are passed by reference. */
- if (mode == BLKmode)
- abort ();
-
- /* We must treat `__builtin_va_alist' as an anonymous arg. */
- if (current_function_varargs)
- first_anon_arg = *cum;
- else
- first_anon_arg = *cum + ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
-
- if (first_anon_arg < MAX_ARC_PARM_REGS && !no_rtl)
- {
- /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
- int first_reg_offset = first_anon_arg;
- /* Size in words to "pretend" allocate. */
- int size = MAX_ARC_PARM_REGS - first_reg_offset;
- /* Extra slop to keep stack eight byte aligned. */
- int align_slop = size & 1;
- rtx regblock;
-
- regblock = gen_rtx (MEM, BLKmode,
- plus_constant (arg_pointer_rtx,
- FIRST_PARM_OFFSET (0)
- + align_slop * UNITS_PER_WORD));
- move_block_from_reg (first_reg_offset, regblock,
- MAX_ARC_PARM_REGS - first_reg_offset,
- ((MAX_ARC_PARM_REGS - first_reg_offset)
- * UNITS_PER_WORD));
-
- *pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
- * UNITS_PER_WORD);
- }
-}
-
-/* Cost functions. */
-
-/* Provide the costs of an addressing mode that contains ADDR.
- If ADDR is not a valid address, its cost is irrelevant. */
-
-int
-arc_address_cost (addr)
- rtx addr;
-{
- switch (GET_CODE (addr))
- {
- case REG :
- /* This is handled in the macro that calls us.
- It's here for documentation. */
- return 1;
-
- case LABEL_REF :
- case SYMBOL_REF :
- case CONST :
- return 2;
-
- case PLUS :
- {
- register rtx plus0 = XEXP (addr, 0);
- register rtx plus1 = XEXP (addr, 1);
-
- if (GET_CODE (plus0) != REG)
- break;
-
- switch (GET_CODE (plus1))
- {
- case CONST_INT :
- return SMALL_INT (plus1) ? 1 : 2;
- case CONST :
- case SYMBOL_REF :
- case LABEL_REF :
- return 2;
- default:
- break;
- }
- break;
- }
- }
-
- return 4;
-}
-
-/* Function prologue/epilogue handlers. */
-
-/* ARC stack frames look like:
-
- Before call After call
- +-----------------------+ +-----------------------+
- | | | |
- high | local variables, | | local variables, |
- mem | reg save area, etc. | | reg save area, etc. |
- | | | |
- +-----------------------+ +-----------------------+
- | | | |
- | arguments on stack. | | arguments on stack. |
- | | | |
- SP+16->+-----------------------+FP+48->+-----------------------+
- | 4 word save area for | | reg parm save area, |
- | return addr, prev %fp | | only created for |
- SP+0->+-----------------------+ | variable argument |
- | functions |
- FP+16->+-----------------------+
- | 4 word save area for |
- | return addr, prev %fp |
- FP+0->+-----------------------+
- | |
- | local variables |
- | |
- +-----------------------+
- | |
- | register save area |
- | |
- +-----------------------+
- | |
- | alloca allocations |
- | |
- +-----------------------+
- | |
- | arguments on stack |
- | |
- SP+16->+-----------------------+
- low | 4 word save area for |
- memory | return addr, prev %fp |
- SP+0->+-----------------------+
-
-Notes:
-1) The "reg parm save area" does not exist for non variable argument fns.
- The "reg parm save area" can be eliminated completely if we created our
- own va-arc.h, but that has tradeoffs as well (so it's not done). */
-
-/* Structure to be filled in by arc_compute_frame_size with register
- save masks, and offsets for the current function. */
-struct arc_frame_info
-{
- unsigned int total_size; /* # bytes that the entire frame takes up. */
- unsigned int extra_size; /* # bytes of extra stuff. */
- unsigned int pretend_size; /* # bytes we push and pretend caller did. */
- unsigned int args_size; /* # bytes that outgoing arguments take up. */
- unsigned int reg_size; /* # bytes needed to store regs. */
- unsigned int var_size; /* # bytes that variables take up. */
- unsigned int reg_offset; /* Offset from new sp to store regs. */
- unsigned int gmask; /* Mask of saved gp registers. */
- int initialized; /* Nonzero if frame size already calculated. */
-};
-
-/* Current frame information calculated by arc_compute_frame_size. */
-static struct arc_frame_info current_frame_info;
-
-/* Zero structure to initialize current_frame_info. */
-static struct arc_frame_info zero_frame_info;
-
-/* Type of function DECL.
-
- The result is cached. To reset the cache at the end of a function,
- call with DECL = NULL_TREE. */
-
-enum arc_function_type
-arc_compute_function_type (decl)
- tree decl;
-{
- tree a;
- /* Cached value. */
- static enum arc_function_type fn_type = ARC_FUNCTION_UNKNOWN;
- /* Last function we were called for. */
- static tree last_fn = NULL_TREE;
-
- /* Resetting the cached value? */
- if (decl == NULL_TREE)
- {
- fn_type = ARC_FUNCTION_UNKNOWN;
- last_fn = NULL_TREE;
- return fn_type;
- }
-
- if (decl == last_fn && fn_type != ARC_FUNCTION_UNKNOWN)
- return fn_type;
-
- /* Assume we have a normal function (not an interrupt handler). */
- fn_type = ARC_FUNCTION_NORMAL;
-
- /* Now see if this is an interrupt handler. */
- for (a = DECL_MACHINE_ATTRIBUTES (current_function_decl);
- a;
- a = TREE_CHAIN (a))
- {
- tree name = TREE_PURPOSE (a), args = TREE_VALUE (a);
-
- if (name == get_identifier ("__interrupt__")
- && list_length (args) == 1
- && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
- {
- tree value = TREE_VALUE (args);
-
- if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
- fn_type = ARC_FUNCTION_ILINK1;
- else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
- fn_type = ARC_FUNCTION_ILINK2;
- else
- abort ();
- break;
- }
- }
-
- last_fn = decl;
- return fn_type;
-}
-
-#define ILINK1_REGNUM 29
-#define ILINK2_REGNUM 30
-#define RETURN_ADDR_REGNUM 31
-#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
-#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
-
-/* Tell prologue and epilogue if register REGNO should be saved / restored.
- The return address and frame pointer are treated separately.
- Don't consider them here. */
-#define MUST_SAVE_REGISTER(regno, interrupt_p) \
-((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
- && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
-
-#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
-
-/* Return the bytes needed to compute the frame pointer from the current
- stack pointer.
-
- SIZE is the size needed for local variables. */
-
-unsigned int
-arc_compute_frame_size (size)
- int size; /* # of var. bytes allocated. */
-{
- int regno;
- unsigned int total_size, var_size, args_size, pretend_size, extra_size;
- unsigned int reg_size, reg_offset;
- unsigned int gmask;
- enum arc_function_type fn_type;
- int interrupt_p;
-
- var_size = size;
- args_size = current_function_outgoing_args_size;
- pretend_size = current_function_pretend_args_size;
- extra_size = FIRST_PARM_OFFSET (0);
- total_size = extra_size + pretend_size + args_size + var_size;
- reg_offset = FIRST_PARM_OFFSET(0) + current_function_outgoing_args_size;
- reg_size = 0;
- gmask = 0;
-
- /* See if this is an interrupt handler. Call used registers must be saved
- for them too. */
- fn_type = arc_compute_function_type (current_function_decl);
- interrupt_p = ARC_INTERRUPT_P (fn_type);
-
- /* Calculate space needed for registers.
- ??? We ignore the extension registers for now. */
-
- for (regno = 0; regno <= 31; regno++)
- {
- if (MUST_SAVE_REGISTER (regno, interrupt_p))
- {
- reg_size += UNITS_PER_WORD;
- gmask |= 1 << regno;
- }
- }
-
- total_size += reg_size;
-
- /* If the only space to allocate is the fp/blink save area this is an
- empty frame. However, if we'll be making a function call we need to
- allocate a stack frame for our callee's fp/blink save area. */
- if (total_size == extra_size
- && !MUST_SAVE_RETURN_ADDR)
- total_size = extra_size = 0;
-
- total_size = ARC_STACK_ALIGN (total_size);
-
- /* Save computed information. */
- current_frame_info.total_size = total_size;
- current_frame_info.extra_size = extra_size;
- current_frame_info.pretend_size = pretend_size;
- current_frame_info.var_size = var_size;
- current_frame_info.args_size = args_size;
- current_frame_info.reg_size = reg_size;
- current_frame_info.reg_offset = reg_offset;
- current_frame_info.gmask = gmask;
- current_frame_info.initialized = reload_completed;
-
- /* Ok, we're done. */
- return total_size;
-}
-
-/* Common code to save/restore registers. */
-
-void
-arc_save_restore (file, base_reg, offset, gmask, op)
- FILE *file;
- char *base_reg;
- unsigned int offset;
- unsigned int gmask;
- char *op;
-{
- int regno;
-
- if (gmask == 0)
- return;
-
- for (regno = 0; regno <= 31; regno++)
- {
- if ((gmask & (1L << regno)) != 0)
- {
- fprintf (file, "\t%s %s,[%s,%d]\n",
- op, reg_names[regno], base_reg, offset);
- offset += UNITS_PER_WORD;
- }
- }
-}
-
-/* Set up the stack and frame pointer (if desired) for the function. */
-
-void
-arc_output_function_prologue (file, size)
- FILE *file;
- int size;
-{
- char *sp_str = reg_names[STACK_POINTER_REGNUM];
- char *fp_str = reg_names[FRAME_POINTER_REGNUM];
- unsigned int gmask = current_frame_info.gmask;
- enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
-
- /* If this is an interrupt handler, set up our stack frame.
- ??? Optimize later. */
- if (ARC_INTERRUPT_P (fn_type))
- {
- fprintf (file, "\t%s interrupt handler\n",
- ASM_COMMENT_START);
- fprintf (file, "\tsub %s,%s,16\n", sp_str, sp_str);
- }
-
- /* This is only for the human reader. */
- fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
- ASM_COMMENT_START, ASM_COMMENT_START,
- current_frame_info.var_size,
- current_frame_info.reg_size / 4,
- current_frame_info.args_size,
- current_frame_info.extra_size);
-
- size = ARC_STACK_ALIGN (size);
- size = (! current_frame_info.initialized
- ? arc_compute_frame_size (size)
- : current_frame_info.total_size);
-
- /* These cases shouldn't happen. Catch them now. */
- if (size == 0 && gmask)
- abort ();
-
- /* Allocate space for register arguments if this is a variadic function. */
- if (current_frame_info.pretend_size != 0)
- fprintf (file, "\tsub %s,%s,%d\n",
- sp_str, sp_str, current_frame_info.pretend_size);
-
- /* The home-grown ABI says link register is saved first. */
- if (MUST_SAVE_RETURN_ADDR)
- fprintf (file, "\tst %s,[%s,%d]\n",
- reg_names[RETURN_ADDR_REGNUM], sp_str, UNITS_PER_WORD);
-
- /* Set up the previous frame pointer next (if we need to). */
- if (frame_pointer_needed)
- {
- fprintf (file, "\tst %s,[%s]\n", fp_str, sp_str);
- fprintf (file, "\tmov %s,%s\n", fp_str, sp_str);
- }
-
- /* ??? We don't handle the case where the saved regs are more than 252
- bytes away from sp. This can be handled by decrementing sp once, saving
- the regs, and then decrementing it again. The epilogue doesn't have this
- problem as the `ld' insn takes reg+limm values (though it would be more
- efficient to avoid reg+limm). */
-
- /* Allocate the stack frame. */
- if (size - current_frame_info.pretend_size > 0)
- fprintf (file, "\tsub %s,%s,%d\n",
- sp_str, sp_str, size - current_frame_info.pretend_size);
-
- /* Save any needed call-saved regs (and call-used if this is an
- interrupt handler). */
- arc_save_restore (file, sp_str, current_frame_info.reg_offset,
- /* The zeroing of these two bits is unnecessary,
- but leave this in for clarity. */
- gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
- "st");
-
- fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
-}
-
-/* Do any necessary cleanup after a function to restore stack, frame,
- and regs. */
-
-void
-arc_output_function_epilogue (file, size)
- FILE *file;
- int size;
-{
- rtx epilogue_delay = current_function_epilogue_delay_list;
- int noepilogue = FALSE;
- enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
-
- /* This is only for the human reader. */
- fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
-
- size = ARC_STACK_ALIGN (size);
- size = (!current_frame_info.initialized
- ? arc_compute_frame_size (size)
- : current_frame_info.total_size);
-
- if (size == 0 && epilogue_delay == 0)
- {
- rtx insn = get_last_insn ();
-
- /* If the last insn was a BARRIER, we don't have to write any code
- because a jump (aka return) was put there. */
- if (GET_CODE (insn) == NOTE)
- insn = prev_nonnote_insn (insn);
- if (insn && GET_CODE (insn) == BARRIER)
- noepilogue = TRUE;
- }
-
- if (!noepilogue)
- {
- unsigned int pretend_size = current_frame_info.pretend_size;
- unsigned int frame_size = size - pretend_size;
- int restored, fp_restored_p;
- int can_trust_sp_p = !current_function_calls_alloca;
- char *sp_str = reg_names[STACK_POINTER_REGNUM];
- char *fp_str = reg_names[FRAME_POINTER_REGNUM];
-
- /* ??? There are lots of optimizations that can be done here.
- EG: Use fp to restore regs if it's closer.
- Maybe in time we'll do them all. For now, always restore regs from
- sp, but don't restore sp if we don't have to. */
-
- if (!can_trust_sp_p)
- {
- if (!frame_pointer_needed)
- abort ();
- fprintf (file,"\tsub %s,%s,%d\t\t%s sp not trusted here\n",
- sp_str, fp_str, frame_size, ASM_COMMENT_START);
- }
-
- /* Restore any saved registers. */
- arc_save_restore (file, sp_str, current_frame_info.reg_offset,
- /* The zeroing of these two bits is unnecessary,
- but leave this in for clarity. */
- current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
- "ld");
-
- if (MUST_SAVE_RETURN_ADDR)
- fprintf (file, "\tld %s,[%s,%d]\n",
- reg_names[RETURN_ADDR_REGNUM],
- frame_pointer_needed ? fp_str : sp_str,
- UNITS_PER_WORD + (frame_pointer_needed ? 0 : frame_size));
-
- /* Keep track of how much of the stack pointer we've restored.
- It makes the following a lot more readable. */
- restored = 0;
- fp_restored_p = 0;
-
- /* We try to emit the epilogue delay slot insn right after the load
- of the return address register so that it can execute with the
- stack intact. Secondly, loads are delayed. */
- /* ??? If stack intactness is important, always emit now. */
- if (MUST_SAVE_RETURN_ADDR && epilogue_delay != NULL_RTX)
- {
- final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
- epilogue_delay = NULL_RTX;
- }
-
- if (frame_pointer_needed)
- {
- /* Try to restore the frame pointer in the delay slot. We can't,
- however, if any of these is true. */
- if (epilogue_delay != NULL_RTX
- || !SMALL_INT (frame_size)
- || pretend_size
- || ARC_INTERRUPT_P (fn_type))
- {
- /* Note that we restore fp and sp here! */
- fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
- restored += frame_size;
- fp_restored_p = 1;
- }
- }
- else if (!SMALL_INT (size /* frame_size + pretend_size */)
- || ARC_INTERRUPT_P (fn_type))
- {
- fprintf (file, "\tadd %s,%s,%d\n", sp_str, sp_str, frame_size);
- restored += frame_size;
- }
-
- /* These must be done before the return insn because the delay slot
- does the final stack restore. */
- if (ARC_INTERRUPT_P (fn_type))
- {
- if (epilogue_delay)
- {
- final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
- }
- }
-
- /* Emit the return instruction. */
- {
- static int regs[4] = {
- 0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM
- };
- fprintf (file, "\tj.d %s\n", reg_names[regs[fn_type]]);
- }
-
- /* If the only register saved is the return address, we need a
- nop, unless we have an instruction to put into it. Otherwise
- we don't since reloading multiple registers doesn't reference
- the register being loaded. */
-
- if (ARC_INTERRUPT_P (fn_type))
- fprintf (file, "\tadd %s,%s,16\n", sp_str, sp_str);
- else if (epilogue_delay != NULL_RTX)
- {
- if (frame_pointer_needed && !fp_restored_p)
- abort ();
- if (restored < size)
- abort ();
- final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
- }
- else if (frame_pointer_needed && !fp_restored_p)
- {
- if (!SMALL_INT (frame_size))
- abort ();
- /* Note that we restore fp and sp here! */
- fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
- }
- else if (restored < size)
- {
- if (!SMALL_INT (size - restored))
- abort ();
- fprintf (file, "\tadd %s,%s,%d\n",
- sp_str, sp_str, size - restored);
- }
- else
- fprintf (file, "\tnop\n");
- }
-
- /* Reset state info for each function. */
- current_frame_info = zero_frame_info;
- arc_compute_function_type (NULL_TREE);
-}
-
-/* Define the number of delay slots needed for the function epilogue.
-
- Interrupt handlers can't have any epilogue delay slots (it's always needed
- for something else, I think). For normal functions, we have to worry about
- using call-saved regs as they'll be restored before the delay slot insn.
- Functions with non-empty frames already have enough choices for the epilogue
- delay slot so for now we only consider functions with empty frames. */
-
-int
-arc_delay_slots_for_epilogue ()
-{
- if (arc_compute_function_type (current_function_decl) != ARC_FUNCTION_NORMAL)
- return 0;
- if (!current_frame_info.initialized)
- (void) arc_compute_frame_size (get_frame_size ());
- if (current_frame_info.total_size == 0)
- return 1;
- return 0;
-}
-
-/* Return true if TRIAL is a valid insn for the epilogue delay slot.
- Any single length instruction which doesn't reference the stack or frame
- pointer or any call-saved register is OK. SLOT will always be 0. */
-
-int
-arc_eligible_for_epilogue_delay (trial, slot)
- rtx trial;
- int slot;
-{
- if (slot != 0)
- abort ();
-
- if (get_attr_length (trial) == 1
- /* If registers where saved, presumably there's more than enough
- possibilities for the delay slot. The alternative is something
- more complicated (of course, if we expanded the epilogue as rtl
- this problem would go away). */
- /* ??? Note that this will always be true since only functions with
- empty frames have epilogue delay slots. See
- arc_delay_slots_for_epilogue. */
- && current_frame_info.gmask == 0
- && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
- && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
- return 1;
- return 0;
-}
-
-/* PIC */
-
-/* Emit special PIC prologues and epilogues. */
-
-void
-arc_finalize_pic ()
-{
- /* nothing to do */
-}
-
-/* Return true if OP is a shift operator. */
-
-int
-shift_operator (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- switch (GET_CODE (op))
- {
- case ASHIFTRT:
- case LSHIFTRT:
- case ASHIFT:
- return 1;
- default:
- return 0;
- }
-}
-
-/* Output the assembler code for doing a shift.
- We go to a bit of trouble to generate efficient code as the ARC only has
- single bit shifts. This is taken from the h8300 port. We only have one
- mode of shifting and can't access individual bytes like the h8300 can, so
- this is greatly simplified (at the expense of not generating hyper-
- efficient code).
-
- This function is not used if the variable shift insns are present. */
-
-/* ??? We assume the output operand is the same as operand 1.
- This can be optimized (deleted) in the case of 1 bit shifts. */
-/* ??? We use the loop register here. We don't use it elsewhere (yet) and
- using it here will give us a chance to play with it. */
-
-char *
-output_shift (operands)
- rtx *operands;
-{
- static int loopend_lab;
- rtx shift = operands[3];
- enum machine_mode mode = GET_MODE (shift);
- enum rtx_code code = GET_CODE (shift);
- char *shift_one;
-
- if (mode != SImode)
- abort ();
-
- switch (code)
- {
- case ASHIFT: shift_one = "asl %0,%0"; break;
- case ASHIFTRT: shift_one = "asr %0,%0"; break;
- case LSHIFTRT: shift_one = "lsr %0,%0"; break;
- default: abort ();
- }
-
- if (GET_CODE (operands[2]) != CONST_INT)
- {
- if (optimize)
- output_asm_insn ("mov lp_count,%2", operands);
- else
- output_asm_insn ("mov %4,%2", operands);
- goto shiftloop;
- }
- else
- {
- int n = INTVAL (operands[2]);
-
- /* If the count is negative, make it 0. */
- if (n < 0)
- n = 0;
- /* If the count is too big, truncate it.
- ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
- do the intuitive thing. */
- else if (n > GET_MODE_BITSIZE (mode))
- n = GET_MODE_BITSIZE (mode);
-
- /* First see if we can do them inline. */
- if (n <= 8)
- {
- while (--n >= 0)
- output_asm_insn (shift_one, operands);
- }
- /* See if we can use a rotate/and. */
- else if (n == BITS_PER_WORD - 1)
- {
- switch (code)
- {
- case ASHIFT :
- output_asm_insn ("and %0,%0,1\n\tror %0,%0", operands);
- break;
- case ASHIFTRT :
- /* The ARC doesn't have a rol insn. Use something else. */
- output_asm_insn ("asl.f 0,%0\n\tsbc %0,0,0", operands);
- break;
- case LSHIFTRT :
- /* The ARC doesn't have a rol insn. Use something else. */
- output_asm_insn ("asl.f 0,%0\n\tadc %0,0,0", operands);
- break;
- }
- }
- /* Must loop. */
- else
- {
- char buf[100];
-
- if (optimize)
- output_asm_insn ("mov lp_count,%c2", operands);
- else
- output_asm_insn ("mov %4,%c2", operands);
- shiftloop:
- if (optimize)
- {
- if (flag_pic)
- sprintf ("lr %%4,[status]\n\tadd %%4,%%4,6\t%s single insn loop start",
- ASM_COMMENT_START);
- else
- sprintf (buf, "mov %%4,%%%%st(1f)\t%s (single insn loop start) >> 2",
- ASM_COMMENT_START);
- output_asm_insn (buf, operands);
- output_asm_insn ("sr %4,[lp_start]", operands);
- output_asm_insn ("add %4,%4,1", operands);
- output_asm_insn ("sr %4,[lp_end]", operands);
- output_asm_insn ("nop\n\tnop", operands);
- if (flag_pic)
- asm_fprintf (asm_out_file, "\t%s single insn loop\n",
- ASM_COMMENT_START);
- else
- asm_fprintf (asm_out_file, "1:\t%s single insn loop\n",
- ASM_COMMENT_START);
- output_asm_insn (shift_one, operands);
- }
- else
- {
- asm_fprintf (asm_out_file, "1:\t%s begin shift loop\n",
- ASM_COMMENT_START);
- output_asm_insn ("sub.f %4,%4,1", operands);
- output_asm_insn ("nop", operands);
- output_asm_insn ("bn.nd 2f", operands);
- output_asm_insn (shift_one, operands);
- output_asm_insn ("b.nd 1b", operands);
- asm_fprintf (asm_out_file, "2:\t%s end shift loop\n",
- ASM_COMMENT_START);
- }
- }
- }
-
- return "";
-}
-
-/* Nested function support. */
-
-/* Emit RTL insns to initialize the variable parts of a trampoline.
- FNADDR is an RTX for the address of the function's pure code.
- CXT is an RTX for the static chain value for the function. */
-
-void
-arc_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp, fnaddr, cxt;
-{
-}
-
-/* Set the cpu type and print out other fancy things,
- at the top of the file. */
-
-void
-arc_asm_file_start (file)
- FILE *file;
-{
- fprintf (file, "\t.cpu %s\n", arc_cpu_string);
-}
-
-/* Print operand X (an rtx) in assembler syntax to file FILE.
- CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
- For `%' followed by punctuation, CODE is the punctuation and X is null. */
-
-void
-arc_print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
-{
- switch (code)
- {
- case '#' :
- /* Conditional branches. For now these are equivalent. */
- case '*' :
- /* Unconditional branches. Output the appropriate delay slot suffix. */
- if (!final_sequence || XVECLEN (final_sequence, 0) == 1)
- {
- /* There's nothing in the delay slot. */
- fputs (".nd", file);
- }
- else
- {
- rtx jump = XVECEXP (final_sequence, 0, 0);
- rtx delay = XVECEXP (final_sequence, 0, 1);
- if (INSN_ANNULLED_BRANCH_P (jump))
- fputs (INSN_FROM_TARGET_P (delay) ? ".jd" : ".nd", file);
- else
- fputs (".d", file);
- }
- return;
- case '?' : /* with leading "." */
- case '!' : /* without leading "." */
- /* This insn can be conditionally executed. See if the ccfsm machinery
- says it should be conditionalized. */
- if (arc_ccfsm_state == 3 || arc_ccfsm_state == 4)
- {
- /* Is this insn in a delay slot? */
- if (final_sequence && XVECLEN (final_sequence, 0) == 2)
- {
- rtx insn = XVECEXP (final_sequence, 0, 1);
-
- /* If the insn is annulled and is from the target path, we need
- to inverse the condition test. */
- if (INSN_ANNULLED_BRANCH_P (insn))
- {
- if (INSN_FROM_TARGET_P (insn))
- fprintf (file, "%s%s",
- code == '?' ? "." : "",
- arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc)]);
- else
- fprintf (file, "%s%s",
- code == '?' ? "." : "",
- arc_condition_codes[arc_ccfsm_current_cc]);
- }
- else
- /* This insn is executed for either path, so don't
- conditionalize it at all. */
- ; /* nothing to do */
- }
- else
- {
- /* This insn isn't in a delay slot. */
- fprintf (file, "%s%s",
- code == '?' ? "." : "",
- arc_condition_codes[arc_ccfsm_current_cc]);
- }
- }
- return;
- case '~' :
- /* Output a nop if we're between a set of the condition codes,
- and a conditional branch. */
- if (last_insn_set_cc_p)
- fputs ("nop\n\t", file);
- return;
- case 'd' :
- fputs (arc_condition_codes[get_arc_condition_code (x)], file);
- return;
- case 'D' :
- fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
- (get_arc_condition_code (x))],
- file);
- return;
- case 'R' :
- /* Write second word of DImode or DFmode reference,
- register or memory. */
- if (GET_CODE (x) == REG)
- fputs (reg_names[REGNO (x)+1], file);
- else if (GET_CODE (x) == MEM)
- {
- fputc ('[', file);
- /* Handle possible auto-increment. Since it is pre-increment and
- we have already done it, we can just use an offset of four. */
- /* ??? This is taken from rs6000.c I think. I don't think it is
- currently necessary, but keep it around. */
- if (GET_CODE (XEXP (x, 0)) == PRE_INC
- || GET_CODE (XEXP (x, 0)) == PRE_DEC)
- output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
- else
- output_address (plus_constant (XEXP (x, 0), 4));
- fputc (']', file);
- }
- else
- output_operand_lossage ("invalid operand to %R code");
- return;
- case 'S' :
- if ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
- || GET_CODE (x) == LABEL_REF)
- {
- fprintf (file, "%%st(");
- output_addr_const (file, x);
- fprintf (file, ")");
- return;
- }
- break;
- case 'H' :
- case 'L' :
- if (GET_CODE (x) == REG)
- {
- /* L = least significant word, H = most significant word */
- if ((TARGET_BIG_ENDIAN != 0) ^ (code == 'L'))
- fputs (reg_names[REGNO (x)], file);
- else
- fputs (reg_names[REGNO (x)+1], file);
- }
- else if (GET_CODE (x) == CONST_INT
- || GET_CODE (x) == CONST_DOUBLE)
- {
- rtx first, second;
-
- split_double (x, &first, &second);
- fprintf (file, "0x%08lx",
- code == 'L' ? INTVAL (first) : INTVAL (second));
- }
- else
- output_operand_lossage ("invalid operand to %H/%L code");
- return;
- case 'A' :
- {
- REAL_VALUE_TYPE d;
- char str[30];
-
- if (GET_CODE (x) != CONST_DOUBLE
- || GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
- abort ();
- REAL_VALUE_FROM_CONST_DOUBLE (d, x);
- REAL_VALUE_TO_DECIMAL (d, "%.20e", str);
- fprintf (file, "%s", str);
- return;
- }
- case 'U' :
- /* Output a load/store with update indicator if appropriate. */
- if (GET_CODE (x) == MEM)
- {
- if (GET_CODE (XEXP (x, 0)) == PRE_INC
- || GET_CODE (XEXP (x, 0)) == PRE_DEC)
- fputs (".a", file);
- }
- else
- output_operand_lossage ("invalid operand to %U code");
- return;
- case 'V' :
- /* Output cache bypass indicator for a load/store insn. Volatile memory
- refs are defined to use the cache bypass mechanism. */
- if (GET_CODE (x) == MEM)
- {
- if (MEM_VOLATILE_P (x))
- fputs (".di", file);
- }
- else
- output_operand_lossage ("invalid operand to %V code");
- return;
- case 0 :
- /* Do nothing special. */
- break;
- default :
- /* Unknown flag. */
- output_operand_lossage ("invalid operand output code");
- }
-
- switch (GET_CODE (x))
- {
- case REG :
- fputs (reg_names[REGNO (x)], file);
- break;
- case MEM :
- fputc ('[', file);
- if (GET_CODE (XEXP (x, 0)) == PRE_INC)
- output_address (plus_constant (XEXP (XEXP (x, 0), 0),
- GET_MODE_SIZE (GET_MODE (x))));
- else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
- output_address (plus_constant (XEXP (XEXP (x, 0), 0),
- - GET_MODE_SIZE (GET_MODE (x))));
- else
- output_address (XEXP (x, 0));
- fputc (']', file);
- break;
- case CONST_DOUBLE :
- /* We handle SFmode constants here as output_addr_const doesn't. */
- if (GET_MODE (x) == SFmode)
- {
- REAL_VALUE_TYPE d;
- long l;
-
- REAL_VALUE_FROM_CONST_DOUBLE (d, x);
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- fprintf (file, "0x%08lx", l);
- break;
- }
- /* Fall through. Let output_addr_const deal with it. */
- default :
- output_addr_const (file, x);
- break;
- }
-}
-
-/* Print a memory address as an operand to reference that memory location. */
-
-void
-arc_print_operand_address (file, addr)
- FILE *file;
- rtx addr;
-{
- register rtx base, index = 0;
- int offset = 0;
-
- switch (GET_CODE (addr))
- {
- case REG :
- fputs (reg_names[REGNO (addr)], file);
- break;
- case SYMBOL_REF :
- if (/*???*/ 0 && SYMBOL_REF_FLAG (addr))
- {
- fprintf (file, "%%st(");
- output_addr_const (file, addr);
- fprintf (file, ")");
- }
- else
- output_addr_const (file, addr);
- break;
- case PLUS :
- if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
- offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
- else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
- offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
- else
- base = XEXP (addr, 0), index = XEXP (addr, 1);
- if (GET_CODE (base) != REG)
- abort ();
- fputs (reg_names[REGNO (base)], file);
- if (index == 0)
- {
- if (offset != 0)
- fprintf (file, ",%d", offset);
- }
- else if (GET_CODE (index) == REG)
- fprintf (file, ",%s", reg_names[REGNO (index)]);
- else if (GET_CODE (index) == SYMBOL_REF)
- fputc (',', file), output_addr_const (file, index);
- else
- abort ();
- break;
- case PRE_INC :
- case PRE_DEC :
- /* We shouldn't get here as we've lost the mode of the memory object
- (which says how much to inc/dec by. */
- abort ();
- break;
- default :
- output_addr_const (file, addr);
- break;
- }
-}
-
-/* Update compare/branch separation marker. */
-
-static void
-record_cc_ref (insn)
- rtx insn;
-{
- last_insn_set_cc_p = current_insn_set_cc_p;
-
- switch (get_attr_cond (insn))
- {
- case COND_SET :
- case COND_SET_ZN :
- case COND_SET_ZNC :
- if (get_attr_length (insn) == 1)
- current_insn_set_cc_p = 1;
- else
- current_insn_set_cc_p = 0;
- break;
- default :
- current_insn_set_cc_p = 0;
- break;
- }
-}
-
-/* Conditional execution support.
-
- This is based on the ARM port but for now is much simpler.
-
- A finite state machine takes care of noticing whether or not instructions
- can be conditionally executed, and thus decrease execution time and code
- size by deleting branch instructions. The fsm is controlled by
- final_prescan_insn, and controls the actions of PRINT_OPERAND. The patterns
- in the .md file for the branch insns also have a hand in this. */
-
-/* The state of the fsm controlling condition codes are:
- 0: normal, do nothing special
- 1: don't output this insn
- 2: don't output this insn
- 3: make insns conditional
- 4: make insns conditional
-
- State transitions (state->state by whom, under what condition):
- 0 -> 1 final_prescan_insn, if insn is conditional branch
- 0 -> 2 final_prescan_insn, if the `target' is an unconditional branch
- 1 -> 3 branch patterns, after having not output the conditional branch
- 2 -> 4 branch patterns, after having not output the conditional branch
- 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
- (the target label has CODE_LABEL_NUMBER equal to
- arc_ccfsm_target_label).
- 4 -> 0 final_prescan_insn, if `target' unconditional branch is reached
-
- If the jump clobbers the conditions then we use states 2 and 4.
-
- A similar thing can be done with conditional return insns.
-
- We also handle separating branches from sets of the condition code.
- This is done here because knowledge of the ccfsm state is required,
- we may not be outputting the branch. */
-
-void
-arc_final_prescan_insn (insn, opvec, noperands)
- rtx insn;
- rtx *opvec;
- int noperands;
-{
- /* BODY will hold the body of INSN. */
- register rtx body = PATTERN (insn);
-
- /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
- an if/then/else), and things need to be reversed. */
- int reverse = 0;
-
- /* If we start with a return insn, we only succeed if we find another one. */
- int seeking_return = 0;
-
- /* START_INSN will hold the insn from where we start looking. This is the
- first insn after the following code_label if REVERSE is true. */
- rtx start_insn = insn;
-
- /* Update compare/branch separation marker. */
- record_cc_ref (insn);
-
- /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
- We can't do this in macro FINAL_PRESCAN_INSN because its called from
- final_scan_insn which has `optimize' as a local. */
- if (optimize < 2 || TARGET_NO_COND_EXEC)
- return;
-
- /* If in state 4, check if the target branch is reached, in order to
- change back to state 0. */
- if (arc_ccfsm_state == 4)
- {
- if (insn == arc_ccfsm_target_insn)
- {
- arc_ccfsm_target_insn = NULL;
- arc_ccfsm_state = 0;
- }
- return;
- }
-
- /* If in state 3, it is possible to repeat the trick, if this insn is an
- unconditional branch to a label, and immediately following this branch
- is the previous target label which is only used once, and the label this
- branch jumps to is not too far off. Or in other words "we've done the
- `then' part, see if we can do the `else' part." */
- if (arc_ccfsm_state == 3)
- {
- if (simplejump_p (insn))
- {
- start_insn = next_nonnote_insn (start_insn);
- if (GET_CODE (start_insn) == BARRIER)
- {
- /* ??? Isn't this always a barrier? */
- start_insn = next_nonnote_insn (start_insn);
- }
- if (GET_CODE (start_insn) == CODE_LABEL
- && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
- && LABEL_NUSES (start_insn) == 1)
- reverse = TRUE;
- else
- return;
- }
- else if (GET_CODE (body) == RETURN)
- {
- start_insn = next_nonnote_insn (start_insn);
- if (GET_CODE (start_insn) == BARRIER)
- start_insn = next_nonnote_insn (start_insn);
- if (GET_CODE (start_insn) == CODE_LABEL
- && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
- && LABEL_NUSES (start_insn) == 1)
- {
- reverse = TRUE;
- seeking_return = 1;
- }
- else
- return;
- }
- else
- return;
- }
-
- if (GET_CODE (insn) != JUMP_INSN)
- return;
-
- /* This jump might be paralleled with a clobber of the condition codes,
- the jump should always come first. */
- if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
- body = XVECEXP (body, 0, 0);
-
- if (reverse
- || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
- && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
- {
- int insns_skipped = 0, fail = FALSE, succeed = FALSE;
- /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
- int then_not_else = TRUE;
- /* Nonzero if next insn must be the target label. */
- int next_must_be_target_label_p;
- rtx this_insn = start_insn, label = 0;
-
- /* Register the insn jumped to. */
- if (reverse)
- {
- if (!seeking_return)
- label = XEXP (SET_SRC (body), 0);
- }
- else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
- label = XEXP (XEXP (SET_SRC (body), 1), 0);
- else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
- {
- label = XEXP (XEXP (SET_SRC (body), 2), 0);
- then_not_else = FALSE;
- }
- else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
- seeking_return = 1;
- else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
- {
- seeking_return = 1;
- then_not_else = FALSE;
- }
- else
- abort ();
-
- /* See how many insns this branch skips, and what kind of insns. If all
- insns are okay, and the label or unconditional branch to the same
- label is not too far away, succeed. */
- for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
- !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
- insns_skipped++)
- {
- rtx scanbody;
-
- this_insn = next_nonnote_insn (this_insn);
- if (!this_insn)
- break;
-
- if (next_must_be_target_label_p)
- {
- if (GET_CODE (this_insn) == BARRIER)
- continue;
- if (GET_CODE (this_insn) == CODE_LABEL
- && this_insn == label)
- {
- arc_ccfsm_state = 1;
- succeed = TRUE;
- }
- else
- fail = TRUE;
- break;
- }
-
- scanbody = PATTERN (this_insn);
-
- switch (GET_CODE (this_insn))
- {
- case CODE_LABEL:
- /* Succeed if it is the target label, otherwise fail since
- control falls in from somewhere else. */
- if (this_insn == label)
- {
- arc_ccfsm_state = 1;
- succeed = TRUE;
- }
- else
- fail = TRUE;
- break;
-
- case BARRIER:
- /* Succeed if the following insn is the target label.
- Otherwise fail.
- If return insns are used then the last insn in a function
- will be a barrier. */
- next_must_be_target_label_p = TRUE;
- break;
-
- case CALL_INSN:
- /* Can handle a call insn if there are no insns after it.
- IE: The next "insn" is the target label. We don't have to
- worry about delay slots as such insns are SEQUENCE's inside
- INSN's. ??? It is possible to handle such insns though. */
- if (get_attr_cond (this_insn) == COND_CANUSE)
- next_must_be_target_label_p = TRUE;
- else
- fail = TRUE;
- break;
-
- case JUMP_INSN:
- /* If this is an unconditional branch to the same label, succeed.
- If it is to another label, do nothing. If it is conditional,
- fail. */
- /* ??? Probably, the test for the SET and the PC are unnecessary. */
-
- if (GET_CODE (scanbody) == SET
- && GET_CODE (SET_DEST (scanbody)) == PC)
- {
- if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
- && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
- {
- arc_ccfsm_state = 2;
- succeed = TRUE;
- }
- else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
- fail = TRUE;
- }
- else if (GET_CODE (scanbody) == RETURN
- && seeking_return)
- {
- arc_ccfsm_state = 2;
- succeed = TRUE;
- }
- else if (GET_CODE (scanbody) == PARALLEL)
- {
- if (get_attr_cond (this_insn) != COND_CANUSE)
- fail = TRUE;
- }
- break;
-
- case INSN:
- /* We can only do this with insns that can use the condition
- codes (and don't set them). */
- if (GET_CODE (scanbody) == SET
- || GET_CODE (scanbody) == PARALLEL)
- {
- if (get_attr_cond (this_insn) != COND_CANUSE)
- fail = TRUE;
- }
- /* We can't handle other insns like sequences. */
- else
- fail = TRUE;
- break;
-
- default:
- break;
- }
- }
-
- if (succeed)
- {
- if ((!seeking_return) && (arc_ccfsm_state == 1 || reverse))
- arc_ccfsm_target_label = CODE_LABEL_NUMBER (label);
- else if (seeking_return || arc_ccfsm_state == 2)
- {
- while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
- {
- this_insn = next_nonnote_insn (this_insn);
- if (this_insn && (GET_CODE (this_insn) == BARRIER
- || GET_CODE (this_insn) == CODE_LABEL))
- abort ();
- }
- if (!this_insn)
- {
- /* Oh dear! we ran off the end, give up. */
- insn_extract (insn);
- arc_ccfsm_state = 0;
- arc_ccfsm_target_insn = NULL;
- return;
- }
- arc_ccfsm_target_insn = this_insn;
- }
- else
- abort ();
-
- /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
- what it was. */
- if (!reverse)
- arc_ccfsm_current_cc = get_arc_condition_code (XEXP (SET_SRC (body),
- 0));
-
- if (reverse || then_not_else)
- arc_ccfsm_current_cc = ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc);
- }
-
- /* Restore recog_operand. Getting the attributes of other insns can
- destroy this array, but final.c assumes that it remains intact
- across this call; since the insn has been recognized already we
- call insn_extract direct. */
- insn_extract (insn);
- }
-}
-
-/* Record that we are currently outputting label NUM with prefix PREFIX.
- It it's the label we're looking for, reset the ccfsm machinery.
-
- Called from ASM_OUTPUT_INTERNAL_LABEL. */
-
-void
-arc_ccfsm_at_label (prefix, num)
- char *prefix;
- int num;
-{
- if (arc_ccfsm_state == 3 && arc_ccfsm_target_label == num
- && !strcmp (prefix, "L"))
- {
- arc_ccfsm_state = 0;
- arc_ccfsm_target_insn = NULL_RTX;
- }
-}
-
-/* See if the current insn, which is a conditional branch, is to be
- deleted. */
-
-int
-arc_ccfsm_branch_deleted_p ()
-{
- if (arc_ccfsm_state == 1 || arc_ccfsm_state == 2)
- return 1;
- return 0;
-}
-
-/* Record a branch isn't output because subsequent insns can be
- conditionalized. */
-
-void
-arc_ccfsm_record_branch_deleted ()
-{
- /* Indicate we're conditionalizing insns now. */
- arc_ccfsm_state += 2;
-
- /* If the next insn is a subroutine call, we still need a nop between the
- cc setter and user. We need to undo the effect of calling record_cc_ref
- for the just deleted branch. */
- current_insn_set_cc_p = last_insn_set_cc_p;
-}
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
deleted file mode 100755
index 49d9fe2..0000000
--- a/gcc/config/arc/arc.h
+++ /dev/null
@@ -1,1642 +0,0 @@
-/* Definitions of target machine for GNU compiler, Argonaut ARC cpu.
- Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* ??? This is an old port, and is undoubtedly suffering from bit rot. */
-
-/* Things to do:
-
- - PREDICATE_CODES
- - incscc, decscc?
- - print active compiler options in assembler output
-*/
-
-/* ??? Create elf.h and have svr4.h include it. */
-#include "svr4.h"
-
-#undef ASM_SPEC
-#undef LINK_SPEC
-#undef STARTFILE_SPEC
-#undef ENDFILE_SPEC
-#undef SIZE_TYPE
-#undef PTRDIFF_TYPE
-#undef WCHAR_TYPE
-#undef WCHAR_TYPE_SIZE
-
-/* Print subsidiary information on the compiler version in use. */
-#define TARGET_VERSION fprintf (stderr, " (arc)")
-
-/* Names to predefine in the preprocessor for this target machine. */
-#define CPP_PREDEFINES "-Acpu(arc) -Amachine(arc) -D__arc__"
-
-/* Additional flags for the preprocessor. */
-#define CPP_SPEC "\
-%{!mcpu=*:-D__base__} %{mcpu=base:-D__base__} \
-%{EB:-D__big_endian__} \
-"
-
-/* Pass -mmangle-cpu if we get -mcpu=*.
- Doing it this way lets one have it on as default with -mcpu=*,
- but also lets one turn it off with -mno-mangle-cpu. */
-#define CC1_SPEC "\
-%{mcpu=*:-mmangle-cpu} \
-%{EB:%{EL:%emay not use both -EB and -EL}} \
-%{EB:-mbig-endian} %{EL:-mlittle-endian} \
-"
-
-#define ASM_SPEC "%{v} %{EB} %{EL}"
-
-#define LINK_SPEC "%{v} %{EB} %{EL}"
-
-#define STARTFILE_SPEC "%{!shared:crt0.o%s} crtinit.o%s"
-
-#define ENDFILE_SPEC "crtfini.o%s"
-
-/* Run-time compilation parameters selecting different hardware subsets. */
-
-extern int target_flags;
-
-/* Mangle all user symbols for the specified cpu.
- ARC's can be shipped in which a collection of cpus are coupled together.
- Each CPU may be different in some way, and thus we may need to distinguish
- code compiled for one to ensure it isn't linked with code compiled for
- another. */
-#define TARGET_MASK_MANGLE_CPU 1
-#define TARGET_MANGLE_CPU (target_flags & TARGET_MASK_MANGLE_CPU)
-
-#if 0
-/* Mangle libgcc symbols by adding a suffix for the specified cpu. */
-#define TARGET_MASK_MANGLE_CPU_LIBGCC 2
-#define TARGET_MANGLE_CPU_LIBGCC (target_flags & TARGET_MASK_MANGLE_CPU_LIBGCC)
-#endif
-
-/* Align loops to 32 byte boundaries (cache line size). */
-#define TARGET_MASK_ALIGN_LOOPS 4
-#define TARGET_ALIGN_LOOPS (target_flags & TARGET_MASK_ALIGN_LOOPS)
-
-/* Big Endian. */
-#define TARGET_MASK_BIG_ENDIAN 8
-#define TARGET_BIG_ENDIAN (target_flags & TARGET_MASK_BIG_ENDIAN)
-
-/* Turn off conditional execution optimization,
- so we can see how well it does, or in case it's buggy. */
-#define TARGET_MASK_NO_COND_EXEC 0x10
-#define TARGET_NO_COND_EXEC (target_flags & TARGET_MASK_NO_COND_EXEC)
-
-/* Macro to define tables used to set the flags.
- This is a list in braces of pairs in braces,
- each pair being { "NAME", VALUE }
- where VALUE is the bits to set or minus the bits to clear.
- An empty string NAME is used to identify the default VALUE. */
-
-#define TARGET_SWITCHES \
-{ \
- { "mangle-cpu", TARGET_MASK_MANGLE_CPU }, \
- { "no-mangle-cpu", -TARGET_MASK_MANGLE_CPU }, \
-/* { "mangle-cpu-libgcc", TARGET_MASK_MANGLE_CPU_LIBGCC }, */ \
-/* { "no-mangle-cpu-libgcc", -TARGET_MASK_MANGLE_CPU_LIBGCC }, */ \
- { "align-loops", TARGET_MASK_ALIGN_LOOPS }, \
- { "no-align-loops", -TARGET_MASK_ALIGN_LOOPS }, \
- { "big-endian", TARGET_MASK_BIG_ENDIAN }, \
- { "little-endian", -TARGET_MASK_BIG_ENDIAN }, \
- { "no-cond-exec", TARGET_MASK_NO_COND_EXEC }, \
- SUBTARGET_SWITCHES \
- { "", TARGET_DEFAULT } \
-}
-
-#define TARGET_DEFAULT (0)
-
-#define SUBTARGET_SWITCHES
-
-/* Instruction set characteristics.
- These are internal macros, set by the appropriate -mcpu= option. */
-
-/* Non-zero means the cpu has a barrel shifter. */
-#define TARGET_SHIFTER 0
-
-/* This macro is similar to `TARGET_SWITCHES' but defines names of
- command options that have values. Its definition is an
- initializer with a subgrouping for each command option.
-
- Each subgrouping contains a string constant, that defines the
- fixed part of the option name, and the address of a variable.
- The variable, type `char *', is set to the variable part of the
- given option if the fixed part matches. The actual option name
- is made by appending `-m' to the specified name.
-
- Here is an example which defines `-mshort-data-NUMBER'. If the
- given option is `-mshort-data-512', the variable `m88k_short_data'
- will be set to the string `"512"'.
-
- extern char *m88k_short_data;
- #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
-
-extern char *arc_cpu_string;
-extern char *arc_text_string,*arc_data_string,*arc_rodata_string;
-
-#define TARGET_OPTIONS \
-{ \
- { "cpu=", &arc_cpu_string }, \
- { "text=", &arc_text_string }, \
- { "data=", &arc_data_string }, \
- { "rodata=", &arc_rodata_string }, \
-}
-
-/* Which cpu we're compiling for. */
-extern int arc_cpu_type;
-
-/* Check if CPU is an extension and set `arc_cpu_type' and `arc_mangle_cpu'
- appropriately. The result should be non-zero if the cpu is recognized,
- otherwise zero. This is intended to be redefined in a cover file.
- This is used by arc_init. */
-#define ARC_EXTENSION_CPU(cpu) 0
-
-/* Sometimes certain combinations of command options do not make
- sense on a particular target machine. You can define a macro
- `OVERRIDE_OPTIONS' to take account of this. This macro, if
- defined, is executed once just after all the command options have
- been parsed.
-
- Don't use this macro to turn on various extra optimizations for
- `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
-
-extern void arc_init ();
-
-#define OVERRIDE_OPTIONS \
-do { \
- /* These need to be done at start up. It's convenient to do them here. */ \
- arc_init (); \
-} while (0)
-
-/* Target machine storage layout. */
-
-/* Define to use software floating point emulator for REAL_ARITHMETIC and
- decimal <-> binary conversion. */
-#define REAL_ARITHMETIC
-
-/* Define this if most significant bit is lowest numbered
- in instructions that operate on numbered bit-fields. */
-#define BITS_BIG_ENDIAN 1
-
-/* Define this if most significant byte of a word is the lowest numbered. */
-#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
-
-/* Define this if most significant word of a multiword number is the lowest
- numbered. */
-#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
-
-/* Define this to set the endianness to use in libgcc2.c, which can
- not depend on target_flags. */
-#ifdef __big_endian__
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
-/* Number of bits in an addressable storage unit. */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
- Note that this is not necessarily the width of data type `int';
- if using 16-bit ints on a 68000, this would still be 32.
- But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD 32
-
-/* Width of a word, in units (bytes). */
-#define UNITS_PER_WORD 4
-
-/* Define this macro if it is advisable to hold scalars in registers
- in a wider mode than that declared by the program. In such cases,
- the value is constrained to be within the bounds of the declared
- type, but kept valid in the wider mode. The signedness of the
- extension may differ from that of the type. */
-#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
-if (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
-{ \
- (MODE) = SImode; \
-}
-
-/* Define this macro if the promotion described by `PROMOTE_MODE'
- should also be done for outgoing function arguments. */
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-#define PROMOTE_FUNCTION_RETURN
-
-/* Width in bits of a pointer.
- See also the macro `Pmode' defined below. */
-#define POINTER_SIZE 32
-
-/* Allocation boundary (in *bits*) for storing arguments in argument list. */
-#define PARM_BOUNDARY 32
-
-/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY 64
-
-/* ALIGN FRAMES on word boundaries */
-#define ARC_STACK_ALIGN(LOC) (((LOC)+7) & ~7)
-
-/* Allocation boundary (in *bits*) for the code of a function. */
-#define FUNCTION_BOUNDARY 32
-
-/* Alignment of field after `int : 0' in a structure. */
-#define EMPTY_FIELD_BOUNDARY 32
-
-/* Every structure's size must be a multiple of this. */
-#define STRUCTURE_SIZE_BOUNDARY 8
-
-/* A bitfield declared as `int' forces `int' alignment for the struct. */
-#define PCC_BITFIELD_TYPE_MATTERS 1
-
-/* No data type wants to be aligned rounder than this. */
-/* This is bigger than currently necessary for the ARC. If 8 byte floats are
- ever added it's not clear whether they'll need such alignment or not. For
- now we assume they will. We can always relax it if necessary but the
- reverse isn't true. */
-#define BIGGEST_ALIGNMENT 64
-
-/* The best alignment to use in cases where we have a choice. */
-#define FASTEST_ALIGNMENT 32
-
-/* Make strings word-aligned so strcpy from constants will be faster. */
-#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- ((TREE_CODE (EXP) == STRING_CST \
- && (ALIGN) < FASTEST_ALIGNMENT) \
- ? FASTEST_ALIGNMENT : (ALIGN))
-
-/* Make arrays of chars word-aligned for the same reasons. */
-#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (TREE_CODE (TYPE) == ARRAY_TYPE \
- && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
- && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
-
-/* Set this nonzero if move instructions will actually fail to work
- when given unaligned data. */
-/* On the ARC the lower address bits are masked to 0 as necessary. The chip
- won't croak when given an unaligned address, but the insn will still fail
- to produce the correct result. */
-#define STRICT_ALIGNMENT 1
-
-/* Layout of source language data types. */
-
-#define SHORT_TYPE_SIZE 16
-#define INT_TYPE_SIZE 32
-#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 this as 1 if `char' should by default be signed; else as 0. */
-#define DEFAULT_SIGNED_CHAR 1
-
-#define SIZE_TYPE "long unsigned int"
-#define PTRDIFF_TYPE "long int"
-#define WCHAR_TYPE "short unsigned int"
-#define WCHAR_TYPE_SIZE 16
-
-/* Define results of standard character escape sequences. */
-#define TARGET_BELL 007
-#define TARGET_BS 010
-#define TARGET_TAB 011
-#define TARGET_NEWLINE 012
-#define TARGET_VT 013
-#define TARGET_FF 014
-#define TARGET_CR 015
-
-/* Standard register usage. */
-
-/* Number of actual hardware registers.
- The hardware registers are assigned numbers for the compiler
- from 0 to just below FIRST_PSEUDO_REGISTER.
- All registers that the compiler knows about must be given numbers,
- even those that are not normally considered general registers. */
-/* Registers 61, 62, and 63 are not really registers and we needn't treat
- them as such. We still need a register for the condition code. */
-#define FIRST_PSEUDO_REGISTER 62
-
-/* 1 for registers that have pervasive standard uses
- and are not available for the register allocator.
-
- 0-28 - general purpose registers
- 29 - ilink1 (interrupt link register)
- 30 - ilink2 (interrupt link register)
- 31 - blink (branch link register)
- 32-59 - reserved for extensions
- 60 - LP_COUNT
- 61 - condition code
-
- For doc purposes:
- 61 - short immediate data indicator (setting flags)
- 62 - long immediate data indicator
- 63 - short immediate data indicator (not setting flags).
-
- The general purpose registers are further broken down into:
- 0-7 - arguments/results
- 8-15 - call used
- 16-23 - call saved
- 24 - call used, static chain pointer
- 25 - call used, gptmp
- 26 - global pointer
- 27 - frame pointer
- 28 - stack pointer
-
- By default, the extension registers are not available. */
-
-#define FIXED_REGISTERS \
-{ 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 1, 1, 1, 1, 0, \
- \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1 }
-
-/* 1 for registers not available across function calls.
- These must include the FIXED_REGISTERS and also any
- registers that can be used without being saved.
- The latter must include the registers where values are returned
- and the register where structure-value addresses are passed.
- Aside from that, you can include as many other registers as you like. */
-
-#define CALL_USED_REGISTERS \
-{ 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1 }
-
-/* If defined, an initializer for a vector of integers, containing the
- numbers of hard registers in the order in which GNU CC should
- prefer to use them (from most preferred to least). */
-#define REG_ALLOC_ORDER \
-{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, \
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 31, \
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, \
- 27, 28, 29, 30 }
-
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
-((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
-extern unsigned int arc_hard_regno_mode_ok[];
-extern unsigned int arc_mode_class[];
-#define HARD_REGNO_MODE_OK(REGNO, MODE) \
-((arc_hard_regno_mode_ok[REGNO] & arc_mode_class[MODE]) != 0)
-
-/* A C expression that is nonzero if it is desirable to choose
- register allocation so as to avoid move instructions between a
- value of mode MODE1 and a value of mode MODE2.
-
- If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
- MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
- MODE2)' must be zero. */
-
-/* Tie QI/HI/SI modes together. */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
-(GET_MODE_CLASS (MODE1) == MODE_INT \
- && GET_MODE_CLASS (MODE2) == MODE_INT \
- && GET_MODE_SIZE (MODE1) <= UNITS_PER_WORD \
- && GET_MODE_SIZE (MODE2) <= UNITS_PER_WORD)
-
-/* Register classes and constants. */
-
-/* Define the classes of registers for register constraints in the
- machine description. Also define ranges of constants.
-
- One of the classes must always be named ALL_REGS and include all hard regs.
- If there is more than one class, another class must be named NO_REGS
- and contain no registers.
-
- The name GENERAL_REGS must be the name of a class (or an alias for
- another name such as ALL_REGS). This is the class of registers
- that is allowed by "g" or "r" in a register constraint.
- Also, registers outside this class are allocated only when
- instructions express preferences for them.
-
- The classes must be numbered in nondecreasing order; that is,
- a larger-numbered class must never be contained completely
- in a smaller-numbered class.
-
- For any two classes, it is very desirable that there be another
- class that represents their union.
-
- It is important that any condition codes have class NO_REGS.
- See `register_operand'. */
-
-enum reg_class {
- NO_REGS, LPCOUNT_REG, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
-};
-
-#define N_REG_CLASSES (int) LIM_REG_CLASSES
-
-/* Give names of register classes as strings for dump file. */
-#define REG_CLASS_NAMES \
-{ "NO_REGS", "LPCOUNT_REG", "GENERAL_REGS", "ALL_REGS" }
-
-/* Define which registers fit in which classes.
- This is an initializer for a vector of HARD_REG_SET
- of length N_REG_CLASSES. */
-
-#define REG_CLASS_CONTENTS \
-{ {0, 0}, {0, 0x10000000}, {0xffffffff, 0xfffffff}, \
- {0xffffffff, 0x1fffffff} }
-
-/* The same information, inverted:
- Return the class number of the smallest class containing
- reg number REGNO. This could be a conditional expression
- or could index an array. */
-extern enum reg_class arc_regno_reg_class[];
-#define REGNO_REG_CLASS(REGNO) \
-(arc_regno_reg_class[REGNO])
-
-/* The class value for index registers, and the one for base regs. */
-#define INDEX_REG_CLASS GENERAL_REGS
-#define BASE_REG_CLASS GENERAL_REGS
-
-/* Get reg_class from a letter such as appears in the machine description. */
-#define REG_CLASS_FROM_LETTER(C) \
-((C) == 'l' ? LPCOUNT_REG /* ??? needed? */ \
- : NO_REGS)
-
-/* These assume that REGNO is a hard or pseudo reg number.
- They give nonzero only if REGNO is a hard reg of the suitable class
- or a pseudo reg currently allocated to a suitable hard reg.
- Since they use reg_renumber, they are safe only once reg_renumber
- has been allocated, which happens in local-alloc.c. */
-#define REGNO_OK_FOR_BASE_P(REGNO) \
-((REGNO) < 29 || (unsigned) reg_renumber[REGNO] < 29)
-#define REGNO_OK_FOR_INDEX_P(REGNO) \
-((REGNO) < 29 || (unsigned) reg_renumber[REGNO] < 29)
-
-/* Given an rtx X being reloaded into a reg required to be
- in class CLASS, return the class of reg to actually use.
- In general this is just CLASS; but on some machines
- in some cases it is preferable to use a more restrictive class. */
-#define PREFERRED_RELOAD_CLASS(X,CLASS) \
-(CLASS)
-
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
-((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-/* The letters I, J, K, L, M, N, O, P in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- This macro defines what the ranges are.
- C is the letter, and VALUE is a constant value.
- Return 1 if VALUE is in the range specified by C. */
-/* 'I' is used for short immediates (always signed).
- 'J' is used for long immediates.
- 'K' is used for any constant up to 64 bits (for 64x32 situations?). */
-
-/* local to this file */
-#define SMALL_INT(X) ((unsigned) ((X) + 0x100) < 0x200)
-/* local to this file */
-#define LARGE_INT(X) \
-((X) >= (-(HOST_WIDE_INT) 0x7fffffff - 1) \
- && (X) <= (unsigned HOST_WIDE_INT) 0xffffffff)
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
-((C) == 'I' ? SMALL_INT (VALUE) \
- : (C) == 'J' ? LARGE_INT (VALUE) \
- : (C) == 'K' ? 1 \
- : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
- Here VALUE is the CONST_DOUBLE rtx itself. */
-/* 'G' is used for integer values for the multiplication insns where the
- operands are extended from 4 bytes to 8 bytes.
- 'H' is used when any 64 bit constant is allowed. */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-((C) == 'G' ? arc_double_limm_p (VALUE) \
- : (C) == 'H' ? 1 \
- : 0)
-
-/* A C expression that defines the optional machine-dependent constraint
- letters that can be used to segregate specific types of operands,
- usually memory references, for the target machine. It should return 1 if
- VALUE corresponds to the operand type represented by the constraint letter
- C. If C is not defined as an extra constraint, the value returned should
- be 0 regardless of VALUE. */
-/* ??? This currently isn't used. Waiting for PIC. */
-#if 0
-#define EXTRA_CONSTRAINT(VALUE, C) \
-((C) == 'R' ? (SYMBOL_REF_FLAG (VALUE) || GET_CODE (VALUE) == LABEL_REF) \
- : 0)
-#endif
-
-/* Stack layout and stack pointer usage. */
-
-/* Define this macro if pushing a word onto the stack moves the stack
- pointer to a smaller address. */
-#define STACK_GROWS_DOWNWARD
-
-/* Define this if the nominal address of the stack frame
- is at the high-address end of the local variables;
- that is, each additional local variable allocated
- goes at a more negative offset in the frame. */
-#define FRAME_GROWS_DOWNWARD
-
-/* Offset within stack frame to start allocating local variables at.
- If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
- first local allocated. Otherwise, it is the offset to the BEGINNING
- of the first local allocated. */
-#define STARTING_FRAME_OFFSET 0
-
-/* Offset from the stack pointer register to the first location at which
- outgoing arguments are placed. */
-#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET (0)
-
-/* Offset of first parameter from the argument pointer register value. */
-/* 4 bytes for each of previous fp, return address, and previous gp.
- 4 byte reserved area for future considerations. */
-#define FIRST_PARM_OFFSET(FNDECL) 16
-
-/* A C expression whose value is RTL representing the address in a
- stack frame where the pointer to the caller's frame is stored.
- Assume that FRAMEADDR is an RTL expression for the address of the
- stack frame itself.
-
- If you don't define this macro, the default is to return the value
- of FRAMEADDR--that is, the stack frame address is also the address
- of the stack word that points to the previous frame. */
-/* ??? unfinished */
-/*define DYNAMIC_CHAIN_ADDRESS (FRAMEADDR)*/
-
-/* A C expression whose value is RTL representing the value of the
- return address for the frame COUNT steps up from the current frame.
- FRAMEADDR is the frame pointer of the COUNT frame, or the frame
- pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME'
- is defined. */
-/* The current return address is in r31. The return address of anything
- farther back is at [%fp,4]. */
-#if 0 /* The default value should work. */
-#define RETURN_ADDR_RTX(COUNT, FRAME) \
-(((COUNT) == -1) \
- ? gen_rtx (REG, Pmode, 31) \
- : copy_to_reg (gen_rtx (MEM, Pmode, \
- memory_address (Pmode, plus_constant ((FRAME), UNITS_PER_WORD)))))
-#endif
-
-/* Register to use for pushing function arguments. */
-#define STACK_POINTER_REGNUM 28
-
-/* Base register for access to local variables of the function. */
-#define FRAME_POINTER_REGNUM 27
-
-/* Base register for access to arguments of the function. */
-#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
-
-/* Register in which static-chain is passed to a function. This must
- not be a register used by the prologue. */
-#define STATIC_CHAIN_REGNUM 24
-
-/* A C expression which is nonzero if a function must have and use a
- frame pointer. This expression is evaluated in the reload pass.
- If its value is nonzero the function will have a frame pointer. */
-#define FRAME_POINTER_REQUIRED \
-(current_function_calls_alloca)
-
-/* C statement to store the difference between the frame pointer
- and the stack pointer values immediately after the function prologue. */
-#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
-((VAR) = arc_compute_frame_size (get_frame_size ()))
-
-/* Function argument passing. */
-
-/* When a prototype says `char' or `short', really pass an `int'. */
-#define PROMOTE_PROTOTYPES
-
-/* If defined, the maximum amount of space required for outgoing
- arguments will be computed and placed into the variable
- `current_function_outgoing_args_size'. No space will be pushed
- onto the stack for each call; instead, the function prologue should
- increase the stack frame size by this amount. */
-#define ACCUMULATE_OUTGOING_ARGS
-
-/* Value is the number of bytes of arguments automatically
- popped when returning from a subroutine call.
- FUNDECL is the declaration node of the function (as a tree),
- FUNTYPE is the data type of the function (as a tree),
- or for a library call it is an identifier node for the subroutine name.
- SIZE is the number of bytes of arguments passed on the stack. */
-#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0
-
-/* Define a data type for recording info about an argument list
- during the scan of that argument list. This data type should
- hold all necessary information about the function itself
- and about the args processed so far, enough to enable macros
- such as FUNCTION_ARG to determine where the next arg should go. */
-#define CUMULATIVE_ARGS int
-
-/* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
- For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
-((CUM) = 0)
-
-/* The number of registers used for parameter passing. Local to this file. */
-#define MAX_ARC_PARM_REGS 8
-
-/* 1 if N is a possible register number for function argument passing. */
-#define FUNCTION_ARG_REGNO_P(N) \
-((unsigned) (N) < MAX_ARC_PARM_REGS)
-
-/* The ROUND_ADVANCE* macros are local to this file. */
-/* Round SIZE up to a word boundary. */
-#define ROUND_ADVANCE(SIZE) \
-(((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-/* Round arg MODE/TYPE up to the next word boundary. */
-#define ROUND_ADVANCE_ARG(MODE, TYPE) \
-((MODE) == BLKmode \
- ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
- : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))
-
-/* Round CUM up to the necessary point for argument MODE/TYPE. */
-#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) \
-((((MODE) == BLKmode ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) \
- > BITS_PER_WORD) \
- ? ((CUM) + 1 & ~1) \
- : (CUM))
-
-/* Return boolean indicating arg of type TYPE and mode MODE will be passed in
- a reg. This includes arguments that have to be passed by reference as the
- pointer to them is passed in a reg if one is available (and that is what
- we're given).
- When passing arguments NAMED is always 1. When receiving arguments NAMED
- is 1 for each argument except the last in a stdarg/varargs function. In
- a stdarg function we want to treat the last named arg as named. In a
- varargs function we want to treat the last named arg (which is
- `__builtin_va_alist') as unnamed.
- This macro is only used in this file. */
-extern int current_function_varargs;
-#define PASS_IN_REG_P(CUM, MODE, TYPE, NAMED) \
-((!current_function_varargs || (NAMED)) \
- && (CUM) < MAX_ARC_PARM_REGS \
- && ((ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) \
- + ROUND_ADVANCE_ARG ((MODE), (TYPE)) \
- <= MAX_ARC_PARM_REGS)))
-
-/* Determine where to put an argument to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-
- MODE is the argument's machine mode.
- TYPE is the data type of the argument (as a tree).
- This is null for libcalls where that information may
- not be available.
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called.
- NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis). */
-/* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
- and the rest are pushed. */
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-(PASS_IN_REG_P ((CUM), (MODE), (TYPE), (NAMED)) \
- ? gen_rtx (REG, (MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE))) \
- : 0)
-
-/* A C expression for the number of words, at the beginning of an
- argument, must be put in registers. The value must be zero for
- arguments that are passed entirely in registers or that are entirely
- pushed on the stack.
-
- On some machines, certain arguments must be passed partially in
- registers and partially in memory. On these machines, typically the
- first @var{n} words of arguments are passed in registers, and the rest
- on the stack. If a multi-word argument (a @code{double} or a
- structure) crosses that boundary, its first few words must be passed
- in registers and the rest must be pushed. This macro tells the
- compiler when this occurs, and how many of the words should go in
- registers. */
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
-
-/* A C expression that indicates when an argument must be passed by
- reference. If nonzero for an argument, a copy of that argument is
- made in memory and a pointer to the argument is passed instead of
- the argument itself. The pointer is passed in whatever way is
- appropriate for passing a pointer to that type. */
-/* All aggregates and arguments greater than 8 bytes are passed this way. */
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-(TYPE \
- && (AGGREGATE_TYPE_P (TYPE) \
- || int_size_in_bytes (TYPE) > 8))
-
-/* A C expression that indicates when it is the called function's
- responsibility to make copies of arguments passed by reference.
- If the callee can determine that the argument won't be modified, it can
- avoid the copy. */
-/* ??? We'd love to be able to use NAMED here. Unfortunately, it doesn't
- include the last named argument so we keep track of the args ourselves. */
-
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
-FUNCTION_ARG_PASS_BY_REFERENCE ((CUM), (MODE), (TYPE), (NAMED))
-
-/* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-((CUM) = (ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)) \
- + ROUND_ADVANCE_ARG ((MODE), (TYPE))))
-
-/* If defined, a C expression that gives the alignment boundary, in bits,
- of an argument with the specified mode and type. If it is not defined,
- PARM_BOUNDARY is used for all arguments. */
-#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
-(((TYPE) ? TYPE_ALIGN (TYPE) : GET_MODE_BITSIZE (MODE)) <= PARM_BOUNDARY \
- ? PARM_BOUNDARY \
- : 2 * PARM_BOUNDARY)
-
-/* This macro offers an alternative
- to using `__builtin_saveregs' and defining the macro
- `EXPAND_BUILTIN_SAVEREGS'. Use it to store the anonymous register
- arguments into the stack so that all the arguments appear to have
- been passed consecutively on the stack. Once this is done, you
- can use the standard implementation of varargs that works for
- machines that pass all their arguments on the stack.
-
- The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure,
- containing the values that obtain after processing of the named
- arguments. The arguments MODE and TYPE describe the last named
- argument--its machine mode and its data type as a tree node.
-
- The macro implementation should do two things: first, push onto the
- stack all the argument registers *not* used for the named
- arguments, and second, store the size of the data thus pushed into
- the `int'-valued variable whose name is supplied as the argument
- PRETEND_SIZE. The value that you store here will serve as
- additional offset for setting up the stack frame.
-
- If the argument NO_RTL is nonzero, it means that the
- arguments of the function are being analyzed for the second time.
- This happens for an inline function, which is not actually
- compiled until the end of the source file. The macro
- `SETUP_INCOMING_VARARGS' should not generate any instructions in
- this case. */
-
-#define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
-arc_setup_incoming_varargs(&ARGS_SO_FAR, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
-
-/* Function results. */
-
-/* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
-
-/* Define how to find the value returned by a library function
- assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, 0)
-
-/* 1 if N is a possible register number for a function value
- as seen by the caller. */
-/* ??? What about r1 in DI/DF values. */
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
-
-/* A C expression which can inhibit the returning of certain function
- values in registers, based on the type of value. A nonzero value says
- to return the function value in memory, just as large structures are
- always returned. Here TYPE will be a C expression of type `tree',
- representing the data type of the value. */
-#define RETURN_IN_MEMORY(TYPE) \
-(AGGREGATE_TYPE_P (TYPE) \
- || int_size_in_bytes (TYPE) > 8 \
- || TREE_ADDRESSABLE (TYPE))
-
-/* Tell GCC to use RETURN_IN_MEMORY. */
-#define DEFAULT_PCC_STRUCT_RETURN 0
-
-/* Register in which address to store a structure value
- is passed to a function, or 0 to use `invisible' first argument. */
-#define STRUCT_VALUE 0
-
-/* Function entry and exit. */
-
-/* This macro generates the assembly code for function entry.
- FILE is a stdio stream to output the code to.
- SIZE is an int: how many units of temporary storage to allocate.
- Refer to the array `regs_ever_live' to determine which registers
- to save; `regs_ever_live[I]' is nonzero if register number I
- is ever used in the function. This macro is responsible for
- knowing which registers should not be saved even if used. */
-#define FUNCTION_PROLOGUE(FILE, SIZE) \
-arc_output_function_prologue (FILE, SIZE)
-
-/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
- the stack pointer does not matter. The value is tested only in
- functions that have frame pointers.
- No definition is equivalent to always zero. */
-#define EXIT_IGNORE_STACK 0
-
-/* This macro generates the assembly code for function exit,
- on machines that need it. If FUNCTION_EPILOGUE is not defined
- then individual return instructions are generated for each
- return statement. Args are same as for FUNCTION_PROLOGUE.
-
- The function epilogue should not depend on the current stack pointer!
- It should use the frame pointer only. This is mandatory because
- of alloca; we also take advantage of it to omit stack adjustments
- before returning. */
-#define FUNCTION_EPILOGUE(FILE, SIZE) \
-arc_output_function_epilogue (FILE, SIZE)
-
-/* Epilogue delay slots. */
-#define DELAY_SLOTS_FOR_EPILOGUE arc_delay_slots_for_epilogue ()
-
-#define ELIGIBLE_FOR_EPILOGUE_DELAY(TRIAL, SLOTS_FILLED) \
-arc_eligible_for_epilogue_delay (TRIAL, SLOTS_FILLED)
-
-/* Output assembler code to FILE to increment profiler label # LABELNO
- for profiling a function entry. */
-#define FUNCTION_PROFILER(FILE, LABELNO)
-
-/* Trampolines. */
-/* ??? This doesn't work yet because GCC will use as the address of a nested
- function the address of the trampoline. We need to use that address
- right shifted by 2. It looks like we'll need PSImode after all. :-( */
-
-/* Output assembler code for a block containing the constant parts
- of a trampoline, leaving space for the variable parts. */
-/* On the ARC, the trampoline is quite simple as we have 32 bit immediate
- constants.
-
- mov r24,STATIC
- j.nd FUNCTION
-*/
-#define TRAMPOLINE_TEMPLATE(FILE) \
-do { \
- ASM_OUTPUT_INT (FILE, GEN_INT (0x631f7c00)); \
- ASM_OUTPUT_INT (FILE, const0_rtx); \
- ASM_OUTPUT_INT (FILE, GEN_INT (0x381f0000)); \
- ASM_OUTPUT_INT (FILE, const0_rtx); \
-} while (0)
-
-/* Length in units of the trampoline for entering a nested function. */
-#define TRAMPOLINE_SIZE 16
-
-/* Emit RTL insns to initialize the variable parts of a trampoline.
- FNADDR is an RTX for the address of the function's pure code.
- CXT is an RTX for the static chain value for the function. */
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-do { \
- emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 4)), CXT); \
- emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 12)), FNADDR); \
- emit_insn (gen_flush_icache (validize_mem (gen_rtx (MEM, SImode, TRAMP)))); \
-} while (0)
-
-/* Library calls. */
-
-/* Generate calls to memcpy, memcmp and memset. */
-#define TARGET_MEM_FUNCTIONS
-
-/* Addressing modes, and classification of registers for them. */
-
-/* Maximum number of registers that can appear in a valid memory address. */
-/* The `ld' insn allows 2, but the `st' insn only allows 1. */
-#define MAX_REGS_PER_ADDRESS 1
-
-/* We have pre inc/dec (load/store with update). */
-#define HAVE_PRE_INCREMENT 1
-#define HAVE_PRE_DECREMENT 1
-
-/* Recognize any constant value that is a valid address. */
-#define CONSTANT_ADDRESS_P(X) \
-(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
-
-/* Nonzero if the constant value X is a legitimate general operand.
- We can handle any 32 or 64 bit constant. */
-/* "1" should work since the largest constant should be a 64 bit critter. */
-/* ??? Not sure what to do for 64x32 compiler. */
-#define LEGITIMATE_CONSTANT_P(X) 1
-
-/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used.
-
- Most source files want to accept pseudo regs in the hope that
- they will get allocated to the class that the insn wants them to be in.
- Source files for reload pass need to be strict.
- After reload, it makes no difference, since pseudo regs have
- been eliminated by then. */
-
-#ifndef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) \
-((unsigned) REGNO (X) - 29 >= FIRST_PSEUDO_REGISTER - 29)
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) \
-((unsigned) REGNO (X) - 29 >= FIRST_PSEUDO_REGISTER - 29)
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
-#endif
-
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address. */
-/* The `ld' insn allows [reg],[reg+shimm],[reg+limm],[reg+reg],[limm]
- but the `st' insn only allows [reg],[reg+shimm],[limm].
- The only thing we can do is only allow the most strict case `st' and hope
- other parts optimize out the restrictions for `ld'. */
-
-/* local to this file */
-#define RTX_OK_FOR_BASE_P(X) \
-(REG_P (X) && REG_OK_FOR_BASE_P (X))
-
-/* local to this file */
-#define RTX_OK_FOR_INDEX_P(X) \
-(0 && /*???*/ REG_P (X) && REG_OK_FOR_INDEX_P (X))
-
-/* local to this file */
-/* ??? Loads can handle any constant, stores can only handle small ones. */
-#define RTX_OK_FOR_OFFSET_P(X) \
-(GET_CODE (X) == CONST_INT && SMALL_INT (INTVAL (X)))
-
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
-(GET_CODE (X) == PLUS \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
- && (RTX_OK_FOR_INDEX_P (XEXP (X, 1)) \
- || RTX_OK_FOR_OFFSET_P (XEXP (X, 1))))
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ if (RTX_OK_FOR_BASE_P (X)) \
- goto ADDR; \
- if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X))) \
- goto ADDR; \
- if (GET_CODE (X) == CONST_INT && LARGE_INT (INTVAL (X))) \
- goto ADDR; \
- if (GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == LABEL_REF \
- || GET_CODE (X) == CONST) \
- goto ADDR; \
- if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
- /* We're restricted here by the `st' insn. */ \
- && RTX_OK_FOR_BASE_P (XEXP ((X), 0))) \
- goto ADDR; \
-}
-
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output. */
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
-
-/* Go to LABEL if ADDR (a legitimate address expression)
- has an effect that depends on the machine mode it is used for. */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-{ if (GET_CODE (ADDR) == PRE_DEC) \
- goto LABEL; \
- if (GET_CODE (ADDR) == PRE_INC) \
- goto LABEL; \
-}
-
-/* Condition code usage. */
-
-/* Some insns set all condition code flags, some only set the ZNC flags, and
- some only set the ZN flags. */
-
-#define EXTRA_CC_MODES CCZNCmode, CCZNmode
-
-#define EXTRA_CC_NAMES "CCZNC", "CCZN"
-
-/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
- return the mode to be used for the comparison. */
-extern enum machine_mode arc_select_cc_mode ();
-#define SELECT_CC_MODE(OP, X, Y) \
-arc_select_cc_mode (OP, X, Y)
-
-/* Return non-zero if SELECT_CC_MODE will never return MODE for a
- floating point inequality comparison. */
-#define REVERSIBLE_CC_MODE(MODE) 1 /*???*/
-
-/* Costs. */
-
-/* An insn is define to cost 4 "units", and we work from there.
- COSTS_N_INSNS (N) is defined as (N) * 4 - 2 so that seems reasonable.
- Some values are supposed to be defined relative to each other and thus
- aren't necessarily related to COSTS_N_INSNS. */
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-/* Small integers are as cheap as registers. 4 byte values can be fetched
- as immediate constants - let's give that the cost of an extra insn. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT : \
- if (SMALL_INT (INTVAL (X))) \
- return 0; \
- /* fall through */ \
- case CONST : \
- case LABEL_REF : \
- case SYMBOL_REF : \
- return 4; \
- case CONST_DOUBLE : \
- { \
- rtx high, low; \
- split_double (X, &high, &low); \
- return 4 * (!SMALL_INT (INTVAL (high)) \
- + !SMALL_INT (INTVAL (low))); \
- }
-
-/* Compute the cost of an address. */
-#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : arc_address_cost (ADDR))
-
-/* Compute extra cost of moving data between one register class
- and another. */
-#define REGISTER_MOVE_COST(CLASS1, CLASS2) 2
-
-/* Compute the cost of moving data between registers and memory. */
-/* Memory is 3 times as expensive as registers.
- ??? Is that the right way to look at it? */
-#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
-(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
-
-/* The cost of a branch insn. */
-/* ??? What's the right value here? Branches are certainly more
- expensive than reg->reg moves. */
-#define BRANCH_COST 2
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. The purpose for the cost of MULT is to encourage
- `synth_mult' to find a synthetic multiply when reasonable.
-
- If we need more than 12 insns to do a multiply, then go out-of-line,
- since the call overhead will be < 10% of the cost of the multiply. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ASHIFT : \
- case ASHIFTRT : \
- case LSHIFTRT : \
- if (TARGET_SHIFTER) \
- return COSTS_N_INSNS (1); \
- if (GET_CODE (XEXP ((X), 1)) != CONST_INT) \
- return COSTS_N_INSNS (16); \
- return COSTS_N_INSNS (INTVAL (XEXP ((X), 1)));
-
-/* Nonzero if access to memory by bytes is slow and undesirable.
- For RISC chips, it means that access to memory by bytes is no
- better than access by words when possible, so grab a whole word
- and maybe make use of that. */
-#define SLOW_BYTE_ACCESS 1
-
-/* Define this macro if it is as good or better to call a constant
- function address than to call an address kept in a register. */
-/* On the ARC, calling through registers is slow. */
-#define NO_FUNCTION_CSE
-
-/* Define this macro if it is as good or better for a function to call
- itself with an explicit address than to call an address kept in a
- register. */
-/* On the ARC, calling through registers is slow. */
-#define NO_RECURSIVE_FUNCTION_CSE
-
-/* Section selection. */
-/* WARNING: These section names also appear in dwarfout.c. */
-
-/* The names of the text, data, and readonly-data sections are runtime
- selectable. */
-
-#define ARC_SECTION_FORMAT "\t.section %s"
-#define ARC_DEFAULT_TEXT_SECTION ".text"
-#define ARC_DEFAULT_DATA_SECTION ".data"
-#define ARC_DEFAULT_RODATA_SECTION ".rodata"
-
-extern char *arc_text_section,*arc_data_section,*arc_rodata_section;
-
-/* initfini.c uses this in an asm. */
-#if defined (CRT_INIT) || defined (CRT_FINI)
-#define TEXT_SECTION_ASM_OP "\t.section .text"
-#else
-#define TEXT_SECTION_ASM_OP arc_text_section /*"\t.section .text"*/
-#endif
-#define DATA_SECTION_ASM_OP arc_data_section /*"\t.section .data"*/
-
-#undef CONST_SECTION_ASM_OP
-#define CONST_SECTION_ASM_OP arc_rodata_section /*"\t.section .rodata"*/
-
-#define BSS_SECTION_ASM_OP "\t.section .bss"
-
-/* Define this macro if jump tables (for tablejump insns) should be
- output in the text section, along with the assembler instructions.
- Otherwise, the readonly data section is used.
- This macro is irrelevant if there is no separate readonly data section. */
-/*#define JUMP_TABLES_IN_TEXT_SECTION*/
-
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- The macro definition, if any, is executed immediately after the
- rtl for DECL or other node is created.
- The value of the rtl will be a `mem' whose address is a
- `symbol_ref'.
-
- The usual thing for this macro to do is to store a flag in the
- `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
- name string in the `symbol_ref' (if one bit is not enough
- information). */
-
-/* On the ARC, function addresses are not the same as normal addresses.
- Branch to absolute address insns take an address that is right-shifted
- by 2. We encode the fact that we have a function here, and then emit a
- special assembler op when outputting the address. */
-#define ENCODE_SECTION_INFO(DECL) \
-do { \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
-} while (0)
-
-/* Decode SYM_NAME and store the real name part in VAR, sans
- the characters that encode section info. Define this macro if
- ENCODE_SECTION_INFO alters the symbol's name string. */
-/*#define STRIP_NAME_ENCODING(VAR, SYM_NAME)*/
-
-/* For DWARF. Marginally different than default so output is "prettier"
- (and consistent with above). */
-#define PUSHSECTION_FORMAT "\t%s %s\n"
-
-/* Tell crtstuff.c we're using ELF. */
-#define OBJECT_FORMAT_ELF
-
-/* PIC */
-
-/* The register number of the register used to address a table of static
- data addresses in memory. In some cases this register is defined by a
- processor's ``application binary interface'' (ABI). When this macro
- is defined, RTL is generated for this register once, as with the stack
- pointer and frame pointer registers. If this macro is not defined, it
- is up to the machine-dependent files to allocate such a register (if
- necessary). */
-#define PIC_OFFSET_TABLE_REGNUM 26
-
-/* Define this macro if the register defined by PIC_OFFSET_TABLE_REGNUM is
- clobbered by calls. Do not define this macro if PIC_OFFSET_TABLE_REGNUM
- is not defined. */
-/* This register is call-saved on the ARC. */
-/*#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED*/
-
-/* By generating position-independent code, when two different programs (A
- and B) share a common library (libC.a), the text of the library can be
- shared whether or not the library is linked at the same address for both
- programs. In some of these environments, position-independent code
- requires not only the use of different addressing modes, but also
- special code to enable the use of these addressing modes.
-
- The FINALIZE_PIC macro serves as a hook to emit these special
- codes once the function is being compiled into assembly code, but not
- before. (It is not done before, because in the case of compiling an
- inline function, it would lead to multiple PIC prologues being
- included in functions which used inline functions and were compiled to
- assembly language.) */
-
-#define FINALIZE_PIC arc_finalize_pic ()
-
-/* A C expression that is nonzero if X is a legitimate immediate
- operand on the target machine when generating position independent code.
- You can assume that X satisfies CONSTANT_P, so you need not
- check this. You can also assume `flag_pic' is true, so you need not
- check it either. You need not define this macro if all constants
- (including SYMBOL_REF) can be immediate operands when generating
- position independent code. */
-/*#define LEGITIMATE_PIC_OPERAND_P(X)*/
-
-/* Control the assembler format that we output. */
-
-/* Output at beginning of assembler file. */
-extern void arc_asm_file_start ();
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) arc_asm_file_start (FILE)
-
-/* A C statement to output assembler commands which will identify the
- object file as having been compiled with GNU CC (or another GNU
- compiler). */
-#undef ASM_IDENTIFY_GCC
-#define ASM_IDENTIFY_GCC(FILE) /* nothing */
-
-/* Needed because we define ASM_IDENTIFY_GCC. */
-#define ASM_IDENTIFY_LANGUAGE(FILE) output_lang_identify (FILE)
-
-/* A C string constant describing how to begin a comment in the target
- assembler language. The compiler assumes that the comment will
- end at the end of the line. */
-#define ASM_COMMENT_START ";"
-
-/* Output to assembler file text saying following lines
- may contain character constants, extra white space, comments, etc. */
-#define ASM_APP_ON ""
-
-/* Output to assembler file text saying following lines
- no longer contain unusual constructs. */
-#define ASM_APP_OFF ""
-
-/* This is how to output an assembler line defining a `char' constant. */
-#define ASM_OUTPUT_CHAR(FILE, VALUE) \
-( fprintf (FILE, "\t.byte\t"), \
- output_addr_const (FILE, (VALUE)), \
- fprintf (FILE, "\n"))
-
-/* This is how to output an assembler line defining a `short' constant. */
-#define ASM_OUTPUT_SHORT(FILE, VALUE) \
-( fprintf (FILE, "\t.hword\t"), \
- output_addr_const (FILE, (VALUE)), \
- fprintf (FILE, "\n"))
-
-/* This is how to output an assembler line defining an `int' constant.
- We also handle symbol output here. Code addresses must be right shifted
- by 2 because that's how the jump instruction wants them. */
-#define ASM_OUTPUT_INT(FILE, VALUE) \
-do { \
- fprintf (FILE, "\t.word\t"); \
- if ((GET_CODE (VALUE) == SYMBOL_REF && SYMBOL_REF_FLAG (VALUE)) \
- || GET_CODE (VALUE) == LABEL_REF) \
- { \
- fprintf (FILE, "%%st("); \
- output_addr_const (FILE, (VALUE)); \
- fprintf (FILE, ")"); \
- } \
- else \
- output_addr_const (FILE, (VALUE)); \
- fprintf (FILE, "\n"); \
-} while (0)
-
-/* This is how to output an assembler line defining a `float' constant. */
-#define ASM_OUTPUT_FLOAT(FILE, VALUE) \
-{ \
- long t; \
- char str[30]; \
- REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
- REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
- fprintf (FILE, "\t.word\t0x%lx %s %s\n", \
- t, ASM_COMMENT_START, str); \
-}
-
-/* This is how to output an assembler line defining a `double' constant. */
-#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \
-{ \
- long t[2]; \
- char str[30]; \
- REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
- REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \
- fprintf (FILE, "\t.word\t0x%lx %s %s\n\t.word\t0x%lx\n", \
- t[0], ASM_COMMENT_START, str, t[1]); \
-}
-
-/* This is how to output an assembler line for a numeric constant byte. */
-#define ASM_BYTE_OP ".byte"
-#define ASM_OUTPUT_BYTE(FILE, VALUE) \
- fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE))
-
-/* The assembler's parentheses characters. */
-#define ASM_OPEN_PAREN "("
-#define ASM_CLOSE_PAREN ")"
-
-/* This is how to output the definition of a user-level label named NAME,
- such as the label on a static function or variable NAME. */
-#define ASM_OUTPUT_LABEL(FILE, NAME) \
-do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
-
-/* This is how to output a command to make the user-level label named NAME
- defined for reference from other files. */
-#define ASM_GLOBALIZE_LABEL(FILE, NAME) \
-do { \
- fputs ("\t.global\t", FILE); \
- assemble_name (FILE, NAME); \
- fputs ("\n", FILE); \
-} while (0)
-
-/* A C statement (sans semicolon) to output on FILE an assembler pseudo-op to
- declare a library function name external. The name of the library function
- is given by SYMREF, which has type RTX and is a SYMBOL_REF. */
-#if 0
-/* On the ARC we want to have libgcc's for multiple cpus in one binary.
- We can't use `assemble_name' here as that will call ASM_OUTPUT_LABELREF
- and we'll get another suffix added on if -mmangle-cpu. */
-extern char *arc_mangle_cpu;
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, SYMREF) \
-do { \
- if (TARGET_MANGLE_CPU_LIBGCC) \
- { \
- fprintf (FILE, "\t.rename\t_%s, _%s%s\n", \
- XSTR (SYMREF, 0), XSTR (SYMREF, 0), \
- arc_mangle_suffix); \
- } \
-} while (0)
-#endif
-
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-/* We mangle all user labels to provide protection from linking code
- compiled for different cpus. */
-/* We work around a dwarfout.c deficiency by watching for labels from it and
- not adding the '_' prefix nor the cpu suffix. There is a comment in
- dwarfout.c that says it should be using ASM_OUTPUT_INTERNAL_LABEL. */
-extern char *arc_mangle_cpu;
-#define ASM_OUTPUT_LABELREF(FILE, NAME) \
-do { \
- if ((NAME)[0] == '.' && (NAME)[1] == 'L') \
- fprintf (FILE, "%s", NAME); \
- else \
- { \
- fputc ('_', FILE); \
- if (TARGET_MANGLE_CPU && arc_mangle_cpu != NULL) \
- fprintf (FILE, "%s_", arc_mangle_cpu); \
- fprintf (FILE, "%s", NAME); \
- } \
-} while (0)
-
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
-do { \
- arc_ccfsm_at_label (PREFIX, NUM); \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM); \
-} while (0)
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
-/* Assembler pseudo-op to equate one value with another. */
-/* ??? This is needed because dwarfout.c provides a default definition too
- late for defaults.h (which contains the default definition of ASM_OUTPUT_DEF
- that we use). */
-#define SET_ASM_OP ".set"
-
-/* A C statement (sans semicolon) to output an element in the table of
- global constructors. */
-#undef ASM_OUTPUT_CONSTRUCTOR
-#define ASM_OUTPUT_CONSTRUCTOR(FILE, NAME) \
-do { \
- ctors_section (); \
- fprintf (FILE, "\t.word\t%%st("); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, ")\n"); \
-} while (0)
-
-/* A C statement (sans semicolon) to output an element in the table of
- global destructors. */
-#undef ASM_OUTPUT_DESTRUCTOR
-#define ASM_OUTPUT_DESTRUCTOR(FILE, NAME) \
-do { \
- dtors_section (); \
- fprintf (FILE, "\t.word\t%%st("); \
- assemble_name (FILE, NAME); \
- fprintf (FILE, ")\n"); \
-} while (0)
-
-/* How to refer to registers in assembler output.
- This sequence is indexed by compiler's hard-register-number (see above). */
-#define REGISTER_NAMES \
-{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
- "r24", "r25", "r26", "fp", "sp", "ilink1", "ilink2", "blink", \
- "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
- "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \
- "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \
- "r56", "r57", "r58", "r59", "lp_count", "cc"}
-
-/* Entry to the insn conditionalizer. */
-#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
-arc_final_prescan_insn (INSN, OPVEC, NOPERANDS)
-
-/* A C expression which evaluates to true if CODE is a valid
- punctuation character for use in the `PRINT_OPERAND' macro. */
-extern char arc_punct_chars[];
-#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
-arc_punct_chars[(unsigned char) (CHAR)]
-
-/* Print operand X (an rtx) in assembler syntax to file FILE.
- CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
- For `%' followed by punctuation, CODE is the punctuation and X is null. */
-#define PRINT_OPERAND(FILE, X, CODE) \
-arc_print_operand (FILE, X, CODE)
-
-/* A C compound statement to output to stdio stream STREAM the
- assembler syntax for an instruction operand that is a memory
- reference whose address is ADDR. ADDR is an RTL expression.
-
- On some machines, the syntax for a symbolic address depends on
- the section that the address refers to. On these machines,
- define the macro `ENCODE_SECTION_INFO' to store the information
- into the `symbol_ref', and then check for it here. */
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-arc_print_operand_address (FILE, ADDR)
-
-/* This is how to output an element of a case-vector that is absolute. */
-#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-do { \
- char label[30]; \
- ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
- fprintf (FILE, "\t.word %%st("); \
- assemble_name (FILE, label); \
- fprintf (FILE, ")\n"); \
-} while (0)
-
-/* This is how to output an element of a case-vector that is relative. */
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-do { \
- char label[30]; \
- ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
- fprintf (FILE, "\t.word %%st("); \
- assemble_name (FILE, label); \
- fprintf (FILE, "-"); \
- ASM_GENERATE_INTERNAL_LABEL (label, "L", REL); \
- assemble_name (FILE, label); \
- fprintf (FILE, ")\n"); \
-} while (0)
-
-/* The desired alignment for the location counter at the beginning
- of a loop. */
-/* On the ARC, align loops to 32 byte boundaries (cache line size)
- if -malign-loops. */
-#define LOOP_ALIGN(LABEL) (TARGET_ALIGN_LOOPS ? 5 : 0)
-
-/* This is how to output an assembler line
- that says to advance the location counter
- to a multiple of 2**LOG bytes. */
-#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
-
-/* Debugging information. */
-
-/* Generate DBX and DWARF debugging information. */
-#define DBX_DEBUGGING_INFO
-#define DWARF_DEBUGGING_INFO
-
-/* Prefer STABS (for now). */
-#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-/* How to renumber registers for dbx and gdb. */
-#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-
-/* Turn off splitting of long stabs. */
-#define DBX_CONTIN_LENGTH 0
-
-/* Miscellaneous. */
-
-/* Specify the machine mode that this machine uses
- for the index in the tablejump instruction. */
-#define CASE_VECTOR_MODE Pmode
-
-/* Define as C expression which evaluates to nonzero if the tablejump
- instruction expects the table to contain offsets from the address of the
- table.
- Do not define this if the table should contain absolute addresses. */
-/* It's not clear what PIC will look like or whether we want to use -fpic
- for the embedded form currently being talked about. For now require -fpic
- to get pc relative switch tables. */
-/*#define CASE_VECTOR_PC_RELATIVE 1 */
-
-/* Define if operations between registers always perform the operation
- on the full register even if a narrower mode is specified. */
-#define WORD_REGISTER_OPERATIONS
-
-/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
- will either zero-extend or sign-extend. The value of this macro should
- be the code that says which one of the two operations is implicitly
- done, NIL if none. */
-#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
-
-/* Specify the tree operation to be used to convert reals to integers. */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case. */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
-/* Max number of bytes we can move from memory to memory
- in one reasonably fast instruction. */
-#define MOVE_MAX 4
-
-/* Define this to be nonzero if shift instructions ignore all but the low-order
- few bits. */
-#define SHIFT_COUNT_TRUNCATED 1
-
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-#define STORE_FLAG_VALUE 1
-
-/* Specify the machine mode that pointers have.
- After generation of rtl, the compiler makes no further distinction
- between pointers and any other objects of this machine mode. */
-/* ??? The arc doesn't have full 32 bit pointers, but making this PSImode has
- its own problems (you have to add extendpsisi2 and trucnsipsi2 but how does
- one do it without getting excess code?). Try to avoid it. */
-#define Pmode SImode
-
-/* A function address in a call instruction. */
-#define FUNCTION_MODE SImode
-
-/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
- is a valid machine specific attribute for DECL.
- The attributes in ATTRIBUTES have previously been assigned to TYPE. */
-extern int arc_valid_machine_attribute ();
-#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
-arc_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
-
-/* A C expression that returns zero if the attributes on TYPE1 and TYPE2 are
- incompatible, one if they are compatible, and two if they are
- nearly compatible (which causes a warning to be generated). */
-extern int arc_comp_type_attributes ();
-#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
-arc_comp_type_attributes (TYPE1, TYPE2)
-
-/* Give newly defined TYPE some default attributes. */
-extern void arc_set_default_type_attributes ();
-#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
-arc_set_default_type_attributes (TYPE)
-
-/* Define this if the target system supports the function
- atexit from the ANSI C standard. If this is not defined,
- and INIT_SECTION_ASM_OP is not defined, a default
- exit function will be provided to support C++. */
-#define HAVE_ATEXIT
-
-/* alloca should avoid clobbering the old register save area. */
-/* ??? Not defined in tm.texi. */
-#define SETJMP_VIA_SAVE_AREA
-
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-extern struct rtx_def *arc_compare_op0, *arc_compare_op1;
-
-/* Define the function that build the compare insn for scc and bcc. */
-extern struct rtx_def *gen_compare_reg ();
-
-/* Declarations for various fns used in the .md file. */
-extern char *output_shift ();
-
-/* ARC function types. */
-enum arc_function_type {
- ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL,
- /* These are interrupt handlers. The name corresponds to the register
- name that contains the return address. */
- ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2
-};
-#define ARC_INTERRUPT_P(TYPE) \
-((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2)
-/* Compute the type of a function from its DECL. */
-enum arc_function_type arc_compute_function_type ();
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
deleted file mode 100755
index 328b1eb..0000000
--- a/gcc/config/arc/arc.md
+++ /dev/null
@@ -1,1630 +0,0 @@
-;; Machine description of the Argonaut ARC cpu for GNU C compiler
-;; Copyright (C) 1994, 1997 Free Software Foundation, Inc.
-
-;; This file is part of GNU CC.
-
-;; GNU CC is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
-
-;; ??? This is an old port, and is undoubtedly suffering from bit rot.
-
-;; Insn type. Used to default other attribute values.
-
-(define_attr "type"
- "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
- (const_string "binary"))
-
-;; Length (in # of insns, long immediate constants counted too).
-;; ??? There's a nasty interaction between the conditional execution fsm
-;; and insn lengths: insns with shimm values cannot be conditionally executed.
-(define_attr "length" ""
- (cond [(eq_attr "type" "load")
- (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
- (const_int 2) (const_int 1))
-
- (eq_attr "type" "store")
- (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
- (const_int 2) (const_int 1))
-
- (eq_attr "type" "move,unary,compare")
- (if_then_else (match_operand 1 "long_immediate_operand" "")
- (const_int 2) (const_int 1))
-
- (eq_attr "type" "binary,mul")
- (if_then_else (match_operand 2 "long_immediate_operand" "")
- (const_int 2) (const_int 1))
-
- (eq_attr "type" "cmove")
- (if_then_else (match_operand 2 "register_operand" "")
- (const_int 1) (const_int 2))
-
- (eq_attr "type" "multi") (const_int 2)
- ]
-
- (const_int 1)))
-
-;; The length here is the length of a single asm. Unfortunately it might be
-;; 1 or 2 so we must allow for 2. That's ok though. How often will users
-;; lament asm's not being put in delay slots?
-(define_asm_attributes
- [(set_attr "length" "2")
- (set_attr "type" "multi")])
-
-;; Condition codes: this one is used by final_prescan_insn to speed up
-;; conditionalizing instructions. It saves having to scan the rtl to see if
-;; it uses or alters the condition codes.
-
-;; USE: This insn uses the condition codes (eg: a conditional branch).
-;; CANUSE: This insn can use the condition codes (for conditional execution).
-;; SET: All condition codes are set by this insn.
-;; SET_ZN: the Z and N flags are set by this insn.
-;; SET_ZNC: the Z, N, and C flags are set by this insn.
-;; CLOB: The condition codes are set to unknown values by this insn.
-;; NOCOND: This insn can't use and doesn't affect the condition codes.
-
-(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
- (cond [(and (eq_attr "type" "unary,binary,move")
- (eq_attr "length" "1"))
- (const_string "canuse")
-
- (eq_attr "type" "compare")
- (const_string "set")
-
- (eq_attr "type" "cmove,branch")
- (const_string "use")
-
- (eq_attr "type" "multi,misc")
- (const_string "clob")
- ]
-
- (const_string "nocond")))
-
-;; Delay slots.
-
-(define_attr "in_delay_slot" "false,true"
- (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
- (const_string "false")
- ]
-
- (if_then_else (eq_attr "length" "1")
- (const_string "true")
- (const_string "false"))))
-
-(define_delay (eq_attr "type" "call")
- [(eq_attr "in_delay_slot" "true")
- (eq_attr "in_delay_slot" "true")
- (eq_attr "in_delay_slot" "true")])
-
-(define_delay (eq_attr "type" "branch,uncond_branch")
- [(eq_attr "in_delay_slot" "true")
- (eq_attr "in_delay_slot" "true")
- (eq_attr "in_delay_slot" "true")])
-
-;; Function units of the ARC
-
-;; (define_function_unit {name} {num-units} {n-users} {test}
-;; {ready-delay} {issue-delay} [{conflict-list}])
-
-;; 1) A conditional jump cannot immediately follow the insn setting the flags.
-;; This isn't a complete solution as it doesn't come with guarantees. That
-;; is done in the branch patterns and in arc_print_operand. This exists to
-;; avoid inserting a nop when we can.
-(define_function_unit "compare" 1 0 (eq_attr "type" "compare") 2 2 [(eq_attr "type" "branch")])
-
-;; 2) References to loaded registers should wait a cycle.
-
-;; Memory with load-delay of 1 (i.e., 2 cycle load).
-(define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
-
-;; Units that take one cycle do not need to be specified.
-
-;; Move instructions.
-
-(define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
- ""
- "
-{
- /* Everything except mem = const or mem = mem can be done easily. */
-
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (QImode, operands[1]);
-}")
-
-(define_insn "*movqi_insn"
- [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
- (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
-;; ??? Needed?
- "register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode)"
- "@
- mov%? %0,%1
- mov%? %0,%1
- ldb%U1%V1 %0,%1
- stb%U0%V0 %1,%0"
- [(set_attr "type" "move,move,load,store")])
-
-;; ??? This may never match since there's no cmpqi insn.
-
-(define_insn "*movqi_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
- (const_int 0)))
- (set (match_operand:QI 0 "move_dest_operand" "=r")
- (match_dup 1))]
- ""
- "mov%?.f %0,%1"
- [(set_attr "type" "move")
- (set_attr "cond" "set_zn")])
-
-(define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
- "
-{
- /* Everything except mem = const or mem = mem can be done easily. */
-
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (HImode, operands[1]);
-}")
-
-(define_insn "*movhi_insn"
- [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
- (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
- "register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode)"
- "@
- mov%? %0,%1
- mov%? %0,%1
- ldw%U1%V1 %0,%1
- stw%U0%V0 %1,%0"
- [(set_attr "type" "move,move,load,store")])
-
-;; ??? Will this ever match?
-
-(define_insn "*movhi_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
- (const_int 0)))
- (set (match_operand:HI 0 "move_dest_operand" "=r")
- (match_dup 1))]
-;; ??? Needed?
- "register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode)"
- "mov%?.f %0,%1"
- [(set_attr "type" "move")
- (set_attr "cond" "set_zn")])
-
-(define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
- ""
- "
-{
- /* Everything except mem = const or mem = mem can be done easily. */
-
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (SImode, operands[1]);
-}")
-
-(define_insn "*movsi_insn"
- [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
- (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
- "register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode)"
- "@
- mov%? %0,%1
- mov%? %0,%S1
- ld%U1%V1 %0,%1
- st%U0%V0 %1,%0"
- [(set_attr "type" "move,move,load,store")])
-
-(define_insn "*movsi_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (match_operand:SI 1 "move_src_operand" "rIJi")
- (const_int 0)))
- (set (match_operand:SI 0 "move_dest_operand" "=r")
- (match_dup 1))]
- "register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode)"
- "mov%?.f %0,%S1"
- [(set_attr "type" "move")
- (set_attr "cond" "set_zn")])
-
-(define_expand "movdi"
- [(set (match_operand:DI 0 "general_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- ""
- "
-{
- /* Everything except mem = const or mem = mem can be done easily. */
-
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (DImode, operands[1]);
-}")
-
-(define_insn "*movdi_insn"
- [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
- (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
- "register_operand (operands[0], DImode)
- || register_operand (operands[1], DImode)"
- "*
-{
- switch (which_alternative)
- {
- case 0 :
- /* We normally copy the low-numbered register first. However, if
- the first register operand 0 is the same as the second register of
- operand 1, we must copy in the opposite order. */
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"mov %R0,%R1\;mov %0,%1\";
- else
- return \"mov %0,%1\;mov %R0,%R1\";
- case 1 :
- return \"mov %0,%L1\;mov %R0,%H1\";
- case 2 :
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands [1], 0))
- return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
- else
- return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
- case 3 :
- return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
- }
-}"
- [(set_attr "type" "move,move,load,store")
- ;; ??? The ld/st values could be 4 if it's [reg,bignum].
- (set_attr "length" "2,4,2,2")])
-
-;(define_expand "movdi"
-; [(set (match_operand:DI 0 "general_operand" "")
-; (match_operand:DI 1 "general_operand" ""))]
-; ""
-; "
-;{
-; /* Flow doesn't understand that this is effectively a DFmode move.
-; It doesn't know that all of `operands[0]' is set. */
-; emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
-;
-; /* Emit insns that movsi_insn can handle. */
-; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
-; operand_subword (operands[1], 0, 0, DImode)));
-; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
-; operand_subword (operands[1], 1, 0, DImode)));
-; DONE;
-;}")
-
-;; Floating point move insns.
-
-(define_expand "movsf"
- [(set (match_operand:SF 0 "general_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
- ""
- "
-{
- /* Everything except mem = const or mem = mem can be done easily. */
-
-#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- operands[1] = force_const_mem (SFmode, operands[1]);
-#endif
-
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (SFmode, operands[1]);
-}")
-
-(define_insn "*movsf_insn"
- [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
- (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
- "register_operand (operands[0], SFmode)
- || register_operand (operands[1], SFmode)"
- "@
- mov%? %0,%1
- mov%? %0,%1 ; %A1
- ld%U1%V1 %0,%1
- st%U0%V0 %1,%0"
- [(set_attr "type" "move,move,load,store")])
-
-(define_expand "movdf"
- [(set (match_operand:DF 0 "general_operand" "")
- (match_operand:DF 1 "general_operand" ""))]
- ""
- "
-{
- /* Everything except mem = const or mem = mem can be done easily. */
-
-#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- operands[1] = force_const_mem (DFmode, operands[1]);
-#endif
-
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (DFmode, operands[1]);
-}")
-
-(define_insn "*movdf_insn"
- [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
- (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
- "register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode)"
- "*
-{
- switch (which_alternative)
- {
- case 0 :
- /* We normally copy the low-numbered register first. However, if
- the first register operand 0 is the same as the second register of
- operand 1, we must copy in the opposite order. */
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"mov %R0,%R1\;mov %0,%1\";
- else
- return \"mov %0,%1\;mov %R0,%R1\";
- case 1 :
- return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
- case 2 :
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands [1], 0))
- return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
- else
- return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
- case 3 :
- return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
- }
-}"
- [(set_attr "type" "move,move,load,store")
- ;; ??? The ld/st values could be 4 if it's [reg,bignum].
- (set_attr "length" "2,4,2,2")])
-
-;(define_expand "movdf"
-; [(set (match_operand:DF 0 "general_operand" "")
-; (match_operand:DF 1 "general_operand" ""))]
-; ""
-; "
-;{
-; /* Flow doesn't understand that this is effectively a DFmode move.
-; It doesn't know that all of `operands[0]' is set. */
-; emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
-;
-; /* Emit insns that movsi_insn can handle. */
-; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
-; operand_subword (operands[1], 0, 0, DFmode)));
-; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
-; operand_subword (operands[1], 1, 0, DFmode)));
-; DONE;
-;}")
-
-;; Load/Store with update instructions.
-;;
-;; Some of these we can get by using pre-decrement or pre-increment, but the
-;; hardware can also do cases where the increment is not the size of the
-;; object.
-;;
-;; In all these cases, we use operands 0 and 1 for the register being
-;; incremented because those are the operands that local-alloc will
-;; tie and these are the pair most likely to be tieable (and the ones
-;; that will benefit the most).
-;;
-;; We use match_operator here because we need to know whether the memory
-;; object is volatile or not.
-
-(define_insn "*loadqi_update"
- [(set (match_operand:QI 3 "register_operand" "=r,r")
- (match_operator:QI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldb.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*load_zeroextendqisi_update"
- [(set (match_operand:SI 3 "register_operand" "=r,r")
- (zero_extend:SI (match_operator:QI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldb.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*load_signextendqisi_update"
- [(set (match_operand:SI 3 "register_operand" "=r,r")
- (sign_extend:SI (match_operator:QI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldb.x.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*storeqi_update"
- [(set (match_operator:QI 4 "store_update_operand"
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "short_immediate_operand" "I")])
- (match_operand:QI 3 "register_operand" "r"))
- (set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "stb.a%V4 %3,[%0,%2]"
- [(set_attr "type" "store")
- (set_attr "length" "1")])
-
-(define_insn "*loadhi_update"
- [(set (match_operand:HI 3 "register_operand" "=r,r")
- (match_operator:HI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldw.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*load_zeroextendhisi_update"
- [(set (match_operand:SI 3 "register_operand" "=r,r")
- (zero_extend:SI (match_operator:HI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldw.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*load_signextendhisi_update"
- [(set (match_operand:SI 3 "register_operand" "=r,r")
- (sign_extend:SI (match_operator:HI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldw.x.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*storehi_update"
- [(set (match_operator:HI 4 "store_update_operand"
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "short_immediate_operand" "I")])
- (match_operand:HI 3 "register_operand" "r"))
- (set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "stw.a%V4 %3,[%0,%2]"
- [(set_attr "type" "store")
- (set_attr "length" "1")])
-
-(define_insn "*loadsi_update"
- [(set (match_operand:SI 3 "register_operand" "=r,r")
- (match_operator:SI 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ld.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*storesi_update"
- [(set (match_operator:SI 4 "store_update_operand"
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "short_immediate_operand" "I")])
- (match_operand:SI 3 "register_operand" "r"))
- (set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "st.a%V4 %3,[%0,%2]"
- [(set_attr "type" "store")
- (set_attr "length" "1")])
-
-(define_insn "*loadsf_update"
- [(set (match_operand:SF 3 "register_operand" "=r,r")
- (match_operator:SF 4 "load_update_operand"
- [(match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
- (set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ld.a%V4 %3,[%0,%2]"
- [(set_attr "type" "load,load")
- (set_attr "length" "1,2")])
-
-(define_insn "*storesf_update"
- [(set (match_operator:SF 4 "store_update_operand"
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "short_immediate_operand" "I")])
- (match_operand:SF 3 "register_operand" "r"))
- (set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "st.a%V4 %3,[%0,%2]"
- [(set_attr "type" "store")
- (set_attr "length" "1")])
-
-;; Conditional move instructions.
-
-(define_expand "movsicc"
- [(set (match_operand:SI 0 "register_operand" "")
- (if_then_else (match_operand 1 "comparison_operator" "")
- (match_operand:SI 2 "nonmemory_operand" "")
- (match_operand:SI 3 "register_operand" "")))]
- ""
- "
-{
- enum rtx_code code = GET_CODE (operands[1]);
- rtx ccreg = gen_rtx (REG,
- SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
- 61);
-
- operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
-}")
-
-;(define_expand "movdicc"
-; [(set (match_operand:DI 0 "register_operand" "")
-; (if_then_else (match_operand 1 "comparison_operator" "")
-; (match_operand:DI 2 "nonmemory_operand" "")
-; (match_operand:DI 3 "register_operand" "")))]
-; "0 /* ??? this would work better if we had cmpdi */"
-; "
-;{
-; enum rtx_code code = GET_CODE (operands[1]);
-; rtx ccreg = gen_rtx (REG,
-; SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-; 61);
-;
-; operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
-(define_expand "movsfcc"
- [(set (match_operand:SF 0 "register_operand" "")
- (if_then_else (match_operand 1 "comparison_operator" "")
- (match_operand:SF 2 "nonmemory_operand" "")
- (match_operand:SF 3 "register_operand" "")))]
- ""
- "
-{
- enum rtx_code code = GET_CODE (operands[1]);
- rtx ccreg = gen_rtx (REG,
- SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
- 61);
-
- operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
-}")
-
-;(define_expand "movdfcc"
-; [(set (match_operand:DF 0 "register_operand" "")
-; (if_then_else (match_operand 1 "comparison_operator" "")
-; (match_operand:DF 2 "nonmemory_operand" "")
-; (match_operand:DF 3 "register_operand" "")))]
-; "0 /* ??? can generate less efficient code if constants involved */"
-; "
-;{
-; enum rtx_code code = GET_CODE (operands[1]);
-; rtx ccreg = gen_rtx (REG,
-; SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-; 61);
-;
-; operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
-(define_insn "*movsicc_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (if_then_else (match_operand 1 "comparison_operator" "")
- (match_operand:SI 2 "nonmemory_operand" "rJi")
- (match_operand:SI 3 "register_operand" "0")))]
- ""
- "mov.%d1 %0,%S2"
- [(set_attr "type" "cmove")])
-
-; ??? This doesn't properly handle constants.
-;(define_insn "*movdicc_insn"
-; [(set (match_operand:DI 0 "register_operand" "=r,r")
-; (if_then_else (match_operand 1 "comparison_operator" "")
-; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
-; (match_operand:DI 3 "register_operand" "0,0")))]
-; "0"
-; "*
-;{
-; switch (which_alternative)
-; {
-; case 0 :
-; /* We normally copy the low-numbered register first. However, if
-; the first register operand 0 is the same as the second register of
-; operand 1, we must copy in the opposite order. */
-; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-; else
-; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-; case 1 :
-; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-; }
-;}"
-; [(set_attr "type" "cmove,cmove")
-; (set_attr "length" "2,4")])
-
-(define_insn "*movsfcc_insn"
- [(set (match_operand:SF 0 "register_operand" "=r,r")
- (if_then_else (match_operand 1 "comparison_operator" "")
- (match_operand:SF 2 "nonmemory_operand" "r,E")
- (match_operand:SF 3 "register_operand" "0,0")))]
- ""
- "@
- mov.%d1 %0,%2
- mov.%d1 %0,%2 ; %A2"
- [(set_attr "type" "cmove,cmove")])
-
-;(define_insn "*movdfcc_insn"
-; [(set (match_operand:DF 0 "register_operand" "=r,r")
-; (if_then_else (match_operand 1 "comparison_operator" "")
-; (match_operand:DF 2 "nonmemory_operand" "r,E")
-; (match_operand:DF 3 "register_operand" "0,0")))]
-; "0"
-; "*
-;{
-; switch (which_alternative)
-; {
-; case 0 :
-; /* We normally copy the low-numbered register first. However, if
-; the first register operand 0 is the same as the second register of
-; operand 1, we must copy in the opposite order. */
-; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-; else
-; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-; case 1 :
-; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
-; }
-;}"
-; [(set_attr "type" "cmove,cmove")
-; (set_attr "length" "2,4")])
-
-;; Zero extension instructions.
-;; ??? We don't support volatile memrefs here, but I'm not sure why.
-
-(define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
- ""
- "@
- extb%? %0,%1
- ldb%U1 %0,%1"
- [(set_attr "type" "unary,load")])
-
-(define_insn "*zero_extendqihi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (match_dup 1)))]
- ""
- "extb%?.f %0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-(define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
- ""
- "@
- extb%? %0,%1
- ldb%U1 %0,%1"
- [(set_attr "type" "unary,load")])
-
-(define_insn "*zero_extendqisi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_dup 1)))]
- ""
- "extb%?.f %0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-(define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
- ""
- "@
- extw%? %0,%1
- ldw%U1 %0,%1"
- [(set_attr "type" "unary,load")])
-
-(define_insn "*zero_extendhisi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (match_dup 1)))]
- ""
- "extw%?.f %0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-;; Sign extension instructions.
-
-(define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
- ""
- "@
- sexb%? %0,%1
- ldb.x%U1 %0,%1"
- [(set_attr "type" "unary,load")])
-
-(define_insn "*extendqihi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:HI 0 "register_operand" "=r")
- (sign_extend:HI (match_dup 1)))]
- ""
- "sexb%?.f %0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
- ""
- "@
- sexb%? %0,%1
- ldb.x%U1 %0,%1"
- [(set_attr "type" "unary,load")])
-
-(define_insn "*extendqisi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_dup 1)))]
- ""
- "sexb%?.f %0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-(define_insn "extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
- ""
- "@
- sexw%? %0,%1
- ldw.x%U1 %0,%1"
- [(set_attr "type" "unary,load")])
-
-(define_insn "*extendhisi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_dup 1)))]
- ""
- "sexw%?.f %0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-;; Arithmetic instructions.
-
-(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
- ""
- "add%? %0,%1,%2")
-
-(define_insn "*addsi3_set_cc_insn"
- [(set (reg:CC 61) (compare:CC
- (plus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "add%?.f %0,%1,%2"
- [(set_attr "cond" "set")])
-
-(define_insn "adddi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
- (match_operand:DI 2 "nonmemory_operand" "ri")))
- (clobber (reg:CC 61))]
- ""
- "*
-{
- rtx op2 = operands[2];
-
- if (GET_CODE (op2) == CONST_INT)
- {
- int sign = INTVAL (op2);
- if (sign < 0)
- return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
- else
- return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
- }
- else
- return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
-}"
- [(set_attr "length" "2")])
-
-(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
- ""
- "sub%? %0,%1,%2")
-
-(define_insn "*subsi3_set_cc_insn"
- [(set (reg:CC 61) (compare:CC
- (minus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "sub%?.f %0,%1,%2"
- [(set_attr "cond" "set")])
-
-(define_insn "subdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
- (match_operand:DI 2 "nonmemory_operand" "ri")))
- (clobber (reg:CC 61))]
- ""
- "*
-{
- rtx op2 = operands[2];
-
- if (GET_CODE (op2) == CONST_INT)
- {
- int sign = INTVAL (op2);
- if (sign < 0)
- return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
- else
- return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
- }
- else
- return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
-}"
- [(set_attr "length" "2")])
-
-;; Boolean instructions.
-;;
-;; We don't define the DImode versions as expand_binop does a good enough job.
-
-(define_insn "andsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
- ""
- "and%? %0,%1,%2")
-
-(define_insn "*andsi3_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (and:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "and%?.f %0,%1,%2"
- [(set_attr "cond" "set_zn")])
-
-(define_insn "*bicsi3_insn"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
- (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
- ""
- "bic%? %0,%1,%2"
- [(set_attr "length" "1,2,1,2")])
-
-(define_insn "*bicsi3_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (and:SI (match_operand:SI 1 "register_operand" "%r")
- (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (match_dup 1)
- (not:SI (match_dup 2))))]
- ""
- "bic%?.f %0,%1,%2"
- [(set_attr "cond" "set_zn")])
-
-(define_insn "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
- ""
- "or%? %0,%1,%2")
-
-(define_insn "*iorsi3_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (ior:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "or%?.f %0,%1,%2"
- [(set_attr "cond" "set_zn")])
-
-(define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (xor:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
- ""
- "xor%? %0,%1,%2")
-
-(define_insn "*xorsi3_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CCZN
- (xor:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "nonmemory_operand" "rIJ"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (xor:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "xor%?.f %0,%1,%2"
- [(set_attr "cond" "set_zn")])
-
-(define_insn "negsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "sub%? %0,0,%1"
- [(set_attr "type" "unary")])
-
-(define_insn "*negsi2_set_cc_insn"
- [(set (reg:CC 61) (compare:CC
- (neg:SI (match_operand:SI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_dup 1)))]
- ""
- "sub%?.f %0,0,%1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set")])
-
-(define_insn "negdi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "register_operand" "r")))
- (clobber (reg:SI 61))]
- ""
- "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
- [(set_attr "type" "unary")
- (set_attr "length" "2")])
-
-(define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "xor%? %0,%1,-1"
- [(set_attr "type" "unary")])
-
-(define_insn "*one_cmplsi2_set_cc_insn"
- [(set (reg:CCZN 61) (compare:CC
- (not:SI (match_operand:SI 1 "register_operand" "r"))
- (const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_dup 1)))]
- ""
- "xor%?.f %0,%1,-1"
- [(set_attr "type" "unary")
- (set_attr "cond" "set_zn")])
-
-;; Shift instructions.
-
-(define_expand "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ashift:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "
-{
- if (! TARGET_SHIFTER)
- {
- emit_insn (gen_rtx
- (PARALLEL, VOIDmode,
- gen_rtvec (2,
- gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (ASHIFT, SImode, operands[1], operands[2])),
- gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))));
- DONE;
- }
-}")
-
-(define_expand "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "
-{
- if (! TARGET_SHIFTER)
- {
- emit_insn (gen_rtx
- (PARALLEL, VOIDmode,
- gen_rtvec (2,
- gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (ASHIFTRT, SImode, operands[1], operands[2])),
- gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))));
- DONE;
- }
-}")
-
-(define_expand "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
- ""
- "
-{
- if (! TARGET_SHIFTER)
- {
- emit_insn (gen_rtx
- (PARALLEL, VOIDmode,
- gen_rtvec (2,
- gen_rtx (SET, VOIDmode, operands[0],
- gen_rtx (LSHIFTRT, SImode, operands[1], operands[2])),
- gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)))));
- DONE;
- }
-}")
-
-(define_insn "*ashlsi3_insn"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
- (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
- "TARGET_SHIFTER"
- "asl%? %0,%1,%2"
- [(set_attr "type" "shift")
- (set_attr "length" "1,2,1,2")])
-
-(define_insn "*ashrsi3_insn"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
- (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
- "TARGET_SHIFTER"
- "asr%? %0,%1,%2"
- [(set_attr "type" "shift")
- (set_attr "length" "1,2,1,2")])
-
-(define_insn "*lshrsi3_insn"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
- (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
- "TARGET_SHIFTER"
- "lsr%? %0,%1,%2"
- [(set_attr "type" "shift")
- (set_attr "length" "1,2,1,2")])
-
-(define_insn "*shift_si3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 3 "shift_operator"
- [(match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
- (clobber (match_scratch:SI 4 "=&r"))]
- "! TARGET_SHIFTER"
- "* return output_shift (operands);"
- [(set_attr "type" "shift")
- (set_attr "length" "8")])
-
-;; Compare instructions.
-;; This controls RTL generation and register allocation.
-
-;; We generate RTL for comparisons and branches by having the cmpxx
-;; patterns store away the operands. Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-
-(define_expand "cmpsi"
- [(set (reg:CC 61)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
- ""
- "
-{
- arc_compare_op0 = operands[0];
- arc_compare_op1 = operands[1];
- DONE;
-}")
-
-;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
-;; This assumes sub.f 0,symbol,0 is a valid insn.
-;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
-;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
-;; if it's a small constant.
-
-(define_insn "*cmpsi_cc_insn"
- [(set (reg:CC 61)
- (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
- (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
- ""
- "@
- sub.f 0,%0,%1
- sub.f %1,%0,%1
- sub.f 0,%0,%1"
- [(set_attr "type" "compare,compare,compare")])
-
-(define_insn "*cmpsi_cczn_insn"
- [(set (reg:CCZN 61)
- (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
- (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
- ""
- "@
- sub.f 0,%0,%1
- sub.f %1,%0,%1
- sub.f 0,%0,%1"
- [(set_attr "type" "compare,compare,compare")])
-
-(define_insn "*cmpsi_ccznc_insn"
- [(set (reg:CCZNC 61)
- (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
- (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
- ""
- "@
- sub.f 0,%0,%1
- sub.f %1,%0,%1
- sub.f 0,%0,%1"
- [(set_attr "type" "compare,compare,compare")])
-
-;; Next come the scc insns.
-
-(define_expand "seq"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (gt:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (le:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ge:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lt:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (gtu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (leu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (geu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ltu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_insn "*scc_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
- ""
- "mov %0,1\;sub.%D1 %0,%0,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "2")])
-
-;; ??? Look up negscc insn. See pa.md for example.
-(define_insn "*neg_scc_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operator:SI 1 "comparison_operator"
- [(reg 61) (const_int 0)])))]
- ""
- "mov %0,-1\;sub.%D1 %0,%0,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "2")])
-
-(define_insn "*not_scc_insn"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_operator:SI 1 "comparison_operator"
- [(reg 61) (const_int 0)])))]
- ""
- "mov %0,1\;sub.%d1 %0,%0,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "2")])
-
-;; These control RTL generation for conditional jump insns
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
-}")
-
-;; Now match both normal and inverted jump.
-
-(define_insn "*branch_insn"
- [(set (pc)
- (if_then_else (match_operator 1 "proper_comparison_operator"
- [(reg 61) (const_int 0)])
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- if (arc_ccfsm_branch_deleted_p ())
- {
- arc_ccfsm_record_branch_deleted ();
- return \"; branch deleted, next insns conditionalized\";
- }
- else
- return \"%~b%d1%# %l0\";
-}"
- [(set_attr "type" "branch")])
-
-(define_insn "*rev_branch_insn"
- [(set (pc)
- (if_then_else (match_operator 1 "proper_comparison_operator"
- [(reg 61) (const_int 0)])
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
- "*
-{
- if (arc_ccfsm_branch_deleted_p ())
- {
- arc_ccfsm_record_branch_deleted ();
- return \"; branch deleted, next insns conditionalized\";
- }
- else
- return \"%~b%D1%# %l0\";
-}"
- [(set_attr "type" "branch")])
-
-;; Unconditional and other jump instructions.
-
-(define_insn "jump"
- [(set (pc) (label_ref (match_operand 0 "" "")))]
- ""
- "b%* %l0"
- [(set_attr "type" "uncond_branch")])
-
-(define_insn "indirect_jump"
- [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
- ""
- "j%* %a0"
- [(set_attr "type" "uncond_branch")])
-
-;; Implement a switch statement.
-;; This wouldn't be necessary in the non-pic case if we could distinguish
-;; label refs of the jump table from other label refs. The problem is that
-;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
-;; the real address since it's the address of the table.
-
-(define_expand "casesi"
- [(set (match_dup 5)
- (minus:SI (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))
- (set (reg:CC 61)
- (compare:CC (match_dup 5)
- (match_operand:SI 2 "nonmemory_operand" "")))
- (set (pc)
- (if_then_else (gtu (reg:CC 61)
- (const_int 0))
- (label_ref (match_operand 4 "" ""))
- (pc)))
- (parallel
- [(set (pc)
- (mem:SI (plus:SI (mult:SI (match_dup 5)
- (const_int 4))
- (label_ref (match_operand 3 "" "")))))
- (clobber (match_scratch:SI 6 ""))
- (clobber (match_scratch:SI 7 ""))])]
- ""
- "
-{
- operands[5] = gen_reg_rtx (SImode);
-}")
-
-(define_insn "*casesi_insn"
- [(set (pc)
- (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 4))
- (label_ref (match_operand 1 "" "")))))
- (clobber (match_scratch:SI 2 "=r"))
- (clobber (match_scratch:SI 3 "=r"))]
- ""
- "*
-{
- output_asm_insn (\"mov %2,%1\", operands);
- if (TARGET_SHIFTER)
- output_asm_insn (\"asl %3,%0,2\", operands);
- else
- output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
- output_asm_insn (\"ld %2,[%2,%3]\", operands);
- output_asm_insn (\"j.nd %a2\", operands);
- return \"\";
-}"
- [(set_attr "type" "uncond_branch")
- (set_attr "length" "6")])
-
-(define_insn "tablejump"
- [(set (pc) (match_operand:SI 0 "address_operand" "p"))
- (use (label_ref (match_operand 1 "" "")))]
- "0 /* disabled -> using casesi now */"
- "j%* %a0"
- [(set_attr "type" "uncond_branch")])
-
-(define_expand "call"
- ;; operands[1] is stack_size_rtx
- ;; operands[2] is next_arg_register
- [(parallel [(call (match_operand:SI 0 "call_operand" "")
- (match_operand 1 "" ""))
- (clobber (reg:SI 31))])]
- ""
- "")
-
-(define_insn "*call_via_reg"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
- (match_operand 1 "" ""))
- (clobber (reg:SI 31))]
- ""
- "lr blink,[status]\;j.d %0\;add blink,blink,2"
- [(set_attr "type" "call_no_delay_slot")
- (set_attr "length" "3")])
-
-(define_insn "*call_via_label"
- [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
- (match_operand 1 "" ""))
- (clobber (reg:SI 31))]
- ""
- ; The %~ is necessary in case this insn gets conditionalized and the previous
- ; insn is the cc setter.
- "%~bl%!%* %0"
- [(set_attr "type" "call")
- (set_attr "cond" "canuse")])
-
-(define_expand "call_value"
- ;; operand 2 is stack_size_rtx
- ;; operand 3 is next_arg_register
- [(parallel [(set (match_operand 0 "register_operand" "=r")
- (call (match_operand:SI 1 "call_operand" "")
- (match_operand 2 "" "")))
- (clobber (reg:SI 31))])]
- ""
- "")
-
-(define_insn "*call_value_via_reg"
- [(set (match_operand 0 "register_operand" "=r")
- (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
- (match_operand 2 "" "")))
- (clobber (reg:SI 31))]
- ""
- "lr blink,[status]\;j.d %1\;add blink,blink,2"
- [(set_attr "type" "call_no_delay_slot")
- (set_attr "length" "3")])
-
-(define_insn "*call_value_via_label"
- [(set (match_operand 0 "register_operand" "=r")
- (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
- (match_operand 2 "" "")))
- (clobber (reg:SI 31))]
- ""
- ; The %~ is necessary in case this insn gets conditionalized and the previous
- ; insn is the cc setter.
- "%~bl%!%* %1"
- [(set_attr "type" "call")
- (set_attr "cond" "canuse")])
-
-(define_insn "nop"
- [(const_int 0)]
- ""
- "nop"
- [(set_attr "type" "misc")])
-
-;; Special pattern to flush the icache.
-;; ??? Not sure what to do here. Some ARC's are known to support this.
-
-(define_insn "flush_icache"
- [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
- ""
- "* return \"\";"
- [(set_attr "type" "misc")])
-
-;; Split up troublesome insns for better scheduling.
-
-;; Peepholes go at the end.
diff --git a/gcc/config/arc/initfini.c b/gcc/config/arc/initfini.c
deleted file mode 100755
index 084e229..0000000
--- a/gcc/config/arc/initfini.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* .init/.fini section handling + C++ global constructor/destructor handling.
- This file is based on crtstuff.c, sol2-crti.asm, sol2-crtn.asm.
-
-Copyright (C) 1995, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this file with files
- compiled with GCC to produce an executable, this does not cause
- the resulting executable to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License. */
-
-/* Declare a pointer to void function type. */
-typedef void (*func_ptr) (void);
-
-#ifdef CRT_INIT
-
-/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
- to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
- __DTOR_END__ } per root executable and also one set of these symbols
- per shared library. So in any given whole process image, we may have
- multiple definitions of each of these symbols. In order to prevent
- these definitions from conflicting with one another, and in order to
- ensure that the proper lists are used for the initialization/finalization
- of each individual shared library (respectively), we give these symbols
- only internal (i.e. `static') linkage, and we also make it a point to
- refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__
- symbol in crtinit.o, where they are defined. */
-
-static func_ptr __CTOR_LIST__[1] __attribute__ ((section (".ctors")))
- = { (func_ptr) (-1) };
-
-static func_ptr __DTOR_LIST__[1] __attribute__ ((section (".dtors")))
- = { (func_ptr) (-1) };
-
-/* Run all the global destructors on exit from the program. */
-
-/* Some systems place the number of pointers in the first word of the
- table. On SVR4 however, that word is -1. In all cases, the table is
- null-terminated. On SVR4, we start from the beginning of the list and
- invoke each per-compilation-unit destructor routine in order
- until we find that null.
-
- Note that this function MUST be static. There will be one of these
- functions in each root executable and one in each shared library, but
- although they all have the same code, each one is unique in that it
- refers to one particular associated `__DTOR_LIST__' which belongs to the
- same particular root executable or shared library file. */
-
-static void __do_global_dtors ()
-asm ("__do_global_dtors") __attribute__ ((section (".text")));
-
-static void
-__do_global_dtors ()
-{
- func_ptr *p;
- for (p = __DTOR_LIST__ + 1; *p; p++)
- (*p) ();
-}
-
-/* .init section start.
- This must appear at the start of the .init section. */
-
-asm ("
- .section .init\n
- .global init\n
- .word 0\n
-init:\n
- st blink,[sp,4]\n
- st fp,[sp]\n
- mov fp,sp\n
- sub sp,sp,16\n
-");
-
-/* .fini section start.
- This must appear at the start of the .init section. */
-
-asm ("
- .section .fini\n
- .global fini\n
- .word 0\n
-fini:\n
- st blink,[sp,4]\n
- st fp,[sp]\n
- mov fp,sp\n
- sub sp,sp,16\n
- bl.nd __do_global_dtors
-");
-
-#endif /* CRT_INIT */
-
-#ifdef CRT_FINI
-
-/* Put a word containing zero at the end of each of our two lists of function
- addresses. Note that the words defined here go into the .ctors and .dtors
- sections of the crtend.o file, and since that file is always linked in
- last, these words naturally end up at the very ends of the two lists
- contained in these two sections. */
-
-static func_ptr __CTOR_END__[1] __attribute__ ((section (".ctors")))
- = { (func_ptr) 0 };
-
-static func_ptr __DTOR_END__[1] __attribute__ ((section (".dtors")))
- = { (func_ptr) 0 };
-
-/* Run all global constructors for the program.
- Note that they are run in reverse order. */
-
-static void __do_global_ctors ()
-asm ("__do_global_ctors") __attribute__ ((section (".text")));
-
-static void
-__do_global_ctors ()
-{
- func_ptr *p;
- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
- (*p) ();
-}
-
-/* .init section end.
- This must live at the end of the .init section. */
-
-asm ("
- .section .init\n
- bl.nd __do_global_ctors
- ld blink,[fp,4]\n
- j.d blink\n
- ld.a fp,[sp,16]\n
-");
-
-/* .fini section end.
- This must live at the end of the .fini section. */
-
-asm ("
- .section .fini\n
- ld blink,[fp,4]\n
- j.d blink\n
- ld.a fp,[sp,16]\n
-");
-
-#endif /* CRT_FINI */
diff --git a/gcc/config/arc/lib1funcs.asm b/gcc/config/arc/lib1funcs.asm
deleted file mode 100755
index a2d509a..0000000
--- a/gcc/config/arc/lib1funcs.asm
+++ /dev/null
@@ -1,273 +0,0 @@
-; libgcc1 routines for ARC cpu.
-
-/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
-
-This file is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file with other programs, and to distribute
-those programs without any restriction coming from the use of this
-file. (The General Public License restrictions do apply in other
-respects; for example, they cover modification of the file, and
-distribution when not linked into another program.)
-
-This file is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* As a special exception, if you link this library with other files,
- some of which are compiled with GCC, to produce an executable,
- this library does not by itself cause the resulting executable
- to be covered by the GNU General Public License.
- This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public License. */
-
-#ifdef L_mulsi3
- .section .text
- .align 4
-
-#ifdef __base__
- .cpu base
- .global ___mulsi3
-___mulsi3:
-
-/* This the simple version.
-
- while (a)
- {
- if (a & 1)
- r += b;
- a >>= 1;
- b <<= 1;
- }
-*/
- mov r2,0 ; Accumulate result here.
-.Lloop:
- sub.f 0,r0,0 ; while (a)
- nop
- beq.nd .Ldone
- and.f 0,r0,1 ; if (a & 1)
- add.nz r2,r2,r1 ; r += b
- lsr r0,r0 ; a >>= 1
- b.d .Lloop
- lsl r1,r1 ; b <<= 1
-.Ldone:
- j.d blink
- mov r0,r2
-#endif
-
-#endif /* L_mulsi3 */
-
-#ifdef L_umulsidi3
- .section .text
- .align 4
-
-#ifdef __base__
- .cpu base
- .global ___umulsidi3
-___umulsidi3:
-
-/* This the simple version.
-
- while (a)
- {
- if (a & 1)
- r += b;
- a >>= 1;
- b <<= 1;
- }
-*/
- mov r2,0 ; Top part of b.
- mov r3,0 ; Accumulate result here.
- mov r4,0
-.Lloop:
- sub.f 0,r0,0 ; while (a)
- nop
- beq.nd .Ldone
- and.f 0,r0,1 ; if (a & 1)
- add.nz r4,r4,r1 ; r += b
- adc.nz r3,r3,r2
- lsr r0,r0 ; a >>= 1
- lsl.f r1,r1 ; b <<= 1
- b.d .Lloop
- rlc r2,r2
-.Ldone:
-#ifdef __big_endian__
- mov r1,r4
- j.d blink
- mov r0,r3
-#else
- mov r0,r4
- j.d blink
- mov r1,r3
-#endif
-#endif
-
-#endif /* L_umulsidi3 */
-
-#ifdef L_divmod_tools
-
-; Utilities used by all routines.
-
- .section .text
- .align 4
-
-; inputs: r0 = numerator, r1 = denominator
-; outputs: positive r0/r1,
-; r6.bit1 = sign of numerator, r6.bit0 = sign of result
-
- .global ___divnorm
-___divnorm:
- mov r6,0 ; keep sign in r6
- sub.f 0,r0,0 ; is numerator -ve?
- sub.lt r0,0,r0 ; negate numerator
- mov.lt r6,3 ; sign is -ve
- sub.f 0,r1,0 ; is denominator -ve?
- sub.lt r1,0,r1 ; negate denominator
- xor.lt r6,r6,1 ; toggle sign
- j.nd blink
-
-/*
-unsigned long
-udivmodsi4(int modwanted, unsigned long num, unsigned long den)
-{
- unsigned long bit = 1;
- unsigned long res = 0;
-
- while (den < num && bit && !(den & (1L<<31)))
- {
- den <<=1;
- bit <<=1;
- }
- while (bit)
- {
- if (num >= den)
- {
- num -= den;
- res |= bit;
- }
- bit >>=1;
- den >>=1;
- }
- if (modwanted) return num;
- return res;
-}
-*/
-
-; inputs: r0 = numerator, r1 = denominator
-; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed
-
- .global ___udivmodsi4
-___udivmodsi4:
- mov r2,1 ; bit = 1
- mov r3,0 ; res = 0
-.Lloop1:
- sub.f 0,r1,r0 ; while (den < num
- nop
- bnc.nd .Lloop2
- sub.f 0,r2,0 ; && bit
- nop
- bz.nd .Lloop2
- lsl.f 0,r1 ; && !(den & (1<<31))
- nop
- bc.nd .Lloop2
- lsl r1,r1 ; den <<= 1
- b.d .Lloop1
- lsl r2,r2 ; bit <<= 1
-.Lloop2:
- sub.f 0,r2,0 ; while (bit)
- nop
- bz.nd .Ldivmodend
- sub.f 0,r0,r1 ; if (num >= den)
- nop
- bc.nd .Lshiftdown
- sub r0,r0,r1 ; num -= den
- or r3,r3,r2 ; res |= bit
-.Lshiftdown:
- lsr r2,r2 ; bit >>= 1
- b.d .Lloop2
- lsr r1,r1 ; den >>= 1
-.Ldivmodend:
- mov r1,r0 ; r1 = mod
- j.d blink
- mov r0,r3 ; r0 = res
-
-#endif
-
-#ifdef L_udivsi3
- .section .text
- .align 4
-
-#ifdef __base__
- .cpu base
- .global ___udivsi3
-___udivsi3:
- mov r7,blink
- bl.nd ___udivmodsi4
- j.nd r7
-#endif
-
-#endif /* L_udivsi3 */
-
-#ifdef L_divsi3
- .section .text
- .align 4
-
-#ifdef __base__
- .cpu base
- .global ___divsi3
-___divsi3:
- mov r7,blink
- bl.nd ___divnorm
- bl.nd ___udivmodsi4
- and.f 0,r6,1
- sub.nz r0,0,r0 ; cannot go in delay slot, has limm value
- j.nd r7
-#endif
-
-#endif /* L_divsi3 */
-
-#ifdef L_umodsi3
- .section .text
- .align 4
-
-#ifdef __base__
- .cpu base
- .global ___umodsi3
-___umodsi3:
- mov r7,blink
- bl.nd ___udivmodsi4
- j.d r7
- mov r0,r1
-#endif
-
-#endif /* L_umodsi3 */
-
-#ifdef L_modsi3
- .section .text
- .align 4
-
-#ifdef __base__
- .cpu base
- .global ___modsi3
-___modsi3:
- mov r7,blink
- bl.nd ___divnorm
- bl.nd ___udivmodsi4
- and.f 0,r6,2
- sub.nz r1,0,r1
- j.d r7
- mov r0,r1
-#endif
-
-#endif /* L_modsi3 */
diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
deleted file mode 100755
index d922c27..0000000
--- a/gcc/config/arc/t-arc
+++ /dev/null
@@ -1,72 +0,0 @@
-CROSS_LIBGCC1 = libgcc1-asm.a
-LIB1ASMSRC = arc/lib1funcs.asm
-LIB1ASMFUNCS = _mulsi3 _umulsidi3 _udivsi3 _divsi3 _umodsi3 _modsi3 _divmod_tools
-
-# We need libgcc routines to be mangled according to which cpu they
-# were compiled for.
-# ??? -mmangle-cpu passed by default for now.
-#LIBGCC2_CFLAGS = -g1 -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) -mmangle-cpu
-
-# These are really part of libgcc1, but this will cause them to be
-# built correctly, so...
-
-LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#ifndef __big_endian__' > dp-bit.c
- echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
- echo '#endif' >> dp-bit.c
- cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- echo '#ifndef __big_endian__' >> fp-bit.c
- echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
- echo '#endif' >> fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-# .init/.fini section routines
-
-x-crtinit.o: $(srcdir)/config/arc/initfini.c $(GCC_PASSES) $(CONFIG_H)
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
- -DCRT_INIT -finhibit-size-directive -fno-inline-functions \
- -g0 -c $(srcdir)/config/arc/initfini.c -o $(dir)/crtinit.o
-
-x-crtfini.o: $(srcdir)/config/arc/initfini.c $(GCC_PASSES) $(CONFIG_H)
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
- -DCRT_FINI -finhibit-size-directive -fno-inline-functions \
- -g0 -c $(srcdir)/config/arc/initfini.c -o $(dir)/crtfini.o
-
-MULTILIB_OPTIONS = EB
-MULTILIB_DIRNAMES = be
-
-# We need our own versions to build multiple copies of crt*.o.
-# ??? Use new support in Makefile.
-
-LIBGCC = stmp-multilib-arc
-INSTALL_LIBGCC = install-multilib-arc
-
-stmp-multilib-arc: stmp-multilib
- for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \
- dir=`echo $$i | sed -e 's/;.*$$//'`; \
- flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
- $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- CC="$(CC)" CFLAGS="$(CFLAGS)" \
- HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
- GCC_CFLAGS="$(GCC_CFLAGS) $${flags}" \
- INCLUDES="$(INCLUDES)" CRTSTUFF_T_CFLAGS=$(CRTSTUFF_T_CFLAGS) \
- dir="$${dir}" x-crtinit.o x-crtfini.o; \
- if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- done
- touch stmp-multilib-arc
-
-install-multilib-arc: install-multilib
- for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \
- dir=`echo $$i | sed -e 's/;.*$$//'`; \
- rm -f $(libsubdir)/$${dir}/crtinit.o; \
- $(INSTALL_DATA) $${dir}/crtinit.o $(libsubdir)/$${dir}/crtinit.o; \
- chmod a-x $(libsubdir)/$${dir}/crtinit.o; \
- rm -f $(libsubdir)/$${dir}/crtfini.o; \
- $(INSTALL_DATA) $${dir}/crtfini.o $(libsubdir)/$${dir}/crtfini.o; \
- chmod a-x $(libsubdir)/$${dir}/crtfini.o; \
- done
diff --git a/gcc/config/arc/xm-arc.h b/gcc/config/arc/xm-arc.h
deleted file mode 100755
index ba011e9..0000000
--- a/gcc/config/arc/xm-arc.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Configuration for GNU C-compiler for the ARC processor.
- Copyright (C) 1994, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* #defines that need visibility everywhere. */
-#define FALSE 0
-#define TRUE 1
-
-/* This describes the machine the compiler is hosted on. */
-#define HOST_BITS_PER_CHAR 8
-#define HOST_BITS_PER_SHORT 16
-#define HOST_BITS_PER_INT 32
-#define HOST_BITS_PER_LONG 32
-#define HOST_BITS_PER_LONGLONG 64
-
-/* Doubles are stored in memory with the high order word first. This
- matters when cross-compiling. */
-#define HOST_WORDS_BIG_ENDIAN 1
-
-/* target machine dependencies.
- tm.h is a symbolic link to the actual target specific file. */
-#include "tm.h"
-
-/* Arguments to use with `exit'. */
-#define SUCCESS_EXIT_CODE 0
-#define FATAL_EXIT_CODE 33
-
-/* If compiled with Sun CC, the use of alloca requires this #include. */
-#ifndef __GNUC__
-#include "alloca.h"
-#endif