arc, arc: New directories.
2013-10-01 Saurabh Verma <saurabh.verma@codito.com> Ramana Radhakrishnan <ramana.radhakrishnan@codito.com> Joern Rennecke <joern.rennecke@embecosm.com> Muhammad Khurram Riaz <khurram.riaz@arc.com> Brendan Kehoe <brendan@zen.org> Michael Eager <eager@eagercon.com> Simon Cook <simon.cook@embecosm.com> Jeremy Bennett <jeremy.bennett@embecosm.com> * config/arc, common/config/arc: New directories. Co-Authored-By: Brendan Kehoe <brendan@zen.org> Co-Authored-By: Jeremy Bennett <jeremy.bennett@embecosm.com> Co-Authored-By: Joern Rennecke <joern.rennecke@embecosm.com> Co-Authored-By: Michael Eager <eager@eagercon.com> Co-Authored-By: Muhammad Khurram Riaz <khurram.riaz@arc.com> Co-Authored-By: Ramana Radhakrishnan <ramana.radhakrishnan@codito.com> Co-Authored-By: Simon Cook <simon.cook@embecosm.com> From-SVN: r203072
This commit is contained in:
parent
2a3e690ab3
commit
526b7aee8f
|
@ -1,3 +1,14 @@
|
|||
2013-10-01 Saurabh Verma <saurabh.verma@codito.com>
|
||||
Ramana Radhakrishnan <ramana.radhakrishnan@codito.com>
|
||||
Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
Muhammad Khurram Riaz <khurram.riaz@arc.com>
|
||||
Brendan Kehoe <brendan@zen.org>
|
||||
Michael Eager <eager@eagercon.com>
|
||||
Simon Cook <simon.cook@embecosm.com>
|
||||
Jeremy Bennett <jeremy.bennett@embecosm.com>
|
||||
|
||||
* config/arc, common/config/arc: New directories.
|
||||
|
||||
2013-10-01 Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
Brendan Kehoe <brendan@zen.org>
|
||||
Simon Cook <simon.cook@embecosm.com>
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/* Common hooks for Synopsys DesignWare ARC
|
||||
Copyright (C) 1994, 1995, 1997, 1998, 2007-2013
|
||||
Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "tm.h"
|
||||
#include "common/common-target.h"
|
||||
#include "opts.h"
|
||||
#include "flags.h"
|
||||
|
||||
static void
|
||||
arc_option_init_struct (struct gcc_options *opts)
|
||||
{
|
||||
opts->x_flag_no_common = 255; /* Mark as not user-initialized. */
|
||||
|
||||
/* Which cpu we're compiling for (A5, ARC600, ARC601, ARC700). */
|
||||
arc_cpu = PROCESSOR_NONE;
|
||||
}
|
||||
|
||||
/* Set default optimization options. */
|
||||
/* The conditions are incomplete, so we rely on the evaluation order here,
|
||||
which goes from first to last, i.e. the last match prevails. */
|
||||
/* ??? But this trick only works for reject_negative options. Approximate
|
||||
missing option combination. */
|
||||
#define OPT_LEVELS_3_PLUS_SPEED_ONLY OPT_LEVELS_3_PLUS
|
||||
static const struct default_options arc_option_optimization_table[] =
|
||||
{
|
||||
{ OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
|
||||
{ OPT_LEVELS_ALL, OPT_mRcq, NULL, 1 },
|
||||
{ OPT_LEVELS_ALL, OPT_mRcw, NULL, 1 },
|
||||
{ OPT_LEVELS_ALL, OPT_msize_level_, NULL, 1 },
|
||||
{ OPT_LEVELS_3_PLUS_SPEED_ONLY, OPT_msize_level_, NULL, 0 },
|
||||
{ OPT_LEVELS_SIZE, OPT_msize_level_, NULL, 3 },
|
||||
{ OPT_LEVELS_3_PLUS_SPEED_ONLY, OPT_malign_call, NULL, 1 },
|
||||
{ OPT_LEVELS_ALL, OPT_mearly_cbranchsi, NULL, 1 },
|
||||
{ OPT_LEVELS_ALL, OPT_mbbit_peephole, NULL, 1 },
|
||||
{ OPT_LEVELS_SIZE, OPT_mq_class, NULL, 1 },
|
||||
{ OPT_LEVELS_SIZE, OPT_mcase_vector_pcrel, NULL, 1 },
|
||||
{ OPT_LEVELS_SIZE, OPT_mcompact_casesi, NULL, 1 },
|
||||
{ OPT_LEVELS_NONE, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
/* Process options. */
|
||||
static bool
|
||||
arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
|
||||
const struct cl_decoded_option *decoded,
|
||||
location_t loc)
|
||||
{
|
||||
size_t code = decoded->opt_index;
|
||||
int value = decoded->value;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
static int mcpu_seen = PROCESSOR_NONE;
|
||||
case OPT_mcpu_:
|
||||
/* N.B., at this point arc_cpu has already been set to its new value by
|
||||
our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless. */
|
||||
|
||||
if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
|
||||
warning_at (loc, 0, "multiple -mcpu= options specified.");
|
||||
mcpu_seen = value;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case PROCESSOR_A5:
|
||||
case PROCESSOR_ARC600:
|
||||
case PROCESSOR_ARC700:
|
||||
if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
|
||||
opts->x_target_flags |= MASK_BARREL_SHIFTER;
|
||||
break;
|
||||
case PROCESSOR_ARC601:
|
||||
if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
|
||||
opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
|
||||
#define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
|
||||
#define TARGET_HANDLE_OPTION arc_handle_option
|
||||
|
||||
#define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
|
||||
|
||||
/* We default to ARC700, which has the barrel shifter enabled. */
|
||||
#define TARGET_DEFAULT_TARGET_FLAGS \
|
||||
(MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
|
||||
|
||||
|
||||
#include "common/common-target-def.h"
|
||||
|
||||
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
|
|
@ -0,0 +1,37 @@
|
|||
/* Definitions of target machine for GNU compiler, Synopsys DesignWare ARC cpu.
|
||||
Copyright (C) 2002, 2007-2012 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Some insns set all condition code flags, some only set the ZNC flags, and
|
||||
some only set the ZN flags. */
|
||||
|
||||
CC_MODE (CC_ZN);
|
||||
CC_MODE (CC_Z);
|
||||
CC_MODE (CC_C);
|
||||
CC_MODE (CC_FP_GT);
|
||||
CC_MODE (CC_FP_GE);
|
||||
CC_MODE (CC_FP_ORD);
|
||||
CC_MODE (CC_FP_UNEQ);
|
||||
CC_MODE (CC_FPX);
|
||||
|
||||
/* Vector modes. */
|
||||
VECTOR_MODES (INT, 4); /* V4QI V2HI */
|
||||
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
|
||||
VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
|
|
@ -0,0 +1,28 @@
|
|||
/* GCC option-handling definitions for the Synopsys DesignWare ARC architecture.
|
||||
|
||||
Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
enum processor_type
|
||||
{
|
||||
PROCESSOR_NONE,
|
||||
PROCESSOR_A5,
|
||||
PROCESSOR_ARC600,
|
||||
PROCESSOR_ARC601,
|
||||
PROCESSOR_ARC700
|
||||
};
|
|
@ -0,0 +1,118 @@
|
|||
/* Definitions of target machine for GNU compiler, Synopsys DesignWare ARC cpu.
|
||||
Copyright (C) 2000, 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef RTX_CODE
|
||||
|
||||
extern enum machine_mode arc_select_cc_mode (enum rtx_code, rtx, rtx);
|
||||
|
||||
/* Define the function that build the compare insn for scc, bcc and mov*cc. */
|
||||
extern struct rtx_def *gen_compare_reg (rtx, enum machine_mode);
|
||||
|
||||
/* Declarations for various fns used in the .md file. */
|
||||
extern void arc_output_function_epilogue (FILE *, HOST_WIDE_INT, int);
|
||||
extern const char *output_shift (rtx *);
|
||||
extern bool compact_sda_memory_operand (rtx op,enum machine_mode mode);
|
||||
extern bool arc_double_limm_p (rtx);
|
||||
extern void arc_print_operand (FILE *, rtx, int);
|
||||
extern void arc_print_operand_address (FILE *, rtx);
|
||||
extern void arc_final_prescan_insn (rtx, rtx *, int);
|
||||
extern void arc_set_default_type_attributes(tree type);
|
||||
extern const char *arc_output_libcall (const char *);
|
||||
extern bool prepare_extend_operands (rtx *operands, enum rtx_code code,
|
||||
enum machine_mode omode);
|
||||
extern int arc_output_addsi (rtx *operands, bool, bool);
|
||||
extern int arc_output_commutative_cond_exec (rtx *operands, bool);
|
||||
extern bool arc_expand_movmem (rtx *operands);
|
||||
extern bool prepare_move_operands (rtx *operands, enum machine_mode mode);
|
||||
extern void emit_shift (enum rtx_code, rtx, rtx, rtx);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern enum arc_function_type arc_compute_function_type (struct function *);
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
|
||||
extern void arc_init (void);
|
||||
extern unsigned int arc_compute_frame_size (int);
|
||||
extern bool arc_ccfsm_branch_deleted_p (void);
|
||||
extern void arc_ccfsm_record_branch_deleted (void);
|
||||
|
||||
extern rtx arc_legitimize_pic_address (rtx, rtx);
|
||||
void arc_asm_output_aligned_decl_local (FILE *, tree, const char *,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT);
|
||||
extern rtx arc_return_addr_rtx (int , rtx);
|
||||
extern bool check_if_valid_regno_const (rtx *, int);
|
||||
extern bool check_if_valid_sleep_operand (rtx *, int);
|
||||
extern bool arc_legitimate_constant_p (enum machine_mode, rtx);
|
||||
extern bool arc_legitimate_pc_offset_p (rtx);
|
||||
extern bool arc_legitimate_pic_addr_p (rtx);
|
||||
extern void emit_pic_move (rtx *, enum machine_mode);
|
||||
extern bool arc_raw_symbolic_reference_mentioned_p (rtx, bool);
|
||||
extern bool arc_legitimate_pic_operand_p (rtx);
|
||||
extern bool arc_is_longcall_p (rtx);
|
||||
extern bool arc_is_shortcall_p (rtx);
|
||||
extern bool arc_profile_call (rtx callee);
|
||||
extern bool valid_brcc_with_delay_p (rtx *);
|
||||
extern bool small_data_pattern (rtx , enum machine_mode);
|
||||
extern rtx arc_rewrite_small_data (rtx);
|
||||
extern bool arc_ccfsm_cond_exec_p (void);
|
||||
struct secondary_reload_info;
|
||||
extern int arc_register_move_cost (enum machine_mode, enum reg_class,
|
||||
enum reg_class);
|
||||
extern rtx disi_highpart (rtx);
|
||||
extern int arc_adjust_insn_length (rtx, int, bool);
|
||||
extern int arc_corereg_hazard (rtx, rtx);
|
||||
extern int arc_hazard (rtx, rtx);
|
||||
extern int arc_write_ext_corereg (rtx);
|
||||
extern rtx gen_acc1 (void);
|
||||
extern rtx gen_acc2 (void);
|
||||
extern rtx gen_mlo (void);
|
||||
extern rtx gen_mhi (void);
|
||||
extern bool arc_branch_size_unknown_p (void);
|
||||
struct arc_ccfsm;
|
||||
extern void arc_ccfsm_record_condition (rtx, bool, rtx, struct arc_ccfsm *);
|
||||
extern void arc_expand_prologue (void);
|
||||
extern void arc_expand_epilogue (int);
|
||||
extern void arc_init_expanders (void);
|
||||
extern int arc_check_millicode (rtx op, int offset, int load_p);
|
||||
extern int arc_get_unalign (void);
|
||||
extern void arc_clear_unalign (void);
|
||||
extern void arc_toggle_unalign (void);
|
||||
extern void split_addsi (rtx *);
|
||||
extern void split_subsi (rtx *);
|
||||
extern void arc_pad_return (void);
|
||||
extern rtx arc_split_move (rtx *);
|
||||
extern int arc_verify_short (rtx insn, int unalign, int);
|
||||
extern const char *arc_short_long (rtx insn, const char *, const char *);
|
||||
extern rtx arc_regno_use_in (unsigned int, rtx);
|
||||
extern int arc_attr_type (rtx);
|
||||
extern bool arc_scheduling_not_expected (void);
|
||||
extern bool arc_sets_cc_p (rtx insn);
|
||||
extern int arc_label_align (rtx label);
|
||||
extern bool arc_need_delay (rtx insn);
|
||||
extern bool arc_text_label (rtx);
|
||||
extern int arc_decl_pretend_args (tree decl);
|
||||
extern bool arc_short_comparison_p (rtx, int);
|
||||
extern bool arc_epilogue_uses (int regno);
|
||||
/* insn-attrtab.c doesn't include reload.h, which declares regno_clobbered_p. */
|
||||
extern int regno_clobbered_p (unsigned int, rtx, enum machine_mode, int);
|
||||
extern int arc_return_slot_offset (void);
|
||||
extern bool arc_legitimize_reload_address (rtx *, enum machine_mode, int, int);
|
|
@ -0,0 +1,186 @@
|
|||
/* Synopsys DesignWare ARC SIMD include file.
|
||||
Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||
Written by Saurabh Verma (saurabh.verma@celunite.com) on behalf os Synopsys
|
||||
Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, if you include this header file into source
|
||||
files compiled by GCC, this header file 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. */
|
||||
|
||||
#ifndef _ARC_SIMD_H
|
||||
#define _ARC_SIMD_H 1
|
||||
|
||||
#ifndef __ARC_SIMD__
|
||||
#error Use the "-msimd" flag to enable ARC SIMD support
|
||||
#endif
|
||||
|
||||
/* I0-I7 registers. */
|
||||
#define _IREG_I0 0
|
||||
#define _IREG_I1 1
|
||||
#define _IREG_I2 2
|
||||
#define _IREG_I3 3
|
||||
#define _IREG_I4 4
|
||||
#define _IREG_I5 5
|
||||
#define _IREG_I6 6
|
||||
#define _IREG_I7 7
|
||||
|
||||
/* DMA configuration registers. */
|
||||
#define _DMA_REG_DR0 0
|
||||
#define _DMA_SDM_SRC_ADR_REG _DMA_REG_DR0
|
||||
#define _DMA_SDM_DEST_ADR_REG _DMA_REG_DR0
|
||||
|
||||
#define _DMA_REG_DR1 1
|
||||
#define _DMA_SDM_STRIDE_REG _DMA_REG_DR1
|
||||
|
||||
#define _DMA_REG_DR2 2
|
||||
#define _DMA_BLK_REG _DMA_REG_DR2
|
||||
|
||||
#define _DMA_REG_DR3 3
|
||||
#define _DMA_LOC_REG _DMA_REG_DR3
|
||||
|
||||
#define _DMA_REG_DR4 4
|
||||
#define _DMA_SYS_SRC_ADR_REG _DMA_REG_DR4
|
||||
#define _DMA_SYS_DEST_ADR_REG _DMA_REG_DR4
|
||||
|
||||
#define _DMA_REG_DR5 5
|
||||
#define _DMA_SYS_STRIDE_REG _DMA_REG_DR5
|
||||
|
||||
#define _DMA_REG_DR6 6
|
||||
#define _DMA_CFG_REG _DMA_REG_DR6
|
||||
|
||||
#define _DMA_REG_DR7 7
|
||||
#define _DMA_FT_BASE_ADR_REG _DMA_REG_DR7
|
||||
|
||||
/* Predefined types used in vector instructions. */
|
||||
typedef int __v4si __attribute__((vector_size(16)));
|
||||
typedef short __v8hi __attribute__((vector_size(16)));
|
||||
|
||||
/* Synonyms */
|
||||
#define _vaddaw __builtin_arc_vaddaw
|
||||
#define _vaddw __builtin_arc_vaddw
|
||||
#define _vavb __builtin_arc_vavb
|
||||
#define _vavrb __builtin_arc_vavrb
|
||||
#define _vdifaw __builtin_arc_vdifaw
|
||||
#define _vdifw __builtin_arc_vdifw
|
||||
#define _vmaxaw __builtin_arc_vmaxaw
|
||||
#define _vmaxw __builtin_arc_vmaxw
|
||||
#define _vminaw __builtin_arc_vminaw
|
||||
#define _vminw __builtin_arc_vminw
|
||||
#define _vmulaw __builtin_arc_vmulaw
|
||||
#define _vmulfaw __builtin_arc_vmulfaw
|
||||
#define _vmulfw __builtin_arc_vmulfw
|
||||
#define _vmulw __builtin_arc_vmulw
|
||||
#define _vsubaw __builtin_arc_vsubaw
|
||||
#define _vsubw __builtin_arc_vsubw
|
||||
#define _vsummw __builtin_arc_vsummw
|
||||
#define _vand __builtin_arc_vand
|
||||
#define _vandaw __builtin_arc_vandaw
|
||||
#define _vbic __builtin_arc_vbic
|
||||
#define _vbicaw __builtin_arc_vbicaw
|
||||
#define _vor __builtin_arc_vor
|
||||
#define _vxor __builtin_arc_vxor
|
||||
#define _vxoraw __builtin_arc_vxoraw
|
||||
#define _veqw __builtin_arc_veqw
|
||||
#define _vlew __builtin_arc_vlew
|
||||
#define _vltw __builtin_arc_vltw
|
||||
#define _vnew __builtin_arc_vnew
|
||||
#define _vmr1aw __builtin_arc_vmr1aw
|
||||
#define _vmr1w __builtin_arc_vmr1w
|
||||
#define _vmr2aw __builtin_arc_vmr2aw
|
||||
#define _vmr2w __builtin_arc_vmr2w
|
||||
#define _vmr3aw __builtin_arc_vmr3aw
|
||||
#define _vmr3w __builtin_arc_vmr3w
|
||||
#define _vmr4aw __builtin_arc_vmr4aw
|
||||
#define _vmr4w __builtin_arc_vmr4w
|
||||
#define _vmr5aw __builtin_arc_vmr5aw
|
||||
#define _vmr5w __builtin_arc_vmr5w
|
||||
#define _vmr6aw __builtin_arc_vmr6aw
|
||||
#define _vmr6w __builtin_arc_vmr6w
|
||||
#define _vmr7aw __builtin_arc_vmr7aw
|
||||
#define _vmr7w __builtin_arc_vmr7w
|
||||
#define _vmrb __builtin_arc_vmrb
|
||||
#define _vh264f __builtin_arc_vh264f
|
||||
#define _vh264ft __builtin_arc_vh264ft
|
||||
#define _vh264fw __builtin_arc_vh264fw
|
||||
#define _vvc1f __builtin_arc_vvc1f
|
||||
#define _vvc1ft __builtin_arc_vvc1ft
|
||||
#define _vbaddw __builtin_arc_vbaddw
|
||||
#define _vbmaxw __builtin_arc_vbmaxw
|
||||
#define _vbminw __builtin_arc_vbminw
|
||||
#define _vbmulaw __builtin_arc_vbmulaw
|
||||
#define _vbmulfw __builtin_arc_vbmulfw
|
||||
#define _vbmulw __builtin_arc_vbmulw
|
||||
#define _vbrsubw __builtin_arc_vbrsubw
|
||||
#define _vbsubw __builtin_arc_vbsubw
|
||||
#define _vasrw __builtin_arc_vasrw
|
||||
#define _vsr8 __builtin_arc_vsr8
|
||||
#define _vsr8aw __builtin_arc_vsr8aw
|
||||
#define _vasrrwi __builtin_arc_vasrrwi
|
||||
#define _vasrsrwi __builtin_arc_vasrsrwi
|
||||
#define _vasrwi __builtin_arc_vasrwi
|
||||
#define _vasrpwbi __builtin_arc_vasrpwbi
|
||||
#define _vasrrpwbi __builtin_arc_vasrrpwbi
|
||||
#define _vsr8awi __builtin_arc_vsr8awi
|
||||
#define _vsr8i __builtin_arc_vsr8i
|
||||
#define _vmvaw __builtin_arc_vmvaw
|
||||
#define _vmvw __builtin_arc_vmvw
|
||||
#define _vmvzw __builtin_arc_vmvzw
|
||||
#define _vd6tapf __builtin_arc_vd6tapf
|
||||
#define _vmovaw __builtin_arc_vmovaw
|
||||
#define _vmovw __builtin_arc_vmovw
|
||||
#define _vmovzw __builtin_arc_vmovzw
|
||||
#define _vabsaw __builtin_arc_vabsaw
|
||||
#define _vabsw __builtin_arc_vabsw
|
||||
#define _vaddsuw __builtin_arc_vaddsuw
|
||||
#define _vsignw __builtin_arc_vsignw
|
||||
#define _vexch1 __builtin_arc_vexch1
|
||||
#define _vexch2 __builtin_arc_vexch2
|
||||
#define _vexch4 __builtin_arc_vexch4
|
||||
#define _vupbaw __builtin_arc_vupbaw
|
||||
#define _vupbw __builtin_arc_vupbw
|
||||
#define _vupsbaw __builtin_arc_vupsbaw
|
||||
#define _vupsbw __builtin_arc_vupsbw
|
||||
#define _vdirun __builtin_arc_vdirun
|
||||
#define _vdorun __builtin_arc_vdorun
|
||||
#define _vdiwr __builtin_arc_vdiwr
|
||||
#define _vdowr __builtin_arc_vdowr
|
||||
#define _vrec __builtin_arc_vrec
|
||||
#define _vrun __builtin_arc_vrun
|
||||
#define _vrecrun __builtin_arc_vrecrun
|
||||
#define _vendrec __builtin_arc_vendrec
|
||||
#define _vld32wh __builtin_arc_vld32wh
|
||||
#define _vld32wl __builtin_arc_vld32wl
|
||||
#define _vld64 __builtin_arc_vld64
|
||||
#define _vld32 __builtin_arc_vld32
|
||||
#define _vld64w __builtin_arc_vld64w
|
||||
#define _vld128 __builtin_arc_vld128
|
||||
#define _vst128 __builtin_arc_vst128
|
||||
#define _vst64 __builtin_arc_vst64
|
||||
#define _vst16_n __builtin_arc_vst16_n
|
||||
#define _vst32_n __builtin_arc_vst32_n
|
||||
#define _vinti __builtin_arc_vinti
|
||||
|
||||
/* Additional synonyms to ease programming. */
|
||||
#define _setup_dma_in_channel_reg _vdiwr
|
||||
#define _setup_dma_out_channel_reg _vdowr
|
||||
|
||||
#endif /* _ARC_SIMD_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,390 @@
|
|||
; Options for the Synopsys DesignWare ARC port of the compiler
|
||||
;
|
||||
; Copyright (C) 2005, 2007-2013 Free Software Foundation, Inc.
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
; GCC is free software; you can redistribute it and/or modify it under
|
||||
; the terms of the GNU General Public License as published by the Free
|
||||
; Software Foundation; either version 3, or (at your option) any later
|
||||
; version.
|
||||
;
|
||||
; GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
; License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
HeaderInclude
|
||||
config/arc/arc-opts.h
|
||||
|
||||
mbig-endian
|
||||
Target Report RejectNegative Mask(BIG_ENDIAN)
|
||||
Compile code for big endian mode
|
||||
|
||||
mlittle-endian
|
||||
Target Report RejectNegative InverseMask(BIG_ENDIAN)
|
||||
Compile code for little endian mode. This is the default
|
||||
|
||||
mno-cond-exec
|
||||
Target Report RejectNegative Mask(NO_COND_EXEC)
|
||||
Disable ARCompact specific pass to generate conditional execution instructions
|
||||
|
||||
mA5
|
||||
Target Report
|
||||
Generate ARCompact 32-bit code for ARCtangent-A5 processor
|
||||
|
||||
mA6
|
||||
Target Report
|
||||
Generate ARCompact 32-bit code for ARC600 processor
|
||||
|
||||
mARC600
|
||||
Target Report
|
||||
Same as -mA6
|
||||
|
||||
mARC601
|
||||
Target Report
|
||||
Generate ARCompact 32-bit code for ARC601 processor
|
||||
|
||||
mA7
|
||||
Target Report
|
||||
Generate ARCompact 32-bit code for ARC700 processor
|
||||
|
||||
mARC700
|
||||
Target Report
|
||||
Same as -mA7
|
||||
|
||||
mmixed-code
|
||||
Target Report Mask(MIXED_CODE_SET)
|
||||
Tweak register allocation to help 16-bit instruction generation
|
||||
; originally this was:
|
||||
;Generate ARCompact 16-bit instructions intermixed with 32-bit instructions for ARCtangent-A5 and higher processors
|
||||
; but we do that without -mmixed-code, too, it's just a different instruction
|
||||
; count / size tradeoff.
|
||||
|
||||
; We use an explict definition for the negative form because that is the
|
||||
; actually interesting option, and we want that to have its own comment.
|
||||
mvolatile-cache
|
||||
Target Report RejectNegative Mask(VOLATILE_CACHE_SET)
|
||||
Use ordinarily cached memory accesses for volatile references
|
||||
|
||||
mno-volatile-cache
|
||||
Target Report RejectNegative InverseMask(VOLATILE_CACHE_SET)
|
||||
Enable cache bypass for volatile references
|
||||
|
||||
mbarrel-shifter
|
||||
Target Report Mask(BARREL_SHIFTER)
|
||||
Generate instructions supported by barrel shifter
|
||||
|
||||
mnorm
|
||||
Target Report Mask(NORM_SET)
|
||||
Generate norm instruction
|
||||
|
||||
mswap
|
||||
Target Report Mask(SWAP_SET)
|
||||
Generate swap instruction
|
||||
|
||||
mmul64
|
||||
Target Report Mask(MUL64_SET)
|
||||
Generate mul64 and mulu64 instructions
|
||||
|
||||
mno-mpy
|
||||
Target Report Mask(NOMPY_SET)
|
||||
Do not generate mpy instructions for ARC700
|
||||
|
||||
mea
|
||||
Target Report Mask(EA_SET)
|
||||
Generate Extended arithmetic instructions. Currently only divaw, adds, subs and sat16 are supported
|
||||
|
||||
msoft-float
|
||||
Target Report Mask(0)
|
||||
Dummy flag. This is the default unless FPX switches are provided explicitly
|
||||
|
||||
mlong-calls
|
||||
Target Report Mask(LONG_CALLS_SET)
|
||||
Generate call insns as register indirect calls
|
||||
|
||||
mno-brcc
|
||||
Target Report Mask(NO_BRCC_SET)
|
||||
Do no generate BRcc instructions in arc_reorg.
|
||||
|
||||
msdata
|
||||
Target Report InverseMask(NO_SDATA_SET)
|
||||
Generate sdata references. This is the default, unless you compile for PIC.
|
||||
|
||||
mno-millicode
|
||||
Target Report Mask(NO_MILLICODE_THUNK_SET)
|
||||
Do not generate millicode thunks (needed only with -Os)
|
||||
|
||||
mspfp
|
||||
Target Report Mask(SPFP_COMPACT_SET)
|
||||
FPX: Generate Single Precision FPX (compact) instructions.
|
||||
|
||||
mspfp-compact
|
||||
Target Report Mask(SPFP_COMPACT_SET) MaskExists
|
||||
FPX: Generate Single Precision FPX (compact) instructions.
|
||||
|
||||
mspfp-fast
|
||||
Target Report Mask(SPFP_FAST_SET)
|
||||
FPX: Generate Single Precision FPX (fast) instructions.
|
||||
|
||||
margonaut
|
||||
Target Report Mask(ARGONAUT_SET)
|
||||
FPX: Enable Argonaut ARC CPU Double Precision Floating Point extensions.
|
||||
|
||||
mdpfp
|
||||
Target Report Mask(DPFP_COMPACT_SET)
|
||||
FPX: Generate Double Precision FPX (compact) instructions.
|
||||
|
||||
mdpfp-compact
|
||||
Target Report Mask(DPFP_COMPACT_SET) MaskExists
|
||||
FPX: Generate Double Precision FPX (compact) instructions.
|
||||
|
||||
mdpfp-fast
|
||||
Target Report Mask(DPFP_FAST_SET)
|
||||
FPX: Generate Double Precision FPX (fast) instructions.
|
||||
|
||||
mno-dpfp-lrsr
|
||||
Target Report Mask(DPFP_DISABLE_LRSR)
|
||||
Disable LR and SR instructions from using FPX extension aux registers.
|
||||
|
||||
msimd
|
||||
Target Report Mask(SIMD_SET)
|
||||
Enable generation of ARC SIMD instructions via target-specific builtins.
|
||||
|
||||
mcpu=
|
||||
Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
|
||||
-mcpu=CPU Compile code for ARC variant CPU
|
||||
|
||||
Enum
|
||||
Name(processor_type) Type(enum processor_type)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(A5) Value(PROCESSOR_A5)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
|
||||
|
||||
EnumValue
|
||||
Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
|
||||
|
||||
msize-level=
|
||||
Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
|
||||
size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os
|
||||
|
||||
misize
|
||||
Target Report Var(TARGET_DUMPISIZE)
|
||||
Annotate assembler instructions with estimated addresses
|
||||
|
||||
mmultcost=
|
||||
Target RejectNegative Joined UInteger Var(arc_multcost) Init(-1)
|
||||
Cost to assume for a multiply instruction, with 4 being equal to a normal insn.
|
||||
|
||||
mtune=ARC600
|
||||
Target RejectNegative Var(arc_tune, TUNE_ARC600)
|
||||
Tune for ARC600 cpu.
|
||||
|
||||
mtune=ARC601
|
||||
Target RejectNegative Var(arc_tune, TUNE_ARC600)
|
||||
Tune for ARC601 cpu.
|
||||
|
||||
mtune=ARC700
|
||||
Target RejectNegative Var(arc_tune, TUNE_ARC700_4_2_STD)
|
||||
Tune for ARC700 R4.2 Cpu with standard multiplier block.
|
||||
|
||||
mtune=ARC700-xmac
|
||||
Target RejectNegative Var(arc_tune, TUNE_ARC700_4_2_XMAC)
|
||||
Tune for ARC700 R4.2 Cpu with XMAC block.
|
||||
|
||||
mtune=ARC725D
|
||||
Target RejectNegative Var(arc_tune, TUNE_ARC700_4_2_XMAC)
|
||||
Tune for ARC700 R4.2 Cpu with XMAC block.
|
||||
|
||||
mtune=ARC750D
|
||||
Target RejectNegative Var(arc_tune, TUNE_ARC700_4_2_XMAC)
|
||||
Tune for ARC700 R4.2 Cpu with XMAC block.
|
||||
|
||||
mindexed-loads
|
||||
Target Var(TARGET_INDEXED_LOADS)
|
||||
Enable the use of indexed loads
|
||||
|
||||
mauto-modify-reg
|
||||
Target Var(TARGET_AUTO_MODIFY_REG)
|
||||
Enable the use of pre/post modify with register displacement.
|
||||
|
||||
mmul32x16
|
||||
Target Report Mask(MULMAC_32BY16_SET)
|
||||
Generate 32x16 multiply and mac instructions
|
||||
|
||||
; the initializer is supposed to be: Init(REG_BR_PROB_BASE/2) ,
|
||||
; alas, basic-block.h is not included in options.c .
|
||||
munalign-prob-threshold=
|
||||
Target RejectNegative Joined UInteger Var(arc_unalign_prob_threshold) Init(10000/2)
|
||||
Set probability threshold for unaligning branches
|
||||
|
||||
mmedium-calls
|
||||
Target Var(TARGET_MEDIUM_CALLS) Init(TARGET_MMEDIUM_CALLS_DEFAULT)
|
||||
Don't use less than 25 bit addressing range for calls.
|
||||
|
||||
mannotate-align
|
||||
Target Var(TARGET_ANNOTATE_ALIGN)
|
||||
Explain what alignment considerations lead to the decision to make an insn short or long.
|
||||
|
||||
malign-call
|
||||
Target Var(TARGET_ALIGN_CALL)
|
||||
Do alignment optimizations for call instructions.
|
||||
|
||||
mRcq
|
||||
Target Var(TARGET_Rcq)
|
||||
Enable Rcq constraint handling - most short code generation depends on this.
|
||||
|
||||
mRcw
|
||||
Target Var(TARGET_Rcw)
|
||||
Enable Rcw constraint handling - ccfsm condexec mostly depends on this.
|
||||
|
||||
mearly-cbranchsi
|
||||
Target Var(TARGET_EARLY_CBRANCHSI)
|
||||
Enable pre-reload use of cbranchsi pattern
|
||||
|
||||
mbbit-peephole
|
||||
Target Var(TARGET_BBIT_PEEPHOLE)
|
||||
Enable bbit peephole2
|
||||
|
||||
mcase-vector-pcrel
|
||||
Target Var(TARGET_CASE_VECTOR_PC_RELATIVE)
|
||||
Use pc-relative switch case tables - this enables case table shortening.
|
||||
|
||||
mcompact-casesi
|
||||
Target Var(TARGET_COMPACT_CASESI)
|
||||
Enable compact casesi pattern
|
||||
|
||||
mq-class
|
||||
Target Var(TARGET_Q_CLASS)
|
||||
Enable 'q' instruction alternatives.
|
||||
|
||||
mexpand-adddi
|
||||
Target Var(TARGET_EXPAND_ADDDI)
|
||||
Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
|
||||
|
||||
|
||||
; Flags used by the assembler, but for which we define preprocessor
|
||||
; macro symbols as well.
|
||||
mcrc
|
||||
Target Report
|
||||
Enable variable polynomial CRC extension
|
||||
|
||||
mdsp-packa
|
||||
Target Report
|
||||
Enable DSP 3.1 Pack A extensions
|
||||
|
||||
mdvbf
|
||||
Target Report
|
||||
Enable dual viterbi butterfly extension
|
||||
|
||||
mmac-d16
|
||||
Target Report Undocumented
|
||||
|
||||
mmac-24
|
||||
Target Report Undocumented
|
||||
|
||||
mtelephony
|
||||
Target Report RejectNegative
|
||||
Enable Dual and Single Operand Instructions for Telephony
|
||||
|
||||
mxy
|
||||
Target Report
|
||||
Enable XY Memory extension (DSP version 3)
|
||||
|
||||
; ARC700 4.10 extension instructions
|
||||
mlock
|
||||
Target Report
|
||||
Enable Locked Load/Store Conditional extension
|
||||
|
||||
mswape
|
||||
Target Report
|
||||
Enable swap byte ordering extension instruction
|
||||
|
||||
mrtsc
|
||||
Target Report
|
||||
Enable 64-bit Time-Stamp Counter extension instruction
|
||||
|
||||
mno-epilogue-cfi
|
||||
Target Report RejectNegative InverseMask(EPILOGUE_CFI)
|
||||
Disable generation of cfi for epilogues.
|
||||
|
||||
mepilogue-cfi
|
||||
Target RejectNegative Mask(EPILOGUE_CFI)
|
||||
Enable generation of cfi for epilogues.
|
||||
|
||||
EB
|
||||
Target
|
||||
Pass -EB option through to linker.
|
||||
|
||||
EL
|
||||
Target
|
||||
Pass -EL option through to linker.
|
||||
|
||||
marclinux
|
||||
target
|
||||
Pass -marclinux option through to linker.
|
||||
|
||||
marclinux_prof
|
||||
target
|
||||
Pass -marclinux_prof option through to linker.
|
||||
|
||||
;; lra is still unproven for ARC, so allow to fall back to reload with -mno-lra.
|
||||
;Target InverseMask(NO_LRA)
|
||||
mlra
|
||||
; lra still won't allow to configure libgcc; see PR rtl-optimization/55464.
|
||||
; so don't enable by default.
|
||||
Target Mask(LRA)
|
||||
Enable lra
|
||||
|
||||
mlra-priority-none
|
||||
Target RejectNegative Var(arc_lra_priority_tag, ARC_LRA_PRIORITY_NONE)
|
||||
Don't indicate any priority with TARGET_REGISTER_PRIORITY
|
||||
|
||||
mlra-priority-compact
|
||||
Target RejectNegative Var(arc_lra_prioritytag, ARC_LRA_PRIORITY_COMPACT)
|
||||
Indicate priority for r0..r3 / r12..r15 with TARGET_REGISTER_PRIORITY
|
||||
|
||||
mlra-priority-noncompact
|
||||
Target RejectNegative Var(arc_lra_prioritytag, ARC_LRA_PRIORITY_NONCOMPACT)
|
||||
Reduce priority for r0..r3 / r12..r15 with TARGET_REGISTER_PRIORITY
|
||||
|
||||
mucb-mcount
|
||||
Target Report Var(TARGET_UCB_MCOUNT)
|
||||
instrument with mcount calls as in the ucb code
|
||||
|
||||
; backward-compatibility aliases, translated by DRIVER_SELF_SPECS
|
||||
|
||||
mEA
|
||||
Target
|
||||
|
||||
multcost=
|
||||
Target RejectNegative Joined
|
||||
|
||||
; Unfortunately, listing the full option name gives us clashes
|
||||
; with OPT_opt_name being claimed for both opt_name and opt-name,
|
||||
; so we leave out the last character or more.
|
||||
mbarrel_shifte
|
||||
Target Joined
|
||||
|
||||
mspfp_
|
||||
Target Joined
|
||||
|
||||
mdpfp_
|
||||
Target Joined
|
||||
|
||||
mdsp_pack
|
||||
Target Joined
|
||||
|
||||
mmac_
|
||||
Target Joined
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
;; DFA scheduling description of the Synopsys DesignWare ARC600 cpu
|
||||
;; for GNU C compiler
|
||||
;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
;; Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
;; on behalf of Synopsys Inc.
|
||||
|
||||
;; This file is part of GCC.
|
||||
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define_automaton "ARC600")
|
||||
|
||||
(define_cpu_unit "issue_600" "ARC600")
|
||||
(define_cpu_unit "mul64_600" "ARC600")
|
||||
|
||||
; latency from flag-setting insns to branches is 3.
|
||||
(define_insn_reservation "compare_600" 3
|
||||
(and (eq_attr "tune" "arc600")
|
||||
(eq_attr "type" "compare"))
|
||||
"issue_600")
|
||||
|
||||
(define_insn_reservation "load_DI_600" 4
|
||||
(and (eq_attr "tune" "arc600")
|
||||
(eq_attr "type" "load")
|
||||
(match_operand:DI 0 "" ""))
|
||||
"issue_600")
|
||||
|
||||
(define_insn_reservation "load_600" 3
|
||||
(and (eq_attr "tune" "arc600")
|
||||
(eq_attr "type" "load")
|
||||
(not (match_operand:DI 0 "" "")))
|
||||
"issue_600")
|
||||
|
||||
(define_insn_reservation "mul_600_fast" 3
|
||||
(and (eq_attr "tune" "arc600")
|
||||
(match_test "arc_multcost < COSTS_N_INSNS (7)")
|
||||
(eq_attr "type" "multi,umulti"))
|
||||
"mul64_600*3")
|
||||
|
||||
(define_insn_reservation "mul_600_slow" 8
|
||||
(and (eq_attr "tune" "arc600")
|
||||
(match_test "arc_multcost >= COSTS_N_INSNS (7)")
|
||||
(eq_attr "type" "multi,umulti"))
|
||||
"mul64_600*8")
|
||||
|
||||
(define_insn_reservation "mul_mac_600" 3
|
||||
(and (eq_attr "tune" "arc600")
|
||||
(eq_attr "type" "mulmac_600"))
|
||||
"nothing*3")
|
||||
|
||||
(define_bypass 1 "mul_mac_600" "mul_mac_600")
|
|
@ -0,0 +1,170 @@
|
|||
;; DFA scheduling description of the Synopsys DesignWare ARC700 cpu
|
||||
;; for GNU C compiler
|
||||
;; Comments and Support For ARC700 instructions added by
|
||||
;; Saurabh Verma (saurabh.verma@codito.com)
|
||||
;; Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
|
||||
;; Factoring out and improvement of ARC700 Scheduling by
|
||||
;; Joern Rennecke (joern.rennecke@embecosm.com)
|
||||
;; Copyright (C) 2006-2012 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GCC.
|
||||
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define_automaton "ARC700")
|
||||
|
||||
;; aux to be added here
|
||||
(define_cpu_unit "core, dmp, write_port, dmp_write_port, multiplier, issue, blockage, simd_unit" "ARC700")
|
||||
|
||||
(define_insn_reservation "core_insn_DI" 2
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "unary, move, cmove, binary")
|
||||
(match_operand:DI 0 "" ""))
|
||||
"issue+core, issue+core+write_port, write_port")
|
||||
|
||||
(define_insn_reservation "lr" 2
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "lr"))
|
||||
"issue+blockage, blockage*2, write_port")
|
||||
|
||||
(define_insn_reservation "sr" 1
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "sr"))
|
||||
"issue+dmp_write_port+blockage, blockage*9")
|
||||
|
||||
(define_insn_reservation "core_insn" 1
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "unary, move, binary"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
(define_insn_reservation "cmove" 1
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "cmove"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
(define_insn_reservation "cc_arith" 1
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "cc_arith"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
(define_insn_reservation "two_cycle_core_insn" 2
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "two_cycle_core"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
(define_insn_reservation "divaw_insn" 2
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "divaw"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
(define_insn_reservation "shift_insn" 2
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "shift"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
; Latency from flag setters to arithmetic with carry is 3.
|
||||
(define_insn_reservation "compare_700" 3
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "compare"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
; Assume here the branch is predicted correctly and has a delay slot insn
|
||||
; or is properly unaligned.
|
||||
(define_insn_reservation "branch_700" 1
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "compare"))
|
||||
"issue+core, nothing, write_port")
|
||||
|
||||
; TODOs: is this correct ??
|
||||
(define_insn_reservation "multi_DI" 10
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "multi")
|
||||
(match_operand:DI 0 "" ""))
|
||||
"issue+multiplier, multiplier*2,issue+multiplier, multiplier*2,
|
||||
nothing,write_port,nothing*2, write_port")
|
||||
|
||||
(define_insn_reservation "umulti_DI" 9
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "umulti")
|
||||
(match_operand:DI 0 "" ""))
|
||||
"issue+multiplier, multiplier,issue+multiplier, multiplier*2,
|
||||
write_port,nothing*3, write_port")
|
||||
|
||||
(define_insn_reservation "umulti_xmac" 5
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "umulti"))
|
||||
"issue+multiplier, multiplier, nothing*3, write_port")
|
||||
|
||||
; latency of mpyu is lower than mpy / mpyh / mpyhu
|
||||
(define_insn_reservation "umulti_std" 6
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "umulti"))
|
||||
"issue+multiplier, multiplier*3, nothing*2, write_port")
|
||||
|
||||
;; arc700 xmac multiplier
|
||||
(define_insn_reservation "multi_xmac" 5
|
||||
(and (eq_attr "tune" "arc700_4_2_xmac")
|
||||
(eq_attr "type" "multi"))
|
||||
"issue+multiplier,multiplier,nothing*3,write_port")
|
||||
|
||||
; arc700 standard multiplier
|
||||
(define_insn_reservation "multi_std" 7
|
||||
(and (eq_attr "tune" "arc700_4_2_std")
|
||||
(eq_attr "type" "multi"))
|
||||
"issue+multiplier,multiplier*4,nothing*2,write_port")
|
||||
|
||||
;(define_insn_reservation "multi_SI" 7
|
||||
; (eq_attr "type" "multi")
|
||||
; "issue+multiplier, multiplier*2, nothing*4, write_port")
|
||||
|
||||
; There is no multiplier -> multiplier bypass except for the
|
||||
; mac -> mac dependency on the accumulator.
|
||||
|
||||
; divaw -> divaw latency is 1 cycle
|
||||
(define_bypass 1 "divaw_insn" "divaw_insn")
|
||||
|
||||
(define_bypass 1 "compare_700" "branch_700,core_insn,data_store,data_load")
|
||||
|
||||
; we could shedule the cmove immediately after the compare, but then
|
||||
; the cmove would have higher latency... so just keep the cmove apart
|
||||
; from the compare.
|
||||
(define_bypass 2 "compare_700" "cmove")
|
||||
|
||||
; no functional unit runs when blockage is reserved
|
||||
(exclusion_set "blockage" "core, multiplier")
|
||||
|
||||
(define_insn_reservation "data_load_DI" 4
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "load")
|
||||
(match_operand:DI 0 "" ""))
|
||||
"issue+dmp, issue+dmp, dmp_write_port, dmp_write_port")
|
||||
|
||||
(define_insn_reservation "data_load" 3
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "load")
|
||||
(not (match_operand:DI 0 "" "")))
|
||||
"issue+dmp, nothing, dmp_write_port")
|
||||
|
||||
(define_insn_reservation "data_store_DI" 2
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "store")
|
||||
(match_operand:DI 0 "" ""))
|
||||
"issue+dmp_write_port, issue+dmp_write_port")
|
||||
|
||||
(define_insn_reservation "data_store" 1
|
||||
(and (eq_attr "tune_arc700" "true")
|
||||
(eq_attr "type" "store")
|
||||
(not (match_operand:DI 0 "" "")))
|
||||
"issue+dmp_write_port")
|
|
@ -0,0 +1,399 @@
|
|||
;; Constraint definitions for Synopsys DesignWare ARC.
|
||||
;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;; Register constraints
|
||||
|
||||
; Most instructions accept arbitrary core registers for their inputs, even
|
||||
; if the core register in question cannot be written to, like the multiply
|
||||
; result registers of the ARCtangent-A5 and ARC600 .
|
||||
; First, define a class for core registers that can be read cheaply. This
|
||||
; is most or all core registers for ARC600, but only r0-r31 for ARC700
|
||||
(define_register_constraint "c" "CHEAP_CORE_REGS"
|
||||
"core register @code{r0}-@code{r31}, @code{ap},@code{pcl}")
|
||||
|
||||
; All core regs - e.g. for when we must have a way to reload a register.
|
||||
(define_register_constraint "Rac" "ALL_CORE_REGS"
|
||||
"core register @code{r0}-@code{r60}, @code{ap},@code{pcl}")
|
||||
|
||||
; Some core registers (.e.g lp_count) aren't general registers because they
|
||||
; can't be used as the destination of a multi-cycle operation like
|
||||
; load and/or multiply, yet they are still writable in the sense that
|
||||
; register-register moves and single-cycle arithmetic (e.g "add", "and",
|
||||
; but not "mpy") can write to them.
|
||||
(define_register_constraint "w" "WRITABLE_CORE_REGS"
|
||||
"writable core register: @code{r0}-@code{r31}, @code{r60}, nonfixed core register")
|
||||
|
||||
(define_register_constraint "W" "MPY_WRITABLE_CORE_REGS"
|
||||
"writable core register except @code{LP_COUNT} (@code{r60}): @code{r0}-@code{r31}, nonfixed core register")
|
||||
|
||||
(define_register_constraint "l" "LPCOUNT_REG"
|
||||
"@internal
|
||||
Loop count register @code{r60}")
|
||||
|
||||
(define_register_constraint "x" "R0_REGS"
|
||||
"@code{R0} register.")
|
||||
|
||||
(define_register_constraint "Rgp" "GP_REG"
|
||||
"@internal
|
||||
Global Pointer register @code{r26}")
|
||||
|
||||
(define_register_constraint "f" "FP_REG"
|
||||
"@internal
|
||||
Frame Pointer register @code{r27}")
|
||||
|
||||
(define_register_constraint "b" "SP_REGS"
|
||||
"@internal
|
||||
Stack Pointer register @code{r28}")
|
||||
|
||||
(define_register_constraint "k" "LINK_REGS"
|
||||
"@internal
|
||||
Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30},
|
||||
@code{blink}:@code{r31},")
|
||||
|
||||
(define_register_constraint "q" "ARCOMPACT16_REGS"
|
||||
"Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
|
||||
@code{r12}-@code{r15}")
|
||||
|
||||
(define_register_constraint "e" "AC16_BASE_REGS"
|
||||
"Registers usable as base-regs of memory addresses in ARCompact 16-bit memory
|
||||
instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}")
|
||||
|
||||
(define_register_constraint "D" "DOUBLE_REGS"
|
||||
"ARC FPX (dpfp) 64-bit registers. @code{D0}, @code{D1}")
|
||||
|
||||
(define_register_constraint "d" "SIMD_DMA_CONFIG_REGS"
|
||||
"@internal
|
||||
ARC SIMD DMA configuration registers @code{di0}-@code{di7},
|
||||
@code{do0}-@code{do7}")
|
||||
|
||||
(define_register_constraint "v" "SIMD_VR_REGS"
|
||||
"ARC SIMD 128-bit registers @code{VR0}-@code{VR23}")
|
||||
|
||||
; We could allow call-saved registers for sibling calls if we restored them
|
||||
; in the delay slot of the call. However, that would not allow to adjust the
|
||||
; stack pointer afterwards, so the call-saved register would have to be
|
||||
; restored from a call-used register that was just loaded with the value
|
||||
; before. So sticking to call-used registers for sibcalls will likely
|
||||
; generate better code overall.
|
||||
(define_register_constraint "Rsc" "SIBCALL_REGS"
|
||||
"@internal
|
||||
Sibling call register")
|
||||
|
||||
;; Integer constraints
|
||||
|
||||
(define_constraint "I"
|
||||
"@internal
|
||||
A signed 12-bit integer constant."
|
||||
(and (match_code "const_int")
|
||||
(match_test "SIGNED_INT12 (ival)")))
|
||||
|
||||
(define_constraint "K"
|
||||
"@internal
|
||||
A 3-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT3 (ival)")))
|
||||
|
||||
(define_constraint "L"
|
||||
"@internal
|
||||
A 6-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT6 (ival)")))
|
||||
|
||||
(define_constraint "CnL"
|
||||
"@internal
|
||||
One's complement of a 6-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT6 (~ival)")))
|
||||
|
||||
(define_constraint "CmL"
|
||||
"@internal
|
||||
Two's complement of a 6-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT6 (-ival)")))
|
||||
|
||||
(define_constraint "M"
|
||||
"@internal
|
||||
A 5-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT5 (ival)")))
|
||||
|
||||
(define_constraint "N"
|
||||
"@internal
|
||||
Integer constant 1"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IS_ONE (ival)")))
|
||||
|
||||
(define_constraint "O"
|
||||
"@internal
|
||||
A 7-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT7 (ival)")))
|
||||
|
||||
(define_constraint "P"
|
||||
"@internal
|
||||
An 8-bit unsigned integer constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT8 (ival)")))
|
||||
|
||||
(define_constraint "C_0"
|
||||
"@internal
|
||||
Zero"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 0")))
|
||||
|
||||
(define_constraint "Cn0"
|
||||
"@internal
|
||||
Negative or zero"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival <= 0")))
|
||||
|
||||
(define_constraint "Cca"
|
||||
"@internal
|
||||
Conditional or three-address add / sub constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == -1 << 31
|
||||
|| (ival >= -0x1f8 && ival <= 0x1f8
|
||||
&& ((ival >= 0 ? ival : -ival)
|
||||
<= 0x3f * (ival & -ival)))")))
|
||||
|
||||
; intersection of "O" and "Cca".
|
||||
(define_constraint "CL2"
|
||||
"@internal
|
||||
A 6-bit unsigned integer constant times 2"
|
||||
(and (match_code "const_int")
|
||||
(match_test "!(ival & ~126)")))
|
||||
|
||||
(define_constraint "CM4"
|
||||
"@internal
|
||||
A 5-bit unsigned integer constant times 4"
|
||||
(and (match_code "const_int")
|
||||
(match_test "!(ival & ~124)")))
|
||||
|
||||
(define_constraint "Csp"
|
||||
"@internal
|
||||
A valid stack pointer offset for a short add"
|
||||
(and (match_code "const_int")
|
||||
(match_test "!(ival & ~124) || !(-ival & ~124)")))
|
||||
|
||||
(define_constraint "C2a"
|
||||
"@internal
|
||||
Unconditional two-address add / sub constant"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == -1 << 31
|
||||
|| (ival >= -0x4000 && ival <= 0x4000
|
||||
&& ((ival >= 0 ? ival : -ival)
|
||||
<= 0x7ff * (ival & -ival)))")))
|
||||
|
||||
(define_constraint "C0p"
|
||||
"@internal
|
||||
power of two"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IS_POWEROF2_P (ival)")))
|
||||
|
||||
(define_constraint "C1p"
|
||||
"@internal
|
||||
constant such that x+1 is a power of two, and x != 0"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival && IS_POWEROF2_P (ival + 1)")))
|
||||
|
||||
(define_constraint "Ccp"
|
||||
"@internal
|
||||
constant such that ~x (one's Complement) is a power of two"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IS_POWEROF2_P (~ival)")))
|
||||
|
||||
(define_constraint "Cux"
|
||||
"@internal
|
||||
constant such that AND gives an unsigned extension"
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 0xff || ival == 0xffff")))
|
||||
|
||||
(define_constraint "Crr"
|
||||
"@internal
|
||||
constant that can be loaded with ror b,u6"
|
||||
(and (match_code "const_int")
|
||||
(match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()")))
|
||||
|
||||
;; Floating-point constraints
|
||||
|
||||
(define_constraint "G"
|
||||
"@internal
|
||||
A 32-bit constant double value"
|
||||
(and (match_code "const_double")
|
||||
(match_test "arc_double_limm_p (op)")))
|
||||
|
||||
(define_constraint "H"
|
||||
"@internal
|
||||
All const_double values (including 64-bit values)"
|
||||
(and (match_code "const_double")
|
||||
(match_test "1")))
|
||||
|
||||
;; Memory constraints
|
||||
(define_memory_constraint "T"
|
||||
"@internal
|
||||
A valid memory operand for ARCompact load instructions"
|
||||
(and (match_code "mem")
|
||||
(match_test "compact_load_memory_operand (op, VOIDmode)")))
|
||||
|
||||
(define_memory_constraint "S"
|
||||
"@internal
|
||||
A valid memory operand for ARCompact store instructions"
|
||||
(and (match_code "mem")
|
||||
(match_test "compact_store_memory_operand (op, VOIDmode)")))
|
||||
|
||||
(define_memory_constraint "Usd"
|
||||
"@internal
|
||||
A valid _small-data_ memory operand for ARCompact instructions"
|
||||
(and (match_code "mem")
|
||||
(match_test "compact_sda_memory_operand (op, VOIDmode)")))
|
||||
|
||||
(define_memory_constraint "Usc"
|
||||
"@internal
|
||||
A valid memory operand for storing constants"
|
||||
(and (match_code "mem")
|
||||
(match_test "!CONSTANT_P (XEXP (op,0))")
|
||||
;; ??? the assembler rejects stores of immediates to small data.
|
||||
(match_test "!compact_sda_memory_operand (op, VOIDmode)")))
|
||||
|
||||
(define_memory_constraint "Us<"
|
||||
"@internal
|
||||
Stack pre-decrement"
|
||||
(and (match_code "mem")
|
||||
(match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")
|
||||
(match_test "REG_P (XEXP (XEXP (op, 0), 0))")
|
||||
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
|
||||
|
||||
(define_memory_constraint "Us>"
|
||||
"@internal
|
||||
Stack post-increment"
|
||||
(and (match_code "mem")
|
||||
(match_test "GET_CODE (XEXP (op, 0)) == POST_INC")
|
||||
(match_test "REG_P (XEXP (XEXP (op, 0), 0))")
|
||||
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
|
||||
|
||||
;; General constraints
|
||||
|
||||
(define_constraint "Cbr"
|
||||
"Branch destination"
|
||||
(ior (and (match_code "symbol_ref")
|
||||
(match_test "!arc_is_longcall_p (op)"))
|
||||
(match_code "label_ref")))
|
||||
|
||||
(define_constraint "Cbp"
|
||||
"predicable branch/call destination"
|
||||
(ior (and (match_code "symbol_ref")
|
||||
(match_test "arc_is_shortcall_p (op)"))
|
||||
(match_code "label_ref")))
|
||||
|
||||
(define_constraint "Cpc"
|
||||
"pc-relative constant"
|
||||
(match_test "arc_legitimate_pc_offset_p (op)"))
|
||||
|
||||
(define_constraint "Clb"
|
||||
"label"
|
||||
(and (match_code "label_ref")
|
||||
(match_test "arc_text_label (XEXP (op, 0))")))
|
||||
|
||||
(define_constraint "Cal"
|
||||
"constant for arithmetic/logical operations"
|
||||
(match_test "immediate_operand (op, VOIDmode) && !arc_legitimate_pc_offset_p (op)"))
|
||||
|
||||
(define_constraint "C32"
|
||||
"32 bit constant for arithmetic/logical operations"
|
||||
(match_test "immediate_operand (op, VOIDmode)
|
||||
&& !arc_legitimate_pc_offset_p (op)
|
||||
&& !satisfies_constraint_I (op)"))
|
||||
|
||||
; Note that the 'cryptic' register constraints will not make reload use the
|
||||
; associated class to reload into, but this will not penalize reloading of any
|
||||
; other operands, or using an alternate part of the same alternative.
|
||||
|
||||
; Rcq is different in three important ways from a register class constraint:
|
||||
; - It does not imply a register class, hence reload will not use it to drive
|
||||
; reloads.
|
||||
; - It matches even when there is no register class to describe its accepted
|
||||
; set; not having such a set again lessens the impact on register allocation.
|
||||
; - It won't match when the instruction is conditionalized by the ccfsm.
|
||||
(define_constraint "Rcq"
|
||||
"@internal
|
||||
Cryptic q - for short insn generation while not affecting register allocation
|
||||
Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
|
||||
@code{r12}-@code{r15}"
|
||||
(and (match_code "REG")
|
||||
(match_test "TARGET_Rcq
|
||||
&& !arc_ccfsm_cond_exec_p ()
|
||||
&& ((((REGNO (op) & 7) ^ 4) - 4) & 15) == REGNO (op)")))
|
||||
|
||||
; If we need a reload, we generally want to steer reload to use three-address
|
||||
; alternatives in preference of two-address alternatives, unless the
|
||||
; three-address alternative introduces a LIMM that is unnecessary for the
|
||||
; two-address alternative.
|
||||
(define_constraint "Rcw"
|
||||
"@internal
|
||||
Cryptic w - for use in early alternatives with matching constraint"
|
||||
(and (match_code "REG")
|
||||
(match_test
|
||||
"TARGET_Rcw
|
||||
&& REGNO (op) < FIRST_PSEUDO_REGISTER
|
||||
&& TEST_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS],
|
||||
REGNO (op))")))
|
||||
|
||||
(define_constraint "Rcr"
|
||||
"@internal
|
||||
Cryptic r - for use in early alternatives with matching constraint"
|
||||
(and (match_code "REG")
|
||||
(match_test
|
||||
"TARGET_Rcw
|
||||
&& REGNO (op) < FIRST_PSEUDO_REGISTER
|
||||
&& TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
|
||||
REGNO (op))")))
|
||||
|
||||
(define_constraint "Rcb"
|
||||
"@internal
|
||||
Stack Pointer register @code{r28} - do not reload into its class"
|
||||
(and (match_code "REG")
|
||||
(match_test "REGNO (op) == 28")))
|
||||
|
||||
(define_constraint "Rck"
|
||||
"@internal
|
||||
blink (usful for push_s / pop_s)"
|
||||
(and (match_code "REG")
|
||||
(match_test "REGNO (op) == 31")))
|
||||
|
||||
(define_constraint "Rs5"
|
||||
"@internal
|
||||
sibcall register - only allow one of the five available 16 bit isnsn.
|
||||
Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
|
||||
@code{r12}"
|
||||
(and (match_code "REG")
|
||||
(match_test "!arc_ccfsm_cond_exec_p ()")
|
||||
(ior (match_test "(unsigned) REGNO (op) <= 3")
|
||||
(match_test "REGNO (op) == 12"))))
|
||||
|
||||
(define_constraint "Rcc"
|
||||
"@internal
|
||||
Condition Codes"
|
||||
(and (match_code "REG") (match_test "cc_register (op, VOIDmode)")))
|
||||
|
||||
|
||||
(define_constraint "Q"
|
||||
"@internal
|
||||
Integer constant zero"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IS_ZERO (ival)")))
|
|
@ -0,0 +1,674 @@
|
|||
;; Machine description of the Synopsys DesignWare ARC cpu Floating Point
|
||||
;; extensions for GNU C compiler
|
||||
;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GCC.
|
||||
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; TODOs:
|
||||
;; dpfp blocks?
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Scheduler descriptions for the fpx instructions
|
||||
(define_insn_reservation "spfp_compact" 3
|
||||
(and (match_test "TARGET_SPFP_COMPACT_SET")
|
||||
(eq_attr "type" "spfp"))
|
||||
"issue+core, nothing*2, write_port")
|
||||
|
||||
(define_insn_reservation "spfp_fast" 6
|
||||
(and (match_test "TARGET_SPFP_FAST_SET")
|
||||
(eq_attr "type" "spfp"))
|
||||
"issue+core, nothing*5, write_port")
|
||||
|
||||
(define_insn_reservation "dpfp_compact_mult" 7
|
||||
(and (match_test "TARGET_DPFP_COMPACT_SET")
|
||||
(eq_attr "type" "dpfp_mult"))
|
||||
"issue+core, nothing*6, write_port")
|
||||
|
||||
(define_insn_reservation "dpfp_compact_addsub" 5
|
||||
(and (match_test "TARGET_DPFP_COMPACT_SET")
|
||||
(eq_attr "type" "dpfp_addsub"))
|
||||
"issue+core, nothing*4, write_port")
|
||||
|
||||
(define_insn_reservation "dpfp_fast" 5
|
||||
(and (match_test "TARGET_DPFP_FAST_SET")
|
||||
(eq_attr "type" "dpfp_mult,dpfp_addsub"))
|
||||
"issue+core, nothing*4, write_port")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define_insn "addsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
|
||||
(plus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,GCal,r,0")
|
||||
(match_operand:SF 2 "nonmemory_operand" "I,rL,r,GCal,LrCal")))]
|
||||
; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float
|
||||
"TARGET_SPFP"
|
||||
"@
|
||||
fadd %0,%1,%2
|
||||
fadd %0,%1,%2
|
||||
fadd %0,%S1,%2
|
||||
fadd %0,%1,%S2
|
||||
fadd%? %0,%1,%S2"
|
||||
[(set_attr "type" "spfp")
|
||||
(set_attr "length" "4,4,8,8,8")])
|
||||
|
||||
(define_insn "subsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
|
||||
(minus:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0")
|
||||
(match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))]
|
||||
;"(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float
|
||||
"TARGET_SPFP"
|
||||
"@
|
||||
fsub %0,%1,%2
|
||||
fsub %0,%1,%2
|
||||
fsub %0,%S1,%2
|
||||
fsub %0,%1,%S2
|
||||
fsub%? %0,%1,%S2"
|
||||
[(set_attr "type" "spfp")
|
||||
(set_attr "length" "4,4,8,8,8")])
|
||||
|
||||
(define_insn "mulsf3"
|
||||
[(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
|
||||
(mult:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0")
|
||||
(match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))]
|
||||
; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET" ;Add flag for float
|
||||
"TARGET_SPFP"
|
||||
"@
|
||||
fmul %0,%1,%2
|
||||
fmul %0,%1,%2
|
||||
fmul %0,%S1,%2
|
||||
fmul %0,%1,%S2
|
||||
fmul%? %0,%1,%S2"
|
||||
[(set_attr "type" "spfp")
|
||||
(set_attr "length" "4,4,8,8,8")])
|
||||
|
||||
|
||||
;; For comparisons, we can avoid storing the top half of the result into
|
||||
;; a register since '.f' lets us set the Z bit for the conditional
|
||||
;; branch insns.
|
||||
|
||||
;; ??? FIXME (x-y)==0 is not a correct comparison for floats:
|
||||
;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
|
||||
(define_insn "cmpsfpx_raw"
|
||||
[(set (reg:CC_FPX 61)
|
||||
(compare:CC_FPX (match_operand:SF 0 "register_operand" "r")
|
||||
(match_operand:SF 1 "register_operand" "r")))]
|
||||
"TARGET_ARGONAUT_SET && TARGET_SPFP"
|
||||
"fsub.f 0,%0,%1"
|
||||
[(set_attr "type" "spfp")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; ??? FIXME (x-y)==0 is not a correct comparison for floats:
|
||||
;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
|
||||
;; ??? FIXME we claim to clobber operand 2, yet the two numbers appended
|
||||
;; to the actual instructions are incorrect. The result of the d*subh
|
||||
;; insn is stored in the Dx register specified by that first number.
|
||||
(define_insn "cmpdfpx_raw"
|
||||
[(set (reg:CC_FPX 61)
|
||||
(compare:CC_FPX (match_operand:DF 0 "nonmemory_operand" "D,r")
|
||||
(match_operand:DF 1 "nonmemory_operand" "r,D")))
|
||||
(clobber (match_scratch:DF 2 "=D,D"))]
|
||||
"TARGET_ARGONAUT_SET && TARGET_DPFP"
|
||||
"@
|
||||
dsubh%F0%F1.f 0,%H2,%L2
|
||||
drsubh%F0%F2.f 0,%H1,%L1"
|
||||
[(set_attr "type" "dpfp_addsub")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; ??? FIXME subtraction is not a correct comparison for floats:
|
||||
;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
|
||||
(define_insn "*cmpfpx_gt"
|
||||
[(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:CC_FPX 61) (const_int 0)))]
|
||||
"TARGET_ARGONAUT_SET"
|
||||
"cmp.ls pcl,pcl"
|
||||
[(set_attr "type" "compare")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; ??? FIXME subtraction is not a correct comparison for floats:
|
||||
;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
|
||||
(define_insn "*cmpfpx_ge"
|
||||
[(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:CC_FPX 61) (const_int 0)))]
|
||||
"TARGET_ARGONAUT_SET"
|
||||
"rcmp.pnz pcl,0"
|
||||
[(set_attr "type" "compare")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; DPFP instructions begin...
|
||||
|
||||
;; op0_reg = D1_reg.low
|
||||
(define_insn "*lr_double_lower"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_LR ))]
|
||||
"TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
|
||||
"lr %0, [%1l] ; *lr_double_lower"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "lr")]
|
||||
)
|
||||
|
||||
(define_insn "*lr_double_higher"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_LR_HIGH ))]
|
||||
"TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
|
||||
"lr %0, [%1h] ; *lr_double_higher"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "lr")]
|
||||
)
|
||||
|
||||
|
||||
(define_insn "*dexcl_3op_peep2_insn"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=r") ; not register_operand, to accept SUBREG
|
||||
(unspec_volatile:SI [
|
||||
(match_operand:DF 1 "arc_double_register_operand" "D")
|
||||
(match_operand:SI 2 "shouldbe_register_operand" "r") ; r1
|
||||
(match_operand:SI 3 "shouldbe_register_operand" "r") ; r0
|
||||
] VUNSPEC_DEXCL ))
|
||||
]
|
||||
"TARGET_DPFP"
|
||||
"dexcl%F1 %0, %2, %3"
|
||||
[(set_attr "type" "move")
|
||||
(set_attr "length" "4")]
|
||||
)
|
||||
|
||||
;; version which will not overwrite operand0
|
||||
(define_insn "*dexcl_3op_peep2_insn_nores"
|
||||
[ (unspec_volatile:SI [
|
||||
(match_operand:DF 0 "arc_double_register_operand" "D")
|
||||
(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1
|
||||
(match_operand:SI 2 "shouldbe_register_operand" "r") ; r0
|
||||
] VUNSPEC_DEXCL_NORES )
|
||||
]
|
||||
"TARGET_DPFP"
|
||||
"dexcl%F0 0, %1, %2"
|
||||
[(set_attr "type" "move")
|
||||
(set_attr "length" "4")]
|
||||
)
|
||||
|
||||
;; dexcl a,b,c pattern generated by the peephole2 above
|
||||
(define_insn "*dexcl_3op_peep2_insn_lr"
|
||||
[(parallel [(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "=D")] VUNSPEC_LR ))
|
||||
(set (match_dup 1) (match_operand:DF 2 "register_operand" "r"))]
|
||||
)
|
||||
]
|
||||
"TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
|
||||
"dexcl%F1 %0, %H2, %L2"
|
||||
[(set_attr "type" "move")
|
||||
(set_attr "length" "4")]
|
||||
)
|
||||
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; doubles support for ARC
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; D0 = D1+{reg_pair}2
|
||||
;; (define_expand "adddf3"
|
||||
;; [(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "")
|
||||
;; (match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
;; "TARGET_DPFP"
|
||||
;; " "
|
||||
;; )
|
||||
;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
|
||||
;; OR
|
||||
;; daddh{0}{1} 0, reg3, limm2.lo
|
||||
(define_expand "adddf3"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
(plus:DF (match_operand:DF 1 "arc_double_register_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))
|
||||
]
|
||||
"TARGET_DPFP"
|
||||
" if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
split_double (operands[2], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
|
||||
DONE;
|
||||
"
|
||||
)
|
||||
|
||||
;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
|
||||
;; OR
|
||||
;; daddh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0 */
|
||||
;;
|
||||
(define_insn "adddf3_insn"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
|
||||
(plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
|
||||
(match_operand:DF 2 "nonmemory_operand" "!r,G")))
|
||||
(use (match_operand:SI 3 "" "N,r"))
|
||||
(use (match_operand:SI 4 "" "N,Q"))
|
||||
; Prevent can_combine_p from combining muldf3_insn patterns with
|
||||
; different USE pairs.
|
||||
(use (match_dup 2))
|
||||
]
|
||||
"TARGET_DPFP &&
|
||||
!(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
|
||||
"@
|
||||
daddh%F0%F1 0,%H2,%L2
|
||||
daddh%F0%F1 0,%3,%L2"
|
||||
[(set_attr "type" "dpfp_addsub")
|
||||
(set_attr "length" "4,8")])
|
||||
|
||||
;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
|
||||
;; OR
|
||||
;; dmulh{0}{1} 0, reg3, limm2.lo
|
||||
(define_expand "muldf3"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
(mult:DF (match_operand:DF 1 "arc_double_register_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_DPFP"
|
||||
" if (GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
split_double (operands[2], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
|
||||
|
||||
DONE;
|
||||
")
|
||||
|
||||
|
||||
;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
|
||||
;; OR
|
||||
;; dmulh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
|
||||
(define_insn "muldf3_insn"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
|
||||
(mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
|
||||
(match_operand:DF 2 "nonmemory_operand" "!r,G")))
|
||||
(use (match_operand:SI 3 "" "N,!r"))
|
||||
(use (match_operand:SI 4 "" "N,Q"))
|
||||
; Prevent can_combine_p from combining muldf3_insn patterns with
|
||||
; different USE pairs.
|
||||
(use (match_dup 2))
|
||||
]
|
||||
"TARGET_DPFP &&
|
||||
!(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
|
||||
"@
|
||||
dmulh%F0%F1 0,%H2,%L2
|
||||
dmulh%F0%F1 0,%3, %L2"
|
||||
[(set_attr "type" "dpfp_mult")
|
||||
(set_attr "length" "4,8")])
|
||||
|
||||
;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
|
||||
;; OR
|
||||
;; dsubh{0}{1} 0, reg3, limm2.lo
|
||||
;; OR
|
||||
;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo
|
||||
;; OR
|
||||
;; drsubh{0}{2} 0, reg3, limm1.lo
|
||||
(define_expand "subdf3"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "")
|
||||
(minus:DF (match_operand:DF 1 "nonmemory_operand" "")
|
||||
(match_operand:DF 2 "nonmemory_operand" "")))]
|
||||
"TARGET_DPFP"
|
||||
" if (GET_CODE (operands[1]) == CONST_DOUBLE || GET_CODE (operands[2]) == CONST_DOUBLE)
|
||||
{
|
||||
rtx high, low, tmp;
|
||||
int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1: 2);
|
||||
split_double (operands[const_index], &low, &high);
|
||||
tmp = force_reg (SImode, high);
|
||||
emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
|
||||
|
||||
DONE;
|
||||
"
|
||||
)
|
||||
|
||||
;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */
|
||||
;; OR
|
||||
;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
|
||||
;; OR
|
||||
;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo /* operand 4 = 1 */
|
||||
;; OR
|
||||
;; drsubh{0}{2} 0, reg3, limm1.lo /* operand 4 = 0*/
|
||||
(define_insn "subdf3_insn"
|
||||
[(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D")
|
||||
(minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,!r,G")
|
||||
(match_operand:DF 2 "nonmemory_operand" "!r,G,D,D")))
|
||||
(use (match_operand:SI 3 "" "N,r,N,r"))
|
||||
(use (match_operand:SI 4 "" "N,Q,N,Q"))
|
||||
; Prevent can_combine_p from combining muldf3_insn patterns with
|
||||
; different USE pairs.
|
||||
(use (match_dup 2))]
|
||||
"TARGET_DPFP &&
|
||||
!(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) &&
|
||||
!(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
|
||||
"@
|
||||
dsubh%F0%F1 0,%H2,%L2
|
||||
dsubh%F0%F1 0,%3,%L2
|
||||
drsubh%F0%F2 0,%H1,%L1
|
||||
drsubh%F0%F2 0,%3,%L1"
|
||||
[(set_attr "type" "dpfp_addsub")
|
||||
(set_attr "length" "4,8,4,8")])
|
||||
|
||||
;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;; Peephole for following conversion
|
||||
;; ;; D0 = D2<op>{reg_pair}3
|
||||
;; ;; {reg_pair}5 = D0
|
||||
;; ;; D0 = {reg_pair}6
|
||||
;; ;; |
|
||||
;; ;; V
|
||||
;; ;; _________________________________________________________
|
||||
;; ;; / D0 = D2 <op> {regpair3_or_limmreg34}
|
||||
;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
|
||||
;; ;; | \_________________________________________________________
|
||||
;; ;; |
|
||||
;; ;; | ________________________________________________________
|
||||
;; ;; | / {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
|
||||
;; ;; +-----+ D0 = {reg_pair}6
|
||||
;; ;; \ _________________________________________________________
|
||||
;; ;; ||
|
||||
;; ;; ||
|
||||
;; ;; \/
|
||||
;; ;; d<op>{0}{2}h {reg_pair}5.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
|
||||
;; ;; dexcl{0} {reg_pair}5.lo, {reg_pair}6.lo, {reg_pair}6.hi
|
||||
;; ;; -----------------------------------------------------------------------------------------
|
||||
;; ;; where <op> is one of {+,*,-}
|
||||
;; ;; <opname> is {add,mult,sub}
|
||||
;; ;;
|
||||
;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
|
||||
;; ;; {regpair2_or_limmreg24} and D3
|
||||
;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; (define_peephole2
|
||||
;; [(parallel [(set (match_operand:DF 0 "register_operand" "")
|
||||
;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
|
||||
;; (match_operand:DF 3 "nonmemory_operand" "")]))
|
||||
;; (use (match_operand:SI 4 "" ""))])
|
||||
;; (set (match_operand:DF 5 "register_operand" "")
|
||||
;; (match_dup 0))
|
||||
;; (set (match_dup 0)
|
||||
;; (match_operand:DF 6 "register_operand" ""))
|
||||
;; ]
|
||||
;; "TARGET_DPFP"
|
||||
;; [
|
||||
;; (parallel [(set (match_dup 0)
|
||||
;; (match_op_dup:DF 1 [(match_dup 2)
|
||||
;; (match_dup 3)]))
|
||||
;; (use (match_dup 4))
|
||||
;; (set (match_dup 5)
|
||||
;; (match_op_dup:DF 1 [(match_dup 2)
|
||||
;; (match_dup 3)]))])
|
||||
;; (parallel [
|
||||
;; ;; (set (subreg:SI (match_dup 5) 0)
|
||||
;; (set (match_dup 7)
|
||||
;; (unspec_volatile [(match_dup 0)] VUNSPEC_LR ))
|
||||
;; (set (match_dup 0) (match_dup 6))]
|
||||
;; )
|
||||
;; ]
|
||||
;; "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
|
||||
;; )
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Peephole for following conversion
|
||||
;; D0 = D2<op>{reg_pair}3
|
||||
;; {reg_pair}6 = D0
|
||||
;; D0 = {reg_pair}7
|
||||
;; |
|
||||
;; V
|
||||
;; _________________________________________________________
|
||||
;; / D0 = D2 <op> {regpair3_or_limmreg34}
|
||||
;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
|
||||
;; | \_________________________________________________________
|
||||
;; |
|
||||
;; | ________________________________________________________
|
||||
;; | / {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
|
||||
;; +-----+ D0 = {reg_pair}7
|
||||
;; \ _________________________________________________________
|
||||
;; ||
|
||||
;; ||
|
||||
;; \/
|
||||
;; d<op>{0}{2}h {reg_pair}6.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
|
||||
;; dexcl{0} {reg_pair}6.lo, {reg_pair}7.lo, {reg_pair}7.hi
|
||||
;; -----------------------------------------------------------------------------------------
|
||||
;; where <op> is one of {+,*,-}
|
||||
;; <opname> is {add,mult,sub}
|
||||
;;
|
||||
;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
|
||||
;; {regpair2_or_limmreg24} and D3
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(define_peephole2
|
||||
[(parallel [(set (match_operand:DF 0 "register_operand" "")
|
||||
(match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
|
||||
(match_operand:DF 3 "nonmemory_operand" "")]))
|
||||
(use (match_operand:SI 4 "" ""))
|
||||
(use (match_operand:SI 5 "" ""))
|
||||
(use (match_operand:SI 6 "" ""))])
|
||||
(set (match_operand:DF 7 "register_operand" "")
|
||||
(match_dup 0))
|
||||
(set (match_dup 0)
|
||||
(match_operand:DF 8 "register_operand" ""))
|
||||
]
|
||||
"TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
|
||||
[
|
||||
(parallel [(set (match_dup 0)
|
||||
(match_op_dup:DF 1 [(match_dup 2)
|
||||
(match_dup 3)]))
|
||||
(use (match_dup 4))
|
||||
(use (match_dup 5))
|
||||
(set (match_dup 7)
|
||||
(match_op_dup:DF 1 [(match_dup 2)
|
||||
(match_dup 3)]))])
|
||||
(parallel [
|
||||
;; (set (subreg:SI (match_dup 7) 0)
|
||||
(set (match_dup 9)
|
||||
(unspec_volatile:SI [(match_dup 0)] VUNSPEC_LR ))
|
||||
(set (match_dup 0) (match_dup 8))]
|
||||
)
|
||||
]
|
||||
"operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
|
||||
)
|
||||
|
||||
;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;; Peephole to generate d<opname>{ij}h a,b,c instructions
|
||||
;; ;; D0 = D2<op>{reg_pair}3
|
||||
;; ;; {reg_pair}5 = D0
|
||||
;; ;; |
|
||||
;; ;; V
|
||||
;; ;; __________________________________________
|
||||
;; ;; / D0 = D2 <op> {regpair3_or_limmreg34}
|
||||
;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
|
||||
;; ;; | \__________________________________________
|
||||
;; ;; |
|
||||
;; ;; + --- {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
|
||||
;; ;; ||
|
||||
;; ;; ||
|
||||
;; ;; \/
|
||||
;; ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
|
||||
;; ;; lr {reg_pair}4.lo, {D2l}
|
||||
;; ;; ----------------------------------------------------------------------------------------
|
||||
;; ;; where <op> is one of {+,*,-}
|
||||
;; ;; <opname> is {add,mult,sub}
|
||||
;; ;;
|
||||
;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
|
||||
;; ;; {regpair2_or_limmreg24} and D3
|
||||
;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; (define_peephole2
|
||||
;; [(parallel [(set (match_operand:DF 0 "register_operand" "")
|
||||
;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
|
||||
;; (match_operand:DF 3 "nonmemory_operand" "")]))
|
||||
;; (use (match_operand:SI 4 "" ""))])
|
||||
;; (set (match_operand:DF 5 "register_operand" "")
|
||||
;; (match_dup 0))
|
||||
;; ]
|
||||
;; "TARGET_DPFP"
|
||||
;; [
|
||||
;; (parallel [(set (match_dup 0)
|
||||
;; (match_op_dup:DF 1 [(match_dup 2)
|
||||
;; (match_dup 3)]))
|
||||
;; (use (match_dup 4))
|
||||
;; (set (match_dup 5)
|
||||
;; (match_op_dup:DF 1 [(match_dup 2)
|
||||
;; (match_dup 3)]))])
|
||||
;; ; (set (subreg:SI (match_dup 5) 0)
|
||||
;; (set (match_dup 6)
|
||||
;; (unspec_volatile [(match_dup 0)] VUNSPEC_LR ))
|
||||
;; ]
|
||||
;; "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
|
||||
;; )
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Peephole to generate d<opname>{ij}h a,b,c instructions
|
||||
;; D0 = D2<op>{reg_pair}3
|
||||
;; {reg_pair}6 = D0
|
||||
;; |
|
||||
;; V
|
||||
;; __________________________________________
|
||||
;; / D0 = D2 <op> {regpair3_or_limmreg34}
|
||||
;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
|
||||
;; | \__________________________________________
|
||||
;; |
|
||||
;; + --- {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
|
||||
;; ||
|
||||
;; ||
|
||||
;; \/
|
||||
;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
|
||||
;; lr {reg_pair}4.lo, {D2l}
|
||||
;; ----------------------------------------------------------------------------------------
|
||||
;; where <op> is one of {+,*,-}
|
||||
;; <opname> is {add,mult,sub}
|
||||
;;
|
||||
;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
|
||||
;; {regpair2_or_limmreg24} and D3
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(define_peephole2
|
||||
[(parallel [(set (match_operand:DF 0 "register_operand" "")
|
||||
(match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
|
||||
(match_operand:DF 3 "nonmemory_operand" "")]))
|
||||
(use (match_operand:SI 4 "" ""))
|
||||
(use (match_operand:SI 5 "" ""))
|
||||
(use (match_operand:SI 6 "" ""))])
|
||||
(set (match_operand:DF 7 "register_operand" "")
|
||||
(match_dup 0))
|
||||
]
|
||||
"TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
|
||||
[
|
||||
(parallel [(set (match_dup 0)
|
||||
(match_op_dup:DF 1 [(match_dup 2)
|
||||
(match_dup 3)]))
|
||||
(use (match_dup 4))
|
||||
(use (match_dup 5))
|
||||
(set (match_dup 7)
|
||||
(match_op_dup:DF 1 [(match_dup 2)
|
||||
(match_dup 3)]))])
|
||||
; (set (subreg:SI (match_dup 7) 0)
|
||||
(set (match_dup 8)
|
||||
(unspec_volatile:SI [(match_dup 0)] VUNSPEC_LR ))
|
||||
]
|
||||
"operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
|
||||
)
|
||||
|
||||
;; ;; _______________________________________________________
|
||||
;; ;; / D0 = D1 + {regpair2_or_limmreg23}
|
||||
;; ;; + {reg_pair}4.hi = ( D1 + {regpair2_or_limmreg23} ).hi
|
||||
;; ;; \_______________________________________________________
|
||||
;; (define_insn "*daddh_peep2_insn"
|
||||
;; [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
|
||||
;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
|
||||
;; (match_operand:DF 2 "nonmemory_operand" "r,G")))
|
||||
;; (use (match_operand:SI 3 "" "N,r"))
|
||||
;; (set (match_operand:DF 4 "register_operand" "=r,r")
|
||||
;; (plus:DF (match_dup 1)
|
||||
;; (match_dup 2)))])]
|
||||
;; "TARGET_DPFP"
|
||||
;; "@
|
||||
;; daddh%F0%F1 %H4, %H2, %L2
|
||||
;; daddh%F0%F1 %H4, %3, %L2"
|
||||
;; [(set_attr "type" "dpfp_addsub")
|
||||
;; (set_attr "length" "4,8")]
|
||||
;; )
|
||||
;; _______________________________________________________
|
||||
;; / D0 = D1 + {regpair2_or_limmreg23}
|
||||
;; + {reg_pair}5.hi = ( D1 + {regpair2_or_limmreg23} ).hi
|
||||
;; \_______________________________________________________
|
||||
(define_insn "*daddh_peep2_insn"
|
||||
[(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
|
||||
(plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
|
||||
(match_operand:DF 2 "nonmemory_operand" "r,G")))
|
||||
(use (match_operand:SI 3 "" "N,r"))
|
||||
(use (match_operand:SI 4 "" "N,Q"))
|
||||
(use (match_operand:SI 5 "" ""))
|
||||
(set (match_operand:DF 6 "register_operand" "=r,r")
|
||||
(plus:DF (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"TARGET_DPFP &&
|
||||
!(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
|
||||
"@
|
||||
daddh%F0%F1 %H6, %H2, %L2
|
||||
daddh%F0%F1 %H6, %3, %L2"
|
||||
[(set_attr "type" "dpfp_addsub")
|
||||
(set_attr "length" "4,8")]
|
||||
)
|
||||
|
||||
;; _______________________________________________________
|
||||
;; / D0 = D1 * {regpair2_or_limmreg23}
|
||||
;; + {reg_pair}5.hi = ( D1 * {regpair2_or_limmreg23} ).hi
|
||||
;; \_______________________________________________________
|
||||
(define_insn "*dmulh_peep2_insn"
|
||||
[(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
|
||||
(mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
|
||||
(match_operand:DF 2 "nonmemory_operand" "r,G")))
|
||||
(use (match_operand:SI 3 "" "N,r"))
|
||||
(use (match_operand:SI 4 "" "N,Q"))
|
||||
(use (match_operand:SI 5 "" ""))
|
||||
(set (match_operand:DF 6 "register_operand" "=r,r")
|
||||
(mult:DF (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"TARGET_DPFP &&
|
||||
!(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
|
||||
"@
|
||||
dmulh%F0%F1 %H6, %H2, %L2
|
||||
dmulh%F0%F1 %H6, %3, %L2"
|
||||
[(set_attr "type" "dpfp_mult")
|
||||
(set_attr "length" "4,8")]
|
||||
)
|
||||
|
||||
;; _______________________________________________________
|
||||
;; / D0 = D1 - {regpair2_or_limmreg23}
|
||||
;; + {reg_pair}5.hi = ( D1 - {regpair2_or_limmreg23} ).hi
|
||||
;; \_______________________________________________________
|
||||
;; OR
|
||||
;; _______________________________________________________
|
||||
;; / D0 = {regpair1_or_limmreg13} - D2
|
||||
;; + {reg_pair}5.hi = ( {regpair1_or_limmreg13} ).hi - D2
|
||||
;; \_______________________________________________________
|
||||
(define_insn "*dsubh_peep2_insn"
|
||||
[(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D")
|
||||
(minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,r,G")
|
||||
(match_operand:DF 2 "nonmemory_operand" "r,G,D,D")))
|
||||
(use (match_operand:SI 3 "" "N,r,N,r"))
|
||||
(use (match_operand:SI 4 "" "N,Q,N,Q"))
|
||||
(use (match_operand:SI 5 "" ""))
|
||||
(set (match_operand:DF 6 "register_operand" "=r,r,r,r")
|
||||
(minus:DF (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"TARGET_DPFP &&
|
||||
!(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) &&
|
||||
!(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
|
||||
"@
|
||||
dsubh%F0%F1 %H6, %H2, %L2
|
||||
dsubh%F0%F1 %H6, %3, %L2
|
||||
drsubh%F0%F2 %H6, %H1, %L1
|
||||
drsubh%F0%F2 %H6, %3, %L1"
|
||||
[(set_attr "type" "dpfp_addsub")
|
||||
(set_attr "length" "4,8,4,8")]
|
||||
)
|
|
@ -0,0 +1,807 @@
|
|||
;; Predicate definitions for Synopsys DesignWare ARC.
|
||||
;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define_predicate "dest_reg_operand"
|
||||
(match_code "reg,subreg")
|
||||
{
|
||||
rtx op0 = op;
|
||||
|
||||
if (GET_CODE (op0) == SUBREG)
|
||||
op0 = SUBREG_REG (op0);
|
||||
if (REG_P (op0) && REGNO (op0) < FIRST_PSEUDO_REGISTER
|
||||
&& TEST_HARD_REG_BIT (reg_class_contents[ALL_CORE_REGS],
|
||||
REGNO (op0))
|
||||
&& !TEST_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS],
|
||||
REGNO (op0)))
|
||||
return 0;
|
||||
return register_operand (op, mode);
|
||||
})
|
||||
|
||||
(define_predicate "mpy_dest_reg_operand"
|
||||
(match_code "reg,subreg")
|
||||
{
|
||||
rtx op0 = op;
|
||||
|
||||
if (GET_CODE (op0) == SUBREG)
|
||||
op0 = SUBREG_REG (op0);
|
||||
if (REG_P (op0) && REGNO (op0) < FIRST_PSEUDO_REGISTER
|
||||
&& TEST_HARD_REG_BIT (reg_class_contents[ALL_CORE_REGS],
|
||||
REGNO (op0))
|
||||
/* Make sure the destination register is not LP_COUNT. */
|
||||
&& !TEST_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS],
|
||||
REGNO (op0)))
|
||||
return 0;
|
||||
return register_operand (op, mode);
|
||||
})
|
||||
|
||||
|
||||
;; Returns 1 if OP is a symbol reference.
|
||||
(define_predicate "symbolic_operand"
|
||||
(match_code "symbol_ref, label_ref, const")
|
||||
)
|
||||
|
||||
;; Acceptable arguments to the call insn.
|
||||
(define_predicate "call_address_operand"
|
||||
(ior (match_code "const_int, reg")
|
||||
(match_operand 0 "symbolic_operand")
|
||||
(match_test "CONSTANT_P (op)
|
||||
&& arc_legitimate_constant_p (VOIDmode, op)"))
|
||||
)
|
||||
|
||||
(define_predicate "call_operand"
|
||||
(and (match_code "mem")
|
||||
(match_test "call_address_operand (XEXP (op, 0), mode)"))
|
||||
)
|
||||
|
||||
;; Return true if OP is a unsigned 6-bit immediate (u6) value.
|
||||
(define_predicate "u6_immediate_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "UNSIGNED_INT6 (INTVAL (op))"))
|
||||
)
|
||||
|
||||
;; Return true if OP is a short immediate (shimm) value.
|
||||
(define_predicate "short_immediate_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "SMALL_INT (INTVAL (op))"))
|
||||
)
|
||||
|
||||
(define_predicate "p2_immediate_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "((INTVAL (op) - 1) & INTVAL (op)) == 0")
|
||||
(match_test "INTVAL (op)"))
|
||||
)
|
||||
|
||||
;; Return true if OP will require a long immediate (limm) value.
|
||||
;; This is currently only used when calculating length attributes.
|
||||
(define_predicate "long_immediate_operand"
|
||||
(match_code "symbol_ref, label_ref, const, const_double, const_int")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case SYMBOL_REF :
|
||||
case LABEL_REF :
|
||||
case CONST :
|
||||
return 1;
|
||||
case CONST_INT :
|
||||
return !SIGNED_INT12 (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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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. */
|
||||
(define_predicate "long_immediate_loadstore_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
int size = GET_MODE_SIZE (GET_MODE (op));
|
||||
|
||||
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 :
|
||||
{
|
||||
rtx x = XEXP (op, 1);
|
||||
|
||||
if (GET_CODE (x) == CONST)
|
||||
{
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) == PLUS)
|
||||
x = XEXP (x, 0);
|
||||
}
|
||||
if (CONST_INT_P (x))
|
||||
return (!SMALL_INT (INTVAL (x))
|
||||
&& (size <= 1 || size > 4
|
||||
|| (INTVAL (x) & (size - 1)) != 0
|
||||
|| !SMALL_INT (INTVAL (x) / size)));
|
||||
else if (GET_CODE (x) == SYMBOL_REF)
|
||||
return TARGET_NO_SDATA_SET || !SYMBOL_REF_SMALL_P (x);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
|
||||
;; Return true if OP is any of R0-R3,R12-R15 for ARCompact 16-bit
|
||||
;; instructions
|
||||
(define_predicate "compact_register_operand"
|
||||
(match_code "reg, subreg")
|
||||
{
|
||||
if ((GET_MODE (op) != mode) && (mode != VOIDmode))
|
||||
return 0;
|
||||
|
||||
return (GET_CODE (op) == REG)
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| COMPACT_GP_REG_P (REGNO (op))) ;
|
||||
}
|
||||
)
|
||||
|
||||
;; Return true if OP is an acceptable memory operand for ARCompact
|
||||
;; 16-bit load instructions.
|
||||
(define_predicate "compact_load_memory_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
rtx addr, plus0, plus1;
|
||||
int size, off;
|
||||
|
||||
/* Eliminate non-memory operations. */
|
||||
if (GET_CODE (op) != MEM)
|
||||
return 0;
|
||||
|
||||
/* .di instructions have no 16-bit form. */
|
||||
if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
|
||||
return 0;
|
||||
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op);
|
||||
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
/* dword operations really put out 2 instructions, so eliminate them. */
|
||||
if (size > UNITS_PER_WORD)
|
||||
return 0;
|
||||
|
||||
/* Decode the address now. */
|
||||
addr = XEXP (op, 0);
|
||||
switch (GET_CODE (addr))
|
||||
{
|
||||
case REG:
|
||||
return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
|
||||
|| COMPACT_GP_REG_P (REGNO (addr))
|
||||
|| (SP_REG_P (REGNO (addr)) && (size != 2)));
|
||||
/* Reverting for the moment since ldw_s does not have sp as a valid
|
||||
parameter. */
|
||||
case PLUS:
|
||||
plus0 = XEXP (addr, 0);
|
||||
plus1 = XEXP (addr, 1);
|
||||
|
||||
if ((GET_CODE (plus0) == REG)
|
||||
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|
||||
|| COMPACT_GP_REG_P (REGNO (plus0)))
|
||||
&& ((GET_CODE (plus1) == REG)
|
||||
&& ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
|
||||
|| COMPACT_GP_REG_P (REGNO (plus1)))))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((GET_CODE (plus0) == REG)
|
||||
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|
||||
|| COMPACT_GP_REG_P (REGNO (plus0)))
|
||||
&& (GET_CODE (plus1) == CONST_INT))
|
||||
{
|
||||
off = INTVAL (plus1);
|
||||
|
||||
/* Negative offset is not supported in 16-bit load/store insns. */
|
||||
if (off < 0)
|
||||
return 0;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
return (off < 32);
|
||||
case 2:
|
||||
return ((off < 64) && (off % 2 == 0));
|
||||
case 4:
|
||||
return ((off < 128) && (off % 4 == 0));
|
||||
}
|
||||
}
|
||||
|
||||
if ((GET_CODE (plus0) == REG)
|
||||
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|
||||
|| SP_REG_P (REGNO (plus0)))
|
||||
&& (GET_CODE (plus1) == CONST_INT))
|
||||
{
|
||||
off = INTVAL (plus1);
|
||||
return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
|
||||
}
|
||||
default:
|
||||
break ;
|
||||
/* TODO: 'gp' and 'pcl' are to supported as base address operand
|
||||
for 16-bit load instructions. */
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
;; Return true if OP is an acceptable memory operand for ARCompact
|
||||
;; 16-bit store instructions
|
||||
(define_predicate "compact_store_memory_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
rtx addr, plus0, plus1;
|
||||
int size, off;
|
||||
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op);
|
||||
|
||||
/* .di instructions have no 16-bit form. */
|
||||
if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
|
||||
return 0;
|
||||
|
||||
size = GET_MODE_SIZE (mode);
|
||||
|
||||
/* dword operations really put out 2 instructions, so eliminate them. */
|
||||
if (size > UNITS_PER_WORD)
|
||||
return 0;
|
||||
|
||||
/* Decode the address now. */
|
||||
addr = XEXP (op, 0);
|
||||
switch (GET_CODE (addr))
|
||||
{
|
||||
case REG:
|
||||
return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
|
||||
|| COMPACT_GP_REG_P (REGNO (addr))
|
||||
|| (SP_REG_P (REGNO (addr)) && (size != 2)));
|
||||
/* stw_s does not support SP as a parameter. */
|
||||
case PLUS:
|
||||
plus0 = XEXP (addr, 0);
|
||||
plus1 = XEXP (addr, 1);
|
||||
|
||||
if ((GET_CODE (plus0) == REG)
|
||||
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|
||||
|| COMPACT_GP_REG_P (REGNO (plus0)))
|
||||
&& (GET_CODE (plus1) == CONST_INT))
|
||||
{
|
||||
off = INTVAL (plus1);
|
||||
|
||||
/* Negative offset is not supported in 16-bit load/store insns. */
|
||||
if (off < 0)
|
||||
return 0;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
return (off < 32);
|
||||
case 2:
|
||||
return ((off < 64) && (off % 2 == 0));
|
||||
case 4:
|
||||
return ((off < 128) && (off % 4 == 0));
|
||||
}
|
||||
}
|
||||
|
||||
if ((GET_CODE (plus0) == REG)
|
||||
&& ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
|
||||
|| SP_REG_P (REGNO (plus0)))
|
||||
&& (GET_CODE (plus1) == CONST_INT))
|
||||
{
|
||||
off = INTVAL (plus1);
|
||||
|
||||
return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
|
||||
;; Return true if OP is an acceptable argument for a single word
|
||||
;; move source.
|
||||
(define_predicate "move_src_operand"
|
||||
(match_code "symbol_ref, label_ref, const, const_int, const_double, reg, subreg, mem")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case SYMBOL_REF :
|
||||
case LABEL_REF :
|
||||
case CONST :
|
||||
return (!flag_pic || arc_legitimate_pic_operand_p(op));
|
||||
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.
|
||||
(define_predicate "move_double_src_operand"
|
||||
(match_code "reg, subreg, mem, const_int, const_double")
|
||||
{
|
||||
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 :
|
||||
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.
|
||||
(define_predicate "move_dest_operand"
|
||||
(match_code "reg, subreg, mem")
|
||||
{
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case REG :
|
||||
/* Program Counter register cannot be the target of a move. It is
|
||||
a readonly register. */
|
||||
if (REGNO (op) == PROGRAM_COUNTER_REGNO)
|
||||
return 0;
|
||||
else if (TARGET_MULMAC_32BY16_SET
|
||||
&& (REGNO (op) == 56 || REGNO(op) == 57))
|
||||
return 0;
|
||||
else if (TARGET_MUL64_SET
|
||||
&& (REGNO (op) == 57 || REGNO(op) == 58 || REGNO(op) == 59 ))
|
||||
return 0;
|
||||
else
|
||||
return dest_reg_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 dest_reg_operand (op, mode);
|
||||
case MEM :
|
||||
{
|
||||
rtx addr = XEXP (op, 0);
|
||||
|
||||
if (GET_CODE (addr) == PLUS
|
||||
&& (GET_CODE (XEXP (addr, 0)) == MULT
|
||||
|| (!CONST_INT_P (XEXP (addr, 1))
|
||||
&& (TARGET_NO_SDATA_SET
|
||||
|| GET_CODE (XEXP (addr, 1)) != SYMBOL_REF
|
||||
|| !SYMBOL_REF_SMALL_P (XEXP (addr, 1))))))
|
||||
return 0;
|
||||
if ((GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
|
||||
&& (GET_CODE (XEXP (addr, 1)) != PLUS
|
||||
|| !CONST_INT_P (XEXP (XEXP (addr, 1), 1))))
|
||||
return 0;
|
||||
return address_operand (addr, mode);
|
||||
}
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
;; Return true if OP is valid load with update operand.
|
||||
(define_predicate "load_update_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
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.
|
||||
(define_predicate "store_update_operand"
|
||||
(match_code "mem")
|
||||
{
|
||||
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.
|
||||
(define_predicate "nonvol_nonimm_operand"
|
||||
(and (match_code "subreg, reg, mem")
|
||||
(match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)"))
|
||||
)
|
||||
|
||||
;; 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.
|
||||
|
||||
(define_predicate "proper_comparison_operator"
|
||||
(match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt")
|
||||
{
|
||||
enum rtx_code code = GET_CODE (op);
|
||||
|
||||
if (!COMPARISON_P (op))
|
||||
return 0;
|
||||
|
||||
/* After generic flag-setting insns, we can use eq / ne / pl / mi / pnz .
|
||||
There are some creative uses for hi / ls after shifts, but these are
|
||||
hard to understand for the compiler and could be at best the target of
|
||||
a peephole. */
|
||||
switch (GET_MODE (XEXP (op, 0)))
|
||||
{
|
||||
case CC_ZNmode:
|
||||
return (code == EQ || code == NE || code == GE || code == LT
|
||||
|| code == GT);
|
||||
case CC_Zmode:
|
||||
return code == EQ || code == NE;
|
||||
case CC_Cmode:
|
||||
return code == LTU || code == GEU;
|
||||
case CC_FP_GTmode:
|
||||
return code == GT || code == UNLE;
|
||||
case CC_FP_GEmode:
|
||||
return code == GE || code == UNLT;
|
||||
case CC_FP_ORDmode:
|
||||
return code == ORDERED || code == UNORDERED;
|
||||
case CC_FP_UNEQmode:
|
||||
return code == UNEQ || code == LTGT;
|
||||
case CC_FPXmode:
|
||||
return (code == EQ || code == NE || code == UNEQ || code == LTGT
|
||||
|| code == ORDERED || code == UNORDERED);
|
||||
|
||||
case CCmode:
|
||||
case SImode: /* Used for BRcc. */
|
||||
return 1;
|
||||
/* From combiner. */
|
||||
case QImode: case HImode: case DImode: case SFmode: case DFmode:
|
||||
return 0;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
})
|
||||
|
||||
(define_predicate "equality_comparison_operator"
|
||||
(match_code "eq, ne"))
|
||||
|
||||
(define_predicate "brcc_nolimm_operator"
|
||||
(ior (match_test "REG_P (XEXP (op, 1))")
|
||||
(and (match_code "eq, ne, lt, ge, ltu, geu")
|
||||
(match_test "u6_immediate_operand (XEXP (op, 1), SImode)"))
|
||||
(and (match_code "le, gt, leu, gtu")
|
||||
(match_test "UNSIGNED_INT6 (INTVAL (XEXP (op, 1)) + 1)"))))
|
||||
|
||||
;; Return TRUE if this is the condition code register, if we aren't given
|
||||
;; a mode, accept any CCmode register
|
||||
(define_special_predicate "cc_register"
|
||||
(match_code "reg")
|
||||
{
|
||||
if (mode == VOIDmode)
|
||||
{
|
||||
mode = GET_MODE (op);
|
||||
if (GET_MODE_CLASS (mode) != MODE_CC)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mode == GET_MODE (op) && GET_CODE (op) == REG && REGNO (op) == CC_REG)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
})
|
||||
|
||||
;; Return TRUE if this is the condition code register; if we aren't given
|
||||
;; a mode, accept any CCmode register. If we are given a mode, accept
|
||||
;; modes that set a subset of flags.
|
||||
(define_special_predicate "cc_set_register"
|
||||
(match_code "reg")
|
||||
{
|
||||
enum machine_mode rmode = GET_MODE (op);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
{
|
||||
mode = rmode;
|
||||
if (GET_MODE_CLASS (mode) != MODE_CC)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (REGNO (op) != 61)
|
||||
return FALSE;
|
||||
if (mode == rmode
|
||||
|| (mode == CC_ZNmode && rmode == CC_Zmode)
|
||||
|| (mode == CCmode && rmode == CC_Zmode)
|
||||
|| (mode == CCmode && rmode == CC_ZNmode)
|
||||
|| (mode == CCmode && rmode == CC_Cmode))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
})
|
||||
|
||||
; Accept CC_REG in modes which provide the flags needed for MODE. */
|
||||
(define_special_predicate "cc_use_register"
|
||||
(match_code "reg")
|
||||
{
|
||||
if (REGNO (op) != CC_REG)
|
||||
return 0;
|
||||
if (GET_MODE (op) == mode)
|
||||
return 1;
|
||||
switch (mode)
|
||||
{
|
||||
case CC_Zmode:
|
||||
if (GET_MODE (op) == CC_ZNmode)
|
||||
return 1;
|
||||
/* Fall through. */
|
||||
case CC_ZNmode: case CC_Cmode:
|
||||
return GET_MODE (op) == CCmode;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
})
|
||||
|
||||
(define_special_predicate "zn_compare_operator"
|
||||
(match_code "compare")
|
||||
{
|
||||
return GET_MODE (op) == CC_ZNmode || GET_MODE (op) == CC_Zmode;
|
||||
})
|
||||
|
||||
;; Return true if OP is a shift operator.
|
||||
(define_predicate "shift_operator"
|
||||
(match_code "ashiftrt, lshiftrt, ashift")
|
||||
)
|
||||
|
||||
;; Return true if OP is a left shift operator that can be implemented in
|
||||
;; four insn words or less without a barrel shifter or multiplier.
|
||||
(define_predicate "shiftl4_operator"
|
||||
(and (match_code "ashift")
|
||||
(match_test "const_int_operand (XEXP (op, 1), VOIDmode) ")
|
||||
(match_test "UINTVAL (XEXP (op, 1)) <= 9U
|
||||
|| INTVAL (XEXP (op, 1)) == 29
|
||||
|| INTVAL (XEXP (op, 1)) == 30
|
||||
|| INTVAL (XEXP (op, 1)) == 31")))
|
||||
|
||||
;; Return true if OP is a right shift operator that can be implemented in
|
||||
;; four insn words or less without a barrel shifter or multiplier.
|
||||
(define_predicate "shiftr4_operator"
|
||||
(and (match_code "ashiftrt, lshiftrt")
|
||||
(match_test "const_int_operand (XEXP (op, 1), VOIDmode) ")
|
||||
(match_test "UINTVAL (XEXP (op, 1)) <= 4U
|
||||
|| INTVAL (XEXP (op, 1)) == 30
|
||||
|| INTVAL (XEXP (op, 1)) == 31")))
|
||||
|
||||
;; Return true if OP is a shift operator that can be implemented in
|
||||
;; four insn words or less without a barrel shifter or multiplier.
|
||||
(define_predicate "shift4_operator"
|
||||
(ior (match_operand 0 "shiftl4_operator")
|
||||
(match_operand 0 "shiftr4_operator")))
|
||||
|
||||
(define_predicate "mult_operator"
|
||||
(and (match_code "mult") (match_test "TARGET_ARC700 && !TARGET_NOMPY_SET"))
|
||||
)
|
||||
|
||||
(define_predicate "commutative_operator"
|
||||
(ior (match_code "plus,ior,xor,and")
|
||||
(match_operand 0 "mult_operator")
|
||||
(and (match_code "ss_plus")
|
||||
(match_test "TARGET_ARC700 || TARGET_EA_SET")))
|
||||
)
|
||||
|
||||
(define_predicate "commutative_operator_sans_mult"
|
||||
(ior (match_code "plus,ior,xor,and")
|
||||
(and (match_code "ss_plus")
|
||||
(match_test "TARGET_ARC700 || TARGET_EA_SET")))
|
||||
)
|
||||
|
||||
(define_predicate "noncommutative_operator"
|
||||
(ior (match_code "minus,ashift,ashiftrt,lshiftrt,rotatert")
|
||||
(and (match_code "ss_minus")
|
||||
(match_test "TARGET_ARC700 || TARGET_EA_SET")))
|
||||
)
|
||||
|
||||
(define_predicate "unary_operator"
|
||||
(ior (match_code "abs,neg,not,sign_extend,zero_extend")
|
||||
(and (ior (match_code "ss_neg")
|
||||
(and (match_code "ss_truncate")
|
||||
(match_test "GET_MODE (XEXP (op, 0)) == HImode")))
|
||||
(match_test "TARGET_ARC700 || TARGET_EA_SET")))
|
||||
)
|
||||
|
||||
(define_predicate "_2_4_8_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8"))
|
||||
)
|
||||
|
||||
(define_predicate "arc_double_register_operand"
|
||||
(match_code "reg")
|
||||
{
|
||||
if ((GET_MODE (op) != mode) && (mode != VOIDmode))
|
||||
return 0;
|
||||
|
||||
return (GET_CODE (op) == REG
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| REGNO_REG_CLASS (REGNO (op)) == DOUBLE_REGS));
|
||||
})
|
||||
|
||||
(define_predicate "shouldbe_register_operand"
|
||||
(match_code "reg,subreg,mem")
|
||||
{
|
||||
return ((reload_in_progress || reload_completed)
|
||||
? general_operand : register_operand) (op, mode);
|
||||
})
|
||||
|
||||
(define_predicate "vector_register_operand"
|
||||
(match_code "reg")
|
||||
{
|
||||
if ((GET_MODE (op) != mode) && (mode != VOIDmode))
|
||||
return 0;
|
||||
|
||||
return (GET_CODE (op) == REG
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| REGNO_REG_CLASS (REGNO (op)) == SIMD_VR_REGS));
|
||||
})
|
||||
|
||||
(define_predicate "vector_register_or_memory_operand"
|
||||
( ior (match_code "reg")
|
||||
(match_code "mem"))
|
||||
{
|
||||
if ((GET_MODE (op) != mode) && (mode != VOIDmode))
|
||||
return 0;
|
||||
|
||||
if ((GET_CODE (op) == MEM)
|
||||
&& (mode == V8HImode)
|
||||
&& GET_CODE (XEXP (op,0)) == REG)
|
||||
return 1;
|
||||
|
||||
return (GET_CODE (op) == REG
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| REGNO_REG_CLASS (REGNO (op)) == SIMD_VR_REGS));
|
||||
})
|
||||
|
||||
(define_predicate "arc_dpfp_operator"
|
||||
(match_code "plus, mult,minus")
|
||||
)
|
||||
|
||||
(define_predicate "arc_simd_dma_register_operand"
|
||||
(match_code "reg")
|
||||
{
|
||||
if ((GET_MODE (op) != mode) && (mode != VOIDmode))
|
||||
return 0;
|
||||
|
||||
return (GET_CODE (op) == REG
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| REGNO_REG_CLASS (REGNO (op)) == SIMD_DMA_CONFIG_REGS));
|
||||
})
|
||||
|
||||
(define_predicate "acc1_operand"
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 56 : 57)")))
|
||||
|
||||
(define_predicate "acc2_operand"
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 57 : 56)")))
|
||||
|
||||
(define_predicate "mlo_operand"
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 59 : 58)")))
|
||||
|
||||
(define_predicate "mhi_operand"
|
||||
(and (match_code "reg")
|
||||
(match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 58 : 59)")))
|
||||
|
||||
(define_predicate "extend_operand"
|
||||
(ior (match_test "register_operand (op, mode)")
|
||||
(and (match_test "immediate_operand (op, mode)")
|
||||
(not (match_test "const_int_operand (op, mode)")))))
|
||||
|
||||
(define_predicate "millicode_store_operation"
|
||||
(match_code "parallel")
|
||||
{
|
||||
return arc_check_millicode (op, 0, 0);
|
||||
})
|
||||
|
||||
(define_predicate "millicode_load_operation"
|
||||
(match_code "parallel")
|
||||
{
|
||||
return arc_check_millicode (op, 2, 2);
|
||||
})
|
||||
|
||||
(define_predicate "millicode_load_clob_operation"
|
||||
(match_code "parallel")
|
||||
{
|
||||
return arc_check_millicode (op, 0, 1);
|
||||
})
|
||||
|
||||
(define_special_predicate "immediate_usidi_operand"
|
||||
(if_then_else
|
||||
(match_code "const_int")
|
||||
(match_test "INTVAL (op) >= 0")
|
||||
(and (match_test "const_double_operand (op, mode)")
|
||||
(match_test "CONST_DOUBLE_HIGH (op) == 0"))))
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
|
||||
|
||||
# Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GCC.
|
||||
|
||||
# GCC is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Selecting -mA5 uses the same functional multilib files/libraries
|
||||
# as get used for -mARC600 aka -mA6.
|
||||
MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601 mmul64/mmul32x16 mnorm
|
||||
MULTILIB_DIRNAMES=arc600 arc601 mul64 mul32x16 norm
|
||||
#
|
||||
# Aliases:
|
||||
MULTILIB_MATCHES = mcpu?ARC600=mcpu?arc600
|
||||
MULTILIB_MATCHES += mcpu?ARC600=mARC600
|
||||
MULTILIB_MATCHES += mcpu?ARC600=mA6
|
||||
MULTILIB_MATCHES += mcpu?ARC600=mA5
|
||||
MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
|
||||
MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
|
||||
MULTILIB_MATCHES += EL=mlittle-endian
|
||||
MULTILIB_MATCHES += EB=mbig-endian
|
||||
#
|
||||
# These don't make sense for the ARC700 default target:
|
||||
MULTILIB_EXCEPTIONS=mmul64* mmul32x16* mnorm*
|
||||
# And neither of the -mmul* options make sense without -mnorm:
|
||||
MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
|
|
@ -0,0 +1,20 @@
|
|||
# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
|
||||
|
||||
# Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GCC.
|
||||
|
||||
# GCC is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
MULTILIB_EXTRA_OPTS = mno-sdata
|
Loading…
Reference in New Issue