aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2005-03-11 22:58:49 +0000
committerDavid Edelsohn <edelsohn@gnu.org>2005-03-11 22:58:49 +0000
commit5a5473894a67a653fe964a7ac302e834a08e879d (patch)
tree675b3a954c1c9d341f4acdf5508ad1ae49e1add0 /gcc/expr.c
parentc3631a6cac1ab6ca40a05901709eabfaf7cec5de (diff)
PR rtl-optimization/20306
* expr.c (emit_move_complex): Set try_int false if mode is MODE_COMPLEX_FLOAT and mov_optab exists for inner mode. Only try emit_block_move if try_int is true. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@96312 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 775a83a3cfc..9e08315531f 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2877,19 +2877,14 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
if (push_operand (x, mode))
return emit_move_complex_push (mode, x, y);
- /* For memory to memory moves, optimal behavior can be had with the
- existing block move logic. */
- if (MEM_P (x) && MEM_P (y))
- {
- emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
- BLOCK_OP_NO_LIBCALL);
- return get_last_insn ();
- }
-
/* See if we can coerce the target into moving both values at once. */
+ /* Move floating point as parts. */
+ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
+ && mov_optab->handlers[GET_MODE_INNER (mode)].insn_code != CODE_FOR_nothing)
+ try_int = false;
/* Not possible if the values are inherently not adjacent. */
- if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
+ else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
try_int = false;
/* Is possible if both are registers (or subregs of registers). */
else if (register_operand (x, mode) && register_operand (y, mode))
@@ -2907,7 +2902,18 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
if (try_int)
{
- rtx ret = emit_move_via_integer (mode, x, y);
+ rtx ret;
+
+ /* For memory to memory moves, optimal behavior can be had with the
+ existing block move logic. */
+ if (MEM_P (x) && MEM_P (y))
+ {
+ emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
+ BLOCK_OP_NO_LIBCALL);
+ return get_last_insn ();
+ }
+
+ ret = emit_move_via_integer (mode, x, y);
if (ret)
return ret;
}