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

📄 ip2k.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
     enum rtx_code code;     rtx dest;{#define operands ip2k_compare_operands  enum machine_mode mode;  operands[2] = dest;  mode = GET_MODE (operands[0]);  if ((mode != QImode) && (mode != HImode)      && (mode != SImode) && (mode != DImode))    mode = GET_MODE (operands[1]);  /* We have a fast path for a specific type of QImode compare.  We ought     to extend this for larger cases too but that wins less frequently and     introduces a lot of complexity.  */  if (mode == QImode      && !rtx_equal_p (operands[0], operands[2])      && !rtx_equal_p (operands[1], operands[2])      && (! REG_P (operands[2])	  || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 1)	      && ip2k_xexp_not_uses_reg_p (operands[1],					   REGNO (operands[2]), 1))))    {      OUT_AS1 (clr, %2);      if (immediate_operand (operands[1], QImode)	  && ((INTVAL (operands[1]) & 0xff) == 0xff))        {	  if (code == EQ)            OUT_AS2 (incsnz, w, %0);          else	    OUT_AS2 (incsz, w, %0);	}      else if (immediate_operand (operands[1], QImode)	       && ((INTVAL (operands[1]) & 0xff) == 0x01))	{	  if (code == EQ)            OUT_AS2 (decsnz, w, %0);          else	    OUT_AS2 (decsz, w, %0);	}      else if (ip2k_compare_operands[1] == const0_rtx)	{          OUT_AS2 (mov, w, %0);	  if (code == EQ)            OUT_AS1 (snz,);          else	    OUT_AS1 (sz,);	}      else	{          OUT_AS2 (mov, w, %0);	  if (code == EQ)            OUT_AS2 (csne, w, %1);          else	    OUT_AS2 (cse, w, %1);	}      OUT_AS1 (inc, %2);    }  else    {      if (ip2k_compare_operands[1] == const0_rtx)	{          switch (mode)            {            case QImode:              OUT_AS2 (mov, w, %0);              break;            case HImode:              OUT_AS2 (mov, w, %H0);              OUT_AS2 (or, w, %L0);              break;	    case SImode:              OUT_AS2 (mov, w, %A0);              OUT_AS2 (or, w, %B0);              OUT_AS2 (or, w, %C0);              OUT_AS2 (or, w, %D0);              break;	    case DImode:              OUT_AS2 (mov, w, %S0);              OUT_AS2 (or, w, %T0);              OUT_AS2 (or, w, %U0);              OUT_AS2 (or, w, %V0);              OUT_AS2 (or, w, %W0);              OUT_AS2 (or, w, %X0);              OUT_AS2 (or, w, %Y0);              OUT_AS2 (or, w, %Z0);              break;            default:   	      abort ();            }	}      else	{	  switch (mode)	    {	    case QImode:	      OUT_AS2 (mov, w, %1);	      OUT_AS2 (cmp, w, %0);	      break;	    case HImode:	      OUT_AS2 (mov, w, %H1);	      OUT_AS2 (cmp, w, %H0);	      OUT_AS1 (sz,);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %L1);	      OUT_AS2 (cmp, w, %L0);	      OUT_AS1 (2:,);	      break;	    case SImode:	      if (code == EQ)	        {	          OUT_AS2 (mov, w, #1);	          OUT_AS2 (mov, mulh, w);		}	      else		OUT_AS1 (clr, mulh);	      OUT_AS2 (mov, w, %A1);	      OUT_AS2 (cse, w, %A0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %B1);	      OUT_AS2 (cse, w, %B0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %C1);	      OUT_AS2 (cse, w, %C0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %D1);	      OUT_AS2 (cse, w, %D0);	      OUT_AS1 (2:,);	      if (code == EQ)	        OUT_AS1 (dec, mulh);	      else		OUT_AS1 (inc, mulh);	      OUT_AS2 (mov, w, mulh);	      OUT_AS2 (mov, %2, w);	      return "";	    case DImode:	      if (code == EQ)	        {	          OUT_AS2 (mov, w, #1);	          OUT_AS2 (mov, mulh, w);		}	      else		OUT_AS1 (clr, mulh);	      OUT_AS2 (mov, w, %S1);	      OUT_AS2 (cse, w, %S0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %T1);	      OUT_AS2 (cse, w, %T0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %U1);	      OUT_AS2 (cse, w, %U0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %V1);	      OUT_AS2 (cse, w, %V0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %W1);	      OUT_AS2 (cse, w, %W0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %X1);	      OUT_AS2 (cse, w, %X0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %Y1);	      OUT_AS2 (cse, w, %Y0);	      OUT_AS1 (page, 2f);	      OUT_AS1 (jmp, 2f);	      OUT_AS2 (mov, w, %Z1);	      OUT_AS2 (cse, w, %Z0);	      OUT_AS1 (2:,);	      if (code == EQ)	        OUT_AS1 (dec, mulh);	      else		OUT_AS1 (inc, mulh);	      OUT_AS2 (mov, w, mulh);	      OUT_AS2 (mov, %2, w);	      return "";            default:	      abort ();	    }	}      OUT_AS2 (mov, w, #0);      if (code == EQ)	OUT_AS1 (snz,);      else	OUT_AS1 (sz,);      OUT_AS1 (inc, wreg);      OUT_AS2 (mov, %2, w);    }  return "";#undef operands}const char *ip2k_gen_signed_comp_branch (insn, code, label)     rtx insn;     enum rtx_code code;     rtx label;{#define operands ip2k_compare_operands  enum machine_mode mode;  int can_use_skip = 0;  rtx ninsn;  operands[2] = label;  mode = GET_MODE (operands[0]);  if ((mode != QImode) && (mode != HImode)      && (mode != SImode) && (mode != DImode))    mode = GET_MODE (operands[1]);  /* Look for situations where we can just skip the next instruction instead     of skipping and then branching!  */  ninsn = next_real_insn (insn);  if (ninsn      && (recog_memoized (ninsn) >= 0)      && get_attr_skip (ninsn) == SKIP_YES)    {      rtx skip_tgt = next_nonnote_insn (next_real_insn (insn));      /* The first situation is where the target of the jump is one insn         after the jump insn and the insn being jumped is only one machine	 opcode long.  */      if (label == skip_tgt)        can_use_skip = 1;      else	{          /* If our skip target is in fact a code label then we ignore the             label and move onto the next useful instruction.  Nothing we do	     here has any effect on the use of skipping instructions.  */          if (GET_CODE (skip_tgt) == CODE_LABEL)	    skip_tgt = next_nonnote_insn (skip_tgt);          /* The second situation is where we have something of the form:               test_condition               skip_conditional               page/jump label             optional_label (this may or may not exist):               skippable_insn               page/jump label             In this case we can eliminate the first "page/jump label".  */	  if (GET_CODE (skip_tgt) == JUMP_INSN)	    {	      rtx set = single_set (skip_tgt);	      if (GET_CODE (XEXP (set, 0)) == PC	          && GET_CODE (XEXP (set, 1)) == LABEL_REF	          && label == JUMP_LABEL (skip_tgt))	        can_use_skip = 2;            }	}    }  /* gcc is a little braindead and does some rather stateful things while     inspecting attributes - we have to put this state back to what it's     supposed to be.  */  extract_constrain_insn_cached (insn);  if (ip2k_compare_operands[1] == const0_rtx) /* These are easier.  */    {      switch (code)        {	case LT:	  if (can_use_skip)       	    {	      OUT_AS2 (sb, %0, 7);	    }	  else	    {              OUT_AS2 (snb, %0, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);	    }	  break;	case GT:          switch (mode)	    {            case DImode:              OUT_AS2 (rl, w, %S0);              OUT_AS2 (mov, w, %S0);              OUT_AS2 (or, w, %T0);              OUT_AS2 (or, w, %U0);              OUT_AS2 (or, w, %V0);              OUT_AS2 (or, w, %W0);              OUT_AS2 (or, w, %X0);              OUT_AS2 (or, w, %Y0);              OUT_AS2 (or, w, %Z0); 	      OUT_AS1 (snz, );	      OUT_AS2 (setb, status, 0);	      OUT_AS2 (sb, status, 0);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            case SImode:              OUT_AS2 (rl, w, %A0);              OUT_AS2 (mov, w, %A0);              OUT_AS2 (or, w, %B0);              OUT_AS2 (or, w, %C0);              OUT_AS2 (or, w, %D0); 	      OUT_AS1 (snz, );	      OUT_AS2 (setb, status, 0);	      OUT_AS2 (sb, status, 0);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            case HImode:              OUT_AS2 (rl, w, %H0);              OUT_AS2 (mov, w, %H0);              OUT_AS2 (or, w, %L0); 	      OUT_AS1 (snz, );	      OUT_AS2 (setb, status, 0);	      OUT_AS2 (sb, status, 0);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            case QImode:              OUT_AS2 (mov, w, %0);	/* Will just do "sb w, 7".  */ 	      OUT_AS1 (snz, );	      OUT_AS2 (setb, wreg, 7);	      OUT_AS2 (sb, wreg, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            default:	      abort ();            }	  break;	case LE:          switch (mode)	    {            case DImode:              OUT_AS2 (mov, w, %S0);              OUT_AS2 (or, w, %T0);              OUT_AS2 (or, w, %U0);              OUT_AS2 (or, w, %V0);              OUT_AS2 (or, w, %W0);              OUT_AS2 (or, w, %X0);              OUT_AS2 (or, w, %Y0);              OUT_AS2 (or, w, %Z0);	/* Z is correct.  */	      OUT_AS1 (sz, );	      OUT_AS2 (snb, %S0, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            case SImode:              OUT_AS2 (mov, w, %A0);              OUT_AS2 (or, w, %B0);              OUT_AS2 (or, w, %C0);              OUT_AS2 (or, w, %D0);	/* Z is correct.  */	      OUT_AS1 (sz, );	      OUT_AS2 (snb, %A0, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            case HImode:              OUT_AS2 (mov, w, %H0);              OUT_AS2 (or, w, %L0);	      OUT_AS1 (sz, );	      OUT_AS2 (snb, %H0, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            case QImode:              OUT_AS2 (mov, w, %0);	/* Will just do "sb w, 7".  */	      OUT_AS1 (sz, );	      OUT_AS2 (snb, wreg, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);              break;            default:	      abort ();            }	  break;	case GE:	  if (can_use_skip)            {	      OUT_AS2 (snb, %0, 7);	    }	  else            {	      OUT_AS2 (sb, %0, 7);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);	    }	  break;	default:	  abort ();        }      return "";    }  /* signed compares are out of line because we can't get     the hardware to compute the overflow for us.  */  switch (mode)    {    case QImode:      OUT_AS1 (push, %1%<);      OUT_AS1 (push, %0%>);      OUT_AS1 (page, __cmpqi2);      OUT_AS1 (call, __cmpqi2);      break;    case HImode:      OUT_AS1 (push, %L1%<);      OUT_AS1 (push, %H1%<);      OUT_AS1 (push, %L0%<);      OUT_AS1 (push, %H0%>%>%>);      OUT_AS1 (page, __cmphi2);      OUT_AS1 (call, __cmphi2);      break;    case SImode:      OUT_AS1 (push, %D1%<);      OUT_AS1 (push, %C1%<);      OUT_AS1 (push, %B1%<);      OUT_AS1 (push, %A1%<);      OUT_AS1 (push, %D0%<);      OUT_AS1 (push, %C0%<);      OUT_AS1 (push, %B0%<);      OUT_AS1 (push, %A0%>%>%>%>%>%>%>);      OUT_AS1 (page, __cmpsi2);      OUT_AS1 (call, __cmpsi2);      break;      case DImode:      if (GET_CODE (operands[0]) == MEM	  && true_regnum (XEXP (operands[0], 0)) == REG_DP)	{	  OUT_AS1 (push, %Z1%<);	  OUT_AS1 (push, %Y1%<);	  OUT_AS1 (push, %X1%<);	  OUT_AS1 (push, %W1%<);	  OUT_AS1 (push, %V1%<);	  OUT_AS1 (push, %U1%<);	  OUT_AS1 (push, %T1%<);	  OUT_AS1 (push, %S1%>%>%>%>%>%>%>);	  OUT_AS1 (page, __cmpdi2_dp);	  OUT_AS1 (call, __cmpdi2_dp);	}      else	{	  OUT_AS1 (push, %Z1%<);	  OUT_AS1 (push, %Y1%<);	  OUT_AS1 (push, %X1%<);	  OUT_AS1 (push, %W1%<);	  OUT_AS1 (push, %V1%<);	  OUT_AS1 (push, %U1%<);	  OUT_AS1 (push, %T1%<);	  OUT_AS1 (push, %S1%<);	  OUT_AS1 (push, %Z0%<);	  OUT_AS1 (push, %Y0%<);	  OUT_AS1 (push, %X0%<);	  OUT_AS1 (push, %W0%<);	  OUT_AS1 (push, %V0%<);	  OUT_AS1 (push, %U0%<);	  OUT_AS1 (push, %T0%<);	  OUT_AS1 (push, %S0%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>);	  OUT_AS1 (page, __cmpdi2);	  OUT_AS1 (call, __cmpdi2);	}      break;    default:      abort ();  }  switch (code)    {    case LT:      if (can_use_skip)        {	  OUT_AS2 (cse, w, #0);	}      else	{          OUT_AS2 (csne, w, #0);          OUT_AS1 (page, %2);          OUT_AS1 (jmp, %2);	}      break;          case GT:      if (can_use_skip)	{	  OUT_AS2 (cse, w, #2);	}      else	{          OUT_AS2 (csne, w, #2);          OUT_AS1 (page, %2);          OUT_AS1 (jmp, %2);	}      break;    case LE:      if (can_use_skip)	{	  OUT_AS2 (snb, wreg, 1);	}      else	{          OUT_AS2 (sb, wreg, 1);          OUT_AS1 (page, %2);          OUT_AS1 (jmp, %2);	}      break;    case GE:      if (can_use_skip)	{	  OUT_AS2 (csne, w, #0);	}      else	{          OUT_AS2 (cse, w, #0);          OUT_AS1 (page, %2);          OUT_AS1 (jmp, %2);	}      break;          default:

⌨️ 快捷键说明

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