From 266007a7d6985c467758bbb61b3b23667de075cf Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Fri, 14 Aug 1992 07:40:16 -0400 Subject: [PATCH] (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 --- gcc/expr.c | 105 +++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/gcc/expr.c b/gcc/expr.c index ef537e91696..1959bf9055d 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -113,7 +113,7 @@ static char direct_store[NUM_MACHINE_MODES]; a block move. */ #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 #else /* A value of around 6 would minimize code size; infinity would minimize @@ -122,6 +122,9 @@ static char direct_store[NUM_MACHINE_MODES]; #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. */ #ifndef SLOW_UNALIGNED_ACCESS @@ -129,7 +132,7 @@ static char direct_store[NUM_MACHINE_MODES]; #endif /* 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 init_expr_once () @@ -169,9 +172,32 @@ init_expr_once () SET_SRC (pat) = reg; SET_DEST (pat) = mem; direct_store[(int) mode] = (recog (pat, insn, &num_clobbers)) >= 0; + + movstr_optab[(int) mode] = CODE_FOR_nothing; } 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. */ @@ -1142,56 +1168,39 @@ emit_block_move (x, y, size, align) /* Try the most limited insn first, because there's no point including more than one in the machine description unless the more limited one has some advantage. */ -#ifdef HAVE_movstrqi - if (HAVE_movstrqi - && GET_CODE (size) == CONST_INT - && ((unsigned) INTVAL (size) - < (1 << (GET_MODE_BITSIZE (QImode) - 1)))) - { - 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) + + enum machine_mode mode; + + for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; + mode = GET_MODE_WIDER_MODE (mode)) { - rtx insn = gen_movstrdi (x, y, size, GEN_INT (align)); - if (insn) + enum insn_code code = movstr_optab[(int) mode]; + 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); - return; + rtx op2 = size; + 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 emit_library_call (memcpy_libfunc, 1, -- 2.30.2