diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000-c.c')
-rw-r--r-- | gcc/config/rs6000/rs6000-c.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index 063d4acfafb..aec9a5e0b81 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -6620,6 +6620,10 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, default: break; + case E_V1TImode: + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V1TI]; + break; + case E_V2DFmode: call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF]; break; @@ -6736,11 +6740,13 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, /* If we can use the VSX xxpermdi instruction, use that for insert. */ mode = TYPE_MODE (arg1_type); if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode) - && TREE_CODE (arg2) == INTEGER_CST - && wi::ltu_p (wi::to_wide (arg2), 2)) + && TREE_CODE (arg2) == INTEGER_CST) { + wide_int selector = wi::to_wide (arg2); + selector = wi::umod_trunc (selector, 2); tree call = NULL_TREE; + arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector); if (mode == V2DFmode) call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF]; else if (mode == V2DImode) @@ -6752,11 +6758,12 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, return build_call_expr (call, 3, arg1, arg0, arg2); } else if (mode == V1TImode && VECTOR_UNIT_VSX_P (mode) - && TREE_CODE (arg2) == INTEGER_CST - && wi::eq_p (wi::to_wide (arg2), 0)) + && TREE_CODE (arg2) == INTEGER_CST) { tree call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V1TI]; + wide_int selector = wi::zero(32); + arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector); /* Note, __builtin_vec_insert_<xxx> has vector and scalar types reversed. */ return build_call_expr (call, 3, arg1, arg0, arg2); @@ -6764,10 +6771,13 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */ arg1_inner_type = TREE_TYPE (arg1_type); - arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, - build_int_cst (TREE_TYPE (arg2), - TYPE_VECTOR_SUBPARTS (arg1_type) - - 1), 0); + if (TYPE_VECTOR_SUBPARTS (arg1_type) == 1) + arg2 = build_int_cst (TREE_TYPE (arg2), 0); + else + arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, + build_int_cst (TREE_TYPE (arg2), + TYPE_VECTOR_SUBPARTS (arg1_type) + - 1), 0); decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type); DECL_EXTERNAL (decl) = 0; TREE_PUBLIC (decl) = 0; |