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

📄 sparc.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  temp2 = gen_reg_rtx (DImode);	  temp3 = gen_reg_rtx (DImode);	  temp4 = gen_reg_rtx (DImode);	  temp5 = gen_reg_rtx (DImode);	}      emit_insn (gen_sethh (temp1, op1));      emit_insn (gen_setlm (temp2, op1));      emit_insn (gen_sethm (temp3, temp1, op1));      emit_insn (gen_rtx_SET (VOIDmode, temp4,			      gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));      emit_insn (gen_rtx_SET (VOIDmode, temp5,			      gen_rtx_PLUS (DImode, temp4, temp2)));      emit_insn (gen_setlo (op0, temp5, op1));      break;    case CM_EMBMEDANY:      /* Old old old backwards compatibility kruft here.	 Essentially it is MEDLOW with a fixed 64-bit	 virtual base added to all data segment addresses.	 Text-segment stuff is computed like MEDANY, we can't	 reuse the code above because the relocation knobs	 look different.	 Data segment:	sethi	%hi(symbol), %temp1			add	%temp1, EMBMEDANY_BASE_REG, %temp2			or	%temp2, %lo(symbol), %reg  */      if (data_segment_operand (op1, GET_MODE (op1)))	{	  if (temp)	    {	      temp1 = temp;  /* op0 is allowed.  */	      temp2 = op0;	    }	  else	    {	      temp1 = gen_reg_rtx (DImode);	      temp2 = gen_reg_rtx (DImode);	    }	  emit_insn (gen_embmedany_sethi (temp1, op1));	  emit_insn (gen_embmedany_brsum (temp2, temp1));	  emit_insn (gen_embmedany_losum (op0, temp2, op1));	}      /* Text segment:	sethi	%uhi(symbol), %temp1			sethi	%hi(symbol), %temp2			or	%temp1, %ulo(symbol), %temp3			sllx	%temp3, 32, %temp4			or	%temp4, %temp2, %temp5			or	%temp5, %lo(symbol), %reg  */      else	{	  if (temp)	    {	      /* It is possible that one of the registers we got for operands[2]		 might coincide with that of operands[0] (which is why we made		 it TImode).  Pick the other one to use as our scratch.  */	      if (rtx_equal_p (temp, op0))		{		  if (ti_temp)		    temp = gen_rtx_REG (DImode, REGNO (temp) + 1);		  else		    abort();		}	      temp1 = op0;	      temp2 = temp;  /* op0 is _not_ allowed, see above.  */	      temp3 = op0;	      temp4 = op0;	      temp5 = op0;	    }	  else	    {	      temp1 = gen_reg_rtx (DImode);	      temp2 = gen_reg_rtx (DImode);	      temp3 = gen_reg_rtx (DImode);	      temp4 = gen_reg_rtx (DImode);	      temp5 = gen_reg_rtx (DImode);	    }	  emit_insn (gen_embmedany_textuhi (temp1, op1));	  emit_insn (gen_embmedany_texthi  (temp2, op1));	  emit_insn (gen_embmedany_textulo (temp3, temp1, op1));	  emit_insn (gen_rtx_SET (VOIDmode, temp4,				  gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));	  emit_insn (gen_rtx_SET (VOIDmode, temp5,				  gen_rtx_PLUS (DImode, temp4, temp2)));	  emit_insn (gen_embmedany_textlo  (op0, temp5, op1));	}      break;    default:      abort();    }}/* These avoid problems when cross compiling.  If we do not   go through all this hair then the optimizer will see   invalid REG_EQUAL notes or in some cases none at all.  */static void sparc_emit_set_safe_HIGH64 (rtx, HOST_WIDE_INT);static rtx gen_safe_SET64 (rtx, HOST_WIDE_INT);static rtx gen_safe_OR64 (rtx, HOST_WIDE_INT);static rtx gen_safe_XOR64 (rtx, HOST_WIDE_INT);#if HOST_BITS_PER_WIDE_INT == 64#define GEN_HIGHINT64(__x)		GEN_INT ((__x) & ~(HOST_WIDE_INT)0x3ff)#define GEN_INT64(__x)			GEN_INT (__x)#else#define GEN_HIGHINT64(__x) \	immed_double_const ((__x) & ~(HOST_WIDE_INT)0x3ff, 0, DImode)#define GEN_INT64(__x) \	immed_double_const ((__x) & 0xffffffff, \			    ((__x) & 0x80000000 ? -1 : 0), DImode)#endif/* The optimizer is not to assume anything about exactly   which bits are set for a HIGH, they are unspecified.   Unfortunately this leads to many missed optimizations   during CSE.  We mask out the non-HIGH bits, and matches   a plain movdi, to alleviate this problem.  */static voidsparc_emit_set_safe_HIGH64 (rtx dest, HOST_WIDE_INT val){  emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_HIGHINT64 (val)));}static rtxgen_safe_SET64 (rtx dest, HOST_WIDE_INT val){  return gen_rtx_SET (VOIDmode, dest, GEN_INT64 (val));}static rtxgen_safe_OR64 (rtx src, HOST_WIDE_INT val){  return gen_rtx_IOR (DImode, src, GEN_INT64 (val));}static rtxgen_safe_XOR64 (rtx src, HOST_WIDE_INT val){  return gen_rtx_XOR (DImode, src, GEN_INT64 (val));}/* Worker routines for 64-bit constant formation on arch64.   One of the key things to be doing in these emissions is   to create as many temp REGs as possible.  This makes it   possible for half-built constants to be used later when   such values are similar to something required later on.   Without doing this, the optimizer cannot see such   opportunities.  */static void sparc_emit_set_const64_quick1 (rtx, rtx,					   unsigned HOST_WIDE_INT, int);static voidsparc_emit_set_const64_quick1 (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,						  (-(HOST_WIDE_INT)0x400						   | (low_bits & 0x3ff)))));	}    }}static void sparc_emit_set_const64_quick2 (rtx, rtx, unsigned HOST_WIDE_INT,					   unsigned HOST_WIDE_INT, int);static voidsparc_emit_set_const64_quick2 (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 (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 (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 (unsigned HOST_WIDE_INT,				    unsigned HOST_WIDE_INT,				    int *, int *, int *);static voidanalyze_64bit_constant (unsigned HOST_WIDE_INT high_bits,			unsigned HOST_WIDE_INT low_bits,			int *hbsp, int *lbsp, int *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 (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);static intconst64_is_2insns (unsigned HOST_WIDE_INT high_bits,		   unsigned HOST_WIDE_INT 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 (unsigned HOST_WIDE_INT,							unsigned HOST_WIDE_INT,							int, int);static unsigned HOST_WIDE_INTcreate_simple_focus_bits (unsigned HOST_WIDE_INT high_bits,			  unsigned HOST_WIDE_INT low_bits,			  int lowest_bit_set, int shift){  HOST_WIDE_INT hi, lo;  if

⌨️ 快捷键说明

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