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

📄 c4x.c

📁 gcc编译工具没有什么特别
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If there is a label at the end of the loop we must insert     a NOP.  */  do {    insn = previous_insn (insn);  } while (GET_CODE (insn) == NOTE	   || GET_CODE (insn) == USE	   || GET_CODE (insn) == CLOBBER);  if (GET_CODE (insn) == CODE_LABEL)    return 1;  for (i = 0; i < 4; i++)    {      /* Search back for prev non-note and non-label insn.  */      while (GET_CODE (insn) == NOTE || GET_CODE (insn) == CODE_LABEL	     || GET_CODE (insn) == USE || GET_CODE (insn) == CLOBBER)	{	  if (insn == start_label)	    return i == 0;	  insn = previous_insn (insn);	};      /* If we have a jump instruction we should insert a NOP. If we	 hit repeat block top we should only insert a NOP if the loop	 is empty.  */      if (GET_CODE (insn) == JUMP_INSN)	return 1;      insn = previous_insn (insn);    }  return 0;}voidc4x_rptb_insert (insn)     rtx insn;{  rtx end_label;  rtx start_label;  rtx count_reg;  /* If the count register has not been allocated to RC, say if     there is a movstr pattern in the loop, then do not insert a     RPTB instruction.  Instead we emit a decrement and branch     at the end of the loop.  */  count_reg = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0), 0);  if (REGNO (count_reg) != RC_REGNO)    return;  /* Extract the start label from the jump pattern (rptb_end).  */  start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);    /* We'll have to update the basic blocks.  */  end_label = gen_label_rtx ();  emit_label_after (end_label, insn);  for (; insn; insn = PREV_INSN (insn))    if (insn == start_label)      break;  if (! insn)    fatal_insn ("c4x_rptb_insert: Cannot find start label", start_label);  /* We'll have to update the basic blocks.  */  emit_insn_before (gen_rptb_top (start_label, end_label), insn);}/* This function is a C4x special called immediately before delayed   branch scheduling.  We fix up RTPB style loops that didn't get RC   allocated as the loop counter.  */voidc4x_process_after_reload (first)     rtx first;{  rtx insn;  for (insn = first; insn; insn = NEXT_INSN (insn))    {      /* Look for insn.  */      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')	{	  int insn_code_number;	  insn_code_number = recog_memoized (insn);	  if (insn_code_number < 0)	    continue;	  /* Insert the RTX for RPTB at the top of the loop	     and a label at the end of the loop.  */	  if (insn_code_number == CODE_FOR_rptb_end)	    c4x_rptb_insert(insn);	  /* We split all insns here if they have a # for the output	     template.  */	  if (1)	    {	      const char *template;	      template = insn_template[insn_code_number];	      if (template && template[0] == '#' && template[1] == '\0')		{		  rtx new = try_split (PATTERN(insn), insn, 0);		  		  /* If we didn't split the insn, go away.  */		  if (new == insn && PATTERN (new) == PATTERN(insn))		    fatal_insn ("Couldn't split pattern", insn);		  PUT_CODE (insn, NOTE);		  NOTE_SOURCE_FILE (insn) = 0;		  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;		  insn = new;		}	    }	}    }}static intc4x_a_register (op)     rtx op;{  return REG_P (op) && IS_ADDR_OR_PSEUDO_REGNO (op);}static intc4x_x_register (op)     rtx op;{  return REG_P (op) && IS_INDEX_OR_PSEUDO_REGNO (op);}static intc4x_immed_int_constant (op)     rtx op;{  if (GET_CODE (op) != CONST_INT)    return 0;  return GET_MODE (op) == VOIDmode    || GET_MODE_CLASS (op) == MODE_INT    || GET_MODE_CLASS (op) == MODE_PARTIAL_INT;}static intc4x_immed_float_constant (op)     rtx op;{  if (GET_CODE (op) != CONST_DOUBLE)    return 0;  if (GET_CODE (XEXP (op, 0)) == MEM)    return 0;  return GET_MODE (op) == QFmode || GET_MODE (op) == HFmode;}intc4x_H_constant (op)     rtx op;{  return c4x_immed_float_constant (op) && c4x_immed_float_p (op);}intc4x_I_constant (op)     rtx op;{  return c4x_immed_int_constant (op) && IS_INT16_CONST (INTVAL (op));}intc4x_J_constant (op)     rtx op;{  if (TARGET_C3X)    return 0;  return c4x_immed_int_constant (op) && IS_INT8_CONST (INTVAL (op));}static intc4x_K_constant (op)     rtx op;{  if (TARGET_C3X || ! c4x_immed_int_constant (op))    return 0;  return IS_INT5_CONST (INTVAL (op));}intc4x_L_constant (op)     rtx op;{  return c4x_immed_int_constant (op) && IS_UINT16_CONST (INTVAL (op));}static intc4x_N_constant (op)     rtx op;{  return c4x_immed_int_constant (op) && IS_NOT_UINT16_CONST (INTVAL (op));}static intc4x_O_constant (op)     rtx op;{  return c4x_immed_int_constant (op) && IS_HIGH_CONST (INTVAL (op));}/* The constraints do not have to check the register class,   except when needed to discriminate between the constraints.   The operand has been checked by the predicates to be valid.  *//* ARx + 9-bit signed const or IRn   *ARx, *+ARx(n), *-ARx(n), *+ARx(IRn), *-Arx(IRn) for -256 < n < 256   We don't include the pre/post inc/dec forms here since   they are handled by the <> constraints.  */intc4x_Q_constraint (op)     rtx op;{  enum machine_mode mode = GET_MODE (op);  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  switch (GET_CODE (op))    {    case REG:      return 1;    case PLUS:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);	if (! REG_P (op0))	  return 0;	if (REG_P (op1))	  return 1;	if (GET_CODE (op1) != CONST_INT)	  return 0;	/* HImode and HFmode must be offsettable.  */	if (mode == HImode || mode == HFmode)	  return IS_DISP8_OFF_CONST (INTVAL (op1));		return IS_DISP8_CONST (INTVAL (op1));      }      break;    default:      break;    }  return 0;}/* ARx + 5-bit unsigned const   *ARx, *+ARx(n) for n < 32 */intc4x_R_constraint (op)     rtx op;{  enum machine_mode mode = GET_MODE (op);  if (TARGET_C3X)    return 0;  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  switch (GET_CODE (op))    {    case REG:      return 1;    case PLUS:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);	if (! REG_P (op0))	  return 0;	if (GET_CODE (op1) != CONST_INT)	  return 0;	/* HImode and HFmode must be offsettable.  */	if (mode == HImode || mode == HFmode)	  return IS_UINT5_CONST (INTVAL (op1) + 1);		return IS_UINT5_CONST (INTVAL (op1));      }      break;    default:      break;    }  return 0;}static intc4x_R_indirect (op)     rtx op;{  enum machine_mode mode = GET_MODE (op);  if (TARGET_C3X || GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  switch (GET_CODE (op))    {    case REG:      return IS_ADDR_OR_PSEUDO_REGNO (op);    case PLUS:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);	/* HImode and HFmode must be offsettable.  */	if (mode == HImode || mode == HFmode)	  return IS_ADDR_OR_PSEUDO_REGNO (op0)	    && GET_CODE (op1) == CONST_INT 	    && IS_UINT5_CONST (INTVAL (op1) + 1);	return REG_P (op0)	  && IS_ADDR_OR_PSEUDO_REGNO (op0)	  && GET_CODE (op1) == CONST_INT	  && IS_UINT5_CONST (INTVAL (op1));      }      break;    default:      break;    }  return 0;}/* ARx + 1-bit unsigned const or IRn   *ARx, *+ARx(1), *-ARx(1), *+ARx(IRn), *-Arx(IRn)   We don't include the pre/post inc/dec forms here since   they are handled by the <> constraints.  */intc4x_S_constraint (op)     rtx op;{  enum machine_mode mode = GET_MODE (op);  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  switch (GET_CODE (op))    {    case REG:      return 1;    case PRE_MODIFY:    case POST_MODIFY:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);		if ((GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)	    || (op0 != XEXP (op1, 0)))	  return 0;		op0 = XEXP (op1, 0);	op1 = XEXP (op1, 1);	return REG_P (op0) && REG_P (op1);	/* pre or post_modify with a displacement of 0 or 1 	   should not be generated.  */      }      break;    case PLUS:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);	if (!REG_P (op0))	  return 0;	if (REG_P (op1))	  return 1;	if (GET_CODE (op1) != CONST_INT)	  return 0;		/* HImode and HFmode must be offsettable.  */	if (mode == HImode || mode == HFmode)	  return IS_DISP1_OFF_CONST (INTVAL (op1));		return IS_DISP1_CONST (INTVAL (op1));      }      break;    default:      break;    }  return 0;}static intc4x_S_indirect (op)     rtx op;{  enum machine_mode mode = GET_MODE (op);  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  switch (GET_CODE (op))    {    case PRE_DEC:    case POST_DEC:      if (mode != QImode && mode != QFmode)	return 0;    case PRE_INC:    case POST_INC:      op = XEXP (op, 0);    case REG:      return IS_ADDR_OR_PSEUDO_REGNO (op);    case PRE_MODIFY:    case POST_MODIFY:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);		if (mode != QImode && mode != QFmode)	  return 0;	if ((GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)	    || (op0 != XEXP (op1, 0)))	  return 0;		op0 = XEXP (op1, 0);	op1 = XEXP (op1, 1);	return REG_P (op0) && IS_ADDR_OR_PSEUDO_REGNO (op0)	  && REG_P (op1) && IS_INDEX_OR_PSEUDO_REGNO (op1);	/* pre or post_modify with a displacement of 0 or 1 	   should not be generated.  */      }    case PLUS:      {	rtx op0 = XEXP (op, 0);	rtx op1 = XEXP (op, 1);	if (REG_P (op0))	  {	    /* HImode and HFmode must be offsettable.  */	    if (mode == HImode || mode == HFmode)	      return IS_ADDR_OR_PSEUDO_REGNO (op0)		&& GET_CODE (op1) == CONST_INT 		&& IS_DISP1_OFF_CONST (INTVAL (op1));	    if (REG_P (op1))	      return (IS_INDEX_OR_PSEUDO_REGNO (op1)		      && IS_ADDR_OR_PSEUDO_REGNO (op0))		|| (IS_ADDR_OR_PSEUDO_REGNO (op1)		    && IS_INDEX_OR_PSEUDO_REGNO (op0));	    	    return IS_ADDR_OR_PSEUDO_REGNO (op0)	      && GET_CODE (op1) == CONST_INT 	      && IS_DISP1_CONST (INTVAL (op1));	  }      }      break;    default:      break;    }  return 0;}/* Direct memory operand.  */intc4x_T_constraint (op)     rtx op;{  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  if (GET_CODE (op) != LO_SUM)    {      /* Allow call operands.  */      return GET_CODE (op) == SYMBOL_REF	&& GET_MODE (op) == Pmode	&& SYMBOL_REF_FLAG (op);    }  /* HImode and HFmode are not offsettable.  */  if (GET_MODE (op) == HImode || GE

⌨️ 快捷键说明

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