⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frv.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.   Contributed by Red Hat, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include "config.h"#include "system.h"#include "rtl.h"#include "tree.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-flags.h"#include "output.h"#include "insn-attr.h"#include "flags.h"#include "recog.h"#include "reload.h"#include "expr.h"#include "obstack.h"#include "except.h"#include "function.h"#include "optabs.h"#include "toplev.h"#include "basic-block.h"#include "tm_p.h"#include "ggc.h"#include <ctype.h>#include "target.h"#include "target-def.h"#ifndef FRV_INLINE#define FRV_INLINE inline#endif/* Temporary register allocation support structure.  */typedef struct frv_tmp_reg_struct  {    HARD_REG_SET regs;		/* possible registers to allocate */    int next_reg[N_REG_CLASSES];	/* next register to allocate per class */  }frv_tmp_reg_t;/* Register state information for VLIW re-packing phase.  These values must fit   within an unsigned char.  */#define REGSTATE_DEAD		0x00	/* register is currently dead */#define REGSTATE_CC_MASK	0x07	/* Mask to isolate CCn for cond exec */#define REGSTATE_LIVE		0x08	/* register is live */#define REGSTATE_MODIFIED	0x10	/* reg modified in current VLIW insn */#define REGSTATE_IF_TRUE	0x20	/* reg modified in cond exec true */#define REGSTATE_IF_FALSE	0x40	/* reg modified in cond exec false */#define REGSTATE_UNUSED		0x80	/* bit for hire */#define REGSTATE_MASK		0xff	/* mask for the bits to set */					/* conditional expression used */#define REGSTATE_IF_EITHER	(REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)/* the following is not sure in the reg_state bytes, so can have a larger value   than 0xff.  */#define REGSTATE_CONDJUMP	0x100	/* conditional jump done in VLIW insn *//* Used in frv_frame_accessor_t to indicate the direction of a register-to-   memory move.  */enum frv_stack_op{  FRV_LOAD,  FRV_STORE};/* Information required by frv_frame_access.  */typedef struct{  /* This field is FRV_LOAD if registers are to be loaded from the stack and     FRV_STORE if they should be stored onto the stack.  FRV_STORE implies     the move is being done by the prologue code while FRV_LOAD implies it     is being done by the epilogue.  */  enum frv_stack_op op;  /* The base register to use when accessing the stack.  This may be the     frame pointer, stack pointer, or a temporary.  The choice of register     depends on which part of the frame is being accessed and how big the     frame is.  */  rtx base;  /* The offset of BASE from the bottom of the current frame, in bytes.  */  int base_offset;} frv_frame_accessor_t;/* Define the information needed to generate branch and scc insns.  This is   stored from the compare operation.  */rtx frv_compare_op0;rtx frv_compare_op1;/* Conditional execution support gathered together in one structure */typedef struct  {    /* Linked list of insns to add if the conditional execution conversion was       successful.  Each link points to an EXPR_LIST which points to the pattern       of the insn to add, and the insn to be inserted before.  */    rtx added_insns_list;    /* Identify which registers are safe to allocate for if conversions to       conditional execution.  We keep the last allocated register in the       register classes between COND_EXEC statements.  This will mean we allocate       different registers for each different COND_EXEC group if we can.  This       might allow the scheduler to intermix two different COND_EXEC sections.  */    frv_tmp_reg_t tmp_reg;    /* For nested IFs, identify which CC registers are used outside of setting       via a compare isnsn, and using via a check insn.  This will allow us to       know if we can rewrite the register to use a different register that will       be paired with the CR register controlling the nested IF-THEN blocks.  */    HARD_REG_SET nested_cc_ok_rewrite;    /* Temporary registers allocated to hold constants during conditional       execution.  */    rtx scratch_regs[FIRST_PSEUDO_REGISTER];    /* Current number of temp registers available.  */    int cur_scratch_regs;    /* Number of nested conditional execution blocks */    int num_nested_cond_exec;    /* Map of insns that set up constants in scratch registers.  */    bitmap scratch_insns_bitmap;    /* Conditional execution test register (CC0..CC7) */    rtx cr_reg;    /* Conditional execution compare register that is paired with cr_reg, so that       nested compares can be done.  The csubcc and caddcc instructions don't       have enough bits to specify both a CC register to be set and a CR register       to do the test on, so the same bit number is used for both.  Needless to       say, this is rather inconvient for GCC.  */    rtx nested_cc_reg;    /* Extra CR registers used for &&, ||.  */    rtx extra_int_cr;    rtx extra_fp_cr;    /* Previous CR used in nested if, to make sure we are dealing with the same       nested if as the previous statement. */    rtx last_nested_if_cr;  }frv_ifcvt_t;static /* GTY(()) */ frv_ifcvt_t frv_ifcvt;/* Map register number to smallest register class.  */enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];/* Map class letter into register class */enum reg_class reg_class_from_letter[256];/* Cached value of frv_stack_info */static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;/* -mbranch-cost= support */const char *frv_branch_cost_string;int frv_branch_cost_int = DEFAULT_BRANCH_COST;/* -mcpu= support */const char *frv_cpu_string;		/* -mcpu= option */frv_cpu_t frv_cpu_type = CPU_TYPE;	/* value of -mcpu= *//* -mcond-exec-insns= support */const char *frv_condexec_insns_str;		 /* -mcond-exec-insns= option */int frv_condexec_insns = DEFAULT_CONDEXEC_INSNS; /* value of -mcond-exec-insns*//* -mcond-exec-temps= support */const char *frv_condexec_temps_str;		 /* -mcond-exec-temps= option */int frv_condexec_temps = DEFAULT_CONDEXEC_TEMPS; /* value of -mcond-exec-temps*//* -msched-lookahead=n */const char *frv_sched_lookahead_str;	 /* -msched-lookahead=n */int frv_sched_lookahead = 4;		 /* -msched-lookahead=n *//* Forward references */static int frv_default_flags_for_cpu		PARAMS ((void));static int frv_string_begins_with		PARAMS ((tree, const char *));static FRV_INLINE int symbol_ref_small_data_p	PARAMS ((rtx));static FRV_INLINE int const_small_data_p	PARAMS ((rtx));static FRV_INLINE int plus_small_data_p		PARAMS ((rtx, rtx));static void frv_print_operand_memory_reference_reg						PARAMS ((FILE *, rtx));static void frv_print_operand_memory_reference	PARAMS ((FILE *, rtx, int));static int frv_print_operand_jump_hint		PARAMS ((rtx));static FRV_INLINE int frv_regno_ok_for_base_p	PARAMS ((int, int));static rtx single_set_pattern			PARAMS ((rtx));static int frv_function_contains_far_jump	PARAMS ((void));static rtx frv_alloc_temp_reg			PARAMS ((frv_tmp_reg_t *,							 enum reg_class,							 enum machine_mode,							 int, int));static rtx frv_frame_offset_rtx			PARAMS ((int));static rtx frv_frame_mem			PARAMS ((enum machine_mode,							 rtx, int));static rtx frv_dwarf_store			PARAMS ((rtx, int));static void frv_frame_insn			PARAMS ((rtx, rtx));static void frv_frame_access			PARAMS ((frv_frame_accessor_t*,							 rtx, int));static void frv_frame_access_multi		PARAMS ((frv_frame_accessor_t*,							 frv_stack_t *, int));static void frv_frame_access_standard_regs	PARAMS ((enum frv_stack_op,							 frv_stack_t *));static struct machine_function *frv_init_machine_status		PARAMS ((void));static int frv_legitimate_memory_operand	PARAMS ((rtx,							 enum machine_mode,							 int));static rtx frv_int_to_acc			PARAMS ((enum insn_code,							 int, rtx));static enum machine_mode frv_matching_accg_mode	PARAMS ((enum machine_mode));static rtx frv_read_argument			PARAMS ((tree *));static int frv_check_constant_argument		PARAMS ((enum insn_code,							 int, rtx));static rtx frv_legitimize_target		PARAMS ((enum insn_code, rtx));static rtx frv_legitimize_argument		PARAMS ((enum insn_code,							 int, rtx));static rtx frv_expand_set_builtin		PARAMS ((enum insn_code,							 tree, rtx));static rtx frv_expand_unop_builtin		PARAMS ((enum insn_code,							 tree, rtx));static rtx frv_expand_binop_builtin		PARAMS ((enum insn_code,							 tree, rtx));static rtx frv_expand_cut_builtin		PARAMS ((enum insn_code,							 tree, rtx));static rtx frv_expand_binopimm_builtin		PARAMS ((enum insn_code,							 tree, rtx));static rtx frv_expand_voidbinop_builtin		PARAMS ((enum insn_code,							 tree));static rtx frv_expand_voidtriop_builtin		PARAMS ((enum insn_code,							 tree));static rtx frv_expand_voidaccop_builtin		PARAMS ((enum insn_code,							 tree));static rtx frv_expand_mclracc_builtin		PARAMS ((tree));static rtx frv_expand_mrdacc_builtin		PARAMS ((enum insn_code,							 tree));static rtx frv_expand_mwtacc_builtin		PARAMS ((enum insn_code,							 tree));static rtx frv_expand_noargs_builtin		PARAMS ((enum insn_code));static rtx frv_emit_comparison			PARAMS ((enum rtx_code, rtx,							 rtx));static int frv_clear_registers_used		PARAMS ((rtx *, void *));static void frv_ifcvt_add_insn			PARAMS ((rtx, rtx, int));static rtx frv_ifcvt_rewrite_mem		PARAMS ((rtx,							 enum machine_mode,							 rtx));static rtx frv_ifcvt_load_value			PARAMS ((rtx, rtx));static void frv_registers_update		PARAMS  ((rtx, unsigned char [],							 int [], int *, int));static int frv_registers_used_p			PARAMS ((rtx, unsigned char [],							 int));static int frv_registers_set_p			PARAMS ((rtx, unsigned char [],							 int));static void frv_pack_insns			PARAMS ((void));static void frv_function_prologue		PARAMS ((FILE *, HOST_WIDE_INT));static void frv_function_epilogue		PARAMS ((FILE *, HOST_WIDE_INT));static bool frv_assemble_integer		PARAMS ((rtx, unsigned, int));static const char * frv_strip_name_encoding	PARAMS ((const char *));static void frv_encode_section_info		PARAMS ((tree, int));static void frv_init_builtins			PARAMS ((void));static rtx frv_expand_builtin			PARAMS ((tree, rtx, rtx, enum machine_mode, int));static bool frv_in_small_data_p			PARAMS ((tree));static void frv_asm_output_mi_thunk  PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));/* Initialize the GCC target structure.  */#undef  TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE frv_function_prologue#undef  TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue#undef  TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER frv_assemble_integer#undef  TARGET_STRIP_NAME_ENCODING#define TARGET_STRIP_NAME_ENCODING frv_strip_name_encoding#undef  TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO frv_encode_section_info#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS frv_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN frv_expand_builtin#undef TARGET_IN_SMALL_DATA_P#define TARGET_IN_SMALL_DATA_P frv_in_small_data_p#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcallstruct gcc_target targetm = TARGET_INITIALIZER;/* Given a SYMBOL_REF, return true if it points to small data.  */static FRV_INLINE intsymbol_ref_small_data_p (x)     rtx x;{  return SDATA_NAME_P (XSTR (x, 0));}/* Given a CONST, return true if the symbol_ref points to small data.  */static FRV_INLINE intconst_small_data_p (x)     rtx x;{  rtx x0, x1;  if (GET_CODE (XEXP (x, 0)) != PLUS)    return FALSE;  x0 = XEXP (XEXP (x, 0), 0);  if (GET_CODE (x0) != SYMBOL_REF || !SDATA_NAME_P (XSTR (x0, 0)))    return FALSE;  x1 = XEXP (XEXP (x, 0), 1);  if (GET_CODE (x1) != CONST_INT      || !IN_RANGE_P (INTVAL (x1), -2048, 2047))    return FALSE;  return TRUE;}/* Given a PLUS, return true if this is a small data reference.  */static FRV_INLINE intplus_small_data_p (op0, op1)     rtx op0;     rtx op1;{  if (GET_MODE (op0) == SImode      && GET_CODE (op0) == REG      && REGNO (op0) == SDA_BASE_REG)    {      if (GET_CODE (op1) == SYMBOL_REF)	return symbol_ref_small_data_p (op1);      if (GET_CODE (op1) == CONST)	return const_small_data_p (op1);    }  return FALSE;}static intfrv_default_flags_for_cpu (){  switch (frv_cpu_type)    {    case FRV_CPU_GENERIC:      return MASK_DEFAULT_FRV;    case FRV_CPU_FR500:    case FRV_CPU_TOMCAT:      return MASK_DEFAULT_FR500;    case FRV_CPU_FR400:      return MASK_DEFAULT_FR400;    case FRV_CPU_FR300:    case FRV_CPU_SIMPLE:      return MASK_DEFAULT_SIMPLE;    }  abort ();}/* Sometimes certain combinations of command options do not make

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -