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

📄 v850.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* Return true if OP is a valid short EP memory reference */intep_memory_operand (rtx op, enum machine_mode mode, int unsigned_load){  rtx addr, op0, op1;  int max_offset;  int mask;  if (GET_CODE (op) != MEM)    return FALSE;  max_offset = ep_memory_offset (mode, unsigned_load);  mask = GET_MODE_SIZE (mode) - 1;  addr = XEXP (op, 0);  if (GET_CODE (addr) == CONST)    addr = XEXP (addr, 0);  switch (GET_CODE (addr))    {    default:      break;    case SYMBOL_REF:      return SYMBOL_REF_TDA_P (addr);    case REG:      return REGNO (addr) == EP_REGNUM;    case PLUS:      op0 = XEXP (addr, 0);      op1 = XEXP (addr, 1);      if (GET_CODE (op1) == CONST_INT	  && INTVAL (op1) < max_offset	  && INTVAL (op1) >= 0	  && (INTVAL (op1) & mask) == 0)	{	  if (GET_CODE (op0) == REG && REGNO (op0) == EP_REGNUM)	    return TRUE;	  if (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_TDA_P (op0))	    return TRUE;	}      break;    }  return FALSE;}/* Return true if OP is either a register or 0 */intreg_or_0_operand (rtx op, enum machine_mode mode){  if (GET_CODE (op) == CONST_INT)    return INTVAL (op) == 0;  else if (GET_CODE (op) == CONST_DOUBLE)    return CONST_DOUBLE_OK_FOR_G (op);  else    return register_operand (op, mode);}/* Return true if OP is either a register or a signed five bit integer */intreg_or_int5_operand (rtx op, enum machine_mode mode){  if (GET_CODE (op) == CONST_INT)    return CONST_OK_FOR_J (INTVAL (op));  else    return register_operand (op, mode);}/* Return true if OP is either a register or a signed nine bit integer.  */intreg_or_int9_operand (rtx op, enum machine_mode mode){  if (GET_CODE (op) == CONST_INT)    return CONST_OK_FOR_O (INTVAL (op));  return register_operand (op, mode);}/* Return true if OP is either a register or a const integer.  */intreg_or_const_operand (rtx op, enum machine_mode mode){  if (GET_CODE (op) == CONST_INT)    return TRUE;  return register_operand (op, mode);}/* Return true if OP is a valid call operand.  */intcall_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  /* Only registers are valid call operands if TARGET_LONG_CALLS.  */  if (TARGET_LONG_CALLS)    return GET_CODE (op) == REG;  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);}intspecial_symbolref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  if (GET_CODE (op) == CONST      && GET_CODE (XEXP (op, 0)) == PLUS      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT      && CONST_OK_FOR_K (INTVAL (XEXP (XEXP (op, 0), 1))))    op = XEXP (XEXP (op, 0), 0);  if (GET_CODE (op) == SYMBOL_REF)    return (SYMBOL_REF_FLAGS (op)	    & (SYMBOL_FLAG_ZDA | SYMBOL_FLAG_TDA | SYMBOL_FLAG_SDA)) != 0;  return FALSE;}intmovsi_source_operand (rtx op, enum machine_mode mode){  /* Some constants, as well as symbolic operands     must be done with HIGH & LO_SUM patterns.  */  if (CONSTANT_P (op)      && GET_CODE (op) != HIGH      && !(GET_CODE (op) == CONST_INT           && (CONST_OK_FOR_J (INTVAL (op))               || CONST_OK_FOR_K (INTVAL (op))               || CONST_OK_FOR_L (INTVAL (op)))))    return special_symbolref_operand (op, mode);  else    return general_operand (op, mode);}intpower_of_two_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){  if (GET_CODE (op) != CONST_INT)    return 0;  if (exact_log2 (INTVAL (op)) == -1)    return 0;  return 1;}intnot_power_of_two_operand (rtx op, enum machine_mode mode){  unsigned int mask;  if (mode == QImode)    mask = 0xff;  else if (mode == HImode)    mask = 0xffff;  else if (mode == SImode)    mask = 0xffffffff;  else    return 0;  if (GET_CODE (op) != CONST_INT)    return 0;  if (exact_log2 (~INTVAL (op) & mask) == -1)    return 0;  return 1;}/* Substitute memory references involving a pointer, to use the ep pointer,   taking care to save and preserve the ep.  */static voidsubstitute_ep_register (rtx first_insn,                        rtx last_insn,                        int uses,                        int regno,                        rtx * p_r1,                        rtx * p_ep){  rtx reg = gen_rtx_REG (Pmode, regno);  rtx insn;  if (!*p_r1)    {      regs_ever_live[1] = 1;      *p_r1 = gen_rtx_REG (Pmode, 1);      *p_ep = gen_rtx_REG (Pmode, 30);    }  if (TARGET_DEBUG)    fprintf (stderr, "\Saved %d bytes (%d uses of register %s) in function %s, starting as insn %d, ending at %d\n",	     2 * (uses - 3), uses, reg_names[regno],	     IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),	     INSN_UID (first_insn), INSN_UID (last_insn));  if (GET_CODE (first_insn) == NOTE)    first_insn = next_nonnote_insn (first_insn);  last_insn = next_nonnote_insn (last_insn);  for (insn = first_insn; insn && insn != last_insn; insn = NEXT_INSN (insn))    {      if (GET_CODE (insn) == INSN)	{	  rtx pattern = single_set (insn);	  /* Replace the memory references.  */	  if (pattern)	    {	      rtx *p_mem;	      /* Memory operands are signed by default.  */	      int unsignedp = FALSE;	      if (GET_CODE (SET_DEST (pattern)) == MEM		  && GET_CODE (SET_SRC (pattern)) == MEM)		p_mem = (rtx *)0;	      else if (GET_CODE (SET_DEST (pattern)) == MEM)		p_mem = &SET_DEST (pattern);	      else if (GET_CODE (SET_SRC (pattern)) == MEM)		p_mem = &SET_SRC (pattern);	      else if (GET_CODE (SET_SRC (pattern)) == SIGN_EXTEND		       && GET_CODE (XEXP (SET_SRC (pattern), 0)) == MEM)		p_mem = &XEXP (SET_SRC (pattern), 0);	      else if (GET_CODE (SET_SRC (pattern)) == ZERO_EXTEND		       && GET_CODE (XEXP (SET_SRC (pattern), 0)) == MEM)		{		  p_mem = &XEXP (SET_SRC (pattern), 0);		  unsignedp = TRUE;		}	      else		p_mem = (rtx *)0;	      if (p_mem)		{		  rtx addr = XEXP (*p_mem, 0);		  if (GET_CODE (addr) == REG && REGNO (addr) == (unsigned) regno)		    *p_mem = change_address (*p_mem, VOIDmode, *p_ep);		  else if (GET_CODE (addr) == PLUS			   && GET_CODE (XEXP (addr, 0)) == REG			   && REGNO (XEXP (addr, 0)) == (unsigned) regno			   && GET_CODE (XEXP (addr, 1)) == CONST_INT			   && ((INTVAL (XEXP (addr, 1)))			       < ep_memory_offset (GET_MODE (*p_mem),						   unsignedp))			   && ((INTVAL (XEXP (addr, 1))) >= 0))		    *p_mem = change_address (*p_mem, VOIDmode,					     gen_rtx_PLUS (Pmode,							   *p_ep,							   XEXP (addr, 1)));		}	    }	}    }  /* Optimize back to back cases of ep <- r1 & r1 <- ep.  */  insn = prev_nonnote_insn (first_insn);  if (insn && GET_CODE (insn) == INSN      && GET_CODE (PATTERN (insn)) == SET      && SET_DEST (PATTERN (insn)) == *p_ep      && SET_SRC (PATTERN (insn)) == *p_r1)    delete_insn (insn);  else    emit_insn_before (gen_rtx_SET (Pmode, *p_r1, *p_ep), first_insn);  emit_insn_before (gen_rtx_SET (Pmode, *p_ep, reg), first_insn);  emit_insn_before (gen_rtx_SET (Pmode, *p_ep, *p_r1), last_insn);}/* TARGET_MACHINE_DEPENDENT_REORG.  On the 850, we use it to implement   the -mep mode to copy heavily used pointers to ep to use the implicit   addressing.  */static voidv850_reorg (void){  struct  {    int uses;    rtx first_insn;    rtx last_insn;  }  regs[FIRST_PSEUDO_REGISTER];  int i;  int use_ep = FALSE;  rtx r1 = NULL_RTX;  rtx ep = NULL_RTX;  rtx insn;  rtx pattern;  /* If not ep mode, just return now.  */  if (!TARGET_EP)    return;  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)    {      regs[i].uses = 0;      regs[i].first_insn = NULL_RTX;      regs[i].last_insn = NULL_RTX;    }  for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))    {      switch (GET_CODE (insn))	{	  /* End of basic block */	default:	  if (!use_ep)	    {	      int max_uses = -1;	      int max_regno = -1;	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)		{		  if (max_uses < regs[i].uses)		    {		      max_uses = regs[i].uses;		      max_regno = i;		    }		}	      if (max_uses > 3)		substitute_ep_register (regs[max_regno].first_insn,					regs[max_regno].last_insn,					max_uses, max_regno, &r1, &ep);	    }	  use_ep = FALSE;	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)	    {	      regs[i].uses = 0;	      regs[i].first_insn = NULL_RTX;	      regs[i].last_insn = NULL_RTX;	    }	  break;	case NOTE:	  break;	case INSN:	  pattern = single_set (insn);	  /* See if there are any memory references we can shorten */	  if (pattern)	    {	      rtx src = SET_SRC (pattern);	      rtx dest = SET_DEST (pattern);	      rtx mem;	      /* Memory operands are signed by default.  */	      int unsignedp = FALSE;	      /* We might have (SUBREG (MEM)) here, so just get rid of the		 subregs to make this code simpler.  */	      if (GET_CODE (dest) == SUBREG		  && (GET_CODE (SUBREG_REG (dest)) == MEM		      || GET_CODE (SUBREG_REG (dest)) == REG))		alter_subreg (&dest);	      if (GET_CODE (src) == SUBREG		  && (GET_CODE (SUBREG_REG (src)) == MEM		      || GET_CODE (SUBREG_REG (src)) == REG))		alter_subreg (&src);	      if (GET_CODE (dest) == MEM && GET_CODE (src) == MEM)		mem = NULL_RTX;	      else if (GET_CODE (dest) == MEM)		mem = dest;	      else if (GET_CODE (src) == MEM)		mem = src;	      else if (GET_CODE (src) == SIGN_EXTEND		       && GET_CODE (XEXP (src, 0)) == MEM)		mem = XEXP (src, 0);	      else if (GET_CODE (src) == ZERO_EXTEND		       && GET_CODE (XEXP (src, 0)) == MEM)		{		  mem = XEXP (src, 0);		  unsignedp = TRUE;		}	      else		mem = NULL_RTX;	      if (mem && ep_memory_operand (mem, GET_MODE (mem), unsignedp))		use_ep = TRUE;	      else if (!use_ep && mem		       && GET_MODE_SIZE (GET_MODE (mem)) <= UNITS_PER_WORD)		{		  rtx addr = XEXP (mem, 0);		  int regno = -1;		  int short_p;		  if (GET_CODE (addr) == REG)		    {		      short_p = TRUE;		      regno = REGNO (addr);		    }		  else if (GET_CODE (addr) == PLUS			   && GET_CODE (XEXP (addr, 0)) == REG			   && GET_CODE (XEXP (addr, 1)) == CONST_INT			   && ((INTVAL (XEXP (addr, 1)))			       < ep_memory_offset (GET_MODE (mem), unsignedp))			   && ((INTVAL (XEXP (addr, 1))) >= 0))		    {		      short_p = TRUE;		      regno = REGNO (XEXP (addr, 0));		    }		  else		    short_p = FALSE;		  if (short_p)		    {		      regs[regno].uses++;		      regs[regno].last_insn = insn;		      if (!regs[regno].first_insn)			regs[regno].first_insn = insn;		    }		}	      /* Loading up a register in the basic block zaps any savings		 for the register */	      if (GET_CODE (dest) == REG)		{		  enum machine_mode mode = GET_MODE (dest);		  int regno;		  int endregno;		  regno = REGNO (dest);		  endregno = regno + HARD_REGNO_NREGS (regno, mode);		  if (!use_ep)		    {		      /* See if we can use the pointer before this			 modification.  */		      int max_uses = -1;		      int max_regno = -1;		      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)			{			  if (max_uses < regs[i].uses)			    {			      max_uses = regs[i].uses;			      max_regno = i;			    }			}		      if (max_uses > 3			  && max_regno >= regno			  && max_regno < endregno)			{			  substitute_ep_register (regs[max_regno].first_insn,						  regs[max_regno].last_insn,						  max_uses, max_regno, &r1,						  &ep);			  /* Since we made a substitution, zap all remembered			     registers.  */			  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)			    {			      regs[i].uses = 0;			      regs[i].first_insn = NULL_RTX;			      regs[i].last_insn = NULL_RTX;			    }			}		    }		  for (i = regno; i < endregno; i++)		    {		      regs[i].uses = 0;		      regs[i].first_insn = NULL_RTX;		      regs[i].last_insn = NULL_RTX;		    }		}	    }	}    }}/* # of registers saved by the interrupt handler.  */#define INTERRUPT_FIXED_NUM 4/* # of bytes for registers saved by the interrupt handler.  */#define INTERRUPT_FIXED_SAVE_SIZE (4 * INTERRUPT_FIXED_NUM)/* # of registers saved in register parameter area.  */#define INTERRUPT_REGPARM_NUM 4/* # of words saved for other registers.  */#define INTERRUPT_ALL_SAVE_NUM \  (30 - INTERRUPT_FIXED_NUM + INTERRUPT_REGPARM_NUM)#define INTERRUPT_ALL_SAVE_SIZE (4 * INTERRUPT_ALL_SAVE_NUM)

⌨️ 快捷键说明

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