+2002-04-09 David S. Miller <davem@redhat.com>
+
+ * config/sparc/sparc.c (sparc_extra_constraint_check): New
+ function, implementing EXTRA_CONSTRAINTS. For memory constraints,
+ allow reloading pseudos.
+ * config/sparc/sparc.h (EXTRA_CONSTRAINTS): Use it.
+ * config/sparc/sparc-protos.h: Declare it.
+
+ * config/sparc/sparc.c (const64_is_2insns): Kill signed vs.
+ unsigned comparison warning.
+ (output_restore_regs): Mark leaf_function as unused.
+
Tue Apr 9 09:35:45 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (is_aligning_offset): New function.
int highest_bit_set, lowest_bit_set, all_bits_between_are_set;
if (high_bits == 0
- || high_bits == -1)
+ || high_bits == 0xffffffff)
return 1;
analyze_64bit_constant (high_bits, low_bits,
static void
output_restore_regs (file, leaf_function)
FILE *file;
- int leaf_function;
+ int leaf_function ATTRIBUTE_UNUSED;
{
int offset, n_regs;
const char *base;
fputc ('\n', asm_out_file);
}
#endif /* OBJECT_FORMAT_ELF */
+
+int
+sparc_extra_constraint_check (op, c, strict)
+ rtx op;
+ char c;
+ int strict;
+{
+ int reload_ok_mem;
+
+ if (TARGET_ARCH64
+ && (c == 'T' || c == 'U'))
+ return 0;
+
+ switch (c)
+ {
+ case 'Q':
+ return fp_sethi_p (op);
+
+ case 'R':
+ return fp_mov_p (op);
+
+ case 'S':
+ return fp_high_losum_p (op);
+
+ case 'U':
+ if (! strict
+ || (GET_CODE (op) == REG
+ && (REGNO (op) < FIRST_PSEUDO_REGISTER
+ || reg_renumber[REGNO (op)] >= 0)))
+ return register_ok_for_ldd (op);
+
+ return 0;
+
+ case 'W':
+ case 'T':
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* Our memory extra constraints have to emulate the
+ behavior of 'm' and 'o' in order for reload to work
+ correctly. */
+ if (GET_CODE (op) == MEM)
+ {
+ reload_ok_mem = 0;
+ if ((TARGET_ARCH64 || mem_min_alignment (op, 8))
+ && (! strict
+ || strict_memory_address_p (Pmode, XEXP (op, 0))))
+ reload_ok_mem = 1;
+ }
+ else
+ {
+ reload_ok_mem = (reload_in_progress
+ && GET_CODE (op) == REG
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber [REGNO (op)] < 0);
+ }
+
+ return reload_ok_mem;
+}
'W' handles the memory operand when moving operands in/out
of 'e' constraint floating point registers. */
-#define EXTRA_CONSTRAINT_BASE(OP, C) \
- ((C) == 'Q' ? fp_sethi_p(OP) \
- : (C) == 'R' ? fp_mov_p(OP) \
- : (C) == 'S' ? fp_high_losum_p(OP) \
- : 0)
-
#ifndef REG_OK_STRICT
/* Nonzero if X is a hard reg that can be used as an index
#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X)
/* 'T', 'U' are for aligned memory loads which aren't needed for arch64.
- 'W' is like 'T' but is assumed true on arch64. */
-
-#define EXTRA_CONSTRAINT(OP, C) \
- (EXTRA_CONSTRAINT_BASE(OP, C) \
- || ((! TARGET_ARCH64 && (C) == 'T') \
- ? (mem_min_alignment (OP, 8)) \
- : ((! TARGET_ARCH64 && (C) == 'U') \
- ? (register_ok_for_ldd (OP)) \
- : ((C) == 'W' \
- ? ((TARGET_ARCH64 && GET_CODE (OP) == MEM) \
- || mem_min_alignment (OP, 8)) \
- : 0))))
+ 'W' is like 'T' but is assumed true on arch64.
+
+ Remember to accept pseudo-registers for memory constraints if reload is
+ in progress. */
+
+#define EXTRA_CONSTRAINT(OP, C) \
+ sparc_extra_constraint_check(OP, C, 0)
#else
/* Nonzero if X is a hard reg that can be used as a base reg. */
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-#define EXTRA_CONSTRAINT(OP, C) \
- (EXTRA_CONSTRAINT_BASE(OP, C) \
- || ((! TARGET_ARCH64 && (C) == 'T') \
- ? mem_min_alignment (OP, 8) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \
- : ((! TARGET_ARCH64 && (C) == 'U') \
- ? (GET_CODE (OP) == REG \
- && (REGNO (OP) < FIRST_PSEUDO_REGISTER \
- || reg_renumber[REGNO (OP)] >= 0) \
- && register_ok_for_ldd (OP)) \
- : ((C) == 'W' \
- ? (((TARGET_ARCH64 && GET_CODE (OP) == MEM) \
- || mem_min_alignment (OP, 8)) \
- && strict_memory_address_p (Pmode, XEXP (OP, 0))) \
- : 0))))
+#define EXTRA_CONSTRAINT(OP, C) \
+ sparc_extra_constraint_check(OP, C, 1)
#endif
\f