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

📄 sparc.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines for insn-output.c for SPARC.   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.   Contributed by Michael Tiemann (tiemann@cygnus.com)   64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,   at Cygnus Support.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 "tree.h"#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "insn-codes.h"#include "conditions.h"#include "output.h"#include "insn-attr.h"#include "flags.h"#include "function.h"#include "expr.h"#include "optabs.h"#include "recog.h"#include "toplev.h"#include "ggc.h"#include "tm_p.h"#include "debug.h"#include "target.h"#include "target-def.h"#include "cfglayout.h"#include "tree-gimple.h"#include "langhooks.h"/* Processor costs */static conststruct processor_costs cypress_costs = {  COSTS_N_INSNS (2), /* int load */  COSTS_N_INSNS (2), /* int signed load */  COSTS_N_INSNS (2), /* int zeroed load */  COSTS_N_INSNS (2), /* float load */  COSTS_N_INSNS (5), /* fmov, fneg, fabs */  COSTS_N_INSNS (5), /* fadd, fsub */  COSTS_N_INSNS (1), /* fcmp */  COSTS_N_INSNS (1), /* fmov, fmovr */  COSTS_N_INSNS (7), /* fmul */  COSTS_N_INSNS (37), /* fdivs */  COSTS_N_INSNS (37), /* fdivd */  COSTS_N_INSNS (63), /* fsqrts */  COSTS_N_INSNS (63), /* fsqrtd */  COSTS_N_INSNS (1), /* imul */  COSTS_N_INSNS (1), /* imulX */  0, /* imul bit factor */  COSTS_N_INSNS (1), /* idiv */  COSTS_N_INSNS (1), /* idivX */  COSTS_N_INSNS (1), /* movcc/movr */  0, /* shift penalty */};static conststruct processor_costs supersparc_costs = {  COSTS_N_INSNS (1), /* int load */  COSTS_N_INSNS (1), /* int signed load */  COSTS_N_INSNS (1), /* int zeroed load */  COSTS_N_INSNS (0), /* float load */  COSTS_N_INSNS (3), /* fmov, fneg, fabs */  COSTS_N_INSNS (3), /* fadd, fsub */  COSTS_N_INSNS (3), /* fcmp */  COSTS_N_INSNS (1), /* fmov, fmovr */  COSTS_N_INSNS (3), /* fmul */  COSTS_N_INSNS (6), /* fdivs */  COSTS_N_INSNS (9), /* fdivd */  COSTS_N_INSNS (12), /* fsqrts */  COSTS_N_INSNS (12), /* fsqrtd */  COSTS_N_INSNS (4), /* imul */  COSTS_N_INSNS (4), /* imulX */  0, /* imul bit factor */  COSTS_N_INSNS (4), /* idiv */  COSTS_N_INSNS (4), /* idivX */  COSTS_N_INSNS (1), /* movcc/movr */  1, /* shift penalty */};static conststruct processor_costs hypersparc_costs = {  COSTS_N_INSNS (1), /* int load */  COSTS_N_INSNS (1), /* int signed load */  COSTS_N_INSNS (1), /* int zeroed load */  COSTS_N_INSNS (1), /* float load */  COSTS_N_INSNS (1), /* fmov, fneg, fabs */  COSTS_N_INSNS (1), /* fadd, fsub */  COSTS_N_INSNS (1), /* fcmp */  COSTS_N_INSNS (1), /* fmov, fmovr */  COSTS_N_INSNS (1), /* fmul */  COSTS_N_INSNS (8), /* fdivs */  COSTS_N_INSNS (12), /* fdivd */  COSTS_N_INSNS (17), /* fsqrts */  COSTS_N_INSNS (17), /* fsqrtd */  COSTS_N_INSNS (17), /* imul */  COSTS_N_INSNS (17), /* imulX */  0, /* imul bit factor */  COSTS_N_INSNS (17), /* idiv */  COSTS_N_INSNS (17), /* idivX */  COSTS_N_INSNS (1), /* movcc/movr */  0, /* shift penalty */};static conststruct processor_costs sparclet_costs = {  COSTS_N_INSNS (3), /* int load */  COSTS_N_INSNS (3), /* int signed load */  COSTS_N_INSNS (1), /* int zeroed load */  COSTS_N_INSNS (1), /* float load */  COSTS_N_INSNS (1), /* fmov, fneg, fabs */  COSTS_N_INSNS (1), /* fadd, fsub */  COSTS_N_INSNS (1), /* fcmp */  COSTS_N_INSNS (1), /* fmov, fmovr */  COSTS_N_INSNS (1), /* fmul */  COSTS_N_INSNS (1), /* fdivs */  COSTS_N_INSNS (1), /* fdivd */  COSTS_N_INSNS (1), /* fsqrts */  COSTS_N_INSNS (1), /* fsqrtd */  COSTS_N_INSNS (5), /* imul */  COSTS_N_INSNS (5), /* imulX */  0, /* imul bit factor */  COSTS_N_INSNS (5), /* idiv */  COSTS_N_INSNS (5), /* idivX */  COSTS_N_INSNS (1), /* movcc/movr */  0, /* shift penalty */};static conststruct processor_costs ultrasparc_costs = {  COSTS_N_INSNS (2), /* int load */  COSTS_N_INSNS (3), /* int signed load */  COSTS_N_INSNS (2), /* int zeroed load */  COSTS_N_INSNS (2), /* float load */  COSTS_N_INSNS (1), /* fmov, fneg, fabs */  COSTS_N_INSNS (4), /* fadd, fsub */  COSTS_N_INSNS (1), /* fcmp */  COSTS_N_INSNS (2), /* fmov, fmovr */  COSTS_N_INSNS (4), /* fmul */  COSTS_N_INSNS (13), /* fdivs */  COSTS_N_INSNS (23), /* fdivd */  COSTS_N_INSNS (13), /* fsqrts */  COSTS_N_INSNS (23), /* fsqrtd */  COSTS_N_INSNS (4), /* imul */  COSTS_N_INSNS (4), /* imulX */  2, /* imul bit factor */  COSTS_N_INSNS (37), /* idiv */  COSTS_N_INSNS (68), /* idivX */  COSTS_N_INSNS (2), /* movcc/movr */  2, /* shift penalty */};static conststruct processor_costs ultrasparc3_costs = {  COSTS_N_INSNS (2), /* int load */  COSTS_N_INSNS (3), /* int signed load */  COSTS_N_INSNS (3), /* int zeroed load */  COSTS_N_INSNS (2), /* float load */  COSTS_N_INSNS (3), /* fmov, fneg, fabs */  COSTS_N_INSNS (4), /* fadd, fsub */  COSTS_N_INSNS (5), /* fcmp */  COSTS_N_INSNS (3), /* fmov, fmovr */  COSTS_N_INSNS (4), /* fmul */  COSTS_N_INSNS (17), /* fdivs */  COSTS_N_INSNS (20), /* fdivd */  COSTS_N_INSNS (20), /* fsqrts */  COSTS_N_INSNS (29), /* fsqrtd */  COSTS_N_INSNS (6), /* imul */  COSTS_N_INSNS (6), /* imulX */  0, /* imul bit factor */  COSTS_N_INSNS (40), /* idiv */  COSTS_N_INSNS (71), /* idivX */  COSTS_N_INSNS (2), /* movcc/movr */  0, /* shift penalty */};const struct processor_costs *sparc_costs = &cypress_costs;#ifdef HAVE_AS_RELAX_OPTION/* If 'as' and 'ld' are relaxing tail call insns into branch always, use   "or %o7,%g0,X; call Y; or X,%g0,%o7" always, so that it can be optimized.   With sethi/jmp, neither 'as' nor 'ld' has an easy way how to find out if   somebody does not branch between the sethi and jmp.  */#define LEAF_SIBCALL_SLOT_RESERVED_P 1#else#define LEAF_SIBCALL_SLOT_RESERVED_P \  ((TARGET_ARCH64 && !TARGET_CM_MEDLOW) || flag_pic)#endif/* Global variables for machine-dependent things.  *//* Size of frame.  Need to know this to emit return insns from leaf procedures.   ACTUAL_FSIZE is set by sparc_compute_frame_size() which is called during the   reload pass.  This is important as the value is later used for scheduling   (to see what can go in a delay slot).   APPARENT_FSIZE is the size of the stack less the register save area and less   the outgoing argument area.  It is used when saving call preserved regs.  */static HOST_WIDE_INT apparent_fsize;static HOST_WIDE_INT actual_fsize;/* Number of live general or floating point registers needed to be   saved (as 4-byte quantities).  */static int num_gfregs;/* The alias set for prologue/epilogue register save/restore.  */static GTY(()) int sparc_sr_alias_set;/* Save the operands last given to a compare for use when we   generate a scc or bcc insn.  */rtx sparc_compare_op0, sparc_compare_op1;/* Vector to say how input registers are mapped to output registers.   HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to   eliminate it.  You must use -fomit-frame-pointer to get that.  */char leaf_reg_remap[] ={ 0, 1, 2, 3, 4, 5, 6, 7,  -1, -1, -1, -1, -1, -1, 14, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  8, 9, 10, 11, 12, 13, -1, 15,  32, 33, 34, 35, 36, 37, 38, 39,  40, 41, 42, 43, 44, 45, 46, 47,  48, 49, 50, 51, 52, 53, 54, 55,  56, 57, 58, 59, 60, 61, 62, 63,  64, 65, 66, 67, 68, 69, 70, 71,  72, 73, 74, 75, 76, 77, 78, 79,  80, 81, 82, 83, 84, 85, 86, 87,  88, 89, 90, 91, 92, 93, 94, 95,  96, 97, 98, 99, 100};/* Vector, indexed by hard register number, which contains 1   for a register that is allowable in a candidate for leaf   function treatment.  */char sparc_leaf_regs[] ={ 1, 1, 1, 1, 1, 1, 1, 1,  0, 0, 0, 0, 0, 0, 1, 0,  0, 0, 0, 0, 0, 0, 0, 0,  1, 1, 1, 1, 1, 1, 0, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1};struct machine_function GTY(()){  /* Some local-dynamic TLS symbol name.  */  const char *some_ld_name;  /* True if the current function is leaf and uses only leaf regs,     so that the SPARC leaf function optimization can be applied.     Private version of current_function_uses_only_leaf_regs, see     sparc_expand_prologue for the rationale.  */  int leaf_function_p;  /* True if the data calculated by sparc_expand_prologue are valid.  */  bool prologue_data_valid_p;};#define sparc_leaf_function_p  cfun->machine->leaf_function_p#define sparc_prologue_data_valid_p  cfun->machine->prologue_data_valid_p/* Register we pretend to think the frame pointer is allocated to.   Normally, this is %fp, but if we are in a leaf procedure, this   is %sp+"something".  We record "something" separately as it may   be too big for reg+constant addressing.  */static rtx frame_base_reg;static HOST_WIDE_INT frame_base_offset;/* 1 if the next opcode is to be specially indented.  */int sparc_indent_opcode = 0;static void sparc_init_modes (void);static void scan_record_type (tree, int *, int *, int *);static int function_arg_slotno (const CUMULATIVE_ARGS *, enum machine_mode,				tree, int, int, int *, int *);static int supersparc_adjust_cost (rtx, rtx, rtx, int);static int hypersparc_adjust_cost (rtx, rtx, rtx, int);static void sparc_output_addr_vec (rtx);static void sparc_output_addr_diff_vec (rtx);static void sparc_output_deferred_case_vectors (void);static rtx sparc_builtin_saveregs (void);static int epilogue_renumber (rtx *, int);static bool sparc_assemble_integer (rtx, unsigned int, int);static int set_extends (rtx);static void emit_pic_helper (void);static void load_pic_register (bool);static int save_or_restore_regs (int, int, rtx, int, int);static void emit_save_regs (void);static void emit_restore_regs (void);static void sparc_asm_function_prologue (FILE *, HOST_WIDE_INT);static void sparc_asm_function_epilogue (FILE *, HOST_WIDE_INT);#ifdef OBJECT_FORMAT_ELFstatic void sparc_elf_asm_named_section (const char *, unsigned int, tree);#endifstatic int sparc_adjust_cost (rtx, rtx, rtx, int);static int sparc_issue_rate (void);static void sparc_sched_init (FILE *, int, int);static int sparc_use_sched_lookahead (void);static void emit_soft_tfmode_libcall (const char *, int, rtx *);static void emit_soft_tfmode_binop (enum rtx_code, rtx *);static void emit_soft_tfmode_unop (enum rtx_code, rtx *);static void emit_soft_tfmode_cvt (enum rtx_code, rtx *);static void emit_hard_tfmode_operation (enum rtx_code, rtx *);static bool sparc_function_ok_for_sibcall (tree, tree);static void sparc_init_libfuncs (void);static void sparc_init_builtins (void);static void sparc_vis_init_builtins (void);static rtx sparc_expand_builtin (tree, rtx, rtx, enum machine_mode, int);static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,				   HOST_WIDE_INT, tree);static bool sparc_can_output_mi_thunk (tree, HOST_WIDE_INT,				       HOST_WIDE_INT, tree);static struct machine_function * sparc_init_machine_status (void);static bool sparc_cannot_force_const_mem (rtx);static rtx sparc_tls_get_addr (void);static rtx sparc_tls_got (void);static const char *get_some_local_dynamic_name (void);static int get_some_local_dynamic_name_1 (rtx *, void *);static bool sparc_rtx_costs (rtx, int, int, int *);static bool sparc_promote_prototypes (tree);static rtx sparc_struct_value_rtx (tree, int);static bool sparc_return_in_memory (tree, tree);static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);static bool sparc_vector_mode_supported_p (enum machine_mode);static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,				     enum machine_mode, tree, bool);static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *,				    enum machine_mode, tree, bool);static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int);static void sparc_file_end (void);#ifdef SUBTARGET_ATTRIBUTE_TABLEconst struct attribute_spec sparc_attribute_table[];#endif/* Option handling.  *//* Code model option as passed by user.  */const char *sparc_cmodel_string;/* Parsed value.  */enum cmodel sparc_cmodel;char sparc_hard_reg_printed[8];struct sparc_cpu_select sparc_select[] ={  /* switch	name,		tune	arch */  { (char *)0,	"default",	1,	1 },  { (char *)0,	"-mcpu=",	1,	1 },  { (char *)0,	"-mtune=",	1,	0 },  { 0, 0, 0, 0 }};/* CPU type.  This is set from TARGET_CPU_DEFAULT and -m{cpu,tune}=xxx.  */enum processor_type sparc_cpu;/* Initialize the GCC target structure.  *//* The sparc default is to use .half rather than .short for aligned   HI objects.  Use .word instead of .long on non-ELF systems.  */#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"#ifndef OBJECT_FORMAT_ELF#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"#endif#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP "\t.uahalf\t"#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP "\t.uaword\t"#undef TARGET_ASM_UNALIGNED_DI_OP#define TARGET_ASM_UNALIGNED_DI_OP "\t.uaxword\t"/* The target hook has to handle DI-mode values.  */#undef TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER sparc_assemble_integer#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE sparc_asm_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE sparc_asm_function_epilogue#undef TARGET_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST sparc_adjust_cost#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE sparc_issue_rate#undef TARGET_SCHED_INIT#define TARGET_SCHED_INIT sparc_sched_init#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead#undef TARGET_FUNCTION_OK_FOR_SIBCALL#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall#undef TARGET_INIT_LIBFUNCS#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS sparc_init_builtins#undef TARGET_EXPAND_BUILTIN#define TARGET_EXPAND_BUILTIN sparc_expand_builtin#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 sparc_cannot_force_const_mem#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK sparc_can_output_mi_thunk

⌨️ 快捷键说明

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