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

📄 arm.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
{  return (s_register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))	  || memory_operand (op, mode));}/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a   constant that is valid when negated.  */intarm_add_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (s_register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT	      && (const_ok_for_arm (INTVAL (op))		  || const_ok_for_arm (-INTVAL (op)))));}intarm_not_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (s_register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT	      && (const_ok_for_arm (INTVAL (op))		  || const_ok_for_arm (~INTVAL (op)))));}/* Return TRUE for valid operands for the rhs of an FPU instruction.  */intfpu_rhs_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (s_register_operand (op, mode))    return TRUE;  else if (GET_CODE (op) == CONST_DOUBLE)    return (const_double_rtx_ok_for_fpu (op));  return FALSE;}intfpu_add_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (s_register_operand (op, mode))    return TRUE;  else if (GET_CODE (op) == CONST_DOUBLE)    return (const_double_rtx_ok_for_fpu (op) 	    || neg_const_double_rtx_ok_for_fpu (op));  return FALSE;}/* Return nonzero if OP is a constant power of two.  */intpower_of_two_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) == CONST_INT)    {      HOST_WIDE_INT value = INTVAL(op);      return value != 0  &&  (value & (value - 1)) == 0;    }  return FALSE;}/* Return TRUE for a valid operand of a DImode operation.   Either: REG, CONST_DOUBLE or MEM(DImode_address).   Note that this disallows MEM(REG+REG), but allows   MEM(PRE/POST_INC/DEC(REG)).  */intdi_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (s_register_operand (op, mode))    return TRUE;  switch (GET_CODE (op))    {    case CONST_DOUBLE:    case CONST_INT:      return TRUE;    case MEM:      return memory_address_p (DImode, XEXP (op, 0));    default:      return FALSE;    }}/* Return TRUE for a valid operand of a DFmode operation when -msoft-float.   Either: REG, CONST_DOUBLE or MEM(DImode_address).   Note that this disallows MEM(REG+REG), but allows   MEM(PRE/POST_INC/DEC(REG)).  */intsoft_df_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (s_register_operand (op, mode))    return TRUE;  switch (GET_CODE (op))    {    case CONST_DOUBLE:      return TRUE;    case MEM:      return memory_address_p (DFmode, XEXP (op, 0));    default:      return FALSE;    }}/* Return TRUE for valid index operands. */intindex_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (s_register_operand(op, mode)	  || (immediate_operand (op, mode)	      && INTVAL (op) < 4096 && INTVAL (op) > -4096));}/* Return TRUE for valid shifts by a constant. This also accepts any   power of two on the (somewhat overly relaxed) assumption that the   shift operator in this case was a mult. */intconst_shift_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (power_of_two_operand (op, mode)	  || (immediate_operand (op, mode)	      && (INTVAL (op) < 32 && INTVAL (op) > 0)));}/* Return TRUE for arithmetic operators which can be combined with a multiply   (shift).  */intshiftable_operator (x, mode)     rtx x;     enum machine_mode mode;{  if (GET_MODE (x) != mode)    return FALSE;  else    {      enum rtx_code code = GET_CODE (x);      return (code == PLUS || code == MINUS	      || code == IOR || code == XOR || code == AND);    }}/* Return TRUE for shift operators. */intshift_operator (x, mode)     rtx x;     enum machine_mode mode;{  if (GET_MODE (x) != mode)    return FALSE;  else    {      enum rtx_code code = GET_CODE (x);      if (code == MULT)	return power_of_two_operand (XEXP (x, 1));      return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT	      || code == ROTATERT);    }}int equality_operator (x, mode)     rtx x;     enum machine_mode mode;{  return GET_CODE (x) == EQ || GET_CODE (x) == NE;}/* Return TRUE for SMIN SMAX UMIN UMAX operators. */intminmax_operator (x, mode)     rtx x;     enum machine_mode mode;{  enum rtx_code code = GET_CODE (x);  if (GET_MODE (x) != mode)    return FALSE;  return code == SMIN || code == SMAX || code == UMIN || code == UMAX;}/* return TRUE if x is EQ or NE *//* Return TRUE if this is the condition code register, if we aren't given   a mode, accept any class CCmode register */intcc_register (x, mode)     rtx x;     enum machine_mode mode;{  if (mode == VOIDmode)    {      mode = GET_MODE (x);      if (GET_MODE_CLASS (mode) != MODE_CC)	return FALSE;    }  if (mode == GET_MODE (x) && GET_CODE (x) == REG && REGNO (x) == 24)    return TRUE;  return FALSE;}/* Return TRUE if this is the condition code register, if we aren't given   a mode, accept any mode in class CC_MODE that is reversible */intreversible_cc_register (x, mode)     rtx x;     enum machine_mode mode;{  if (mode == VOIDmode)    {      mode = GET_MODE (x);      if (GET_MODE_CLASS (mode) != MODE_CC	  && GET_CODE (x) == REG && REGNO (x) == 24)	abort ();      if (GET_MODE_CLASS (mode) != MODE_CC	  || (! flag_fast_math && ! REVERSIBLE_CC_MODE (mode)))	return FALSE;    }  if (mode == GET_MODE (x) && GET_CODE (x) == REG && REGNO (x) == 24)    return TRUE;  return FALSE;}enum rtx_codeminmax_code (x)     rtx x;{  enum rtx_code code = GET_CODE (x);  if (code == SMAX)    return GE;  else if (code == SMIN)    return LE;  else if (code == UMIN)    return LEU;  else if (code == UMAX)    return GEU;  abort ();}/* Return 1 if memory locations are adjacent */intadjacent_mem_locations (a, b)     rtx a, b;{  int val0 = 0, val1 = 0;  int reg0, reg1;    if ((GET_CODE (XEXP (a, 0)) == REG       || (GET_CODE (XEXP (a, 0)) == PLUS	   && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))      && (GET_CODE (XEXP (b, 0)) == REG	  || (GET_CODE (XEXP (b, 0)) == PLUS	      && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))    {      if (GET_CODE (XEXP (a, 0)) == PLUS)        {	  reg0 = REGNO (XEXP (XEXP (a, 0), 0));	  val0 = INTVAL (XEXP (XEXP (a, 0), 1));        }      else	reg0 = REGNO (XEXP (a, 0));      if (GET_CODE (XEXP (b, 0)) == PLUS)        {	  reg1 = REGNO (XEXP (XEXP (b, 0), 0));	  val1 = INTVAL (XEXP (XEXP (b, 0), 1));        }      else	reg1 = REGNO (XEXP (b, 0));      return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);    }  return 0;}/* Return 1 if OP is a load multiple operation.  It is known to be   parallel and the first section will be tested. */intload_multiple_operation (op, mode)     rtx op;     enum machine_mode mode;{  HOST_WIDE_INT count = XVECLEN (op, 0);  int dest_regno;  rtx src_addr;  HOST_WIDE_INT i = 1, base = 0;  rtx elt;  if (count <= 1      || GET_CODE (XVECEXP (op, 0, 0)) != SET)    return 0;  /* Check to see if this might be a write-back */  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)    {      i++;      base = 1;      /* Now check it more carefully */      if (GET_CODE (SET_DEST (elt)) != REG          || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG          || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))          || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT          || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 2) * 4          || GET_CODE (XVECEXP (op, 0, count - 1)) != CLOBBER          || GET_CODE (XEXP (XVECEXP (op, 0, count - 1), 0)) != REG          || REGNO (XEXP (XVECEXP (op, 0, count - 1), 0))              != REGNO (SET_DEST (elt)))        return 0;      count--;    }  /* Perform a quick check so we don't blow up below.  */  if (count <= i      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)    return 0;  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);  for (; i < count; i++)    {      rtx elt = XVECEXP (op, 0, i);      if (GET_CODE (elt) != SET          || GET_CODE (SET_DEST (elt)) != REG          || GET_MODE (SET_DEST (elt)) != SImode          || REGNO (SET_DEST (elt)) != dest_regno + i - base          || GET_CODE (SET_SRC (elt)) != MEM          || GET_MODE (SET_SRC (elt)) != SImode          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS          || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)        return 0;    }  return 1;}/* Return 1 if OP is a store multiple operation.  It is known to be   parallel and the first section will be tested. */intstore_multiple_operation (op, mode)     rtx op;     enum machine_mode mode;{  HOST_WIDE_INT count = XVECLEN (op, 0);  int src_regno;  rtx dest_addr;  HOST_WIDE_INT i = 1, base = 0;  rtx elt;  if (count <= 1      || GET_CODE (XVECEXP (op, 0, 0)) != SET)    return 0;  /* Check to see if this might be a write-back */  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)    {      i++;      base = 1;      /* Now check it more carefully */      if (GET_CODE (SET_DEST (elt)) != REG          || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG          || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))          || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT          || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 2) * 4          || GET_CODE (XVECEXP (op, 0, count - 1)) != CLOBBER          || GET_CODE (XEXP (XVECEXP (op, 0, count - 1), 0)) != REG          || REGNO (XEXP (XVECEXP (op, 0, count - 1), 0))              != REGNO (SET_DEST (elt)))        return 0;      count--;    }  /* Perform a quick check so we don't blow up below.  */  if (count <= i      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)    return 0;  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);  for (; i < count; i++)    {      elt = XVECEXP (op, 0, i);      if (GET_CODE (elt) != SET          || GET_CODE (SET_SRC (elt)) != REG          || GET_MODE (SET_SRC (elt)) != SImode          || REGNO (SET_SRC (elt)) != src_regno + i - base          || GET_CODE (SET_DEST (elt)) != MEM          || GET_MODE (SET_DEST (elt)) != SImode          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS          || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)        return 0;    }  return 1;}intmulti_register_push (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) != PARALLEL      || (GET_CODE (XVECEXP (op, 0, 0)) != SET)      || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)      || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != 2))    return 0;  return 1;}/* Routines for use with attributes */intconst_pool_offset (symbol)     rtx symbol;{  return get_pool_offset (symbol) - get_pool_size () - get_prologue_size ();}/* Routines for use in generating RTL */rtxarm_gen_load_multiple (base_regno, count, from, up, write_back)     int base_regno;     int count;     rtx from;     int up;     int write_back;{  int i = 0, j;  rtx result;  int sign = up ? 1 : -1;  result = gen_rtx (PARALLEL, VOIDmode,                    rtvec_alloc (count + (write_back ? 2 : 0)));  if (write_back)    {      XVECEXP (result, 0, 0)	= gen_rtx (SET, GET_MODE (from), from,		   plus_constant (from, count * 4 * sign));      i = 1;      count++;    }  for (j = 0; i < count; i++, j++)    {      XVECEXP (result, 0, i)	= gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, base_regno + j),		   gen_rtx (MEM, SImode,			    plus_constant (from, j * 4 * sign)));    }  if (write_back)    XVECEXP (result, 0, i) = gen_rtx (CLOBBER, SImode, from);  return result;}rtxarm_gen_store_multiple (base_regno, count, to, up, write_back)     int base_regno;     int count;

⌨️ 快捷键说明

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