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

📄 mcore.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
  else if ((load_value & (load_value + 1)) == 0)    output_asm_insn ("bmaski\t%0,%N1", out_operands);     /* Output the constant adjustment.  */  if (load_value > adjust_value)    {      if (cmp_t)	output_asm_insn ("decf\t%0", out_operands);      else	output_asm_insn ("dect\t%0", out_operands);    }  else    {      if (cmp_t)	output_asm_insn ("incf\t%0", out_operands);      else	output_asm_insn ("inct\t%0", out_operands);    }  return "";}/* Outputs the peephole for moving a constant that gets not'ed followed    by an and (i.e. combine the not and the and into andn). BRC  */const char *mcore_output_andn (insn, operands)     rtx insn ATTRIBUTE_UNUSED;     rtx operands[];{  int x, y;  rtx out_operands[3];  const char * load_op;  char buf[256];  if (try_constant_tricks (INTVAL (operands[1]), &x, &y) != 2)    abort ();  out_operands[0] = operands[0];  out_operands[1] = GEN_INT(x);  out_operands[2] = operands[2];  if (x >= 0 && x <= 127)    load_op = "movi\t%0,%1";    /* Try exact power of two.  */  else if ((x & (x - 1)) == 0)    load_op = "bgeni\t%0,%P1";    /* Try exact power of two - 1.  */  else if ((x & (x + 1)) == 0)    load_op = "bmaski\t%0,%N1";    else     load_op = "BADMOVI\t%0,%1";  sprintf (buf, "%s\n\tandn\t%%2,%%0", load_op);  output_asm_insn (buf, out_operands);  return "";}/* Output an inline constant.  */static const char *output_inline_const (mode, operands)     enum machine_mode mode;     rtx operands[];{  int x = 0, y = 0;  int trick_no;  rtx out_operands[3];  char buf[256];  char load_op[256];  const char *dst_fmt;  int value;  value = INTVAL (operands[1]);     if ((trick_no = try_constant_tricks (value, &x, &y)) == 0)    {      /* lrw's are handled separately:  Large inlinable constants	 never get turned into lrw's.  Our caller uses try_constant_tricks         to back off to an lrw rather than calling this routine.  */      abort ();    }  if (trick_no == 1)    x = value;  /* operands: 0 = dst, 1 = load immed., 2 = immed. adjustment.  */  out_operands[0] = operands[0];  out_operands[1] = GEN_INT (x);    if (trick_no > 2)    out_operands[2] = GEN_INT (y);  /* Select dst format based on mode.  */  if (mode == DImode && (! TARGET_LITTLE_END))    dst_fmt = "%R0";  else    dst_fmt = "%0";  if (x >= 0 && x <= 127)    sprintf (load_op, "movi\t%s,%%1", dst_fmt);    /* Try exact power of two.  */  else if ((x & (x - 1)) == 0)    sprintf (load_op, "bgeni\t%s,%%P1", dst_fmt);    /* Try exact power of two - 1.  */  else if ((x & (x + 1)) == 0)    sprintf (load_op, "bmaski\t%s,%%N1", dst_fmt);    else     sprintf (load_op, "BADMOVI\t%s,%%1", dst_fmt);  switch (trick_no)    {    case 1:      strcpy (buf, load_op);      break;    case 2:   /* not */      sprintf (buf, "%s\n\tnot\t%s\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 3:   /* add */      sprintf (buf, "%s\n\taddi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 4:   /* sub */      sprintf (buf, "%s\n\tsubi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 5:   /* rsub */      /* Never happens unless -mrsubi, see try_constant_tricks().  */      sprintf (buf, "%s\n\trsubi\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 6:   /* bset */      sprintf (buf, "%s\n\tbseti\t%s,%%P2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 7:   /* bclr */      sprintf (buf, "%s\n\tbclri\t%s,%%Q2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 8:   /* rotl */      sprintf (buf, "%s\n\trotli\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 9:   /* lsl */      sprintf (buf, "%s\n\tlsli\t%s,%%2\t// %d 0x%x", load_op, dst_fmt, value, value);      break;    case 10:  /* ixh */      sprintf (buf, "%s\n\tixh\t%s,%s\t// %d 0x%x", load_op, dst_fmt, dst_fmt, value, value);      break;    case 11:  /* ixw */      sprintf (buf, "%s\n\tixw\t%s,%s\t// %d 0x%x", load_op, dst_fmt, dst_fmt, value, value);      break;    default:      return "";    }    output_asm_insn (buf, out_operands);  return "";}/* Output a move of a word or less value.  */const char *mcore_output_move (insn, operands, mode)     rtx insn ATTRIBUTE_UNUSED;     rtx operands[];     enum machine_mode mode ATTRIBUTE_UNUSED;{  rtx dst = operands[0];  rtx src = operands[1];  if (GET_CODE (dst) == REG)    {      if (GET_CODE (src) == REG)	{               	  if (REGNO (src) == CC_REG)            /* r-c */            return "mvc\t%0"; 	  else             return "mov\t%0,%1";                /* r-r*/	}      else if (GET_CODE (src) == MEM)	{	  if (GET_CODE (XEXP (src, 0)) == LABEL_REF)             return "lrw\t%0,[%1]";              /* a-R */	  else	    switch (GET_MODE (src))		/* r-m */	      {	      case SImode:		return "ldw\t%0,%1";	      case HImode:		return "ld.h\t%0,%1";	      case QImode:		return "ld.b\t%0,%1";	      default:		abort ();	      }	}      else if (GET_CODE (src) == CONST_INT)	{	  int x, y;	  	  if (CONST_OK_FOR_I (INTVAL (src)))       /* r-I */            return "movi\t%0,%1";	  else if (CONST_OK_FOR_M (INTVAL (src)))  /* r-M */            return "bgeni\t%0,%P1\t// %1 %x1";	  else if (CONST_OK_FOR_N (INTVAL (src)))  /* r-N */            return "bmaski\t%0,%N1\t// %1 %x1";	  else if (try_constant_tricks (INTVAL (src), &x, &y))     /* R-P */            return output_inline_const (SImode, operands);  /* 1-2 insns */	  else             return "lrw\t%0,%x1\t// %1";	/* Get it from literal pool.  */	}      else	return "lrw\t%0, %1";                /* Into the literal pool.  */    }  else if (GET_CODE (dst) == MEM)               /* m-r */    switch (GET_MODE (dst))      {      case SImode:	return "stw\t%1,%0";      case HImode:	return "st.h\t%1,%0";      case QImode:	return "st.b\t%1,%0";      default:	abort ();      }  abort ();}/* Return a sequence of instructions to perform DI or DF move.   Since the MCORE cannot move a DI or DF in one instruction, we have   to take care when we see overlapping source and dest registers.  */const char *mcore_output_movedouble (operands, mode)     rtx operands[];     enum machine_mode mode ATTRIBUTE_UNUSED;{  rtx dst = operands[0];  rtx src = operands[1];  if (GET_CODE (dst) == REG)    {      if (GET_CODE (src) == REG)	{	  int dstreg = REGNO (dst);	  int srcreg = REGNO (src);	  	  /* Ensure the second source not overwritten.  */	  if (srcreg + 1 == dstreg)	    return "mov	%R0,%R1\n\tmov	%0,%1";	  else	    return "mov	%0,%1\n\tmov	%R0,%R1";	}      else if (GET_CODE (src) == MEM)	{	  rtx memexp = memexp = XEXP (src, 0);	  int dstreg = REGNO (dst);	  int basereg = -1;	  	  if (GET_CODE (memexp) == LABEL_REF)	    return "lrw\t%0,[%1]\n\tlrw\t%R0,[%R1]";	  else if (GET_CODE (memexp) == REG) 	    basereg = REGNO (memexp);	  else if (GET_CODE (memexp) == PLUS)	    {	      if (GET_CODE (XEXP (memexp, 0)) == REG)		basereg = REGNO (XEXP (memexp, 0));	      else if (GET_CODE (XEXP (memexp, 1)) == REG)		basereg = REGNO (XEXP (memexp, 1));	      else		abort ();	    }	  else	    abort ();          /* ??? length attribute is wrong here.  */	  if (dstreg == basereg)	    {	      /* Just load them in reverse order.  */	      return "ldw\t%R0,%R1\n\tldw\t%0,%1";	      	      /* XXX: alternative: move basereg to basereg+1	         and then fall through.  */	    }	  else	    return "ldw\t%0,%1\n\tldw\t%R0,%R1";	}      else if (GET_CODE (src) == CONST_INT)	{	  if (TARGET_LITTLE_END)	    {	      if (CONST_OK_FOR_I (INTVAL (src)))		output_asm_insn ("movi	%0,%1", operands);	      else if (CONST_OK_FOR_M (INTVAL (src)))		output_asm_insn ("bgeni	%0,%P1", operands);	      else if (INTVAL (src) == -1)		output_asm_insn ("bmaski	%0,32", operands);	      else if (CONST_OK_FOR_N (INTVAL (src)))		output_asm_insn ("bmaski	%0,%N1", operands);	      else		abort ();	      if (INTVAL (src) < 0)		return "bmaski	%R0,32";	      else		return "movi	%R0,0";	    }	  else	    {	      if (CONST_OK_FOR_I (INTVAL (src)))		output_asm_insn ("movi	%R0,%1", operands);	      else if (CONST_OK_FOR_M (INTVAL (src)))		output_asm_insn ("bgeni	%R0,%P1", operands);	      else if (INTVAL (src) == -1)		output_asm_insn ("bmaski	%R0,32", operands);	      else if (CONST_OK_FOR_N (INTVAL (src)))		output_asm_insn ("bmaski	%R0,%N1", operands);	      else		abort ();	      	      if (INTVAL (src) < 0)		return "bmaski	%0,32";	      else		return "movi	%0,0";	    }	}      else	abort ();    }  else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)    return "stw\t%1,%0\n\tstw\t%R1,%R0";  else    abort ();}/* Predicates used by the templates.  *//* Nonzero if OP can be source of a simple move operation.  */intmcore_general_movsrc_operand (op, mode)     rtx op;     enum machine_mode mode;{  /* Any (MEM LABEL_REF) is OK.  That is a pc-relative load.  */  if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == LABEL_REF)    return 1;  return general_operand (op, mode);}/* Nonzero if OP can be destination of a simple move operation. */intmcore_general_movdst_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) == REG && REGNO (op) == CC_REG)    return 0;    return general_operand (op, mode);}/* Nonzero if OP is a normal arithmetic register.  */intmcore_arith_reg_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (! register_operand (op, mode))    return 0;  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (GET_CODE (op) == REG)    return REGNO (op) != CC_REG;  return 1;}/* Nonzero if OP should be recognized during reload for an ixh/ixw   operand.  See the ixh/ixw patterns.  */intmcore_reload_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (mcore_arith_reg_operand (op, mode))    return 1;  if (! reload_in_progress)    return 0;  return GET_CODE (op) == MEM;}/* Nonzero if OP is a valid source operand for an arithmetic insn.  */intmcore_arith_J_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))    return 1;    return 0;}/* Nonzero if OP is a valid source operand for an arithmetic insn.  */intmcore_arith_K_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))    return 1;  return 0;}/* Nonzero if OP is a valid source operand for a shift or rotate insn.  */intmcore_arith_K_operand_not_0 (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (   GET_CODE (op) == CONST_INT      && CONST_OK_FOR_K (INTVAL (op))      && INTVAL (op) != 0)    return 1;  return 0;}intmcore_arith_K_S_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT)    {      if (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_M (~INTVAL (op)))	return 1;    }    return 0;}intmcore_arith_S_operand (op)     rtx op;{  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (~INTVAL (op)))    return 1;    return 0;}intmcore_arith_M_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))    return 1;  return 0;}/* Nonzero if OP is a valid source operand for loading.  */intmcore_arith_imm_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (register_operand (op, mode))    return 1;  if (GET_CODE (op) == CONST_INT && const_ok_for_mcore (INTVAL (op)))    return 1;  return 0;}intmcore_arith_any_imm_operand (op, mode)

⌨️ 快捷键说明

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