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

📄 rs6000.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines used for code generation on IBM RS/6000.   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,    2000, 2001, 2002, 2003 Free Software Foundation, Inc.   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)This file is part of GNU CC.GNU CC 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.GNU CC 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 GNU CC; 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 "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"#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))/* 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 },};/* 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;/* Nonzero if we have FPRs.  */int rs6000_fprs = 1;/* String from -misel=.  */const char *rs6000_isel_string;/* Set to nonzero once AIX common-mode calls have been defined.  */static int common_mode_defined;/* Private copy of original value of flag_pic for ABI_AIX.  */static int rs6000_flag_pic;/* 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 = 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/* ABI enumeration available for subtarget to use.  */enum rs6000_abi rs6000_current_abi;/* ABI string from -mabi= option.  */const char *rs6000_abi_string;/* Debug flags */const char *rs6000_debug_name;int rs6000_debug_stack;		/* debug stack applications */int rs6000_debug_arg;		/* debug argument handling */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 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;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;};static void rs6000_add_gc_roots PARAMS ((void));static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));static void validate_condition_mode   PARAMS ((enum rtx_code, enum machine_mode));static rtx rs6000_generate_compare PARAMS ((enum rtx_code));static void rs6000_maybe_dead PARAMS ((rtx));static void rs6000_emit_stack_tie PARAMS ((void));static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,				     unsigned int, int, int));static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));static unsigned rs6000_hash_constant PARAMS ((rtx));static unsigned toc_hash_function PARAMS ((const void *));static int toc_hash_eq PARAMS ((const void *, const void *));static int toc_hash_mark_entry PARAMS ((void **, void *));static void toc_hash_mark_table PARAMS ((void *));static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));static struct machine_function * rs6000_init_machine_status PARAMS ((void));static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));#ifdef HAVE_GAS_HIDDENstatic void rs6000_assemble_visibility PARAMS ((tree, int));#endifstatic int rs6000_ra_ever_killed PARAMS ((void));static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));const struct attribute_spec rs6000_attribute_table[];static void rs6000_set_default_type_attributes PARAMS ((tree));static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,					    HOST_WIDE_INT, tree));static rtx rs6000_emit_set_long_const PARAMS ((rtx,  HOST_WIDE_INT, HOST_WIDE_INT));#if TARGET_ELFstatic unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,							   int));static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));static void rs6000_elf_select_section PARAMS ((tree, int,						 unsigned HOST_WIDE_INT));static void rs6000_elf_unique_section PARAMS ((tree, int));static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,						   unsigned HOST_WIDE_INT));static void rs6000_elf_encode_section_info PARAMS ((tree, int))     ATTRIBUTE_UNUSED;static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));static bool rs6000_elf_in_small_data_p PARAMS ((tree));#endif#if TARGET_XCOFFstatic void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));static void rs6000_xcoff_select_section PARAMS ((tree, int,						 unsigned HOST_WIDE_INT));static void rs6000_xcoff_unique_section PARAMS ((tree, int));static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,						     unsigned HOST_WIDE_INT));static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));#endifstatic void rs6000_xcoff_encode_section_info PARAMS ((tree, int))     ATTRIBUTE_UNUSED;static bool rs6000_binds_local_p PARAMS ((tree));static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));static int rs6000_adjust_priority PARAMS ((rtx, int));static int rs6000_issue_rate PARAMS ((void));static void rs6000_init_builtins PARAMS ((void));static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));static void altivec_init_builtins PARAMS ((void));static void rs6000_common_init_builtins PARAMS ((void));static void enable_mask_for_builtins PARAMS ((struct builtin_description *,					      int, enum rs6000_builtins,					      enum rs6000_builtins));static void spe_init_builtins PARAMS ((void));static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));static void rs6000_parse_abi_options PARAMS ((void));static void rs6000_parse_vrsave_option PARAMS ((void));static void rs6000_parse_isel_option PARAMS ((void));static int first_altivec_reg_to_save PARAMS ((void));static unsigned int compute_vrsave_mask PARAMS ((void));static void is_altivec_return_reg PARAMS ((rtx, void *));static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));static int easy_vector_constant PARAMS ((rtx));/* Default register names.  */char rs6000_reg_names[][8] ={      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",      "8",  "9", "10", "11", "12", "13", "14", "15",     "16", "17", "18", "19", "20", "21", "22", "23",     "24", "25", "26", "27", "28", "29", "30", "31",      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",      "8",  "9", "10", "11", "12", "13", "14", "15",     "16", "17", "18", "19", "20", "21", "22", "23",     "24", "25", "26", "27", "28", "29", "30", "31",     "mq", "lr", "ctr","ap",      "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",      "xer",      /* AltiVec registers.  */      "0",  "1",  "2",  "3",  "4",  "5",  "6", "7",      "8",  "9",  "10", "11", "12", "13", "14", "15",      "16", "17", "18", "19", "20", "21", "22", "23",      "24", "25", "26", "27", "28", "29", "30", "31",      "vrsave", "vscr",      /* SPE registers.  */      "spe_acc", "spefscr"};#ifdef TARGET_REGNAMESstatic const char alt_reg_names[][8] ={   "%r0",   "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",   "%r8",   "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",  "%r16",  "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",  "%r24",  "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",   "%f0",   "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",   "%f8",   "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",  "%f16",  "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",  "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",    "mq",    "lr",  "ctr",   "ap",  "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",   "xer",  /* AltiVec registers.  */   "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6", "%v7",   "%v8",  "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",  "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",  "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",  "vrsave", "vscr",  /* SPE registers.  */  "spe_acc", "spefscr"};#endif#ifndef MASK_STRICT_ALIGN#define MASK_STRICT_ALIGN 0#endif/* The VRSAVE bitmask puts bit %v0 as the most significant bit.  */#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))/* Initialize the GCC target structure.  */#undef TARGET_ATTRIBUTE_TABLE#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes#undef TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP/* Default unaligned ops are only provided for ELF.  Find the ops needed   for non-ELF systems.  */#ifndef OBJECT_FORMAT_ELF#if TARGET_XCOFF/* For XCOFF.  rs6000_assemble_integer will handle unaligned DIs on   64-bit targets.  */#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"#undef TARGET_ASM_UNALIGNED_DI_OP#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"#else/* For Darwin.  */#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"#endif#endif/* This hook deals with fixups for relocatable code and DI-mode objects   in 64-bit code.  */#undef TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER rs6000_assemble_integer#ifdef HAVE_GAS_HIDDEN#undef TARGET_ASM_ASSEMBLE_VISIBILITY#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility#endif#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate#undef TARGET_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost#undef TARGET_SCHED_ADJUST_PRIORITY#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS rs6000_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin#undef TARGET_BINDS_LOCAL_P#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk/* ??? Should work everywhere, but ask dje@watson.ibm.com before   enabling for AIX.  */#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall#endifstruct gcc_target targetm = TARGET_INITIALIZER;/* Override command line options.  Mostly we process the processor   type and sometimes adjust other TARGET_ options.  */voidrs6000_override_options (default_cpu)     const char *default_cpu;{  size_t i, j;  struct rs6000_cpu_select *ptr;  /* Simplify the entries below by making a mask for any POWER     variant and any PowerPC variant.  */#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \		       | MASK_PPC_GFXOPT | MASK_POWERPC64)#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)  static struct ptt    {      const char *const name;		/* Canonical processor name.  */      const enum processor_type processor; /* Processor type enum value.  */      const int target_enable;	/* Target flags to enable.  */      const int target_disable;	/* Target flags to disable.  */    } const processor_target_table[]      = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_MASKS},	 {"power", PROCESSOR_POWER,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"power2", PROCESSOR_POWER,	    MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,	    POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"power3", PROCESSOR_PPC630,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT},	 {"power4", PROCESSOR_POWER4,	    MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,	    POWER_MASKS | MASK_PPC_GPOPT},	 {"powerpc", PROCESSOR_POWERPC,	    MASK_POWERPC | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},	 {"powerpc64", PROCESSOR_POWERPC64,	    MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,	    POWER_MASKS | POWERPC_OPT_MASKS},	 {"rios", PROCESSOR_RIOS1,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rios1", PROCESSOR_RIOS1,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rsc", PROCESSOR_PPC601,	    MASK_POWER | MASK_MULTIPLE | MASK_STRING,	    MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},	 {"rsc1", PROCESSOR_PPC601,

⌨️ 快捷键说明

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