Commit f7e0e539 by David S. Miller Committed by David S. Miller

sparc.c (sparc_operand, [...]): Recognize CONSTANT_P_RTX.

	* sparc.c (sparc_operand, move_operand,	arith_operand,
	arith11_operand, arith10_operand, arith_double_operand,
	arith11_double_operand, arith10_double_operand, small_int,
	uns_small_int): Recognize CONSTANT_P_RTX.
	(output_sized_memop, output_move_with_extension,
	output_load_address, output_size_for_block_move,
	output_block_move, delay_operand): Remove, has not been
	enabled or referenced for years.
	* sparc.md (movstrsi, block_move_insn): Likewise.
	* sparc.h (PREDICATE_CODES): Define.
	* linux-aout.h (MACHINE_STATE_{SAVE,RESTORE}): Override with
	version which uses getcc/setcc traps to save/restore condition
	codes.
	* linux64.h: Likewise.
	* sunos4.h: Likewise.
	* linux.h: Likewise.
	* sol2.h: Likewise.
	* sun4o3.h: Likewise.

From-SVN: r20917
parent d420e567
Fri Jul 3 02:33:35 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
* sparc.c (sparc_operand, move_operand, arith_operand,
arith11_operand, arith10_operand, arith_double_operand,
arith11_double_operand, arith10_double_operand, small_int,
uns_small_int): Recognize CONSTANT_P_RTX.
(output_sized_memop, output_move_with_extension,
output_load_address, output_size_for_block_move,
output_block_move, delay_operand): Remove, has not been
enabled or referenced for years.
* sparc.md (movstrsi, block_move_insn): Likewise.
* sparc.h (PREDICATE_CODES): Define.
* linux-aout.h (MACHINE_STATE_{SAVE,RESTORE}): Override with
version which uses getcc/setcc traps to save/restore condition
codes.
* linux64.h: Likewise.
* sunos4.h: Likewise.
* linux.h: Likewise.
* sol2.h: Likewise.
* sun4o3.h: Likewise.
Fri Jul 3 02:28:05 1998 Richard Henderson <rth@cygnus.com> Fri Jul 3 02:28:05 1998 Richard Henderson <rth@cygnus.com>
* alpha.c (alpha_initialize_trampoline): Hack around Pmode/ptr_mode * alpha.c (alpha_initialize_trampoline): Hack around Pmode/ptr_mode
......
...@@ -109,3 +109,22 @@ Boston, MA 02111-1307, USA. */ ...@@ -109,3 +109,22 @@ Boston, MA 02111-1307, USA. */
long double yet. */ long double yet. */
#define LONG_DOUBLE_TYPE_SIZE 128 #define LONG_DOUBLE_TYPE_SIZE 128
#endif #endif
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
reliably. */
#undef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID) \
unsigned long int ms_flags, ms_saveret; \
asm volatile("ta 0x20\n\t" \
"mov %%g1, %0\n\t" \
"mov %%g2, %1\n\t" \
: "=r" (ms_flags), "=r" (ms_saveret));
#undef MACHINE_STATE_RESTORE
#define MACHINE_STATE_RESTORE(ID) \
asm volatile("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"ta 0x21\n\t" \
: /* no outputs */ \
: "r" (ms_flags), "r" (ms_saveret));
...@@ -238,3 +238,22 @@ do { \ ...@@ -238,3 +238,22 @@ do { \
long double yet. */ long double yet. */
#define LONG_DOUBLE_TYPE_SIZE 128 #define LONG_DOUBLE_TYPE_SIZE 128
#endif #endif
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
reliably. */
#undef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID) \
unsigned long int ms_flags, ms_saveret; \
asm volatile("ta 0x20\n\t" \
"mov %%g1, %0\n\t" \
"mov %%g2, %1\n\t" \
: "=r" (ms_flags), "=r" (ms_saveret));
#undef MACHINE_STATE_RESTORE
#define MACHINE_STATE_RESTORE(ID) \
asm volatile("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"ta 0x21\n\t" \
: /* no outputs */ \
: "r" (ms_flags), "r" (ms_saveret));
...@@ -224,3 +224,22 @@ do { \ ...@@ -224,3 +224,22 @@ do { \
RELATIVE relocations. */ RELATIVE relocations. */
/* #define DWARF_OFFSET_SIZE PTR_SIZE */ /* #define DWARF_OFFSET_SIZE PTR_SIZE */
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
reliably. */
#undef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID) \
unsigned long int ms_flags, ms_saveret; \
asm volatile("ta 0x20\n\t" \
"mov %%g1, %0\n\t" \
"mov %%g2, %1\n\t" \
: "=r" (ms_flags), "=r" (ms_saveret));
#undef MACHINE_STATE_RESTORE
#define MACHINE_STATE_RESTORE(ID) \
asm volatile("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"ta 0x21\n\t" \
: /* no outputs */ \
: "r" (ms_flags), "r" (ms_saveret));
...@@ -211,3 +211,22 @@ Boston, MA 02111-1307, USA. */ ...@@ -211,3 +211,22 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT #undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU + MASK_V8PLUS) #define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU + MASK_V8PLUS)
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
reliably. */
#undef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID) \
unsigned long int ms_flags, ms_saveret; \
asm volatile("ta 0x20\n\t" \
"mov %%g1, %0\n\t" \
"mov %%g2, %1\n\t" \
: "=r" (ms_flags), "=r" (ms_saveret));
#undef MACHINE_STATE_RESTORE
#define MACHINE_STATE_RESTORE(ID) \
asm volatile("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"ta 0x21\n\t" \
: /* no outputs */ \
: "r" (ms_flags), "r" (ms_saveret));
...@@ -641,7 +641,8 @@ sparc_operand (op, mode) ...@@ -641,7 +641,8 @@ sparc_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (register_operand (op, mode)) if (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX)
return 1; return 1;
if (GET_CODE (op) == CONST_INT) if (GET_CODE (op) == CONST_INT)
return SMALL_INT (op); return SMALL_INT (op);
...@@ -666,7 +667,8 @@ move_operand (op, mode) ...@@ -666,7 +667,8 @@ move_operand (op, mode)
{ {
if (mode == DImode && arith_double_operand (op, mode)) if (mode == DImode && arith_double_operand (op, mode))
return 1; return 1;
if (register_operand (op, mode)) if (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX)
return 1; return 1;
if (GET_CODE (op) == CONST_INT) if (GET_CODE (op) == CONST_INT)
return SMALL_INT (op) || SPARC_SETHI_P (INTVAL (op)); return SMALL_INT (op) || SPARC_SETHI_P (INTVAL (op));
...@@ -773,6 +775,7 @@ v9_regcmp_op (op, mode) ...@@ -773,6 +775,7 @@ v9_regcmp_op (op, mode)
return v9_regcmp_p (code); return v9_regcmp_p (code);
} }
/* ??? Same as eq_or_neq. */
int int
v8plus_regcmp_op (op, mode) v8plus_regcmp_op (op, mode)
register rtx op; register rtx op;
...@@ -834,7 +837,8 @@ arith_operand (op, mode) ...@@ -834,7 +837,8 @@ arith_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
int val; int val;
if (register_operand (op, mode)) if (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX)
return 1; return 1;
if (GET_CODE (op) != CONST_INT) if (GET_CODE (op) != CONST_INT)
return 0; return 0;
...@@ -852,6 +856,7 @@ arith11_operand (op, mode) ...@@ -852,6 +856,7 @@ arith11_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (register_operand (op, mode) return (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op)))); || (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op))));
} }
...@@ -865,6 +870,7 @@ arith10_operand (op, mode) ...@@ -865,6 +870,7 @@ arith10_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (register_operand (op, mode) return (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op)))); || (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op))));
} }
...@@ -881,6 +887,7 @@ arith_double_operand (op, mode) ...@@ -881,6 +887,7 @@ arith_double_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (register_operand (op, mode) return (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_INT && SMALL_INT (op)) || (GET_CODE (op) == CONST_INT && SMALL_INT (op))
|| (! TARGET_ARCH64 || (! TARGET_ARCH64
&& GET_CODE (op) == CONST_DOUBLE && GET_CODE (op) == CONST_DOUBLE
...@@ -906,6 +913,7 @@ arith11_double_operand (op, mode) ...@@ -906,6 +913,7 @@ arith11_double_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (register_operand (op, mode) return (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_DOUBLE || (GET_CODE (op) == CONST_DOUBLE
&& (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
&& (unsigned HOST_WIDE_INT) (CONST_DOUBLE_LOW (op) + 0x400) < 0x800 && (unsigned HOST_WIDE_INT) (CONST_DOUBLE_LOW (op) + 0x400) < 0x800
...@@ -929,6 +937,7 @@ arith10_double_operand (op, mode) ...@@ -929,6 +937,7 @@ arith10_double_operand (op, mode)
enum machine_mode mode; enum machine_mode mode;
{ {
return (register_operand (op, mode) return (register_operand (op, mode)
|| GET_CODE (op) == CONSTANT_P_RTX
|| (GET_CODE (op) == CONST_DOUBLE || (GET_CODE (op) == CONST_DOUBLE
&& (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode)
&& (unsigned) (CONST_DOUBLE_LOW (op) + 0x200) < 0x400 && (unsigned) (CONST_DOUBLE_LOW (op) + 0x200) < 0x400
...@@ -950,7 +959,8 @@ small_int (op, mode) ...@@ -950,7 +959,8 @@ small_int (op, mode)
rtx op; rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED; enum machine_mode mode ATTRIBUTE_UNUSED;
{ {
return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); return ((GET_CODE (op) == CONST_INT && SMALL_INT (op))
|| GET_CODE (op) == CONSTANT_P_RTX);
} }
/* Recognize operand values for the umul instruction. That instruction sign /* Recognize operand values for the umul instruction. That instruction sign
...@@ -964,14 +974,16 @@ uns_small_int (op, mode) ...@@ -964,14 +974,16 @@ uns_small_int (op, mode)
{ {
#if HOST_BITS_PER_WIDE_INT > 32 #if HOST_BITS_PER_WIDE_INT > 32
/* All allowed constants will fit a CONST_INT. */ /* All allowed constants will fit a CONST_INT. */
return (GET_CODE (op) == CONST_INT return ((GET_CODE (op) == CONST_INT
&& ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000)
|| (INTVAL (op) >= 0xFFFFF000 && INTVAL (op) < 0x100000000L))); || (INTVAL (op) >= 0xFFFFF000 && INTVAL (op) < 0x100000000L)))
|| GET_CODE (op) == CONSTANT_P_RTX);
#else #else
return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) return (((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000)
|| (GET_CODE (op) == CONST_DOUBLE || (GET_CODE (op) == CONST_DOUBLE
&& CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_HIGH (op) == 0
&& (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)); && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000))
|| GET_CODE (op) == CONSTANT_P_RTX);
#endif #endif
} }
...@@ -2686,350 +2698,6 @@ find_addr_reg (addr) ...@@ -2686,350 +2698,6 @@ find_addr_reg (addr)
abort (); abort ();
} }
#if 0 /* not currently used */
void
output_sized_memop (opname, mode, signedp)
char *opname;
enum machine_mode mode;
int signedp;
{
static char *ld_size_suffix_u[] = { "ub", "uh", "", "?", "d" };
static char *ld_size_suffix_s[] = { "sb", "sh", "", "?", "d" };
static char *st_size_suffix[] = { "b", "h", "", "?", "d" };
char **opnametab, *modename;
if (opname[0] == 'l')
if (signedp)
opnametab = ld_size_suffix_s;
else
opnametab = ld_size_suffix_u;
else
opnametab = st_size_suffix;
modename = opnametab[GET_MODE_SIZE (mode) >> 1];
fprintf (asm_out_file, "\t%s%s", opname, modename);
}
void
output_move_with_extension (operands)
rtx *operands;
{
if (GET_MODE (operands[2]) == HImode)
output_asm_insn ("sll %2,0x10,%0", operands);
else if (GET_MODE (operands[2]) == QImode)
output_asm_insn ("sll %2,0x18,%0", operands);
else
abort ();
}
#endif /* not currently used */
#if 0
/* ??? These are only used by the movstrsi pattern, but we get better code
in general without that, because emit_block_move can do just as good a
job as this function does when alignment and size are known. When they
aren't known, a call to strcpy may be faster anyways, because it is
likely to be carefully crafted assembly language code, and below we just
do a byte-wise copy.
Also, emit_block_move expands into multiple read/write RTL insns, which
can then be optimized, whereas our movstrsi pattern can not be optimized
at all. */
/* Load the address specified by OPERANDS[3] into the register
specified by OPERANDS[0].
OPERANDS[3] may be the result of a sum, hence it could either be:
(1) CONST
(2) REG
(2) REG + CONST_INT
(3) REG + REG + CONST_INT
(4) REG + REG (special case of 3).
Note that (3) is not a legitimate address.
All cases are handled here. */
void
output_load_address (operands)
rtx *operands;
{
rtx base, offset;
if (CONSTANT_P (operands[3]))
{
output_asm_insn ("set %3,%0", operands);
return;
}
if (REG_P (operands[3]))
{
if (REGNO (operands[0]) != REGNO (operands[3]))
output_asm_insn ("mov %3,%0", operands);
return;
}
if (GET_CODE (operands[3]) != PLUS)
abort ();
base = XEXP (operands[3], 0);
offset = XEXP (operands[3], 1);
if (GET_CODE (base) == CONST_INT)
{
rtx tmp = base;
base = offset;
offset = tmp;
}
if (GET_CODE (offset) != CONST_INT)
{
/* Operand is (PLUS (REG) (REG)). */
base = operands[3];
offset = const0_rtx;
}
if (REG_P (base))
{
operands[6] = base;
operands[7] = offset;
if (SMALL_INT (offset))
output_asm_insn ("add %6,%7,%0", operands);
else
output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands);
}
else if (GET_CODE (base) == PLUS)
{
operands[6] = XEXP (base, 0);
operands[7] = XEXP (base, 1);
operands[8] = offset;
if (SMALL_INT (offset))
output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands);
else
output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands);
}
else
abort ();
}
/* Output code to place a size count SIZE in register REG.
ALIGN is the size of the unit of transfer.
Because block moves are pipelined, we don't include the
first element in the transfer of SIZE to REG. */
static void
output_size_for_block_move (size, reg, align)
rtx size, reg;
rtx align;
{
rtx xoperands[3];
xoperands[0] = reg;
xoperands[1] = size;
xoperands[2] = align;
if (GET_CODE (size) == REG)
output_asm_insn ("sub %1,%2,%0", xoperands);
else
{
xoperands[1]
= GEN_INT (INTVAL (size) - INTVAL (align));
output_asm_insn ("set %1,%0", xoperands);
}
}
/* Emit code to perform a block move.
OPERANDS[0] is the destination.
OPERANDS[1] is the source.
OPERANDS[2] is the size.
OPERANDS[3] is the alignment safe to use.
OPERANDS[4] is a register we can safely clobber as a temp. */
char *
output_block_move (operands)
rtx *operands;
{
/* A vector for our computed operands. Note that load_output_address
makes use of (and can clobber) up to the 8th element of this vector. */
rtx xoperands[10];
rtx zoperands[10];
static int movstrsi_label = 0;
int i;
rtx temp1 = operands[4];
rtx sizertx = operands[2];
rtx alignrtx = operands[3];
int align = INTVAL (alignrtx);
char label3[30], label5[30];
xoperands[0] = operands[0];
xoperands[1] = operands[1];
xoperands[2] = temp1;
/* We can't move more than this many bytes at a time because we have only
one register, %g1, to move them through. */
if (align > UNITS_PER_WORD)
{
align = UNITS_PER_WORD;
alignrtx = GEN_INT (UNITS_PER_WORD);
}
/* We consider 8 ld/st pairs, for a total of 16 inline insns to be
reasonable here. (Actually will emit a maximum of 18 inline insns for
the case of size == 31 and align == 4). */
if (GET_CODE (sizertx) == CONST_INT && (INTVAL (sizertx) / align) <= 8
&& memory_address_p (QImode, plus_constant_for_output (xoperands[0],
INTVAL (sizertx)))
&& memory_address_p (QImode, plus_constant_for_output (xoperands[1],
INTVAL (sizertx))))
{
int size = INTVAL (sizertx);
int offset = 0;
/* We will store different integers into this particular RTX. */
xoperands[2] = rtx_alloc (CONST_INT);
PUT_MODE (xoperands[2], VOIDmode);
/* This case is currently not handled. Abort instead of generating
bad code. */
if (align > UNITS_PER_WORD)
abort ();
if (TARGET_ARCH64 && align >= 8)
{
for (i = (size >> 3) - 1; i >= 0; i--)
{
INTVAL (xoperands[2]) = (i << 3) + offset;
output_asm_insn ("ldx [%a1+%2],%%g1\n\tstx %%g1,[%a0+%2]",
xoperands);
}
offset += (size & ~0x7);
size = size & 0x7;
if (size == 0)
return "";
}
if (align >= 4)
{
for (i = (size >> 2) - 1; i >= 0; i--)
{
INTVAL (xoperands[2]) = (i << 2) + offset;
output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]",
xoperands);
}
offset += (size & ~0x3);
size = size & 0x3;
if (size == 0)
return "";
}
if (align >= 2)
{
for (i = (size >> 1) - 1; i >= 0; i--)
{
INTVAL (xoperands[2]) = (i << 1) + offset;
output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]",
xoperands);
}
offset += (size & ~0x1);
size = size & 0x1;
if (size == 0)
return "";
}
if (align >= 1)
{
for (i = size - 1; i >= 0; i--)
{
INTVAL (xoperands[2]) = i + offset;
output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]",
xoperands);
}
return "";
}
/* We should never reach here. */
abort ();
}
/* If the size isn't known to be a multiple of the alignment,
we have to do it in smaller pieces. If we could determine that
the size was a multiple of 2 (or whatever), we could be smarter
about this. */
if (GET_CODE (sizertx) != CONST_INT)
align = 1;
else
{
int size = INTVAL (sizertx);
while (size % align)
align >>= 1;
}
if (align != INTVAL (alignrtx))
alignrtx = GEN_INT (align);
xoperands[3] = GEN_INT (movstrsi_label++);
xoperands[4] = GEN_INT (align);
xoperands[5] = GEN_INT (movstrsi_label++);
ASM_GENERATE_INTERNAL_LABEL (label3, "Lm", INTVAL (xoperands[3]));
ASM_GENERATE_INTERNAL_LABEL (label5, "Lm", INTVAL (xoperands[5]));
/* This is the size of the transfer. Emit code to decrement the size
value by ALIGN, and store the result in the temp1 register. */
output_size_for_block_move (sizertx, temp1, alignrtx);
/* Must handle the case when the size is zero or negative, so the first thing
we do is compare the size against zero, and only copy bytes if it is
zero or greater. Note that we have already subtracted off the alignment
once, so we must copy 1 alignment worth of bytes if the size is zero
here.
The SUN assembler complains about labels in branch delay slots, so we
do this before outputting the load address, so that there will always
be a harmless insn between the branch here and the next label emitted
below. */
{
char pattern[100];
sprintf (pattern, "cmp %%2,0\n\tbl %s", &label5[1]);
output_asm_insn (pattern, xoperands);
}
zoperands[0] = operands[0];
zoperands[3] = plus_constant_for_output (operands[0], align);
output_load_address (zoperands);
/* ??? This might be much faster if the loops below were preconditioned
and unrolled.
That is, at run time, copy enough bytes one at a time to ensure that the
target and source addresses are aligned to the largest possible
alignment. Then use a preconditioned unrolled loop to copy say 16
bytes at a time. Then copy bytes one at a time until finish the rest. */
/* Output the first label separately, so that it is spaced properly. */
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "Lm", INTVAL (xoperands[3]));
{
char pattern[200];
register char *ld_suffix = ((align == 1) ? "ub" : (align == 2) ? "uh"
: (align == 8 && TARGET_ARCH64) ? "x" : "");
register char *st_suffix = ((align == 1) ? "b" : (align == 2) ? "h"
: (align == 8 && TARGET_ARCH64) ? "x" : "");
sprintf (pattern, "ld%s [%%1+%%2],%%%%g1\n\tsubcc %%2,%%4,%%2\n\tbge %s\n\tst%s %%%%g1,[%%0+%%2]\n%s:", ld_suffix, &label3[1], st_suffix, &label5[1]);
output_asm_insn (pattern, xoperands);
}
return "";
}
#endif
/* Output reasonable peephole for set-on-condition-code insns. /* Output reasonable peephole for set-on-condition-code insns.
Note that these insns assume a particular way of defining Note that these insns assume a particular way of defining
labels. Therefore, *both* sparc.h and this function must labels. Therefore, *both* sparc.h and this function must
...@@ -6798,30 +6466,3 @@ sparc_return_peephole_ok (dest, src) ...@@ -6798,30 +6466,3 @@ sparc_return_peephole_ok (dest, src)
return 0; return 0;
return IN_OR_GLOBAL_P (dest); return IN_OR_GLOBAL_P (dest);
} }
int
delay_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
switch (GET_CODE (op))
{
case CONST:
case CONST_INT:
case SYMBOL_REF:
case LABEL_REF:
return 1;
case MEM:
return delay_operand (XEXP (op, 0), Pmode);
case REG:
return IN_OR_GLOBAL_P (op);
case PLUS:
return delay_operand (XEXP (op, 0), Pmode) && delay_operand (XEXP (op, 1), Pmode);
default:
return 0;
}
}
...@@ -3186,6 +3186,49 @@ do { \ ...@@ -3186,6 +3186,49 @@ do { \
} \ } \
} }
/* Define the codes that are matched by predicates in sparc.c. */
#define PREDICATE_CODES \
{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
{"fp_zero_operand", {CONST_DOUBLE}}, \
{"intreg_operand", {SUBREG, REG}}, \
{"fcc_reg_operand", {REG}}, \
{"icc_or_fcc_reg_operand", {REG}}, \
{"restore_operand", {REG}}, \
{"call_operand", {MEM}}, \
{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE, ADDRESSOF, \
SUBREG, REG, PLUS, LO_SUM, CONST_INT}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE}}, \
{"symbolic_memory_operand", {SUBREG, MEM}}, \
{"label_ref_operand", {LABEL_REF}}, \
{"sp64_medium_pic_operand", {CONST}}, \
{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}}, \
{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}}, \
{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \
{"sparc_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \
{"move_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE, MEM}}, \
{"splittable_symbolic_memory_operand", {MEM}}, \
{"splittable_immediate_memory_operand", {MEM}}, \
{"eq_or_neq", {EQ, NE}}, \
{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \
{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \
{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \
{"v8plus_regcmp_op", {EQ, NE}}, \
{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \
{"cc_arithop", {AND, IOR, XOR}}, \
{"cc_arithopn", {AND, IOR}}, \
{"arith_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
{"arith11_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
{"arith10_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \
{"arith_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
{"arith11_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
{"arith10_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
{"small_int", {CONST_INT, CONSTANT_P_RTX}}, \
{"uns_small_int", {CONST_INT, CONSTANT_P_RTX}}, \
{"uns_arith_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"clobbered_register", {REG}},
/* The number of Pmode words for the setjmp buffer. */ /* The number of Pmode words for the setjmp buffer. */
#define JMP_BUF_SIZE 12 #define JMP_BUF_SIZE 12
......
...@@ -2314,55 +2314,6 @@ ...@@ -2314,55 +2314,6 @@
;; ??? There's no symbolic (set (mem:DI ...) ...). ;; ??? There's no symbolic (set (mem:DI ...) ...).
;; Experimentation with v9 suggested one isn't needed. ;; Experimentation with v9 suggested one isn't needed.
;; Block move insns.
;; ??? We get better code without it. See output_block_move in sparc.c.
;; The definition of this insn does not really explain what it does,
;; but it should suffice
;; that anything generated as this insn will be recognized as one
;; and that it will not successfully combine with anything.
;(define_expand "movstrsi"
; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
; (use (match_operand:SI 2 "nonmemory_operand" ""))
; (use (match_operand:SI 3 "immediate_operand" ""))
; (clobber (match_dup 0))
; (clobber (match_dup 1))
; (clobber (match_scratch:SI 4 ""))
; (clobber (reg:SI 100))
; (clobber (reg:SI 1))])]
; ""
; "
;{
; /* If the size isn't known, don't emit inline code. output_block_move
; would output code that's much slower than the library function.
; Also don't output code for large blocks. */
; if (GET_CODE (operands[2]) != CONST_INT
; || GET_CODE (operands[3]) != CONST_INT
; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
; FAIL;
;
; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
; operands[2] = force_not_mem (operands[2]);
;}")
;(define_insn "*block_move_insn"
; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
; (use (match_operand:SI 3 "immediate_operand" "i"))
; (clobber (match_dup 0))
; (clobber (match_dup 1))
; (clobber (match_scratch:SI 4 "=&r"))
; (clobber (reg:SI 100))
; (clobber (reg:SI 1))]
; ""
; "* return output_block_move (operands);"
; [(set_attr "type" "multi")
; (set_attr "length" "6")])
;; Floating point move insns ;; Floating point move insns
;; This pattern forces (set (reg:SF ...) (const_double ...)) ;; This pattern forces (set (reg:SF ...) (const_double ...))
......
...@@ -5,6 +5,25 @@ ...@@ -5,6 +5,25 @@
fprintf (FILE, "\tsethi %%hi(LP%d),%%o0\n\tcall .mcount\n\tor %%lo(LP%d),%%o0,%%o0\n", \ fprintf (FILE, "\tsethi %%hi(LP%d),%%o0\n\tcall .mcount\n\tor %%lo(LP%d),%%o0,%%o0\n", \
(LABELNO), (LABELNO)) (LABELNO), (LABELNO))
/* LINK_SPEC is needed only for Sunos 4. */ /* LINK_SPEC is needed only for SunOS 4. */
#undef LINK_SPEC #undef LINK_SPEC
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
reliably. */
#undef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID) \
unsigned long int ms_flags, ms_saveret; \
asm volatile("ta 0x20\n\t" \
"mov %%g1, %0\n\t" \
"mov %%g2, %1\n\t" \
: "=r" (ms_flags), "=r" (ms_saveret));
#undef MACHINE_STATE_RESTORE
#define MACHINE_STATE_RESTORE(ID) \
asm volatile("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"ta 0x21\n\t" \
: /* no outputs */ \
: "r" (ms_flags), "r" (ms_saveret));
...@@ -28,3 +28,22 @@ Boston, MA 02111-1307, USA. */ ...@@ -28,3 +28,22 @@ Boston, MA 02111-1307, USA. */
/* The Sun as doesn't like unaligned data. */ /* The Sun as doesn't like unaligned data. */
#define DWARF2_UNWIND_INFO 0 #define DWARF2_UNWIND_INFO 0
/* Override MACHINE_STATE_{SAVE,RESTORE} because we have special
traps available which can get and set the condition codes
reliably. */
#undef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID) \
unsigned long int ms_flags, ms_saveret; \
asm volatile("ta 0x20\n\t" \
"mov %%g1, %0\n\t" \
"mov %%g2, %1\n\t" \
: "=r" (ms_flags), "=r" (ms_saveret));
#undef MACHINE_STATE_RESTORE
#define MACHINE_STATE_RESTORE(ID) \
asm volatile("mov %0, %%g1\n\t" \
"mov %1, %%g2\n\t" \
"ta 0x21\n\t" \
: /* no outputs */ \
: "r" (ms_flags), "r" (ms_saveret));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment