Esempio n. 1
0
File: ree.c Progetto: aixoss/gcc
static bool
transform_ifelse (ext_cand *cand, rtx def_insn)
{
  rtx set_insn = PATTERN (def_insn);
  rtx srcreg, dstreg, srcreg2;
  rtx map_srcreg, map_dstreg, map_srcreg2;
  rtx ifexpr;
  rtx cond;
  rtx new_set;

  gcc_assert (GET_CODE (set_insn) == SET);

  cond = XEXP (SET_SRC (set_insn), 0);
  dstreg = SET_DEST (set_insn);
  srcreg = XEXP (SET_SRC (set_insn), 1);
  srcreg2 = XEXP (SET_SRC (set_insn), 2);
  /* If the conditional move already has the right or wider mode,
     there is nothing to do.  */
  if (GET_MODE_SIZE (GET_MODE (dstreg)) >= GET_MODE_SIZE (cand->mode))
    return true;

  map_srcreg = gen_rtx_REG (cand->mode, REGNO (srcreg));
  map_srcreg2 = gen_rtx_REG (cand->mode, REGNO (srcreg2));
  map_dstreg = gen_rtx_REG (cand->mode, REGNO (dstreg));
  ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2);
  new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr);

  if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)
      && update_reg_equal_equiv_notes (def_insn, cand->mode, GET_MODE (dstreg),
				       cand->code))
    {
      if (dump_file)
        {
          fprintf (dump_file,
		   "Mode of conditional move instruction extended:\n");
          print_rtl_single (dump_file, def_insn);
        }
      return true;
    }

  return false;
}
Esempio n. 2
0
File: lm32.c Progetto: boomeer/gcc
static void
gen_int_relational (enum rtx_code code,	
		    rtx result,	
		    rtx cmp0,	
		    rtx cmp1,	
		    rtx destination)	
{
  machine_mode mode;
  int branch_p;

  mode = GET_MODE (cmp0);
  if (mode == VOIDmode)
    mode = GET_MODE (cmp1);

  /* Is this a branch or compare.  */
  branch_p = (destination != 0);

  /* Instruction set doesn't support LE or LT, so swap operands and use 
     GE, GT.  */
  switch (code)
    {
    case LE:
    case LT:
    case LEU:
    case LTU:
      {
	rtx temp;

	code = swap_condition (code);
	temp = cmp0;
	cmp0 = cmp1;
	cmp1 = temp;
	break;
      }
    default:
      break;
    }

  if (branch_p)
    {
      rtx insn, cond, label;

      /* Operands must be in registers.  */
      if (!register_operand (cmp0, mode))
	cmp0 = force_reg (mode, cmp0);
      if (!register_operand (cmp1, mode))
	cmp1 = force_reg (mode, cmp1);

      /* Generate conditional branch instruction.  */
      cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
      label = gen_rtx_LABEL_REF (VOIDmode, destination);
      insn = gen_rtx_SET (pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode,
							cond, label, pc_rtx));
      emit_jump_insn (insn);
    }
  else
    {
      /* We can't have const_ints in cmp0, other than 0.  */
      if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0))
	cmp0 = force_reg (mode, cmp0);

      /* If the comparison is against an int not in legal range
         move it into a register.  */
      if (GET_CODE (cmp1) == CONST_INT)
	{
	  switch (code)
	    {
	    case EQ:
	    case NE:
	    case LE:
	    case LT:
	    case GE:
	    case GT:
	      if (!satisfies_constraint_K (cmp1))
		cmp1 = force_reg (mode, cmp1);
	      break;
	    case LEU:
	    case LTU:
	    case GEU:
	    case GTU:
	      if (!satisfies_constraint_L (cmp1))
		cmp1 = force_reg (mode, cmp1);
	      break;
	    default:
	      gcc_unreachable ();
	    }
	}

      /* Generate compare instruction.  */
      emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1));
    }
}
void
gen_int_relational (enum rtx_code code, /* relational test (EQ, etc) */
                    rtx result,		/* result to store comp. or 0 if branch */
                    rtx cmp0,		/* first operand to compare */
                    rtx cmp1,		/* second operand to compare */
                    rtx destination)	/* destination of the branch, or 0 if compare */
{
    enum machine_mode mode;
    int branch_p;

    mode = GET_MODE (cmp0);
    if (mode == VOIDmode)
        mode = GET_MODE (cmp1);

    /* Is this a branch or compare */
    branch_p = (destination != 0);

    /* Instruction set doesn't support LE or LT, so swap operands and use GE, GT */
    switch (code)
    {
    case LE:
    case LT:
    case LEU:
    case LTU:
        code = swap_condition (code);
        rtx temp = cmp0;
        cmp0 = cmp1;
        cmp1 = temp;
        break;
    default:
        break;
    }

    if (branch_p)
    {
        rtx insn;

        /* Operands must be in registers */
        if (!register_operand (cmp0, mode))
            cmp0 = force_reg (mode, cmp0);
        if (!register_operand (cmp1, mode))
            cmp1 = force_reg (mode, cmp1);

        /* Generate conditional branch instruction */
        rtx cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
        rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
        insn = gen_rtx_SET (VOIDmode, pc_rtx,
                            gen_rtx_IF_THEN_ELSE (VOIDmode,
                                    cond, label, pc_rtx));
        emit_jump_insn (insn);
    }
    else
    {
        /* We can't have const_ints in cmp0, other than 0 */
        if ((GET_CODE (cmp0) == CONST_INT) && (INTVAL (cmp0) != 0))
            cmp0 = force_reg (mode, cmp0);

        /* If the comparison is against an int not in legal range
           move it into a register */
        if (GET_CODE (cmp1) == CONST_INT)
        {
            HOST_WIDE_INT value = INTVAL (cmp1);
            switch (code)
            {
            case EQ:
            case NE:
            case LE:
            case LT:
            case GE:
            case GT:
                if (!MEDIUM_INT(value))
                    cmp1 = force_reg (mode, cmp1);
                break;
            case LEU:
            case LTU:
            case GEU:
            case GTU:
                if (!MEDIUM_UINT(value))
                    cmp1 = force_reg (mode, cmp1);
                break;
            default:
                abort ();
            }
        }

        /* Generate compare instruction */
        emit_move_insn (result, gen_rtx_fmt_ee (code, mode, cmp0, cmp1));
    }
}