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

📄 ip2k.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
      abort ();    }  return "";#undef operands}const char *ip2k_gen_unsigned_comp_branch (insn, code, label)     rtx insn;     enum rtx_code code;     rtx label;{#define operands ip2k_compare_operands  enum machine_mode mode;  int imm_sub = 0;  int imm_cmp = 0;  int can_use_skip = 0;  rtx ninsn;  HOST_WIDE_INT const_low;  HOST_WIDE_INT const_high;  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)    {      switch (code)        {        case LEU:          code = EQ;			/* Nothing is LTU 0.  */          goto zero;        case GTU:			          code = NE;			/* Anything nonzero is GTU.  */          /* fall-thru  */        case EQ:        case NE:			/* Test all the bits, result in					   Z AND WREG.  */        zero:          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);              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 HImode:              OUT_AS2 (mov, w, %H0);              OUT_AS2 (or, w, %L0);              break;            case QImode:              OUT_AS2 (mov, w, %0);              break;            default:   	      abort ();            }	  if (can_use_skip)            {	      if (code == EQ)		OUT_AS1 (sz, );	      else		OUT_AS1 (snz, );            }	  else            {	      if (code == EQ)                OUT_AS1 (snz,);	      else	        OUT_AS1 (sz,);              OUT_AS1 (page, %2);              OUT_AS1 (jmp, %2);	    }          break;        case GEU:          /* Always succeed.  */          OUT_AS1 (page, %2);          OUT_AS1 (jmp, %2);          break;        case LTU:			          /* Always fail.  */          break;        default:          abort ();	}      return "";    }  /* Look at whether we have a constant as one of our operands.  If we do     and it's in the position that we use to subtract from during our     normal optimized comparison concept then we have to shuffle things     around!  */  if (mode != QImode)    {      if ((immediate_operand (operands[1], GET_MODE (operands[1]))	   && ((code == LEU) || (code == GTU)))	  || (immediate_operand (operands[0], GET_MODE (operands[0]))	      && ((code == LTU) || (code == GEU))))        {          imm_sub = 1;        }    }  /* Same as above - look if we have a constant that we can compare     for equality or non-equality.  If we know this then we can look     for common value eliminations.  Note that we want to ensure that     any immediate value is operand 1 to simplify the code later!  */  if ((code == EQ) || (code == NE))    {      imm_cmp = immediate_operand (operands[1], GET_MODE (operands[1]));      if (! imm_cmp)	{	  imm_cmp = immediate_operand (operands[0], GET_MODE (operands[0]));	  if (imm_cmp) 	    {	      rtx tmp = operands[1];	      operands[1] = operands[0];	      operands[0] = tmp;	    }	}    }    switch (mode)    {    case QImode:      switch (code)        {        case EQ:	  if (imm_cmp && ((INTVAL (operands[1]) & 0xff) == 0xff))	    OUT_AS2 (incsnz, w, %0);	  else if (imm_cmp && ((INTVAL (operands[1]) & 0xff) == 0x01))	    OUT_AS2 (decsnz, w, %0);	  else	    {              OUT_AS2 (mov, w, %1);	      OUT_AS2 (csne, w, %0);	    }	  OUT_AS1 (page, %2);	  OUT_AS1 (jmp, %2);	  break;	case NE:	  if (imm_cmp && ((INTVAL (operands[1]) & 0xff) == 0xff))	    OUT_AS2 (incsz, w, %0);	  else if (imm_cmp && ((INTVAL (operands[1]) & 0xff) == 0x01))	    OUT_AS2 (decsz, w, %0);	  else	    {              OUT_AS2 (mov, w, %1);	      OUT_AS2 (cse, w, %0);	    }	  OUT_AS1 (page, %2);	  OUT_AS1 (jmp, %2);	  break;	case GTU:	  OUT_AS2 (mov, w, %0);	  OUT_AS2 (cmp, w, %1);	  OUT_AS1 (sc,);	  OUT_AS1 (page, %2);	  OUT_AS1 (jmp, %2);	  break;	case GEU:	  OUT_AS2 (mov, w, %1);	  OUT_AS2 (cmp, w, %0);	  OUT_AS1 (snc,);	  OUT_AS1 (page, %2);	  OUT_AS1 (jmp, %2);	  break;	case LTU:	  OUT_AS2 (mov, w, %1);	  OUT_AS2 (cmp, w, %0);	  OUT_AS1 (sc,);	  OUT_AS1 (page, %2);	  OUT_AS1 (jmp, %2);	  break;	case LEU:	  OUT_AS2 (mov, w, %0);	  OUT_AS2 (cmp, w, %1);	  OUT_AS1 (snc,);	  OUT_AS1 (page, %2);	  OUT_AS1 (jmp, %2);	  break;	default:	  abort ();        }      break;    case HImode:      switch (code)        {	case EQ:	  {	    unsigned char h = 0, l = 1;	    if (imm_cmp)	      {	        h = (INTVAL (operands[1]) >> 8) & 0xff;	        l = INTVAL (operands[1]) & 0xff;		if ((h == 0xff) && (l == 0xff))	          {		    /* We should be able to do the following, but the		       IP2k simulator doesn't like it and we get a load		       of failures in gcc-c-torture.  */		    OUT_AS2 (incsnz, w, %L0);		    OUT_AS2 (incsz, w, %H0);/*		    OUT_AS1 (skip,);		   Should have this  */		    OUT_AS1 (page, 1f);/* Shouldn't need this!  */	            OUT_AS1 (jmp, 1f); /* Shouldn't need this either.  */		    OUT_AS1 (page, %2);	            OUT_AS1 (jmp, %2);	            OUT_AS1 (1:,);		    break;	          }		else if (h == 0)		  {		    if (l == 1)		      OUT_AS2 (dec, w, %L0);		    else		      {		        OUT_AS2 (mov, w, %L0);		        OUT_AS2 (sub, w, %L1);		      }		    OUT_AS2 (or, w, %H0);		    OUT_AS1 (snz,);		    OUT_AS1 (page, %2);	            OUT_AS1 (jmp, %2);		    break;		  }		else if (l == 0)		  {		    if (h == 1)		      OUT_AS2 (dec, w, %H0);		    else		      {		        OUT_AS2 (mov, w, %H0);		        OUT_AS2 (sub, w, %H1);		      }		    OUT_AS2 (or, w, %L0);		    OUT_AS1 (snz,);		    OUT_AS1 (page, %2);	            OUT_AS1 (jmp, %2);		    break;		  }	      }	    OUT_AS2 (mov, w, %H1);	    OUT_AS2 (cse, w, %H0);	    OUT_AS1 (page, 2f);	    OUT_AS1 (jmp, 2f);	    if (! imm_cmp || (h != l))	      OUT_AS2 (mov, w, %L1);	    OUT_AS2 (csne, w, %L0);	    OUT_AS1 (page, %2);	    OUT_AS1 (jmp, %2);	    OUT_AS1 (2:,);	  }          break;	case NE:	  {	    unsigned char h = 0, l = 1;	    if (imm_cmp)	      {	        h = (INTVAL (operands[1]) >> 8) & 0xff;	        l = INTVAL (operands[1]) & 0xff;		if ((h == 0xff) && (l == 0xff))	          {		    OUT_AS2 (incsnz, w, %L0);		    OUT_AS2 (incsz, w, %H0);		    OUT_AS1 (page, %2);	            OUT_AS1 (jmp, %2);		    break;	          }	    	else if (h == 0)		  {		    if (l == 1)		      OUT_AS2 (dec, w, %L0);		    else		      {		        OUT_AS2 (mov, w, %L0);		        OUT_AS2 (sub, w, %L1);		      }		    OUT_AS2 (or, w, %H0);		    OUT_AS1 (sz,);		    OUT_AS1 (page, %2);	            OUT_AS1 (jmp, %2);		    break;		  }		else if (l == 0)		  {		    if (h == 1)		      OUT_AS2 (dec, w, %H0);		    else		      {		        OUT_AS2 (mov, w, %H0);		        OUT_AS2 (sub, w, %H1);		      }		    OUT_AS2 (or, w, %L0);		    OUT_AS1 (sz,);		    OUT_AS1 (page, %2);	            OUT_AS1 (jmp, %2);		    break;		  }	      }	    OUT_AS2 (mov, w, %H1);	    if (imm_cmp && (h == l))	      {	        OUT_AS2 (csne, w, %H0);	        OUT_AS2 (cse, w, %L0);	      }	    else	      {	        OUT_AS2 (cse, w, %H0);	        OUT_AS1 (page, %2);	        OUT_AS1 (jmp, %2);	        OUT_AS2 (mov, w, %L1);	        OUT_AS2 (cse, w, %L0);	      }	    OUT_AS1 (page, %2);	    OUT_AS1 (jmp, %2);	  }	  break;	case GTU:	  if (imm_sub)	    {	      /* > 0xffff never suceeds!  */	      if ((INTVAL (operands[1]) & 0xffff) != 0xffff)		{	          operands[3] = GEN_INT (INTVAL (operands[1]) + 1);	          OUT_AS2 (mov, w, %L3);	          OUT_AS2 (sub, w, %L0);	          OUT_AS2 (mov, w, %H3);	          OUT_AS2 (subc, w, %H0);	          OUT_AS1 (snc,);	          OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	    }	  else	    {	      OUT_AS2 (mov, w, %L0);	      OUT_AS2 (sub, w, %L1);	      OUT_AS2 (mov, w, %H0);	      OUT_AS2 (subc, w, %H1);	      OUT_AS1 (sc,);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);	    }	  break;	case GEU:	  if (imm_sub)	    {	      if (INTVAL (operands[0]) == 0)		{                  OUT_AS2 (mov, w, %H1);                  OUT_AS2 (or, w, %L1);		  OUT_AS1 (snz,);	          OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	      else	        {	          operands[3] = GEN_INT (INTVAL (operands[0]) - 1);	          OUT_AS2 (mov, w, %L3);	          OUT_AS2 (sub, w, %L1);	          OUT_AS2 (mov, w, %H3);	          OUT_AS2 (subc, w, %H1);	          OUT_AS1 (sc,);	          OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	    }	  else	    {	      OUT_AS2 (mov, w, %L1);	      OUT_AS2 (sub, w, %L0);	      OUT_AS2 (mov, w, %H1);	      OUT_AS2 (subc, w, %H0);	      OUT_AS1 (snc,);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);	    }	  break;	case LTU:	  if (imm_sub)	    {	      if (INTVAL (operands[0]) == 0)	        {                  OUT_AS2 (mov, w, %H1);                  OUT_AS2 (or, w, %L1);		  OUT_AS1 (sz,);	          OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	      else	        {	          operands[3] = GEN_INT (INTVAL (operands[0]) - 1);	          OUT_AS2 (mov, w, %L3);	          OUT_AS2 (sub, w, %L1);	          OUT_AS2 (mov, w, %H3);	          OUT_AS2 (subc, w, %H1);	          OUT_AS1 (snc,);	          OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	    }	  else	    {	      OUT_AS2 (mov, w, %L1);	      OUT_AS2 (sub, w, %L0);	      OUT_AS2 (mov, w, %H1);	      OUT_AS2 (subc, w, %H0);	      OUT_AS1 (sc,);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);            } 	  break;	case LEU:	  if (imm_sub)	    {	      if ((INTVAL (operands[1]) & 0xffff) == 0xffff)	        {		  /* <= 0xffff always suceeds.  */		  OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	      else		{	          operands[3] = GEN_INT (INTVAL (operands[1]) + 1);	          OUT_AS2 (mov, w, %L3);	          OUT_AS2 (sub, w, %L0);	          OUT_AS2 (mov, w, %H3);	          OUT_AS2 (subc, w, %H0);	          OUT_AS1 (sc,);	          OUT_AS1 (page, %2);	          OUT_AS1 (jmp, %2);		}	    }	  else	    {	      OUT_AS2 (mov, w, %L0);	      OUT_AS2 (sub, w, %L1);	      OUT_AS2 (mov, w, %H0);	      OUT_AS2 (subc, w, %H1);	      OUT_AS1 (snc,);	      OUT_AS1 (page, %2);	      OUT_AS1 (jmp, %2);	    }	  break;	default:	  abort ();        }      break;    case SImode:      switch (code)        {	case EQ:	  {	    unsigned char a = 0, b = 1, c = 2, d = 3;	    if (imm_cmp)	      {	        a = (INTVAL (operands[1]) >> 24) & 0xff;	        b = (INTVAL (operands[1]) >> 16) & 0xff;                c = (INTVAL (operands[1]) >> 8) & 0xff;

⌨️ 快捷键说明

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