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

📄 rs6000.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)	return 0;    }  return 1;}/* Similar, but tests for store multiple.  Here, the second vector element   is a CLOBBER.  It will be tested later.  */intstore_multiple_operation (op, mode)     rtx op;     enum machine_mode mode;{  int count = XVECLEN (op, 0) - 1;  int src_regno;  rtx dest_addr;  int i;  /* Perform a quick check so we don't blow up below.  */  if (count <= 1      || GET_CODE (XVECEXP (op, 0, 0)) != SET      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)    return 0;  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);  for (i = 1; i < count; i++)    {      rtx elt = XVECEXP (op, 0, i + 1);      if (GET_CODE (elt) != SET	  || GET_CODE (SET_SRC (elt)) != REG	  || GET_MODE (SET_SRC (elt)) != SImode	  || REGNO (SET_SRC (elt)) != src_regno + i	  || GET_CODE (SET_DEST (elt)) != MEM	  || GET_MODE (SET_DEST (elt)) != SImode	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)	return 0;    }  return 1;}/* Return 1 if OP is a comparison operation that is valid for a branch insn.   We only check the opcode against the mode of the CC value here.  */intbranch_comparison_operator (op, mode)     register rtx op;     enum machine_mode mode;{  enum rtx_code code = GET_CODE (op);  enum machine_mode cc_mode;  if (GET_RTX_CLASS (code) != '<')    return 0;  cc_mode = GET_MODE (XEXP (op, 0));  if (GET_MODE_CLASS (cc_mode) != MODE_CC)    return 0;  if ((code == GT || code == LT || code == GE || code == LE)      && cc_mode == CCUNSmode)    return 0;  if ((code == GTU || code == LTU || code == GEU || code == LEU)      && (cc_mode != CCUNSmode))    return 0;  return 1;}/* Return 1 if OP is a comparison operation that is valid for an scc insn.   We check the opcode against the mode of the CC value and disallow EQ or   NE comparisons for integers.  */intscc_comparison_operator (op, mode)     register rtx op;     enum machine_mode mode;{  enum rtx_code code = GET_CODE (op);  enum machine_mode cc_mode;  if (GET_MODE (op) != mode && mode != VOIDmode)    return 0;  if (GET_RTX_CLASS (code) != '<')    return 0;  cc_mode = GET_MODE (XEXP (op, 0));  if (GET_MODE_CLASS (cc_mode) != MODE_CC)    return 0;  if (code == NE && cc_mode != CCFPmode)    return 0;  if ((code == GT || code == LT || code == GE || code == LE)      && cc_mode == CCUNSmode)    return 0;  if ((code == GTU || code == LTU || code == GEU || code == LEU)      && (cc_mode != CCUNSmode))    return 0;  if (cc_mode == CCEQmode && code != EQ && code != NE)    return 0;  return 1;}/* Return 1 if ANDOP is a mask that has no bits on that are not in the   mask required to convert the result of a rotate insn into a shift   left insn of SHIFTOP bits.  Both are known to be CONST_INT.  */intincludes_lshift_p (shiftop, andop)     register rtx shiftop;     register rtx andop;{  int shift_mask = (~0 << INTVAL (shiftop));  return (INTVAL (andop) & ~shift_mask) == 0;}/* Similar, but for right shift.  */intincludes_rshift_p (shiftop, andop)     register rtx shiftop;     register rtx andop;{  unsigned shift_mask = ~0;  shift_mask >>= INTVAL (shiftop);  return (INTVAL (andop) & ~ shift_mask) == 0;}/* Return the register class of a scratch register needed to copy IN into   or out of a register in CLASS in MODE.  If it can be done directly,   NO_REGS is returned.  */enum reg_classsecondary_reload_class (class, mode, in)     enum reg_class class;     enum machine_mode mode;     rtx in;{  int regno = true_regnum (in);  if (regno >= FIRST_PSEUDO_REGISTER)    regno = -1;  /* We can place anything into GENERAL_REGS and can put GENERAL_REGS     into anything.  */  if (class == GENERAL_REGS || class == BASE_REGS      || (regno >= 0 && INT_REGNO_P (regno)))    return NO_REGS;  /* Constants, memory, and FP registers can go into FP registers.  */  if ((regno == -1 || FP_REGNO_P (regno))      && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))    return NO_REGS;  /* We can copy among the CR registers.  */  if ((class == CR_REGS || class == CR0_REGS)      && regno >= 0 && CR_REGNO_P (regno))    return NO_REGS;  /* Otherwise, we need GENERAL_REGS.  */  return GENERAL_REGS;}/* Given a comparison operation, return the bit number in CCR to test.  We   know this is a valid comparison.     SCC_P is 1 if this is for an scc.  That means that %D will have been   used instead of %C, so the bits will be in different places.   Return -1 if OP isn't a valid comparison for some reason.  */intccr_bit (op, scc_p)     register rtx op;     int scc_p;{  enum rtx_code code = GET_CODE (op);  enum machine_mode cc_mode;  int cc_regnum;  int base_bit;  if (GET_RTX_CLASS (code) != '<')    return -1;  cc_mode = GET_MODE (XEXP (op, 0));  cc_regnum = REGNO (XEXP (op, 0));  base_bit = 4 * (cc_regnum - 68);  /* In CCEQmode cases we have made sure that the result is always in the     third bit of the CR field.  */  if (cc_mode == CCEQmode)    return base_bit + 3;  switch (code)    {    case NE:      return scc_p ? base_bit + 3 : base_bit + 2;    case EQ:      return base_bit + 2;    case GT:  case GTU:      return base_bit + 1;    case LT:  case LTU:      return base_bit;    case GE:  case GEU:      /* If floating-point, we will have done a cror to put the bit in the	 unordered position.  So test that bit.  For integer, this is ! LT	 unless this is an scc insn.  */      return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit;    case LE:  case LEU:      return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1;    default:      abort ();    }}/* Print an operand.  Recognize special options, documented below.  */voidprint_operand (file, x, code)    FILE *file;    rtx x;    char code;{  int i;  int val;  /* These macros test for integers and extract the low-order bits.  */#define INT_P(X)  \((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE)	\ && GET_MODE (X) == VOIDmode)#define INT_LOWPART(X) \  (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))  switch (code)    {    case 'h':      /* If constant, output low-order five bits.  Otherwise,	 write normally. */      if (INT_P (x))	fprintf (file, "%d", INT_LOWPART (x) & 31);      else	print_operand (file, x, 0);      return;    case 'H':      /* X must be a constant.  Output the low order 5 bits plus 24.  */      if (! INT_P (x))	output_operand_lossage ("invalid %%H value");      fprintf (file, "%d", (INT_LOWPART (x) + 24) & 31);      return;    case 'b':      /* Low-order 16 bits of constant, unsigned.  */      if (! INT_P (x))	output_operand_lossage ("invalid %%b value");      fprintf (file, "%d", INT_LOWPART (x) & 0xffff);      return;    case 'w':      /* If constant, low-order 16 bits of constant, signed.  Otherwise, write	 normally.  */      if (INT_P (x))	fprintf (file, "%d",		 (INT_LOWPART (x) & 0xffff) - 2 * (INT_LOWPART (x) & 0x8000));      else	print_operand (file, x, 0);      return;    case 'W':      /* If constant, low-order 16 bits of constant, unsigned.	 Otherwise, write normally.  */      if (INT_P (x))	fprintf (file, "%d", INT_LOWPART (x) & 0xffff);      else	print_operand (file, x, 0);      return;    case 'u':      /* High-order 16 bits of constant.  */      if (! INT_P (x))	output_operand_lossage ("invalid %%u value");      fprintf (file, "%d", (INT_LOWPART (x) >> 16) & 0xffff);      return;    case 's':      /* Low 5 bits of 32 - value */      if (! INT_P (x))	output_operand_lossage ("invalid %%s value");      fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31);      return;    case 'S':      /* Low 5 bits of 31 - value */      if (! INT_P (x))	output_operand_lossage ("invalid %%S value");      fprintf (file, "%d", (31 - INT_LOWPART (x)) & 31);      return;    case 'p':      /* X is a CONST_INT that is a power of two.  Output the logarithm.  */      if (! INT_P (x)	  || (i = exact_log2 (INT_LOWPART (x))) < 0)	output_operand_lossage ("invalid %%p value");      fprintf (file, "%d", i);      return;    case 'm':      /* MB value for a mask operand.  */      if (! mask_operand (x, VOIDmode))	output_operand_lossage ("invalid %%m value");      val = INT_LOWPART (x);      /* If the high bit is set and the low bit is not, the value is zero.	 If the high bit is zero, the value is the first 1 bit we find from	 the left.  */      if (val < 0 && (val & 1) == 0)	{	  fprintf (file, "0");	  return;	}      else if (val >= 0)	{	  for (i = 1; i < 32; i++)	    if ((val <<= 1) < 0)	      break;	  fprintf (file, "%d", i);	  return;	}	        /* Otherwise, look for the first 0 bit from the right.  The result is its	 number plus 1. We know the low-order bit is one.  */      for (i = 0; i < 32; i++)	if (((val >>= 1) & 1) == 0)	  break;      /* If we ended in ...01, I would be 0.  The correct value is 31, so	 we want 31 - i.  */      fprintf (file, "%d", 31 - i);      return;    case 'M':      /* ME value for a mask operand.  */      if (! mask_operand (x, VOIDmode))	output_operand_lossage ("invalid %%m value");      val = INT_LOWPART (x);      /* If the low bit is set and the high bit is not, the value is 31.	 If the low bit is zero, the value is the first 1 bit we find from	 the right.  */      if ((val & 1) && val >= 0)	{	  fprintf (file, "31");	  return;	}      else if ((val & 1) == 0)	{	  for (i = 0; i < 32; i++)	    if ((val >>= 1) & 1)	      break;	  /* If we had ....10, I would be 0.  The result should be	     30, so we need 30 - i.  */	  fprintf (file, "%d", 30 - i);	  return;	}	        /* Otherwise, look for the first 0 bit from the left.  The result is its	 number minus 1. We know the high-order bit is one.  */      for (i = 0; i < 32; i++)	if ((val <<= 1) >= 0)	  break;      fprintf (file, "%d", i);      return;    case 'f':      /* X is a CR register.  Print the shift count needed to move it	 to the high-order four bits.  */      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))	output_operand_lossage ("invalid %%f value");      else	fprintf (file, "%d", 4 * (REGNO (x) - 68));      return;    case 'F':      /* Similar, but print the count for the rotate in the opposite	 direction.  */      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))	output_operand_lossage ("invalid %%F value");      else	fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));      return;    case 'E':      /* X is a CR register.  Print the number of the third bit of the CR */      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))	output_operand_lossage ("invalid %%E value");      fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3);      break;    case 'R':      /* X is a CR register.  Print the mask for `mtcrf'.  */      if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))	output_operand_lossage ("invalid %%R value");      else	fprintf (file, "%d", 128 >> (REGNO (x) - 68));      return;    case 'X':      if (GET_CODE (x) == MEM	  && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))	fprintf (file, "x");      return;    case 'U':      /* Print `u' is this has an auto-increment or auto-decrement.  */      if (GET_CODE (x) == MEM	  && (GET_CODE (XEXP (x, 0)) == PRE_INC	      || GET_CODE (XEXP (x, 0)) == PRE_DEC))

⌨️ 快捷键说明

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