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

📄 final.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
     FILE *file;     rtx insn;     enum debugger write_symbols;{  register char *filename = NOTE_SOURCE_FILE (insn);  last_linenum = NOTE_LINE_NUMBER (insn);  if (write_symbols == GDB_DEBUG)    {      /* Output GDB-format line number info.  */      /* If this is not the same source file as last time,	 find or assign a GDB-file-number to this file.  */      if (filename && (lastfile == 0 || strcmp (filename, lastfile)		       || current_gdbfile == 0))	set_current_gdbfile (filename);      ++current_gdbfile->nlines;      fprintf (file, "\t.gdbline %d,%d\n",	       current_gdbfile->filenum, NOTE_LINE_NUMBER (insn));    }  if (write_symbols == SDB_DEBUG || write_symbols == DBX_DEBUG)    {#ifdef SDB_DEBUGGING_INFO      if (write_symbols == SDB_DEBUG#if 0 /* People like having line numbers even in wrong file!  */	  /* COFF can't handle multiple source files--lose, lose.  */	  && !strcmp (filename, main_input_filename)#endif	  /* COFF relative line numbers must be positive.  */	  && last_linenum > sdb_begin_function_line)	{#ifdef ASM_OUTPUT_SOURCE_LINE	  ASM_OUTPUT_SOURCE_LINE (file, last_linenum);#else	  fprintf (file, "\t.ln\t%d\n",		   (sdb_begin_function_line		    ? last_linenum - sdb_begin_function_line : 1));#endif	}#endif#ifdef DBX_DEBUGGING_INFO      if (write_symbols == DBX_DEBUG)	{	  /* Write DBX line number data.  */	  if (filename && (lastfile == 0 || strcmp (filename, lastfile)))	    {#ifdef ASM_OUTPUT_SOURCE_FILENAME	      ASM_OUTPUT_SOURCE_FILENAME (file, filename);#else	      fprintf (file, "\t.stabs \"%s\",%d,0,0,Ltext\n",		       filename, N_SOL);#endif	      lastfile = filename;	    }	}#ifdef ASM_OUTPUT_SOURCE_LINE      ASM_OUTPUT_SOURCE_LINE (file, NOTE_LINE_NUMBER (insn));#else      fprintf (file, "\t.stabd %d,0,%d\n",	       N_SLINE, NOTE_LINE_NUMBER (insn));#endif#endif /* DBX_DEBUGGING_INFO */    }}/* If X is a SUBREG, replace it with a REG or a MEM,   based on the thing it is a subreg of.  */rtxalter_subreg (x)     register rtx x;{  register rtx y = SUBREG_REG (x);  if (GET_CODE (y) == SUBREG)    y = alter_subreg (y);  if (GET_CODE (y) == REG)    {      /* If the containing reg really gets a hard reg, so do we.  */      PUT_CODE (x, REG);      REGNO (x) = REGNO (y) + SUBREG_WORD (x);    }  else if (GET_CODE (y) == MEM)    {      register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;#ifdef BYTES_BIG_ENDIAN      offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))		 - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));#endif      PUT_CODE (x, MEM);      MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);      XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);    }  else if (GET_CODE (y) == CONST_DOUBLE)    return y;  return x;}/* Do alter_subreg on all the SUBREGs contained in X.  */static rtxwalk_alter_subreg (x)     rtx x;{  switch (GET_CODE (x))    {    case PLUS:    case MULT:      XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));      XEXP (x, 1) = walk_alter_subreg (XEXP (x, 1));      break;    case MEM:      XEXP (x, 0) = walk_alter_subreg (XEXP (x, 0));      break;    case SUBREG:      return alter_subreg (x);    }  return x;}/* Given BODY, the body of a jump instruction, alter the jump condition   as required by the bits that are set in cc_status.flags.   Not all of the bits there can be handled at this level in all cases.   The value is normally 0.   1 means that the condition has become always true.   -1 means that the condition has become always false.   2 means that COND has been altered.  */static intalter_cond (cond)     register rtx cond;{  int value = 0;  if (cc_status.flags & CC_REVERSED)    {      value = 2;      switch (GET_CODE (cond))	{	case LE:	  PUT_CODE (cond, GE);	  break;	case GE:	  PUT_CODE (cond, LE);	  break;	case LT:	  PUT_CODE (cond, GT);	  break;	case GT:	  PUT_CODE (cond, LT);	  break;	case LEU:	  PUT_CODE (cond, GEU);	  break;	case GEU:	  PUT_CODE (cond, LEU);	  break;	case LTU:	  PUT_CODE (cond, GTU);	  break;	case GTU:	  PUT_CODE (cond, LTU);	  break;	}    }  if (cc_status.flags & CC_NOT_POSITIVE)    switch (GET_CODE (cond))      {      case LE:      case LEU:      case GEU:	/* Jump becomes unconditional.  */	return 1;      case GT:      case GTU:      case LTU:	/* Jump becomes no-op.  */	return -1;      case GE:	PUT_CODE (cond, EQ);	value = 2;	break;      case LT:	PUT_CODE (cond, NE);	value = 2;	break;      }  if (cc_status.flags & CC_NOT_NEGATIVE)    switch (GET_CODE (cond))      {      case GE:      case GEU:	/* Jump becomes unconditional.  */	return 1;      case LT:      case LTU:	/* Jump becomes no-op.  */	return -1;      case LE:      case LEU:	PUT_CODE (cond, EQ);	value = 2;	break;      case GT:      case GTU:	PUT_CODE (cond, NE);	value = 2;	break;      }  if (cc_status.flags & CC_NO_OVERFLOW)    switch (GET_CODE (cond))      {      case GEU:	/* Jump becomes unconditional.  */	return 1;      case LEU:	PUT_CODE (cond, EQ);	value = 2;	break;      case GTU:	PUT_CODE (cond, NE);	value = 2;	break;      case LTU:	/* Jump becomes no-op.  */	return -1;      }  if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N))    switch (GET_CODE (cond))      {      case LE:      case LEU:      case GE:      case GEU:      case LT:      case LTU:      case GT:      case GTU:	abort ();      case NE:	PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);	value = 2;	break;      case EQ:	PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE);	value = 2;	break;      }    return value;}/* Report inconsistency between the assembler template and the operands.   In an `asm', it's the user's fault; otherwise, the compiler's fault.  */static voidoutput_operand_lossage (str)     char *str;{  if (this_is_asm_operands)    error_for_asm (this_is_asm_operands, "invalid `asm': %s", str);  else    abort ();}/* Output of assembler code from a template, and its subroutines.  *//* Output text from TEMPLATE to the assembler output file,   obeying %-directions to substitute operands taken from   the vector OPERANDS.   %N (for N a digit) means print operand N in usual manner.   %lN means require operand N to be a CODE_LABEL or LABEL_REF      and print the label name with no punctuation.   %cN means require operand N to be a constant      and print the constant expression with no punctuation.   %aN means expect operand N to be a memory address      (not a memory reference!) and print a reference      to that address.   %nN means expect operand N to be a constant      and print a constant expression for minus the value      of the operand, with no other punctuation.  */voidoutput_asm_insn (template, operands)     char *template;     rtx *operands;{  register char *p;  register int c;  /* An insn may return a null string template     in a case where no assembler code is needed.  */  if (*template == 0)    return;  p = template;  putc ('\t', asm_out_file);#ifdef ASM_OUTPUT_OPCODE  ASM_OUTPUT_OPCODE (asm_out_file, p);#endif  while (c = *p++)    {#ifdef ASM_OUTPUT_OPCODE      if (c == '\n')	{	  putc (c, asm_out_file);	  while ((c = *p) == '\t')	    {	      putc (c, asm_out_file);	      p++;	    }	  ASM_OUTPUT_OPCODE (asm_out_file, p);	}      else#endif      if (c != '%')	putc (c, asm_out_file);      else	{	  /* %% outputs a single %.  */	  if (*p == '%')	    {	      p++;	      putc (c, asm_out_file);	    }	  /* % followed by a letter and some digits	     outputs an operand in a special way depending on the letter.	     Letters `acln' are implemented here.	     Other letters are passed to `output_operand' so that	     the PRINT_OPERAND macro can define them.  */	  else if ((*p >= 'a' && *p <= 'z')		   || (*p >= 'A' && *p <= 'Z'))	    {	      int letter = *p++;	      c = atoi (p);	      if (! (*p >= '0' && *p <= '9'))		output_operand_lossage ("operand number missing after %-letter");	      else if (this_is_asm_operands && c >= (unsigned) insn_noperands)		output_operand_lossage ("operand number out of range");	      else if (letter == 'l')		output_asm_label (operands[c]);	      else if (letter == 'a')		output_address (operands[c]);	      else if (letter == 'c')		{		  if (CONSTANT_ADDRESS_P (operands[c]))		    output_addr_const (asm_out_file, operands[c]);		  else		    output_operand (operands[c], 'c');		}	      else if (letter == 'n')		{		  if (GET_CODE (operands[c]) == CONST_INT)		    fprintf (asm_out_file, "%d", - INTVAL (operands[c]));		  else		    {		      putc ('-', asm_out_file);		      output_addr_const (asm_out_file, operands[c]);		    }		}	      else		output_operand (operands[c], letter);	      while ((c = *p) >= '0' && c <= '9') p++;	    }	  /* % followed by a digit outputs an operand the default way.  */	  else if (*p >= '0' && *p <= '9')	    {	      c = atoi (p);	      if (this_is_asm_operands && c >= (unsigned) insn_noperands)		output_operand_lossage ("operand number out of range");	      else		output_operand (operands[c], 0);	      while ((c = *p) >= '0' && c <= '9') p++;	    }	  /* % followed by punctuation: output something for that	     punctuation character alone, with no operand.	     The PRINT_OPERAND macro decides what is actually done.  */#ifdef PRINT_OPERAND_PUNCT_VALID_P	  else if (PRINT_OPERAND_PUNCT_VALID_P (*p))	    output_operand (0, *p++);#endif	  else	    output_operand_lossage ("invalid %%-code");	}    }  putc ('\n', asm_out_file);}/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */voidoutput_asm_label (x)     rtx x;{  char buf[256];  if (GET_CODE (x) == LABEL_REF)    ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));  else if (GET_CODE (x) == CODE_LABEL)    ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));  else    output_operand_lossage ("`%l' operand isn't a label");  assemble_name (asm_out_file, buf);}/* Print operand X using machine-dependent assembler syntax.   The macro PRINT_OPERAND is defined just to control this function.   CODE is a non-digit that preceded the operand-number in the % spec,   such as 'z' if the spec was `%z3'.  CODE is 0 if there was no char   between the % and the digits.   When CODE is a non-letter, X is 0.   The meanings of the letters are machine-dependent and controlled   by PRINT_OPERAND.  */static voidoutput_operand (x, code)     rtx x;     int code;{  if (x && GET_CODE (x) == SUBREG)    x = alter_subreg (x);  PRINT_OPERAND (asm_out_file, x, code);}/* Print a memory reference operand for address X   using machine-dependent assembler syntax.   The macro PRINT_OPERAND_ADDRESS exists just to control this function.  */voidoutput_address (x)     rtx x;{  walk_alter_subreg (x);  PRINT_OPERAND_ADDRESS (asm_out_file, x);}/* Print an integer constant expression in assembler syntax.   Addition and subtraction are the only arithmetic   that may appear in these expressions.  */voidoutput_addr_const (file, x)     FILE *file;     rtx x;{  char buf[256]; restart:  switch (GET_CODE (x))    {    case SYMBOL_REF:      assemble_name (file, XSTR (x, 0));      break;    case LABEL_REF:      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));      assemble_name (asm_out_file, buf);      break;    case CODE_LABEL:      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));      assemble_name (asm_out_file, buf);      break;    case CONST_INT:      fprintf (file, "%d", INTVAL (x));      break;    case CONST:      x = XEXP (x, 0);      goto restart;    case CONST_DOUBLE:      if (GET_MODE (x) == DImode)	{	  /* We can use %d if the number is <32 bits and positive.  */	  if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)	    fprintf (file, "0x%x%08x",		     CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));	  else	    fprintf (file, "%d", CONST_DOUBLE_LOW (x));	}      else	/* We can't handle floating point constants;	   PRINT_OPERAND must handle them.  */	output_operand_lossage ("floating constant misused");      break;    case PLUS:      /* Some assemblers need integer constants to appear last (eg masm).  */      if (GET_CODE (XEXP (x, 0)) == CONST_INT)	{	  output_addr_const (file, XEXP (x, 1));	  if (INTVAL (XEXP (x, 0)) >= 0)	    fprintf (file, "+");	  output_addr_const (file, XEXP (x, 0));	}      else	{	  output_addr_const (file, XEXP (x, 0));	  if (INTVAL (XEXP (x, 1)) >= 0)	    fprintf (file, "+");	  output_addr_const (file, XEXP (x, 1));	}      break;    case MINUS:      output_addr_const (file, XEXP (x, 0));      fprintf (file, "-");      output_addr_const (file, XEXP (x, 1));      break;    default:      output_operand_lossage ("invalid expression as operand");    }}

⌨️ 快捷键说明

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