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

📄 emit-rtl.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{  first_insn = first;  last_insn = last;}/* Go through all the RTL insn bodies and copy any invalid shared structure.   It does not work to do this twice, because the mark bits set here   are not cleared afterwards.  */static int unshare_copies = 0;	/* Count rtx's that were copied.  */static rtx copy_rtx_if_shared ();voidunshare_all_rtl (insn)     register rtx insn;{  extern rtx stack_slot_list;  for (; insn; insn = NEXT_INSN (insn))    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN	|| GET_CODE (insn) == CALL_INSN)      {	PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));	REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));	LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));      }  /* Make sure the addresses of stack slots are not shared     with anything in the insn chain.  That could happen if     the stack slot is referenced only by its address.  */  copy_rtx_if_shared (stack_slot_list);}/* Mark ORIG as in use, and return a copy of it if it was already in use.   Recursively does the same for subexpressions.  */static rtxcopy_rtx_if_shared (orig)     rtx orig;{  register rtx x = orig;  register int i;  register enum rtx_code code;  register char *format_ptr;  int copied = 0;  if (x == 0)    return 0;  code = GET_CODE (x);  /* These types may be freely shared.  */  switch (code)    {    case REG:    case QUEUED:    case CONST_INT:    case CONST_DOUBLE:    case SYMBOL_REF:    case CODE_LABEL:    case PC:    case CC0:      return x;    case INSN:    case JUMP_INSN:    case CALL_INSN:    case NOTE:    case LABEL_REF:    case BARRIER:      /* The chain of insns is not being copied.  */      return x;    case MEM:      /* A MEM is allowed to be shared if its address is constant	 or is a constant plus one of the special registers.  */      if (CONSTANT_ADDRESS_P (XEXP (x, 0)))	return x;      if (GET_CODE (XEXP (x, 0)) == PLUS	  && (XEXP (XEXP (x, 0), 0) == frame_pointer_rtx	      || XEXP (XEXP (x, 0), 0) == arg_pointer_rtx)	  && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))	{	  /* This MEM can appear in more than one place,	     but its address better not be shared with anything else.  */	  if (! x->used)	    XEXP (x, 0) = copy_rtx_if_shared (XEXP (x, 0));	  x->used = 1;	  return x;	}      if (XEXP (x, 0) == frame_pointer_rtx	  || XEXP (x, 0) == arg_pointer_rtx)	return x;    }  /* This rtx may not be shared.  If it has already been seen,     replace it with a copy of itself.  */  if (x->used)    {      register rtx copy;      unshare_copies++;      copy = rtx_alloc (code);      bcopy (x, copy, (sizeof (*copy) - sizeof (copy->fld)		       + sizeof (copy->fld[0]) * GET_RTX_LENGTH (code)));      x = copy;      copied = 1;    }  x->used = 1;  /* Now scan the subexpressions recursively.     We can store any replaced subexpressions directly into X     since we know X is not shared!  Any vectors in X     must be copied if X was copied.  */  format_ptr = GET_RTX_FORMAT (code);  for (i = 0; i < GET_RTX_LENGTH (code); i++)    {      switch (*format_ptr++)	{	case 'e':	  XEXP (x, i) = copy_rtx_if_shared (XEXP (x, i));	  break;	case 'E':	  if (XVEC (x, i) != NULL)	    {	      register int j;	      if (copied)		XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), &XVECEXP (x, i, 0));	      for (j = 0; j < XVECLEN (x, i); j++)		XVECEXP (x, i, j)		  = copy_rtx_if_shared (XVECEXP (x, i, j));	    }	  break;	}    }  return x;}/* Copy X if necessary so that it won't be altered by changes in OTHER.   Return X or the rtx for the pseudo reg the value of X was copied into.   OTHER must be valid as a SET_DEST.  */rtxmake_safe_from (x, other)     rtx x, other;{  while (1)    switch (GET_CODE (other))      {      case SUBREG:	other = SUBREG_REG (other);	break;      case STRICT_LOW_PART:      case SIGN_EXTEND:      case ZERO_EXTEND:	other = XEXP (other, 0);	break;      default:	goto done;      } done:  if ((GET_CODE (other) == MEM       && ! CONSTANT_P (x)       && GET_CODE (x) != CONST_DOUBLE       && GET_CODE (x) != REG       && GET_CODE (x) != SUBREG)      || (GET_CODE (other) == REG	  && (REGNO (other) < FIRST_PSEUDO_REGISTER	      || reg_mentioned_p (other, x))))    {      rtx temp = gen_reg_rtx (GET_MODE (x));      emit_move_insn (temp, x);      return temp;    }  return x;}/* Emission of insns (adding them to the doubly-linked list).  *//* Return the first insn of the current sequence or current function.  */rtxget_insns (){  return first_insn;}/* Return the last insn emitted in current sequence or current function.  */rtxget_last_insn (){  return last_insn;}/* Specify a new insn as the last in the chain.  */voidset_last_insn (insn)     rtx insn;{  if (NEXT_INSN (insn) != 0)    abort ();  last_insn = insn;}/* Return a number larger than any instruction's uid in this function.  */intget_max_uid (){  return cur_insn_uid;}rtxnext_insn (insn)     rtx insn;{  if (insn) return NEXT_INSN (insn);  return 0;}rtxprevious_insn (insn)     rtx insn;{  if (insn) return PREV_INSN (insn);  return 0;}/* Make and return an INSN rtx, initializing all its slots.   Store PATTERN in the pattern slots.   PAT_FORMALS is an idea that never really went anywhere.  */static rtxmake_insn_raw (pattern, pat_formals)     rtx pattern;     rtvec pat_formals;{  register rtx insn;  insn = rtx_alloc(INSN);  INSN_UID(insn) = cur_insn_uid++;  PATTERN (insn) = pattern;  INSN_CODE (insn) = -1;  LOG_LINKS(insn) = NULL;  REG_NOTES(insn) = NULL;  return insn;}/* Like `make_insn' but make a JUMP_INSN instead of an insn.  */static rtxmake_jump_insn_raw (pattern, pat_formals)     rtx pattern;     rtvec pat_formals;{  register rtx insn;  insn = rtx_alloc(JUMP_INSN);  INSN_UID(insn) = cur_insn_uid++;  PATTERN (insn) = pattern;  INSN_CODE (insn) = -1;  LOG_LINKS(insn) = NULL;  REG_NOTES(insn) = NULL;  JUMP_LABEL(insn) = NULL;  return insn;}/* Add INSN to the end of the doubly-linked list.   INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */static voidadd_insn (insn)     register rtx insn;{  PREV_INSN (insn) = last_insn;  NEXT_INSN (insn) = 0;  if (NULL != last_insn)    NEXT_INSN (last_insn) = insn;  if (NULL == first_insn)    first_insn = insn;  last_insn = insn;}/* Add INSN, an rtx of code INSN, into the doubly-linked list   after insn AFTER.  */static voidadd_insn_after (insn, after)     rtx insn, after;{  NEXT_INSN (insn) = NEXT_INSN (after);  PREV_INSN (insn) = after;  if (NEXT_INSN (insn))    PREV_INSN (NEXT_INSN (insn)) = insn;  else if (last_insn == after)    last_insn = insn;  else    {      rtx stack = sequence_stack;      /* Scan all pending sequences too.  */      for (; stack; stack = XEXP (XEXP (stack, 1), 1))	if (after == XEXP (XEXP (stack, 1), 0))	  XEXP (XEXP (stack, 1), 0) = insn;    }  NEXT_INSN (after) = insn;}/* Delete all insns made since FROM.   FROM becomes the new last instruction.  */voiddelete_insns_since (from)     rtx from;{  if (from == 0)    first_insn = 0;  else    NEXT_INSN (from) = 0;  last_insn = from;}/* Move a consecutive bunch of insns to a different place in the chain.   The insns to be moved are those between FROM and TO.   They are moved to a new position after the insn AFTER.  */voidreorder_insns (from, to, after)     rtx from, to, after;{  /* Splice this bunch out of where it is now.  */  if (PREV_INSN (from))    NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);  if (NEXT_INSN (to))    PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);  if (last_insn == to)    last_insn = PREV_INSN (from);  if (first_insn == from)    first_insn = NEXT_INSN (to);  /* Make the new neighbors point to it and it to them.  */  if (NEXT_INSN (after))    {      PREV_INSN (NEXT_INSN (after)) = to;      NEXT_INSN (to) = NEXT_INSN (after);    }  PREV_INSN (from) = after;  NEXT_INSN (after) = from;  if (after == last_insn)    last_insn = to;}/* Emit an insn of given code and pattern   at a specified place within the doubly-linked list.  *//* Make an instruction with body PATTERN   and output it before the instruction BEFORE.  */rtxemit_insn_before (pattern, before)     register rtx pattern, before;{  register rtx insn;  if (GET_CODE (pattern) == SEQUENCE)    {      register int i;      /* For an empty sequence, emit nothing.  */      if (XVEC (pattern, 0))	for (i = 0; i < XVECLEN (pattern, 0); i++)	  add_insn_after (XVECEXP (pattern, 0, i), PREV_INSN (before));      return PREV_INSN (before);    }  insn = make_insn_raw (pattern, 0);  PREV_INSN (insn) = PREV_INSN (before);  NEXT_INSN (insn) = before;  if (PREV_INSN (insn))    NEXT_INSN (PREV_INSN (insn)) = insn;  else    first_insn = insn;  PREV_INSN (before) = insn;  return insn;}/* Make an instruction with body PATTERN and code JUMP_INSN   and output it before the instruction BEFORE.  */rtxemit_jump_insn_before (pattern, before)     register rtx pattern, before;{  register rtx insn = make_jump_insn_raw (pattern, 0);  PREV_INSN (insn) = PREV_INSN (before);  NEXT_INSN (insn) = before;  if (PREV_INSN (insn))    NEXT_INSN (PREV_INSN (insn)) = insn;  else    first_insn = insn;  PREV_INSN (before) = insn;  return insn;}/* Make an instruction with body PATTERN and code CALL_INSN   and output it before the instruction BEFORE.  */rtxemit_call_insn_before (pattern, before)     register rtx pattern, before;{  rtx insn = emit_insn_before (pattern, before);  PUT_CODE (insn, CALL_INSN);  return insn;}/* Make an insn of code INSN with body PATTERN   and output it after the insn AFTER.  */rtxemit_insn_after (pattern, after)     register rtx pattern, after;{  if (GET_CODE (pattern) == SEQUENCE)    {      register int i;      /* For an empty sequence, emit nothing.  */      if (XVEC (pattern, 0))	for (i = 0; i < XVECLEN (pattern, 0); i++)	  {	    add_insn_after (XVECEXP (pattern, 0, i), after);	    after = NEXT_INSN (after);	  }      return after;    }  else    {      register rtx insn = make_insn_raw (pattern, 0);      add_insn_after (insn, after);      return insn;    }}/* Make an insn of code JUMP_INSN with body PATTERN   and output it after the insn AFTER.  */rtxemit_jump_insn_after (pattern, after)     register rtx pattern, after;{  register rtx insn = make_jump_insn_raw (pattern, 0);  add_insn_after (insn, after);  return insn;}/* Make an insn of code BARRIER   and output it after the insn AFTER.  */rtxemit_barrier_after (after)     register rtx after;{  register rtx insn = rtx_alloc (BARRIER);  INSN_UID (insn) = cur_insn_uid++;  add_insn_after (insn, after);  return insn;}/* Emit the label LABEL after the insn AFTER.  */voidemit_label_after (label, after)     rtx label, after;{  /* This can be called twice for the same label     as a result of the confusion that follows a syntax error!     So make it harmless.  */  if (INSN_UID (label) == 0)    {      INSN_UID (label) = cur_insn_uid++;      add_insn_after (label, after);    }}/* Emit a note of subtype SUBTYPE after the insn AFTER.  */voidemit_note_after (subtype, after)     int subtype;     rtx after;{  register rtx note = rtx_alloc (NOTE);  INSN_UID (note) = cur_insn_uid++;  XSTR (note, 3) = 0;  XINT (note, 4) = subtype;  add_insn_after (note, after);}/* Make an insn of code INSN with pattern PATTERN   and add it to the end of the doubly-linked list.   If PATTERN is a SEQUENCE, take the elements of it   and emit an insn for each element.   Returns the last insn emitted.  */rtxemit_insn (pattern)     rtx pattern;{  rtx insn;  if (GET_CODE (pattern) == SEQUENCE)    {      register int i;      /* For an empty sequence, emit nothing.  */      if (XVEC (pattern, 0))	for (i = 0; i < XVECLEN (pattern, 0); i++)	  add_insn (insn = XVECEXP (pattern, 0, i));    }  else    {

⌨️ 快捷键说明

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