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

📄 c4x.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 5 页
字号:
	  fprintf (file, "%s\t@", TARGET_C3X ? "ldp" : "ldpk");          output_address (XEXP (op, 0));	  fprintf (file, "\n\t");	}      return;    case 'O':			/* Offset address.  */      if (code == MEM && c4x_autoinc_operand (op, Pmode))	break;      else if (code == MEM)	output_address (XEXP (adjust_address (op, VOIDmode, 1), 0));      else if (code == REG)	fprintf (file, "%s", reg_names[REGNO (op) + 1]);      else	fatal_insn ("c4x_print_operand: %%O inconsistency", op);      return;    case 'C':			/* Call.  */      break;    case 'U':			/* Call/callu.  */      if (code != SYMBOL_REF)	fprintf (file, "u");      return;    default:      break;    }    switch (code)    {    case REG:      if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT	  && ! TARGET_TI)	fprintf (file, "%s", float_reg_names[REGNO (op)]);      else	fprintf (file, "%s", reg_names[REGNO (op)]);      break;          case MEM:      output_address (XEXP (op, 0));      break;          case CONST_DOUBLE:      {	char str[64];		real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (op),			 sizeof (str), 0, 1);	fprintf (file, "%s", str);      }      break;          case CONST_INT:      fprintf (file, "%d", INTVAL (op));      break;          case NE:      fprintf (file, "ne");      break;          case EQ:      fprintf (file, "eq");      break;          case GE:      fprintf (file, "ge");      break;    case GT:      fprintf (file, "gt");      break;    case LE:      fprintf (file, "le");      break;    case LT:      fprintf (file, "lt");      break;    case GEU:      fprintf (file, "hs");      break;    case GTU:      fprintf (file, "hi");      break;    case LEU:      fprintf (file, "ls");      break;    case LTU:      fprintf (file, "lo");      break;    case SYMBOL_REF:      output_addr_const (file, op);      break;    case CONST:      output_addr_const (file, XEXP (op, 0));      break;    case CODE_LABEL:      break;    default:      fatal_insn ("c4x_print_operand: Bad operand case", op);      break;    }}voidc4x_print_operand_address (file, addr)     FILE *file;     rtx addr;{  switch (GET_CODE (addr))    {    case REG:      fprintf (file, "*%s", reg_names[REGNO (addr)]);      break;    case PRE_DEC:      fprintf (file, "*--%s", reg_names[REGNO (XEXP (addr, 0))]);      break;    case POST_INC:      fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);      break;    case POST_MODIFY:      {	rtx op0 = XEXP (XEXP (addr, 1), 0);	rtx op1 = XEXP (XEXP (addr, 1), 1);		if (GET_CODE (XEXP (addr, 1)) == PLUS && REG_P (op1))	  fprintf (file, "*%s++(%s)", reg_names[REGNO (op0)],		   reg_names[REGNO (op1)]);	else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) > 0)	  fprintf (file, "*%s++(%d)", reg_names[REGNO (op0)],		   INTVAL (op1));	else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) < 0)	  fprintf (file, "*%s--(%d)", reg_names[REGNO (op0)],		   -INTVAL (op1));	else if (GET_CODE (XEXP (addr, 1)) == MINUS && REG_P (op1))	  fprintf (file, "*%s--(%s)", reg_names[REGNO (op0)],		   reg_names[REGNO (op1)]);	else	  fatal_insn ("c4x_print_operand_address: Bad post_modify", addr);      }      break;          case PRE_MODIFY:      {	rtx op0 = XEXP (XEXP (addr, 1), 0);	rtx op1 = XEXP (XEXP (addr, 1), 1);		if (GET_CODE (XEXP (addr, 1)) == PLUS && REG_P (op1))	  fprintf (file, "*++%s(%s)", reg_names[REGNO (op0)],		   reg_names[REGNO (op1)]);	else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) > 0)	  fprintf (file, "*++%s(%d)", reg_names[REGNO (op0)],		   INTVAL (op1));	else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) < 0)	  fprintf (file, "*--%s(%d)", reg_names[REGNO (op0)],		   -INTVAL (op1));	else if (GET_CODE (XEXP (addr, 1)) == MINUS && REG_P (op1))	  fprintf (file, "*--%s(%s)", reg_names[REGNO (op0)],		   reg_names[REGNO (op1)]);	else	  fatal_insn ("c4x_print_operand_address: Bad pre_modify", addr);      }      break;          case PRE_INC:      fprintf (file, "*++%s", reg_names[REGNO (XEXP (addr, 0))]);      break;    case POST_DEC:      fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);      break;    case PLUS:			/* Indirect with displacement.  */      {	rtx op0 = XEXP (addr, 0);	rtx op1 = XEXP (addr, 1);	if (REG_P (op0))	  {	    if (REG_P (op1))	      {		if (IS_INDEX_REG (op0))		  {		    fprintf (file, "*+%s(%s)",			     reg_names[REGNO (op1)],			     reg_names[REGNO (op0)]);	/* Index + base.  */		  }		else		  {		    fprintf (file, "*+%s(%s)",			     reg_names[REGNO (op0)],			     reg_names[REGNO (op1)]);	/* Base + index.  */		  }	      }	    else if (INTVAL (op1) < 0)	      {		fprintf (file, "*-%s(%d)",			 reg_names[REGNO (op0)],			 -INTVAL (op1));	/* Base - displacement.  */	      }	    else	      {		fprintf (file, "*+%s(%d)",			 reg_names[REGNO (op0)],			 INTVAL (op1));	/* Base + displacement.  */	      }	  }	else          fatal_insn ("c4x_print_operand_address: Bad operand case", addr);      }      break;    case LO_SUM:      {	rtx op0 = XEXP (addr, 0);	rtx op1 = XEXP (addr, 1);	  	if (REG_P (op0) && REGNO (op0) == DP_REGNO)	  c4x_print_operand_address (file, op1);	else          fatal_insn ("c4x_print_operand_address: Bad operand case", addr);      }      break;    case CONST:    case SYMBOL_REF:    case LABEL_REF:      fprintf (file, "@");      output_addr_const (file, addr);      break;      /* We shouldn't access CONST_INT addresses.  */    case CONST_INT:    default:      fatal_insn ("c4x_print_operand_address: Bad operand case", addr);      break;    }}/* Return nonzero if the floating point operand will fit   in the immediate field.  */static intc4x_immed_float_p (op)     rtx op;{  long convval[2];  int exponent;  REAL_VALUE_TYPE r;  REAL_VALUE_FROM_CONST_DOUBLE (r, op);  if (GET_MODE (op) == HFmode)    REAL_VALUE_TO_TARGET_DOUBLE (r, convval);  else    {      REAL_VALUE_TO_TARGET_SINGLE (r, convval[0]);      convval[1] = 0;    }  /* Sign extend exponent.  */  exponent = (((convval[0] >> 24) & 0xff) ^ 0x80) - 0x80;  if (exponent == -128)    return 1;			/* 0.0  */  if ((convval[0] & 0x00000fff) != 0 || convval[1] != 0)    return 0;			/* Precision doesn't fit.  */  return (exponent <= 7)	/* Positive exp.  */    && (exponent >= -7);	/* Negative exp.  */}/* The last instruction in a repeat block cannot be a Bcond, DBcound,   CALL, CALLCond, TRAPcond, RETIcond, RETScond, IDLE, RPTB or RPTS.   None of the last four instructions from the bottom of the block can   be a BcondD, BRD, DBcondD, RPTBD, LAJ, LAJcond, LATcond, BcondAF,   BcondAT or RETIcondD.   This routine scans the four previous insns for a jump insn, and if   one is found, returns 1 so that we bung in a nop instruction.   This simple minded strategy will add a nop, when it may not   be required.  Say when there is a JUMP_INSN near the end of the   block that doesn't get converted into a delayed branch.   Note that we cannot have a call insn, since we don't generate   repeat loops with calls in them (although I suppose we could, but   there's no benefit.)     !!! FIXME.  The rptb_top insn may be sucked into a SEQUENCE.  */intc4x_rptb_nop_p (insn)     rtx insn;{  rtx start_label;  int i;  /* Extract the start label from the jump pattern (rptb_end).  */  start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);  /* 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;}/* The C4x looping instruction needs to be emitted at the top of the  loop.  Emitting the true RTL for a looping instruction at the top of  the loop can cause problems with flow analysis.  So instead, a dummy  doloop insn is emitted at the end of the loop.  This routine checks  for the presence of this doloop insn and then searches back to the  top of the loop, where it inserts the true looping insn (provided  there are no instructions in the loop which would cause problems).  Any additional labels can be emitted at this point.  In addition, if  the desired loop count register was not allocated, this routine does  nothing.   Before we can create a repeat block looping instruction we have to  verify that there are no jumps outside the loop and no jumps outside  the loop go into this loop. This can happen in the basic blocks reorder  pass. The C4x cpu can not handle this.  */static intc4x_label_ref_used_p (x, code_label)     rtx x, code_label;{  enum rtx_code code;  int i, j;  const char *fmt;  if (x == 0)    return 0;  code = GET_CODE (x);  if (code == LABEL_REF)    return INSN_UID (XEXP (x,0)) == INSN_UID (code_label);  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      if (fmt[i] == 'e')	{          if (c4x_label_ref_used_p (XEXP (x, i), code_label))	    return 1;	}      else if (fmt[i] == 'E')        for (j = XVECLEN (x, i) - 1; j >= 0; j--)          if (c4x_label_ref_used_p (XVECEXP (x, i, j), code_label))	    return 1;    }  return 0;}static intc4x_rptb_valid_p (insn, start_label)     rtx insn, start_label;{  rtx end = insn;  rtx start;  rtx tmp;  /* Find the start label.  */  for (; insn; insn = PREV_INSN (insn))    if (insn == start_label)      break;  /* Note found then we can not use a rptb or rpts.  The label was     probably moved by the basic block reorder pass.  */  if (! insn)    return 0;  start = insn;  /* If any jump jumps inside this block then we must fail.  */  for (insn = PREV_INSN (start); insn; insn = PREV_INSN (insn))    {      if (GET_CODE (insn) == CODE_LABEL)	{	  for (tmp = NEXT_INSN (start); tmp != end; tmp = NEXT_INSN(tmp))	    if (GET_CODE (tmp) == JUMP_INSN                && c4x_label_ref_used_p (tmp, insn))	      return 0;        }    }  for (insn = NEXT_INSN (end); insn; insn = NEXT_INSN (insn))    {      if (GET_CODE (insn) == CODE_LABEL)	{	  for (tmp = NEXT_INSN (start); tmp != end; tmp = NEXT_INSN(tmp))	    if (GET_CODE (tmp) == JUMP_INSN                && c4x_label_ref_used_p (tmp, insn))	      return 0;        }    }  /* If any jump jumps outside this block then we must fail.  */  for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))    {      if (GET_CODE (insn) == CODE_LABEL)	{	  for (tmp = NEXT_INSN (end); tmp; tmp = NEXT_INSN(tmp))	    if (GET_CODE (tmp) == JUMP_INSN                && c4x_label_ref_used_p (tmp, insn))	      return 0;	  for (tmp = PREV_INSN (start); tmp; tmp = PREV_INSN(tmp))	    if (GET_CODE (tmp) == JUMP_INSN                && c4x_label_ref_used_p (tmp, insn))	      return 0;        }    }  /* All checks OK.  */  return 1;}voidc4x_rptb_insert (insn)     rtx insn;{  rtx end_label;  rtx start_label;  rtx new_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;  

⌨️ 快捷键说明

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