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

📄 pa.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines for insn-output.c for HPPA.   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,   2002, 2003 Free Software Foundation, Inc.   Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.cThis 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 "tree.h"#include "output.h"#include "except.h"#include "expr.h"#include "optabs.h"#include "libfuncs.h"#include "reload.h"#include "c-tree.h"#include "integrate.h"#include "function.h"#include "obstack.h"#include "toplev.h"#include "ggc.h"#include "recog.h"#include "predict.h"#include "tm_p.h"#include "target.h"#include "target-def.h"static int hppa_use_dfa_pipeline_interface PARAMS ((void));#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE hppa_use_dfa_pipeline_interfacestatic inthppa_use_dfa_pipeline_interface (){  return 1;}/* Return nonzero if there is a bypass for the output of    OUT_INSN and the fp store IN_INSN.  */inthppa_fpstore_bypass_p (out_insn, in_insn)     rtx out_insn, in_insn;{  enum machine_mode store_mode;  enum machine_mode other_mode;  rtx set;  if (recog_memoized (in_insn) < 0      || get_attr_type (in_insn) != TYPE_FPSTORE      || recog_memoized (out_insn) < 0)    return 0;  store_mode = GET_MODE (SET_SRC (PATTERN (in_insn)));  set = single_set (out_insn);  if (!set)    return 0;  other_mode = GET_MODE (SET_SRC (set));  return (GET_MODE_SIZE (store_mode) == GET_MODE_SIZE (other_mode));}  #ifndef DO_FRAME_NOTES#ifdef INCOMING_RETURN_ADDR_RTX#define DO_FRAME_NOTES 1#else#define DO_FRAME_NOTES 0#endif#endifstatic inline rtx force_mode PARAMS ((enum machine_mode, rtx));static void pa_combine_instructions PARAMS ((rtx));static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));static int forward_branch_p PARAMS ((rtx));static int shadd_constant_p PARAMS ((int));static void compute_zdepwi_operands PARAMS ((unsigned HOST_WIDE_INT, unsigned *));static int compute_movstrsi_length PARAMS ((rtx));static bool pa_assemble_integer PARAMS ((rtx, unsigned int, int));static void remove_useless_addtr_insns PARAMS ((rtx, int));static void store_reg PARAMS ((int, int, int));static void store_reg_modify PARAMS ((int, int, int));static void load_reg PARAMS ((int, int, int));static void set_reg_plus_d PARAMS ((int, int, int, int));static void pa_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void pa_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));static int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));static int pa_adjust_priority PARAMS ((rtx, int));static int pa_issue_rate PARAMS ((void));static void pa_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT))     ATTRIBUTE_UNUSED;static void pa_encode_section_info PARAMS ((tree, int));static const char *pa_strip_name_encoding PARAMS ((const char *));static void pa_globalize_label PARAMS ((FILE *, const char *))     ATTRIBUTE_UNUSED;static void pa_asm_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,					    HOST_WIDE_INT, tree));#if !defined(USE_COLLECT2)static void pa_asm_out_constructor PARAMS ((rtx, int));static void pa_asm_out_destructor PARAMS ((rtx, int));#endifstatic void pa_init_builtins PARAMS ((void));static void copy_fp_args PARAMS ((rtx)) ATTRIBUTE_UNUSED;static int length_fp_args PARAMS ((rtx)) ATTRIBUTE_UNUSED;static struct deferred_plabel *get_plabel PARAMS ((const char *))     ATTRIBUTE_UNUSED;/* Save the operands last given to a compare for use when we   generate a scc or bcc insn.  */rtx hppa_compare_op0, hppa_compare_op1;enum cmp_type hppa_branch_type;/* Which cpu we are scheduling for.  */enum processor_type pa_cpu;/* String to hold which cpu we are scheduling for.  */const char *pa_cpu_string;/* Which architecture we are generating code for.  */enum architecture_type pa_arch;/* String to hold which architecture we are generating code for.  */const char *pa_arch_string;/* Counts for the number of callee-saved general and floating point   registers which were saved by the current function's prologue.  */static int gr_saved, fr_saved;static rtx find_addr_reg PARAMS ((rtx));/* Keep track of the number of bytes we have output in the CODE subspaces   during this compilation so we'll know when to emit inline long-calls.  */unsigned long total_code_bytes;/* Variables to handle plabels that we discover are necessary at assembly   output time.  They are output after the current function.  */struct deferred_plabel GTY(()){  rtx internal_label;  const char *name;};static GTY((length ("n_deferred_plabels"))) struct deferred_plabel *  deferred_plabels;static size_t n_deferred_plabels = 0;/* Initialize the GCC target structure.  */#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"#undef TARGET_ASM_ALIGNED_SI_OP#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"#undef TARGET_ASM_ALIGNED_DI_OP#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"#undef TARGET_ASM_UNALIGNED_HI_OP#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP#undef TARGET_ASM_UNALIGNED_SI_OP#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP#undef TARGET_ASM_UNALIGNED_DI_OP#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP#undef TARGET_ASM_INTEGER#define TARGET_ASM_INTEGER pa_assemble_integer#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE pa_output_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue#undef TARGET_SCHED_ADJUST_COST#define TARGET_SCHED_ADJUST_COST pa_adjust_cost#undef TARGET_SCHED_ADJUST_PRIORITY#define TARGET_SCHED_ADJUST_PRIORITY pa_adjust_priority#undef TARGET_SCHED_ISSUE_RATE#define TARGET_SCHED_ISSUE_RATE pa_issue_rate#undef TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO pa_encode_section_info#undef TARGET_STRIP_NAME_ENCODING#define TARGET_STRIP_NAME_ENCODING pa_strip_name_encoding#undef TARGET_ASM_OUTPUT_MI_THUNK#define TARGET_ASM_OUTPUT_MI_THUNK pa_asm_output_mi_thunk#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall#if !defined(USE_COLLECT2)#undef TARGET_ASM_CONSTRUCTOR#define TARGET_ASM_CONSTRUCTOR pa_asm_out_constructor#undef TARGET_ASM_DESTRUCTOR#define TARGET_ASM_DESTRUCTOR pa_asm_out_destructor#endif#undef TARGET_INIT_BUILTINS#define TARGET_INIT_BUILTINS pa_init_builtinsstruct gcc_target targetm = TARGET_INITIALIZER;voidoverride_options (){  if (pa_cpu_string == NULL)    pa_cpu_string = TARGET_SCHED_DEFAULT;  if (! strcmp (pa_cpu_string, "8000"))    {      pa_cpu_string = "8000";      pa_cpu = PROCESSOR_8000;    }  else if (! strcmp (pa_cpu_string, "7100"))    {      pa_cpu_string = "7100";      pa_cpu = PROCESSOR_7100;    }  else if (! strcmp (pa_cpu_string, "700"))    {      pa_cpu_string = "700";      pa_cpu = PROCESSOR_700;    }  else if (! strcmp (pa_cpu_string, "7100LC"))    {      pa_cpu_string = "7100LC";      pa_cpu = PROCESSOR_7100LC;    }  else if (! strcmp (pa_cpu_string, "7200"))    {      pa_cpu_string = "7200";      pa_cpu = PROCESSOR_7200;    }  else if (! strcmp (pa_cpu_string, "7300"))    {      pa_cpu_string = "7300";      pa_cpu = PROCESSOR_7300;    }  else    {      warning ("unknown -mschedule= option (%s).\nValid options are 700, 7100, 7100LC, 7200, 7300, and 8000\n", pa_cpu_string);    }  /* Set the instruction set architecture.  */  if (pa_arch_string && ! strcmp (pa_arch_string, "1.0"))    {      pa_arch_string = "1.0";      pa_arch = ARCHITECTURE_10;      target_flags &= ~(MASK_PA_11 | MASK_PA_20);    }  else if (pa_arch_string && ! strcmp (pa_arch_string, "1.1"))    {      pa_arch_string = "1.1";      pa_arch = ARCHITECTURE_11;      target_flags &= ~MASK_PA_20;      target_flags |= MASK_PA_11;    }  else if (pa_arch_string && ! strcmp (pa_arch_string, "2.0"))    {      pa_arch_string = "2.0";      pa_arch = ARCHITECTURE_20;      target_flags |= MASK_PA_11 | MASK_PA_20;    }  else if (pa_arch_string)    {      warning ("unknown -march= option (%s).\nValid options are 1.0, 1.1, and 2.0\n", pa_arch_string);    }  /* Unconditional branches in the delay slot are not compatible with dwarf2     call frame information.  There is no benefit in using this optimization     on PA8000 and later processors.  */  if (pa_cpu >= PROCESSOR_8000      || (! USING_SJLJ_EXCEPTIONS && flag_exceptions)      || flag_unwind_tables)    target_flags &= ~MASK_JUMP_IN_DELAY;  if (flag_pic && TARGET_PORTABLE_RUNTIME)    {      warning ("PIC code generation is not supported in the portable runtime model\n");    }  if (flag_pic && TARGET_FAST_INDIRECT_CALLS)   {      warning ("PIC code generation is not compatible with fast indirect calls\n");   }  if (! TARGET_GAS && write_symbols != NO_DEBUG)    {      warning ("-g is only supported when using GAS on this processor,");      warning ("-g option disabled");      write_symbols = NO_DEBUG;    }  /* We only support the "big PIC" model now.  And we always generate PIC     code when in 64bit mode.  */  if (flag_pic == 1 || TARGET_64BIT)    flag_pic = 2;  /* We can't guarantee that .dword is available for 32-bit targets.  */  if (UNITS_PER_WORD == 4)    targetm.asm_out.aligned_op.di = NULL;  /* The unaligned ops are only available when using GAS.  */  if (!TARGET_GAS)    {      targetm.asm_out.unaligned_op.hi = NULL;      targetm.asm_out.unaligned_op.si = NULL;      targetm.asm_out.unaligned_op.di = NULL;    }}static voidpa_init_builtins (){#ifdef DONT_HAVE_FPUTC_UNLOCKED  built_in_decls[(int) BUILT_IN_FPUTC_UNLOCKED] = NULL_TREE;#endif}/* Return nonzero only if OP is a register of mode MODE,   or CONST0_RTX.  */intreg_or_0_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (op == CONST0_RTX (mode) || register_operand (op, mode));}/* Return nonzero if OP is suitable for use in a call to a named   function.   For 2.5 try to eliminate either call_operand_address or   function_label_operand, they perform very similar functions.  */intcall_operand_address (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return (GET_MODE (op) == word_mode	  && CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);}/* Return 1 if X contains a symbolic expression.  We know these   expressions will have one of a few well defined forms, so   we need only check those forms.  */intsymbolic_expression_p (x)     register rtx x;{  /* Strip off any HIGH.  */  if (GET_CODE (x) == HIGH)    x = XEXP (x, 0);  return (symbolic_operand (x, VOIDmode));}intsymbolic_operand (op, mode)     register rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  switch (GET_CODE (op))    {    case SYMBOL_REF:    case LABEL_REF:      return 1;    case CONST:      op = XEXP (op, 0);      return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF	       || GET_CODE (XEXP (op, 0)) == LABEL_REF)	      && GET_CODE (XEXP (op, 1)) == CONST_INT);    default:      return 0;    }}/* Return truth value of statement that OP is a symbolic memory   operand of mode MODE.  */intsymbolic_memory_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST	  || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);}/* Return 1 if the operand is either a register or a memory operand that is   not symbolic.  */intreg_or_nonsymb_mem_operand (op, mode)    register rtx op;    enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))    return 1;  return 0;}/* Return 1 if the operand is either a register, zero, or a memory operand   that is not symbolic.  */intreg_or_0_or_nonsymb_mem_operand (op, mode)    register rtx op;    enum machine_mode mode;{  if (register_operand (op, mode))    return 1;

⌨️ 快捷键说明

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