📄 i386.c
字号:
-1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */ -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */};/* Test and compare insns in i386.md store the information needed to generate branch and scc insns here. */rtx ix86_compare_op0 = NULL_RTX;rtx ix86_compare_op1 = NULL_RTX;rtx ix86_compare_emitted = NULL_RTX;/* Size of the register save area. */#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)/* Define the structure for the machine field in struct function. */struct stack_local_entry GTY(()){ unsigned short mode; unsigned short n; rtx rtl; struct stack_local_entry *next;};/* Structure describing stack frame layout. Stack grows downward: [arguments] <- ARG_POINTER saved pc saved frame pointer if frame_pointer_needed <- HARD_FRAME_POINTER [saved regs] [padding1] \ ) [va_arg registers] ( > to_allocate <- FRAME_POINTER [frame] ( ) [padding2] / */struct ix86_frame{ int nregs; int padding1; int va_arg_size; HOST_WIDE_INT frame; int padding2; int outgoing_arguments_size; int red_zone_size; HOST_WIDE_INT to_allocate; /* The offsets relative to ARG_POINTER. */ HOST_WIDE_INT frame_pointer_offset; HOST_WIDE_INT hard_frame_pointer_offset; HOST_WIDE_INT stack_pointer_offset; /* When save_regs_using_mov is set, emit prologue using move instead of push instructions. */ bool save_regs_using_mov;};/* Code model option. */enum cmodel ix86_cmodel;/* Asm dialect. */enum asm_dialect ix86_asm_dialect = ASM_ATT;/* TLS dialext. */enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;/* Which unit we are generating floating point math for. */enum fpmath_unit ix86_fpmath;/* Which cpu are we scheduling for. */enum processor_type ix86_tune;/* Which instruction set architecture to use. */enum processor_type ix86_arch;/* true if sse prefetch instruction is not NOOP. */int x86_prefetch_sse;/* ix86_regparm_string as a number */static int ix86_regparm;/* Preferred alignment for stack boundary in bits. */unsigned int ix86_preferred_stack_boundary;/* Values 1-5: see jump.c */int ix86_branch_cost;/* Variables which are this size or smaller are put in the data/bss or ldata/lbss sections. */int ix86_section_threshold = 65536;/* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */char internal_label_prefix[16];int internal_label_prefix_len;static bool ix86_handle_option (size_t, const char *, int);static void output_pic_addr_const (FILE *, rtx, int);static void put_condition_code (enum rtx_code, enum machine_mode, int, int, FILE *);static const char *get_some_local_dynamic_name (void);static int get_some_local_dynamic_name_1 (rtx *, void *);static rtx ix86_expand_int_compare (enum rtx_code, rtx, rtx);static enum rtx_code ix86_prepare_fp_compare_args (enum rtx_code, rtx *, rtx *);static bool ix86_fixed_condition_code_regs (unsigned int *, unsigned int *);static enum machine_mode ix86_cc_modes_compatible (enum machine_mode, enum machine_mode);static rtx get_thread_pointer (int);static rtx legitimize_tls_address (rtx, enum tls_model, int);static void get_pc_thunk_name (char [32], unsigned int);static rtx gen_push (rtx);static int ix86_flags_dependant (rtx, rtx, enum attr_type);static int ix86_agi_dependant (rtx, rtx, enum attr_type);static struct machine_function * ix86_init_machine_status (void);static int ix86_split_to_parts (rtx, rtx *, enum machine_mode);static int ix86_nsaved_regs (void);static void ix86_emit_save_regs (void);static void ix86_emit_save_regs_using_mov (rtx, HOST_WIDE_INT);static void ix86_emit_restore_regs_using_mov (rtx, HOST_WIDE_INT, int);static void ix86_output_function_epilogue (FILE *, HOST_WIDE_INT);static HOST_WIDE_INT ix86_GOT_alias_set (void);static void ix86_adjust_counter (rtx, HOST_WIDE_INT);static rtx ix86_expand_aligntest (rtx, int);static void ix86_expand_strlensi_unroll_1 (rtx, rtx, rtx);static int ix86_issue_rate (void);static int ix86_adjust_cost (rtx, rtx, rtx, int);static int ia32_multipass_dfa_lookahead (void);static void ix86_init_mmx_sse_builtins (void);static rtx x86_this_parameter (tree);static void x86_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);static bool x86_can_output_mi_thunk (tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);static void x86_file_start (void);static void ix86_reorg (void);static bool ix86_expand_carry_flag_compare (enum rtx_code, rtx, rtx, rtx*);static tree ix86_build_builtin_va_list (void);static void ix86_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);static tree ix86_gimplify_va_arg (tree, tree, tree *, tree *);static bool ix86_vector_mode_supported_p (enum machine_mode);static int ix86_address_cost (rtx);static bool ix86_cannot_force_const_mem (rtx);static rtx ix86_delegitimize_address (rtx);static void i386_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;struct builtin_description;static rtx ix86_expand_sse_comi (const struct builtin_description *, tree, rtx);static rtx ix86_expand_sse_compare (const struct builtin_description *, tree, rtx);static rtx ix86_expand_unop1_builtin (enum insn_code, tree, rtx);static rtx ix86_expand_unop_builtin (enum insn_code, tree, rtx, int);static rtx ix86_expand_binop_builtin (enum insn_code, tree, rtx);static rtx ix86_expand_store_builtin (enum insn_code, tree);static rtx safe_vector_operand (rtx, enum machine_mode);static rtx ix86_expand_fp_compare (enum rtx_code, rtx, rtx, rtx, rtx *, rtx *);static int ix86_fp_comparison_arithmetics_cost (enum rtx_code code);static int ix86_fp_comparison_fcomi_cost (enum rtx_code code);static int ix86_fp_comparison_sahf_cost (enum rtx_code code);static int ix86_fp_comparison_cost (enum rtx_code code);static unsigned int ix86_select_alt_pic_regnum (void);static int ix86_save_reg (unsigned int, int);static void ix86_compute_frame_layout (struct ix86_frame *);static int ix86_comp_type_attributes (tree, tree);static int ix86_function_regparm (tree, tree);const struct attribute_spec ix86_attribute_table[];static bool ix86_function_ok_for_sibcall (tree, tree);static tree ix86_handle_cconv_attribute (tree *, tree, tree, int, bool *);static int ix86_value_regno (enum machine_mode, tree, tree);static bool contains_128bit_aligned_vector_p (tree);static rtx ix86_struct_value_rtx (tree, int);static bool ix86_ms_bitfield_layout_p (tree);static tree ix86_handle_struct_attribute (tree *, tree, tree, int, bool *);static int extended_reg_mentioned_1 (rtx *, void *);static bool ix86_rtx_costs (rtx, int, int, int *);static int min_insn_size (rtx);static tree ix86_md_asm_clobbers (tree outputs, tree inputs, tree clobbers);static bool ix86_must_pass_in_stack (enum machine_mode mode, tree type);static bool ix86_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);static void ix86_init_builtins (void);static rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);static const char *ix86_mangle_fundamental_type (tree);static tree ix86_stack_protect_fail (void);static rtx ix86_internal_arg_pointer (void);static void ix86_dwarf_handle_frame_unspec (const char *, rtx, int);/* This function is only used on Solaris. */static void i386_solaris_elf_named_section (const char *, unsigned int, tree) ATTRIBUTE_UNUSED;/* Register class used for passing given 64bit part of the argument. These represent classes as documented by the PS ABI, with the exception of SSESF, SSEDF classes, that are basically SSE class, just gcc will use SF or DFmode move instead of DImode to avoid reformatting penalties. Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves whenever possible (upper half does contain padding). */enum x86_64_reg_class { X86_64_NO_CLASS, X86_64_INTEGER_CLASS, X86_64_INTEGERSI_CLASS, X86_64_SSE_CLASS, X86_64_SSESF_CLASS, X86_64_SSEDF_CLASS, X86_64_SSEUP_CLASS, X86_64_X87_CLASS, X86_64_X87UP_CLASS, X86_64_COMPLEX_X87_CLASS, X86_64_MEMORY_CLASS };static const char * const x86_64_reg_class_name[] = { "no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "cplx87", "no"};#define MAX_CLASSES 4/* Table of constants used by fldpi, fldln2, etc.... */static REAL_VALUE_TYPE ext_80387_constants_table [5];static bool ext_80387_constants_init = 0;static void init_ext_80387_constants (void);static bool ix86_in_large_data_p (tree) ATTRIBUTE_UNUSED;static void ix86_encode_section_info (tree, rtx, int) ATTRIBUTE_UNUSED;static void x86_64_elf_unique_section (tree decl, int reloc) ATTRIBUTE_UNUSED;static void x86_64_elf_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) ATTRIBUTE_UNUSED;/* Initialize the GCC target structure. */#undef TARGET_ATTRIBUTE_TABLE#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table#if TARGET_DLLIMPORT_DECL_ATTRIBUTES# undef TARGET_MERGE_DECL_ATTRIBUTES# define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes#endif#undef TARGET_COMP_TYPE_ATTRIBUTES#define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS ix86_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN ix86_expand_builtin#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue#undef TARGET_ENCODE_SECTION_INFO#ifndef SUBTARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info#else#define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO#endif#undef TARGET_ASM_OPEN_PAREN#define TARGET_ASM_OPEN_PAREN ""#undef TARGET_ASM_CLOSE_PAREN#define TARGET_ASM_CLOSE_PAREN ""#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP ASM_LONG#ifdef ASM_QUAD#undef TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD#endif#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_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST ix86_adjust_cost#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE ix86_issue_rate#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ ia32_multipass_dfa_lookahead#undef TARGET_FUNCTION_OK_FOR_SIBCALL#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall#ifdef HAVE_AS_TLS#undef TARGET_HAVE_TLS#define TARGET_HAVE_TLS true#endif#undef TARGET_CANNOT_FORCE_CONST_MEM#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem#undef TARGET_DELEGITIMIZE_ADDRESS#define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address#undef TARGET_MS_BITFIELD_LAYOUT_P#define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p#if TARGET_MACHO#undef TARGET_BINDS_LOCAL_P#define TARGET_BINDS_LOCAL_P darwin_binds_local_p#endif#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk#undef TARGET_ASM_FILE_START#define TARGET_ASM_FILE_START x86_file_start#undef TARGET_DEFAULT_TARGET_FLAGS#define TARGET_DEFAULT_TARGET_FLAGS \ (TARGET_DEFAULT \ | TARGET_64BIT_DEFAULT \ | TARGET_SUBTARGET_DEFAULT \ | TARGET_TLS_DIRECT_SEG_REFS_DEFAULT)#undef TARGET_HANDLE_OPTION#define TARGET_HANDLE_OPTION ix86_handle_option#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS ix86_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST ix86_address_cost#undef TARGET_FIXED_CONDITION_CODE_REGS#define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs#undef TARGET_CC_MODES_COMPATIBLE#define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible#undef TARGET_MACHINE_DEPENDENT_REORG#define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg#undef TARGET_BUILD_BUILTIN_VA_LIST#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list#undef TARGET_MD_ASM_CLOBBERS#define TARGET_MD_ASM_CLOBBERS ix86_md_asm_clobbers#undef TARGET_PROMOTE_PROTOTYPES#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true#undef TARGET_STRUCT_VALUE_RTX#define TARGET_STRUCT_VALUE_RTX ix86_struct_value_rtx#undef TARGET_SETUP_INCOMING_VARARGS#define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs#undef TARGET_MUST_PASS_IN_STACK#define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack#undef TARGET_PASS_BY_REFERENCE#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference#undef TARGET_INTERNAL_ARG_POINTER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -