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

📄 cris.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Definitions for GCC.  Part of the machine description for CRIS.   Copyright (C) 1998, 1999, 2000, 2001, 2002 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.  */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));}/* 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));}/* The CONDITIONAL_REGISTER_USAGE worker.   */voidcris_conditional_register_usage (){  /* FIXME: This isn't nice.  We should be able to use that register for     something else if the PIC table isn't needed.  */  if (flag_pic)    fixed_regs[PIC_OFFSET_TABLE_REGNUM]      = call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;}/* Return current_function_uses_pic_offset_table.  For use in cris.md,   since some generated files do not include function.h.  */int

⌨️ 快捷键说明

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