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

📄 cris.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Definitions for GCC.  Part of the machine description for CRIS.   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 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 "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"/* 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;/* Fix for reg_overlap_mentioned_p.  */static int cris_reg_overlap_mentioned_p PARAMS ((rtx, rtx));static void cris_print_base PARAMS ((rtx, FILE *));static void cris_print_index PARAMS ((rtx, FILE *));static struct machine_function * cris_init_machine_status PARAMS ((void));static int cris_initial_frame_pointer_offset PARAMS ((void));static int saved_regs_mentioned PARAMS ((rtx));static void cris_target_asm_function_prologue  PARAMS ((FILE *, HOST_WIDE_INT));static void cris_target_asm_function_epilogue  PARAMS ((FILE *, HOST_WIDE_INT));static void cris_encode_section_info PARAMS ((tree, int));static void cris_operand_lossage PARAMS ((const char *, rtx));static void cris_asm_output_mi_thunk  PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));/* 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_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO cris_encode_section_info#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_vcallstruct 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 (op, mode)     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 (op, mode)     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 (x, mode)     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 (x, mode)     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 (x, mode)     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 (x, mode)     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 (x, mode)     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 (x, mode)     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 (op, mode)     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 (op, mode)     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 (op, mode)     rtx op;     enum machine_mode mode;{  return general_operand (op, mode)    || (GET_CODE (op) == CONST	&& GET_CODE (XEXP (op, 0)) == UNSPEC	&& !TARGET_AVOID_GOTPLT);}/* This matches a (MEM (general_operand)) or   (MEM (cris_general_operand_or_symbol)).  The second one isn't a valid   memory_operand, so we need this predicate to recognize call   destinations before we change them to a PLT operand (by wrapping in   UNSPEC 0).  */intcris_mem_call_operand (op, mode)     rtx op;     enum machine_mode mode;{  rtx xmem;  if (GET_CODE (op) != MEM)    return 0;  if (memory_operand (op, mode))    return 1;  xmem = XEXP (op, 0);  return cris_general_operand_or_symbol (xmem, GET_MODE (op));

⌨️ 快捷键说明

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