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

📄 xtensa.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
     enum machine_mode mode ATTRIBUTE_UNUSED;{  return ((GET_CODE (op) == CONST_INT) && xtensa_tp7 (INTVAL (op) - 1));}intlsbitnum_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == CONST_INT)    {      return (BITS_BIG_ENDIAN	      ? (INTVAL (op) == BITS_PER_WORD-1)	      : (INTVAL (op) == 0));    }  return FALSE;}static intb4const_or_zero (v)     int v;{  if (v == 0)    return TRUE;  return xtensa_b4const (v);}intbranch_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) == CONST_INT)    return b4const_or_zero (INTVAL (op));  return register_operand (op, mode);}intubranch_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) == CONST_INT)    return xtensa_b4constu (INTVAL (op));  return register_operand (op, mode);}intcall_insn_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if ((GET_CODE (op) == REG)      && (op != arg_pointer_rtx)      && ((REGNO (op) < FRAME_POINTER_REGNUM)	  || (REGNO (op) > LAST_VIRTUAL_REGISTER)))    return TRUE;  if (CONSTANT_ADDRESS_P (op))    {      /* Direct calls only allowed to static functions with PIC.  */      return (!flag_pic || (GET_CODE (op) == SYMBOL_REF			    && SYMBOL_REF_FLAG (op)));    }  return FALSE;}intmove_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return TRUE;  /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and     result in 0/1. */  if (GET_CODE (op) == CONSTANT_P_RTX)    return TRUE;  if (GET_CODE (op) == CONST_INT)    return xtensa_simm12b (INTVAL (op));  if (GET_CODE (op) == MEM)    return memory_address_p (mode, XEXP (op, 0));  return FALSE;}intsmalloffset_mem_p (op)     rtx op;{  if (GET_CODE (op) == MEM)    {      rtx addr = XEXP (op, 0);      if (GET_CODE (addr) == REG)	return REG_OK_FOR_BASE_P (addr);      if (GET_CODE (addr) == PLUS)	{	  rtx offset = XEXP (addr, 0);	  if (GET_CODE (offset) != CONST_INT)	    offset = XEXP (addr, 1);	  if (GET_CODE (offset) != CONST_INT)	    return FALSE;	  return xtensa_lsi4x4 (INTVAL (offset));	}    }  return FALSE;}intsmalloffset_double_mem_p (op)     rtx op;{  if (!smalloffset_mem_p (op))    return FALSE;  return smalloffset_mem_p (adjust_address (op, GET_MODE (op), 4));}intconstantpool_address_p (addr)     rtx addr;{  rtx sym = addr;  if (GET_CODE (addr) == CONST)    {      rtx offset;      /* only handle (PLUS (SYM, OFFSET)) form */      addr = XEXP (addr, 0);      if (GET_CODE (addr) != PLUS)	return FALSE;      /* make sure the address is word aligned */      offset = XEXP (addr, 1);      if ((GET_CODE (offset) != CONST_INT)	  || ((INTVAL (offset) & 3) != 0))	return FALSE;      sym = XEXP (addr, 0);    }  if ((GET_CODE (sym) == SYMBOL_REF)      && CONSTANT_POOL_ADDRESS_P (sym))    return TRUE;  return FALSE;}intconstantpool_mem_p (op)     rtx op;{  if (GET_CODE (op) == MEM)    return constantpool_address_p (XEXP (op, 0));  return FALSE;}intnon_const_move_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (GET_CODE (op) == MEM)    return memory_address_p (mode, XEXP (op, 0));  return FALSE;}/* Accept the floating point constant 1 in the appropriate mode.  */intconst_float_1_operand (op, mode)     rtx op;     enum machine_mode mode;{  REAL_VALUE_TYPE d;  static REAL_VALUE_TYPE onedf;  static REAL_VALUE_TYPE onesf;  static int one_initialized;  if ((GET_CODE (op) != CONST_DOUBLE)      || (mode != GET_MODE (op))      || (mode != DFmode && mode != SFmode))    return FALSE;  REAL_VALUE_FROM_CONST_DOUBLE (d, op);  if (! one_initialized)    {      onedf = REAL_VALUE_ATOF ("1.0", DFmode);      onesf = REAL_VALUE_ATOF ("1.0", SFmode);      one_initialized = TRUE;    }  if (mode == DFmode)    return REAL_VALUES_EQUAL (d, onedf);  else    return REAL_VALUES_EQUAL (d, onesf);}intfpmem_offset_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == CONST_INT)    return xtensa_mem_offset (INTVAL (op), SFmode);  return 0;}voidxtensa_extend_reg (dst, src)     rtx dst;     rtx src;{  rtx temp = gen_reg_rtx (SImode);  rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));  /* generate paradoxical subregs as needed so that the modes match */  src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);  dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);  emit_insn (gen_ashlsi3 (temp, src, shift));  emit_insn (gen_ashrsi3 (dst, temp, shift));}voidxtensa_load_constant (dst, src)     rtx dst;     rtx src;{  enum machine_mode mode = GET_MODE (dst);  src = force_const_mem (SImode, src);  /* PC-relative loads are always SImode so we have to add a SUBREG if that     is not the desired mode */  if (mode != SImode)    {      if (register_operand (dst, mode))	dst = simplify_gen_subreg (SImode, dst, mode, 0);      else	{	  src = force_reg (SImode, src);	  src = gen_lowpart_SUBREG (mode, src);	}    }  emit_move_insn (dst, src);}intbranch_operator (x, mode)     rtx x;     enum machine_mode mode;{  if (GET_MODE (x) != mode)    return FALSE;  switch (GET_CODE (x))    {    case EQ:    case NE:    case LT:    case GE:      return TRUE;    default:      break;    }  return FALSE;}intubranch_operator (x, mode)     rtx x;     enum machine_mode mode;{  if (GET_MODE (x) != mode)    return FALSE;  switch (GET_CODE (x))    {    case LTU:    case GEU:      return TRUE;    default:      break;    }  return FALSE;}intboolean_operator (x, mode)     rtx x;     enum machine_mode mode;{  if (GET_MODE (x) != mode)    return FALSE;  switch (GET_CODE (x))    {    case EQ:    case NE:      return TRUE;    default:      break;    }  return FALSE;}intxtensa_mask_immediate (v)     int v;{#define MAX_MASK_SIZE 16  int mask_size;  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)    {      if ((v & 1) == 0)	return FALSE;      v = v >> 1;      if (v == 0)	return TRUE;    }  return FALSE;}intxtensa_mem_offset (v, mode)     unsigned v;     enum machine_mode mode;{  switch (mode)    {    case BLKmode:      /* Handle the worst case for block moves.  See xtensa_expand_block_move	 where we emit an optimized block move operation if the block can be	 moved in < "move_ratio" pieces.  The worst case is when the block is	 aligned but has a size of (3 mod 4) (does this happen?) so that the	 last piece requires a byte load/store. */      return (xtensa_uimm8 (v) &&	      xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));    case QImode:      return xtensa_uimm8 (v);    case HImode:      return xtensa_uimm8x2 (v);    case DFmode:      return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));    default:      break;    }  return xtensa_uimm8x4 (v);}/* Make normal rtx_code into something we can index from an array */static enum internal_testmap_test_to_internal_test (test_code)     enum rtx_code test_code;{  enum internal_test test = ITEST_MAX;  switch (test_code)    {    default:			break;    case EQ:  test = ITEST_EQ;  break;    case NE:  test = ITEST_NE;  break;    case GT:  test = ITEST_GT;  break;    case GE:  test = ITEST_GE;  break;    case LT:  test = ITEST_LT;  break;    case LE:  test = ITEST_LE;  break;    case GTU: test = ITEST_GTU; break;    case GEU: test = ITEST_GEU; break;    case LTU: test = ITEST_LTU; break;    case LEU: test = ITEST_LEU; break;    }  return test;}/* Generate the code to compare two integer values.  The return value is   the comparison expression. */static rtxgen_int_relational (test_code, cmp0, cmp1, p_invert)     enum rtx_code test_code;	/* relational test (EQ, etc) */     rtx cmp0;			/* first operand to compare */     rtx cmp1;			/* second operand to compare */     int *p_invert;		/* whether branch needs to reverse its test */{  struct cmp_info {    enum rtx_code test_code;	/* test code to use in insn */    int (*const_range_p) PARAMS ((int)); /* predicate function to check range */    int const_add;		/* constant to add (convert LE -> LT) */    int reverse_regs;		/* reverse registers in test */    int invert_const;		/* != 0 if invert value if cmp1 is constant */    int invert_reg;		/* != 0 if invert value if cmp1 is register */    int unsignedp;		/* != 0 for unsigned comparisons.  */  };  static struct cmp_info info[ (int)ITEST_MAX ] = {    { EQ,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* EQ  */    { NE,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* NE  */    { LT,	b4const_or_zero,	1, 1, 1, 0, 0 },	/* GT  */    { GE,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* GE  */    { LT,	b4const_or_zero,	0, 0, 0, 0, 0 },	/* LT  */    { GE,	b4const_or_zero,	1, 1, 1, 0, 0 },	/* LE  */    { LTU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* GTU */    { GEU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* GEU */    { LTU,	xtensa_b4constu,	0, 0, 0, 0, 1 },	/* LTU */    { GEU,	xtensa_b4constu,	1, 1, 1, 0, 1 },	/* LEU */  };  enum internal_test test;  enum machine_mode mode;  struct cmp_info *p_info;  test = map_test_to_internal_test (test_code);  if (test == ITEST_MAX)    abort ();  p_info = &info[ (int)test ];  mode = GET_MODE (cmp0);  if (mode == VOIDmode)    mode = GET_MODE (cmp1);  /* Make sure we can handle any constants given to us.  */  if (GET_CODE (cmp1) == CONST_INT)    {      HOST_WIDE_INT value = INTVAL (cmp1);      unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;      /* if the immediate overflows or does not fit in the immediate field,	 spill it to a register */      if ((p_info->unsignedp ?	   (uvalue + p_info->const_add > uvalue) :	   (value + p_info->const_add > value)) != (p_info->const_add > 0))	{	  cmp1 = force_reg (mode, cmp1);	}      else if (!(p_info->const_range_p) (value + p_info->const_add))	{	  cmp1 = force_reg (mode, cmp1);	}    }  else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))    {      cmp1 = force_reg (mode, cmp1);    }  /* See if we need to invert the result.  */  *p_invert = ((GET_CODE (cmp1) == CONST_INT)	       ? p_info->invert_const	       : p_info->invert_reg);  /* Comparison to constants, may involve adding 1 to change a LT into LE.     Comparison between two registers, may involve switching operands.  */  if (GET_CODE (cmp1) == CONST_INT)    {      if (p_info->const_add != 0)	cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);    }  else if (p_info->reverse_regs)    {      rtx temp = cmp0;      cmp0 = cmp1;      cmp1 = temp;    }  return gen_rtx (p_info->test_code, VOIDmode, cmp0, cmp1);}/* Generate the code to compare two float values.  The return value is   the comparison expression. */static rtxgen_float_relational (test_code, cmp0, cmp1)     enum rtx_code test_code;	/* relational test (EQ, etc) */     rtx cmp0;			/* first operand to compare */

⌨️ 快捷键说明

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