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; }
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)); } }