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

📄 m68k.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
       sp@, (sp) or (%sp) depending on the style of syntax.   '#' for an immediate operand prefix (# in MIT and Motorola syntax       but & in SGS syntax).   '!' for the cc register (used in an `and to cc' insn).   '$' for the letter `s' in an op code, but only on the 68040.   '&' for the letter `d' in an op code, but only on the 68040.   '/' for register prefix needed by longlong.h.   'b' for byte insn (no effect, on the Sun; this is for the ISI).   'd' to force memory addressing to be absolute, not relative.   'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)   'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather       than directly).  Second part of 'y' below.   'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),       or print pair of registers as rx:ry.   'y' for a FPA insn (print pair of registers as rx:ry).  This also outputs       CONST_DOUBLE's as SunFPA constant RAM registers if       possible, so it should not be used except for the SunFPA.   */voidprint_operand (file, op, letter)     FILE *file;		/* file to write to */     rtx op;			/* operand to print */     int letter;		/* %<letter> or 0 */{  int i;  if (letter == '.')    {#ifdef MOTOROLA      asm_fprintf (file, ".");#endif    }  else if (letter == '#')    {      asm_fprintf (file, "%0I");    }  else if (letter == '-')    {#ifdef MOTOROLA      asm_fprintf (file, "-(%Rsp)");#else      asm_fprintf (file, "%Rsp@-");#endif    }  else if (letter == '+')    {#ifdef MOTOROLA      asm_fprintf (file, "(%Rsp)+");#else      asm_fprintf (file, "%Rsp@+");#endif    }  else if (letter == '@')    {#ifdef MOTOROLA      asm_fprintf (file, "(%Rsp)");#else      asm_fprintf (file, "%Rsp@");#endif    }  else if (letter == '!')    {      asm_fprintf (file, "%Rfpcr");    }  else if (letter == '$')    {      if (TARGET_68040_ONLY)	{	  fprintf (file, "s");	}    }  else if (letter == '&')    {      if (TARGET_68040_ONLY)	{	  fprintf (file, "d");	}    }  else if (letter == '/')    {      asm_fprintf (file, "%R");    }  else if (GET_CODE (op) == REG)    {      if (REGNO (op) < 16	  && (letter == 'y' || letter == 'x')	  && GET_MODE (op) == DFmode)	{	  fprintf (file, "%s:%s", reg_names[REGNO (op)],		   reg_names[REGNO (op)+1]);	}      else	{	  fprintf (file, "%s", reg_names[REGNO (op)]);	}    }  else if (GET_CODE (op) == MEM)    {      output_address (XEXP (op, 0));      if (letter == 'd' && ! TARGET_68020	  && CONSTANT_ADDRESS_P (XEXP (op, 0))	  && !(GET_CODE (XEXP (op, 0)) == CONST_INT	       && INTVAL (XEXP (op, 0)) < 0x8000	       && INTVAL (XEXP (op, 0)) >= -0x8000))	{	  fprintf (file, ":l");	}    }#ifdef SUPPORT_SUN_FPA  else if ((letter == 'y' || letter == 'w')	   && GET_CODE (op) == CONST_DOUBLE	   && (i = standard_sun_fpa_constant_p (op)))    {      fprintf (file, "%%%d", i & 0x1ff);    }#endif  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)    {      double d;      union { float f; int i; } u1;      REAL_VALUE_FROM_CONST_DOUBLE (d, op);      u1.f = d;      PRINT_OPERAND_PRINT_FLOAT (letter, file);    }  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) != DImode)    {      double d;      REAL_VALUE_FROM_CONST_DOUBLE (d, op);      ASM_OUTPUT_DOUBLE_OPERAND (file, d);    }  else    {      asm_fprintf (file, "%0I"); output_addr_const (file, op);    }}/* A C compound statement to output to stdio stream STREAM the   assembler syntax for an instruction operand that is a memory   reference whose address is ADDR.  ADDR is an RTL expression.   Note that this contains a kludge that knows that the only reason   we have an address (plus (label_ref...) (reg...)) when not generating   PIC code is in the insn before a tablejump, and we know that m68k.md   generates a label LInnn: on such an insn.   It is possible for PIC to generate a (plus (label_ref...) (reg...))   and we handle that just like we would a (plus (symbol_ref...) (reg...)).   Some SGS assemblers have a bug such that "Lnnn-LInnn-2.b(pc,d0.l*2)"   fails to assemble.  Luckily "Lnnn(pc,d0.l*2)" produces the results   we want.  This difference can be accommodated by using an assembler   define such "LDnnn" to be either "Lnnn-LInnn-2.b", "Lnnn", or any other   string, as necessary.  This is accomplished via the ASM_OUTPUT_CASE_END   macro.  See m68ksgs.h for an example; for versions without the bug.   They also do not like things like "pea 1.w", so we simple leave off   the .w on small constants.    This routine is responsible for distinguishing between -fpic and -fPIC    style relocations in an address.  When generating -fpic code the   offset is output in word mode (eg movel a5@(_foo:w), a0).  When generating   -fPIC code the offset is output in long mode (eg movel a5@(_foo:l), a0) */voidprint_operand_address (file, addr)     FILE *file;     rtx addr;{  register rtx reg1, reg2, breg, ireg;  rtx offset;  switch (GET_CODE (addr))    {      case REG:#ifdef MOTOROLA	fprintf (file, "(%s)", reg_names[REGNO (addr)]);#else	fprintf (file, "%s@", reg_names[REGNO (addr)]);#endif	break;      case PRE_DEC:#ifdef MOTOROLA	fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);#else	fprintf (file, "%s@-", reg_names[REGNO (XEXP (addr, 0))]);#endif	break;      case POST_INC:#ifdef MOTOROLA	fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);#else	fprintf (file, "%s@+", reg_names[REGNO (XEXP (addr, 0))]);#endif	break;      case PLUS:	reg1 = reg2 = ireg = breg = offset = 0;	if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))	  {	    offset = XEXP (addr, 0);	    addr = XEXP (addr, 1);	  }	else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))	  {	    offset = XEXP (addr, 1);	    addr = XEXP (addr, 0);	  }	if (GET_CODE (addr) != PLUS)	  {	    ;	  }	else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)	  {	    reg1 = XEXP (addr, 0);	    addr = XEXP (addr, 1);	  }	else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)	  {	    reg1 = XEXP (addr, 1);	    addr = XEXP (addr, 0);	  }	else if (GET_CODE (XEXP (addr, 0)) == MULT)	  {	    reg1 = XEXP (addr, 0);	    addr = XEXP (addr, 1);	  }	else if (GET_CODE (XEXP (addr, 1)) == MULT)	  {	    reg1 = XEXP (addr, 1);	    addr = XEXP (addr, 0);	  }	else if (GET_CODE (XEXP (addr, 0)) == REG)	  {	    reg1 = XEXP (addr, 0);	    addr = XEXP (addr, 1);	  }	else if (GET_CODE (XEXP (addr, 1)) == REG)	  {	    reg1 = XEXP (addr, 1);	    addr = XEXP (addr, 0);	  }	if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT	    || GET_CODE (addr) == SIGN_EXTEND)	  {	    if (reg1 == 0)	      {		reg1 = addr;	      }	    else	      {		reg2 = addr;	      }	    addr = 0;	  }#if 0	/* for OLD_INDEXING */	else if (GET_CODE (addr) == PLUS)	  {	    if (GET_CODE (XEXP (addr, 0)) == REG)	      {		reg2 = XEXP (addr, 0);		addr = XEXP (addr, 1);	      }	    else if (GET_CODE (XEXP (addr, 1)) == REG)	      {		reg2 = XEXP (addr, 1);		addr = XEXP (addr, 0);	      }	  }#endif	if (offset != 0)	  {	    if (addr != 0)	      {		abort ();	      }	    addr = offset;	  }	if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND		      || GET_CODE (reg1) == MULT))	    || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))	  {	    breg = reg2;	    ireg = reg1;	  }	else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))	  {	    breg = reg1;	    ireg = reg2;	  }	if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF	    && ! (flag_pic && ireg == pic_offset_table_rtx))	  {	    int scale = 1;	    if (GET_CODE (ireg) == MULT)	      {		scale = INTVAL (XEXP (ireg, 1));		ireg = XEXP (ireg, 0);	      }	    if (GET_CODE (ireg) == SIGN_EXTEND)	      {#ifdef MOTOROLA#ifdef SGS		asm_fprintf (file, "%LLD%d(%Rpc,%s.w",			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (XEXP (ireg, 0))]);#else		asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.w",			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (XEXP (ireg, 0))]);#endif#else		asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:w",			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (XEXP (ireg, 0))]);#endif	      }	    else	      {#ifdef MOTOROLA#ifdef SGS		asm_fprintf (file, "%LLD%d(%Rpc,%s.l",			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (ireg)]);#else		asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l",			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (ireg)]);#endif#else		asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l",			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (ireg)]);#endif	      }	    if (scale != 1)	      {#ifdef MOTOROLA		fprintf (file, "*%d", scale);#else		fprintf (file, ":%d", scale);#endif	      }	    putc (')', file);	    break;	  }	if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF	    && ! (flag_pic && breg == pic_offset_table_rtx))	  {#ifdef MOTOROLA#ifdef SGS	    asm_fprintf (file, "%LLD%d(%Rpc,%s.l",			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (breg)]);#else	    asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l",			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (breg)]);#endif#else	    asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l",			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (breg)]);#endif	    putc (')', file);	    break;	  }	if (ireg != 0 || breg != 0)	  {	    int scale = 1;	    if (breg == 0)	      {		abort ();	      }	    if (! flag_pic && addr && GET_CODE (addr) == LABEL_REF)	      {		abort ();	      }#ifdef MOTOROLA	    if (addr != 0)	      {		output_addr_const (file, addr);	        if ((flag_pic == 1) && (breg == pic_offset_table_rtx))	          fprintf (file, ".w");	        if ((flag_pic == 2) && (breg == pic_offset_table_rtx))	          fprintf (file, ".l");	      }	    fprintf (file, "(%s", reg_names[REGNO (breg)]);	    if (ireg != 0)	      {		putc (',', file);	      }#else	    fprintf (file, "%s@(", reg_names[REGNO (breg)]);	    if (addr != 0)	      {		output_addr_const (file, addr);	        if ((flag_pic == 1) && (breg == pic_offset_table_rtx))	          fprintf (file, ":w");	        if ((flag_pic == 2) && (breg == pic_offset_table_rtx))	          fprintf (file, ":l");	      }	    if (addr != 0 && ireg != 0)	      {		putc (',', file);	      }#endif	    if (ireg != 0 && GET_CODE (ireg) == MULT)	      {		scale = INTVAL (XEXP (ireg, 1));		ireg = XEXP (ireg, 0);	      }	    if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)	      {#ifdef MOTOROLA		fprintf (file, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);#else		fprintf (file, "%s:w", reg_names[REGNO (XEXP (ireg, 0))]);#endif	      }	    else if (ireg != 0)	      {#ifdef MOTOROLA		fprintf (file, "%s.l", reg_names[REGNO (ireg)]);#else		fprintf (file, "%s:l", reg_names[REGNO (ireg)]);#endif	      }	    if (scale != 1)	      {#ifdef MOTOROLA		fprintf (file, "*%d", scale);#else		fprintf (file, ":%d", scale);#endif	      }	    putc (')', file);	    break;	  }	else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF		 && ! (flag_pic && reg1 == pic_offset_table_rtx))		  {#ifdef MOTOROLA#ifdef SGS	    asm_fprintf (file, "%LLD%d(%Rpc,%s.l)",			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (reg1)]);#else	    asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.l)",			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (reg1)]);#endif#else	    asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:l)",			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (reg1)]);#endif	    break;	  }	/* FALL-THROUGH (is this really what we want? */      default:        if (GET_CODE (addr) == CONST_INT	    && INTVAL (addr) < 0x8000	    && INTVAL (addr) >= -0x8000)	  {#ifdef MOTOROLA#ifdef SGS	    /* Many SGS assemblers croak on size specifiers for constants. */	    fprintf (file, "%d", INTVAL (addr));#else	    fprintf (file, "%d.w", INTVAL (addr));#endif#else	    fprintf (file, "%d:w", INTVAL (addr));#endif	  }	else	  {	    output_addr_const (file, addr);	  }	break;    }}

⌨️ 快捷键说明

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