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

📄 i960.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
      sprintf (lbuf, "b	LR%d", ret_label);      return lbuf;    }  /* Must clear g14 on return if this function set it.     Only varargs/stdarg functions modify g14.  */  if (VARARGS_STDARG_FUNCTION (current_function_decl))    output_asm_insn ("mov	0,g14", 0);  if (i960_leaf_ret_reg >= 0)    {      sprintf (lbuf, "bx	(%s)", reg_names[i960_leaf_ret_reg]);      return lbuf;    }  return "ret";}#if 0/* Return a character string representing the branch prediction   opcode to be tacked on an instruction.  This must at least   return a null string.  */char *i960_br_predict_opcode (lab_ref, insn)     rtx lab_ref, insn;{  if (TARGET_BRANCH_PREDICT)    {      unsigned long label_uid;            if (GET_CODE (lab_ref) == CODE_LABEL)	label_uid = INSN_UID (lab_ref);      else if (GET_CODE (lab_ref) == LABEL_REF)	label_uid = INSN_UID (XEXP (lab_ref, 0));      else	return ".f";      /* If not optimizing, then the insn_addresses array will not be	 valid.  In this case, always return ".t" since most branches	 are taken.  If optimizing, return .t for backward branches	 and .f for forward branches.  */      if (! optimize	  || insn_addresses[label_uid] < insn_addresses[INSN_UID (insn)])	return ".t";      return ".f";    }      return "";}#endif/* Print the operand represented by rtx X formatted by code CODE.  */voidi960_print_operand (file, x, code)     FILE *file;     rtx x;     char code;{  enum rtx_code rtxcode = GET_CODE (x);  if (rtxcode == REG)    {      switch (code)	{	case 'D':	  /* Second reg of a double or quad.  */	  fprintf (file, "%s", reg_names[REGNO (x)+1]);	  break;	case 'E':	  /* Third reg of a quad.  */	  fprintf (file, "%s", reg_names[REGNO (x)+2]);	  break;	case 'F':	  /* Fourth reg of a quad.  */	  fprintf (file, "%s", reg_names[REGNO (x)+3]);	  break;	case 0:	  fprintf (file, "%s", reg_names[REGNO (x)]);	  break;	default:	  abort ();	}      return;    }  else if (rtxcode == MEM)    {      output_address (XEXP (x, 0));      return;    }  else if (rtxcode == CONST_INT)    {      if (INTVAL (x) > 9999 || INTVAL (x) < -999)	fprintf (file, "0x%x", INTVAL (x));      else	fprintf (file, "%d", INTVAL (x));      return;    }  else if (rtxcode == CONST_DOUBLE)    {      REAL_VALUE_TYPE d;      char dstr[30];      if (x == CONST0_RTX (GET_MODE (x)))	{	  fprintf (file, "0f0.0");	  return;	}      else if (x == CONST1_RTX (GET_MODE (x)))	{	  fprintf (file, "0f1.0");	  return;	}      REAL_VALUE_FROM_CONST_DOUBLE (d, x);      REAL_VALUE_TO_DECIMAL (d, "%#g", dstr);      fprintf (file, "0f%s", dstr);      return;    }  switch(code)    {    case 'B':      /* Branch or jump, depending on assembler.  */      if (TARGET_ASM_COMPAT)	fputs ("j", file);      else	fputs ("b", file);      break;    case 'S':      /* Sign of condition.  */      if ((rtxcode == EQ) || (rtxcode == NE) || (rtxcode == GTU)	  || (rtxcode == LTU) || (rtxcode == GEU) || (rtxcode == LEU))	fputs ("o", file);      else if ((rtxcode == GT) || (rtxcode == LT)	  || (rtxcode == GE) || (rtxcode == LE))	fputs ("i", file);      else	abort();      break;    case 'I':      /* Inverted condition.  */      rtxcode = reverse_condition (rtxcode);      goto normal;    case 'X':      /* Inverted condition w/ reversed operands.  */      rtxcode = reverse_condition (rtxcode);      /* Fallthrough.  */    case 'R':      /* Reversed operand condition.  */      rtxcode = swap_condition (rtxcode);      /* Fallthrough.  */    case 'C':      /* Normal condition.  */    normal:      if (rtxcode == EQ)  { fputs ("e", file); return; }      else if (rtxcode == NE)  { fputs ("ne", file); return; }      else if (rtxcode == GT)  { fputs ("g", file); return; }      else if (rtxcode == GTU) { fputs ("g", file); return; }      else if (rtxcode == LT)  { fputs ("l", file); return; }      else if (rtxcode == LTU) { fputs ("l", file); return; }      else if (rtxcode == GE)  { fputs ("ge", file); return; }      else if (rtxcode == GEU) { fputs ("ge", file); return; }      else if (rtxcode == LE)  { fputs ("le", file); return; }      else if (rtxcode == LEU) { fputs ("le", file); return; }      else abort ();      break;    case 0:      output_addr_const (file, x);      break;    default:      abort ();    }  return;}/* Print a memory address as an operand to reference that memory location.   This is exactly the same as legitimate_address_p, except that it the prints   addresses instead of recognizing them.  */voidi960_print_operand_addr (file, addr)     FILE *file;     register rtx addr;{  rtx breg, ireg;  rtx scale, offset;  ireg = 0;  breg = 0;  offset = 0;  scale = const1_rtx;  if (GET_CODE (addr) == REG)    breg = addr;  else if (CONSTANT_P (addr))    offset = addr;  else if (GET_CODE (addr) == PLUS)    {      rtx op0, op1;      op0 = XEXP (addr, 0);      op1 = XEXP (addr, 1);      if (GET_CODE (op0) == REG)	{	  breg = op0;	  if (GET_CODE (op1) == REG)	    ireg = op1;	  else if (CONSTANT_P (op1))	    offset = op1;	  else	    abort ();	}      else if (GET_CODE (op0) == PLUS)	{	  if (GET_CODE (XEXP (op0, 0)) == MULT)	    {	      ireg = XEXP (XEXP (op0, 0), 0);	      scale = XEXP (XEXP (op0, 0), 1);	      if (GET_CODE (XEXP (op0, 1)) == REG)		{		  breg = XEXP (op0, 1);		  offset = op1;		}	      else		abort ();	    }	  else if (GET_CODE (XEXP (op0, 0)) == REG)	    {	      breg = XEXP (op0, 0);	      if (GET_CODE (XEXP (op0, 1)) == REG)		{		  ireg = XEXP (op0, 1);		  offset = op1;		}	      else		abort ();	    }	  else	    abort ();	}      else if (GET_CODE (op0) == MULT)	{	  ireg = XEXP (op0, 0);	  scale = XEXP (op0, 1);	  if (GET_CODE (op1) == REG)	    breg = op1;	  else if (CONSTANT_P (op1))	    offset = op1;	  else	    abort ();	}      else	abort ();    }  else if (GET_CODE (addr) == MULT)    {      ireg = XEXP (addr, 0);      scale = XEXP (addr, 1);    }  else    abort ();  if (offset)    output_addr_const (file, offset);  if (breg)    fprintf (file, "(%s)", reg_names[REGNO (breg)]);  if (ireg)    fprintf (file, "[%s*%d]", reg_names[REGNO (ireg)], INTVAL (scale));}/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression   that is a valid memory address for an instruction.   The MODE argument is the machine mode for the MEM expression   that wants to use this address.	On 80960, legitimate addresses are:		base				ld	(g0),r0		disp	(12 or 32 bit)		ld	foo,r0		base + index			ld	(g0)[g1*1],r0		base + displ			ld	0xf00(g0),r0		base + index*scale + displ	ld	0xf00(g0)[g1*4],r0		index*scale + base		ld	(g0)[g1*4],r0		index*scale + displ		ld	0xf00[g1*4],r0		index*scale			ld	[g1*4],r0		index + base + displ		ld	0xf00(g0)[g1*1],r0	In each case, scale can be 1, 2, 4, 8, or 16.  *//* This is exactly the same as i960_print_operand_addr, except that   it recognizes addresses instead of printing them.   It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should   convert common non-canonical forms to canonical form so that they will   be recognized.  *//* These two macros allow us to accept either a REG or a SUBREG anyplace   where a register is valid.  */#define RTX_OK_FOR_BASE_P(X, STRICT)					\  ((GET_CODE (X) == REG							\    && (STRICT ? REG_OK_FOR_BASE_P_STRICT (X) : REG_OK_FOR_BASE_P (X)))	\   || (GET_CODE (X) == SUBREG						\       && GET_CODE (SUBREG_REG (X)) == REG				\       && (STRICT ? REG_OK_FOR_BASE_P_STRICT (SUBREG_REG (X))		\	   : REG_OK_FOR_BASE_P (SUBREG_REG (X)))))#define RTX_OK_FOR_INDEX_P(X, STRICT)					\  ((GET_CODE (X) == REG							\    && (STRICT ? REG_OK_FOR_INDEX_P_STRICT (X) : REG_OK_FOR_INDEX_P (X)))\   || (GET_CODE (X) == SUBREG						\       && GET_CODE (SUBREG_REG (X)) == REG				\       && (STRICT ? REG_OK_FOR_INDEX_P_STRICT (SUBREG_REG (X))		\	   : REG_OK_FOR_INDEX_P (SUBREG_REG (X)))))intlegitimate_address_p (mode, addr, strict)     enum machine_mode mode;     register rtx addr;     int strict;{  if (RTX_OK_FOR_BASE_P (addr, strict))    return 1;  else if (CONSTANT_P (addr))    return 1;  else if (GET_CODE (addr) == PLUS)    {      rtx op0, op1;      if (! TARGET_COMPLEX_ADDR && ! reload_completed)	return 0;      op0 = XEXP (addr, 0);      op1 = XEXP (addr, 1);      if (RTX_OK_FOR_BASE_P (op0, strict))	{	  if (RTX_OK_FOR_INDEX_P (op1, strict))	    return 1;	  else if (CONSTANT_P (op1))	    return 1;	  else	    return 0;	}      else if (GET_CODE (op0) == PLUS)	{	  if (GET_CODE (XEXP (op0, 0)) == MULT)	    {	      if (! (RTX_OK_FOR_INDEX_P (XEXP (XEXP (op0, 0), 0), strict)		     && SCALE_TERM_P (XEXP (XEXP (op0, 0), 1))))		return 0;	      if (RTX_OK_FOR_BASE_P (XEXP (op0, 1), strict)		  && CONSTANT_P (op1))		return 1;	      else		return 0;	    }	  else if (RTX_OK_FOR_BASE_P (XEXP (op0, 0), strict))	    {	      if (RTX_OK_FOR_INDEX_P (XEXP (op0, 1), strict)		  && CONSTANT_P (op1))		return 1;	      else		return 0;	    }	  else	    return 0;	}      else if (GET_CODE (op0) == MULT)	{	  if (! (RTX_OK_FOR_INDEX_P (XEXP (op0, 0), strict)		 && SCALE_TERM_P (XEXP (op0, 1))))	    return 0;	  if (RTX_OK_FOR_BASE_P (op1, strict))	    return 1;	  else if (CONSTANT_P (op1))	    return 1;	  else	    return 0;	}      else	return 0;    }  else if (GET_CODE (addr) == MULT)    {      if (! TARGET_COMPLEX_ADDR && ! reload_completed)	return 0;      return (RTX_OK_FOR_INDEX_P (XEXP (addr, 0), strict)	      && SCALE_TERM_P (XEXP (addr, 1)));    }  else    return 0;}/* Try machine-dependent ways of modifying an illegitimate address   to be legitimate.  If we find one, return the new, valid address.   This macro is used in only one place: `memory_address' in explow.c.   This converts some non-canonical addresses to canonical form so they   can be recognized.  */rtxlegitimize_address (x, oldx, mode)     register rtx x;     register rtx oldx;     enum machine_mode mode;{   if (GET_CODE (x) == SYMBOL_REF)    {      abort ();      x = copy_to_reg (x);    }  if (! TARGET_COMPLEX_ADDR && ! reload_completed)    return x;  /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))     into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be     created by virtual register instantiation, register elimination, and     similar optimizations.  */  if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT      && GET_CODE (XEXP (x, 1)) == PLUS)    x = gen_rtx (PLUS, Pmode,		 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),		 XEXP (XEXP (x, 1), 1));  /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)     into (plus (plus (mult (reg) (const)) (reg)) (const)).  */  else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS	   && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT	   && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS	   && CONSTANT_P (XEXP (x, 1)))    {      rtx constant, other;      if (GET_CODE (XEXP (x, 1)) == CONST_INT)	{	  constant = XEXP (x, 1);	  other = XEXP (XEXP (XEXP (x, 0), 1), 1);	}      else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)	{	  constant = XEXP (XEXP (XEXP (x, 0), 1), 1);	  other = XEXP (x, 1);	}      else	constant = 0;      if (constant)	x = gen_rtx (PLUS, Pmode,		     gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),			      XEXP (XEXP (XEXP (x, 0), 1), 0)),		     plus_constant (other, INTVAL (constant)));    }  return x;}#if 0/* Return the most stringent alignment that we are willing to consider   objects of size SIZE and known alignment ALIGN as having. */   inti960_alignment (size, align)     int size;     int align;{  int i;  if (! TARGET_STRICT_ALIGN)    if (TARGET_IC_COMPAT2_0 || align >= 4)      {	i = i960_object_bytes_bitalign (size) / BITS_PER_UNIT;	if (i > align)	  align = i;      }  return align;}#endif/* Modes for condition codes.  */#define C_MODES		\  ((1 << (int) CCmode) | (1 << (int) CC_UNSmode) | (1<< (int) CC_CHKmode))/* Modes for single-word (and smaller) quantities.  */#define S_MODES						\ (~C_MODES						\  & ~ ((1 << (int) DImode) | (1 << (int) TImode)	\       | (1 << (int) DFmode) | (1 << (int) XFmode)))/* Modes for double-word (and smaller) quantities.  */#define D_MODES					\  (~C_MODES					\   & ~ ((1 << (int) TImode) | (1 << (int) XFmode)))

⌨️ 快捷键说明

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