{
enum insn_code icode;
rtx target = to;
+ scalar_mode from_mode, to_mode;
machine_mode fmode, imode;
bool can_do_signed = false;
/* Unsigned integer, and no way to convert directly. Convert as signed,
then unconditionally adjust the result. */
- if (unsignedp && can_do_signed)
+ if (unsignedp
+ && can_do_signed
+ && is_a <scalar_mode> (GET_MODE (to), &to_mode)
+ && is_a <scalar_mode> (GET_MODE (from), &from_mode))
{
rtx_code_label *label = gen_label_rtx ();
rtx temp;
least as wide as the target. Using FMODE will avoid rounding woes
with unsigned values greater than the signed maximum value. */
- FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
- if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
- && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
+ FOR_EACH_MODE_FROM (fmode, to_mode)
+ if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
+ && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
break;
if (fmode == VOIDmode)
{
/* There is no such mode. Pretend the target is wide enough. */
- fmode = GET_MODE (to);
+ fmode = to_mode;
/* Avoid double-rounding when TO is narrower than FROM. */
if ((significand_size (fmode) + 1)
- < GET_MODE_PRECISION (GET_MODE (from)))
+ < GET_MODE_PRECISION (from_mode))
{
rtx temp1;
rtx_code_label *neglabel = gen_label_rtx ();
|| GET_MODE (target) != fmode)
target = gen_reg_rtx (fmode);
- imode = GET_MODE (from);
+ imode = from_mode;
do_pending_stack_adjust ();
/* Test whether the sign bit is set. */
/* If we are about to do some arithmetic to correct for an
unsigned operand, do it in a pseudo-register. */
- if (GET_MODE (to) != fmode
+ if (to_mode != fmode
|| !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
target = gen_reg_rtx (fmode);
correct its value by 2**bitwidth. */
do_pending_stack_adjust ();
- emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
+ emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
0, label);
- real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
+ real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
temp = expand_binop (fmode, add_optab, target,
const_double_from_real_value (offset, fmode),
target, 0, OPTAB_LIB_WIDEN);
2^63. The subtraction of 2^63 should not generate any rounding as it
simply clears out that bit. The rest is trivial. */
- if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
+ scalar_int_mode to_mode;
+ if (unsignedp
+ && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
+ && HWI_COMPUTABLE_MODE_P (to_mode))
FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
- if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
+ if (CODE_FOR_nothing != can_fix_p (to_mode, fmode, 0, &must_trunc)
&& (!DECIMAL_FLOAT_MODE_P (fmode)
- || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
+ || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode)))
{
int bitsize;
REAL_VALUE_TYPE offset;
rtx_code_label *lab1, *lab2;
rtx_insn *insn;
- bitsize = GET_MODE_PRECISION (GET_MODE (to));
+ bitsize = GET_MODE_PRECISION (to_mode);
real_2expN (&offset, bitsize - 1, fmode);
limit = const_double_from_real_value (offset, fmode);
lab1 = gen_label_rtx ();
target = expand_binop (GET_MODE (from), sub_optab, from, limit,
NULL_RTX, 0, OPTAB_LIB_WIDEN);
expand_fix (to, target, 0);
- target = expand_binop (GET_MODE (to), xor_optab, to,
+ target = expand_binop (to_mode, xor_optab, to,
gen_int_mode
(HOST_WIDE_INT_1 << (bitsize - 1),
- GET_MODE (to)),
+ to_mode),
to, 1, OPTAB_LIB_WIDEN);
if (target != to)
emit_label (lab2);
- if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
+ if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
{
/* Make a place for a REG_NOTE and add it. */
insn = emit_move_insn (to, to);
set_dst_reg_note (insn, REG_EQUAL,
- gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
+ gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
copy_rtx (from)),
to);
}