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

📄 rs6000.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      long l;      REAL_VALUE_TYPE rv;      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);      REAL_VALUE_TO_TARGET_SINGLE (rv, l);      return num_insns_constant_wide (l) == 1;    }  else if (mode == DImode)    return ((TARGET_POWERPC64	     && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)	    || (num_insns_constant (op, DImode) <= 2));  else if (mode == SImode)    return 1;  else    abort ();}/* Return 1 if the operand is a CONST_INT and can be put into a   register with one instruction.  */static inteasy_vector_constant (op)     rtx op;{  rtx elt;  int units, i;  if (GET_CODE (op) != CONST_VECTOR)    return 0;  units = CONST_VECTOR_NUNITS (op);  /* We can generate 0 easily.  Look for that.  */  for (i = 0; i < units; ++i)    {      elt = CONST_VECTOR_ELT (op, i);      /* We could probably simplify this by just checking for equality	 with CONST0_RTX for the current mode, but let's be safe	 instead.  */      switch (GET_CODE (elt))	{	case CONST_INT:	  if (INTVAL (elt) != 0)	    return 0;	  break;	case CONST_DOUBLE:	  if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)	    return 0;	  break;	default:	  return 0;	}    }  /* We could probably generate a few other constants trivially, but     gcc doesn't generate them yet.  FIXME later.  */  return 1;}/* Return 1 if the operand is the constant 0.  This works for scalars   as well as vectors.  */intzero_constant (op, mode)     rtx op;     enum machine_mode mode;{  return op == CONST0_RTX (mode);}/* Return 1 if the operand is 0.0.  */intzero_fp_constant (op, mode)     rtx op;     enum machine_mode mode;{  return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);}/* Return 1 if the operand is in volatile memory.  Note that during   the RTL generation phase, memory_operand does not return TRUE for   volatile memory references.  So this function allows us to   recognize volatile references where its safe.  */intvolatile_mem_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) != MEM)    return 0;  if (!MEM_VOLATILE_P (op))    return 0;  if (mode != GET_MODE (op))    return 0;  if (reload_completed)    return memory_operand (op, mode);  if (reload_in_progress)    return strict_memory_address_p (mode, XEXP (op, 0));  return memory_address_p (mode, XEXP (op, 0));}/* Return 1 if the operand is an offsettable memory operand.  */intoffsettable_mem_operand (op, mode)     rtx op;     enum machine_mode mode;{  return ((GET_CODE (op) == MEM)	  && offsettable_address_p (reload_completed || reload_in_progress,				    mode, XEXP (op, 0)));}/* Return 1 if the operand is either an easy FP constant (see above) or   memory.  */intmem_or_easy_const_operand (op, mode)     rtx op;     enum machine_mode mode;{  return memory_operand (op, mode) || easy_fp_constant (op, mode);}/* Return 1 if the operand is either a non-special register or an item   that can be used as the operand of a `mode' add insn.  */intadd_operand (op, mode)    rtx op;    enum machine_mode mode;{  if (GET_CODE (op) == CONST_INT)    return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')	    || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));  return gpc_reg_operand (op, mode);}/* Return 1 if OP is a constant but not a valid add_operand.  */intnon_add_cint_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return (GET_CODE (op) == CONST_INT	  && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')	  && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));}/* Return 1 if the operand is a non-special register or a constant that   can be used as the operand of an OR or XOR insn on the RS/6000.  */intlogical_operand (op, mode)     rtx op;     enum machine_mode mode;{  HOST_WIDE_INT opl, oph;  if (gpc_reg_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT)    {      opl = INTVAL (op) & GET_MODE_MASK (mode);#if HOST_BITS_PER_WIDE_INT <= 32      if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)	return 0;#endif    }  else if (GET_CODE (op) == CONST_DOUBLE)    {      if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)	abort ();      opl = CONST_DOUBLE_LOW (op);      oph = CONST_DOUBLE_HIGH (op);      if (oph != 0)	return 0;    }  else    return 0;  return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0	  || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);}/* Return 1 if C is a constant that is not a logical operand (as   above), but could be split into one.  */intnon_logical_cint_operand (op, mode)     rtx op;     enum machine_mode mode;{  return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)	  && ! logical_operand (op, mode)	  && reg_or_logical_cint_operand (op, mode));}/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the   RS/6000.  It is if there are no more than two 1->0 or 0->1 transitions.   Reject all ones and all zeros, since these should have been optimized   away and confuse the making of MB and ME.  */intmask_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  HOST_WIDE_INT c, lsb;  if (GET_CODE (op) != CONST_INT)    return 0;  c = INTVAL (op);  /* Fail in 64-bit mode if the mask wraps around because the upper     32-bits of the mask will all be 1s, contrary to GCC's internal view.  */  if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)    return 0;  /* We don't change the number of transitions by inverting,     so make sure we start with the LS bit zero.  */  if (c & 1)    c = ~c;  /* Reject all zeros or all ones.  */  if (c == 0)    return 0;  /* Find the first transition.  */  lsb = c & -c;  /* Invert to look for a second transition.  */  c = ~c;  /* Erase first transition.  */  c &= -lsb;  /* Find the second transition (if any).  */  lsb = c & -c;  /* Match if all the bits above are 1's (or c is zero).  */  return c == -lsb;}/* Return 1 for the PowerPC64 rlwinm corner case.  */intmask_operand_wrap (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  HOST_WIDE_INT c, lsb;  if (GET_CODE (op) != CONST_INT)    return 0;  c = INTVAL (op);  if ((c & 0x80000001) != 0x80000001)    return 0;  c = ~c;  if (c == 0)    return 0;  lsb = c & -c;  c = ~c;  c &= -lsb;  lsb = c & -c;  return c == -lsb;}/* Return 1 if the operand is a constant that is a PowerPC64 mask.   It is if there are no more than one 1->0 or 0->1 transitions.   Reject all zeros, since zero should have been optimized away and   confuses the making of MB and ME.  */intmask64_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == CONST_INT)    {      HOST_WIDE_INT c, lsb;      c = INTVAL (op);      /* Reject all zeros.  */      if (c == 0)	return 0;      /* We don't change the number of transitions by inverting,	 so make sure we start with the LS bit zero.  */      if (c & 1)	c = ~c;      /* Find the transition, and check that all bits above are 1's.  */      lsb = c & -c;      return c == -lsb;    }  return 0;}/* Like mask64_operand, but allow up to three transitions.  This   predicate is used by insn patterns that generate two rldicl or   rldicr machine insns.  */intmask64_2_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == CONST_INT)    {      HOST_WIDE_INT c, lsb;      c = INTVAL (op);      /* Disallow all zeros.  */      if (c == 0)	return 0;      /* We don't change the number of transitions by inverting,	 so make sure we start with the LS bit zero.  */      if (c & 1)	c = ~c;      /* Find the first transition.  */      lsb = c & -c;      /* Invert to look for a second transition.  */      c = ~c;      /* Erase first transition.  */      c &= -lsb;      /* Find the second transition.  */      lsb = c & -c;      /* Invert to look for a third transition.  */      c = ~c;      /* Erase second transition.  */      c &= -lsb;      /* Find the third transition (if any).  */      lsb = c & -c;      /* Match if all the bits above are 1's (or c is zero).  */      return c == -lsb;    }  return 0;}/* Generates shifts and masks for a pair of rldicl or rldicr insns to   implement ANDing by the mask IN.  */voidbuild_mask64_2_operands (in, out)     rtx in;     rtx *out;{#if HOST_BITS_PER_WIDE_INT >= 64  unsigned HOST_WIDE_INT c, lsb, m1, m2;  int shift;  if (GET_CODE (in) != CONST_INT)    abort ();  c = INTVAL (in);  if (c & 1)    {      /* Assume c initially something like 0x00fff000000fffff.  The idea	 is to rotate the word so that the middle ^^^^^^ group of zeros	 is at the MS end and can be cleared with an rldicl mask.  We then	 rotate back and clear off the MS    ^^ group of zeros with a	 second rldicl.  */      c = ~c;			/*   c == 0xff000ffffff00000 */      lsb = c & -c;		/* lsb == 0x0000000000100000 */      m1 = -lsb;		/*  m1 == 0xfffffffffff00000 */      c = ~c;			/*   c == 0x00fff000000fffff */      c &= -lsb;		/*   c == 0x00fff00000000000 */      lsb = c & -c;		/* lsb == 0x0000100000000000 */      c = ~c;			/*   c == 0xff000fffffffffff */      c &= -lsb;		/*   c == 0xff00000000000000 */      shift = 0;      while ((lsb >>= 1) != 0)	shift++;		/* shift == 44 on exit from loop */      m1 <<= 64 - shift;	/*  m1 == 0xffffff0000000000 */      m1 = ~m1;			/*  m1 == 0x000000ffffffffff */      m2 = ~c;			/*  m2 == 0x00ffffffffffffff */    }  else    {      /* Assume c initially something like 0xff000f0000000000.  The idea	 is to rotate the word so that the     ^^^  middle group of zeros	 is at the LS end and can be cleared with an rldicr mask.  We then	 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with	 a second rldicr.  */      lsb = c & -c;		/* lsb == 0x0000010000000000 */      m2 = -lsb;		/*  m2 == 0xffffff0000000000 */      c = ~c;			/*   c == 0x00fff0ffffffffff */      c &= -lsb;		/*   c == 0x00fff00000000000 */      lsb = c & -c;		/* lsb == 0x0000100000000000 */      c = ~c;			/*   c == 0xff000fffffffffff */      c &= -lsb;		/*   c == 0xff00000000000000 */      shift = 0;      while ((lsb >>= 1) != 0)	shift++;		/* shift == 44 on exit from loop */      m1 = ~c;			/*  m1 == 0x00ffffffffffffff */      m1 >>= shift;		/*  m1 == 0x0000000000000fff */      m1 = ~m1;			/*  m1 == 0xfffffffffffff000 */    }  /* Note that when we only have two 0->1 and 1->0 transitions, one of the     masks will be all 1's.  We are guaranteed more than one transition.  */  out[0] = GEN_INT (64 - shift);  out[1] = GEN_INT (m1);  out[2] = GEN_INT (shift);  out[3] = GEN_INT (m2);#else  (void)in;  (void)out;  abort ();#endif}/* Return 1 if the operand is either a non-special register or a constant   that can be used as the operand of a PowerPC64 logical AND insn.  */intand64_operand (op, mode)    rtx op;    enum machine_mode mode;{

⌨️ 快捷键说明

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