* optabs.h (OTI_movmisalign, movmisalign_optab): New.
* optabs.c (init_optabs): Create it.
* genopinit.c (optabs): Initialize it.
* expr.c (expand_expr_real_1) <MISALIGNED_INDIRECT_REF>: Use it.
* tree-vectorizer.c (vect_supportable_dr_alignment): Likewise.
* target-def.h (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
* target.h (vectorize.misaligned_mem_ok): Remove.
* targhooks.c (default_vect_misaligned_mem_ok): Remove.
* doc/md.texi (movmisalign): New.
* doc/tm.texi (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
From-SVN: r92537
+2004-12-22 Richard Henderson <rth@redhat.com>
+
+ * optabs.h (OTI_movmisalign, movmisalign_optab): New.
+ * optabs.c (init_optabs): Create it.
+ * genopinit.c (optabs): Initialize it.
+ * expr.c (expand_expr_real_1) <MISALIGNED_INDIRECT_REF>: Use it.
+ * tree-vectorizer.c (vect_supportable_dr_alignment): Likewise.
+ * target-def.h (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
+ * target.h (vectorize.misaligned_mem_ok): Remove.
+ * targhooks.c (default_vect_misaligned_mem_ok): Remove.
+ * doc/md.texi (movmisalign): New.
+ * doc/tm.texi (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
+
2004-12-22 Richard Henderson <rth@redhat.com>
* config/i386/emmintrin.h (_mm_loadh_pd): Don't cast pointer arg
the @samp{movstrict@var{m}} instruction is guaranteed not to alter
any of the register except the part which belongs to mode @var{m}.
+@cindex @code{movmisalign@var{m}} instruction pattern
+@item @samp{movmisalign@var{m}}
+This variant of a move pattern is designed to load or store a value
+from a memory address that is not naturally aligned for its mode.
+For a store, the memory will be in operand 0; for a load, the memory
+will be in operand 1. The other operand is guaranteed not to be a
+memory, so that it's easy to tell whether this is a load or store.
+
+This pattern is used by the autovectorizer, and when expanding a
+@code{MISALIGNED_INDIRECT_REF} expression.
+
@cindex @code{load_multiple} instruction pattern
@item @samp{load_multiple}
Load several consecutive memory locations into consecutive registers.
of TLS symbols for various targets.
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_VECTORIZE_MISALIGNED_MEM_OK (@var{mode})
-This hook should return true if a move* pattern to/from memory
-can be generated for machine_mode @var{mode} even if the memory location
-is unaligned.
-If a move* of data to/from unaligned memory locations is not supported for
-machine_mode @var{mode}, the hook should return false.
-This hook is used by the autovectorizer, and when expanding a
-@code{MISALIGNED_INDIRECT_REF} expression.
-@end deftypefn
-
@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void)
This hook should return the DECL of a function @var{f} that given an
address @var{addr} as an argument returns a mask @var{m} that can be
tree exp1 = TREE_OPERAND (exp, 0);
tree orig;
- if (code == MISALIGNED_INDIRECT_REF
- && !targetm.vectorize.misaligned_mem_ok (mode))
- abort ();
-
if (modifier != EXPAND_WRITE)
{
tree t;
orig = exp;
set_mem_attributes (temp, orig, 0);
+ /* Resolve the misalignment now, so that we don't have to remember
+ to resolve it later. Of course, this only works for reads. */
+ /* ??? When we get around to supporting writes, we'll have to handle
+ this in store_expr directly. The vectorizer isn't generating
+ those yet, however. */
+ if (code == MISALIGNED_INDIRECT_REF)
+ {
+ int icode;
+ rtx reg, insn;
+
+ gcc_assert (modifier == EXPAND_NORMAL);
+
+ /* The vectorizer should have already checked the mode. */
+ icode = movmisalign_optab->handlers[mode].insn_code;
+ gcc_assert (icode != CODE_FOR_nothing);
+
+ /* We've already validated the memory, and we're creating a
+ new pseudo destination. The predicates really can't fail. */
+ reg = gen_reg_rtx (mode);
+
+ /* Nor can the insn generator. */
+ insn = GEN_FCN (icode) (reg, temp);
+ emit_insn (insn);
+
+ return reg;
+ }
+
return temp;
}
"parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
"mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
"movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
+ "movmisalign_optab->handlers[$A].insn_code = CODE_FOR_$(movmisalign$a$)",
"cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
"tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
"addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
vec_set_optab = init_optab (UNKNOWN);
vec_init_optab = init_optab (UNKNOWN);
vec_realign_load_optab = init_optab (UNKNOWN);
+ movmisalign_optab = init_optab (UNKNOWN);
/* Conversions. */
sext_optab = init_convert_optab (SIGN_EXTEND);
OTI_mov,
/* Move, preserving high part of register. */
OTI_movstrict,
+ /* Move, with a misaligned memory. */
+ OTI_movmisalign,
/* Unary operations */
/* Negation */
#define mov_optab (optab_table[OTI_mov])
#define movstrict_optab (optab_table[OTI_movstrict])
+#define movmisalign_optab (optab_table[OTI_movmisalign])
#define neg_optab (optab_table[OTI_neg])
#define negv_optab (optab_table[OTI_negv])
TARGET_SCHED_DFA_NEW_CYCLE, \
TARGET_SCHED_IS_COSTLY_DEPENDENCE}
-#ifndef TARGET_VECTORIZE_MISALIGNED_MEM_OK
-#define TARGET_VECTORIZE_MISALIGNED_MEM_OK default_vect_misaligned_mem_ok
-#endif
#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD 0
#define TARGET_VECTORIZE \
- {TARGET_VECTORIZE_MISALIGNED_MEM_OK, \
- TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD}
+ {TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD}
/* In except.c */
#define TARGET_EH_RETURN_FILTER_MODE default_eh_return_filter_mode
/* Functions relating to vectorization. */
struct vectorize
{
- /* The following member value is a pointer to a function called
- by te vectorizer, and when expanding a MISALIGNED_INDIRECT_REF
- expression. If the hook returns true (false) then a move* pattern
- to/from memory can (cannot) be generated for this mode even if the
- memory location is unaligned. */
- bool (* misaligned_mem_ok) (enum machine_mode);
-
/* The following member value is a pointer to a function called
by the vectorizer, and return the decl of the target builtin
function. */
}
}
-bool
-default_vect_misaligned_mem_ok (enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return !STRICT_ALIGNMENT;
-}
-
bool
hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
|| targetm.vectorize.builtin_mask_for_load ()))
return dr_unaligned_software_pipeline;
- if (targetm.vectorize.misaligned_mem_ok (mode))
- /* Can't software pipeline the loads. */
+ if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
+ /* Can't software pipeline the loads, but can at least do them. */
return dr_unaligned_supported;
}