Commit 88042663 by Richard Henderson Committed by Richard Henderson

mcore.c (mode_from_align): Remove DImode.

        * config/mcore/mcore.c (mode_from_align): Remove DImode.
        (block_move_sequence): Rewrite to use adjust_address.
        (mcore_expand_block_move): Cleanup logic.  Accept only operands.
        Return boolean indicating success/failure.
        * config/mcore/mcore-protos.h (mcore_expand_block_move): Update decl.
        * config/mcore/mcore.md (movmemsi): Update to match.

From-SVN: r86234
parent 27ab0504
2004-08-18 Richard Henderson <rth@redhat.com>
* config/mcore/mcore.c (mode_from_align): Remove DImode.
(block_move_sequence): Rewrite to use adjust_address.
(mcore_expand_block_move): Cleanup logic. Accept only operands.
Return boolean indicating success/failure.
* config/mcore/mcore-protos.h (mcore_expand_block_move): Update decl.
* config/mcore/mcore.md (movmemsi): Update to match.
2004-08-18 Mike Stump <mrs@apple.com>
* doc/invoke.texi (-mfix-and-continue): Add support for
......
......@@ -57,7 +57,7 @@ extern char * mcore_output_call (rtx *, int);
extern int mcore_is_dead (rtx, rtx);
extern int mcore_expand_insv (rtx *);
extern int mcore_modify_comparison (RTX_CODE);
extern void mcore_expand_block_move (rtx, rtx, rtx *);
extern bool mcore_expand_block_move (rtx *);
extern const char * mcore_output_andn (rtx, rtx *);
extern void mcore_print_operand_address (FILE *, rtx);
extern void mcore_print_operand (FILE *, rtx, int);
......
......@@ -122,7 +122,6 @@ static int calc_live_regs (int *);
static int const_ok_for_mcore (int);
static int try_constant_tricks (long, int *, int *);
static const char * output_inline_const (enum machine_mode, rtx *);
static void block_move_sequence (rtx, rtx, rtx, rtx, int, int, int);
static void layout_mcore_frame (struct mcore_frame *);
static void mcore_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
static cond_type is_cond_candidate (rtx);
......@@ -1824,127 +1823,117 @@ mcore_store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
static const enum machine_mode mode_from_align[] =
{
VOIDmode, QImode, HImode, VOIDmode, SImode,
VOIDmode, VOIDmode, VOIDmode, DImode
};
static void
block_move_sequence (rtx dest, rtx dst_mem, rtx src, rtx src_mem,
int size, int align, int offset)
block_move_sequence (rtx dst_mem, rtx src_mem, int size, int align)
{
rtx temp[2];
enum machine_mode mode[2];
int amount[2];
int active[2];
bool active[2];
int phase = 0;
int next;
int offset_ld = offset;
int offset_st = offset;
int offset_ld = 0;
int offset_st = 0;
rtx x;
active[0] = active[1] = FALSE;
/* Establish parameters for the first load and for the second load if
it is known to be the same mode as the first. */
amount[0] = amount[1] = align;
mode[0] = mode_from_align[align];
x = XEXP (dst_mem, 0);
if (!REG_P (x))
{
x = force_reg (Pmode, x);
dst_mem = replace_equiv_address (dst_mem, x);
}
temp[0] = gen_reg_rtx (mode[0]);
if (size >= 2 * align)
x = XEXP (src_mem, 0);
if (!REG_P (x))
{
mode[1] = mode[0];
temp[1] = gen_reg_rtx (mode[1]);
x = force_reg (Pmode, x);
src_mem = replace_equiv_address (src_mem, x);
}
active[0] = active[1] = false;
do
{
rtx srcp, dstp;
next = phase;
phase = !phase;
phase ^= 1;
if (size > 0)
{
/* Change modes as the sequence tails off. */
if (size < amount[next])
{
amount[next] = (size >= 4 ? 4 : (size >= 2 ? 2 : 1));
mode[next] = mode_from_align[amount[next]];
temp[next] = gen_reg_rtx (mode[next]);
}
size -= amount[next];
srcp = gen_rtx_MEM (
#if 0
MEM_IN_STRUCT_P (src_mem) ? mode[next] : BLKmode,
#else
mode[next],
#endif
gen_rtx_PLUS (Pmode, src, GEN_INT (offset_ld)));
MEM_READONLY_P (srcp) = MEM_READONLY_P (src_mem);
MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem);
MEM_IN_STRUCT_P (srcp) = 1;
emit_insn (gen_rtx_SET (VOIDmode, temp[next], srcp));
offset_ld += amount[next];
active[next] = TRUE;
int next_amount;
next_amount = (size >= 4 ? 4 : (size >= 2 ? 2 : 1));
next_amount = MIN (next_amount, align);
amount[next] = next_amount;
mode[next] = mode_from_align[next_amount];
temp[next] = gen_reg_rtx (mode[next]);
x = adjust_address (src_mem, mode[next], offset_ld);
emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
offset_ld += next_amount;
size -= next_amount;
active[next] = true;
}
if (active[phase])
{
active[phase] = FALSE;
dstp = gen_rtx_MEM (
#if 0
MEM_IN_STRUCT_P (dst_mem) ? mode[phase] : BLKmode,
#else
mode[phase],
#endif
gen_rtx_PLUS (Pmode, dest, GEN_INT (offset_st)));
active[phase] = false;
MEM_READONLY_P (dstp) = MEM_READONLY_P (dst_mem);
MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dst_mem);
MEM_IN_STRUCT_P (dstp) = 1;
emit_insn (gen_rtx_SET (VOIDmode, dstp, temp[phase]));
x = adjust_address (dst_mem, mode[phase], offset_st);
emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
offset_st += amount[phase];
}
}
while (active[next]);
}
void
mcore_expand_block_move (rtx dst_mem, rtx src_mem, rtx * operands)
bool
mcore_expand_block_move (rtx *operands)
{
int align = INTVAL (operands[3]);
int bytes;
HOST_WIDE_INT align, bytes, max;
if (GET_CODE (operands[2]) != CONST_INT)
return false;
bytes = INTVAL (operands[2]);
align = INTVAL (operands[3]);
if (GET_CODE (operands[2]) == CONST_INT)
if (bytes <= 0)
return false;
if (align > 4)
align = 4;
switch (align)
{
bytes = INTVAL (operands[2]);
if (bytes <= 0)
return;
if (align > 4)
align = 4;
/* RBE: bumped 1 and 2 byte align from 1 and 2 to 4 and 8 bytes before
we give up and go to memcpy. */
if ((align == 4 && (bytes <= 4*4
|| ((bytes & 01) == 0 && bytes <= 8*4)
|| ((bytes & 03) == 0 && bytes <= 16*4)))
|| (align == 2 && bytes <= 4*2)
|| (align == 1 && bytes <= 4*1))
{
block_move_sequence (operands[0], dst_mem, operands[1], src_mem,
bytes, align, 0);
return;
}
case 4:
if (bytes & 1)
max = 4*4;
else if (bytes & 3)
max = 8*4;
else
max = 16*4;
break;
case 2:
max = 4*2;
break;
case 1:
max = 4*1;
break;
default:
abort ();
}
if (bytes <= max)
{
block_move_sequence (operands[0], operands[1], bytes, align);
return true;
}
/* If we get here, just use the library routine. */
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "memcpy"), 0, VOIDmode, 3,
operands[0], Pmode, operands[1], Pmode, operands[2],
SImode);
return false;
}
......@@ -3104,7 +3093,7 @@ mcore_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
{
int arg_reg;
if (! named)
if (! named || mode == VOIDmode)
return 0;
if (targetm.calls.must_pass_in_stack (mode, type))
......
......@@ -2854,12 +2854,10 @@
""
"
{
rtx dest_mem = operands[0];
rtx src_mem = operands[1];
operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
mcore_expand_block_move (dest_mem, src_mem, operands);
DONE;
if (mcore_expand_block_move (operands))
DONE;
else
FAIL;
}")
;; ;;; ??? These patterns are meant to be generated from expand_block_move,
......
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