/* Convert tree expression to rtl instructions, for GNU compiler.
- Copyright (C) 1988-2019 Free Software Foundation, Inc.
+ Copyright (C) 1988-2020 Free Software Foundation, Inc.
This file is part of GCC.
if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
{
+ if (GET_MODE_UNIT_PRECISION (to_mode)
+ > GET_MODE_UNIT_PRECISION (from_mode))
+ {
+ optab op = unsignedp ? zext_optab : sext_optab;
+ insn_code icode = convert_optab_handler (op, to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ emit_unop_insn (icode, to, from,
+ unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
+ return;
+ }
+ }
+
+ if (GET_MODE_UNIT_PRECISION (to_mode)
+ < GET_MODE_UNIT_PRECISION (from_mode))
+ {
+ insn_code icode = convert_optab_handler (trunc_optab,
+ to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+ {
+ emit_unop_insn (icode, to, from, TRUNCATE);
+ return;
+ }
+ }
+
gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
GET_MODE_BITSIZE (to_mode)));
rtx_insn *ret;
/* For memory to memory moves, optimal behavior can be had with the
- existing block move logic. */
+ existing block move logic. But use normal expansion if optimizing
+ for size. */
if (MEM_P (x) && MEM_P (y))
{
emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
- BLOCK_OP_NO_LIBCALL);
+ (optimize_insn_for_speed_p()
+ ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
return get_last_insn ();
}
}
else
{
+ machine_mode from_mode
+ = GET_MODE (result) == VOIDmode
+ ? TYPE_MODE (TREE_TYPE (from))
+ : GET_MODE (result);
rtx from_rtx;
if (MEM_P (result))
from_rtx = change_address (result, to_mode, NULL_RTX);
else
from_rtx
- = simplify_gen_subreg (to_mode, result,
- TYPE_MODE (TREE_TYPE (from)), 0);
+ = simplify_gen_subreg (to_mode, result, from_mode, 0);
if (from_rtx)
{
emit_move_insn (XEXP (to_rtx, 0),
{
to_mode = GET_MODE_INNER (to_mode);
rtx from_real
- = simplify_gen_subreg (to_mode, result,
- TYPE_MODE (TREE_TYPE (from)),
- 0);
+ = simplify_gen_subreg (to_mode, result, from_mode, 0);
rtx from_imag
- = simplify_gen_subreg (to_mode, result,
- TYPE_MODE (TREE_TYPE (from)),
+ = simplify_gen_subreg (to_mode, result, from_mode,
GET_MODE_SIZE (to_mode));
if (!from_real || !from_imag)
goto concat_store_slow;