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

📄 m68k.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif  if (! inited_FPA_table)    init_FPA_table ();  REAL_VALUE_FROM_CONST_DOUBLE (r, x);  for (i=0; i<12; i++)    {      if (REAL_VALUES_EQUAL (r, values_FPA[i]))        return (codes_FPA[i]);    }  if (GET_MODE (x) == SFmode)    {      for (i=25; i<38; i++)        {          if (REAL_VALUES_EQUAL (r, values_FPA[i]))            return (codes_FPA[i]);        }    }  else    {      for (i=12; i<25; i++)        {          if (REAL_VALUES_EQUAL (r, values_FPA[i]))            return (codes_FPA[i]);        }    }  return 0x0;}#endif /* define SUPPORT_SUN_FPA *//* A C compound statement to output to stdio stream STREAM the   assembler syntax for an instruction operand X.  X is an RTL   expression.   CODE is a value that can be used to specify one of several ways   of printing the operand.  It is used when identical operands   must be printed differently depending on the context.  CODE   comes from the `%' specification that was used to request   printing of the operand.  If the specification was just `%DIGIT'   then CODE is 0; if the specification was `%LTR DIGIT' then CODE   is the ASCII code for LTR.   If X is a register, this macro should print the register's name.   The names can be found in an array `reg_names' whose type is   `char *[]'.  `reg_names' is initialized from `REGISTER_NAMES'.   When the machine description has a specification `%PUNCT' (a `%'   followed by a punctuation character), this macro is called with   a null pointer for X and the punctuation character for CODE.   The m68k specific codes are:   '.' for dot needed in Motorola-style opcode names.   '-' for an operand pushing on the stack:       sp@-, -(sp) or -(%sp) depending on the style of syntax.   '+' for an operand pushing on the stack:       sp@+, (sp)+ or (%sp)+ depending on the style of syntax.   '@' for a reference to the top word on the stack:       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)    {#ifdef SUPPORT_SUN_FPA      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#endif	{	  if (letter == 'R')	    /* Print out the second register name of a register pair.	       I.e., R (6) => 7.  */	    fputs (reg_names[REGNO (op) + 1], file);	  else	    fputs (reg_names[REGNO (op)], file);	}    }  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)    {      REAL_VALUE_TYPE r;      REAL_VALUE_FROM_CONST_DOUBLE (r, op);      ASM_OUTPUT_FLOAT_OPERAND (letter, file, r);    }  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)    {      REAL_VALUE_TYPE r;      REAL_VALUE_FROM_CONST_DOUBLE (r, op);      ASM_OUTPUT_LONG_DOUBLE_OPERAND (file, r);    }  else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)    {      REAL_VALUE_TYPE r;      REAL_VALUE_FROM_CONST_DOUBLE (r, op);      ASM_OUTPUT_DOUBLE_OPERAND (file, r);    }  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 m68k/sgs.h for an example; for versions without the bug.   Some assemblers refuse all the above solutions.  The workaround is to   emit "K(pc,d0.l*2)" with K being a small constant known to give the   right behaviour.   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) */#ifndef ASM_OUTPUT_CASE_FETCH#ifdef MOTOROLA#ifdef SGS#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\	asm_fprintf (file, "%LLD%d(%Rpc,%s.", labelno, regname)#else#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\	asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)#endif#else#define ASM_OUTPUT_CASE_FETCH(file, labelno, regname)\	asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)#endif#endif /* ASM_OUTPUT_CASE_FETCH */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)	      {		ASM_OUTPUT_CASE_FETCH (file,			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (XEXP (ireg, 0))]);		fprintf (file, "w");	      }	    else	      {		ASM_OUTPUT_CASE_FETCH (file,			     CODE_LABEL_NUMBER (XEXP (addr, 0)),			     reg_names[REGNO (ireg)]);		fprintf (file, "l");	      }	    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))	  {	    ASM_OUTPUT_CASE_FETCH (file,			 CODE_LABEL_NUMBER (XEXP (addr, 0)),			 reg_names[REGNO (breg)]);	    fprintf (file, "l)");	    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 && (breg == pic_offset_table_rtx))	          fprintf (file, "@GOT");	      }	    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) == L

⌨️ 快捷键说明

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