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

📄 emit-rtl.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
     struct function *p;{  p->reg_rtx_no = reg_rtx_no;  p->first_label_num = first_label_num;  p->first_insn = first_insn;  p->last_insn = last_insn;  p->sequence_rtl_expr = sequence_rtl_expr;  p->sequence_stack = sequence_stack;  p->cur_insn_uid = cur_insn_uid;  p->last_linenum = last_linenum;  p->last_filename = last_filename;  p->regno_pointer_flag = regno_pointer_flag;  p->regno_pointer_flag_length = regno_pointer_flag_length;  p->regno_reg_rtx = regno_reg_rtx;}/* Restore all variables describing the current status from the structure *P.   This is used after a nested function.  */voidrestore_emit_status (p)     struct function *p;{  int i;  reg_rtx_no = p->reg_rtx_no;  first_label_num = p->first_label_num;  last_label_num = 0;  first_insn = p->first_insn;  last_insn = p->last_insn;  sequence_rtl_expr = p->sequence_rtl_expr;  sequence_stack = p->sequence_stack;  cur_insn_uid = p->cur_insn_uid;  last_linenum = p->last_linenum;  last_filename = p->last_filename;  regno_pointer_flag = p->regno_pointer_flag;  regno_pointer_flag_length = p->regno_pointer_flag_length;  regno_reg_rtx = p->regno_reg_rtx;  /* Clear our cache of rtx expressions for start_sequence and gen_sequence. */  sequence_element_free_list = 0;  for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)    sequence_result[i] = 0;}/* 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.  */voidunshare_all_rtl (insn)     register rtx insn;{  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 found outside the insn chain     (such as, in DECL_RTL of a variable) are not shared     with the insn chain.     This special care is necessary when the stack slot MEM does not     actually appear in the insn chain.  If it does appear, its address     is unshared from all else at that point.  */  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.  */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:    case SCRATCH:      /* SCRATCH must be shared because they represent distinct values. */      return x;    case CONST:      /* CONST can be shared if it contains a SYMBOL_REF.  If it contains	 a LABEL_REF, it isn't sharable.  */      if (GET_CODE (XEXP (x, 0)) == PLUS	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)	return x;      break;    case INSN:    case JUMP_INSN:    case CALL_INSN:    case NOTE:    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))	  || XEXP (x, 0) == virtual_stack_vars_rtx	  || XEXP (x, 0) == virtual_incoming_args_rtx)	return x;      if (GET_CODE (XEXP (x, 0)) == PLUS	  && (XEXP (XEXP (x, 0), 0) == virtual_stack_vars_rtx	      || XEXP (XEXP (x, 0), 0) == virtual_incoming_args_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;	}    }  /* 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;      copy = rtx_alloc (code);      bcopy ((char *) x, (char *) 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;	      int len = XVECLEN (x, i);	      if (copied && len > 0)		XVEC (x, i) = gen_rtvec_v (len, &XVECEXP (x, i, 0));	      for (j = 0; j < len; j++)		XVECEXP (x, i, j) = copy_rtx_if_shared (XVECEXP (x, i, j));	    }	  break;	}    }  return x;}/* Clear all the USED bits in X to allow copy_rtx_if_shared to be used   to look for shared sub-parts.  */voidreset_used_flags (x)     rtx x;{  register int i, j;  register enum rtx_code code;  register char *format_ptr;  if (x == 0)    return;  code = GET_CODE (x);  /* These types may be freely shared so we needn't do any resetting     for them.  */  switch (code)    {    case REG:    case QUEUED:    case CONST_INT:    case CONST_DOUBLE:    case SYMBOL_REF:    case CODE_LABEL:    case PC:    case CC0:      return;    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->used = 0;  format_ptr = GET_RTX_FORMAT (code);  for (i = 0; i < GET_RTX_LENGTH (code); i++)    {      switch (*format_ptr++)	{	case 'e':	  reset_used_flags (XEXP (x, i));	  break;	case 'E':	  for (j = 0; j < XVECLEN (x, i); j++)	    reset_used_flags (XVECEXP (x, i, j));	  break;	}    }}/* 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) != 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 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

⌨️ 快捷键说明

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