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

📄 final.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
		  if (result == 1)		    validate_change (insn, &SET_SRC (body), const_true_rtx, 0);		  else if (result == -1)		    validate_change (insn, &SET_SRC (body), const0_rtx, 0);		  else if (result == 2)		    INSN_CODE (insn) = -1;		}	      }	  }#endif	/* Do machine-specific peephole optimizations if desired.  */	if (optimize && !flag_no_peephole && !nopeepholes)	  {	    rtx next = peephole (insn);	    /* When peepholing, if there were notes within the peephole,	       emit them before the peephole.  */	    if (next != 0 && next != NEXT_INSN (insn))	      {		rtx prev = PREV_INSN (insn);		rtx note;		for (note = NEXT_INSN (insn); note != next;		     note = NEXT_INSN (note))		  final_scan_insn (note, file, optimize, prescan, nopeepholes);		/* In case this is prescan, put the notes		   in proper position for later rescan.  */		note = NEXT_INSN (insn);		PREV_INSN (note) = prev;		NEXT_INSN (prev) = note;		NEXT_INSN (PREV_INSN (next)) = insn;		PREV_INSN (insn) = PREV_INSN (next);		NEXT_INSN (insn) = next;		PREV_INSN (next) = insn;	      }	    /* PEEPHOLE might have changed this.  */	    body = PATTERN (insn);	  }	/* Try to recognize the instruction.	   If successful, verify that the operands satisfy the	   constraints for the instruction.  Crash if they don't,	   since `reload' should have changed them so that they do.  */	insn_code_number = recog_memoized (insn);	insn_extract (insn);	for (i = 0; i < insn_n_operands[insn_code_number]; i++)	  {	    if (GET_CODE (recog_operand[i]) == SUBREG)	      recog_operand[i] = alter_subreg (recog_operand[i]);	    else if (GET_CODE (recog_operand[i]) == PLUS		     || GET_CODE (recog_operand[i]) == MULT)	      recog_operand[i] = walk_alter_subreg (recog_operand[i]);	  }	for (i = 0; i < insn_n_dups[insn_code_number]; i++)	  {	    if (GET_CODE (*recog_dup_loc[i]) == SUBREG)	      *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);	    else if (GET_CODE (*recog_dup_loc[i]) == PLUS		     || GET_CODE (*recog_dup_loc[i]) == MULT)	      *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);	  }#ifdef REGISTER_CONSTRAINTS	if (! constrain_operands (insn_code_number, 1))	  fatal_insn_not_found (insn);#endif	/* Some target machines need to prescan each insn before	   it is output.  */#ifdef FINAL_PRESCAN_INSN	FINAL_PRESCAN_INSN (insn, recog_operand,			    insn_n_operands[insn_code_number]);#endif#ifdef HAVE_cc0	cc_prev_status = cc_status;	/* Update `cc_status' for this instruction.	   The instruction's output routine may change it further.	   If the output routine for a jump insn needs to depend	   on the cc status, it should look at cc_prev_status.  */	NOTICE_UPDATE_CC (body, insn);#endif	debug_insn = insn;	/* If the proper template needs to be chosen by some C code,	   run that code and get the real template.  */	template = insn_template[insn_code_number];	if (template == 0)	  {	    template = (*insn_outfun[insn_code_number]) (recog_operand, insn);	    /* If the C code returns 0, it means that it is a jump insn	       which follows a deleted test insn, and that test insn	       needs to be reinserted.  */	    if (template == 0)	      {		if (prev_nonnote_insn (insn) != last_ignored_compare)		  abort ();		new_block = 0;		return prev_nonnote_insn (insn);	      }	  }	/* If the template is the string "#", it means that this insn must	   be split.  */	if (template[0] == '#' && template[1] == '\0')	  {	    rtx new = try_split (body, insn, 0);	    /* If we didn't split the insn, go away.  */	    if (new == insn && PATTERN (new) == body)	      abort ();	      	    new_block = 0;	    return new;	  }		if (prescan > 0)	  break;	/* Output assembler code from the template.  */	output_asm_insn (template, recog_operand);#if 0	/* It's not at all clear why we did this and doing so interferes	   with tests we'd like to do to use REG_WAS_0 notes, so let's try	   with this out.  */	/* Mark this insn as having been output.  */	INSN_DELETED_P (insn) = 1;#endif	debug_insn = 0;      }    }  return NEXT_INSN (insn);}/* Output debugging info to the assembler file FILE   based on the NOTE-insn INSN, assumed to be a line number.  */static voidoutput_source_line (file, insn)     FILE *file;     rtx insn;{  register char *filename = NOTE_SOURCE_FILE (insn);  /* Remember filename for basic block profiling.     Filenames are allocated on the permanent obstack     or are passed in ARGV, so we don't have to save     the string.  */  if (profile_block_flag && last_filename != filename)    bb_file_label_num = add_bb_string (filename, TRUE);  last_filename = filename;  last_linenum = NOTE_LINE_NUMBER (insn);  high_block_linenum = MAX (last_linenum, high_block_linenum);  high_function_linenum = MAX (last_linenum, high_function_linenum);  if (write_symbols != NO_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 > -1)		    ? last_linenum - sdb_begin_function_line : 1));#endif	}#endif#if defined (DBX_DEBUGGING_INFO)      if (write_symbols == DBX_DEBUG)	dbxout_source_line (file, filename, NOTE_LINE_NUMBER (insn));#endif#if defined (XCOFF_DEBUGGING_INFO)      if (write_symbols == XCOFF_DEBUG)	xcoffout_source_line (file, filename, insn);#endif#ifdef DWARF_DEBUGGING_INFO      if (write_symbols == DWARF_DEBUG)	dwarfout_line (filename, NOTE_LINE_NUMBER (insn));#endif    }}/* 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;      if (BYTES_BIG_ENDIAN)	offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))		   - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));      PUT_CODE (x, MEM);      MEM_VOLATILE_P (x) = MEM_VOLATILE_P (y);      XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);    }  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;}#ifdef HAVE_cc0/* 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;      PUT_CODE (cond, swap_condition (GET_CODE (cond)));    }  if (cc_status.flags & CC_INVERTED)    {      value = 2;      PUT_CODE (cond, reverse_condition (GET_CODE (cond)));    }  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;      }  if (cc_status.flags & CC_NOT_SIGNED)    /* The flags are valid if signed condition operators are converted       to unsigned.  */    switch (GET_CODE (cond))      {      case LE:	PUT_CODE (cond, LEU);	value = 2;	break;      case LT:	PUT_CODE (cond, LTU);	value = 2;	break;      case GT:	PUT_CODE (cond, GTU);	value = 2;	break;      case GE:	PUT_CODE (cond, GEU);	value = 2;	break;      }  return value;}#endif/* Report inconsistency between the assembler template and the operands.   In an `asm', it's the user's fault; otherwise, the compiler's fault.  */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.  */static voidoutput_asm_name (){  if (flag_print_asm_name)    {      /* Annotate the assembly with a comment describing the pattern and	 alternative used.  */      if (debug_insn)	{	  register int num = INSN_CODE (debug_insn);	  fprintf (asm_out_file, " %s %d %s", 		   ASM_COMMENT_START, INSN_UID (debug_insn), insn_name[num]);	  if (insn_n_a

⌨️ 快捷键说明

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