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

📄 mips.c

📁 gcc3.2.1源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		ret = "mov.s\t%0,%1";	    }	  else if (MD_REG_P (regno0))	    {	      if (GP_REG_P (regno1))		{		  delay = DELAY_HILO;		  if (regno0 != HILO_REGNUM && ! TARGET_MIPS16)		    ret = "mt%0\t%1";		}	    }	  else if (regno0 == FPSW_REGNUM && ! ISA_HAS_8CC)	    {	      if (GP_REG_P (regno1))		{		  delay = DELAY_LOAD;		  ret = "ctc1\t%0,$31";		}	    }	}      else if (code1 == MEM)	{	  delay = DELAY_LOAD;	  if (TARGET_STATS)	    mips_count_memory_refs (op1, 1);	  if (GP_REG_P (regno0))	    {	      /* For loads, use the mode of the memory item, instead of the		 target, so zero/sign extend can use this code as well.  */	      switch (GET_MODE (op1))		{		default:		  break;		case SFmode:		  ret = "lw\t%0,%1";		  break;		case SImode:		case CCmode:		  ret = ((unsignedp && TARGET_64BIT)			 ? "lwu\t%0,%1"			 : "lw\t%0,%1");		  break;		case HImode:		  ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";		  break;		case QImode:		  ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";		  break;		}	    }	  else if (FP_REG_P (regno0) && (mode == SImode || mode == SFmode))	    ret = "l.s\t%0,%1";	  if (ret != (char *)0 && MEM_VOLATILE_P (op1))	    {	      size_t i = strlen (ret);	      if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))		abort ();	      sprintf (volatile_buffer, "%%{%s%%}", ret);	      ret = volatile_buffer;	    }	}      else if (code1 == CONST_INT	       || (code1 == CONST_DOUBLE		   && GET_MODE (op1) == VOIDmode))	{	  if (code1 == CONST_DOUBLE)	    {	      /* This can happen when storing constants into long long                 bitfields.  Just store the least significant word of                 the value.  */	      operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1));	    }	  if (INTVAL (op1) == 0 && ! TARGET_MIPS16)	    {	      if (GP_REG_P (regno0))		ret = "move\t%0,%z1";	      else if (FP_REG_P (regno0))		{		  delay = DELAY_LOAD;		  ret = "mtc1\t%z1,%0";		}	      else if (MD_REG_P (regno0))		{		  delay = DELAY_HILO;		  ret = "mt%0\t%.";		}	    }	  else if (GP_REG_P (regno0))	    {	      /* Don't use X format, because that will give out of		 range numbers for 64 bit host and 32 bit target.  */	      if (! TARGET_MIPS16)		ret = "li\t%0,%1\t\t\t# %X1";	      else		{		  if (INTVAL (op1) >= 0 && INTVAL (op1) <= 0xffff)		    ret = "li\t%0,%1";		  else if (INTVAL (op1) < 0 && INTVAL (op1) >= -0xffff)		    ret = "li\t%0,%n1\n\tneg\t%0";		}	    }	}      else if (code1 == CONST_DOUBLE && mode == SFmode)	{	  if (op1 == CONST0_RTX (SFmode))	    {	      if (GP_REG_P (regno0))		ret = "move\t%0,%.";	      else if (FP_REG_P (regno0))		{		  delay = DELAY_LOAD;		  ret = "mtc1\t%.,%0";		}	    }	  else	    {	      delay = DELAY_LOAD;	      ret = "li.s\t%0,%1";	    }	}      else if (code1 == LABEL_REF)	{	  if (TARGET_STATS)	    mips_count_memory_refs (op1, 1);	  ret = "la\t%0,%a1";	}      else if (code1 == SYMBOL_REF || code1 == CONST)	{	  if (HALF_PIC_P () && CONSTANT_P (op1) && HALF_PIC_ADDRESS_P (op1))	    {	      rtx offset = const0_rtx;	      if (GET_CODE (op1) == CONST)		op1 = eliminate_constant_term (XEXP (op1, 0), &offset);	      if (GET_CODE (op1) == SYMBOL_REF)		{		  operands[2] = HALF_PIC_PTR (op1);		  if (TARGET_STATS)		    mips_count_memory_refs (operands[2], 1);		  if (INTVAL (offset) == 0)		    {		      delay = DELAY_LOAD;		      ret = (unsignedp && TARGET_64BIT			     ? "lwu\t%0,%2"			     : "lw\t%0,%2");		    }		  else		    {		      dslots_load_total++;		      operands[3] = offset;		      if (unsignedp && TARGET_64BIT)			ret = (SMALL_INT (offset)			       ? "lwu\t%0,%2%#\n\tadd\t%0,%0,%3"			       : "lwu\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]");		      else			ret = (SMALL_INT (offset)			       ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"			       : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]");		    }		}	    }	  else if (TARGET_MIPS16		   && code1 == CONST		   && GET_CODE (XEXP (op1, 0)) == REG		   && REGNO (XEXP (op1, 0)) == GP_REG_FIRST + 28)	    {	      /* This case arises on the mips16; see                 mips16_gp_pseudo_reg.  */	      ret = "move\t%0,%+";	    }	  else if (TARGET_MIPS16		   && code1 == SYMBOL_REF		   && SYMBOL_REF_FLAG (op1)		   && (XSTR (op1, 0)[0] != '*'		       || strncmp (XSTR (op1, 0) + 1,				   LOCAL_LABEL_PREFIX,				   sizeof LOCAL_LABEL_PREFIX - 1) != 0))	    {	      /* This can occur when reloading the address of a GP                 relative symbol on the mips16.  */	      ret = "move\t%0,%+\n\taddu\t%0,%%gprel(%a1)";	    }	  else	    {	      if (TARGET_STATS)		mips_count_memory_refs (op1, 1);	      ret = "la\t%0,%a1";	    }	}      else if (code1 == PLUS)	{	  rtx add_op0 = XEXP (op1, 0);	  rtx add_op1 = XEXP (op1, 1);	  if (GET_CODE (XEXP (op1, 1)) == REG	      && GET_CODE (XEXP (op1, 0)) == CONST_INT)	    add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0);	  operands[2] = add_op0;	  operands[3] = add_op1;	  ret = "add%:\t%0,%2,%3";	}      else if (code1 == HIGH)	{	  operands[1] = XEXP (op1, 0);	  ret = "lui\t%0,%%hi(%1)";	}    }  else if (code0 == MEM)    {      if (TARGET_STATS)	mips_count_memory_refs (op0, 1);      if (code1 == REG)	{	  int regno1 = REGNO (op1) + subreg_offset1;	  if (GP_REG_P (regno1))	    {	      switch (mode)		{		case SFmode: ret = "sw\t%1,%0"; break;		case SImode: ret = "sw\t%1,%0"; break;		case HImode: ret = "sh\t%1,%0"; break;		case QImode: ret = "sb\t%1,%0"; break;		default: break;		}	    }	  else if (FP_REG_P (regno1) && (mode == SImode || mode == SFmode))	    ret = "s.s\t%1,%0";	}      else if (code1 == CONST_INT && INTVAL (op1) == 0)	{	  switch (mode)	    {	    case SFmode: ret = "sw\t%z1,%0"; break;	    case SImode: ret = "sw\t%z1,%0"; break;	    case HImode: ret = "sh\t%z1,%0"; break;	    case QImode: ret = "sb\t%z1,%0"; break;	    default: break;	    }	}      else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode))	{	  switch (mode)	    {	    case SFmode: ret = "sw\t%.,%0"; break;	    case SImode: ret = "sw\t%.,%0"; break;	    case HImode: ret = "sh\t%.,%0"; break;	    case QImode: ret = "sb\t%.,%0"; break;	    default: break;	    }	}      if (ret != 0 && MEM_VOLATILE_P (op0))	{	  size_t i = strlen (ret);	  if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))	    abort ();	  sprintf (volatile_buffer, "%%{%s%%}", ret);	  ret = volatile_buffer;	}    }  if (ret == 0)    {      abort_with_insn (insn, "bad move");      return 0;    }  if (delay != DELAY_NONE)    return mips_fill_delay_slot (ret, delay, operands, insn);  return ret;}/* Return the appropriate instructions to move 2 words */const char *mips_move_2words (operands, insn)     rtx operands[];     rtx insn;{  const char *ret = 0;  rtx op0 = operands[0];  rtx op1 = operands[1];  enum rtx_code code0 = GET_CODE (operands[0]);  enum rtx_code code1 = GET_CODE (operands[1]);  int subreg_offset0 = 0;  int subreg_offset1 = 0;  enum delay_type delay = DELAY_NONE;  while (code0 == SUBREG)    {      subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)),					     GET_MODE (SUBREG_REG (op0)),					     SUBREG_BYTE (op0),					     GET_MODE (op0));      op0 = SUBREG_REG (op0);      code0 = GET_CODE (op0);    }  if (code1 == SIGN_EXTEND)    {      op1 = XEXP (op1, 0);      code1 = GET_CODE (op1);    }  while (code1 == SUBREG)    {      subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)),					     GET_MODE (SUBREG_REG (op1)),					     SUBREG_BYTE (op1),					     GET_MODE (op1));      op1 = SUBREG_REG (op1);      code1 = GET_CODE (op1);    }  /* Sanity check.  */  if (GET_CODE (operands[1]) == SIGN_EXTEND      && code1 != REG      && code1 != CONST_INT      /* The following three can happen as the result of a questionable	 cast.  */      && code1 != LABEL_REF      && code1 != SYMBOL_REF      && code1 != CONST)    abort ();  if (code0 == REG)    {      int regno0 = REGNO (op0) + subreg_offset0;      if (code1 == REG)	{	  int regno1 = REGNO (op1) + subreg_offset1;	  /* Just in case, don't do anything for assigning a register	     to itself, unless we are filling a delay slot.  */	  if (regno0 == regno1 && set_nomacro == 0)	    ret = "";	  else if (FP_REG_P (regno0))	    {	      if (FP_REG_P (regno1))		ret = "mov.d\t%0,%1";	      else		{		  delay = DELAY_LOAD;		  if (TARGET_FLOAT64)		    {		      if (!TARGET_64BIT)			abort_with_insn (insn, "bad move");#ifdef TARGET_FP_CALL_32		      if (FP_CALL_GP_REG_P (regno1))			ret = "dsll\t%1,32\n\tor\t%1,%D1\n\tdmtc1\t%1,%0";		      else#endif			ret = "dmtc1\t%1,%0";		    }		  else		    ret = "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";		}	    }	  else if (FP_REG_P (regno1))	    {	      delay = DELAY_LOAD;	      if (TARGET_FLOAT64)		{		  if (!TARGET_64BIT)		    abort_with_insn (insn, "bad move");#ifdef TARGET_FP_CALL_32		  if (FP_CALL_GP_REG_P (regno0))		    ret = "dmfc1\t%0,%1\n\tmfc1\t%D0,%1\n\tdsrl\t%0,32";		  else#endif		    ret = "dmfc1\t%0,%1";		}	      else		ret = "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";	    }	  else if (MD_REG_P (regno0) && GP_REG_P (regno1) && !TARGET_MIPS16)	    {	      delay = DELAY_HILO;	      if (TARGET_64BIT)		{		  if (regno0 != HILO_REGNUM)		    ret = "mt%0\t%1";		  else if (regno1 == 0)		    ret = "mtlo\t%.\n\tmthi\t%.";		}	      else		ret = "mthi\t%M1\n\tmtlo\t%L1";	    }	  else if (GP_REG_P (regno0) && MD_REG_P (regno1))	    {	      delay = DELAY_HILO;	      if (TARGET_64BIT)		{		  if (regno1 != HILO_REGNUM)		    ret = "mf%1\t%0";		}	      else		ret = "mfhi\t%M0\n\tmflo\t%L0";	    }	  else if (TARGET_64BIT)	    ret = "move\t%0,%1";	  else if (regno0 != (regno1+1))	    ret = "move\t%0,%1\n\tmove\t%D0,%D1";	  else	    ret = "move\t%D0,%D1\n\tmove\t%0,%1";	}      else if (code1 == CONST_DOUBLE)	{	  /* Move zero from $0 unless !TARGET_64BIT and recipient	     is 64-bit fp reg, in which case generate a constant.  */	  if (op1 != CONST0_RTX (GET_MODE (op1))	      || (TARGET_FLOAT64 && !TARGET_64BIT && FP_REG_P (regno0)))	    {	      if (GET_MODE (op1) == DFmode)		{		  delay = DELAY_LOAD;#ifdef TARGET_FP_CALL_32		  if (FP_CALL_GP_REG_P (regno0))		    {		      if (TARGET_FLOAT64 && !TARGET_64BIT)			{			  split_double (op1, operands + 2, operands + 3);			  ret = "li\t%0,%2\n\tli\t%D0,%3";			}		      else			ret = "li.d\t%0,%1\n\tdsll\t%D0,%0,32\n\tdsrl\t%D0,32\n\tdsrl\t%0,32";		    }		  else#endif		    /* GNU as emits 64-bit code for li.d if the ISA is 3		       or higher.  For !TARGET_64BIT && gp registers we		       need to avoid this by using two li instructions		       instead.  */		    if (ISA_HAS_64BIT_REGS			&& ! TARGET_64BIT			&& ! FP_REG_P (regno0))		      {			spl

⌨️ 快捷键说明

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