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

📄 cris.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Definitions for GCC.  Part of the machine description for CRIS.   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005   Free Software Foundation, Inc.   Contributed by Axis Communications.  Written by Hans-Peter Nilsson.This file is part of GCC.GCC is free software; you can redistribute it and/or 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.GCC 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 GCC; 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 "coretypes.h"#include "tm.h"#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-attr.h"#include "flags.h"#include "tree.h"#include "expr.h"#include "except.h"#include "function.h"#include "toplev.h"#include "recog.h"#include "tm_p.h"#include "debug.h"#include "output.h"#include "target.h"#include "target-def.h"#include "ggc.h"#include "optabs.h"/* Usable when we have an amount to add or subtract, and want the   optimal size of the insn.  */#define ADDITIVE_SIZE_MODIFIER(size) \ ((size) <= 63 ? "q" : (size) <= 255 ? "u.b" : (size) <= 65535 ? "u.w" : ".d")#define ASSERT_PLT_UNSPEC(x)					\  do								\    {								\      if (XEXP (x, 1) != NULL_RTX				\	  || (GET_CODE (XVECEXP (x, 0, 0)) != SYMBOL_REF	\	      && GET_CODE (XVECEXP (x, 0, 0)) != LABEL_REF))	\	abort ();						\    } while (0)#define LOSE_AND_RETURN(msgid, x)			\  do						\    {						\      cris_operand_lossage (msgid, x);		\      return;					\    } while (0)/* Per-function machine data.  */struct machine_function GTY(()) {   int needs_return_address_on_stack; };/* This little fix suppresses the 'u' or 's' when '%e' in assembly   pattern.  */static char cris_output_insn_is_bound = 0;/* This one suppresses printing out the "rPIC+" in   "rPIC+sym:GOTOFF+offset" when doing PIC.  For a PLT symbol, it   suppresses outputting it as [rPIC+sym:GOTPLT] and outputs similarly   just the "sym:GOTOFF" part.  */static int cris_pic_sympart_only = 0;/* In code for output macros, this is how we know whether e.g. constant   goes in code or in a static initializer.  */static int in_code = 0;/* Fix for reg_overlap_mentioned_p.  */static int cris_reg_overlap_mentioned_p (rtx, rtx);static void cris_print_base (rtx, FILE *);static void cris_print_index (rtx, FILE *);static void cris_output_addr_const (FILE *, rtx);static struct machine_function * cris_init_machine_status (void);static rtx cris_struct_value_rtx (tree, int);static void cris_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,					 tree type, int *, int);static int cris_initial_frame_pointer_offset (void);static int saved_regs_mentioned (rtx);static void cris_target_asm_function_prologue (FILE *, HOST_WIDE_INT);static void cris_target_asm_function_epilogue (FILE *, HOST_WIDE_INT);static void cris_operand_lossage (const char *, rtx);static void cris_asm_output_mi_thunk  (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);static void cris_file_start (void);static void cris_init_libfuncs (void);static bool cris_rtx_costs (rtx, int, int, int *);static int cris_address_cost (rtx);static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,				    tree, bool);static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,				   tree, bool);/* The function cris_target_asm_function_epilogue puts the last insn to   output here.  It always fits; there won't be a symbol operand.  Used in   delay_slots_for_epilogue and function_epilogue.  */static char save_last[80];/* This is the argument from the "-max-stack-stackframe=" option.  */const char *cris_max_stackframe_str;/* This is the argument from the "-march=" option.  */const char *cris_cpu_str;/* This is the argument from the "-mtune=" option.  */const char *cris_tune_str;/* This is the argument from the "-melinux-stacksize=" option.  */const char *cris_elinux_stacksize_str;/* This is the parsed result of the "-max-stack-stackframe=" option.  If   it (still) is zero, then there was no such option given.  */int cris_max_stackframe = 0;/* This is the parsed result of the "-march=" option, if given.  */int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP "\t.dword\t"#undef TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"/* We need to define these, since the 2byte, 4byte, 8byte op:s are only   available in ELF.  These "normal" pseudos do not have any alignment   constraints or side-effects.  */#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP#undef TARGET_ASM_UNALIGNED_DI_OP#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE cris_target_asm_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE cris_target_asm_function_epilogue#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK cris_asm_output_mi_thunk#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall#undef TARGET_ASM_FILE_START#define TARGET_ASM_FILE_START cris_file_start#undef TARGET_INIT_LIBFUNCS#define TARGET_INIT_LIBFUNCS cris_init_libfuncs#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS cris_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST cris_address_cost#undef TARGET_PROMOTE_FUNCTION_ARGS#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true#undef TARGET_STRUCT_VALUE_RTX#define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx#undef TARGET_SETUP_INCOMING_VARARGS#define TARGET_SETUP_INCOMING_VARARGS cris_setup_incoming_varargs#undef TARGET_PASS_BY_REFERENCE#define TARGET_PASS_BY_REFERENCE cris_pass_by_reference#undef TARGET_ARG_PARTIAL_BYTES#define TARGET_ARG_PARTIAL_BYTES cris_arg_partial_bytesstruct gcc_target targetm = TARGET_INITIALIZER;/* Predicate functions.  *//* This checks a part of an address, the one that is not a plain register   for an addressing mode using BDAP.   Allowed operands is either:   a) a register   b) a CONST operand (but not a symbol when generating PIC)   c) a [r] or [r+] in SImode, or sign-extend from HI or QI.  */intcris_bdap_operand (rtx op, enum machine_mode mode){  register enum rtx_code code = GET_CODE (op);  if (mode != SImode && (mode != VOIDmode || GET_MODE (op) != VOIDmode))    return 0;  /* Just return whether this is a simple register or constant.  */  if (register_operand (op, mode)      || (CONSTANT_P (op) && !(flag_pic && cris_symbol (op))))    return 1;  /* Is it a [r] or possibly a [r+]?  */  if (code == MEM)    {      rtx tem = XEXP (op, 0);      if (mode == SImode	  && (register_operand (tem, SImode)	      || (GET_CODE (tem) == POST_INC		  && register_operand (XEXP (tem, 0), SImode))))	return 1;      else	return 0;    }  /* Perhaps a sign-extended mem: [r].(b|w) or [r+].(b|w)?  */  if (code == SIGN_EXTEND)    {      rtx tem = XEXP (op, 0);      if (GET_CODE (tem) != MEM)	return 0;      tem = XEXP (tem, 0);      if (mode == SImode	  && (register_operand (tem, SImode)	      || (GET_CODE (tem) == POST_INC		  && register_operand (XEXP (tem, 0), SImode))))	return 1;      else	return 0;    }  return 0;}/* This is similar to cris_bdap_operand:   It checks a part of an address, the one that is not a plain register   for an addressing mode using BDAP *or* BIAP.   Allowed operands is either:   a) a register   b) a CONST operand (but not a symbol when generating PIC)   c) a mult of (1, 2 or 4) and a register   d) a [r] or [r+] in SImode, or sign-extend from HI or QI.  */intcris_bdap_biap_operand (rtx op, enum machine_mode mode){  register enum rtx_code code = GET_CODE (op);  rtx reg;  rtx val;  /* Check for bdap operand.  */  if (cris_bdap_operand (op, mode))    return 1;  if (mode != SImode && (mode != VOIDmode || GET_MODE (op) != VOIDmode))    return 0;  /* Check that we're looking at a BIAP operand.  */  if (code != MULT)    return 0;  /* Canonicalize register and multiplicand.  */  if (GET_CODE (XEXP (op, 0)) == CONST_INT)    {      val = XEXP (op, 0);      reg = XEXP (op, 1);    }  else    {      val = XEXP (op, 1);      reg = XEXP (op, 0);    }  /* Check that the operands are correct after canonicalization.  */  if (! register_operand (reg, SImode) || GET_CODE (val) != CONST_INT)    return 0;  /* Check that the multiplicand has a valid value.  */  if ((code == MULT       && (INTVAL (val) == 1 || INTVAL (val) == 2 || INTVAL (val) == 4)))    return 1;  return 0;}/* Check if MODE is same as mode for X, and X is PLUS, MINUS, IOR or   AND or UMIN.  */intcris_orthogonal_operator (rtx x, enum machine_mode mode){  enum rtx_code code = GET_CODE (x);  if (mode == VOIDmode)    mode = GET_MODE (x);  return (GET_MODE (x) == mode	  && (code == PLUS || code == MINUS	      || code == IOR || code == AND || code == UMIN));}/* Check if MODE is same as mode for X, and X is PLUS, IOR or AND or   UMIN.  */intcris_commutative_orth_op (rtx x, enum machine_mode mode){  enum rtx_code code = GET_CODE (x);  if (mode == VOIDmode)    mode = GET_MODE (x);  return (GET_MODE (x) == mode &&	  (code == PLUS	   || code == IOR || code == AND || code == UMIN));}/* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN.   By the name, you might think we should include MULT.  We don't because   it doesn't accept the same addressing modes as the others (ony   registers) and there's also the problem of handling TARGET_MUL_BUG.  */intcris_operand_extend_operator (rtx x, enum machine_mode mode){  enum rtx_code code = GET_CODE (x);  if (mode == VOIDmode)    mode = GET_MODE (x);  return (GET_MODE (x) == mode	  && (code == PLUS || code == MINUS || code == UMIN));}/* Check if MODE is same as mode for X, and X is PLUS or MINUS.  */intcris_additive_operand_extend_operator (rtx x, enum machine_mode mode){  enum rtx_code code = GET_CODE (x);  if (mode == VOIDmode)    mode = GET_MODE (x);  return (GET_MODE (x) == mode	  && (code == PLUS || code == MINUS));}/* Check to see if MODE is same as mode for X, and X is SIGN_EXTEND or   ZERO_EXTEND.  */intcris_extend_operator (rtx x, enum machine_mode mode){  enum rtx_code code = GET_CODE (x);  if (mode == VOIDmode)    mode = GET_MODE (x);  return    (GET_MODE (x) == mode && (code == SIGN_EXTEND || code == ZERO_EXTEND));}/* Check to see if MODE is same as mode for X, and X is PLUS or BOUND.  */intcris_plus_or_bound_operator (rtx x, enum machine_mode mode){  enum rtx_code code = GET_CODE (x);  if (mode == VOIDmode)    mode = GET_MODE (x);  return    (GET_MODE (x) == mode && (code == UMIN || code == PLUS));}/* Used as an operator to get a handle on a already-known-valid MEM rtx:es   (no need to validate the address), where some address expression parts   have their own match_operand.  */intcris_mem_op (rtx x, enum machine_mode mode){  if (mode == VOIDmode)    mode = GET_MODE (x);  return GET_MODE (x) == mode && GET_CODE (x) == MEM;}/* Since with -fPIC, not all symbols are valid PIC symbols or indeed   general_operands, we have to have a predicate that matches it for the   "movsi" expander.  */intcris_general_operand_or_symbol (rtx op, enum machine_mode mode){  return general_operand (op, mode)    || (CONSTANT_P (op) && cris_symbol (op));}/* Since a PIC symbol without a GOT entry is not a general_operand, we   have to have a predicate that matches it.  We use this in the expanded   "movsi" anonymous pattern for PIC symbols.  */intcris_general_operand_or_gotless_symbol (rtx op, enum machine_mode mode){  return general_operand (op, mode)    || (CONSTANT_P (op) && cris_gotless_symbol (op));}/* Since a PLT symbol is not a general_operand, we have to have a   predicate that matches it when we need it.  We use this in the expanded   "call" and "call_value" anonymous patterns.  */intcris_general_operand_or_plt_symbol (rtx op, enum machine_mode mode){  return general_operand (op, mode)    || (GET_CODE (op) == CONST	&& GET_CODE (XEXP (op, 0)) == UNSPEC	&& !TARGET_AVOID_GOTPLT);}

⌨️ 快捷键说明

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