{
register rtx t0 = gen_reg_rtx (wider_mode);
register rtx t1 = gen_reg_rtx (wider_mode);
+ rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
+ rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
- if (expand_twoval_binop (binoptab,
- convert_modes (wider_mode, mode, op0,
- unsignedp),
- convert_modes (wider_mode, mode, op1,
- unsignedp),
+ if (expand_twoval_binop (binoptab, cop0, cop1,
t0, t1, unsignedp))
{
convert_move (targ0, t0, unsignedp);
into a MEM later. Protect the libcall block from this change. */
if (! REG_P (target) || REG_USERVAR_P (target))
target = gen_reg_rtx (GET_MODE (target));
-
+
+ /* If we're using non-call exceptions, a libcall corresponding to an
+ operation that may trap may also trap. */
+ if (flag_non_call_exceptions && may_trap_p (equiv))
+ {
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+
+ if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
+ remove_note (insn, note);
+ }
+ }
+ else
/* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
reg note to indicate that this call cannot throw or execute a nonlocal
goto (unless there is already a REG_EH_REGION note, in which case
- we update it). Also set the CONST_CALL_P flag. */
-
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CALL_INSN)
- {
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
- CONST_CALL_P (insn) = 1;
- if (note != 0)
- XEXP (note, 0) = GEN_INT (-1);
- else
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
- REG_NOTES (insn));
- }
+ we update it). */
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+
+ if (note != 0)
+ XEXP (note, 0) = GEN_INT (-1);
+ else
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
+ REG_NOTES (insn));
+ }
/* First emit all insns that set pseudos. Remove them from the list as
we go. Avoid insns that set pseudos which were referenced in previous
unsigned int align;
rtx label;
{
- rtx op0;
- rtx op1;
-
- if ((CONSTANT_P (x) && ! CONSTANT_P (y))
- || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
+ rtx op0 = x, op1 = y;
+
+ /* Swap operands and condition to ensure canonical RTL. */
+ if (swap_commutative_operands_p (x, y))
{
- /* Swap operands and condition to ensure canonical RTL. */
- op0 = y;
- op1 = x;
+ /* If we're not emitting a branch, this means some caller
+ is out of sync. */
+ if (! label)
+ abort ();
+
+ op0 = y, op1 = x;
comparison = swap_condition (comparison);
}
- else
- {
- op0 = x;
- op1 = y;
- }
#ifdef HAVE_cc0
/* If OP0 is still a constant, then both X and Y must be constants. Force
{
rtx tem, subtarget, comparison, insn;
enum insn_code icode;
+ enum rtx_code reversed;
/* If one operand is constant, make it the second one. Only do this
if the other operand is not constant as well. */
- if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
- || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
+ if (swap_commutative_operands_p (op0, op1))
{
tem = op0;
op0 = op1;
if (cmode == VOIDmode)
cmode = GET_MODE (op0);
- if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
- || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
- && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
- || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
- || flag_unsafe_math_optimizations))
+ if (swap_commutative_operands_p (op2, op3)
+ && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
+ != UNKNOWN))
{
tem = op2;
op2 = op3;
op3 = tem;
- code = reverse_condition (code);
+ code = reversed;
}
if (mode == VOIDmode)
}
int
-have_add2_insn (mode)
- enum machine_mode mode;
+have_add2_insn (x, y)
+ rtx x, y;
{
- return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
+ int icode;
+
+ if (GET_MODE (x) == VOIDmode)
+ abort ();
+
+ icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
+
+ if (icode == CODE_FOR_nothing)
+ return 0;
+
+ if (! ((*insn_data[icode].operand[0].predicate)
+ (x, insn_data[icode].operand[0].mode))
+ || ! ((*insn_data[icode].operand[1].predicate)
+ (x, insn_data[icode].operand[1].mode))
+ || ! ((*insn_data[icode].operand[2].predicate)
+ (y, insn_data[icode].operand[2].mode)))
+ return 0;
+
+ return 1;
}
/* Generate and return an insn body to subtract Y from X. */
}
int
-have_sub2_insn (mode)
- enum machine_mode mode;
+have_sub2_insn (x, y)
+ rtx x, y;
{
- return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
+ int icode;
+
+ if (GET_MODE (x) == VOIDmode)
+ abort ();
+
+ icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
+
+ if (icode == CODE_FOR_nothing)
+ return 0;
+
+ if (! ((*insn_data[icode].operand[0].predicate)
+ (x, insn_data[icode].operand[0].mode))
+ || ! ((*insn_data[icode].operand[1].predicate)
+ (x, insn_data[icode].operand[1].mode))
+ || ! ((*insn_data[icode].operand[2].predicate)
+ (y, insn_data[icode].operand[2].mode)))
+ return 0;
+
+ return 1;
}
/* Generate the body of an instruction to copy Y into X.
x = gen_lowpart_common (tmode, x1);
if (x == 0 && GET_CODE (x1) == MEM)
{
- x = gen_rtx_MEM (tmode, XEXP (x1, 0));
- MEM_COPY_ATTRIBUTES (x, x1);
+ x = adjust_address_nv (x1, tmode, 0);
copy_replacements (x1, x);
}
y = gen_lowpart_common (tmode, y1);
if (y == 0 && GET_CODE (y1) == MEM)
{
- y = gen_rtx_MEM (tmode, XEXP (y1, 0));
- MEM_COPY_ATTRIBUTES (y, y1);
+ y = adjust_address_nv (y1, tmode, 0);
copy_replacements (y1, y);
}
}
enum machine_mode to_mode, from_mode;
int unsignedp;
{
- return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
+#ifdef HAVE_ptr_extend
+ if (unsignedp < 0)
+ return CODE_FOR_ptr_extend;
+ else
+#endif
+ return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
}
/* Generate the body of an insn to extend Y (with mode MFROM)
cbranch_optab = init_optab (UNKNOWN);
cmov_optab = init_optab (UNKNOWN);
cstore_optab = init_optab (UNKNOWN);
+ push_optab = init_optab (UNKNOWN);
for (i = 0; i < NUM_MACHINE_MODES; i++)
{