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

📄 m88k.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	      || (REG_P (addr) && REGNO (addr) == 1))	    {	      operands[1] = dest;	      return (REG_P (addr)		      ? "jsr %0\n\tbr %l1"		      : (flag_pic			 ? "bsr %0#plt\n\tbr %l1"			 : "bsr %0\n\tbr %l1"));	    }	  /* Output the short branch form.  */	  output_asm_insn ((REG_P (addr)			    ? "jsr.n %0"			    : (flag_pic ? "bsr.n %0#plt" : "bsr.n %0")),			   operands);#ifdef USE_GAS	  last = (delta < 0		  ? "subu %#r1,%#r1,.-%l0+4"		  : "addu %#r1,%#r1,%l0-.-4");	  operands[0] = dest;#else	  operands[0] = gen_label_rtx ();	  operands[1] = gen_label_rtx ();	  if (delta < 0)	    {	      low = dest;	      high = operands[1];	      last = "subu %#r1,%#r1,%l0\n%l1:";	    }	  else	    {	      low = operands[1];	      high = dest;	      last = "addu %#r1,%#r1,%l0\n%l1:";	    }	  /* Record the values to be computed later as "def name,high-low".  */	  sb_name = gen_rtx_EXPR_LIST (VOIDmode, operands[0], sb_name);	  sb_high = gen_rtx_EXPR_LIST (VOIDmode, high, sb_high);	  sb_low = gen_rtx_EXPR_LIST (VOIDmode, low, sb_low);#endif /* Don't USE_GAS */	  return last;	}    }  return (REG_P (addr)	  ? "jsr%. %0"	  : (flag_pic ? "bsr%. %0#plt" : "bsr%. %0"));}static voidoutput_short_branch_defs (stream)     FILE *stream;{  char name[256], high[256], low[256];  for (; sb_name && sb_high && sb_low;       sb_name = XEXP (sb_name, 1),       sb_high = XEXP (sb_high, 1),       sb_low = XEXP (sb_low, 1))    {      ASM_GENERATE_INTERNAL_LABEL	(name, "L", CODE_LABEL_NUMBER (XEXP (sb_name, 0)));      ASM_GENERATE_INTERNAL_LABEL	(high, "L", CODE_LABEL_NUMBER (XEXP (sb_high, 0)));      ASM_GENERATE_INTERNAL_LABEL	(low, "L", CODE_LABEL_NUMBER (XEXP (sb_low, 0)));      /* This will change as the assembler requirements become known.  */      fprintf (stream, "%s%s,%s-%s\n",	       SET_ASM_OP, &name[1], &high[1], &low[1]);    }  if (sb_name || sb_high || sb_low)    abort ();}/* Return truth value of the statement that this conditional branch is likely   to fall through.  CONDITION, is the condition that JUMP_INSN is testing.  */intmostly_false_jump (jump_insn, condition)     rtx jump_insn, condition;{  rtx target_label = JUMP_LABEL (jump_insn);  rtx insnt, insnj;  /* Much of this isn't computed unless we're optimizing.  */  if (optimize == 0)    return 0;  /* Determine if one path or the other leads to a return.  */  for (insnt = NEXT_INSN (target_label);       insnt;       insnt = NEXT_INSN (insnt))    {      if (GET_CODE (insnt) == JUMP_INSN)	break;      else if (GET_CODE (insnt) == INSN	       && GET_CODE (PATTERN (insnt)) == SEQUENCE	       && GET_CODE (XVECEXP (PATTERN (insnt), 0, 0)) == JUMP_INSN)	{	  insnt = XVECEXP (PATTERN (insnt), 0, 0);	  break;	}    }  if (insnt      && (GET_CODE (PATTERN (insnt)) == RETURN	  || (GET_CODE (PATTERN (insnt)) == SET	      && GET_CODE (SET_SRC (PATTERN (insnt))) == REG	      && REGNO (SET_SRC (PATTERN (insnt))) == 1)))    insnt = 0;  for (insnj = NEXT_INSN (jump_insn);       insnj;       insnj = NEXT_INSN (insnj))    {      if (GET_CODE (insnj) == JUMP_INSN)	break;      else if (GET_CODE (insnj) == INSN	       && GET_CODE (PATTERN (insnj)) == SEQUENCE	       && GET_CODE (XVECEXP (PATTERN (insnj), 0, 0)) == JUMP_INSN)	{	  insnj = XVECEXP (PATTERN (insnj), 0, 0);	  break;	}    }  if (insnj      && (GET_CODE (PATTERN (insnj)) == RETURN	  || (GET_CODE (PATTERN (insnj)) == SET	      && GET_CODE (SET_SRC (PATTERN (insnj))) == REG	      && REGNO (SET_SRC (PATTERN (insnj))) == 1)))    insnj = 0;  /* Predict to not return.  */  if ((insnt == 0) != (insnj == 0))    return (insnt == 0);  /* Predict loops to loop.  */  for (insnt = PREV_INSN (target_label);       insnt && GET_CODE (insnt) == NOTE;       insnt = PREV_INSN (insnt))    if (NOTE_LINE_NUMBER (insnt) == NOTE_INSN_LOOP_END)      return 1;    else if (NOTE_LINE_NUMBER (insnt) == NOTE_INSN_LOOP_BEG)      return 0;    else if (NOTE_LINE_NUMBER (insnt) == NOTE_INSN_LOOP_CONT)      return 0;  /* Predict backward branches usually take.  */  if (final_sequence)    insnj = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));  else    insnj = jump_insn;  if (INSN_ADDRESSES (INSN_UID (insnj))      > INSN_ADDRESSES (INSN_UID (target_label)))    return 0;  /* EQ tests are usually false and NE tests are usually true.  Also,     most quantities are positive, so we can make the appropriate guesses     about signed comparisons against zero.  Consider unsigned comparisons     to be a range check and assume quantities to be in range.  */  switch (GET_CODE (condition))    {    case CONST_INT:      /* Unconditional branch.  */      return 0;    case EQ:      return 1;    case NE:      return 0;    case LE:    case LT:    case GEU:    case GTU: /* Must get casesi right at least.  */      if (XEXP (condition, 1) == const0_rtx)        return 1;      break;    case GE:    case GT:    case LEU:    case LTU:      if (XEXP (condition, 1) == const0_rtx)	return 0;      break;    default:      break;    }  return 0;}/* Return true if the operand is a power of two and is a floating   point type (to optimize division by power of two into multiplication).  */intreal_power_of_2_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  REAL_VALUE_TYPE d;  union {    long l[2];    struct {				/* IEEE double precision format */      unsigned sign	 :  1;      unsigned exponent  : 11;      unsigned mantissa1 : 20;      unsigned mantissa2;    } s;    struct {				/* IEEE double format to quick check */      unsigned sign	 :  1;		/* if it fits in a float */      unsigned exponent1 :  4;      unsigned exponent2 :  7;      unsigned mantissa1 : 20;      unsigned mantissa2;    } s2;  } u;  if (GET_MODE (op) != DFmode && GET_MODE (op) != SFmode)    return 0;  if (GET_CODE (op) != CONST_DOUBLE)    return 0;  REAL_VALUE_FROM_CONST_DOUBLE (d, op);  REAL_VALUE_TO_TARGET_DOUBLE (d, u.l);  if (u.s.mantissa1 != 0 || u.s.mantissa2 != 0	/* not a power of two */      || u.s.exponent == 0			/* constant 0.0 */      || u.s.exponent == 0x7ff			/* NAN */      || (u.s2.exponent1 != 0x8 && u.s2.exponent1 != 0x7))    return 0;					/* const won't fit in float */  return 1;}/* Make OP legitimate for mode MODE.  Currently this only deals with DFmode   operands, putting them in registers and making CONST_DOUBLE values   SFmode where possible.  */struct rtx_def *legitimize_operand (op, mode)     rtx op;     enum machine_mode mode;{  rtx temp;  REAL_VALUE_TYPE r;  union {    long l[2];    struct {				/* IEEE double precision format */      unsigned sign	 :  1;      unsigned exponent  : 11;      unsigned mantissa1 : 20;      unsigned mantissa2;    } d;    struct {				/* IEEE double format to quick check */      unsigned sign	 :  1;		/* if it fits in a float */      unsigned exponent1 :  4;      unsigned exponent2 :  7;      unsigned mantissa1 : 20;      unsigned mantissa2;    } s;  } u;  if (GET_CODE (op) == REG || mode != DFmode)    return op;  if (GET_CODE (op) == CONST_DOUBLE)    {      REAL_VALUE_FROM_CONST_DOUBLE (r, op);      REAL_VALUE_TO_TARGET_DOUBLE (r, u.l);      if (u.d.exponent != 0x7ff /* NaN */	  && u.d.mantissa2 == 0 /* Mantissa fits */	  && (u.s.exponent1 == 0x8 || u.s.exponent1 == 0x7) /* Exponent fits */	  && (temp = simplify_unary_operation (FLOAT_TRUNCATE, SFmode,					       op, mode)) != 0)	return gen_rtx_FLOAT_EXTEND (mode, force_reg (SFmode, temp));    }  else if (register_operand (op, mode))    return op;  return force_reg (mode, op);}/* Return true if OP is a suitable input for a move insn.  */intmove_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT)    return (classify_integer (mode, INTVAL (op)) < m88k_oru_hi16);  if (GET_MODE (op) != mode)    return 0;  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (GET_CODE (op) != MEM)    return 0;  op = XEXP (op, 0);  if (GET_CODE (op) == LO_SUM)    return (REG_P (XEXP (op, 0))	    && symbolic_address_p (XEXP (op, 1)));  return memory_address_p (mode, op);}/* Return true if OP is suitable for a call insn.  */intcall_address_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return (REG_P (op) || symbolic_address_p (op));}/* Returns true if OP is either a symbol reference or a sum of a symbol   reference and a constant.  */intsymbolic_address_p (op)     register rtx op;{  switch (GET_CODE (op))    {    case SYMBOL_REF:    case LABEL_REF:      return 1;    case CONST:      op = XEXP (op, 0);      return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF	       || GET_CODE (XEXP (op, 0)) == LABEL_REF)	      && GET_CODE (XEXP (op, 1)) == CONST_INT);    default:      return 0;    }}/* Return true if OP is a register or const0_rtx.  */intreg_or_0_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (op == const0_rtx || register_operand (op, mode));}/* Nonzero if OP is a valid second operand for an arithmetic insn.  */intarith_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));}/* Return true if OP is a  register or 5 bit integer.  */intarith5_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 32));}intarith32_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);}intarith64_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || GET_CODE (op) == CONST_INT	  || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode));}intint5_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return (GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 32);}intint32_operand (op, mode)     rtx op;     enum machine_mode mode ATTRIBUTE_UNUSED;{  return (GET_CODE (op) == CONST_INT);}/* Return true if OP is a register or a valid immediate operand for   addu or subu.  */intadd_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_INT && ADD_INT (op)));}/* Nonzero if this is a bitmask filling the bottom bits, for optimizing and +   shift left combinations into a single mak instruction.  */intmak_mask_p (value)     int value;{  return (value && POWER_OF_2_or_0 (value + 1));}intreg_or_bbx_mask_operand (op, mode)     rtx op;     enum machine_mode mode;{  int value;  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) != CONST_INT)    return 0;  value = INTVAL (op);  if (POWER_OF_2 (value))    return 1;  return 0;}/* Return true if OP is valid to use in the context of a floating   point operation.  Special case 0.0, since we can use r0.  */intreal_or_0_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (mode != SFmode && mode != DFmode)    return 0;  return (register_operand (op, mode)	  || (GET_CODE (op) == CONST_DOUBLE	      && op == CONST0_RTX (mode)));}/* Return true if OP is valid to use in the context of logic arithmetic

⌨️ 快捷键说明

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