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

📄 sh.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Output routines for GCC for Renesas / SuperH SH.   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,   2003, 2004, 2005 Free Software Foundation, Inc.   Contributed by Steve Chamberlain (sac@cygnus.com).   Improved by Jim Wilson (wilson@cygnus.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 "insn-config.h"#include "rtl.h"#include "tree.h"#include "flags.h"#include "expr.h"#include "optabs.h"#include "function.h"#include "regs.h"#include "hard-reg-set.h"#include "output.h"#include "insn-attr.h"#include "toplev.h"#include "recog.h"#include "c-pragma.h"#include "integrate.h"#include "dwarf2.h"#include "tm_p.h"#include "target.h"#include "target-def.h"#include "real.h"#include "langhooks.h"#include "basic-block.h"#include "cfglayout.h"#include "intl.h"#include "sched-int.h"#include "ggc.h"#include "tree-gimple.h"int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;#define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)#define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)/* These are some macros to abstract register modes.  */#define CONST_OK_FOR_ADD(size) \  (TARGET_SHMEDIA ? CONST_OK_FOR_I10 (size) : CONST_OK_FOR_I08 (size))#define GEN_MOV (*(TARGET_SHMEDIA64 ? gen_movdi : gen_movsi))#define GEN_ADD3 (*(TARGET_SHMEDIA64 ? gen_adddi3 : gen_addsi3))#define GEN_SUB3 (*(TARGET_SHMEDIA64 ? gen_subdi3 : gen_subsi3))/* Set to 1 by expand_prologue() when the function is an interrupt handler.  */int current_function_interrupt;/* ??? The pragma interrupt support will not work for SH3.  *//* This is set by #pragma interrupt and #pragma trapa, and causes gcc to   output code for the next function appropriate for an interrupt handler.  */int pragma_interrupt;/* This is set by the trap_exit attribute for functions.   It specifies   a trap number to be used in a trapa instruction at function exit   (instead of an rte instruction).  */int trap_exit;/* This is used by the sp_switch attribute for functions.  It specifies   a variable holding the address of the stack the interrupt function   should switch to/from at entry/exit.  */rtx sp_switch;/* This is set by #pragma trapa, and is similar to the above, except that   the compiler doesn't emit code to preserve all registers.  */static int pragma_trapa;/* This is set by #pragma nosave_low_regs.  This is useful on the SH3,   which has a separate set of low regs for User and Supervisor modes.   This should only be used for the lowest level of interrupts.  Higher levels   of interrupts must save the registers in case they themselves are   interrupted.  */int pragma_nosave_low_regs;/* This is used for communication between TARGET_SETUP_INCOMING_VARARGS and   sh_expand_prologue.  */int current_function_anonymous_args;/* Global variables for machine-dependent things.  *//* Which cpu are we scheduling for.  */enum processor_type sh_cpu;/* Definitions used in ready queue reordering for first scheduling pass.  *//* Reg weights arrays for modes SFmode and SImode, indexed by insn LUID.  */static short *regmode_weight[2];/* Total SFmode and SImode weights of scheduled insns.  */static int curr_regmode_pressure[2];/* If true, skip cycles for Q -> R movement.  */static int skip_cycles = 0;/* Cached value of can_issue_more. This is cached in sh_variable_issue hook   and returned from sh_reorder2.  */static short cached_can_issue_more;/* Saved operands from the last compare to use when we generate an scc   or bcc insn.  */rtx sh_compare_op0;rtx sh_compare_op1;/* Provides the class number of the smallest class containing   reg number.  */enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] ={  R0_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,  FP0_REGS,FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  FP_REGS, FP_REGS, FP_REGS, FP_REGS,  TARGET_REGS, TARGET_REGS, TARGET_REGS, TARGET_REGS,  TARGET_REGS, TARGET_REGS, TARGET_REGS, TARGET_REGS,  DF_REGS, DF_REGS, DF_REGS, DF_REGS,  DF_REGS, DF_REGS, DF_REGS, DF_REGS,  NO_REGS, GENERAL_REGS, PR_REGS, T_REGS,  MAC_REGS, MAC_REGS, FPUL_REGS, FPSCR_REGS,  GENERAL_REGS,};char sh_register_names[FIRST_PSEUDO_REGISTER] \  [MAX_REGISTER_NAME_LENGTH + 1] = SH_REGISTER_NAMES_INITIALIZER;char sh_additional_register_names[ADDREGNAMES_SIZE] \  [MAX_ADDITIONAL_REGISTER_NAME_LENGTH + 1]  = SH_ADDITIONAL_REGISTER_NAMES_INITIALIZER;/* Provide reg_class from a letter such as appears in the machine   description.  *: target independently reserved letter.   reg_class_from_letter['e' - 'a'] is set to NO_REGS for TARGET_FMOVD.  */enum reg_class reg_class_from_letter[] ={  /* a */ ALL_REGS,  /* b */ TARGET_REGS, /* c */ FPSCR_REGS, /* d */ DF_REGS,  /* e */ FP_REGS,   /* f */ FP_REGS,  /* g **/ NO_REGS,     /* h */ NO_REGS,  /* i **/ NO_REGS,  /* j */ NO_REGS,  /* k */ SIBCALL_REGS, /* l */ PR_REGS,  /* m **/ NO_REGS,  /* n **/ NO_REGS, /* o **/ NO_REGS,     /* p **/ NO_REGS,  /* q */ NO_REGS,   /* r **/ NO_REGS, /* s **/ NO_REGS,     /* t */ T_REGS,  /* u */ NO_REGS,   /* v */ NO_REGS,  /* w */ FP0_REGS,     /* x */ MAC_REGS,  /* y */ FPUL_REGS, /* z */ R0_REGS};int assembler_dialect;static bool shmedia_space_reserved_for_target_registers;static void split_branches (rtx);static int branch_dest (rtx);static void force_into (rtx, rtx);static void print_slot (rtx);static rtx add_constant (rtx, enum machine_mode, rtx);static void dump_table (rtx, rtx);static int hi_const (rtx);static int broken_move (rtx);static int mova_p (rtx);static rtx find_barrier (int, rtx, rtx);static int noncall_uses_reg (rtx, rtx, rtx *);static rtx gen_block_redirect (rtx, int, int);static void sh_reorg (void);static void output_stack_adjust (int, rtx, int, HARD_REG_SET *);static rtx frame_insn (rtx);static rtx push (int);static void pop (int);static void push_regs (HARD_REG_SET *, int);static int calc_live_regs (HARD_REG_SET *);static void mark_use (rtx, rtx *);static HOST_WIDE_INT rounded_frame_size (int);static rtx mark_constant_pool_use (rtx);const struct attribute_spec sh_attribute_table[];static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, int, bool *);static tree sh_handle_sp_switch_attribute (tree *, tree, tree, int, bool *);static tree sh_handle_trap_exit_attribute (tree *, tree, tree, int, bool *);static tree sh_handle_renesas_attribute (tree *, tree, tree, int, bool *);static void sh_output_function_epilogue (FILE *, HOST_WIDE_INT);static void sh_insert_attributes (tree, tree *);static int sh_adjust_cost (rtx, rtx, rtx, int);static int sh_issue_rate (void);static int sh_dfa_new_cycle (FILE *, int, rtx, int, int, int *sort_p);static short find_set_regmode_weight (rtx, enum machine_mode);static short find_insn_regmode_weight (rtx, enum machine_mode);static void find_regmode_weight (int, enum machine_mode);static void  sh_md_init_global (FILE *, int, int);static void  sh_md_finish_global (FILE *, int);static int rank_for_reorder (const void *, const void *);static void swap_reorder (rtx *, int);static void ready_reorder (rtx *, int);static short high_pressure (enum machine_mode);static int sh_reorder (FILE *, int, rtx *, int *, int);static int sh_reorder2 (FILE *, int, rtx *, int *, int);static void sh_md_init (FILE *, int, int);static int sh_variable_issue (FILE *, int, rtx, int);static bool sh_function_ok_for_sibcall (tree, tree);static bool sh_cannot_modify_jumps_p (void);static int sh_target_reg_class (void);static bool sh_optimize_target_register_callee_saved (bool);static bool sh_ms_bitfield_layout_p (tree);static void sh_init_builtins (void);static void sh_media_init_builtins (void);static rtx sh_expand_builtin (tree, rtx, rtx, enum machine_mode, int);static void sh_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);static void sh_file_start (void);static int flow_dependent_p (rtx, rtx);static void flow_dependent_p_1 (rtx, rtx, void *);static int shiftcosts (rtx);static int andcosts (rtx);static int addsubcosts (rtx);static int multcosts (rtx);static bool unspec_caller_rtx_p (rtx);static bool sh_cannot_copy_insn_p (rtx);static bool sh_rtx_costs (rtx, int, int, int *);static int sh_address_cost (rtx);static int shmedia_target_regs_stack_space (HARD_REG_SET *);static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *);static int shmedia_target_regs_stack_adjust (HARD_REG_SET *);static int scavenge_reg (HARD_REG_SET *s);struct save_schedule_s;static struct save_entry_s *sh5_schedule_saves (HARD_REG_SET *,						struct save_schedule_s *, int);static rtx sh_struct_value_rtx (tree, int);static bool sh_return_in_memory (tree, tree);static rtx sh_builtin_saveregs (void);static void sh_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);static bool sh_strict_argument_naming (CUMULATIVE_ARGS *);static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);static tree sh_build_builtin_va_list (void);static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *);static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,				  tree, bool);static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,			      tree, bool);static int sh_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,			         tree, bool);static int sh_dwarf_calling_convention (tree);static int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);/* Initialize the GCC target structure.  */#undef TARGET_ATTRIBUTE_TABLE#define TARGET_ATTRIBUTE_TABLE sh_attribute_table/* The next two are used for debug info when compiling with -gdwarf.  */#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP "\t.uaword\t"#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP "\t.ualong\t"/* These are NULLed out on non-SH5 in OVERRIDE_OPTIONS.  */#undef TARGET_ASM_UNALIGNED_DI_OP#define TARGET_ASM_UNALIGNED_DI_OP "\t.uaquad\t"#undef TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE sh_output_function_epilogue#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK sh_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 sh_file_start#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true#undef TARGET_INSERT_ATTRIBUTES#define TARGET_INSERT_ATTRIBUTES sh_insert_attributes#undef TARGET_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST sh_adjust_cost#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE sh_issue_rate/* The next 5 hooks have been implemented for reenabling sched1.  With the   help of these macros we are limiting the movement of insns in sched1 to   reduce the register pressure.  The overall idea is to keep count of SImode   and SFmode regs required by already scheduled insns. When these counts   cross some threshold values; give priority to insns that free registers.   The insn that frees registers is most likely to be the insn with lowest   LUID (original insn order); but such an insn might be there in the stalled   queue (Q) instead of the ready queue (R).  To solve this, we skip cycles   upto a max of 8 cycles so that such insns may move from Q -> R.   The description of the hooks are as below:   TARGET_SCHED_INIT_GLOBAL: Added a new target hook in the generic   scheduler; it is called inside the sched_init function just after   find_insn_reg_weights function call. It is used to calculate the SImode   and SFmode weights of insns of basic blocks; much similar to what   find_insn_reg_weights does.   TARGET_SCHED_FINISH_GLOBAL: Corresponding cleanup hook.   TARGET_SCHED_DFA_NEW_CYCLE: Skip cycles if high register pressure is   indicated by TARGET_SCHED_REORDER2; doing this may move insns from   (Q)->(R).   TARGET_SCHED_REORDER: If the register pressure for SImode or SFmode is   high; reorder the ready queue so that the insn with lowest LUID will be   issued next.   TARGET_SCHED_REORDER2: If the register pressure is high, indicate to   TARGET_SCHED_DFA_NEW_CYCLE to skip cycles.   TARGET_SCHED_VARIABLE_ISSUE: Cache the value of can_issue_more so that it   can be returned from TARGET_SCHED_REORDER2.   TARGET_SCHED_INIT: Reset the register pressure counting variables.  */#undef TARGET_SCHED_DFA_NEW_CYCLE#define TARGET_SCHED_DFA_NEW_CYCLE sh_dfa_new_cycle#undef TARGET_SCHED_INIT_GLOBAL#define TARGET_SCHED_INIT_GLOBAL sh_md_init_global#undef TARGET_SCHED_FINISH_GLOBAL#define TARGET_SCHED_FINISH_GLOBAL sh_md_finish_global#undef TARGET_SCHED_VARIABLE_ISSUE#define TARGET_SCHED_VARIABLE_ISSUE sh_variable_issue#undef TARGET_SCHED_REORDER#define TARGET_SCHED_REORDER sh_reorder#undef TARGET_SCHED_REORDER2#define TARGET_SCHED_REORDER2 sh_reorder2#undef TARGET_SCHED_INIT#define TARGET_SCHED_INIT sh_md_init#undef TARGET_CANNOT_MODIFY_JUMPS_P#define TARGET_CANNOT_MODIFY_JUMPS_P sh_cannot_modify_jumps_p#undef TARGET_BRANCH_TARGET_REGISTER_CLASS#define TARGET_BRANCH_TARGET_REGISTER_CLASS sh_target_reg_class#undef TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED#define TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED \ sh_optimize_target_register_callee_saved#undef TARGET_MS_BITFIELD_LAYOUT_P#define TARGET_MS_BITFIELD_LAYOUT_P sh_ms_bitfield_layout_p#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS sh_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN sh_expand_builtin#undef TARGET_FUNCTION_OK_FOR_SIBCALL#define TARGET_FUNCTION_OK_FOR_SIBCALL sh_function_ok_for_sibcall#undef TARGET_CANNOT_COPY_INSN_P#define TARGET_CANNOT_COPY_INSN_P sh_cannot_copy_insn_p#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS sh_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST sh_address_cost#undef TARGET_MACHINE_DEPENDENT_REORG#define TARGET_MACHINE_DEPENDENT_REORG sh_reorg#ifdef HAVE_AS_TLS#undef TARGET_HAVE_TLS#define TARGET_HAVE_TLS true#endif#undef TARGET_PROMOTE_PROTOTYPES#define TARGET_PROMOTE_PROTOTYPES sh_promote_prototypes#undef TARGET_PROMOTE_FUNCTION_ARGS#define TARGET_PROMOTE_FUNCTION_ARGS sh_promote_prototypes#undef TARGET_PROMOTE_FUNCTION_RETURN#define TARGET_PROMOTE_FUNCTION_RETURN sh_promote_prototypes#undef TARGET_STRUCT_VALUE_RTX#define TARGET_STRUCT_VALUE_RTX sh_struct_value_rtx#undef TARGET_RETURN_IN_MEMORY#define TARGET_RETURN_IN_MEMORY sh_return_in_memory#undef TARGET_EXPAND_BUILTIN_SAVEREGS

⌨️ 快捷键说明

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