+2002-04-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR optimization/6305
+ * config/s390/s390.c (s390_expand_plus_operand): Use find_replacement
+ to make sure previous reloads are taken into account. Generate
+ better code if one operand is an in-range immediate constant.
+
2002-04-16 Andrew Haley <aph@cambridge.redhat.com>
* doc/install.texi (Building): libgcj requires GNU make.
#include "function.h"
#include "recog.h"
#include "expr.h"
+#include "reload.h"
#include "toplev.h"
#include "basic-block.h"
#include "integrate.h"
if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
abort ();
- sum1 = XEXP (src, 0);
- sum2 = XEXP (src, 1);
+ /* Check if any of the two operands is already scheduled
+ for replacement by reload. This can happen e.g. when
+ float registers occur in an address. */
+ sum1 = find_replacement (&XEXP (src, 0));
+ sum2 = find_replacement (&XEXP (src, 1));
/* If one of the two operands is equal to the target,
- make it the first one. */
- if (rtx_equal_p (target, sum2))
+ make it the first one. If one is a constant, make
+ it the second one. */
+ if (rtx_equal_p (target, sum2)
+ || GET_CODE (sum1) == CONST_INT)
{
- sum2 = XEXP (src, 0);
- sum1 = XEXP (src, 1);
+ rtx tem = sum2;
+ sum2 = sum1;
+ sum1 = tem;
}
/* If the first operand is not an address register,
/* Likewise for the second operand. However, take
care not to clobber the target if we already used
- it for the first operand. Use the scratch instead. */
- if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
+ it for the first operand. Use the scratch instead.
+ Also, allow an immediate offset if it is in range. */
+ if ((true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
+ && !(GET_CODE (sum2) == CONST_INT
+ && INTVAL (sum2) >= 0 && INTVAL (sum2) < 4096))
{
if (!rtx_equal_p (target, sum1))
{