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

📄 emit-rtl.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 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.   LAST is non-zero if we should return the last insn of the sequence produced.   If this routine succeeds in splitting, it returns the first or last   replacement insn depending on the value of LAST.  Otherwise, it   returns TRIAL.  If the insn to be returned can be split, it will be.  */rtxtry_split (pat, trial, last)     rtx pat, trial;     int last;{  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);	  /* Recursively call try_split for each new insn created; by the	     time control returns here that insn will be fully split, so	     set LAST and continue from the insn after the one returned.	     We can't use next_active_insn here since AFTER may be a note.	     Ignore deleted insns, which can be occur if not optimizing.  */	  for (tem = NEXT_INSN (before); tem != after;	       tem = NEXT_INSN (tem))	    if (! INSN_DELETED_P (tem))	      tem = try_split (PATTERN (tem), tem, 1);	}      /* 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;	  try_split (seq, trial, last);	}      /* Return either the first or the last insn, depending on which was	 requested.  */      return last ? prev_active_insn (after) : next_active_insn (before);    }  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;  /* If in RTL generation phase, see if FREE_INSN can be used.  */  if (free_insn != 0 && rtx_equal_function_value_matters)    {      insn = free_insn;      free_insn = NEXT_INSN (free_insn);      PUT_CODE (insn, INSN);    }  else    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;}/* Like `make_insn' but make a CALL_INSN instead of an insn.  */static rtxmake_call_insn_raw (pattern)     rtx pattern;{  register rtx insn;  insn = rtx_alloc (CALL_INSN);  INSN_UID (insn) = cur_insn_uid++;  PATTERN (insn) = pattern;  INSN_CODE (insn) = -1;  LOG_LINKS (insn) = NULL;  REG_NOTES (insn) = NULL;  CALL_INSN_FUNCTION_USAGE (insn) = NULL;  return insn;}

⌨️ 快捷键说明

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