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

📄 alpha.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
          else if (a >= 4 && c % 4 == 0)	    dst_align = 4;          else if (a >= 2 && c % 2 == 0)	    dst_align = 2;	}    }  /*   * Load the entire block into registers.   */  if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)    {      enum machine_mode mode;      tmp = XEXP (XEXP (orig_src, 0), 0);      /* Don't use the existing register if we're reading more than	 is held in the register.  Nor if there is not a mode that	 handles the exact size.  */      mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);      if (mode != BLKmode	  && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)	{	  if (mode == TImode)	    {	      data_regs[nregs] = gen_lowpart (DImode, tmp);	      data_regs[nregs+1] = gen_highpart (DImode, tmp);	      nregs += 2;	    }	  else	    data_regs[nregs++] = gen_lowpart (mode, tmp);	  goto src_done;	}      /* No appropriate mode; fall back on memory.  */      orig_src = change_address (orig_src, GET_MODE (orig_src),				 copy_addr_to_reg (XEXP (orig_src, 0)));    }  ofs = 0;  if (src_align >= 8 && bytes >= 8)    {      words = bytes / 8;      for (i = 0; i < words; ++i)	data_regs[nregs+i] = gen_reg_rtx(DImode);      for (i = 0; i < words; ++i)	{	  emit_move_insn (data_regs[nregs+i],			  change_address (orig_src, DImode,					  plus_constant (XEXP (orig_src, 0),							 ofs + i*8)));	}      nregs += words;      bytes -= words * 8;      ofs += words * 8;    }  if (src_align >= 4 && bytes >= 4)    {      words = bytes / 4;      for (i = 0; i < words; ++i)	data_regs[nregs+i] = gen_reg_rtx(SImode);      for (i = 0; i < words; ++i)	{	  emit_move_insn (data_regs[nregs+i],			  change_address (orig_src, SImode,					  plus_constant (XEXP (orig_src, 0),							 ofs + i*4)));	}      nregs += words;      bytes -= words * 4;      ofs += words * 4;    }  if (bytes >= 16)    {      words = bytes / 8;      for (i = 0; i < words+1; ++i)	data_regs[nregs+i] = gen_reg_rtx(DImode);      alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,					 words, ofs);      nregs += words;      bytes -= words * 8;      ofs += words * 8;    }  if (!TARGET_BWX && bytes >= 8)    {      data_regs[nregs++] = tmp = gen_reg_rtx (DImode);      alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);      bytes -= 8;      ofs += 8;    }  if (!TARGET_BWX && bytes >= 4)    {      data_regs[nregs++] = tmp = gen_reg_rtx (SImode);      alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);      bytes -= 4;      ofs += 4;    }  if (bytes >= 2)    {      if (src_align >= 2)	{	  do {	    data_regs[nregs++] = tmp = gen_reg_rtx (HImode);	    emit_move_insn (tmp,			    change_address (orig_src, HImode,					    plus_constant (XEXP (orig_src, 0),							   ofs)));	    bytes -= 2;	    ofs += 2;	  } while (bytes >= 2);	}      else if (!TARGET_BWX)	{	  data_regs[nregs++] = tmp = gen_reg_rtx (HImode);	  alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);	  bytes -= 2;	  ofs += 2;	}    }  while (bytes > 0)    {      data_regs[nregs++] = tmp = gen_reg_rtx (QImode);      emit_move_insn (tmp,		      change_address (orig_src, QImode,				      plus_constant (XEXP (orig_src, 0),						     ofs)));      bytes -= 1;      ofs += 1;    } src_done:  if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))    abort();  /*   * Now save it back out again.   */  i = 0, ofs = 0;  if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)    {      enum machine_mode mode;      tmp = XEXP (XEXP (orig_dst, 0), 0);      mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);      if (GET_MODE (tmp) == mode)	{	  if (nregs == 1)	    {	      emit_move_insn (tmp, data_regs[0]);	      i = 1;	      goto dst_done;	    }	  else if (nregs == 2 && mode == TImode)	    {	      /* Undo the subregging done above when copying between		 two TImode registers.  */	      if (GET_CODE (data_regs[0]) == SUBREG		  && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)		{		  emit_move_insn (tmp, SUBREG_REG (data_regs[0]));		}	      else		{		  rtx seq;		  start_sequence ();		  emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);		  emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);		  seq = get_insns ();		  end_sequence ();		  emit_no_conflict_block (seq, tmp, data_regs[0],					  data_regs[1], NULL_RTX);		}	      i = 2;	      goto dst_done;	    }	}      /* ??? If nregs > 1, consider reconstructing the word in regs.  */      /* ??? Optimize mode < dst_mode with strict_low_part.  */      /* No appropriate mode; fall back on memory.  We can speed things	 up by recognizing extra alignment information.  */      orig_dst = change_address (orig_dst, GET_MODE (orig_dst),				 copy_addr_to_reg (XEXP (orig_dst, 0)));      dst_align = GET_MODE_SIZE (GET_MODE (tmp));    }  /* Write out the data in whatever chunks reading the source allowed.  */  if (dst_align >= 8)    {      while (i < nregs && GET_MODE (data_regs[i]) == DImode)	{	  emit_move_insn (change_address (orig_dst, DImode,					  plus_constant (XEXP (orig_dst, 0),							 ofs)),			  data_regs[i]);	  ofs += 8;	  i++;	}    }  if (dst_align >= 4)    {      /* If the source has remaining DImode regs, write them out in	 two pieces.  */      while (i < nregs && GET_MODE (data_regs[i]) == DImode)	{	  tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),			      NULL_RTX, 1, OPTAB_WIDEN);	  emit_move_insn (change_address (orig_dst, SImode,					  plus_constant (XEXP (orig_dst, 0),							 ofs)),			  gen_lowpart (SImode, data_regs[i]));	  emit_move_insn (change_address (orig_dst, SImode,					  plus_constant (XEXP (orig_dst, 0),							 ofs+4)),			  gen_lowpart (SImode, tmp));	  ofs += 8;	  i++;	}      while (i < nregs && GET_MODE (data_regs[i]) == SImode)	{	  emit_move_insn (change_address(orig_dst, SImode,					 plus_constant (XEXP (orig_dst, 0),							ofs)),			  data_regs[i]);	  ofs += 4;	  i++;	}    }  if (i < nregs && GET_MODE (data_regs[i]) == DImode)    {      /* Write out a remaining block of words using unaligned methods.  */      for (words = 1; i+words < nregs ; ++words)	if (GET_MODE (data_regs[i+words]) != DImode)	  break;      if (words == 1)	alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);      else        alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);           i += words;      ofs += words * 8;    }  /* Due to the above, this won't be aligned.  */  /* ??? If we have more than one of these, consider constructing full     words in registers and using alpha_expand_unaligned_store_words.  */  while (i < nregs && GET_MODE (data_regs[i]) == SImode)    {      alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);      ofs += 4;      i++;    }  if (dst_align >= 2)    while (i < nregs && GET_MODE (data_regs[i]) == HImode)      {	emit_move_insn (change_address (orig_dst, HImode,					plus_constant (XEXP (orig_dst, 0),						       ofs)),			data_regs[i]);	i++;	ofs += 2;      }  else    while (i < nregs && GET_MODE (data_regs[i]) == HImode)      {	alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);	i++;	ofs += 2;      }  while (i < nregs && GET_MODE (data_regs[i]) == QImode)    {      emit_move_insn (change_address (orig_dst, QImode,				      plus_constant (XEXP (orig_dst, 0),						     ofs)),		      data_regs[i]);      i++;      ofs += 1;    } dst_done:  if (i != nregs)    abort();  return 1;}intalpha_expand_block_clear (operands)     rtx operands[];{  rtx bytes_rtx	= operands[1];  rtx align_rtx = operands[2];  HOST_WIDE_INT bytes = INTVAL (bytes_rtx);  HOST_WIDE_INT align = INTVAL (align_rtx);  rtx orig_dst	= operands[0];  rtx tmp;  HOST_WIDE_INT i, words, ofs = 0;    if (bytes <= 0)    return 1;  if (bytes > MAX_MOVE_WORDS*8)    return 0;  /* Look for stricter alignment.  */  tmp = XEXP (orig_dst, 0);  if (GET_CODE (tmp) == REG)    {      if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)	align = REGNO_POINTER_ALIGN (REGNO (tmp));    }  else if (GET_CODE (tmp) == PLUS	   && GET_CODE (XEXP (tmp, 0)) == REG	   && GET_CODE (XEXP (tmp, 1)) == CONST_INT)    {      HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));      int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));      if (a > align)	{          if (a >= 8 && c % 8 == 0)	    align = 8;          else if (a >= 4 && c % 4 == 0)	    align = 4;          else if (a >= 2 && c % 2 == 0)	    align = 2;	}    }  else if (GET_CODE (tmp) == ADDRESSOF)    {      enum machine_mode mode;      mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);      if (GET_MODE (XEXP (tmp, 0)) == mode)	{	  emit_move_insn (XEXP (tmp, 0), const0_rtx);	  return 1;	}      /* No appropriate mode; fall back on memory.  */      orig_dst = change_address (orig_dst, GET_MODE (orig_dst),				 copy_addr_to_reg (tmp));      align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0)));    }  /* Handle a block of contiguous words first.  */  if (align >= 8 && bytes >= 8)    {      words = bytes / 8;      for (i = 0; i < words; ++i)	{	  emit_move_insn (change_address(orig_dst, DImode,					 plus_constant (XEXP (orig_dst, 0),							ofs + i*8)),			  const0_rtx);	}      bytes -= words * 8;      ofs += words * 8;    }  if (align >= 4 && bytes >= 4)    {      words = bytes / 4;      for (i = 0; i < words; ++i)	{	  emit_move_insn (change_address (orig_dst, SImode,					  plus_constant (XEXP (orig_dst, 0),							 ofs + i*4)),			  const0_rtx);	}      bytes -= words * 4;      ofs += words * 4;    }  if (bytes >= 16)    {      words = bytes / 8;      alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);      bytes -= words * 8;      ofs += words * 8;    }  /* Next clean up any trailing pieces.  We know from the contiguous     block move that there are no aligned SImode or DImode hunks left.  */  if (!TARGET_BWX && bytes >= 8)    {      alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);      bytes -= 8;      ofs += 8;    }  if (!TARGET_BWX && bytes >= 4)    {      alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);      bytes -= 4;      ofs += 4;    }  if (bytes >= 2)    {      if (align >= 2)	{	  do {	    emit_move_insn (change_address (orig_dst, HImode,					    plus_constant (XEXP (orig_dst, 0),							   ofs)),			    const0_rtx);	    bytes -= 2;	    ofs += 2;	  } while (bytes >= 2);	}      else if (!TARGET_BWX)	{	  alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);	  bytes -= 2;	  ofs += 2;	}    }  while (bytes > 0)    {      emit_move_insn (change_address (orig_dst, QImode,				      plus_constant (XEXP (orig_dst, 0),						     ofs)),		      const0_rtx);      bytes -= 1;      ofs += 1;    }  return 1;}/* Adjust the cost of a scheduling dependency.  Return the new cost of   a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */intalpha_adjust_cost (insn, link, dep_insn, cost)     rtx insn;     rtx link;     rtx dep_insn;     int cost;{  rtx set, set_src;  enum attr_type insn_type, dep_insn_type;  /* If the dependence is an anti-dependence, there is no cost.  For an     output dependence, there is sometimes a cost, but it doesn't seem     worth handling those few cases.  */  if (REG_NOTE_KIND (link) != 0)    return 0;  /* If we can't recognize the insns, we can't really do anything.  */  if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)    return cost;  insn_type = get_attr_type (insn);  dep_insn_type = get_attr_type (dep_insn);  /* Bring in the user-defined memory latency.  */  if (dep_insn_type == TYPE_ILD      || dep_insn_type == TYPE_FLD     

⌨️ 快捷键说明

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