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

📄 sparc.c

📁 gcc编译工具没有什么特别
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidsparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg)  rtx op0;  rtx temp;  unsigned HOST_WIDE_INT low_bits;  int is_neg;{  unsigned HOST_WIDE_INT high_bits;  if (is_neg)    high_bits = (~low_bits) & 0xffffffff;  else    high_bits = low_bits;  sparc_emit_set_safe_HIGH64 (temp, high_bits);  if (!is_neg)    {      emit_insn (gen_rtx_SET (VOIDmode, op0,			      gen_safe_OR64 (temp, (high_bits & 0x3ff))));    }  else    {      /* If we are XOR'ing with -1, then we should emit a one's complement	 instead.  This way the combiner will notice logical operations	 such as ANDN later on and substitute.  */      if ((low_bits & 0x3ff) == 0x3ff)	{	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_NOT (DImode, temp)));	}      else	{	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_safe_XOR64 (temp,						  (-0x400 | (low_bits & 0x3ff)))));	}    }}static void sparc_emit_set_const64_quick2	PROTO((rtx, rtx, unsigned HOST_WIDE_INT,	       unsigned HOST_WIDE_INT, int));static voidsparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count)  rtx op0;  rtx temp;  unsigned HOST_WIDE_INT high_bits;  unsigned HOST_WIDE_INT low_immediate;  int shift_count;{  rtx temp2 = op0;  if ((high_bits & 0xfffffc00) != 0)    {      sparc_emit_set_safe_HIGH64 (temp, high_bits);      if ((high_bits & ~0xfffffc00) != 0)	emit_insn (gen_rtx_SET (VOIDmode, op0,				gen_safe_OR64 (temp, (high_bits & 0x3ff))));      else	temp2 = temp;    }  else    {      emit_insn (gen_safe_SET64 (temp, high_bits));      temp2 = temp;    }  /* Now shift it up into place. */  emit_insn (gen_rtx_SET (VOIDmode, op0,			  gen_rtx_ASHIFT (DImode, temp2,					  GEN_INT (shift_count))));  /* If there is a low immediate part piece, finish up by     putting that in as well.  */  if (low_immediate != 0)    emit_insn (gen_rtx_SET (VOIDmode, op0,			    gen_safe_OR64 (op0, low_immediate)));}static void sparc_emit_set_const64_longway	PROTO((rtx, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT));/* Full 64-bit constant decomposition.  Even though this is the   'worst' case, we still optimize a few things away.  */static voidsparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)     rtx op0;     rtx temp;     unsigned HOST_WIDE_INT high_bits;     unsigned HOST_WIDE_INT low_bits;{  rtx sub_temp;  if (reload_in_progress || reload_completed)    sub_temp = op0;  else    sub_temp = gen_reg_rtx (DImode);  if ((high_bits & 0xfffffc00) != 0)    {      sparc_emit_set_safe_HIGH64 (temp, high_bits);      if ((high_bits & ~0xfffffc00) != 0)	emit_insn (gen_rtx_SET (VOIDmode,				sub_temp,				gen_safe_OR64 (temp, (high_bits & 0x3ff))));      else	sub_temp = temp;    }  else    {      emit_insn (gen_safe_SET64 (temp, high_bits));      sub_temp = temp;    }  if (!reload_in_progress && !reload_completed)    {      rtx temp2 = gen_reg_rtx (DImode);      rtx temp3 = gen_reg_rtx (DImode);      rtx temp4 = gen_reg_rtx (DImode);      emit_insn (gen_rtx_SET (VOIDmode, temp4,			      gen_rtx_ASHIFT (DImode, sub_temp,					      GEN_INT (32))));      sparc_emit_set_safe_HIGH64 (temp2, low_bits);      if ((low_bits & ~0xfffffc00) != 0)	{	  emit_insn (gen_rtx_SET (VOIDmode, temp3,				  gen_safe_OR64 (temp2, (low_bits & 0x3ff))));	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_PLUS (DImode, temp4, temp3)));	}      else	{	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_PLUS (DImode, temp4, temp2)));	}    }  else    {      rtx low1 = GEN_INT ((low_bits >> (32 - 12))          & 0xfff);      rtx low2 = GEN_INT ((low_bits >> (32 - 12 - 12))     & 0xfff);      rtx low3 = GEN_INT ((low_bits >> (32 - 12 - 12 - 8)) & 0x0ff);      int to_shift = 12;      /* We are in the middle of reload, so this is really	 painful.  However we do still make an attempt to	 avoid emitting truly stupid code.  */      if (low1 != const0_rtx)	{	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_ASHIFT (DImode, sub_temp,						  GEN_INT (to_shift))));	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_IOR (DImode, op0, low1)));	  sub_temp = op0;	  to_shift = 12;	}      else	{	  to_shift += 12;	}      if (low2 != const0_rtx)	{	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_ASHIFT (DImode, sub_temp,						  GEN_INT (to_shift))));	  emit_insn (gen_rtx_SET (VOIDmode, op0,				  gen_rtx_IOR (DImode, op0, low2)));	  sub_temp = op0;	  to_shift = 8;	}      else	{	  to_shift += 8;	}      emit_insn (gen_rtx_SET (VOIDmode, op0,			      gen_rtx_ASHIFT (DImode, sub_temp,					      GEN_INT (to_shift))));      if (low3 != const0_rtx)	emit_insn (gen_rtx_SET (VOIDmode, op0,				gen_rtx_IOR (DImode, op0, low3)));      /* phew... */    }}/* Analyze a 64-bit constant for certain properties. */static void analyze_64bit_constant	PROTO((unsigned HOST_WIDE_INT,	       unsigned HOST_WIDE_INT,	       int *, int *, int *));static voidanalyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp)     unsigned HOST_WIDE_INT high_bits, low_bits;     int *hbsp, *lbsp, *abbasp;{  int lowest_bit_set, highest_bit_set, all_bits_between_are_set;  int i;  lowest_bit_set = highest_bit_set = -1;  i = 0;  do    {      if ((lowest_bit_set == -1)	  && ((low_bits >> i) & 1))	lowest_bit_set = i;      if ((highest_bit_set == -1)	  && ((high_bits >> (32 - i - 1)) & 1))	highest_bit_set = (64 - i - 1);    }  while (++i < 32	 && ((highest_bit_set == -1)	     || (lowest_bit_set == -1)));  if (i == 32)    {      i = 0;      do	{	  if ((lowest_bit_set == -1)	      && ((high_bits >> i) & 1))	    lowest_bit_set = i + 32;	  if ((highest_bit_set == -1)	      && ((low_bits >> (32 - i - 1)) & 1))	    highest_bit_set = 32 - i - 1;	}      while (++i < 32	     && ((highest_bit_set == -1)		 || (lowest_bit_set == -1)));    }  /* If there are no bits set this should have gone out     as one instruction!  */  if (lowest_bit_set == -1      || highest_bit_set == -1)    abort ();  all_bits_between_are_set = 1;  for (i = lowest_bit_set; i <= highest_bit_set; i++)    {      if (i < 32)	{	  if ((low_bits & (1 << i)) != 0)	    continue;	}      else	{	  if ((high_bits & (1 << (i - 32))) != 0)	    continue;	}      all_bits_between_are_set = 0;      break;    }  *hbsp = highest_bit_set;  *lbsp = lowest_bit_set;  *abbasp = all_bits_between_are_set;}static int const64_is_2insns	PROTO((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT));static intconst64_is_2insns (high_bits, low_bits)     unsigned HOST_WIDE_INT high_bits, low_bits;{  int highest_bit_set, lowest_bit_set, all_bits_between_are_set;  if (high_bits == 0      || high_bits == 0xffffffff)    return 1;  analyze_64bit_constant (high_bits, low_bits,			  &highest_bit_set, &lowest_bit_set,			  &all_bits_between_are_set);  if ((highest_bit_set == 63       || lowest_bit_set == 0)      && all_bits_between_are_set != 0)    return 1;  if ((highest_bit_set - lowest_bit_set) < 21)    return 1;  return 0;}static unsigned HOST_WIDE_INT create_simple_focus_bits	PROTO((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,	       int, int));static unsigned HOST_WIDE_INTcreate_simple_focus_bits (high_bits, low_bits, lowest_bit_set, shift)     unsigned HOST_WIDE_INT high_bits, low_bits;     int lowest_bit_set, shift;{  HOST_WIDE_INT hi, lo;  if (lowest_bit_set < 32)    {      lo = (low_bits >> lowest_bit_set) << shift;      hi = ((high_bits << (32 - lowest_bit_set)) << shift);    }  else    {      lo = 0;      hi = ((high_bits >> (lowest_bit_set - 32)) << shift);    }  if (hi & lo)    abort ();  return (hi | lo);}/* Here we are sure to be arch64 and this is an integer constant   being loaded into a register.  Emit the most efficient   insn sequence possible.  Detection of all the 1-insn cases   has been done already.  */voidsparc_emit_set_const64 (op0, op1)     rtx op0;     rtx op1;{  unsigned HOST_WIDE_INT high_bits, low_bits;  int lowest_bit_set, highest_bit_set;  int all_bits_between_are_set;  rtx temp;  /* Sanity check that we know what we are working with.  */  if (! TARGET_ARCH64      || GET_CODE (op0) != REG      || (REGNO (op0) >= SPARC_FIRST_FP_REG	  && REGNO (op0) <= SPARC_LAST_V9_FP_REG))    abort ();  if (reload_in_progress || reload_completed)    temp = op0;  else    temp = gen_reg_rtx (DImode);  if (GET_CODE (op1) != CONST_DOUBLE      && GET_CODE (op1) != CONST_INT)    {      sparc_emit_set_symbolic_const64 (op0, op1, temp);      return;    }  if (GET_CODE (op1) == CONST_DOUBLE)    {#if HOST_BITS_PER_WIDE_INT == 64      high_bits = (CONST_DOUBLE_LOW (op1) >> 32) & 0xffffffff;      low_bits  = CONST_DOUBLE_LOW (op1) & 0xffffffff;#else      high_bits = CONST_DOUBLE_HIGH (op1);      low_bits = CONST_DOUBLE_LOW (op1);#endif    }  else    {#if HOST_BITS_PER_WIDE_INT == 64      high_bits = ((INTVAL (op1) >> 32) & 0xffffffff);      low_bits = (INTVAL (op1) & 0xffffffff);#else      high_bits = ((INTVAL (op1) < 0) ?		   0xffffffff :		   0x00000000);      low_bits = INTVAL (op1);#endif    }  /* low_bits	bits 0  --> 31     high_bits	bits 32 --> 63  */  analyze_64bit_constant (high_bits, low_bits,			  &highest_bit_set, &lowest_bit_set,			  &all_bits_between_are_set);  /* First try for a 2-insn sequence.  */  /* These situations are preferred because the optimizer can   * do more things with them:   * 1) mov	-1, %reg   *    sllx	%reg, shift, %reg   * 2) mov	-1, %reg   *    srlx	%reg, shift, %reg   * 3) mov	some_small_const, %reg   *    sllx	%reg, shift, %reg   */  if (((highest_bit_set == 63	|| lowest_bit_set == 0)       && all_bits_between_are_set != 0)      || ((highest_bit_set - lowest_bit_set) < 12))    {      HOST_WIDE_INT the_const = -1;      int shift = lowest_bit_set;      if ((highest_bit_set != 63	   && lowest_bit_set != 0)	  || all_bits_between_are_set == 0)	{	  the_const =	    create_simple_focus_bits (high_bits, low_bits,				      lowest_bit_set, 0);	}      else if (lowest_bit_set == 0)	shift = -(63 - highest_bit_set);      if (! SPARC_SIMM13_P (the_const))	abort ();      emit_insn (gen_safe_SET64 (temp, the_const));      if (shift > 0)	emit_insn (gen_rtx_SET (VOIDmode,				op0,				gen_rtx_ASHIFT (DImode,						temp,						GEN_INT (shift))));      else if (shift < 0)	emit_insn (gen_rtx_SET (VOIDmode,				op0,				gen_rtx_LSHIFTRT (DImode,						  temp,						  GEN_INT (-shift))));      else	abort ();      return;    }  /* Now a range of 22 or less bits set somewhere.   * 1) sethi	%hi(focus_bits), %reg   *    sllx	%reg, shift, %reg   * 2) sethi	%hi(focus_bits), %reg   *    srlx	%reg, shift, %reg   */  if ((highest_bit_set - lowest_bit_set) < 21)    {      unsigned HOST_WIDE_INT focus_bits =	create_simple_focus_bits (high_bits, low_bits,				  lowest_bit_set, 10);      if (! SPARC_SETHI_P (focus_bits))	 abort ();      sparc_emit_set_safe_HIGH64 (temp, focus_bits);      /* If lowest_bit_set == 10 then a sethi alone could have done it.  */      if (lowest_bit_set < 10)	emit_insn (gen_rtx_SET (VOIDmode,				op0,				gen_rtx_LSHIFTRT (DImode, temp,						  GEN_INT (10 - lowest_bit_set))));      else if (lowest_bit_set > 10)	emit_insn (gen_rtx_SET (VOIDmode,				op0,				gen_rtx_ASHIFT (DImode, temp,						GEN_INT (lowest_bit_set - 10))));      else	abort ();      return;    }  /* 1) sethi	%hi(low_bits), %reg   *    or	%reg, %lo(low_bits), %reg   * 2) sethi	%hi(~low_bits), %reg   *	xor	%reg, %lo(-0x400 | (low_bits & 0x3ff)), %reg   */  if (high_bits == 0      || high_bits == 0xffffffff)    {      sparc_emit_set_const64_quick1 (op0, temp, low_bits,				     (high_bits == 0xffffffff));      return;    }  /* Now, try 3-insn sequences.  */  /* 1) sethi	%hi(high_bits), %reg

⌨️ 快捷键说明

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