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

📄 emit-rtl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (NEXT_INSN (insn) != 0)    abort ();  last_insn = insn;}/* Return the last insn emitted, even if it is in a sequence now pushed.  */rtxget_last_insn_anywhere (){  struct sequence_stack *stack;  if (last_insn)    return last_insn;  for (stack = sequence_stack; stack; stack = stack->next)    if (stack->last != 0)      return stack->last;  return 0;}/* Return a number larger than any instruction's uid in this function.  */intget_max_uid (){  return cur_insn_uid;}/* Return the next insn.  If it is a SEQUENCE, return the first insn   of the sequence.  */rtxnext_insn (insn)     rtx insn;{  if (insn)    {      insn = NEXT_INSN (insn);      if (insn && GET_CODE (insn) == INSN	  && GET_CODE (PATTERN (insn)) == SEQUENCE)	insn = XVECEXP (PATTERN (insn), 0, 0);    }  return insn;}/* Return the previous insn.  If it is a SEQUENCE, return the last insn   of the sequence.  */rtxprevious_insn (insn)     rtx insn;{  if (insn)    {      insn = PREV_INSN (insn);      if (insn && GET_CODE (insn) == INSN	  && GET_CODE (PATTERN (insn)) == SEQUENCE)	insn = XVECEXP (PATTERN (insn), 0, XVECLEN (PATTERN (insn), 0) - 1);    }  return insn;}/* Return the next insn after INSN that is not a NOTE.  This routine does not   look inside SEQUENCEs.  */rtxnext_nonnote_insn (insn)     rtx insn;{  while (insn)    {      insn = NEXT_INSN (insn);      if (insn == 0 || GET_CODE (insn) != NOTE)	break;    }  return insn;}/* Return the previous insn before INSN that is not a NOTE.  This routine does   not look inside SEQUENCEs.  */rtxprev_nonnote_insn (insn)     rtx insn;{  while (insn)    {      insn = PREV_INSN (insn);      if (insn == 0 || GET_CODE (insn) != NOTE)	break;    }  return insn;}/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;   or 0, if there is none.  This routine does not look inside   SEQUENCEs. */rtxnext_real_insn (insn)     rtx insn;{  while (insn)    {      insn = NEXT_INSN (insn);      if (insn == 0 || GET_CODE (insn) == INSN	  || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)	break;    }  return insn;}/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;   or 0, if there is none.  This routine does not look inside   SEQUENCEs.  */rtxprev_real_insn (insn)     rtx insn;{  while (insn)    {      insn = PREV_INSN (insn);      if (insn == 0 || GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN	  || GET_CODE (insn) == JUMP_INSN)	break;    }  return insn;}/* Find the next insn after INSN that really does something.  This routine   does not look inside SEQUENCEs.  Until reload has completed, this is the   same as next_real_insn.  */rtxnext_active_insn (insn)     rtx insn;{  while (insn)    {      insn = NEXT_INSN (insn);      if (insn == 0	  || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN	  || (GET_CODE (insn) == INSN	      && (! reload_completed		  || (GET_CODE (PATTERN (insn)) != USE		      && GET_CODE (PATTERN (insn)) != CLOBBER))))	break;    }  return insn;}/* Find the last insn before INSN that really does something.  This routine   does not look inside SEQUENCEs.  Until reload has completed, this is the   same as prev_real_insn.  */rtxprev_active_insn (insn)     rtx insn;{  while (insn)    {      insn = PREV_INSN (insn);      if (insn == 0	  || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN	  || (GET_CODE (insn) == INSN	      && (! reload_completed		  || (GET_CODE (PATTERN (insn)) != USE		      && GET_CODE (PATTERN (insn)) != CLOBBER))))	break;    }  return insn;}/* Return the next CODE_LABEL after the insn INSN, or 0 if there is none.  */rtxnext_label (insn)     rtx insn;{  while (insn)    {      insn = NEXT_INSN (insn);      if (insn == 0 || GET_CODE (insn) == CODE_LABEL)	break;    }  return insn;}/* Return the last CODE_LABEL before the insn INSN, or 0 if there is none.  */rtxprev_label (insn)     rtx insn;{  while (insn)    {      insn = PREV_INSN (insn);      if (insn == 0 || GET_CODE (insn) == CODE_LABEL)	break;    }  return insn;}#ifdef HAVE_cc0/* INSN uses CC0 and is being moved into a delay slot.  Set up REG_CC_SETTER   and REG_CC_USER notes so we can find it.  */voidlink_cc0_insns (insn)     rtx insn;{  rtx user = next_nonnote_insn (insn);  if (GET_CODE (user) == INSN && GET_CODE (PATTERN (user)) == SEQUENCE)    user = XVECEXP (PATTERN (user), 0, 0);  REG_NOTES (user) = gen_rtx (INSN_LIST, REG_CC_SETTER, insn,			      REG_NOTES (user));  REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_CC_USER, user, REG_NOTES (insn));}/* Return the next insn that uses CC0 after INSN, which is assumed to   set it.  This is the inverse of prev_cc0_setter (i.e., prev_cc0_setter   applied to the result of this function should yield INSN).   Normally, this is simply the next insn.  However, if a REG_CC_USER note   is present, it contains the insn that uses CC0.   Return 0 if we can't find the insn.  */rtxnext_cc0_user (insn)     rtx insn;{  rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX);  if (note)    return XEXP (note, 0);  insn = next_nonnote_insn (insn);  if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)    insn = XVECEXP (PATTERN (insn), 0, 0);  if (insn && GET_RTX_CLASS (GET_CODE (insn)) == 'i'      && reg_mentioned_p (cc0_rtx, PATTERN (insn)))    return insn;  return 0;}/* Find the insn that set CC0 for INSN.  Unless INSN has a REG_CC_SETTER   note, it is the previous insn.  */rtxprev_cc0_setter (insn)     rtx insn;{  rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);  rtx link;  if (note)    return XEXP (note, 0);  insn = prev_nonnote_insn (insn);  if (! sets_cc0_p (PATTERN (insn)))    abort ();  return insn;}#endif/* Try splitting insns that can be split for better scheduling.   PAT is the pattern which might split.   TRIAL is the insn providing PAT.   BACKWARDS is non-zero if we are scanning insns from last to first.   If this routine succeeds in splitting, it returns the first or last   replacement insn depending on the value of BACKWARDS.  Otherwise, it   returns TRIAL.  If the insn to be returned can be split, it will be.  */rtxtry_split (pat, trial, backwards)     rtx pat, trial;     int backwards;{  rtx before = PREV_INSN (trial);  rtx after = NEXT_INSN (trial);  rtx seq = split_insns (pat, trial);  int has_barrier = 0;  rtx tem;  /* If we are splitting a JUMP_INSN, it might be followed by a BARRIER.     We may need to handle this specially.  */  if (after && GET_CODE (after) == BARRIER)    {      has_barrier = 1;      after = NEXT_INSN (after);    }  if (seq)    {      /* SEQ can either be a SEQUENCE or the pattern of a single insn.	 The latter case will normally arise only when being done so that	 it, in turn, will be split (SFmode on the 29k is an example).  */      if (GET_CODE (seq) == SEQUENCE)	{	  /* If we are splitting a JUMP_INSN, look for the JUMP_INSN in	     SEQ and copy our JUMP_LABEL to it.  If JUMP_LABEL is non-zero,	     increment the usage count so we don't delete the label.  */	  int i;	  if (GET_CODE (trial) == JUMP_INSN)	    for (i = XVECLEN (seq, 0) - 1; i >= 0; i--)	      if (GET_CODE (XVECEXP (seq, 0, i)) == JUMP_INSN)		{		  JUMP_LABEL (XVECEXP (seq, 0, i)) = JUMP_LABEL (trial);		  if (JUMP_LABEL (trial))		    LABEL_NUSES (JUMP_LABEL (trial))++;		}	  tem = emit_insn_after (seq, before);	  delete_insn (trial);	  if (has_barrier)	    emit_barrier_after (tem);	}      /* Avoid infinite loop if the result matches the original pattern.  */      else if (rtx_equal_p (seq, pat))	return trial;      else	{	  PATTERN (trial) = seq;	  INSN_CODE (trial) = -1;	}      /* Set TEM to the insn we should return.  */      tem = backwards ? prev_active_insn (after) : next_active_insn (before);      return try_split (PATTERN (tem), tem, backwards);    }  return trial;}/* Make and return an INSN rtx, initializing all its slots.   Store PATTERN in the pattern slots.  */rtxmake_insn_raw (pattern)     rtx pattern;{  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)     rtx pattern;{  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.  */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 into the doubly-linked list after insn AFTER.  This should be the   only function called to insert an insn once delay slots have been filled   since only it knows how to update a SEQUENCE.  */voidadd_insn_after (insn, after)     rtx insn, after;{  rtx next = NEXT_INSN (after);  NEXT_INSN (insn) = next;  PREV_INSN (insn) = after;  if (next)    {      PREV_INSN (next) = insn;      if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;    }  else if (last_insn == after)    last_insn = insn;  else    {      struct sequence_stack *stack = sequence_stack;      /* Scan all pending sequences too.  */      for (; stack; stack = stack->next)	if (after == stack->last)	  stack->last = insn;    }  NEXT_INSN (after) = insn;  if (GET_CODE (after) == INSN && GET_CODE (PATTERN (after)) == SEQUENCE)    {      rtx sequence = PATTERN (after);      NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = 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.   AFTER must not be FROM or TO or any insn in between.   This function does not know about SEQUENCEs and hence should not be   called after delay-slot filling has been done.  */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;

⌨️ 快捷键说明

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