📄 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 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, 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 "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"/* APPLE LOCAL 3893112 */#include "params.h"/* APPLE LOCAL mainline 2005-04-14 */#include "intl.h"#if TARGET_XCOFF#include "xcoffout.h" /* get declarations of xcoff_*_section_name */#endif#if TARGET_MACHO#include "gstab.h" /* for N_SLINE */#endif/* APPLE LOCAL begin pascal strings */#include "../../libcpp/internal.h"extern struct cpp_reader* parse_in;/* APPLE LOCAL end pascal strings *//* APPLE LOCAL begin Macintosh alignment */#ifndef TARGET_ALIGN_MAC68K#define TARGET_ALIGN_MAC68K 0#endif/* APPLE LOCAL end Macintosh alignment */#ifndef TARGET_NO_PROTOTYPE#define TARGET_NO_PROTOTYPE 0#endif#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)#define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e && !((n) & 1))#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) */ int varargs_size; /* size to hold V.4 args passed in regs */ 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;/* 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 adjust_priority scheduler hook and -mprioritize-restricted-insns= option. */const char *rs6000_sched_restricted_insns_priority_str;int rs6000_sched_restricted_insns_priority;/* 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 */const char *rs6000_long_double_size_string;int rs6000_long_double_type_size;/* Whether -mabi=altivec has appeared */int rs6000_altivec_abi;/* Whether VRSAVE instructions should be generated. */int rs6000_altivec_vrsave;/* String from -mvrsave= option. */const char *rs6000_altivec_vrsave_string;/* Nonzero if we want SPE ABI extensions. */int rs6000_spe_abi;/* Whether isel instructions should be generated. */int rs6000_isel;/* Whether SPE simd instructions should be generated. */int rs6000_spe;/* 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;/* String from -mfloat-gprs=. */const char *rs6000_float_gprs_string;/* String from -misel=. */const char *rs6000_isel_string;/* String from -mspe=. */const char *rs6000_spe_string;/* 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;/* ABI string from -mabi= option. */const char *rs6000_abi_string;/* 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 accepatable. */bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];/* Opaque types. */static GTY(()) tree opaque_V2SI_type_node;static GTY(()) tree opaque_V2SF_type_node;static GTY(()) tree opaque_p_V2SI_type_node;static GTY(()) tree V16QI_type_node;static GTY(()) tree V2SI_type_node;static GTY(()) tree V2SF_type_node;static GTY(()) tree V4HI_type_node;static GTY(()) tree V4SI_type_node;static GTY(()) tree V4SF_type_node;static GTY(()) tree V8HI_type_node;static GTY(()) tree unsigned_V16QI_type_node;static GTY(()) tree unsigned_V8HI_type_node;static GTY(()) tree unsigned_V4SI_type_node;static GTY(()) tree bool_char_type_node; /* __bool char */static GTY(()) tree bool_short_type_node; /* __bool short */static GTY(()) tree bool_int_type_node; /* __bool int */static GTY(()) tree pixel_type_node; /* __pixel */static GTY(()) tree bool_V16QI_type_node; /* __vector __bool char */static GTY(()) tree bool_V8HI_type_node; /* __vector __bool short */static GTY(()) tree bool_V4SI_type_node; /* __vector __bool int */static GTY(()) tree pixel_V8HI_type_node; /* __vector __pixel */int rs6000_warn_altivec_long = 1; /* On by default. */const char *rs6000_warn_altivec_long_switch;/* APPLE LOCAL begin AltiVec */int rs6000_altivec_pim = 0;const char *rs6000_altivec_pim_switch;/* APPLE LOCAL end AltiVec */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;/* Call distance, overridden by -mlongcall and #pragma longcall(1). The only place that looks at this is rs6000_set_default_type_attributes; everywhere else should rely on the presence or absence of a longcall attribute on the function declaration. Exception: init_cumulative_args looks at it too, for libcalls. */int rs6000_default_long_calls;const char *rs6000_longcall_switch;/* Control alignment for fields within structures. *//* String from -malign-XXXXX. */const char *rs6000_alignment_string;int rs6000_alignment_flags;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. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -