Commit 266007a7 by Richard Kenner

(movstr_optab): New variable.

(init_expr_once): Initialize it.
(emit_block_move): Rework code that generates movstrxx insns to check
predicates and use an optab.

From-SVN: r1827
parent efb07da7
...@@ -113,7 +113,7 @@ static char direct_store[NUM_MACHINE_MODES]; ...@@ -113,7 +113,7 @@ static char direct_store[NUM_MACHINE_MODES];
a block move. */ a block move. */
#ifndef MOVE_RATIO #ifndef MOVE_RATIO
#if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) #if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) || defined (HAVE_movstrti)
#define MOVE_RATIO 2 #define MOVE_RATIO 2
#else #else
/* A value of around 6 would minimize code size; infinity would minimize /* A value of around 6 would minimize code size; infinity would minimize
...@@ -122,6 +122,9 @@ static char direct_store[NUM_MACHINE_MODES]; ...@@ -122,6 +122,9 @@ static char direct_store[NUM_MACHINE_MODES];
#endif #endif
#endif #endif
/* This array records the insn_code of insns to perform block moves. */
static enum insn_code movstr_optab[NUM_MACHINE_MODES];
/* SLOW_UNALIGNED_ACCESS is non-zero if unaligned accesses are very slow. */ /* SLOW_UNALIGNED_ACCESS is non-zero if unaligned accesses are very slow. */
#ifndef SLOW_UNALIGNED_ACCESS #ifndef SLOW_UNALIGNED_ACCESS
...@@ -129,7 +132,7 @@ static char direct_store[NUM_MACHINE_MODES]; ...@@ -129,7 +132,7 @@ static char direct_store[NUM_MACHINE_MODES];
#endif #endif
/* This is run once per compilation to set up which modes can be used /* This is run once per compilation to set up which modes can be used
directly in memory. */ directly in memory and to initialize the block move optab. */
void void
init_expr_once () init_expr_once ()
...@@ -169,9 +172,32 @@ init_expr_once () ...@@ -169,9 +172,32 @@ init_expr_once ()
SET_SRC (pat) = reg; SET_SRC (pat) = reg;
SET_DEST (pat) = mem; SET_DEST (pat) = mem;
direct_store[(int) mode] = (recog (pat, insn, &num_clobbers)) >= 0; direct_store[(int) mode] = (recog (pat, insn, &num_clobbers)) >= 0;
movstr_optab[(int) mode] = CODE_FOR_nothing;
} }
end_sequence (); end_sequence ();
#ifdef HAVE_movstrqi
if (HAVE_movstrqi)
movstr_optab[(int) QImode] = CODE_FOR_movstrqi;
#endif
#ifdef HAVE_movstrhi
if (HAVE_movstrhi)
movstr_optab[(int) HImode] = CODE_FOR_movstrhi;
#endif
#ifdef HAVE_movstrsi
if (HAVE_movstrsi)
movstr_optab[(int) SImode] = CODE_FOR_movstrsi;
#endif
#ifdef HAVE_movstrdi
if (HAVE_movstrdi)
movstr_optab[(int) DImode] = CODE_FOR_movstrdi;
#endif
#ifdef HAVE_movstrti
if (HAVE_movstrti)
movstr_optab[(int) TImode] = CODE_FOR_movstrti;
#endif
} }
/* This is run at the start of compiling a function. */ /* This is run at the start of compiling a function. */
...@@ -1142,56 +1168,39 @@ emit_block_move (x, y, size, align) ...@@ -1142,56 +1168,39 @@ emit_block_move (x, y, size, align)
/* Try the most limited insn first, because there's no point /* Try the most limited insn first, because there's no point
including more than one in the machine description unless including more than one in the machine description unless
the more limited one has some advantage. */ the more limited one has some advantage. */
#ifdef HAVE_movstrqi
if (HAVE_movstrqi enum machine_mode mode;
&& GET_CODE (size) == CONST_INT
&& ((unsigned) INTVAL (size) for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
< (1 << (GET_MODE_BITSIZE (QImode) - 1)))) mode = GET_MODE_WIDER_MODE (mode))
{
rtx insn = gen_movstrqi (x, y, size, GEN_INT (align));
if (insn)
{
emit_insn (insn);
return;
}
}
#endif
#ifdef HAVE_movstrhi
if (HAVE_movstrhi
&& GET_CODE (size) == CONST_INT
&& ((unsigned) INTVAL (size)
< (1 << (GET_MODE_BITSIZE (HImode) - 1))))
{
rtx insn = gen_movstrhi (x, y, size, GEN_INT (align));
if (insn)
{
emit_insn (insn);
return;
}
}
#endif
#ifdef HAVE_movstrsi
if (HAVE_movstrsi)
{
rtx insn = gen_movstrsi (x, y, size, GEN_INT (align));
if (insn)
{
emit_insn (insn);
return;
}
}
#endif
#ifdef HAVE_movstrdi
if (HAVE_movstrdi)
{ {
rtx insn = gen_movstrdi (x, y, size, GEN_INT (align)); enum insn_code code = movstr_optab[(int) mode];
if (insn) rtx opalign = GEN_INT (align);
if (code != CODE_FOR_nothing
&& GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT
&& (unsigned) INTVAL (size) <= GET_MODE_MASK (mode)
&& (*insn_operand_predicate[(int) code][0]) (x, Pmode)
&& (*insn_operand_predicate[(int) code][1]) (y, Pmode)
&& (*insn_operand_predicate[(int) code][3]) (opalign, VOIDmode))
{ {
emit_insn (insn); rtx op2 = size;
return; rtx last = get_last_insn ();
rtx pat;
if (! (*insn_operand_predicate[(int) code][2]) (op2, mode))
op2 = copy_to_mode_reg (mode, op2);
pat = GEN_FCN ((int) code) (x, y, op2, opalign);
if (pat)
{
emit_insn (pat);
return;
}
else
delete_insns_since (last);
} }
} }
#endif
#ifdef TARGET_MEM_FUNCTIONS #ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memcpy_libfunc, 1, emit_library_call (memcpy_libfunc, 1,
......
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