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

📄 pa.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines for insn-output.c for HPPA.   Copyright (C) 1992, 1993, 1994, 1995 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 <stdio.h>#include "config.h"#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-flags.h"#include "output.h"#include "insn-attr.h"#include "flags.h"#include "tree.h"#include "c-tree.h"#include "expr.h"#include "obstack.h"/* 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.  */char *pa_cpu_string;/* Set by the FUNCTION_PROFILER macro. */int hp_profile_labelno;/* 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 ();/* 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 int total_code_bytes;/* Variables to handle plabels that we discover are necessary at assembly   output time.  They are output after the current function.  */struct defer_plab{  rtx internal_label;  rtx symbol;} *deferred_plabels = 0;int n_deferred_plabels = 0;voidoverride_options (){  /* Default to 700 scheduling which is reasonable for older 800 processors     correct for the 700s, and not too bad for the 7100s and 7100LCs.  */  if (pa_cpu_string == NULL      || ! strcmp (pa_cpu_string, "700"))    {      pa_cpu_string = "700";      pa_cpu = PROCESSOR_700;    }  else if (! strcmp (pa_cpu_string, "7100"))    {      pa_cpu_string = "7100";      pa_cpu = PROCESSOR_7100;    }  else if (! strcmp (pa_cpu_string, "7100LC"))    {      pa_cpu_string = "7100LC";      pa_cpu = PROCESSOR_7100LC;    }  else    {      warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC\n", pa_cpu_string);    }}/* Return non-zero 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 non-zero 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;{  return (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;{  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;{  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;  if (op == CONST0_RTX (mode))    return 1;  if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))    return 1;  return 0;}/* Accept any constant that can be moved in one instructions into a   general register.  */intcint_ok_for_move (intval)     HOST_WIDE_INT intval;{  /* OK if ldo, ldil, or zdepi, can be used.  */  return (VAL_14_BITS_P (intval) || (intval & 0x7ff) == 0	  || zdepi_cint_p (intval));}/* Accept anything that can be moved in one instruction into a general   register.  */intmove_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT)    return cint_ok_for_move (INTVAL (op));  if (GET_MODE (op) != mode)    return 0;  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  if (GET_CODE (op) == LO_SUM)    return (register_operand (XEXP (op, 0), Pmode)	    && CONSTANT_P (XEXP (op, 1)));  return memory_address_p (mode, op);}/* Accept REG and any CONST_INT that can be moved in one instruction into a   general register.  */intreg_or_cint_move_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT)    return cint_ok_for_move (INTVAL (op));  return 0;}intpic_label_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (!flag_pic)    return 0;  switch (GET_CODE (op))    {    case LABEL_REF:      return 1;    case CONST:      op = XEXP (op, 0);      return (GET_CODE (XEXP (op, 0)) == LABEL_REF	      && GET_CODE (XEXP (op, 1)) == CONST_INT);    default:      return 0;    }}intfp_reg_operand (op, mode)     rtx op;     enum machine_mode mode;{  return reg_renumber && FP_REG_P (op);}/* Return truth value of whether OP can be used as an operand in a   three operand arithmetic insn that accepts registers of mode MODE   or 14-bit signed integers.  */intarith_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));}/* Return truth value of whether OP can be used as an operand in a   three operand arithmetic insn that accepts registers of mode MODE   or 11-bit signed integers.  */intarith11_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));}/* A constant integer suitable for use in a PRE_MODIFY memory   reference.  */intpre_cint_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (GET_CODE (op) == CONST_INT	  && INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);}/* A constant integer suitable for use in a POST_MODIFY memory   reference.  */intpost_cint_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (GET_CODE (op) == CONST_INT	  && INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);}intarith_double_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_DOUBLE	      && GET_MODE (op) == mode	      && VAL_14_BITS_P (CONST_DOUBLE_LOW (op))	      && (CONST_DOUBLE_HIGH (op) >= 0		  == ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));}/* Return truth value of whether OP is a integer which fits the   range constraining immediate operands in three-address insns.  */intint5_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));}intuint5_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));}intint11_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));}intuint32_operand (op, mode)     rtx op;     enum machine_mode mode;{#if HOST_BITS_PER_WIDE_INT > 32  /* All allowed constants will fit a CONST_INT.  */  return (GET_CODE (op) == CONST_INT	  && (INTVAL (op) >= 0 && INTVAL (op) < 0x100000000L));#else  return (GET_CODE (op) == CONST_INT	  || (GET_CODE (op) == CONST_DOUBLE	      && CONST_DOUBLE_HIGH (op) == 0));#endif}intarith5_operand (op, mode)     rtx op;     enum machine_mode mode;{  return register_operand (op, mode) || int5_operand (op, mode);}/* True iff zdepi can be used to generate this CONST_INT.  */intzdepi_cint_p (x)     unsigned HOST_WIDE_INT x;{  unsigned HOST_WIDE_INT lsb_mask, t;  /* This might not be obvious, but it's at least fast.     This function is critical; we don't have the time loops would take.  */  lsb_mask = x & -x;  t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);  /* Return true iff t is a power of two.  */  return ((t & (t - 1)) == 0);}/* True iff depi or extru can be used to compute (reg & mask).   Accept bit pattern like these:   0....01....1   1....10....0   1..10..01..1  */intand_mask_p (mask)     unsigned HOST_WIDE_INT mask;{  mask = ~mask;  mask += mask & -mask;  return (mask & (mask - 1)) == 0;}/* True iff depi or extru can be used to compute (reg & OP).  */intand_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));}/* True iff depi can be used to compute (reg | MASK).  */intior_mask_p (mask)     unsigned HOST_WIDE_INT mask;{  mask += mask & -mask;  return (mask & (mask - 1)) == 0;}/* True iff depi can be used to compute (reg | OP).  */intior_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));}intlhs_lshift_operand (op, mode)     rtx op;

⌨️ 快捷键说明

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