diff options
author | Hans-Peter Nilsson <hp@bitrange.com> | 2003-03-09 01:32:42 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@gcc.gnu.org> | 2003-03-09 01:32:42 +0000 |
commit | a3600c718eb2abf543cd17458e98899958cdd839 (patch) | |
tree | 5939b9c628058a9aab673e2656bd7d35a9246792 /gcc/expr.c | |
parent | a6e464ae019d39af515fe0e2be9a949ed75bce92 (diff) | |
download | gcc-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/expr.c')
-rw-r--r-- | gcc/expr.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -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. */ |