aboutsummaryrefslogtreecommitdiff
path: root/gcc/internal-fn.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/internal-fn.cc')
-rw-r--r--gcc/internal-fn.cc39
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index bec60cd..278db7b 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -175,6 +175,7 @@ init_internal_fns ()
#define len_store_direct { 3, 3, false }
#define len_maskstore_direct { 4, 5, false }
#define vec_set_direct { 3, 3, false }
+#define vec_extract_direct { 3, 3, false }
#define unary_direct { 0, 0, true }
#define unary_convert_direct { -1, 0, true }
#define binary_direct { 0, 0, true }
@@ -3107,6 +3108,43 @@ expand_vec_set_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
gcc_unreachable ();
}
+/* Expand VEC_EXTRACT optab internal function. */
+
+static void
+expand_vec_extract_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
+{
+ tree lhs = gimple_call_lhs (stmt);
+ tree op0 = gimple_call_arg (stmt, 0);
+ tree op1 = gimple_call_arg (stmt, 1);
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+
+ machine_mode outermode = TYPE_MODE (TREE_TYPE (op0));
+ machine_mode extract_mode = TYPE_MODE (TREE_TYPE (lhs));
+
+ rtx src = expand_normal (op0);
+ rtx pos = expand_normal (op1);
+
+ class expand_operand ops[3];
+ enum insn_code icode = convert_optab_handler (optab, outermode,
+ extract_mode);
+
+ if (icode != CODE_FOR_nothing)
+ {
+ create_output_operand (&ops[0], target, extract_mode);
+ create_input_operand (&ops[1], src, outermode);
+ create_convert_operand_from (&ops[2], pos,
+ TYPE_MODE (TREE_TYPE (op1)), true);
+ if (maybe_expand_insn (icode, 3, ops))
+ {
+ if (!rtx_equal_p (target, ops[0].value))
+ emit_move_insn (target, ops[0].value);
+ return;
+ }
+ }
+ gcc_unreachable ();
+}
+
static void
expand_ABNORMAL_DISPATCHER (internal_fn, gcall *)
{
@@ -3946,6 +3984,7 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
#define direct_mask_fold_left_optab_supported_p direct_optab_supported_p
#define direct_check_ptrs_optab_supported_p direct_optab_supported_p
#define direct_vec_set_optab_supported_p direct_optab_supported_p
+#define direct_vec_extract_optab_supported_p direct_optab_supported_p
/* Return the optab used by internal function FN. */