diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-12 21:12:43 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-12 21:12:43 +0000 |
commit | df2975206a849aa543bf5bd560a40b31a9db4c54 (patch) | |
tree | e9963f8e60cf011e1d03417f864235eb33ad2a54 /gcc/expr.c | |
parent | 3f18ef378b0e57ce5a30f2710b79f8035b5f1346 (diff) | |
download | gcc-df2975206a849aa543bf5bd560a40b31a9db4c54.tar.gz |
* expr.c (emit_move_change_mode): New.
(emit_move_via_alt_mode): Use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92065 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 8505d8f676f..fffb60d003b 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -2652,46 +2652,55 @@ read_complex_part (rtx cplx, bool imag_p) true, NULL_RTX, imode, imode); } -/* A subroutine of emit_move_insn_1. Generate a move from Y into X using - ALT_MODE instead of the operand's natural mode, MODE. CODE is the insn - code for the move in ALT_MODE, and is known to be valid. Returns the - instruction emitted. */ +/* A subroutine of emit_move_via_alt_mode. Yet another lowpart generator. + NEW_MODE and OLD_MODE are the same size. Return NULL if X cannot be + represented in NEW_MODE. */ static rtx -emit_move_via_alt_mode (enum machine_mode alt_mode, enum machine_mode mode, - enum insn_code code, rtx x, rtx y) +emit_move_change_mode (enum machine_mode new_mode, + enum machine_mode old_mode, rtx x) { - /* Get X and Y in ALT_MODE. We can't use gen_lowpart here because it - may call change_address which is not appropriate if we were - called when a reload was in progress. We don't have to worry - about changing the address since the size in bytes is supposed to - be the same. Copy the MEM to change the mode and move any - substitutions from the old MEM to the new one. */ + rtx ret; - if (reload_in_progress) + if (reload_in_progress && MEM_P (x)) { - rtx x1 = x, y1 = y; + /* We can't use gen_lowpart here because it may call change_address + which is not appropriate if we were called when a reload was in + progress. We don't have to worry about changing the address since + the size in bytes is supposed to be the same. Copy the MEM to + change the mode and move any substitutions from the old MEM to + the new one. */ - x = gen_lowpart_common (alt_mode, x1); - if (x == 0 && MEM_P (x1)) - { - x = adjust_address_nv (x1, alt_mode, 0); - copy_replacements (x1, x); - } - - y = gen_lowpart_common (alt_mode, y1); - if (y == 0 && MEM_P (y1)) - { - y = adjust_address_nv (y1, alt_mode, 0); - copy_replacements (y1, y); - } + ret = adjust_address_nv (x, new_mode, 0); + copy_replacements (x, ret); } else { - x = simplify_gen_subreg (alt_mode, x, mode, 0); - y = simplify_gen_subreg (alt_mode, y, mode, 0); + /* Note that we do want simplify_subreg's behaviour of validating + that the new mode is ok for a hard register. If we were to use + simplify_gen_subreg, we would create the subreg, but would + probably run into the target not being able to implement it. */ + ret = simplify_subreg (new_mode, x, old_mode, 0); } + return ret; +} + +/* A subroutine of emit_move_insn_1. Generate a move from Y into X using + ALT_MODE instead of the operand's natural mode, MODE. CODE is the insn + code for the move in ALT_MODE, and is known to be valid. Returns the + instruction emitted, or NULL if X or Y cannot be represented in ALT_MODE. */ + +static rtx +emit_move_via_alt_mode (enum machine_mode alt_mode, enum machine_mode mode, + enum insn_code code, rtx x, rtx y) +{ + x = emit_move_change_mode (alt_mode, mode, x); + if (x == NULL_RTX) + return NULL_RTX; + y = emit_move_change_mode (alt_mode, mode, y); + if (y == NULL_RTX) + return NULL_RTX; return emit_insn (GEN_FCN (code) (x, y)); } |