aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2006-04-03 11:20:07 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2006-04-03 11:20:07 +0000
commitb5c82fa1381f4c1610f8137ede5ea6789fa90c8a (patch)
treee8c7101e8fefacd29cfe88d998da545388f1d4d1 /gcc/reload.c
parentf096660b460d13d3a4f511071de80085300b4af9 (diff)
downloadgcc-b5c82fa1381f4c1610f8137ede5ea6789fa90c8a.zip
gcc-b5c82fa1381f4c1610f8137ede5ea6789fa90c8a.tar.gz
gcc-b5c82fa1381f4c1610f8137ede5ea6789fa90c8a.tar.bz2
re PR target/19653 (x87 reg allocated for constants for -mfpmath=sse)
2005-08-08 Paolo Bonzini <bonzini@gnu.org> Dale Johannesen <dalej@apple.com> PR target/19653 * regclass.c (struct reg_pref): Update documentation. (regclass): Set prefclass to NO_REGS if memory is the best option. (record_reg_classes): Cope with a prefclass set to NO_REGS. * reload.c (find_reloads): Take PREFERRED_OUTPUT_RELOAD_CLASS into account. For non-registers, equate an empty preferred reload class to a `!' in the constraint; move the if clause to do so after those that reject the insn. (push_reload): Allow PREFERRED_*_RELOAD_CLASS to liberally return NO_REGS. (find_dummy_reload): Likewise. * doc/tm.texi (Register Classes): Document what it means if PREFERRED_*_RELOAD_CLASS return NO_REGS. * config/i386/i386.c (ix86_preferred_reload_class): Force using SSE registers (and return NO_REGS for floating-point constants) if math is done with SSE. (ix86_preferred_output_reload_class): New. * config/i386/i386-protos.h (ix86_preferred_output_reload_class): New. * config/i386/i386.h (PREFERRED_OUTPUT_RELOAD_CLASS): New. * config/i386/i386.md: Remove # register preferences. Co-Authored-By: Dale Johannesen <dalej@apple.com> From-SVN: r112637
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 9bfb748..f3023ae 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1184,15 +1184,24 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
/* Narrow down the class of register wanted if that is
desirable on this machine for efficiency. */
- if (in != 0)
- class = PREFERRED_RELOAD_CLASS (in, class);
+ {
+ enum reg_class preferred_class = class;
+
+ if (in != 0)
+ preferred_class = PREFERRED_RELOAD_CLASS (in, class);
/* Output reloads may need analogous treatment, different in detail. */
#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
- if (out != 0)
- class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
+ if (out != 0)
+ preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class);
#endif
+ /* Discard what the target said if we cannot do it. */
+ if (preferred_class != NO_REGS
+ || (optional && type == RELOAD_FOR_OUTPUT))
+ class = preferred_class;
+ }
+
/* Make sure we use a class that can handle the actual pseudo
inside any subreg. For example, on the 386, QImode regs
can appear within SImode subregs. Although GENERAL_REGS
@@ -1885,7 +1894,11 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
/* Narrow down the reg class, the same way push_reload will;
otherwise we might find a dummy now, but push_reload won't. */
- class = PREFERRED_RELOAD_CLASS (in, class);
+ {
+ enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, class);
+ if (class != NO_REGS)
+ class = preferred_class;
+ }
/* See if OUT will do. */
if (REG_P (out)
@@ -3401,22 +3414,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
losers++;
}
- /* If we can't reload this value at all, reject this
- alternative. Note that we could also lose due to
- LIMIT_RELOAD_RELOAD_CLASS, but we don't check that
- here. */
-
- if (! CONSTANT_P (operand)
- && (enum reg_class) this_alternative[i] != NO_REGS
- && (PREFERRED_RELOAD_CLASS (operand,
- (enum reg_class) this_alternative[i])
- == NO_REGS))
- bad = 1;
-
/* Alternative loses if it requires a type of reload not
permitted for this insn. We can always reload SCRATCH
and objects with a REG_UNUSED note. */
- else if (GET_CODE (operand) != SCRATCH
+ if (GET_CODE (operand) != SCRATCH
&& modified[i] != RELOAD_READ && no_output_reloads
&& ! find_reg_note (insn, REG_UNUSED, operand))
bad = 1;
@@ -3424,6 +3425,28 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& ! const_to_mem)
bad = 1;
+ /* If we can't reload this value at all, reject this
+ alternative. Note that we could also lose due to
+ LIMIT_RELOAD_CLASS, but we don't check that
+ here. */
+
+ if (! CONSTANT_P (operand)
+ && (enum reg_class) this_alternative[i] != NO_REGS)
+ {
+ if (PREFERRED_RELOAD_CLASS
+ (operand, (enum reg_class) this_alternative[i])
+ == NO_REGS)
+ reject = 600;
+
+#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
+ if (operand_type[i] == RELOAD_FOR_OUTPUT
+ && PREFERRED_OUTPUT_RELOAD_CLASS
+ (operand, (enum reg_class) this_alternative[i])
+ == NO_REGS)
+ reject = 600;
+#endif
+ }
+
/* We prefer to reload pseudos over reloading other things,
since such reloads may be able to be eliminated later.
If we are reloading a SCRATCH, we won't be generating any