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

📄 c4x.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 5 页
字号:
                   gen_rtx_LSHIFTRT (HImode,                            gen_rtx_MULT (HImode,                                     gen_rtx (code, HImode, operands[1]),                                     gen_rtx (code, HImode, operands[2])),                                     GEN_INT (32)));  insns = get_insns ();  end_sequence ();  emit_libcall_block (insns, operands[0], ret, equiv);}/* Set the SYMBOL_REF_FLAG for a function decl.  However, wo do not   yet use this info.  */static voidc4x_encode_section_info (decl, first)     tree decl;     int first ATTRIBUTE_UNUSED;{  if (TREE_CODE (decl) == FUNCTION_DECL)       SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;}intc4x_check_legit_addr (mode, addr, strict)     enum machine_mode mode;     rtx addr;     int strict;{  rtx base = NULL_RTX;		/* Base register (AR0-AR7).  */  rtx indx = NULL_RTX;		/* Index register (IR0,IR1).  */  rtx disp = NULL_RTX;		/* Displacement.  */  enum rtx_code code;  code = GET_CODE (addr);  switch (code)    {      /* Register indirect with auto increment/decrement.  We don't	 allow SP here---push_operand should recognize an operand	 being pushed on the stack.  */    case PRE_DEC:    case PRE_INC:    case POST_DEC:      if (mode != QImode && mode != QFmode)	return 0;    case POST_INC:      base = XEXP (addr, 0);      if (! REG_P (base))	return 0;      break;    case PRE_MODIFY:    case POST_MODIFY:      {	rtx op0 = XEXP (addr, 0);	rtx op1 = XEXP (addr, 1);	if (mode != QImode && mode != QFmode)	  return 0;	if (! REG_P (op0) 	    || (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS))	  return 0;	base = XEXP (op1, 0);	if (base != op0)	  return 0;	if (REG_P (XEXP (op1, 1)))	  indx = XEXP (op1, 1);	else	  disp = XEXP (op1, 1);      }      break;	      /* Register indirect.  */    case REG:      base = addr;      break;      /* Register indirect with displacement or index.  */    case PLUS:      {	rtx op0 = XEXP (addr, 0);	rtx op1 = XEXP (addr, 1);	enum rtx_code code0 = GET_CODE (op0);	switch (code0)	  {	  case REG:	    if (REG_P (op1))	      {		base = op0;	/* Base + index.  */		indx = op1;		if (IS_INDEX_REG (base) || IS_ADDR_REG (indx))		  {		    base = op1;		    indx = op0;		  }	      }	    else	      {		base = op0;	/* Base + displacement.  */		disp = op1;	      }	    break;	  default:	    return 0;	  }      }      break;      /* Direct addressing with DP register.  */    case LO_SUM:      {	rtx op0 = XEXP (addr, 0);	rtx op1 = XEXP (addr, 1);	/* HImode and HFmode direct memory references aren't truly	   offsettable (consider case at end of data page).  We	   probably get better code by loading a pointer and using an	   indirect memory reference.  */	if (mode == HImode || mode == HFmode)	  return 0;	if (!REG_P (op0) || REGNO (op0) != DP_REGNO)	  return 0;	if ((GET_CODE (op1) == SYMBOL_REF || GET_CODE (op1) == LABEL_REF))	  return 1;	if (GET_CODE (op1) == CONST)	  return 1;	return 0;      }      break;      /* Direct addressing with some work for the assembler...  */    case CONST:      /* Direct addressing.  */    case LABEL_REF:    case SYMBOL_REF:      if (! TARGET_EXPOSE_LDP && ! strict && mode != HFmode && mode != HImode)	return 1;      /* These need to be converted to a LO_SUM (...). 	 LEGITIMIZE_RELOAD_ADDRESS will do this during reload.  */      return 0;      /* Do not allow direct memory access to absolute addresses.         This is more pain than it's worth, especially for the         small memory model where we can't guarantee that         this address is within the data page---we don't want         to modify the DP register in the small memory model,         even temporarily, since an interrupt can sneak in....  */    case CONST_INT:      return 0;      /* Indirect indirect addressing.  */    case MEM:      return 0;    case CONST_DOUBLE:      fatal_insn ("using CONST_DOUBLE for address", addr);    default:      return 0;    }  /* Validate the base register.  */  if (base)    {      /* Check that the address is offsettable for HImode and HFmode.  */      if (indx && (mode == HImode || mode == HFmode))	return 0;      /* Handle DP based stuff.  */      if (REGNO (base) == DP_REGNO)	return 1;      if (strict && ! REGNO_OK_FOR_BASE_P (REGNO (base)))	return 0;      else if (! strict && ! IS_ADDR_OR_PSEUDO_REG (base))	return 0;    }  /* Now validate the index register.  */  if (indx)    {      if (GET_CODE (indx) != REG)	return 0;      if (strict && ! REGNO_OK_FOR_INDEX_P (REGNO (indx)))	return 0;      else if (! strict && ! IS_INDEX_OR_PSEUDO_REG (indx))	return 0;    }  /* Validate displacement.  */  if (disp)    {      if (GET_CODE (disp) != CONST_INT)	return 0;      if (mode == HImode || mode == HFmode)	{	  /* The offset displacement must be legitimate.  */	  if (! IS_DISP8_OFF_CONST (INTVAL (disp)))	    return 0;	}      else	{	  if (! IS_DISP8_CONST (INTVAL (disp)))	    return 0;	}      /* Can't add an index with a disp.  */      if (indx)	return 0;		    }  return 1;}rtxc4x_legitimize_address (orig, mode)     rtx orig ATTRIBUTE_UNUSED;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (orig) == SYMBOL_REF      || GET_CODE (orig) == LABEL_REF)    {      if (mode == HImode || mode == HFmode)	{	  /* We need to force the address into	     a register so that it is offsettable.  */	  rtx addr_reg = gen_reg_rtx (Pmode);	  emit_move_insn (addr_reg, orig);	  return addr_reg;	}      else	{	  rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);	  	  if (! TARGET_SMALL)	    emit_insn (gen_set_ldp (dp_reg, orig));	  	  return gen_rtx_LO_SUM (Pmode, dp_reg, orig);	}    }  return NULL_RTX;}/* Provide the costs of an addressing mode that contains ADDR.   If ADDR is not a valid address, its cost is irrelevant.     This is used in cse and loop optimisation to determine   if it is worthwhile storing a common address into a register.    Unfortunately, the C4x address cost depends on other operands.  */int c4x_address_cost (addr)     rtx addr;{  switch (GET_CODE (addr))    {    case REG:      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:	    /* The following tries to improve GIV combination	       in strength reduce but appears not to help.  */	    if (TARGET_DEVEL && IS_UINT5_CONST (INTVAL (op1)))	      return 1;	    if (IS_DISP1_CONST (INTVAL (op1)))	      return 1;	    if (! TARGET_C3X && IS_UINT5_CONST (INTVAL (op1)))	      return 2;	    return 3;	  }      }    default:      break;    }    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)     const 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)	fprintf (file, "d");      return;    }  code = GET_CODE (op);  switch (letter)    {    case 'A':			/* Direct address.  */      if (code == CONST_INT || code == SYMBOL_REF || code == CONST)	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)	    {	      fprintf (file, "\t%s\t@", TARGET_C3X ? "ldp" : "ldpk");	      output_address (XEXP (adjust_address (op, VOIDmode, 1), 0));	      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))	{

⌨️ 快捷键说明

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