]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/expr.c
Update copyright years.
[thirdparty/gcc.git] / gcc / expr.c
index 06e934e5be6e1d500460bba3779057455c85ba7a..b97c217e86da73401a04f3c4fc531d83987e8d5d 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -250,6 +250,31 @@ convert_move (rtx to, rtx from, int unsignedp)
 
   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)));
 
@@ -3571,11 +3596,13 @@ emit_move_complex (machine_mode mode, rtx x, rtx y)
       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 ();
        }
 
@@ -5258,13 +5285,16 @@ expand_assignment (tree to, tree from, bool nontemporal)
                }
              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),
@@ -5276,12 +5306,9 @@ expand_assignment (tree to, tree from, bool nontemporal)
                    {
                      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;