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

📄 m32r.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 5 页
字号:
  REAL_VALUE_FROM_CONST_DOUBLE (r, op);  REAL_VALUE_TO_TARGET_DOUBLE (r, l);  if (l[0] == 0 && l[1] == 0)    return 1;  if ((l[0] & 0xffff) == 0 && l[1] == 0)    return 1;  return 0;}/* Return 1 if OP is an EQ or NE comparison operator.  */inteqne_comparison_operator (op, mode)    rtx op;    enum machine_mode mode ATTRIBUTE_UNUSED;{  enum rtx_code code = GET_CODE (op);  if (GET_RTX_CLASS (code) != '<')    return 0;  return (code == EQ || code == NE);}/* Return 1 if OP is a signed comparison operator.  */intsigned_comparison_operator (op, mode)    rtx op;    enum machine_mode mode ATTRIBUTE_UNUSED;{  enum rtx_code code = GET_CODE (op);  if (GET_RTX_CLASS (code) != '<')    return 0;  return (code == EQ || code == NE	  || code == LT || code == LE || code == GT || code == GE);}/* Return 1 if OP is (mem (reg ...)).   This is used in insn length calcs.  */intmemreg_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;}/* Return true if OP is an acceptable input argument for a zero/sign extend   operation.  */intextend_operand (op, mode)     rtx op;     enum machine_mode mode;{  rtx addr;  switch (GET_CODE (op))    {    case REG :    case SUBREG :      return register_operand (op, mode);    case MEM :      addr = XEXP (op, 0);      if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)	return 0;		/* loads can't do pre inc/pre dec */      return address_operand (addr, mode);    default :      return 0;    }}/* Return nonzero if the operand is an insn that is a small insn.   Allow const_int 0 as well, which is a placeholder for NOP slots.  */intsmall_insn_p (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)    return 1;  if (! INSN_P (op))    return 0;  return get_attr_length (op) == 2;}/* Return nonzero if the operand is an insn that is a large insn.  */intlarge_insn_p (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  if (! INSN_P (op))    return 0;  return get_attr_length (op) != 2;}/* Comparisons.  *//* X and Y are two things to compare using CODE.  Emit the compare insn and   return the rtx for compare [arg0 of the if_then_else].   If need_compare is true then the comparison insn must be generated, rather   than being susummed into the following branch instruction.  */rtxgen_compare (code, x, y, need_compare)     enum rtx_code code;     rtx x, y;     int need_compare;{  enum rtx_code compare_code, branch_code;  rtx cc_reg = gen_rtx_REG (CCmode, CARRY_REGNUM);  int must_swap = 0;  switch (code)    {    case EQ:  compare_code = EQ;  branch_code = NE; break;    case NE:  compare_code = EQ;  branch_code = EQ; break;    case LT:  compare_code = LT;  branch_code = NE; break;    case LE:  compare_code = LT;  branch_code = EQ; must_swap = 1; break;    case GT:  compare_code = LT;  branch_code = NE; must_swap = 1; break;    case GE:  compare_code = LT;  branch_code = EQ; break;    case LTU: compare_code = LTU; branch_code = NE; break;    case LEU: compare_code = LTU; branch_code = EQ; must_swap = 1; break;    case GTU: compare_code = LTU; branch_code = NE; must_swap = 1; break;    case GEU: compare_code = LTU; branch_code = EQ; break;    default:      abort ();    }  if (need_compare)    {      switch (compare_code)	{	case EQ:	  if (GET_CODE (y) == CONST_INT	      && CMP_INT16_P (INTVAL (y))		/* reg equal to small const.  */	      && y != const0_rtx)	    {	      rtx tmp = gen_reg_rtx (SImode);			      	      emit_insn (gen_cmp_ne_small_const_insn (tmp, x, y));	      x = tmp;	      y = const0_rtx;	    }	  else if (CONSTANT_P (y))			/* reg equal to const.  */	    {	      rtx tmp = force_reg (GET_MODE (x), y);	      y = tmp;	    }	  if (register_operand (y, SImode) 		/* reg equal to reg.  */	      || y == const0_rtx) 	   		/* req equal to zero. */	    {	      emit_insn (gen_cmp_eqsi_insn (x, y));			      return gen_rtx (code, CCmode, cc_reg, const0_rtx);	    }	  break;      	case LT:	  if (register_operand (y, SImode)	      || (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))	    {	      rtx tmp = gen_reg_rtx (SImode);	      /* reg compared to reg. */	      	      switch (code)		{		case LT:		  emit_insn (gen_cmp_ltsi_insn (x, y));		  code = EQ;		  break;		case LE:		  if (y == const0_rtx)		    tmp = const1_rtx;		  else		    emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));		  emit_insn (gen_cmp_ltsi_insn (x, tmp));		  code = EQ;		  break;		case GT:		  if (GET_CODE (y) == CONST_INT)		    tmp = gen_rtx (PLUS, SImode, y, const1_rtx);		  else		    emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));		  emit_insn (gen_cmp_ltsi_insn (x, tmp));		  code = NE;		  break;		case GE:		  emit_insn (gen_cmp_ltsi_insn (x, y));		  code = NE;		  break;		default:		  abort ();		}	      	      return gen_rtx (code, CCmode, cc_reg, const0_rtx);	    }	  break;	  	case LTU:	  if (register_operand (y, SImode)	      || (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))	    {	      rtx tmp = gen_reg_rtx (SImode);	      /* reg (unsigned) compared to reg. */	      	      switch (code)		{		case LTU:		  emit_insn (gen_cmp_ltusi_insn (x, y));		  code = EQ;		  break;		case LEU:		  if (y == const0_rtx)		    tmp = const1_rtx;		  else		    emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));		  emit_insn (gen_cmp_ltusi_insn (x, tmp));		  code = EQ;		  break;		case GTU:		  if (GET_CODE (y) == CONST_INT)		    tmp = gen_rtx (PLUS, SImode, y, const1_rtx);		  else		    emit_insn (gen_cmp_ne_small_const_insn (tmp, y, const1_rtx));		  emit_insn (gen_cmp_ltusi_insn (x, tmp));		  code = NE;		  break;		case GEU:		  emit_insn (gen_cmp_ltusi_insn (x, y));		  code = NE;		  break;		default:		  abort();		}	      	      return gen_rtx (code, CCmode, cc_reg, const0_rtx);	    }	  break;	default:	  abort();	}    }  else    {      /* reg/reg equal comparison */      if (compare_code == EQ	  && register_operand (y, SImode))	return gen_rtx (code, CCmode, x, y);            /* reg/zero signed comparison */      if ((compare_code == EQ || compare_code == LT)	  && y == const0_rtx)	return gen_rtx (code, CCmode, x, y);            /* reg/smallconst equal comparison */      if (compare_code == EQ	  && GET_CODE (y) == CONST_INT	  && CMP_INT16_P (INTVAL (y)))	{	  rtx tmp = gen_reg_rtx (SImode);	  emit_insn (gen_cmp_ne_small_const_insn (tmp, x, y));	  return gen_rtx (code, CCmode, tmp, const0_rtx);	}            /* reg/const equal comparison */      if (compare_code == EQ	  && CONSTANT_P (y))	{	  rtx tmp = force_reg (GET_MODE (x), y);	  return gen_rtx (code, CCmode, x, tmp);	}    }  if (CONSTANT_P (y))    {      if (must_swap)	y = force_reg (GET_MODE (x), y);      else	{	  int ok_const =	    (code == LTU || code == LEU || code == GTU || code == GEU)	    ? uint16_operand (y, GET_MODE (y))	    : reg_or_cmp_int16_operand (y, GET_MODE (y));	  	  if (! ok_const)	    y = force_reg (GET_MODE (x), y);	}    }  switch (compare_code)    {    case EQ :      emit_insn (gen_cmp_eqsi_insn (must_swap ? y : x, must_swap ? x : y));      break;    case LT :      emit_insn (gen_cmp_ltsi_insn (must_swap ? y : x, must_swap ? x : y));      break;    case LTU :      emit_insn (gen_cmp_ltusi_insn (must_swap ? y : x, must_swap ? x : y));      break;    default:      abort ();    }  return gen_rtx (branch_code, VOIDmode, cc_reg, CONST0_RTX (CCmode));}/* Split a 2 word move (DI or DF) into component parts.  */rtxgen_split_move_double (operands)     rtx operands[];{  enum machine_mode mode = GET_MODE (operands[0]);  rtx dest = operands[0];  rtx src  = operands[1];  rtx val;  /* We might have (SUBREG (MEM)) here, so just get rid of the     subregs to make this code simpler.  It is safe to call     alter_subreg any time after reload.  */  if (GET_CODE (dest) == SUBREG)    alter_subreg (&dest);  if (GET_CODE (src) == SUBREG)    alter_subreg (&src);  start_sequence ();  if (GET_CODE (dest) == REG)    {      int dregno = REGNO (dest);      /* reg = reg */      if (GET_CODE (src) == REG)	{	  int sregno = REGNO (src);	  int reverse = (dregno == sregno + 1);	  /* We normally copy the low-numbered register first.  However, if	     the first register operand 0 is the same as the second register of	     operand 1, we must copy in the opposite order.  */	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, reverse, TRUE, mode),				  operand_subword (src,  reverse, TRUE, mode)));	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, !reverse, TRUE, mode),				  operand_subword (src,  !reverse, TRUE, mode)));	}      /* reg = constant */      else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)	{	  rtx words[2];	  split_double (src, &words[0], &words[1]);	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, 0, TRUE, mode),				  words[0]));	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, 1, TRUE, mode),				  words[1]));	}      /* reg = mem */      else if (GET_CODE (src) == MEM)	{	  /* If the high-address word is used in the address, we must load it	     last.  Otherwise, load it first.  */	  int reverse	    = (refers_to_regno_p (dregno, dregno + 1, XEXP (src, 0), 0) != 0);	  /* We used to optimize loads from single registers as		ld r1,r3+; ld r2,r3	     if r3 were not used subsequently.  However, the REG_NOTES aren't	     propigated correctly by the reload phase, and it can cause bad	     code to be generated.  We could still try:		ld r1,r3+; ld r2,r3; addi r3,-4	     which saves 2 bytes and doesn't force longword alignment.  */	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, reverse, TRUE, mode),				  adjust_address (src, SImode,						  reverse * UNITS_PER_WORD)));	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, !reverse, TRUE, mode),				  adjust_address (src, SImode,						  !reverse * UNITS_PER_WORD)));	}      else	abort ();    }  /* mem = reg */  /* We used to optimize loads from single registers as	st r1,r3; st r2,+r3     if r3 were not used subsequently.  However, the REG_NOTES aren't     propigated correctly by the reload phase, and it can cause bad     code to be generated.  We could still try:	st r1,r3; st r2,+r3; addi r3,-4     which saves 2 bytes and doesn't force longword alignment.  */  else if (GET_CODE (dest) == MEM && GET_CODE (src) == REG)    {      emit_insn (gen_rtx_SET (VOIDmode,			      adjust_address (dest, SImode, 0),			      operand_subword (src, 0, TRUE, mode)));      emit_insn (gen_rtx_SET (VOIDmode,			      adjust_address (dest, SImode, UNITS_PER_WORD),			      operand_subword (src, 1, TRUE, mode)));    }  else    abort ();  val = get_insns ();  end_sequence ();  return val;}/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.  */intfunction_arg_partial_nregs (cum, mode, type, named)     CUMULATIVE_ARGS *cum;     enum machine_mode mode;     tree type;     int named ATTRIBUTE_UNUSED;{  int ret;  unsigned int size =    (((mode == BLKmode && type)      ? (unsigned int) int_size_in_bytes (type)      : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)    / UNITS_PER_WORD;  if (*cum >= M32R_MAX_PARM_REGS)    ret = 0;  else if (*cum + size > M32R_MAX_PARM_REGS)    ret = (*cum + size) - M32R_MAX_PARM_REGS;  else    ret = 0;  return ret;}/* Do any needed setup for a variadic function.  For the M32R, we must   create a register parameter block, and then copy any anonymous arguments   in registers to memory.   CUM has not been updated for the last named argument which has type TYPE   and mode MODE, and we rely on this fact.  */

⌨️ 快捷键说明

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