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

📄 rtlanal.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  if (GET_CODE (PATTERN (insn)) == SET)    {      rtx dest = SET_DEST (PATTERN (insn));       /* A value is totally replaced if it is the destination or the	 destination is a SUBREG of REGNO that does not change the number of	 words in it.  */     if (GET_CODE (dest) == SUBREG	  && (((GET_MODE_SIZE (GET_MODE (dest))		+ UNITS_PER_WORD - 1) / UNITS_PER_WORD)	      == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))		   + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))	dest = SUBREG_REG (dest);      if (GET_CODE (dest) != REG)	return 0;      regno = REGNO (dest);      endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1		  : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));      return (test_regno >= regno && test_regno < endregno);    }  else if (GET_CODE (PATTERN (insn)) == PARALLEL)    {      register int i;      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)	{	  rtx body = XVECEXP (PATTERN (insn), 0, i);	  if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)	    {	      rtx dest = SET_DEST (body);	      if (GET_CODE (dest) == SUBREG		  && (((GET_MODE_SIZE (GET_MODE (dest))			+ UNITS_PER_WORD - 1) / UNITS_PER_WORD)		      == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))			   + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))		dest = SUBREG_REG (dest);	      if (GET_CODE (dest) != REG)		continue;	      regno = REGNO (dest);	      endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1			  : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));	      if (test_regno >= regno && test_regno < endregno)		return 1;	    }	}    }  return 0;}/* Return the reg-note of kind KIND in insn INSN, if there is one.   If DATUM is nonzero, look for one whose datum is DATUM.  */rtxfind_reg_note (insn, kind, datum)     rtx insn;     enum reg_note kind;     rtx datum;{  register rtx link;  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))    if (REG_NOTE_KIND (link) == kind	&& (datum == 0 || datum == XEXP (link, 0)))      return link;  return 0;}/* Return the reg-note of kind KIND in insn INSN which applies to register   number REGNO, if any.  Return 0 if there is no such reg-note.  */rtxfind_regno_note (insn, kind, regno)     rtx insn;     enum reg_note kind;     int regno;{  register rtx link;  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))    if (REG_NOTE_KIND (link) == kind	/* Verify that it is a register, so that scratch and MEM won't cause a	   problem here.  */	&& GET_CODE (XEXP (link, 0)) == REG	&& REGNO (XEXP (link, 0)) == regno)      return link;  return 0;}/* Remove register note NOTE from the REG_NOTES of INSN.  */voidremove_note (insn, note)     register rtx note;     register rtx insn;{  register rtx link;  if (REG_NOTES (insn) == note)    {      REG_NOTES (insn) = XEXP (note, 1);      return;    }  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))    if (XEXP (link, 1) == note)      {	XEXP (link, 1) = XEXP (note, 1);	return;      }  abort ();}/* Nonzero if X contains any volatile memory references   UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions.  */intvolatile_refs_p (x)     rtx x;{  register RTX_CODE code;  code = GET_CODE (x);  switch (code)    {    case LABEL_REF:    case SYMBOL_REF:    case CONST_INT:    case CONST:    case CONST_DOUBLE:    case CC0:    case PC:    case REG:    case SCRATCH:    case CLOBBER:    case ASM_INPUT:    case ADDR_VEC:    case ADDR_DIFF_VEC:      return 0;    case CALL:    case UNSPEC_VOLATILE: /* case TRAP_IF: This isn't clear yet.  */      return 1;    case MEM:    case ASM_OPERANDS:      if (MEM_VOLATILE_P (x))	return 1;    }  /* Recursively scan the operands of this expression.  */  {    register char *fmt = GET_RTX_FORMAT (code);    register int i;        for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)      {	if (fmt[i] == 'e')	  {	    if (volatile_refs_p (XEXP (x, i)))	      return 1;	  }	if (fmt[i] == 'E')	  {	    register int j;	    for (j = 0; j < XVECLEN (x, i); j++)	      if (volatile_refs_p (XVECEXP (x, i, j)))		return 1;	  }      }  }  return 0;}/* Similar to above, except that it also rejects register pre- and post-   incrementing.  */intside_effects_p (x)     rtx x;{  register RTX_CODE code;  code = GET_CODE (x);  switch (code)    {    case LABEL_REF:    case SYMBOL_REF:    case CONST_INT:    case CONST:    case CONST_DOUBLE:    case CC0:    case PC:    case REG:    case SCRATCH:    case ASM_INPUT:    case ADDR_VEC:    case ADDR_DIFF_VEC:      return 0;    case CLOBBER:      /* Reject CLOBBER with a non-VOID mode.  These are made by combine.c	 when some combination can't be done.  If we see one, don't think	 that we can simplify the expression.  */      return (GET_MODE (x) != VOIDmode);    case PRE_INC:    case PRE_DEC:    case POST_INC:    case POST_DEC:    case CALL:    case UNSPEC_VOLATILE: /* case TRAP_IF: This isn't clear yet.  */      return 1;    case MEM:    case ASM_OPERANDS:      if (MEM_VOLATILE_P (x))	return 1;    }  /* Recursively scan the operands of this expression.  */  {    register char *fmt = GET_RTX_FORMAT (code);    register int i;        for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)      {	if (fmt[i] == 'e')	  {	    if (side_effects_p (XEXP (x, i)))	      return 1;	  }	if (fmt[i] == 'E')	  {	    register int j;	    for (j = 0; j < XVECLEN (x, i); j++)	      if (side_effects_p (XVECEXP (x, i, j)))		return 1;	  }      }  }  return 0;}/* Return nonzero if evaluating rtx X might cause a trap.  */intmay_trap_p (x)     rtx x;{  int i;  enum rtx_code code;  char *fmt;  if (x == 0)    return 0;  code = GET_CODE (x);  switch (code)    {      /* Handle these cases quickly.  */    case CONST_INT:    case CONST_DOUBLE:    case SYMBOL_REF:    case LABEL_REF:    case CONST:    case PC:    case CC0:    case REG:    case SCRATCH:      return 0;      /* Conditional trap can trap!  */    case UNSPEC_VOLATILE:    case TRAP_IF:      return 1;      /* Memory ref can trap unless it's a static var or a stack slot.  */    case MEM:      return rtx_addr_can_trap_p (XEXP (x, 0));      /* Division by a non-constant might trap.  */    case DIV:    case MOD:    case UDIV:    case UMOD:      if (! CONSTANT_P (XEXP (x, 1)))	return 1;      /* This was const0_rtx, but by not using that,	 we can link this file into other programs.  */      if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)	return 1;    default:      /* Any floating arithmetic may trap.  */      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)	return 1;    }  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      if (fmt[i] == 'e')	{	  if (may_trap_p (XEXP (x, i)))	    return 1;	}      else if (fmt[i] == 'E')	{	  register int j;	  for (j = 0; j < XVECLEN (x, i); j++)	    if (may_trap_p (XVECEXP (x, i, j)))	      return 1;	}    }  return 0;}/* Return nonzero if X contains a comparison that is not either EQ or NE,   i.e., an inequality.  */intinequality_comparisons_p (x)     rtx x;{  register char *fmt;  register int len, i;  register enum rtx_code code = GET_CODE (x);  switch (code)    {    case REG:    case SCRATCH:    case PC:    case CC0:    case CONST_INT:    case CONST_DOUBLE:    case CONST:    case LABEL_REF:    case SYMBOL_REF:      return 0;    case LT:    case LTU:    case GT:    case GTU:    case LE:    case LEU:    case GE:    case GEU:      return 1;    }  len = GET_RTX_LENGTH (code);  fmt = GET_RTX_FORMAT (code);  for (i = 0; i < len; i++)    {      if (fmt[i] == 'e')	{	  if (inequality_comparisons_p (XEXP (x, i)))	    return 1;	}      else if (fmt[i] == 'E')	{	  register int j;	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)	    if (inequality_comparisons_p (XVECEXP (x, i, j)))	      return 1;	}    }	      return 0;}/* Replace any occurrence of FROM in X with TO.   Note that copying is not done so X must not be shared unless all copies   are to be modified.  */rtxreplace_rtx (x, from, to)     rtx x, from, to;{  register int i, j;  register char *fmt;  if (x == from)    return to;  /* Allow this function to make replacements in EXPR_LISTs.  */  if (x == 0)    return 0;  fmt = GET_RTX_FORMAT (GET_CODE (x));  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)    {      if (fmt[i] == 'e')	XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);      else if (fmt[i] == 'E')	for (j = XVECLEN (x, i) - 1; j >= 0; j--)	  XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);    }  return x;}  /* Throughout the rtx X, replace many registers according to REG_MAP.   Return the replacement for X (which may be X with altered contents).   REG_MAP[R] is the replacement for register R, or 0 for don't replace.   NREGS is the length of REG_MAP; regs >= NREGS are not mapped.     We only support REG_MAP entries of REG or SUBREG.  Also, hard registers   should not be mapped to pseudos or vice versa since validate_change   is not called.   If REPLACE_DEST is 1, replacements are also done in destinations;   otherwise, only sources are replaced.  */rtxreplace_regs (x, reg_map, nregs, replace_dest)     rtx x;     rtx *reg_map;     int nregs;     int replace_dest;{  register enum rtx_code code;  register int i;  register char *fmt;  if (x == 0)    return x;  code = GET_CODE (x);  switch (code)    {    case SCRATCH:    case PC:    case CC0:    case CONST_INT:    case CONST_DOUBLE:    case CONST:    case SYMBOL_REF:    case LABEL_REF:      return x;    case REG:      /* Verify that the register has an entry before trying to access it.  */      if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)	return reg_map[REGNO (x)];      return x;    case SUBREG:      /* Prevent making nested SUBREGs.  */      if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs	  && reg_map[REGNO (SUBREG_REG (x))] != 0	  && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)	{	  rtx map_val = reg_map[REGNO (SUBREG_REG (x))];	  rtx map_inner = SUBREG_REG (map_val);	  if (GET_MODE (x) == GET_MODE (map_inner))	    return map_inner;	  else	    {	      /* We cannot call gen_rtx here since we may be linked with		 genattrtab.c.  */	      /* Let's try clobbering the incoming SUBREG and see		 if this is really safe.  */	      SUBREG_REG (x) = map_inner;	      SUBREG_WORD (x) += SUBREG_WORD (map_val);	      return x;#if 0	      rtx new = rtx_alloc (SUBREG);	      PUT_MODE (new, GET_MODE (x));	      SUBREG_REG (new) = map_inner;	      SUBREG_WORD (new) = SUBREG_WORD (x) + SUBREG_WORD (map_val);#endif	    }	}      break;    case SET:      if (replace_dest)	SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0);      else if (GET_CODE (SET_DEST (x)) == MEM	       || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)	/* Even if we are not to replace destinations, replace register if it	   is CONTAINED in destination (destination is memory or	   STRICT_LOW_PART).  */	XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0),					       reg_map, nregs, 0);      else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)	/* Similarly, for ZERO_EXTRACT we replace all operands.  */	break;      SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0);      return x;    }  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    {      if (fmt[i] == 'e')	XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest);      if (fmt[i] == 'E')	{	  register int j;	  for (j = 0; j < XVECLEN (x, i); j++)	    XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map,					      nregs, replace_dest);	}    }  return x;}

⌨️ 快捷键说明

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