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

📄 final.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
	    sdbout_end_block (file, high_block_linenum,			      pending_blocks[block_depth]);#endif#ifdef DWARF_DEBUGGING_INFO	  if (write_symbols == DWARF_DEBUG && block_depth >= 1)	    dwarfout_end_block (pending_blocks[block_depth]);#endif	}      else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL	       && (debug_info_level == DINFO_LEVEL_NORMAL		   || debug_info_level == DINFO_LEVEL_VERBOSE))	{#ifdef DWARF_DEBUGGING_INFO          if (write_symbols == DWARF_DEBUG)            dwarfout_label (insn);#endif	}      else if (NOTE_LINE_NUMBER (insn) > 0)	/* This note is a line-number.  */	{	  register rtx note;#if 0 /* This is what we used to do.  */	  output_source_line (file, insn);#endif	  int note_after = 0;	  /* If there is anything real after this note,	     output it.  If another line note follows, omit this one.  */	  for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))	    {	      if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)		break;	      /* These types of notes can be significant		 so make sure the preceding line number stays.  */	      else if (GET_CODE (note) == NOTE		       && (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG			   || NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END			   || NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))  		break;	      else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)		{		  /* Another line note follows; we can delete this note		     if no intervening line numbers have notes elsewhere.  */		  int num;		  for (num = NOTE_LINE_NUMBER (insn) + 1;		       num < NOTE_LINE_NUMBER (note);		       num++)		    if (line_note_exists[num])		      break;		  if (num >= NOTE_LINE_NUMBER (note))		    note_after = 1;		  break;		}	    }	  /* Output this line note	     if it is the first or the last line note in a row.  */	  if (!note_after)	    output_source_line (file, insn);	}      break;    case BARRIER:#ifdef ASM_OUTPUT_ALIGN_CODE      /* Don't litter the assembler output with needless alignments.  A	 BARRIER will be placed at the end of every function if HAVE_epilogue	 is true.  */	       if (NEXT_INSN (insn))	ASM_OUTPUT_ALIGN_CODE (file);#endif      break;    case CODE_LABEL:      CC_STATUS_INIT;      if (prescan > 0)	break;      new_block = 1;#ifdef SDB_DEBUGGING_INFO      if (write_symbols == SDB_DEBUG && LABEL_NAME (insn))	sdbout_label (insn);#endif#ifdef DWARF_DEBUGGING_INFO      if (write_symbols == DWARF_DEBUG && LABEL_NAME (insn))	dwarfout_label (insn);#endif      if (app_on)	{	  fprintf (file, ASM_APP_OFF);	  app_on = 0;	}      if (NEXT_INSN (insn) != 0	  && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)	{	  rtx nextbody = PATTERN (NEXT_INSN (insn));	  /* If this label is followed by a jump-table,	     make sure we put the label in the read-only section.  Also	     possibly write the label and jump table together.  */	  if (GET_CODE (nextbody) == ADDR_VEC	      || GET_CODE (nextbody) == ADDR_DIFF_VEC)	    {#ifndef JUMP_TABLES_IN_TEXT_SECTION	      readonly_data_section ();#ifdef READONLY_DATA_SECTION	      ASM_OUTPUT_ALIGN (file,				exact_log2 (BIGGEST_ALIGNMENT					    / BITS_PER_UNIT));#endif /* READONLY_DATA_SECTION */#else /* JUMP_TABLES_IN_TEXT_SECTION */	      function_section (current_function_decl);#endif /* JUMP_TABLES_IN_TEXT_SECTION */#ifdef ASM_OUTPUT_CASE_LABEL	      ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),				     NEXT_INSN (insn));#else	      ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));#endif	      break;	    }	}      ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));      break;    default:      {	register rtx body = PATTERN (insn);	int insn_code_number;	char *template;	rtx note;	/* An INSN, JUMP_INSN or CALL_INSN.	   First check for special kinds that recog doesn't recognize.  */	if (GET_CODE (body) == USE /* These are just declarations */	    || GET_CODE (body) == CLOBBER)	  break;#ifdef HAVE_cc0	/* If there is a REG_CC_SETTER note on this insn, it means that	   the setting of the condition code was done in the delay slot	   of the insn that branched here.  So recover the cc status	   from the insn that set it.  */	note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);	if (note)	  {	    NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0));	    cc_prev_status = cc_status;	  }#endif	/* Detect insns that are really jump-tables	   and output them as such.  */	if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)	  {	    register int vlen, idx;	    if (prescan > 0)	      break;	    if (app_on)	      {		fprintf (file, ASM_APP_OFF);		app_on = 0;	      }	    vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);	    for (idx = 0; idx < vlen; idx++)	      {		if (GET_CODE (body) == ADDR_VEC)		  {#ifdef ASM_OUTPUT_ADDR_VEC_ELT		    ASM_OUTPUT_ADDR_VEC_ELT		      (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));#else		    abort ();#endif		  }		else		  {#ifdef ASM_OUTPUT_ADDR_DIFF_ELT		    ASM_OUTPUT_ADDR_DIFF_ELT		      (file,		       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),		       CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));#else		    abort ();#endif		  }	      }#ifdef ASM_OUTPUT_CASE_END	    ASM_OUTPUT_CASE_END (file,				 CODE_LABEL_NUMBER (PREV_INSN (insn)),				 insn);#endif	    function_section (current_function_decl);	    break;	  }	/* Do basic-block profiling when we reach a new block.	   Done here to avoid jump tables.  */	if (profile_block_flag && new_block)	  add_bb (file);	if (GET_CODE (body) == ASM_INPUT)	  {	    /* There's no telling what that did to the condition codes.  */	    CC_STATUS_INIT;	    if (prescan > 0)	      break;	    if (! app_on)	      {		fprintf (file, ASM_APP_ON);		app_on = 1;	      }	    fprintf (asm_out_file, "\t%s\n", XSTR (body, 0));	    break;	  }	/* Detect `asm' construct with operands.  */	if (asm_noperands (body) >= 0)	  {	    int noperands = asm_noperands (body);	    rtx *ops = (rtx *) alloca (noperands * sizeof (rtx));	    char *string;	    /* There's no telling what that did to the condition codes.  */	    CC_STATUS_INIT;	    if (prescan > 0)	      break;	    if (! app_on)	      {		fprintf (file, ASM_APP_ON);		app_on = 1;	      }	    /* Get out the operand values.  */	    string = decode_asm_operands (body, ops, NULL_PTR,					  NULL_PTR, NULL_PTR);	    /* Inhibit aborts on what would otherwise be compiler bugs.  */	    insn_noperands = noperands;	    this_is_asm_operands = insn;	    /* Output the insn using them.  */	    output_asm_insn (string, ops);	    this_is_asm_operands = 0;	    break;	  }	if (prescan <= 0 && app_on)	  {	    fprintf (file, ASM_APP_OFF);	    app_on = 0;	  }	if (GET_CODE (body) == SEQUENCE)	  {	    /* A delayed-branch sequence */	    register int i;	    rtx next;	    if (prescan > 0)	      break;	    final_sequence = body;	    /* The first insn in this SEQUENCE might be a JUMP_INSN that will	       force the restoration of a comparison that was previously	       thought unnecessary.  If that happens, cancel this sequence	       and cause that insn to be restored.  */	    next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1);	    if (next != XVECEXP (body, 0, 1))	      {		final_sequence = 0;		return next;	      }	    for (i = 1; i < XVECLEN (body, 0); i++)	      {		rtx insn = XVECEXP (body, 0, i);		rtx next = NEXT_INSN (insn);		/* We loop in case any instruction in a delay slot gets		   split.  */		do		  insn = final_scan_insn (insn, file, 0, prescan, 1);		while (insn != next);	      }#ifdef DBR_OUTPUT_SEQEND	    DBR_OUTPUT_SEQEND (file);#endif	    final_sequence = 0;	    /* If the insn requiring the delay slot was a CALL_INSN, the	       insns in the delay slot are actually executed before the	       called function.  Hence we don't preserve any CC-setting	       actions in these insns and the CC must be marked as being	       clobbered by the function.  */	    if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN)	      CC_STATUS_INIT;	    /* Following a conditional branch sequence, we have a new basic	       block.  */	    if (profile_block_flag)	      {		rtx insn = XVECEXP (body, 0, 0);		rtx body = PATTERN (insn);		if ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET		     && GET_CODE (SET_SRC (body)) != LABEL_REF)		    || (GET_CODE (insn) == JUMP_INSN			&& GET_CODE (body) == PARALLEL			&& GET_CODE (XVECEXP (body, 0, 0)) == SET			&& GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF))		  new_block = 1;	      }	    break;	  }	/* We have a real machine instruction as rtl.  */	body = PATTERN (insn);#ifdef HAVE_cc0	/* Check for redundant test and compare instructions	   (when the condition codes are already set up as desired).	   This is done only when optimizing; if not optimizing,	   it should be possible for the user to alter a variable	   with the debugger in between statements	   and the next statement should reexamine the variable	   to compute the condition codes.  */	if (optimize	    && GET_CODE (body) == SET	    && GET_CODE (SET_DEST (body)) == CC0	    && insn != last_ignored_compare)	  {	    if (GET_CODE (SET_SRC (body)) == SUBREG)	      SET_SRC (body) = alter_subreg (SET_SRC (body));	    else if (GET_CODE (SET_SRC (body)) == COMPARE)	      {		if (GET_CODE (XEXP (SET_SRC (body), 0)) == SUBREG)		  XEXP (SET_SRC (body), 0)		    = alter_subreg (XEXP (SET_SRC (body), 0));		if (GET_CODE (XEXP (SET_SRC (body), 1)) == SUBREG)		  XEXP (SET_SRC (body), 1)		    = alter_subreg (XEXP (SET_SRC (body), 1));	      }	    if ((cc_status.value1 != 0		 && rtx_equal_p (SET_SRC (body), cc_status.value1))		|| (cc_status.value2 != 0		    && rtx_equal_p (SET_SRC (body), cc_status.value2)))	      {		/* Don't delete insn if it has an addressing side-effect.  */		if (! FIND_REG_INC_NOTE (insn, 0)		    /* or if anything in it is volatile.  */		    && ! volatile_refs_p (PATTERN (insn)))		  {		    /* We don't really delete the insn; just ignore it.  */		    last_ignored_compare = insn;		    break;		  }	      }	  }#endif	/* Following a conditional branch, we have a new basic block.	   But if we are inside a sequence, the new block starts after the	   last insn of the sequence.  */	if (profile_block_flag && final_sequence == 0	    && ((GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == SET		 && GET_CODE (SET_SRC (body)) != LABEL_REF)		|| (GET_CODE (insn) == JUMP_INSN && GET_CODE (body) == PARALLEL		    && GET_CODE (XVECEXP (body, 0, 0)) == SET		    && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) != LABEL_REF)))	  new_block = 1;#ifndef STACK_REGS	/* Don't bother outputting obvious no-ops, even without -O.	   This optimization is fast and doesn't interfere with debugging.	   Don't do this if the insn is in a delay slot, since this	   will cause an improper number of delay insns to be written.  */	if (final_sequence == 0	    && prescan >= 0	    && GET_CODE (insn) == INSN && GET_CODE (body) == SET	    && GET_CODE (SET_SRC (body)) == REG	    && GET_CODE (SET_DEST (body)) == REG	    && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))	  break;#endif#ifdef HAVE_cc0	/* If this is a conditional branch, maybe modify it	   if the cc's are in a nonstandard state	   so that it accomplishes the same thing that it would	   do straightforwardly if the cc's were set up normally.  */	if (cc_status.flags != 0	    && GET_CODE (insn) == JUMP_INSN	    && GET_CODE (body) == SET	    && SET_DEST (body) == pc_rtx	    && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE	    && GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (body), 0))) == '<'	    && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx	    /* This is done during prescan; it is not done again	       in final scan when prescan has been done.  */	    && prescan >= 0)	  {	    /* This function may alter the contents of its argument	       and clear some of the cc_status.flags bits.	       It may also return 1 meaning condition now always true	       or -1 meaning condition now always false	       or 2 meaning condition nontrivial but altered.  */	    register int result = alter_cond (XEXP (SET_SRC (body), 0));	    /* If condition now has fixed value, replace the IF_THEN_ELSE	       with its then-operand or its else-operand.  */	    if (result == 1)	      SET_SRC (body) = XEXP (SET_SRC (body), 1);	    if (result == -1)	      SET_SRC (body) = XEXP (SET_SRC (body), 2);	    /* The jump is now either unconditional or a no-op.	       If it has become a no-op, don't try to output it.	       (It would not be recognized.)  */	    if (SET_SRC (body) == pc_rtx)	      {		PUT_CODE (insn, NOTE);		NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;		NOTE_SOURCE_FILE (insn) = 0;		break;	      }	    else if (GET_CODE (SET_SRC (body)) == RETURN)	      /* Replace (set (pc) (return)) with (return).  */	      PATTERN (insn) = body = SET_SRC (body);	    /* Rerecognize the instruction if it has changed.  */	    if (result != 0)	      INSN_CODE (insn) = -1;	  }	/* Make same adjustments to instructions that examine the	   condition codes without jumping (if this machine has them).  */	if (cc_status.flags != 0	    && GET_CODE (body) == SET)	  {	    switch (GET_CODE (SET_SRC (body)))	      {	      case GTU:	      case GT:	      case LTU:	      case LT:	      case GEU:	      case GE:	      case LEU:	      case LE:	      case EQ:	      case NE:		{		  register int result;		  if (XEXP (SET_SRC (body), 0) != cc0_rtx)		    break;		  result = alter_cond (SET_SRC (body));

⌨️ 快捷键说明

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