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

📄 s390.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines used for code generation on IBM S/390 and zSeries   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005   Free Software Foundation, Inc.   Contributed by Hartmut Penner (hpenner@de.ibm.com) and                  Ulrich Weigand (uweigand@de.ibm.com).This file is part of GCC.GCC is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.GCC is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public Licensealong with GCC; see the file COPYING.  If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.  */#include "config.h"#include "system.h"#include "coretypes.h"#include "tm.h"#include "rtl.h"#include "tree.h"#include "tm_p.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 "except.h"#include "function.h"#include "recog.h"#include "expr.h"#include "reload.h"#include "toplev.h"#include "basic-block.h"#include "integrate.h"#include "ggc.h"#include "target.h"#include "target-def.h"#include "debug.h"#include "langhooks.h"#include "optabs.h"#include "tree-gimple.h"/* Machine-specific symbol_ref flags.  */#define SYMBOL_FLAG_ALIGN1	(SYMBOL_FLAG_MACH_DEP << 0)static bool s390_assemble_integer (rtx, unsigned int, int);static void s390_encode_section_info (tree, rtx, int);static bool s390_cannot_force_const_mem (rtx);static rtx s390_delegitimize_address (rtx);static bool s390_return_in_memory (tree, tree);static void s390_init_builtins (void);static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,				  HOST_WIDE_INT, tree);static enum attr_type s390_safe_attr_type (rtx);static int s390_adjust_priority (rtx, int);static int s390_issue_rate (void);static int s390_first_cycle_multipass_dfa_lookahead (void);static bool s390_cannot_copy_insn_p (rtx);static bool s390_rtx_costs (rtx, int, int, int *);static int s390_address_cost (rtx);static void s390_reorg (void);static bool s390_valid_pointer_mode (enum machine_mode);static tree s390_build_builtin_va_list (void);static tree s390_gimplify_va_arg (tree, tree, tree *, tree *);static bool s390_function_ok_for_sibcall (tree, tree);static bool s390_call_saved_register_used (tree);static bool s390_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,				    tree, bool);static bool s390_fixed_condition_code_regs (unsigned int *, unsigned int *);static enum machine_mode s390_cc_modes_compatible (enum machine_mode, 						   enum machine_mode);/* Define the specific costs for a given cpu.  */struct processor_costs {  /* multiplication */  const int m;        /* cost of an M instruction.  */  const int mghi;     /* cost of an MGHI instruction.  */  const int mh;       /* cost of an MH instruction.  */  const int mhi;      /* cost of an MHI instruction.  */  const int ml;       /* cost of an ML instruction.  */  const int mr;       /* cost of an MR instruction.  */  const int ms;       /* cost of an MS instruction.  */  const int msg;      /* cost of an MSG instruction.  */  const int msgf;     /* cost of an MSGF instruction.  */  const int msgfr;    /* cost of an MSGFR instruction.  */  const int msgr;     /* cost of an MSGR instruction.  */  const int msr;      /* cost of an MSR instruction.  */  const int mult_df;  /* cost of multiplication in DFmode.  */  /* square root */  const int sqdbr;    /* cost of square root in DFmode.  */  const int sqebr;    /* cost of square root in SFmode.  */  /* multiply and add */  const int madbr;    /* cost of multiply and add in DFmode.  */  const int maebr;    /* cost of multiply and add in SFmode.  */  /* division */  const int ddbr;  const int ddr;  const int debr;  const int der;  const int dlgr;  const int dlr;  const int dr;  const int dsgfr;  const int dsgr;};const struct processor_costs *s390_cost;static conststruct processor_costs z900_cost = {  COSTS_N_INSNS (5),     /* M     */  COSTS_N_INSNS (10),    /* MGHI  */  COSTS_N_INSNS (5),     /* MH    */  COSTS_N_INSNS (4),     /* MHI   */  COSTS_N_INSNS (5),     /* ML    */  COSTS_N_INSNS (5),     /* MR    */  COSTS_N_INSNS (4),     /* MS    */  COSTS_N_INSNS (15),    /* MSG   */  COSTS_N_INSNS (7),     /* MSGF  */  COSTS_N_INSNS (7),     /* MSGFR */  COSTS_N_INSNS (10),    /* MSGR  */  COSTS_N_INSNS (4),     /* MSR   */  COSTS_N_INSNS (7),     /* multiplication in DFmode */  COSTS_N_INSNS (44),    /* SQDBR */  COSTS_N_INSNS (35),    /* SQEBR */  COSTS_N_INSNS (18),    /* MADBR */  COSTS_N_INSNS (13),    /* MAEBR */  COSTS_N_INSNS (30),    /* DDBR */  COSTS_N_INSNS (30),    /* DDR  */  COSTS_N_INSNS (27),    /* DEBR */  COSTS_N_INSNS (26),    /* DER  */  COSTS_N_INSNS (220),   /* DLGR */  COSTS_N_INSNS (34),    /* DLR */  COSTS_N_INSNS (34),    /* DR */  COSTS_N_INSNS (32),    /* DSGFR */  COSTS_N_INSNS (32),    /* DSGR */};static conststruct processor_costs z990_cost = {  COSTS_N_INSNS (4),     /* M     */  COSTS_N_INSNS (2),     /* MGHI  */  COSTS_N_INSNS (2),     /* MH    */  COSTS_N_INSNS (2),     /* MHI   */  COSTS_N_INSNS (4),     /* ML    */  COSTS_N_INSNS (4),     /* MR    */  COSTS_N_INSNS (5),     /* MS    */  COSTS_N_INSNS (6),     /* MSG   */  COSTS_N_INSNS (4),     /* MSGF  */  COSTS_N_INSNS (4),     /* MSGFR */  COSTS_N_INSNS (4),     /* MSGR  */  COSTS_N_INSNS (4),     /* MSR   */  COSTS_N_INSNS (1),     /* multiplication in DFmode */  COSTS_N_INSNS (66),    /* SQDBR */  COSTS_N_INSNS (38),    /* SQEBR */  COSTS_N_INSNS (1),     /* MADBR */  COSTS_N_INSNS (1),     /* MAEBR */  COSTS_N_INSNS (40),    /* DDBR */  COSTS_N_INSNS (44),    /* DDR  */  COSTS_N_INSNS (26),    /* DDBR */  COSTS_N_INSNS (28),    /* DER  */  COSTS_N_INSNS (176),   /* DLGR */  COSTS_N_INSNS (31),    /* DLR */  COSTS_N_INSNS (31),    /* DR */  COSTS_N_INSNS (31),    /* DSGFR */  COSTS_N_INSNS (31),    /* DSGR */};#undef  TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"#undef  TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"#undef  TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER s390_assemble_integer#undef  TARGET_ASM_OPEN_PAREN#define TARGET_ASM_OPEN_PAREN ""#undef  TARGET_ASM_CLOSE_PAREN#define TARGET_ASM_CLOSE_PAREN ""#undef	TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info#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 s390_cannot_force_const_mem#undef TARGET_DELEGITIMIZE_ADDRESS#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address#undef TARGET_RETURN_IN_MEMORY#define TARGET_RETURN_IN_MEMORY s390_return_in_memory#undef  TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS s390_init_builtins#undef  TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN s390_expand_builtin#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK s390_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_SCHED_ADJUST_PRIORITY#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE s390_issue_rate#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead#undef TARGET_CANNOT_COPY_INSN_P#define TARGET_CANNOT_COPY_INSN_P s390_cannot_copy_insn_p#undef TARGET_RTX_COSTS#define TARGET_RTX_COSTS s390_rtx_costs#undef TARGET_ADDRESS_COST#define TARGET_ADDRESS_COST s390_address_cost#undef TARGET_MACHINE_DEPENDENT_REORG#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg#undef TARGET_VALID_POINTER_MODE#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode#undef TARGET_BUILD_BUILTIN_VA_LIST#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list#undef TARGET_GIMPLIFY_VA_ARG_EXPR#define TARGET_GIMPLIFY_VA_ARG_EXPR s390_gimplify_va_arg#undef TARGET_PROMOTE_FUNCTION_ARGS#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true#undef TARGET_PROMOTE_FUNCTION_RETURN#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true#undef TARGET_PASS_BY_REFERENCE#define TARGET_PASS_BY_REFERENCE s390_pass_by_reference#undef TARGET_FUNCTION_OK_FOR_SIBCALL#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall#undef TARGET_FIXED_CONDITION_CODE_REGS#define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs#undef TARGET_CC_MODES_COMPATIBLE#define TARGET_CC_MODES_COMPATIBLE s390_cc_modes_compatiblestruct gcc_target targetm = TARGET_INITIALIZER;extern int reload_completed;/* The alias set for prologue/epilogue register save/restore.  */static int s390_sr_alias_set = 0;/* Save information from a "cmpxx" operation until the branch or scc is   emitted.  */rtx s390_compare_op0, s390_compare_op1;/* Structure used to hold the components of a S/390 memory   address.  A legitimate address on S/390 is of the general   form          base + index + displacement   where any of the components is optional.   base and index are registers of the class ADDR_REGS,   displacement is an unsigned 12-bit immediate constant.  */struct s390_address{  rtx base;  rtx indx;  rtx disp;  int pointer;};/* Which cpu are we tuning for.  */enum processor_type s390_tune;enum processor_flags s390_tune_flags;/* Which instruction set architecture to use.  */enum processor_type s390_arch;enum processor_flags s390_arch_flags;/* Strings to hold which cpu and instruction set architecture  to use.  */const char *s390_tune_string;		/* for -mtune=<xxx> */const char *s390_arch_string;		/* for -march=<xxx> */const char *s390_warn_framesize_string;const char *s390_warn_dynamicstack_string;const char *s390_stack_size_string;const char *s390_stack_guard_string;HOST_WIDE_INT s390_warn_framesize = 0;bool s390_warn_dynamicstack_p = 0;HOST_WIDE_INT s390_stack_size = 0;HOST_WIDE_INT s390_stack_guard = 0;/* The following structure is embedded in the machine    specific part of struct function.  */struct s390_frame_layout GTY (()){  /* Offset within stack frame.  */  HOST_WIDE_INT gprs_offset;  HOST_WIDE_INT f0_offset;  HOST_WIDE_INT f4_offset;  HOST_WIDE_INT f8_offset;  HOST_WIDE_INT backchain_offset;    /* Number of first and last gpr to be saved, restored.  */  int first_save_gpr;  int first_restore_gpr;  int last_save_gpr;  int last_restore_gpr;  /* Bits standing for floating point registers. Set, if the      respective register has to be saved. Starting with reg 16 (f0)      at the rightmost bit.     Bit 15 -  8  7  6  5  4  3  2  1  0     fpr 15 -  8  7  5  3  1  6  4  2  0     reg 31 - 24 23 22 21 20 19 18 17 16  */  unsigned int fpr_bitmap;  /* Number of floating point registers f8-f15 which must be saved.  */  int high_fprs;  /* Set if return address needs to be saved.  */  bool save_return_addr_p;  /* Size of stack frame.  */  HOST_WIDE_INT frame_size;};/* Define the structure for the machine field in struct function.  */struct machine_function GTY(()){  struct s390_frame_layout frame_layout;  /* Literal pool base register.  */  rtx base_reg;  /* True if we may need to perform branch splitting.  */  bool split_branches_pending_p;  /* Some local-dynamic TLS symbol name.  */  const char *some_ld_name;};/* Few accessor macros for struct cfun->machine->s390_frame_layout.  */#define cfun_frame_layout (cfun->machine->frame_layout)#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr -           \  cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)#define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |=    \  (1 << (BITNUM)))#define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap &    \  (1 << (BITNUM))))static int s390_match_ccmode_set (rtx, enum machine_mode);static int s390_branch_condition_mask (rtx);static const char *s390_branch_condition_mnemonic (rtx, int);static int check_mode (rtx, enum machine_mode *);static int s390_short_displacement (rtx);static int s390_decompose_address (rtx, struct s390_address *);static rtx get_thread_pointer (void);static rtx legitimize_tls_address (rtx, rtx);static void print_shift_count_operand (FILE *, rtx);static const char *get_some_local_dynamic_name (void);static int get_some_local_dynamic_name_1 (rtx *, void *);static int reg_used_in_mem_p (int, rtx);static int addr_generation_dependency_p (rtx, rtx);static int s390_split_branches (void);static void annotate_constant_pool_refs (rtx *x);static void find_constant_pool_ref (rtx, rtx *);static void replace_constant_pool_ref (rtx *, rtx, rtx);static rtx find_ltrel_base (rtx);static void replace_ltrel_base (rtx *);static void s390_optimize_prologue (void);static int find_unused_clobbered_reg (void);static void s390_frame_area (int *, int *);static void s390_register_info (int []);static void s390_frame_info (void);static void s390_init_frame_layout (void);static void s390_update_frame_layout (void);static rtx save_fpr (rtx, int, int);static rtx restore_fpr (rtx, int, int);static rtx save_gprs (rtx, int, int, int);static rtx restore_gprs (rtx, int, int, int);static int s390_function_arg_size (enum machine_mode, tree);static bool s390_function_arg_float (enum machine_mode, tree);static struct machine_function * s390_init_machine_status (void);/* Check whether integer displacement is in range.  */#define DISP_IN_RANGE(d) \  (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \                           : ((d) >= 0 && (d) <= 4095))/* Return true if SET either doesn't set the CC register, or else   the source and destination have matching CC modes and that   CC mode is at least as constrained as REQ_MODE.  */static ints390_match_ccmode_set (rtx set, enum machine_mode req_mode){  enum machine_mode set_mode;  if (GET_CODE (set) != SET)    abort ();  if (GET_CODE (SET_DEST (set)) != REG || !CC_REGNO_P (REGNO (SET_DEST (set))))    return 1;  set_mode = GET_MODE (SET_DEST (set));  switch (set_mode)    {    case CCSmode:    case CCSRmode:    case CCUmode:    case CCURmode:    case CCLmode:    case CCL1mode:    case CCL2mode:    case CCL3mode:    case CCT1mode:    case CCT2mode:    case CCT3mode:      if (req_mode != set_mode)        return 0;      break;    case CCZmode:      if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode	  && req_mode != CCSRmode && req_mode != CCURmode)        return 0;      break;    case CCAPmode:    case CCANmode:      if (req_mode != CCAmode)        return 0;      break;    default:      abort ();    }  return (GET_MODE (SET_SRC (set)) == set_mode);}/* Return true if every SET in INSN that sets the CC register   has source and destination with matching CC modes and that   CC mode is at least as constrained as REQ_MODE.   If REQ_MODE is VOIDmode, always return false.  */ints390_match_ccmode (rtx insn, enum machine_mode req_mode)

⌨️ 快捷键说明

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