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

📄 ia64.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Definitions of target machine for GNU compiler.   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.   Contributed by James E. Wilson <wilson@cygnus.com> and   		  David Mosberger <davidm@hpl.hp.com>.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 "output.h"#include "insn-attr.h"#include "flags.h"#include "recog.h"#include "expr.h"#include "optabs.h"#include "except.h"#include "function.h"#include "ggc.h"#include "basic-block.h"#include "toplev.h"#include "sched-int.h"#include "timevar.h"#include "target.h"#include "target-def.h"#include "tm_p.h"#include "langhooks.h"/* This is used for communication between ASM_OUTPUT_LABEL and   ASM_OUTPUT_LABELREF.  */int ia64_asm_output_label = 0;/* Define the information needed to generate branch and scc insns.  This is   stored from the compare operation.  */struct rtx_def * ia64_compare_op0;struct rtx_def * ia64_compare_op1;/* Register names for ia64_expand_prologue.  */static const char * const ia64_reg_numbers[96] ={ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",  "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",  "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",  "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",  "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",  "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",  "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",  "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",  "r96", "r97", "r98", "r99", "r100","r101","r102","r103",  "r104","r105","r106","r107","r108","r109","r110","r111",  "r112","r113","r114","r115","r116","r117","r118","r119",  "r120","r121","r122","r123","r124","r125","r126","r127"};/* ??? These strings could be shared with REGISTER_NAMES.  */static const char * const ia64_input_reg_names[8] ={ "in0",  "in1",  "in2",  "in3",  "in4",  "in5",  "in6",  "in7" };/* ??? These strings could be shared with REGISTER_NAMES.  */static const char * const ia64_local_reg_names[80] ={ "loc0", "loc1", "loc2", "loc3", "loc4", "loc5", "loc6", "loc7",  "loc8", "loc9", "loc10","loc11","loc12","loc13","loc14","loc15",  "loc16","loc17","loc18","loc19","loc20","loc21","loc22","loc23",  "loc24","loc25","loc26","loc27","loc28","loc29","loc30","loc31",  "loc32","loc33","loc34","loc35","loc36","loc37","loc38","loc39",  "loc40","loc41","loc42","loc43","loc44","loc45","loc46","loc47",  "loc48","loc49","loc50","loc51","loc52","loc53","loc54","loc55",  "loc56","loc57","loc58","loc59","loc60","loc61","loc62","loc63",  "loc64","loc65","loc66","loc67","loc68","loc69","loc70","loc71",  "loc72","loc73","loc74","loc75","loc76","loc77","loc78","loc79" };/* ??? These strings could be shared with REGISTER_NAMES.  */static const char * const ia64_output_reg_names[8] ={ "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" };/* String used with the -mfixed-range= option.  */const char *ia64_fixed_range_string;/* Determines whether we use adds, addl, or movl to generate our   TLS immediate offsets.  */int ia64_tls_size = 22;/* String used with the -mtls-size= option.  */const char *ia64_tls_size_string;/* Determines whether we run our final scheduling pass or not.  We always   avoid the normal second scheduling pass.  */static int ia64_flag_schedule_insns2;/* Variables which are this size or smaller are put in the sdata/sbss   sections.  */unsigned int ia64_section_threshold;/* Structure to be filled in by ia64_compute_frame_size with register   save masks and offsets for the current function.  */struct ia64_frame_info{  HOST_WIDE_INT total_size;	/* size of the stack frame, not including				   the caller's scratch area.  */  HOST_WIDE_INT spill_cfa_off;	/* top of the reg spill area from the cfa.  */  HOST_WIDE_INT spill_size;	/* size of the gr/br/fr spill area.  */  HOST_WIDE_INT extra_spill_size;  /* size of spill area for others.  */  HARD_REG_SET mask;		/* mask of saved registers.  */  unsigned int gr_used_mask;	/* mask of registers in use as gr spill 				   registers or long-term scratches.  */  int n_spilled;		/* number of spilled registers.  */  int reg_fp;			/* register for fp.  */  int reg_save_b0;		/* save register for b0.  */  int reg_save_pr;		/* save register for prs.  */  int reg_save_ar_pfs;		/* save register for ar.pfs.  */  int reg_save_ar_unat;		/* save register for ar.unat.  */  int reg_save_ar_lc;		/* save register for ar.lc.  */  int reg_save_gp;		/* save register for gp.  */  int n_input_regs;		/* number of input registers used.  */  int n_local_regs;		/* number of local registers used.  */  int n_output_regs;		/* number of output registers used.  */  int n_rotate_regs;		/* number of rotating registers used.  */  char need_regstk;		/* true if a .regstk directive needed.  */  char initialized;		/* true if the data is finalized.  */};/* Current frame information calculated by ia64_compute_frame_size.  */static struct ia64_frame_info current_frame_info;static rtx gen_tls_get_addr PARAMS ((void));static rtx gen_thread_pointer PARAMS ((void));static int find_gr_spill PARAMS ((int));static int next_scratch_gr_reg PARAMS ((void));static void mark_reg_gr_used_mask PARAMS ((rtx, void *));static void ia64_compute_frame_size PARAMS ((HOST_WIDE_INT));static void setup_spill_pointers PARAMS ((int, rtx, HOST_WIDE_INT));static void finish_spill_pointers PARAMS ((void));static rtx spill_restore_mem PARAMS ((rtx, HOST_WIDE_INT));static void do_spill PARAMS ((rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx));static void do_restore PARAMS ((rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT));static rtx gen_movdi_x PARAMS ((rtx, rtx, rtx));static rtx gen_fr_spill_x PARAMS ((rtx, rtx, rtx));static rtx gen_fr_restore_x PARAMS ((rtx, rtx, rtx));static enum machine_mode hfa_element_mode PARAMS ((tree, int));static void fix_range PARAMS ((const char *));static struct machine_function * ia64_init_machine_status PARAMS ((void));static void emit_insn_group_barriers PARAMS ((FILE *, rtx));static void emit_all_insn_group_barriers PARAMS ((FILE *, rtx));static void emit_predicate_relation_info PARAMS ((void));static bool ia64_in_small_data_p PARAMS ((tree));static void ia64_encode_section_info PARAMS ((tree, int));static const char *ia64_strip_name_encoding PARAMS ((const char *));static void process_epilogue PARAMS ((void));static int process_set PARAMS ((FILE *, rtx));static rtx ia64_expand_fetch_and_op PARAMS ((optab, enum machine_mode,					     tree, rtx));static rtx ia64_expand_op_and_fetch PARAMS ((optab, enum machine_mode,					     tree, rtx));static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode,						 enum machine_mode,						 int, tree, rtx));static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,						  tree, rtx));static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx));static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));static void ia64_output_function_end_prologue PARAMS ((FILE *));static int ia64_issue_rate PARAMS ((void));static int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));static void ia64_sched_init PARAMS ((FILE *, int, int));static void ia64_sched_finish PARAMS ((FILE *, int));static int ia64_internal_sched_reorder PARAMS ((FILE *, int, rtx *,						int *, int, int));static int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));static int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));static void ia64_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,					  HOST_WIDE_INT, tree));static void ia64_select_rtx_section PARAMS ((enum machine_mode, rtx,					     unsigned HOST_WIDE_INT));static void ia64_rwreloc_select_section PARAMS ((tree, int,					         unsigned HOST_WIDE_INT))     ATTRIBUTE_UNUSED;static void ia64_rwreloc_unique_section PARAMS ((tree, int))     ATTRIBUTE_UNUSED;static void ia64_rwreloc_select_rtx_section PARAMS ((enum machine_mode, rtx,					             unsigned HOST_WIDE_INT))     ATTRIBUTE_UNUSED;static unsigned int ia64_rwreloc_section_type_flags     PARAMS ((tree, const char *, int))     ATTRIBUTE_UNUSED;static void ia64_hpux_add_extern_decl PARAMS ((const char *name))     ATTRIBUTE_UNUSED;/* Table of valid machine attributes.  */static const struct attribute_spec ia64_attribute_table[] ={  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */  { "syscall_linkage", 0, 0, false, true,  true,  NULL },  { NULL,              0, 0, false, false, false, NULL }};/* Initialize the GCC target structure.  */#undef TARGET_ATTRIBUTE_TABLE#define TARGET_ATTRIBUTE_TABLE ia64_attribute_table#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS ia64_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN ia64_expand_builtin#undef TARGET_ASM_BYTE_OP#define TARGET_ASM_BYTE_OP "\tdata1\t"#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\tdata2\t"#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP "\tdata4\t"#undef TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP "\tdata8\t"#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP "\tdata2.ua\t"#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP "\tdata4.ua\t"#undef TARGET_ASM_UNALIGNED_DI_OP#define TARGET_ASM_UNALIGNED_DI_OP "\tdata8.ua\t"#undef TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER ia64_assemble_integer#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE ia64_output_function_prologue#undef TARGET_ASM_FUNCTION_END_PROLOGUE#define TARGET_ASM_FUNCTION_END_PROLOGUE ia64_output_function_end_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE ia64_output_function_epilogue#undef TARGET_IN_SMALL_DATA_P#define TARGET_IN_SMALL_DATA_P  ia64_in_small_data_p#undef TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info#undef TARGET_STRIP_NAME_ENCODING#define TARGET_STRIP_NAME_ENCODING ia64_strip_name_encoding#undef TARGET_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST ia64_adjust_cost#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE ia64_issue_rate#undef TARGET_SCHED_VARIABLE_ISSUE#define TARGET_SCHED_VARIABLE_ISSUE ia64_variable_issue#undef TARGET_SCHED_INIT#define TARGET_SCHED_INIT ia64_sched_init#undef TARGET_SCHED_FINISH#define TARGET_SCHED_FINISH ia64_sched_finish#undef TARGET_SCHED_REORDER#define TARGET_SCHED_REORDER ia64_sched_reorder#undef TARGET_SCHED_REORDER2#define TARGET_SCHED_REORDER2 ia64_sched_reorder2#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_truestruct gcc_target targetm = TARGET_INITIALIZER;/* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */intcall_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (mode != GET_MODE (op) && mode != VOIDmode)    return 0;  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG	  || (GET_CODE (op) == SUBREG && GET_CODE (XEXP (op, 0)) == REG));}/* Return 1 if OP refers to a symbol in the sdata section.  */intsdata_symbolic_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  switch (GET_CODE (op))    {    case CONST:      if (GET_CODE (XEXP (op, 0)) != PLUS	  || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF)	break;      op = XEXP (XEXP (op, 0), 0);      /* FALLTHRU */    case SYMBOL_REF:      if (CONSTANT_POOL_ADDRESS_P (op))	return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;      else	{	  const char *str = XSTR (op, 0);          return (str[0] == ENCODE_SECTION_INFO_CHAR && str[1] == 's');	}    default:      break;    }  return 0;}/* Return 1 if OP refers to a symbol, and is appropriate for a GOT load.  */intgot_symbolic_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  switch (GET_CODE (op))    {    case CONST:      op = XEXP (op, 0);      if (GET_CODE (op) != PLUS)	return 0;      if (GET_CODE (XEXP (op, 0)) != SYMBOL_REF)	return 0;      op = XEXP (op, 1);      if (GET_CODE (op) != CONST_INT)	return 0;	return 1;      /* Ok if we're not using GOT entries at all.  */      if (TARGET_NO_PIC || TARGET_AUTO_PIC)	return 1;      /* "Ok" while emitting rtl, since otherwise we won't be provided	 with the entire offset during emission, which makes it very	 hard to split the offset into high and low parts.  */      if (rtx_equal_function_value_matters)	return 1;      /* Force the low 14 bits of the constant to zero so that we do not	 use up so many GOT entries.  */      return (INTVAL (op) & 0x3fff) == 0;    case SYMBOL_REF:    case LABEL_REF:      return 1;    default:      break;    }  return 0;}/* Return 1 if OP refers to a symbol.  */intsymbolic_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  switch (GET_CODE (op))    {    case CONST:    case SYMBOL_REF:    case LABEL_REF:      return 1;    default:      break;    }  return 0;}/* Return tls_model if OP refers to a TLS symbol.  */inttls_symbolic_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  const char *str;  if (GET_CODE (op) != SYMBOL_REF)    return 0;  str = XSTR (op, 0);  if (str[0] != ENCODE_SECTION_INFO_CHAR)    return 0;  switch (str[1])    {    case 'G':      return TLS_MODEL_GLOBAL_DYNAMIC;    case 'L':      return TLS_MODEL_LOCAL_DYNAMIC;    case 'i':      return TLS_MODEL_INITIAL_EXEC;    case 'l':      return TLS_MODEL_LOCAL_EXEC;    }  return 0;}/* Return 1 if OP refers to a function.  */intfunction_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FLAG (op))    return 1;  else    return 0;}/* Return 1 if OP is setjmp or a similar function.  *//* ??? This is an unsatisfying solution.  Should rethink.  */intsetjmp_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  const char *name;  int retval = 0;  if (GET_CODE (op) != SYMBOL_REF)    return 0;

⌨️ 快捷键说明

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