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

📄 pa.h

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
       /* Floating-point loads and stores are used to load		\	  integer values as well as floating-point values.		\	  They don't have the same set of REG+D address modes		\	  as integer loads and stores.  PA 1.x supports only		\	  short displacements.  PA 2.0 supports long displacements	\	  but the base register needs to be aligned.			\									\	  The checks in GO_IF_LEGITIMATE_ADDRESS for SFmode and		\	  DFmode test the validity of an address for use in a		\	  floating point load or store.  So, we use SFmode/DFmode	\	  to see if the address is valid for a floating-point		\	  load/store operation.  */					\       && memory_address_p ((GET_MODE_SIZE (GET_MODE (OP)) == 4		\			     ? SFmode					\			     : DFmode),					\			    XEXP (OP, 0)))				\   : ((C) == 'S' ?							\      (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31)			\   : ((C) == 'U' ?							\      (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0)))))))	/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx   and check its validity for a certain class.   We have two alternate definitions for each of them.   The usual definition accepts all pseudo regs; the other rejects   them unless they have been allocated suitable hard regs.   The symbol REG_OK_STRICT causes the latter definition to be used.   Most source files want to accept pseudo regs in the hope that   they will get allocated to the class that the insn wants them to be in.   Source files for reload pass need to be strict.   After reload, it makes no difference, since pseudo regs have   been eliminated by then.  */#ifndef REG_OK_STRICT/* Nonzero if X is a hard reg that can be used as an index   or if it is a pseudo reg.  */#define REG_OK_FOR_INDEX_P(X) \(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))/* Nonzero if X is a hard reg that can be used as a base reg   or if it is a pseudo reg.  */#define REG_OK_FOR_BASE_P(X) \(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))#else/* Nonzero if X is a hard reg that can be used as an index.  */#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))/* Nonzero if X is a hard reg that can be used as a base reg.  */#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))#endif/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a   valid memory address for an instruction.  The MODE argument is the   machine mode for the MEM expression that wants to use this address.   On HP PA-RISC, the legitimate address forms are REG+SMALLINT,   REG+REG, and REG+(REG*SCALE).  The indexed address forms are only   available with floating point loads and stores, and integer loads.   We get better code by allowing indexed addresses in the initial   RTL generation.   The acceptance of indexed addresses as legitimate implies that we   must provide patterns for doing indexed integer stores, or the move   expanders must force the address of an indexed store to a register.   We have adopted the latter approach.      Another function of GO_IF_LEGITIMATE_ADDRESS is to ensure that   the base register is a valid pointer for indexed instructions.   On targets that have non-equivalent space registers, we have to   know at the time of assembler output which register in a REG+REG   pair is the base register.  The REG_POINTER flag is sometimes lost   in reload and the following passes, so it can't be relied on during   code generation.  Thus, we either have to canonicalize the order   of the registers in REG+REG indexed addresses, or treat REG+REG   addresses separately and provide patterns for both permutations.   The latter approach requires several hundred additional lines of   code in pa.md.  The downside to canonicalizing is that a PLUS   in the wrong order can't combine to form to make a scaled indexed   memory operand.  As we won't need to canonicalize the operands if   the REG_POINTER lossage can be fixed, it seems better canonicalize.   We initially break out scaled indexed addresses in canonical order   in emit_move_sequence.  LEGITIMIZE_ADDRESS also canonicalizes   scaled indexed addresses during RTL generation.  However, fold_rtx   has its own opinion on how the operands of a PLUS should be ordered.   If one of the operands is equivalent to a constant, it will make   that operand the second operand.  As the base register is likely to   be equivalent to a SYMBOL_REF, we have made it the second operand.   GO_IF_LEGITIMATE_ADDRESS accepts REG+REG as legitimate when the   operands are in the order INDEX+BASE on targets with non-equivalent   space registers, and in any order on targets with equivalent space   registers.  It accepts both MULT+BASE and BASE+MULT for scaled indexing.   We treat a SYMBOL_REF as legitimate if it is part of the current   function's constant-pool, because such addresses can actually be   output as REG+SMALLINT.    Note we only allow 5 bit immediates for access to a constant address;   doing so avoids losing for loading/storing a FP register at an address   which will not fit in 5 bits.  */#define VAL_5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x10 < 0x20)#define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X))#define VAL_U5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) < 0x20)#define INT_U5_BITS(X) VAL_U5_BITS_P (INTVAL (X))#define VAL_11_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x400 < 0x800)#define INT_11_BITS(X) VAL_11_BITS_P (INTVAL (X))#define VAL_14_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x2000 < 0x4000)#define INT_14_BITS(X) VAL_14_BITS_P (INTVAL (X))#if HOST_BITS_PER_WIDE_INT > 32#define VAL_32_BITS_P(X) \  ((unsigned HOST_WIDE_INT)(X) + ((unsigned HOST_WIDE_INT) 1 << 31)    \   < (unsigned HOST_WIDE_INT) 2 << 31)#else#define VAL_32_BITS_P(X) 1#endif#define INT_32_BITS(X) VAL_32_BITS_P (INTVAL (X))/* These are the modes that we allow for scaled indexing.  */#define MODE_OK_FOR_SCALED_INDEXING_P(MODE) \  ((TARGET_64BIT && (MODE) == DImode)					\   || (MODE) == SImode							\   || (MODE) == HImode							\   || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))/* These are the modes that we allow for unscaled indexing.  */#define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \  ((TARGET_64BIT && (MODE) == DImode)					\   || (MODE) == SImode							\   || (MODE) == HImode							\   || (MODE) == QImode							\   || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \{									\  if ((REG_P (X) && REG_OK_FOR_BASE_P (X))				\      || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC		\	   || GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC)	\	  && REG_P (XEXP (X, 0))					\	  && REG_OK_FOR_BASE_P (XEXP (X, 0))))				\    goto ADDR;								\  else if (GET_CODE (X) == PLUS)					\    {									\      rtx base = 0, index = 0;						\      if (REG_P (XEXP (X, 1))						\	  && REG_OK_FOR_BASE_P (XEXP (X, 1)))				\	base = XEXP (X, 1), index = XEXP (X, 0);			\      else if (REG_P (XEXP (X, 0))					\	       && REG_OK_FOR_BASE_P (XEXP (X, 0)))			\	base = XEXP (X, 0), index = XEXP (X, 1);			\      if (base								\	  && GET_CODE (index) == CONST_INT				\	  && ((INT_14_BITS (index)					\	       && (((MODE) != DImode					\		    && (MODE) != SFmode					\		    && (MODE) != DFmode)				\		   /* The base register for DImode loads and stores	\		      with long displacements must be aligned because	\		      the lower three bits in the displacement are	\		      assumed to be zero.  */				\		   || ((MODE) == DImode					\		       && (!TARGET_64BIT				\			   || (INTVAL (index) % 8) == 0))		\		   /* Similarly, the base register for SFmode/DFmode	\		      loads and stores with long displacements must	\		      be aligned.					\									\		      FIXME: the ELF32 linker clobbers the LSB of	\		      the FP register number in PA 2.0 floating-point	\		      insns with long displacements.  This is because	\		      R_PARISC_DPREL14WR and other relocations like	\		      it are not supported.  For now, we reject long	\		      displacements on this target.  */			\		   || (((MODE) == SFmode || (MODE) == DFmode)		\		       && (TARGET_SOFT_FLOAT				\			   || (TARGET_PA_20				\			       && !TARGET_ELF32				\			       && (INTVAL (index)			\				   % GET_MODE_SIZE (MODE)) == 0)))))	\	       || INT_5_BITS (index)))					\	goto ADDR;							\      if (!TARGET_DISABLE_INDEXING					\	  /* Only accept the "canonical" INDEX+BASE operand order	\	     on targets with non-equivalent space registers.  */	\	  && (TARGET_NO_SPACE_REGS					\	      ? (base && REG_P (index))					\	      : (base == XEXP (X, 1) && REG_P (index)			\		 && (reload_completed					\		     || (reload_in_progress && HARD_REGISTER_P (base))	\		     || REG_POINTER (base))				\		 && (reload_completed					\		     || (reload_in_progress && HARD_REGISTER_P (index))	\		     || !REG_POINTER (index))))				\	  && MODE_OK_FOR_UNSCALED_INDEXING_P (MODE)			\	  && REG_OK_FOR_INDEX_P (index)					\	  && borx_reg_operand (base, Pmode)				\	  && borx_reg_operand (index, Pmode))				\	goto ADDR;							\      if (!TARGET_DISABLE_INDEXING					\	  && base							\	  && GET_CODE (index) == MULT					\	  && MODE_OK_FOR_SCALED_INDEXING_P (MODE)			\	  && REG_P (XEXP (index, 0))					\	  && GET_MODE (XEXP (index, 0)) == Pmode			\	  && REG_OK_FOR_INDEX_P (XEXP (index, 0))			\	  && GET_CODE (XEXP (index, 1)) == CONST_INT			\	  && INTVAL (XEXP (index, 1))					\	     == (HOST_WIDE_INT) GET_MODE_SIZE (MODE)			\	  && borx_reg_operand (base, Pmode))				\	goto ADDR;							\    }									\  else if (GET_CODE (X) == LO_SUM					\	   && GET_CODE (XEXP (X, 0)) == REG				\	   && REG_OK_FOR_BASE_P (XEXP (X, 0))				\	   && CONSTANT_P (XEXP (X, 1))					\	   && (TARGET_SOFT_FLOAT					\	       /* We can allow symbolic LO_SUM addresses for PA2.0.  */	\	       || (TARGET_PA_20						\		   && !TARGET_ELF32					\	           && GET_CODE (XEXP (X, 1)) != CONST_INT)		\	       || ((MODE) != SFmode					\		   && (MODE) != DFmode)))				\    goto ADDR;								\  else if (GET_CODE (X) == LO_SUM					\	   && GET_CODE (XEXP (X, 0)) == SUBREG				\	   && GET_CODE (SUBREG_REG (XEXP (X, 0))) == REG		\	   && REG_OK_FOR_BASE_P (SUBREG_REG (XEXP (X, 0)))		\	   && CONSTANT_P (XEXP (X, 1))					\	   && (TARGET_SOFT_FLOAT					\	       /* We can allow symbolic LO_SUM addresses for PA2.0.  */	\	       || (TARGET_PA_20						\		   && !TARGET_ELF32					\	           && GET_CODE (XEXP (X, 1)) != CONST_INT)		\	       || ((MODE) != SFmode					\		   && (MODE) != DFmode)))				\    goto ADDR;								\  else if (GET_CODE (X) == LABEL_REF					\	   || (GET_CODE (X) == CONST_INT				\	       && INT_5_BITS (X)))					\    goto ADDR;								\  /* Needed for -fPIC */						\  else if (GET_CODE (X) == LO_SUM					\	   && GET_CODE (XEXP (X, 0)) == REG             		\	   && REG_OK_FOR_BASE_P (XEXP (X, 0))				\	   && GET_CODE (XEXP (X, 1)) == UNSPEC				\	   && (TARGET_SOFT_FLOAT					\	       || (TARGET_PA_20	&& !TARGET_ELF32)			\	       || ((MODE) != SFmode					\		   && (MODE) != DFmode)))				\    goto ADDR;								\}/* Look for machine dependent ways to make the invalid address AD a   valid address.   For the PA, transform:        memory(X + <large int>)   into:        if (<large int> & mask) >= 16          Y = (<large int> & ~mask) + mask + 1  Round up.        else          Y = (<large int> & ~mask)             Round down.        Z = X + Y        memory (Z + (<large int> - Y));   This makes reload inheritance and reload_cse work better since Z   can be reused.   There may be more opportunities to improve code with this hook.  */#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) 	\do { 									\  long offset, newoffset, mask;						\  rtx new, temp = NULL_RTX;						\									\  mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT				\	  ? (TARGET_PA_20 && !TARGET_ELF32 ? 0x3fff : 0x1f) : 0x3fff);	\									\  if (optimize && GET_CODE (AD) == PLUS)				\    temp = simplify_binary_operation (PLUS, Pmode,			\				      XEXP (AD, 0), XEXP (AD, 1));	\									\  new = temp ? temp : AD;						\									\  if (optimize								\      && GET_CODE (new) == PLUS						\      && GET_CODE (XEXP (new, 0)) == REG				\      && GET_CODE (XEXP (new, 1)) == CONST_INT)				\    {									\      offset = INTVAL (XEXP ((new), 1));				\									\      /* Choose rounding direction.  Round up if we are >= halfway.  */	\      if ((offset & mask) >= ((mask + 1) / 2))				\	newoffset = (offset & ~mask) + mask + 1;			\      else								\	newoffset = offset & ~mask;					\									\      /* Ensure that long displacements are aligned.  */		\      if (!VAL_5_BITS_P (newoffset)					\	  && GET_MODE_CLASS (MODE) == MODE_FLOAT)			\	newoffset &= ~(GET_MODE_SIZE (MODE) -1);			\									\      if (newoffset != 0 && VAL_14_BITS_P (newoffset))			\	{								\	  temp = gen_rtx_PLUS (Pmode, XEXP (new, 0),			\			       GEN_INT (newoffset));			\	  AD = gen_rtx_PLUS (Pmode, temp, GEN_INT (offset - newoffset));\	  push_reload (XEXP (AD, 0), 0, &XEXP (AD, 0), 0,		\		       BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,		\		       (OPNUM), (TYPE));				\	  goto WIN;							\	}								\    }									\} while (0)/* Try machine-dependent ways of modifying an illegitimate address   to be legitimate.  If we find one, return the new, valid address.   This macro is used in only

⌨️ 快捷键说明

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