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

📄 pa.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	  reg1 = XEXP (XEXP (idx, 0), 0);	  if (GET_CODE (reg1) != REG)	    reg1 = force_reg (Pmode, force_operand (reg1, 0));	  reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, reg1, GEN_INT (val)));	  /* We can now generate a simple scaled indexed address.  */	  return force_reg (Pmode,			    gen_rtx_PLUS (Pmode,					  gen_rtx_MULT (Pmode, reg1,						        XEXP (XEXP (idx, 0), 1)),					  base));	}      /* If B + C is still a valid base register, then add them.  */      if (GET_CODE (XEXP (idx, 1)) == CONST_INT	  && INTVAL (XEXP (idx, 1)) <= 4096	  && INTVAL (XEXP (idx, 1)) >= -4096)	{	  int val = INTVAL (XEXP (XEXP (idx, 0), 1));	  rtx reg1, reg2;	  reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, XEXP (idx, 1)));	  reg2 = XEXP (XEXP (idx, 0), 0);	  if (GET_CODE (reg2) != CONST_INT)	    reg2 = force_reg (Pmode, force_operand (reg2, 0));	  return force_reg (Pmode, gen_rtx_PLUS (Pmode,					         gen_rtx_MULT (Pmode, reg2,							       GEN_INT (val)),						 reg1));	}      /* Get the index into a register, then add the base + index and	 return a register holding the result.  */      /* First get A into a register.  */      reg1 = XEXP (XEXP (idx, 0), 0);      if (GET_CODE (reg1) != REG)	reg1 = force_reg (Pmode, force_operand (reg1, 0));      /* And get B into a register.  */      reg2 = XEXP (idx, 1);      if (GET_CODE (reg2) != REG)	reg2 = force_reg (Pmode, force_operand (reg2, 0));      reg1 = force_reg (Pmode,			gen_rtx_PLUS (Pmode,				      gen_rtx_MULT (Pmode, reg1,						    XEXP (XEXP (idx, 0), 1)),				      reg2));      /* Add the result to our base register and return.  */      return force_reg (Pmode, gen_rtx_PLUS (Pmode, base, reg1));          }  /* Uh-oh.  We might have an address for x[n-100000].  This needs     special handling to avoid creating an indexed memory address     with x-100000 as the base.         If the constant part is small enough, then it's still safe because     there is a guard page at the beginning and end of the data segment.     Scaled references are common enough that we want to try and rearrange the     terms so that we can use indexing for these addresses too.  Only     do the optimization for floatint point modes.  */  if (GET_CODE (x) == PLUS      && symbolic_expression_p (XEXP (x, 1)))    {      /* Ugly.  We modify things here so that the address offset specified	 by the index expression is computed first, then added to x to form	 the entire address.  */      rtx regx1, regx2, regy1, regy2, y;      /* Strip off any CONST.  */      y = XEXP (x, 1);      if (GET_CODE (y) == CONST)	y = XEXP (y, 0);      if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)	{	  /* See if this looks like		(plus (mult (reg) (shadd_const))		      (const (plus (symbol_ref) (const_int))))	     Where const_int is small.  In that case the const	     expression is a valid pointer for indexing. 	     If const_int is big, but can be divided evenly by shadd_const	     and added to (reg).  This allows more scaled indexed addresses.  */	  if (GET_CODE (XEXP (y, 0)) == SYMBOL_REF	      && GET_CODE (XEXP (x, 0)) == MULT	      && GET_CODE (XEXP (y, 1)) == CONST_INT	      && INTVAL (XEXP (y, 1)) >= -4096	      && INTVAL (XEXP (y, 1)) <= 4095	      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT	      && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))	    {	      int val = INTVAL (XEXP (XEXP (x, 0), 1));	      rtx reg1, reg2;	      reg1 = XEXP (x, 1);	      if (GET_CODE (reg1) != REG)		reg1 = force_reg (Pmode, force_operand (reg1, 0));	      reg2 = XEXP (XEXP (x, 0), 0);	      if (GET_CODE (reg2) != REG)	        reg2 = force_reg (Pmode, force_operand (reg2, 0));	      return force_reg (Pmode,				gen_rtx_PLUS (Pmode,					      gen_rtx_MULT (Pmode, reg2,							    GEN_INT (val)),						reg1));	    }	  else if ((mode == DFmode || mode == SFmode)		   && GET_CODE (XEXP (y, 0)) == SYMBOL_REF		   && GET_CODE (XEXP (x, 0)) == MULT		   && GET_CODE (XEXP (y, 1)) == CONST_INT		   && INTVAL (XEXP (y, 1)) % INTVAL (XEXP (XEXP (x, 0), 1)) == 0		   && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT		   && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))	    {	      regx1		= force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))					     / INTVAL (XEXP (XEXP (x, 0), 1))));	      regx2 = XEXP (XEXP (x, 0), 0);	      if (GET_CODE (regx2) != REG)		regx2 = force_reg (Pmode, force_operand (regx2, 0));	      regx2 = force_reg (Pmode, gen_rtx_fmt_ee (GET_CODE (y), Pmode,							regx2, regx1));	      return force_reg (Pmode,				gen_rtx_PLUS (Pmode,					      gen_rtx_MULT (Pmode, regx2,						            XEXP (XEXP (x, 0),							    1)),					      force_reg (Pmode, XEXP (y, 0))));	    }	  else if (GET_CODE (XEXP (y, 1)) == CONST_INT		   && INTVAL (XEXP (y, 1)) >= -4096		   && INTVAL (XEXP (y, 1)) <= 4095)	    {	      /* This is safe because of the guard page at the		 beginning and end of the data space.  Just		 return the original address.  */	      return orig;	    }	  else	    {	      /* Doesn't look like one we can optimize.  */	      regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));	      regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));	      regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));	      regx1 = force_reg (Pmode,				 gen_rtx_fmt_ee (GET_CODE (y), Pmode,						 regx1, regy2));	      return force_reg (Pmode, gen_rtx_PLUS (Pmode, regx1, regy1));	    }	}    }  return orig;}/* For the HPPA, REG and REG+CONST is cost 0   and addresses involving symbolic constants are cost 2.   PIC addresses are very expensive.   It is no coincidence that this has the same structure   as GO_IF_LEGITIMATE_ADDRESS.  */inthppa_address_cost (X)     rtx X;{  if (GET_CODE (X) == PLUS)      return 1;  else if (GET_CODE (X) == LO_SUM)    return 1;  else if (GET_CODE (X) == HIGH)    return 2;  return 4;}/* Emit insns to move operands[1] into operands[0].   Return 1 if we have written out everything that needs to be done to   do the move.  Otherwise, return 0 and the caller will emit the move   normally.  */intemit_move_sequence (operands, mode, scratch_reg)     rtx *operands;     enum machine_mode mode;     rtx scratch_reg;{  register rtx operand0 = operands[0];  register rtx operand1 = operands[1];  register rtx tem;  if (scratch_reg      && reload_in_progress && GET_CODE (operand0) == REG      && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)    operand0 = reg_equiv_mem[REGNO (operand0)];  else if (scratch_reg	   && reload_in_progress && GET_CODE (operand0) == SUBREG	   && GET_CODE (SUBREG_REG (operand0)) == REG	   && REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)    {     /* We must not alter SUBREG_WORD (operand0) since that would confuse	the code which tracks sets/uses for delete_output_reload.  */      rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),				 reg_equiv_mem [REGNO (SUBREG_REG (operand0))],				 SUBREG_WORD (operand0));      operand0 = alter_subreg (temp);    }  if (scratch_reg      && reload_in_progress && GET_CODE (operand1) == REG      && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)    operand1 = reg_equiv_mem[REGNO (operand1)];  else if (scratch_reg	   && reload_in_progress && GET_CODE (operand1) == SUBREG	   && GET_CODE (SUBREG_REG (operand1)) == REG	   && REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)    {     /* We must not alter SUBREG_WORD (operand0) since that would confuse	the code which tracks sets/uses for delete_output_reload.  */      rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),				 reg_equiv_mem [REGNO (SUBREG_REG (operand1))],				 SUBREG_WORD (operand1));      operand1 = alter_subreg (temp);    }  if (scratch_reg && reload_in_progress && GET_CODE (operand0) == MEM      && ((tem = find_replacement (&XEXP (operand0, 0)))	  != XEXP (operand0, 0)))    operand0 = gen_rtx_MEM (GET_MODE (operand0), tem);  if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM      && ((tem = find_replacement (&XEXP (operand1, 0)))	  != XEXP (operand1, 0)))    operand1 = gen_rtx_MEM (GET_MODE (operand1), tem);  /* Handle secondary reloads for loads/stores of FP registers from     REG+D addresses where D does not fit in 5 bits, including      (subreg (mem (addr))) cases.  */  if (fp_reg_operand (operand0, mode)      && ((GET_CODE (operand1) == MEM	   && ! memory_address_p (DFmode, XEXP (operand1, 0)))	  || ((GET_CODE (operand1) == SUBREG	       && GET_CODE (XEXP (operand1, 0)) == MEM	       && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))      && scratch_reg)    {      if (GET_CODE (operand1) == SUBREG)	operand1 = XEXP (operand1, 0);      scratch_reg = gen_rtx_REG (SImode, REGNO (scratch_reg));      /* D might not fit in 14 bits either; for such cases load D into	 scratch reg.  */      if (!memory_address_p (SImode, XEXP (operand1, 0)))	{	  emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));	  emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)),						       SImode,						       XEXP (XEXP (operand1, 0), 0),						       scratch_reg));	}      else	emit_move_insn (scratch_reg, XEXP (operand1, 0));      emit_insn (gen_rtx_SET (VOIDmode, operand0, gen_rtx_MEM (mode,							       scratch_reg)));      return 1;    }  else if (fp_reg_operand (operand1, mode)	   && ((GET_CODE (operand0) == MEM		&& ! memory_address_p (DFmode, XEXP (operand0, 0)))	       || ((GET_CODE (operand0) == SUBREG)		   && GET_CODE (XEXP (operand0, 0)) == MEM		   && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))	   && scratch_reg)    {      if (GET_CODE (operand0) == SUBREG)	operand0 = XEXP (operand0, 0);      scratch_reg = gen_rtx_REG (SImode, REGNO (scratch_reg));      /* D might not fit in 14 bits either; for such cases load D into	 scratch reg.  */      if (!memory_address_p (SImode, XEXP (operand0, 0)))	{	  emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1));	  emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand0,								        0)),						       SImode,						       XEXP (XEXP (operand0, 0),								   0),						       scratch_reg));	}      else	emit_move_insn (scratch_reg, XEXP (operand0, 0));      emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (mode, scratch_reg),			      operand1));      return 1;    }  /* Handle secondary reloads for loads of FP registers from constant     expressions by forcing the constant into memory.     use scratch_reg to hold the address of the memory location.     ??? The proper fix is to change PREFERRED_RELOAD_CLASS to return     NO_REGS when presented with a const_int and an register class     containing only FP registers.  Doing so unfortunately creates     more problems than it solves.   Fix this for 2.5.  */  else if (fp_reg_operand (operand0, mode)	   && CONSTANT_P (operand1)	   && scratch_reg)    {      rtx xoperands[2];      /* Force the constant into memory and put the address of the	 memory location into scratch_reg.  */      xoperands[0] = scratch_reg;      xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);      emit_move_sequence (xoperands, Pmode, 0);      /* Now load the destination register.  */      emit_insn (gen_rtx_SET (mode, operand0, gen_rtx_MEM (mode, scratch_reg)));      return 1;    }  /* Handle secondary reloads for SAR.  These occur when trying to load     the SAR from memory a FP register, or with a constant.  */  else if (GET_CODE (operand0) == REG	   && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS	   && (GET_CODE (operand1) == MEM	       || GET_CODE (operand1) == CONST_INT	       || (GET_CODE (operand1) == REG		   && FP_REG_CLASS_P (REGNO_REG_CLASS (REGNO (operand1)))))	   && scratch_reg)    {      /* D might not fit in 14 bits either; for such cases load D into	 scratch reg.  */      if (GET_CODE (operand1) == MEM	  && !memory_address_p (SImode, XEXP (operand1, 0)))	{	  emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));		  emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1,								        0)),						       SImode,						       XEXP (XEXP (operand1, 0),						       0),						       scratch_reg));	  emit_move_insn (scratch_reg, gen_rtx_MEM (GET_MODE (operand1),						    scratch_reg));	}      else	emit_move_insn (scratch_reg, operand1);      emit_move_insn (operand0, scratch_reg);      return 1;    }  /* Handle most common case: storing into a register.  */  else if (register_operand (operand0, mode))    {      if (register_operand (operand1, mode)	  || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))	  || (operand1 == CONST0_RTX (mode))	  || (GET_CODE (operand1) == HIGH	      && !symbolic_operand (XEXP (operand1, 0), VOIDmode))	  /* Only `general_operands' can come here, so MEM is ok.  */	  || GET_CODE (operand1) == MEM)	{	  /* Run this case quickly.  */	  emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));	  return 1;	}    }  else if (GET_CODE (operand0) == MEM)    {      if (mode == DFmode && operand1 == CONST0_RTX (mode)	  && !(reload_in_progress || reload_completed))	{	  rtx temp = gen_reg_rtx (DFmode);	  emit_insn (gen_rtx_SET (VOIDmode, temp, operand1));	  emit_insn (gen_rtx_SET (VOIDmode, operand0, temp));	  return 1;	}      if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))	{	  /* Run this case quickly.  */	  emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));	  return 1;	}      if (! (reload_in_progress || reload_completed))	{	  operands[0] = validize_mem (operand0);	  operands[1] = operand1 = force_reg (mode, operand1);	}    }  /* Simplify the source if we need to.     Note we do have to handle function labels here, even though we do     not consider them legitimate constants.  Loop optimizations can     call the emit_move_xxx with one as a source.  */  if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))      || function_label_operand (operand1, mode)      || (GET_CODE (operand1) == HIGH	  && symbolic_operand (XEXP (operand1, 0), mode)))    {      int ishighonly = 0;      if (GET_CODE (operand1) == HIGH)	{	  ishighonly = 1;	  operand1 = XEXP (operand1, 0);	}      if (symbolic_operand (operand1, mode))	{	  /* Argh.  The assembler and linker can't handle arithmetic	     involving plabels.	     So we force the plabel into memory, load operand0 from	     the memory location, then add in the constant part.  */	  if ((GET_CODE (operand1) == CONST	       && GET_CODE (XEXP (operand1, 0)) == PLUS	       && function_label_operand (XEXP (XEXP (operand1, 0), 0), Pmode))	      || function_label_operand (operand1, mode))	    {	      rtx temp, const_part;	      /* Figure out what (if any) scratch register to use.  */	      if (reload_in_progress || reload_completed)		scratch_reg = scratch_reg ? scratch_reg : operand0;	      else if (flag_pic)		scratch_reg = gen_reg_rtx (Pmode);	      if (GET_CODE (operand1) == CONST)		{		  /* Save away the constant part of the expression.  */		  const_part = XEXP (XEXP (operand1, 0), 1);		  if (GET_CODE (const_part) != CONST_INT)		    abort ();		  /* Force the function label into memory.  */		  temp = force_const_mem (mode, XEXP (XEXP (operand1, 0), 0));		}	      else		{		  /* No constant part.  */		  const_part = NULL_RTX;		  /* Force the function label into memory.  */		  temp = force_const_mem (mode, operand1);		}		

⌨️ 快捷键说明

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