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

📄 crx.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 3 页
字号:
      if (next_param == (tree) 0 && TREE_VALUE (param) != void_type_node)	{	  cum->ints = -1;	  return;	}    }}/* Implements the macro FUNCTION_ARG_ADVANCE defined in crx.h.  */voidcrx_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode,		      tree type, int named ATTRIBUTE_UNUSED){  /* l holds the number of registers required */  int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;  /* If the parameter isn't passed on a register don't advance cum.  */  if (!last_parm_in_reg)    return;  if (targetm.calls.must_pass_in_stack (mode, type) || (cum->ints < 0))    return;  if (mode == SImode || mode == HImode || mode == QImode || mode == DImode)    {      if (l <= 1)	cum->ints += 1;      else	cum->ints += l;    }  else if (mode == SFmode || mode == DFmode)    cum->ints += l;  else if ((mode) == BLKmode)    {      if ((l = enough_regs_for_param (cum, type, mode)) != 0)	cum->ints += l;    }}/* Implements the macro FUNCTION_ARG_REGNO_P defined in crx.h.  Return nonzero * if N is a register used for passing parameters.  */intcrx_function_arg_regno_p (int n){  return (n <= MAX_REG_FOR_PASSING_ARGS && n >= MIN_REG_FOR_PASSING_ARGS);}/* ADDRESSING MODES *//* ---------------- *//* Implements the macro GO_IF_LEGITIMATE_ADDRESS defined in crx.h. * The following addressing modes are supported on CRX: * * Relocations		--> const | symbol_ref | label_ref * Absolute address	--> 32 bit absolute * Post increment	--> reg + 12 bit disp. * Post modify		--> reg + 12 bit disp. * Register relative	--> reg | 32 bit disp. + reg | 4 bit + reg * Scaled index		--> reg + reg | 22 bit disp. + reg + reg | *			    22 disp. + reg + reg + (2 | 4 | 8) */static int crx_addr_reg_p (rtx addr_reg){  rtx reg;  if (REG_P (addr_reg))    {      reg = addr_reg;    }  else if ((GET_CODE (addr_reg) == SUBREG	   && REG_P (SUBREG_REG (addr_reg))	   && GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))	   <= UNITS_PER_WORD))    {      reg = SUBREG_REG (addr_reg);    }  else    return FALSE;  if (GET_MODE (addr_reg) != Pmode)    {      return FALSE;    }  return TRUE;}enum crx_addrtypecrx_decompose_address (rtx addr, struct crx_address *out){  rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;  rtx scale_rtx = NULL_RTX, side_effect = NULL_RTX;  int scale = -1;    enum crx_addrtype retval = CRX_INVALID;  switch (GET_CODE (addr))    {    case CONST_INT:      /* Absolute address (known at compile time) */      retval = CRX_ABSOLUTE;      disp = addr;      if (!UNSIGNED_INT_FITS_N_BITS (INTVAL (disp), GET_MODE_BITSIZE (Pmode)))	return CRX_INVALID;      break;          case CONST:    case SYMBOL_REF:    case LABEL_REF:      /* Absolute address (known at link time) */      retval = CRX_ABSOLUTE;      disp = addr;      break;    case REG:    case SUBREG:      /* Register relative address */      retval = CRX_REG_REL;      base = addr;      break;    case PLUS:      switch (GET_CODE (XEXP (addr, 0)))	{	case REG:	case SUBREG:	  if (REG_P (XEXP (addr, 1)))	    {	      /* Scaled index with scale = 1 and disp. = 0 */	      retval = CRX_SCALED_INDX;	      base = XEXP (addr, 1);	      index = XEXP (addr, 0); 	      scale = 1;	    }	  else if (RTX_SIGNED_INT_FITS_N_BITS (XEXP (addr, 1), 28))	    {	      /* Register relative address and <= 28-bit disp. */	      retval = CRX_REG_REL;	      base = XEXP (addr, 0);	      disp = XEXP (addr, 1);	    }	  else	    return CRX_INVALID;	  break;	case PLUS:	  /* Scaled index and <= 22-bit disp. */	  retval = CRX_SCALED_INDX;	  base = XEXP (XEXP (addr, 0), 1); 	  disp = XEXP (addr, 1);	  if (!RTX_SIGNED_INT_FITS_N_BITS (disp, 22))	    return CRX_INVALID;	  switch (GET_CODE (XEXP (XEXP (addr, 0), 0)))	    {	    case REG:	      /* Scaled index with scale = 0 and <= 22-bit disp. */	      index = XEXP (XEXP (addr, 0), 0); 	      scale = 1;	      break;	      	    case MULT:	      /* Scaled index with scale >= 0 and <= 22-bit disp. */	      index = XEXP (XEXP (XEXP (addr, 0), 0), 0); 	      scale_rtx = XEXP (XEXP (XEXP (addr, 0), 0), 1); 	      if ((scale = SCALE_FOR_INDEX_P (scale_rtx)) == -1)		return CRX_INVALID;	      break;	    default:	      return CRX_INVALID;	    }	  break;	  	case MULT:	  /* Scaled index with scale >= 0 */	  retval = CRX_SCALED_INDX;	  base = XEXP (addr, 1); 	  index = XEXP (XEXP (addr, 0), 0); 	  scale_rtx = XEXP (XEXP (addr, 0), 1); 	  /* Scaled index with scale >= 0 and <= 22-bit disp. */	  if ((scale = SCALE_FOR_INDEX_P (scale_rtx)) == -1)	    return CRX_INVALID;	  break;	default:	  return CRX_INVALID;	}      break;    case POST_INC:    case POST_DEC:      /* Simple post-increment */      retval = CRX_POST_INC;      base = XEXP (addr, 0);      side_effect = addr;      break;    case POST_MODIFY:      /* Generic post-increment with <= 12-bit disp. */      retval = CRX_POST_INC;      base = XEXP (addr, 0);      side_effect = XEXP (addr, 1);      if (base != XEXP (side_effect, 0))	return CRX_INVALID;      switch (GET_CODE (side_effect))	{	case PLUS:	case MINUS:	  disp = XEXP (side_effect, 1);	  if (!RTX_SIGNED_INT_FITS_N_BITS (disp, 12))	    return CRX_INVALID;	  break;	default:	  /* CRX only supports PLUS and MINUS */	  return CRX_INVALID;	}      break;    default:      return CRX_INVALID;    }  if (base && !crx_addr_reg_p (base)) return CRX_INVALID;  if (index && !crx_addr_reg_p (index)) return CRX_INVALID;    out->base = base;  out->index = index;  out->disp = disp;  out->scale = scale;  out->side_effect = side_effect;  return retval;}intcrx_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,			  rtx addr, int strict){  enum crx_addrtype addrtype;  struct crx_address address;						   if (TARGET_DEBUG_ADDR)    {      fprintf (stderr,               "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",               GET_MODE_NAME (mode), strict);      debug_rtx (addr);    }    addrtype = crx_decompose_address (addr, &address);  if (addrtype == CRX_POST_INC && GET_MODE_SIZE (mode) > UNITS_PER_WORD)    return FALSE;  if (TARGET_DEBUG_ADDR)    {      const char *typestr;      switch (addrtype)	{	case CRX_INVALID:	  typestr = "Invalid";	  break;	case CRX_REG_REL:	  typestr = "Register relative";	  break;	case CRX_POST_INC:	  typestr = "Post-increment";	  break;	case CRX_SCALED_INDX:	  typestr = "Scaled index";	  break;	case CRX_ABSOLUTE:	  typestr = "Absolute";	  break;	default:	  abort ();	}      fprintf (stderr, "CRX Address type: %s\n", typestr);    }    if (addrtype == CRX_INVALID)    return FALSE;  if (strict)    {      if (address.base && !REGNO_OK_FOR_BASE_P (REGNO (address.base)))	{	  if (TARGET_DEBUG_ADDR)	    fprintf (stderr, "Base register not strict\n");	  return FALSE;	}      if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index)))	{	  if (TARGET_DEBUG_ADDR)	    fprintf (stderr, "Index register not strict\n");	  return FALSE;	}    }  return TRUE;}/* ROUTINES TO COMPUTE COSTS *//* ------------------------- *//* Return cost of the memory address x. */static intcrx_address_cost (rtx addr){  enum crx_addrtype addrtype;  struct crx_address address;						   int cost = 2;    addrtype = crx_decompose_address (addr, &address);    gcc_assert (addrtype != CRX_INVALID);  /* An absolute address causes a 3-word instruction */  if (addrtype == CRX_ABSOLUTE)    cost+=2;    /* Post-modifying addresses are more powerful.  */  if (addrtype == CRX_POST_INC)    cost-=2;  /* Attempt to minimize number of registers in the address. */  if (address.base)    cost++;    if (address.index && address.scale == 1)    cost+=5;  if (address.disp && !INT_CST4 (INTVAL (address.disp)))    cost+=2;  if (TARGET_DEBUG_ADDR)    {      fprintf (stderr, "\n======\nTARGET_ADDRESS_COST = %d\n", cost);      debug_rtx (addr);    }    return cost;}/* Return the cost of moving data of mode MODE between a register of class * CLASS and memory; IN is zero if the value is to be written to memory, * nonzero if it is to be read in. This cost is relative to those in * REGISTER_MOVE_COST.  */intcrx_memory_move_cost (enum machine_mode mode,		  enum reg_class class ATTRIBUTE_UNUSED,		  int in ATTRIBUTE_UNUSED){  /* One LD or ST takes twice the time of a simple reg-reg move */  if (reg_classes_intersect_p (class, GENERAL_REGS))    {      /* printf ("GENERAL_REGS LD/ST = %d\n", 4 * HARD_REGNO_NREGS (0, mode));*/      return 4 * HARD_REGNO_NREGS (0, mode);    }	  else if (reg_classes_intersect_p (class, HILO_REGS))    {      /* HILO to memory and vice versa */      /* printf ("HILO_REGS %s = %d\n", in ? "LD" : "ST",	     (REGISTER_MOVE_COST (mode,				 in ? GENERAL_REGS : HILO_REGS,				 in ? HILO_REGS : GENERAL_REGS) + 4)	* HARD_REGNO_NREGS (0, mode)); */      return (REGISTER_MOVE_COST (mode,				 in ? GENERAL_REGS : HILO_REGS,				 in ? HILO_REGS : GENERAL_REGS) + 4)	* HARD_REGNO_NREGS (0, mode);    }  else /* default (like in i386) */    {      /* printf ("ANYREGS = 100\n"); */      return 100;    }}/* INSTRUCTION OUTPUT *//* ------------------ *//* Check if a const_double is ok for crx store-immediate instructions */intcrx_const_double_ok (rtx op){  if (GET_MODE (op) == DFmode)  {    REAL_VALUE_TYPE r;    long l[2];    REAL_VALUE_FROM_CONST_DOUBLE (r, op);    REAL_VALUE_TO_TARGET_DOUBLE (r, l);    return (UNSIGNED_INT_FITS_N_BITS (l[0], 4) &&	    UNSIGNED_INT_FITS_N_BITS (l[1], 4)) ? 1 : 0;  }  if (GET_MODE (op) == SFmode)  {    REAL_VALUE_TYPE r;    long l;    REAL_VALUE_FROM_CONST_DOUBLE (r, op);    REAL_VALUE_TO_TARGET_SINGLE (r, l);    return UNSIGNED_INT_FITS_N_BITS (l, 4) ? 1 : 0;  }  return (UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_LOW (op), 4) &&	  UNSIGNED_INT_FITS_N_BITS (CONST_DOUBLE_HIGH (op), 4)) ? 1 : 0;}/* Implements the macro PRINT_OPERAND defined in crx.h.  */voidcrx_print_operand (FILE * file, rtx x, int code){  switch (code)    {    case 'p' :      if (GET_CODE (x) == REG) {	if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode)	  {	    int regno = REGNO (x);	    if (regno + 1 >= SP_REGNUM) abort ();	    fprintf (file, "{%s, %s}", reg_names[regno], reg_names[regno + 1]);	    return;	  }	else	  {	    if (REGNO (x) >= SP_REGNUM) abort ();	    fprintf (file, "%s", reg_names[REGNO (x)]);	    return;	  }      }    case 'd' :	{	  const char *crx_cmp_str;	  switch (GET_CODE (x))	    { /* MD: compare (reg, reg or imm) but CRX: cmp (reg or imm, reg)	       * -> swap all non symmetric ops */	    case EQ  : crx_cmp_str = "eq"; break;	    case NE  : crx_cmp_str = "ne"; break;	    case GT  : crx_cmp_str = "lt"; break;	    case GTU : crx_cmp_str = "lo"; break;	    case LT  : crx_cmp_str = "gt"; break;	    case LTU : crx_cmp_str = "hi"; break;	    case GE  : crx_cmp_str = "le"; break;	    case GEU : crx_cmp_str = "ls"; break;	    case LE  : crx_cmp_str = "ge"; break;	    case LEU : crx_cmp_str = "hs"; break;	    default : abort ();	    }	  fprintf (file, "%s", crx_cmp_str);	  return;	}    case 'H':      /* Print high part of a double precision value. */      switch (GET_CODE (x))	{	case CONST_DOUBLE:	  if (GET_MODE (x) == SFmode) abort ();	  if (GET_MODE (x) == DFmode)	    {	      /* High part of a DF const. */	      REAL_VALUE_TYPE r;	      long l[2];	      REAL_VALUE_FROM_CONST_DOUBLE (r, x);	      REAL_VALUE_TO_TARGET_DOUBLE (r, l);	      fprintf (file, "$0x%lx", l[1]);	      return;	    }	  /* -- Fallthrough to handle DI consts -- */	case CONST_INT:	    {	      rtx high, low;	      split_double (x, &low, &high);	      putc ('$', file);	      output_addr_const (file, high);	      return;

⌨️ 快捷键说明

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