📄 rs6000.c
字号:
/* Subroutines used for code generation on IBM RS/6000. Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the 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 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#include "config.h"#include "system.h"#include "coretypes.h"#include "tm.h"#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-attr.h"#include "flags.h"#include "recog.h"#include "obstack.h"#include "tree.h"#include "expr.h"#include "optabs.h"#include "except.h"#include "function.h"#include "output.h"#include "basic-block.h"#include "integrate.h"#include "toplev.h"#include "ggc.h"#include "hashtab.h"#include "tm_p.h"#include "target.h"#include "target-def.h"#include "langhooks.h"#include "reload.h"#include "cfglayout.h"#include "sched-int.h"#include "tree-gimple.h"#include "intl.h"#include "params.h"#if TARGET_XCOFF#include "xcoffout.h" /* get declarations of xcoff_*_section_name */#endif#if TARGET_MACHO#include "gstab.h" /* for N_SLINE */#endif#ifndef TARGET_NO_PROTOTYPE#define TARGET_NO_PROTOTYPE 0#endif#define min(A,B) ((A) < (B) ? (A) : (B))#define max(A,B) ((A) > (B) ? (A) : (B))/* Structure used to define the rs6000 stack */typedef struct rs6000_stack { int first_gp_reg_save; /* first callee saved GP register used */ int first_fp_reg_save; /* first callee saved FP register used */ int first_altivec_reg_save; /* first callee saved AltiVec register used */ int lr_save_p; /* true if the link reg needs to be saved */ int cr_save_p; /* true if the CR reg needs to be saved */ unsigned int vrsave_mask; /* mask of vec registers to save */ int toc_save_p; /* true if the TOC needs to be saved */ int push_p; /* true if we need to allocate stack space */ int calls_p; /* true if the function makes any calls */ int world_save_p; /* true if we're saving *everything*: r13-r31, cr, f14-f31, vrsave, v20-v31 */ enum rs6000_abi abi; /* which ABI to use */ int gp_save_offset; /* offset to save GP regs from initial SP */ int fp_save_offset; /* offset to save FP regs from initial SP */ int altivec_save_offset; /* offset to save AltiVec regs from initial SP */ int lr_save_offset; /* offset to save LR from initial SP */ int cr_save_offset; /* offset to save CR from initial SP */ int vrsave_save_offset; /* offset to save VRSAVE from initial SP */ int spe_gp_save_offset; /* offset to save spe 64-bit gprs */ int toc_save_offset; /* offset to save the TOC pointer */ int varargs_save_offset; /* offset to save the varargs registers */ int ehrd_offset; /* offset to EH return data */ int reg_size; /* register size (4 or 8) */ HOST_WIDE_INT vars_size; /* variable save area size */ int parm_size; /* outgoing parameter size */ int save_size; /* save area size */ int fixed_size; /* fixed size of stack frame */ int gp_size; /* size of saved GP registers */ int fp_size; /* size of saved FP registers */ int altivec_size; /* size of saved AltiVec registers */ int cr_size; /* size to hold CR if not in save_size */ int lr_size; /* size to hold LR if not in save_size */ int vrsave_size; /* size to hold VRSAVE if not in save_size */ int altivec_padding_size; /* size of altivec alignment padding if not in save_size */ int spe_gp_size; /* size of 64-bit GPR save size for SPE */ int spe_padding_size; int toc_size; /* size to hold TOC if not in save_size */ HOST_WIDE_INT total_size; /* total bytes allocated for stack */ int spe_64bit_regs_used;} rs6000_stack_t;/* A C structure for machine-specific, per-function data. This is added to the cfun structure. */typedef struct machine_function GTY(()){ /* Flags if __builtin_return_address (n) with n >= 1 was used. */ int ra_needs_full_frame; /* Some local-dynamic symbol. */ const char *some_ld_name; /* Whether the instruction chain has been scanned already. */ int insn_chain_scanned_p; /* Flags if __builtin_return_address (0) was used. */ int ra_need_lr; /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4 varargs save area. */ HOST_WIDE_INT varargs_save_offset;} machine_function;/* Target cpu type */enum processor_type rs6000_cpu;struct rs6000_cpu_select rs6000_select[3] ={ /* switch name, tune arch */ { (const char *)0, "--with-cpu=", 1, 1 }, { (const char *)0, "-mcpu=", 1, 1 }, { (const char *)0, "-mtune=", 1, 0 },};/* Always emit branch hint bits. */static GTY(()) bool rs6000_always_hint;/* Schedule instructions for group formation. */static GTY(()) bool rs6000_sched_groups;/* Support for -msched-costly-dep option. */const char *rs6000_sched_costly_dep_str;enum rs6000_dependence_cost rs6000_sched_costly_dep;/* Support for -minsert-sched-nops option. */const char *rs6000_sched_insert_nops_str;enum rs6000_nop_insertion rs6000_sched_insert_nops;/* Support targetm.vectorize.builtin_mask_for_load. */static GTY(()) tree altivec_builtin_mask_for_load;/* Size of long double. */int rs6000_long_double_type_size;/* IEEE quad extended precision long double. */int rs6000_ieeequad;/* Whether -mabi=altivec has appeared. */int rs6000_altivec_abi;/* Nonzero if we want SPE ABI extensions. */int rs6000_spe_abi;/* Nonzero if floating point operations are done in the GPRs. */int rs6000_float_gprs = 0;/* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */int rs6000_darwin64_abi;/* Set to nonzero once AIX common-mode calls have been defined. */static GTY(()) int common_mode_defined;/* Save information from a "cmpxx" operation until the branch or scc is emitted. */rtx rs6000_compare_op0, rs6000_compare_op1;int rs6000_compare_fp_p;/* Label number of label created for -mrelocatable, to call to so we can get the address of the GOT section */int rs6000_pic_labelno;#ifdef USING_ELFOS_H/* Which abi to adhere to */const char *rs6000_abi_name;/* Semantics of the small data area */enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;/* Which small data model to use */const char *rs6000_sdata_name = (char *)0;/* Counter for labels which are to be placed in .fixup. */int fixuplabelno = 0;#endif/* Bit size of immediate TLS offsets and string from which it is decoded. */int rs6000_tls_size = 32;const char *rs6000_tls_size_string;/* ABI enumeration available for subtarget to use. */enum rs6000_abi rs6000_current_abi;/* Whether to use variant of AIX ABI for PowerPC64 Linux. */int dot_symbols;/* Debug flags */const char *rs6000_debug_name;int rs6000_debug_stack; /* debug stack applications */int rs6000_debug_arg; /* debug argument handling *//* Value is TRUE if register/mode pair is acceptable. */bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];/* Built in types. */tree rs6000_builtin_types[RS6000_BTI_MAX];tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];const char *rs6000_traceback_name;static enum { traceback_default = 0, traceback_none, traceback_part, traceback_full} rs6000_traceback;/* Flag to say the TOC is initialized */int toc_initialized;char toc_label_name[10];/* Alias set for saves and restores from the rs6000 stack. */static GTY(()) int rs6000_sr_alias_set;/* Control alignment for fields within structures. *//* String from -malign-XXXXX. */int rs6000_alignment_flags;/* True for any options that were explicitly set. */struct { bool aix_struct_ret; /* True if -maix-struct-ret was used. */ bool alignment; /* True if -malign- was used. */ bool abi; /* True if -mabi= was used. */ bool spe; /* True if -mspe= was used. */ bool float_gprs; /* True if -mfloat-gprs= was used. */ bool isel; /* True if -misel was used. */ bool long_double; /* True if -mlong-double- was used. */} rs6000_explicit_options;struct builtin_description{ /* mask is not const because we're going to alter it below. This nonsense will go away when we rewrite the -march infrastructure to give us more target flag bits. */ unsigned int mask; const enum insn_code icode; const char *const name; const enum rs6000_builtins code;};/* Target cpu costs. */struct processor_costs { const int mulsi; /* cost of SImode multiplication. */ const int mulsi_const; /* cost of SImode multiplication by constant. */ const int mulsi_const9; /* cost of SImode mult by short constant. */ const int muldi; /* cost of DImode multiplication. */ const int divsi; /* cost of SImode division. */ const int divdi; /* cost of DImode division. */ const int fp; /* cost of simple SFmode and DFmode insns. */ const int dmul; /* cost of DFmode multiplication (and fmadd). */ const int sdiv; /* cost of SFmode division (fdivs). */ const int ddiv; /* cost of DFmode division (fdiv). */};const struct processor_costs *rs6000_cost;/* Processor costs (relative to an add) *//* Instruction size costs on 32bit processors. */static conststruct processor_costs size32_cost = { COSTS_N_INSNS (1), /* mulsi */ COSTS_N_INSNS (1), /* mulsi_const */ COSTS_N_INSNS (1), /* mulsi_const9 */ COSTS_N_INSNS (1), /* muldi */ COSTS_N_INSNS (1), /* divsi */ COSTS_N_INSNS (1), /* divdi */ COSTS_N_INSNS (1), /* fp */ COSTS_N_INSNS (1), /* dmul */ COSTS_N_INSNS (1), /* sdiv */ COSTS_N_INSNS (1), /* ddiv */};/* Instruction size costs on 64bit processors. */static conststruct processor_costs size64_cost = { COSTS_N_INSNS (1), /* mulsi */ COSTS_N_INSNS (1), /* mulsi_const */ COSTS_N_INSNS (1), /* mulsi_const9 */ COSTS_N_INSNS (1), /* muldi */ COSTS_N_INSNS (1), /* divsi */ COSTS_N_INSNS (1), /* divdi */ COSTS_N_INSNS (1), /* fp */ COSTS_N_INSNS (1), /* dmul */ COSTS_N_INSNS (1), /* sdiv */ COSTS_N_INSNS (1), /* ddiv */};/* Instruction costs on RIOS1 processors. */static conststruct processor_costs rios1_cost = { COSTS_N_INSNS (5), /* mulsi */ COSTS_N_INSNS (4), /* mulsi_const */ COSTS_N_INSNS (3), /* mulsi_const9 */ COSTS_N_INSNS (5), /* muldi */ COSTS_N_INSNS (19), /* divsi */ COSTS_N_INSNS (19), /* divdi */ COSTS_N_INSNS (2), /* fp */ COSTS_N_INSNS (2), /* dmul */ COSTS_N_INSNS (19), /* sdiv */ COSTS_N_INSNS (19), /* ddiv */};/* Instruction costs on RIOS2 processors. */static conststruct processor_costs rios2_cost = { COSTS_N_INSNS (2), /* mulsi */ COSTS_N_INSNS (2), /* mulsi_const */ COSTS_N_INSNS (2), /* mulsi_const9 */ COSTS_N_INSNS (2), /* muldi */ COSTS_N_INSNS (13), /* divsi */ COSTS_N_INSNS (13), /* divdi */ COSTS_N_INSNS (2), /* fp */ COSTS_N_INSNS (2), /* dmul */ COSTS_N_INSNS (17), /* sdiv */ COSTS_N_INSNS (17), /* ddiv */};/* Instruction costs on RS64A processors. */static conststruct processor_costs rs64a_cost = { COSTS_N_INSNS (20), /* mulsi */ COSTS_N_INSNS (12), /* mulsi_const */ COSTS_N_INSNS (8), /* mulsi_const9 */ COSTS_N_INSNS (34), /* muldi */ COSTS_N_INSNS (65), /* divsi */ COSTS_N_INSNS (67), /* divdi */ COSTS_N_INSNS (4), /* fp */ COSTS_N_INSNS (4), /* dmul */ COSTS_N_INSNS (31), /* sdiv */ COSTS_N_INSNS (31), /* ddiv */};/* Instruction costs on MPCCORE processors. */static conststruct processor_costs mpccore_cost = { COSTS_N_INSNS (2), /* mulsi */ COSTS_N_INSNS (2), /* mulsi_const */ COSTS_N_INSNS (2), /* mulsi_const9 */ COSTS_N_INSNS (2), /* muldi */ COSTS_N_INSNS (6), /* divsi */ COSTS_N_INSNS (6), /* divdi */ COSTS_N_INSNS (4), /* fp */ COSTS_N_INSNS (5), /* dmul */ COSTS_N_INSNS (10), /* sdiv */ COSTS_N_INSNS (17), /* ddiv */};/* Instruction costs on PPC403 processors. */static conststruct processor_costs ppc403_cost = { COSTS_N_INSNS (4), /* mulsi */ COSTS_N_INSNS (4), /* mulsi_const */ COSTS_N_INSNS (4), /* mulsi_const9 */ COSTS_N_INSNS (4), /* muldi */ COSTS_N_INSNS (33), /* divsi */ COSTS_N_INSNS (33), /* divdi */ COSTS_N_INSNS (11), /* fp */ COSTS_N_INSNS (11), /* dmul */ COSTS_N_INSNS (11), /* sdiv */ COSTS_N_INSNS (11), /* ddiv */};/* Instruction costs on PPC405 processors. */static conststruct processor_costs ppc405_cost = { COSTS_N_INSNS (5), /* mulsi */ COSTS_N_INSNS (4), /* mulsi_const */ COSTS_N_INSNS (3), /* mulsi_const9 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -