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

📄 v850.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    case 'S':      {        /* if it's a reference to a TDA variable, use sst/sld vs. st/ld */        if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), FALSE))          fputs ("s", file);        break;      }    case 'T':      {	/* Like an 'S' operand above, but for unsigned loads only.  */        if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), TRUE))          fputs ("s", file);        break;      }    case 'W':			/* print the instruction suffix */      switch (GET_MODE (x))	{	default:	  abort ();	case QImode: fputs (".b", file); break;	case HImode: fputs (".h", file); break;	case SImode: fputs (".w", file); break;	case SFmode: fputs (".w", file); break;	}      break;    case '.':			/* register r0 */      fputs (reg_names[0], file);      break;    case 'z':			/* reg or zero */      if (x == const0_rtx)	fputs (reg_names[0], file);      else if (GET_CODE (x) == REG)	fputs (reg_names[REGNO (x)], file);      else	abort ();      break;    default:      switch (GET_CODE (x))	{	case MEM:	  if (GET_CODE (XEXP (x, 0)) == CONST_INT)	    output_address (gen_rtx_PLUS (SImode, gen_rtx (REG, SImode, 0),					  XEXP (x, 0)));	  else	    output_address (XEXP (x, 0));	  break;	case REG:	  fputs (reg_names[REGNO (x)], file);	  break;	case SUBREG:	  fputs (reg_names[subreg_regno (x)], file);	  break;	case CONST_INT:	case SYMBOL_REF:	case CONST:	case LABEL_REF:	case CODE_LABEL:	  print_operand_address (file, x);	  break;	default:	  abort ();	}      break;    }}/* Output assembly language output for the address ADDR to FILE.  */voidprint_operand_address (file, addr)     FILE *file;     rtx addr;{  switch (GET_CODE (addr))    {    case REG:      fprintf (file, "0[");      print_operand (file, addr, 0);      fprintf (file, "]");      break;    case LO_SUM:      if (GET_CODE (XEXP (addr, 0)) == REG)	{	  /* reg,foo */	  fprintf (file, "lo(");	  print_operand (file, XEXP (addr, 1), 0);	  fprintf (file, ")[");	  print_operand (file, XEXP (addr, 0), 0);	  fprintf (file, "]");	}      break;    case PLUS:      if (GET_CODE (XEXP (addr, 0)) == REG	  || GET_CODE (XEXP (addr, 0)) == SUBREG)	{	  /* reg,foo */	  print_operand (file, XEXP (addr, 1), 0);	  fprintf (file, "[");	  print_operand (file, XEXP (addr, 0), 0);	  fprintf (file, "]");	}      else	{	  print_operand (file, XEXP (addr, 0), 0);	  fprintf (file, "+");	  print_operand (file, XEXP (addr, 1), 0);	}      break;    case SYMBOL_REF:      if (ENCODED_NAME_P (XSTR (addr, 0)))        {          const char *name = XSTR (addr, 0);          const char *off_name;          const char *reg_name;          if (ZDA_NAME_P (name))            {              off_name = "zdaoff";              reg_name = "r0";            }          else if (SDA_NAME_P (name))            {              off_name = "sdaoff";              reg_name = "gp";            }          else if (TDA_NAME_P (name))            {              off_name = "tdaoff";              reg_name = "ep";            }          else            abort ();          fprintf (file, "%s(", off_name);          output_addr_const (file, addr);          fprintf (file, ")[%s]", reg_name);        }      else        output_addr_const (file, addr);      break;    case CONST:      if (special_symbolref_operand (addr, VOIDmode))        {          const char *name = XSTR (XEXP (XEXP (addr, 0), 0), 0);          const char *off_name;          const char *reg_name;          if (ZDA_NAME_P (name))            {              off_name = "zdaoff";              reg_name = "r0";            }          else if (SDA_NAME_P (name))            {              off_name = "sdaoff";              reg_name = "gp";            }          else if (TDA_NAME_P (name))            {              off_name = "tdaoff";              reg_name = "ep";            }          else            abort ();          fprintf (file, "%s(", off_name);          output_addr_const (file, addr);          fprintf (file, ")[%s]", reg_name);        }      else        output_addr_const (file, addr);      break;    default:      output_addr_const (file, addr);      break;    }}/* When assemble_integer is used to emit the offsets for a switch   table it can encounter (TRUNCATE:HI (MINUS:SI (LABEL_REF:SI) (LABEL_REF:SI))).   output_addr_const will normally barf at this, but it is OK to omit   the truncate and just emit the difference of the two labels.  The   .hword directive will automatically handle the truncation for us.      Returns 1 if rtx was handled, 0 otherwise.  */intv850_output_addr_const_extra (file, x)     FILE * file;     rtx x;{  if (GET_CODE (x) != TRUNCATE)    return 0;  x = XEXP (x, 0);  /* We must also handle the case where the switch table was passed a     constant value and so has been collapsed.  In this case the first     label will have been deleted.  In such a case it is OK to emit     nothing, since the table will not be used.     (cf gcc.c-torture/compile/990801-1.c).  */  if (GET_CODE (x) == MINUS      && GET_CODE (XEXP (x, 0)) == LABEL_REF      && GET_CODE (XEXP (XEXP (x, 0), 0)) == CODE_LABEL      && INSN_DELETED_P (XEXP (XEXP (x, 0), 0)))    return 1;  output_addr_const (file, x);  return 1;}/* Return appropriate code to load up a 1, 2, or 4 integer/floating   point value.  */const char *output_move_single (operands)     rtx *operands;{  rtx dst = operands[0];  rtx src = operands[1];  if (REG_P (dst))    {      if (REG_P (src))	return "mov %1,%0";      else if (GET_CODE (src) == CONST_INT)	{	  HOST_WIDE_INT value = INTVAL (src);	  if (CONST_OK_FOR_J (value))		/* Signed 5 bit immediate.  */	    return "mov %1,%0";	  else if (CONST_OK_FOR_K (value))	/* Signed 16 bit immediate.  */	    return "movea lo(%1),%.,%0";	  else if (CONST_OK_FOR_L (value))	/* Upper 16 bits were set.  */	    return "movhi hi(%1),%.,%0";	  /* A random constant.  */	  else if (TARGET_V850E)	      return "mov %1,%0";	  else	    return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";	}      else if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode)	{	  HOST_WIDE_INT high, low;	  const_double_split (src, &high, &low);	  if (CONST_OK_FOR_J (high))		/* Signed 5 bit immediate.  */	    return "mov %F1,%0";	  else if (CONST_OK_FOR_K (high))	/* Signed 16 bit immediate.  */	    return "movea lo(%F1),%.,%0";	  else if (CONST_OK_FOR_L (high))	/* Upper 16 bits were set.  */	    return "movhi hi(%F1),%.,%0";	  /* A random constant.  */	  else if (TARGET_V850E)	      return "mov %F1,%0";	  else	    return "movhi hi(%F1),%.,%0\n\tmovea lo(%F1),%0,%0";	}      else if (GET_CODE (src) == MEM)	return "%S1ld%W1 %1,%0";      else if (special_symbolref_operand (src, VOIDmode))	return "movea %O1(%P1),%Q1,%0";      else if (GET_CODE (src) == LABEL_REF	       || GET_CODE (src) == SYMBOL_REF	       || GET_CODE (src) == CONST)	{	  if (TARGET_V850E)	    return "mov hilo(%1),%0";	  else	    return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";	}      else if (GET_CODE (src) == HIGH)	return "movhi hi(%1),%.,%0";      else if (GET_CODE (src) == LO_SUM)	{	  operands[2] = XEXP (src, 0);	  operands[3] = XEXP (src, 1);	  return "movea lo(%3),%2,%0";	}    }  else if (GET_CODE (dst) == MEM)    {      if (REG_P (src))	return "%S0st%W0 %1,%0";      else if (GET_CODE (src) == CONST_INT && INTVAL (src) == 0)	return "%S0st%W0 %.,%0";      else if (GET_CODE (src) == CONST_DOUBLE	       && CONST0_RTX (GET_MODE (dst)) == src)	return "%S0st%W0 %.,%0";    }  fatal_insn ("output_move_single:", gen_rtx_SET (VOIDmode, dst, src));  return "";}/* Return appropriate code to load up an 8 byte integer or   floating point value */const char *output_move_double (operands)    rtx *operands;{  enum machine_mode mode = GET_MODE (operands[0]);  rtx dst = operands[0];  rtx src = operands[1];  if (register_operand (dst, mode)      && register_operand (src, mode))    {      if (REGNO (src) + 1 == REGNO (dst))	return "mov %R1,%R0\n\tmov %1,%0";      else	return "mov %1,%0\n\tmov %R1,%R0";    }  /* Storing 0 */  if (GET_CODE (dst) == MEM      && ((GET_CODE (src) == CONST_INT && INTVAL (src) == 0)	  || (GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src))))    return "st.w %.,%0\n\tst.w %.,%R0";  if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)    {      HOST_WIDE_INT high_low[2];      int i;      rtx xop[10];      if (GET_CODE (src) == CONST_DOUBLE)	const_double_split (src, &high_low[1], &high_low[0]);      else	{	  high_low[0] = INTVAL (src);	  high_low[1] = (INTVAL (src) >= 0) ? 0 : -1;	}      for (i = 0; i < 2; i++)	{	  xop[0] = gen_rtx_REG (SImode, REGNO (dst)+i);	  xop[1] = GEN_INT (high_low[i]);	  output_asm_insn (output_move_single (xop), xop);	}      return "";    }  if (GET_CODE (src) == MEM)    {      int ptrreg = -1;      int dreg = REGNO (dst);      rtx inside = XEXP (src, 0);      if (GET_CODE (inside) == REG) 	ptrreg = REGNO (inside);      else if (GET_CODE (inside) == SUBREG)	ptrreg = subreg_regno (inside);      else if (GET_CODE (inside) == PLUS)	ptrreg = REGNO (XEXP (inside, 0));      else if (GET_CODE (inside) == LO_SUM)	ptrreg = REGNO (XEXP (inside, 0));      if (dreg == ptrreg)	return "ld.w %R1,%R0\n\tld.w %1,%0";    }  if (GET_CODE (src) == MEM)    return "ld.w %1,%0\n\tld.w %R1,%R0";    if (GET_CODE (dst) == MEM)    return "st.w %1,%0\n\tst.w %R1,%R0";  return "mov %1,%0\n\tmov %R1,%R0";}/* Return maximum offset supported for a short EP memory reference of mode   MODE and signedness UNSIGNEDP.  */static intep_memory_offset (mode, unsignedp)     enum machine_mode mode;     int ATTRIBUTE_UNUSED unsignedp;{  int max_offset = 0;  switch (mode)    {    case QImode:      if (TARGET_SMALL_SLD)	max_offset = (1 << 4);      else if (TARGET_V850E 	       && (   (  unsignedp && ! TARGET_US_BIT_SET)		   || (! unsignedp &&   TARGET_US_BIT_SET)))	max_offset = (1 << 4);      else	max_offset = (1 << 7);      break;    case HImode:      if (TARGET_SMALL_SLD)	max_offset = (1 << 5);      else if (TARGET_V850E	       && (   (  unsignedp && ! TARGET_US_BIT_SET)		   || (! unsignedp &&   TARGET_US_BIT_SET)))	max_offset = (1 << 5);      else	max_offset = (1 << 8);      break;    case SImode:    case SFmode:      max_offset = (1 << 8);      break;          default:      break;    }  return max_offset;}/* Return true if OP is a valid short EP memory reference */intep_memory_operand (op, mode, unsigned_load)     rtx op;     enum machine_mode mode;     int unsigned_load;{  rtx addr, op0, op1;  int max_offset;  int mask;  if (GET_CODE (op) != MEM)    return FALSE;  max_offset = ep_memory_offset (mode, unsigned_load);  mask = GET_MODE_SIZE (mode) - 1;  addr = XEXP (op, 0);  if (GET_CODE (addr) == CONST)    addr = XEXP (addr, 0);  switch (GET_CODE (addr))    {    default:      break;    case SYMBOL_REF:      return TDA_NAME_P (XSTR (addr, 0));    case REG:      return REGNO (addr) == EP_REGNUM;    case PLUS:      op0 = XEXP (addr, 0);      op1 = XEXP (addr, 1);      if (GET_CODE (op1) == CONST_INT	  && INTVAL (op1) < max_offset	  && INTVAL (op1) >= 0	  && (INTVAL (op1) & mask) == 0)	{	  if (GET_CODE (op0) == REG && REGNO (op0) == EP_REGNUM)	    return TRUE;	  if (GET_CODE (op0) == SYMBOL_REF && TDA_NAME_P (XSTR (op0, 0)))	    return TRUE;	}      break;    }  return FALSE;}/* Return true if OP is either a register or 0 */intreg_or_0_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) == CONST_INT)    return INTVAL (op) == 0;  else if (GET_CODE (op) == CONST_DOUBLE)    return CONST_DOUBLE_OK_FOR_G (op);  else    return register_operand (op, mode);}/* Return true if OP is either a register or a signed five bit integer */intreg_or_int5_operand (op, mode)     rtx op;

⌨️ 快捷键说明

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