Пример #1
0
static void
find_flags_uses_in_insn (struct comparison *cmp, rtx_insn *insn)
{
  df_ref use;

  /* If we've already lost track of uses, don't bother collecting more.  */
  if (cmp->missing_uses)
    return;

  /* Find a USE of the flags register.  */
  FOR_EACH_INSN_USE (use, insn)
    if (DF_REF_REGNO (use) == targetm.flags_regnum)
      {
	rtx x, *loc;

	/* If this is an unusual use, quit.  */
	if (DF_REF_TYPE (use) != DF_REF_REG_USE)
	  goto fail;

	/* If we've run out of slots to record uses, quit.  */
	if (cmp->n_uses == MAX_CMP_USE)
	  goto fail;

	/* Unfortunately the location of the flags register, while present
	   in the reference structure, doesn't help.  We need to find the
	   comparison code that is outer to the actual flags use.  */
	loc = DF_REF_LOC (use);
	x = PATTERN (insn);
	if (GET_CODE (x) == PARALLEL)
	  x = XVECEXP (x, 0, 0);
	x = SET_SRC (x);
	if (GET_CODE (x) == IF_THEN_ELSE)
	  x = XEXP (x, 0);
	if (COMPARISON_P (x)
	    && loc == &XEXP (x, 0)
	    && XEXP (x, 1) == const0_rtx)
	  {
	    /* We've found a use of the flags that we understand.  */
	    struct comparison_use *cuse = &cmp->uses[cmp->n_uses++];
	    cuse->insn = insn;
	    cuse->loc = loc;
	    cuse->code = GET_CODE (x);
	  }
	else
	  goto fail;
      }
  return;

 fail:
  /* We failed to recognize this use of the flags register.  */
  cmp->missing_uses = true;
}
Пример #2
0
rtx
compare_from_rtx (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
                  enum machine_mode mode, rtx size)
{
  rtx tem;

  /* If one operand is constant, make it the second one.  Only do this
     if the other operand is not constant as well.  */

  if (swap_commutative_operands_p (op0, op1))
    {
      tem = op0;
      op0 = op1;
      op1 = tem;
      code = swap_condition (code);
    }

  do_pending_stack_adjust ();

  code = unsignedp ? unsigned_condition (code) : code;
  tem = simplify_relational_operation (code, VOIDmode, mode, op0, op1);
  if (tem)
    {
      if (CONSTANT_P (tem))
        return tem;

      if (COMPARISON_P (tem))
        {
          code = GET_CODE (tem);
          op0 = XEXP (tem, 0);
          op1 = XEXP (tem, 1);
          mode = GET_MODE (op0);
          unsignedp = (code == GTU || code == LTU
                       || code == GEU || code == LEU);
        }
    }

  emit_cmp_insn (op0, op1, code, size, mode, unsignedp);

#if HAVE_cc0
  return gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
#else
  return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
#endif
}