📄 ia64.c
字号:
/* Definitions of target machine for GNU compiler. Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by James E. Wilson <wilson@cygnus.com> and David Mosberger <davidm@hpl.hp.com>.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 "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 "hashtab.h"#include "langhooks.h"#include "cfglayout.h"#include "tree-gimple.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;/* Which cpu are we scheduling for. */enum processor_type ia64_tune;/* String used with the -tune= option. */const char *ia64_tune_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;/* Determines whether we run variable tracking in machine dependent reorganization. */static int ia64_flag_var_tracking;/* Variables which are this size or smaller are put in the sdata/sbss sections. */unsigned int ia64_section_threshold;/* The following variable is used by the DFA insn scheduler. The value is TRUE if we do insn bundling instead of insn scheduling. */int bundling_p = 0;/* 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 int ia64_first_cycle_multipass_dfa_lookahead (void);static void ia64_dependencies_evaluation_hook (rtx, rtx);static void ia64_init_dfa_pre_cycle_insn (void);static rtx ia64_dfa_pre_cycle_insn (void);static int ia64_first_cycle_multipass_dfa_lookahead_guard (rtx);static int ia64_dfa_new_cycle (FILE *, int, rtx, int, int, int *);static rtx gen_tls_get_addr (void);static rtx gen_thread_pointer (void);static int find_gr_spill (int);static int next_scratch_gr_reg (void);static void mark_reg_gr_used_mask (rtx, void *);static void ia64_compute_frame_size (HOST_WIDE_INT);static void setup_spill_pointers (int, rtx, HOST_WIDE_INT);static void finish_spill_pointers (void);static rtx spill_restore_mem (rtx, HOST_WIDE_INT);static void do_spill (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx);static void do_restore (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT);static rtx gen_movdi_x (rtx, rtx, rtx);static rtx gen_fr_spill_x (rtx, rtx, rtx);static rtx gen_fr_restore_x (rtx, rtx, rtx);static enum machine_mode hfa_element_mode (tree, bool);static void ia64_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);static bool ia64_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);static bool ia64_function_ok_for_sibcall (tree, tree);static bool ia64_return_in_memory (tree, tree);static bool ia64_rtx_costs (rtx, int, int, int *);static void fix_range (const char *);static struct machine_function * ia64_init_machine_status (void);static void emit_insn_group_barriers (FILE *);static void emit_all_insn_group_barriers (FILE *);static void final_emit_insn_group_barriers (FILE *);static void emit_predicate_relation_info (void);static void ia64_reorg (void);static bool ia64_in_small_data_p (tree);static void process_epilogue (void);static int process_set (FILE *, rtx);static rtx ia64_expand_fetch_and_op (optab, enum machine_mode, tree, rtx);static rtx ia64_expand_op_and_fetch (optab, enum machine_mode, tree, rtx);static rtx ia64_expand_compare_and_swap (enum machine_mode, enum machine_mode, int, tree, rtx);static rtx ia64_expand_lock_test_and_set (enum machine_mode, tree, rtx);static rtx ia64_expand_lock_release (enum machine_mode, tree, rtx);static bool ia64_assemble_integer (rtx, unsigned int, int);static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT);static void ia64_output_function_epilogue (FILE *, HOST_WIDE_INT);static void ia64_output_function_end_prologue (FILE *);static int ia64_issue_rate (void);static int ia64_adjust_cost (rtx, rtx, rtx, int);static void ia64_sched_init (FILE *, int, int);static void ia64_sched_finish (FILE *, int);static int ia64_dfa_sched_reorder (FILE *, int, rtx *, int *, int, int);static int ia64_sched_reorder (FILE *, int, rtx *, int *, int);static int ia64_sched_reorder2 (FILE *, int, rtx *, int *, int);static int ia64_variable_issue (FILE *, int, rtx, int);static struct bundle_state *get_free_bundle_state (void);static void free_bundle_state (struct bundle_state *);static void initiate_bundle_states (void);static void finish_bundle_states (void);static unsigned bundle_state_hash (const void *);static int bundle_state_eq_p (const void *, const void *);static int insert_bundle_state (struct bundle_state *);static void initiate_bundle_state_table (void);static void finish_bundle_state_table (void);static int try_issue_nops (struct bundle_state *, int);static int try_issue_insn (struct bundle_state *, rtx);static void issue_nops_and_insn (struct bundle_state *, int, rtx, int, int);static int get_max_pos (state_t);static int get_template (state_t, int);static rtx get_next_important_insn (rtx, rtx);static void bundling (FILE *, int, rtx, rtx);static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);static void ia64_file_start (void);static void ia64_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT);static void ia64_rwreloc_select_section (tree, int, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED;static void ia64_rwreloc_unique_section (tree, int) ATTRIBUTE_UNUSED;static void ia64_rwreloc_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED;static unsigned int ia64_section_type_flags (tree, const char *, int);static void ia64_hpux_add_extern_decl (tree decl) ATTRIBUTE_UNUSED;static void ia64_hpux_file_end (void) ATTRIBUTE_UNUSED;static void ia64_init_libfuncs (void) ATTRIBUTE_UNUSED;static void ia64_hpux_init_libfuncs (void) ATTRIBUTE_UNUSED;static void ia64_sysv4_init_libfuncs (void) ATTRIBUTE_UNUSED;static void ia64_vms_init_libfuncs (void) ATTRIBUTE_UNUSED;static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);static void ia64_encode_section_info (tree, rtx, int);static rtx ia64_struct_value_rtx (tree, int);static tree ia64_gimplify_va_arg (tree, tree, tree *, tree *);static bool ia64_scalar_mode_supported_p (enum machine_mode mode);static bool ia64_vector_mode_supported_p (enum machine_mode mode);static bool ia64_cannot_force_const_mem (rtx);/* 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 }, { "model", 1, 1, true, false, false, ia64_handle_model_attribute }, { 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_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_SCHED_DEPENDENCIES_EVALUATION_HOOK#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ia64_dependencies_evaluation_hook#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ia64_first_cycle_multipass_dfa_lookahead#undef TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN#define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN ia64_init_dfa_pre_cycle_insn#undef TARGET_SCHED_DFA_PRE_CYCLE_INSN#define TARGET_SCHED_DFA_PRE_CYCLE_INSN ia64_dfa_pre_cycle_insn#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD\ ia64_first_cycle_multipass_dfa_lookahead_guard#undef TARGET_SCHED_DFA_NEW_CYCLE#define TARGET_SCHED_DFA_NEW_CYCLE ia64_dfa_new_cycle#undef TARGET_FUNCTION_OK_FOR_SIBCALL#define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall#undef TARGET_PASS_BY_REFERENCE#define TARGET_PASS_BY_REFERENCE ia64_pass_by_reference#undef TARGET_ARG_PARTIAL_BYTES#define TARGET_ARG_PARTIAL_BYTES ia64_arg_partial_bytes#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_true#undef TARGET_ASM_FILE_START#define TARGET_ASM_FILE_START ia64_file_start#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS ia64_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST hook_int_rtx_0#undef TARGET_MACHINE_DEPENDENT_REORG#define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg#undef TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info#undef TARGET_SECTION_TYPE_FLAGS#define TARGET_SECTION_TYPE_FLAGS ia64_section_type_flags/* ??? ABI doesn't allow us to define this. */#if 0#undef TARGET_PROMOTE_FUNCTION_ARGS#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true#endif/* ??? ABI doesn't allow us to define this. */#if 0#undef TARGET_PROMOTE_FUNCTION_RETURN#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true#endif/* ??? Investigate. */#if 0#undef TARGET_PROMOTE_PROTOTYPES#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true#endif#undef TARGET_STRUCT_VALUE_RTX#define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx#undef TARGET_RETURN_IN_MEMORY#define TARGET_RETURN_IN_MEMORY ia64_return_in_memory#undef TARGET_SETUP_INCOMING_VARARGS#define TARGET_SETUP_INCOMING_VARARGS ia64_setup_incoming_varargs#undef TARGET_STRICT_ARGUMENT_NAMING#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true#undef TARGET_MUST_PASS_IN_STACK#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size#undef TARGET_GIMPLIFY_VA_ARG_EXPR#define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg#undef TARGET_UNWIND_EMIT#define TARGET_UNWIND_EMIT process_for_unwind_directive#undef TARGET_SCALAR_MODE_SUPPORTED_P#define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p#undef TARGET_VECTOR_MODE_SUPPORTED_P#define TARGET_VECTOR_MODE_SUPPORTED_P ia64_vector_mode_supported_p/* ia64 architecture manual 4.4.7: ... reads, writes, and flushes may occur in an order different from the specified program order. */#undef TARGET_RELAXED_ORDERING#define TARGET_RELAXED_ORDERING true#undef TARGET_CANNOT_FORCE_CONST_MEM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -