aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-03-01 16:00:41 -0700
committerJeff Law <law@gcc.gnu.org>1996-03-01 16:00:41 -0700
commit9725066d7d42464a95415862668c0b96f740cac7 (patch)
treecb22a4cfe3163d18f7772355ee42448ac5c2feca /gcc
parentfff4998bc9872fac229a83563e4759e811ab360a (diff)
downloadgcc-9725066d7d42464a95415862668c0b96f740cac7.zip
gcc-9725066d7d42464a95415862668c0b96f740cac7.tar.gz
gcc-9725066d7d42464a95415862668c0b96f740cac7.tar.bz2
optabs.c (emit_cmp_insn): Immediately copy the return value from the library call into a pseudo register.
* optabs.c (emit_cmp_insn): Immediately copy the return value from the library call into a pseudo register. (emit_float_lib_cmp): Likewise. From-SVN: r11398
Diffstat (limited to 'gcc')
-rw-r--r--gcc/optabs.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 4020e64..09c4526 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -2743,6 +2743,8 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
else
#endif
{
+ rtx result;
+
#ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memcmp_libfunc, 0,
TYPE_MODE (integer_type_node), 3,
@@ -2759,7 +2761,14 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
TREE_UNSIGNED (integer_type_node)),
TYPE_MODE (integer_type_node));
#endif
- emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
+
+ /* Immediately move the result of the libcall into a pseudo
+ register so reload doesn't clobber the value if it needs
+ the return register for a spill reg. */
+ result = gen_reg_rtx (TYPE_MODE (integer_type_node));
+ emit_move_insn (result,
+ hard_libcall_value (TYPE_MODE (integer_type_node)));
+ emit_cmp_insn (result,
const0_rtx, comparison, NULL_RTX,
TYPE_MODE (integer_type_node), 0, 0);
}
@@ -2836,6 +2845,8 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
&& class != MODE_FLOAT)
{
rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
+ rtx result;
+
/* If we want unsigned, and this mode has a distinct unsigned
comparison routine, use that. */
if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
@@ -2844,11 +2855,16 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
emit_library_call (libfunc, 1,
word_mode, 2, x, mode, y, mode);
+ /* Immediately move the result of the libcall into a pseudo
+ register so reload doesn't clobber the value if it needs
+ the return register for a spill reg. */
+ result = gen_reg_rtx (word_mode);
+ emit_move_insn (result, hard_libcall_value (word_mode));
+
/* Integer comparison returns a result that must be compared against 1,
so that even if we do an unsigned compare afterward,
there is still a value that can represent the result "less than". */
-
- emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
+ emit_cmp_insn (result, const1_rtx,
comparison, NULL_RTX, word_mode, unsignedp, 0);
return;
}
@@ -2887,6 +2903,7 @@ emit_float_lib_cmp (x, y, comparison)
{
enum machine_mode mode = GET_MODE (x);
rtx libfunc = 0;
+ rtx result;
if (mode == HFmode)
switch (comparison)
@@ -3051,7 +3068,13 @@ emit_float_lib_cmp (x, y, comparison)
emit_library_call (libfunc, 1,
word_mode, 2, x, mode, y, mode);
- emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
+ /* Immediately move the result of the libcall into a pseudo
+ register so reload doesn't clobber the value if it needs
+ the return register for a spill reg. */
+ result = gen_reg_rtx (word_mode);
+ emit_move_insn (result, hard_libcall_value (word_mode));
+
+ emit_cmp_insn (result, const0_rtx, comparison,
NULL_RTX, word_mode, 0, 0);
}