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

📄 c4x.c

📁 gcc编译工具没有什么特别
💻 C
📖 第 1 页 / 共 5 页
字号:
      return 1;    case POST_INC:    case POST_DEC:    case PRE_INC:    case PRE_DEC:      return 1;            /* These shouldn't be directly generated.  */    case SYMBOL_REF:    case LABEL_REF:    case CONST:      return 10;    case LO_SUM:      {	rtx op1 = XEXP (addr, 1);	if (GET_CODE (op1) == LABEL_REF || GET_CODE (op1) == SYMBOL_REF)	  return TARGET_SMALL ? 3 : 4;		if (GET_CODE (op1) == CONST)	  {	    rtx offset = const0_rtx;	    	    op1 = eliminate_constant_term (op1, &offset);	    	    /* ??? These costs need rethinking...  */	    if (GET_CODE (op1) == LABEL_REF)	      return 3;	    	    if (GET_CODE (op1) != SYMBOL_REF)	      return 4;	    	    if (INTVAL (offset) == 0)	      return 3;	    return 4;	  }	fatal_insn ("c4x_address_cost: Invalid addressing mode", addr);      }      break;          case PLUS:      {	register rtx op0 = XEXP (addr, 0);	register rtx op1 = XEXP (addr, 1);		if (GET_CODE (op0) != REG)	  break;		switch (GET_CODE (op1))	  {	  default:	    break;	  case REG:	    /* This cost for REG+REG must be greater than the cost	       for REG if we want autoincrement addressing modes.  */	    return 2;	  case CONST_INT:	    if (IS_DISP1_CONST (INTVAL (op1)))	      return 1;	    if (! TARGET_C3X && IS_UINT5_CONST (INTVAL (op1)))	      return 2;	    return 3;	  }      }    default:    }    return 4;}rtxc4x_gen_compare_reg (code, x, y)     enum rtx_code code;     rtx x, y;{  enum machine_mode mode = SELECT_CC_MODE (code, x, y);  rtx cc_reg;  if (mode == CC_NOOVmode      && (code == LE || code == GE || code == LT || code == GT))    return NULL_RTX;  cc_reg = gen_rtx_REG (mode, ST_REGNO);  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,			  gen_rtx_COMPARE (mode, x, y)));  return cc_reg;}char *c4x_output_cbranch (form, seq)     char *form;     rtx seq;{  int delayed = 0;  int annultrue = 0;  int annulfalse = 0;  rtx delay;  char *cp;  static char str[100];    if (final_sequence)    {      delay = XVECEXP (final_sequence, 0, 1);      delayed = ! INSN_ANNULLED_BRANCH_P (seq);      annultrue = INSN_ANNULLED_BRANCH_P (seq) && ! INSN_FROM_TARGET_P (delay);      annulfalse = INSN_ANNULLED_BRANCH_P (seq) && INSN_FROM_TARGET_P (delay);    }  strcpy (str, form);  cp = &str [strlen (str)];  if (delayed)    {      *cp++ = '%';      *cp++ = '#';    }  if (annultrue)    {      *cp++ = 'a';      *cp++ = 't';    }  if (annulfalse)    {      *cp++ = 'a';       *cp++ = 'f';    }  *cp++ = '\t';  *cp++ = '%';   *cp++ = 'l';  *cp++ = '1';  *cp = 0;  return str;}voidc4x_print_operand (file, op, letter)     FILE *file;		/* file to write to */     rtx op;			/* operand to print */     int letter;		/* %<letter> or 0 */{  rtx op1;  enum rtx_code code;  switch (letter)    {    case '#':			/* delayed */      if (final_sequence)	asm_fprintf (file, "d");      return;    }  code = GET_CODE (op);  switch (letter)    {    case 'A':			/* direct address */      if (code == CONST_INT || code == SYMBOL_REF)	asm_fprintf (file, "@");      break;    case 'H':			/* sethi */      output_addr_const (file, op);      return;    case 'I':			/* reversed condition */      code = reverse_condition (code);      break;    case 'L':			/* log 2 of constant */      if (code != CONST_INT)	fatal_insn ("c4x_print_operand: %%L inconsistency", op);      fprintf (file, "%d", exact_log2 (INTVAL (op)));      return;    case 'N':			/* ones complement of small constant */      if (code != CONST_INT)	fatal_insn ("c4x_print_operand: %%N inconsistency", op);      fprintf (file, "%d", ~INTVAL (op));      return;    case 'K':			/* generate ldp(k) if direct address */      if (! TARGET_SMALL	  && code == MEM	  && GET_CODE (XEXP (op, 0)) == LO_SUM	  && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG	  && REGNO (XEXP (XEXP (op, 0), 0)) == DP_REGNO)	{	  op1 = XEXP (XEXP (op, 0), 1);          if (GET_CODE(op1) == CONST_INT || GET_CODE(op1) == SYMBOL_REF)	    {	      asm_fprintf (file, "\t%s\t", TARGET_C3X ? "ldp" : "ldpk");	      output_address (XEXP (adj_offsettable_operand (op, 1), 0));	      asm_fprintf (file, "\n");	    }	}      return;    case 'M':			/* generate ldp(k) if direct address */      if (! TARGET_SMALL		/* only used in asm statements */	  && code == MEM	  && (GET_CODE (XEXP (op, 0)) == CONST	      || GET_CODE (XEXP (op, 0)) == SYMBOL_REF))	{	  asm_fprintf (file, "%s\t", TARGET_C3X ? "ldp" : "ldpk");          output_address (XEXP (op, 0));	  asm_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 (adj_offsettable_operand (op, 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)	asm_fprintf (file, "u");      return;    default:      break;    }    switch (code)    {    case REG:      if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)	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[30];	REAL_VALUE_TYPE r;		REAL_VALUE_FROM_CONST_DOUBLE (r, op);	REAL_VALUE_TO_DECIMAL (r, "%20f", str);	fprintf (file, "%s", str);      }      break;          case CONST_INT:      fprintf (file, "%d", INTVAL (op));      break;          case NE:      asm_fprintf (file, "ne");      break;          case EQ:      asm_fprintf (file, "eq");      break;          case GE:      asm_fprintf (file, "ge");      break;    case GT:      asm_fprintf (file, "gt");      break;    case LE:      asm_fprintf (file, "le");      break;    case LT:      asm_fprintf (file, "lt");      break;    case GEU:      asm_fprintf (file, "hs");      break;    case GTU:      asm_fprintf (file, "hi");      break;    case LEU:      asm_fprintf (file, "ls");      break;    case LTU:      asm_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_REGNO (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);

⌨️ 快捷键说明

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