aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@bitrange.com>2003-03-09 01:32:42 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2003-03-09 01:32:42 +0000
commita3600c718eb2abf543cd17458e98899958cdd839 (patch)
tree5939b9c628058a9aab673e2656bd7d35a9246792 /gcc
parenta6e464ae019d39af515fe0e2be9a949ed75bce92 (diff)
downloadgcc-a3600c718eb2abf543cd17458e98899958cdd839.zip
gcc-a3600c718eb2abf543cd17458e98899958cdd839.tar.gz
gcc-a3600c718eb2abf543cd17458e98899958cdd839.tar.bz2
optabs.c (gen_move_insn): Move logic for synthesizing MODE_CC moves from here ...
* optabs.c (gen_move_insn): Move logic for synthesizing MODE_CC moves from here ... * expr.c (emit_move_insn_1): ... to here. From-SVN: r64015
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/expr.c55
-rw-r--r--gcc/optabs.c61
3 files changed, 59 insertions, 61 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a64ec23..ebd9e8a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2003-03-09 Hans-Peter Nilsson <hp@bitrange.com>
+ * optabs.c (gen_move_insn): Move logic for synthesizing MODE_CC
+ moves from here ...
+ * expr.c (emit_move_insn_1): ... to here.
+
* config/cris/aout.h (CRIS_CPP_SUBTARGET_SPEC): Move -D__AOUT__ to...
(TARGET_OS_CPP_BUILTINS): New macro.
* config/cris/cris.h (CRIS_CPP_SUBTARGET_SPEC): Move -D__ELF__ to...
diff --git a/gcc/expr.c b/gcc/expr.c
index c0119af..46b264e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3384,6 +3384,61 @@ emit_move_insn_1 (x, y)
return get_last_insn ();
}
+ /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
+ find a mode to do it in. If we have a movcc, use it. Otherwise,
+ find the MODE_INT mode of the same width. */
+ else if (GET_MODE_CLASS (mode) == MODE_CC
+ && mov_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
+ {
+ enum insn_code insn_code;
+ enum machine_mode tmode = VOIDmode;
+ rtx x1 = x, y1 = y;
+
+ if (mode != CCmode
+ && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
+ tmode = CCmode;
+ else
+ for (tmode = QImode; tmode != VOIDmode;
+ tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
+ break;
+
+ if (tmode == VOIDmode)
+ abort ();
+
+ /* Get X and Y in TMODE. 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. */
+
+ if (reload_in_progress)
+ {
+ x = gen_lowpart_common (tmode, x1);
+ if (x == 0 && GET_CODE (x1) == MEM)
+ {
+ x = adjust_address_nv (x1, tmode, 0);
+ copy_replacements (x1, x);
+ }
+
+ y = gen_lowpart_common (tmode, y1);
+ if (y == 0 && GET_CODE (y1) == MEM)
+ {
+ y = adjust_address_nv (y1, tmode, 0);
+ copy_replacements (y1, y);
+ }
+ }
+ else
+ {
+ x = gen_lowpart (tmode, x);
+ y = gen_lowpart (tmode, y);
+ }
+
+ insn_code = mov_optab->handlers[(int) tmode].insn_code;
+ return emit_insn (GEN_FCN (insn_code) (x, y));
+ }
+
/* This will handle any multi-word or full-word mode that lacks a move_insn
pattern. However, you will get better code if you define such patterns,
even if they must turn into multiple assembler instructions. */
diff --git a/gcc/optabs.c b/gcc/optabs.c
index d4eaf6c..ffad83f 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4654,69 +4654,8 @@ rtx
gen_move_insn (x, y)
rtx x, y;
{
- enum machine_mode mode = GET_MODE (x);
- enum insn_code insn_code;
rtx seq;
- if (mode == VOIDmode)
- mode = GET_MODE (y);
-
- insn_code = mov_optab->handlers[(int) mode].insn_code;
-
- /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
- find a mode to do it in. If we have a movcc, use it. Otherwise,
- find the MODE_INT mode of the same width. */
-
- if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
- {
- enum machine_mode tmode = VOIDmode;
- rtx x1 = x, y1 = y;
-
- if (mode != CCmode
- && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
- tmode = CCmode;
- else
- for (tmode = QImode; tmode != VOIDmode;
- tmode = GET_MODE_WIDER_MODE (tmode))
- if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
- break;
-
- if (tmode == VOIDmode)
- abort ();
-
- /* Get X and Y in TMODE. 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. */
-
- if (reload_in_progress)
- {
- x = gen_lowpart_common (tmode, x1);
- if (x == 0 && GET_CODE (x1) == MEM)
- {
- x = adjust_address_nv (x1, tmode, 0);
- copy_replacements (x1, x);
- }
-
- y = gen_lowpart_common (tmode, y1);
- if (y == 0 && GET_CODE (y1) == MEM)
- {
- y = adjust_address_nv (y1, tmode, 0);
- copy_replacements (y1, y);
- }
- }
- else
- {
- x = gen_lowpart (tmode, x);
- y = gen_lowpart (tmode, y);
- }
-
- insn_code = mov_optab->handlers[(int) tmode].insn_code;
- return (GEN_FCN (insn_code) (x, y));
- }
-
start_sequence ();
emit_move_insn_1 (x, y);
seq = get_insns ();