[gcc(refs/users/wschmidt/heads/builtins4)] rs6000: Update the overloading logic
William Schmidt
wschmidt@gcc.gnu.org
Mon Nov 23 21:34:19 GMT 2020
https://gcc.gnu.org/g:adcf0eba77ebeb97a7b1f20d0987cea0b0273b0b
commit adcf0eba77ebeb97a7b1f20d0987cea0b0273b0b
Author: Bill Schmidt <wschmidt@linux.ibm.com>
Date: Mon Nov 23 15:34:00 2020 -0600
rs6000: Update the overloading logic
2020-11-23 Bill Schmidt <wschmidt@linux.ibm.com>
gcc/
* config.gcc (extra_objs): Add rs6000-c.o; otherwise it isn't
included in the "ar" command and dependency ordering misfires.
* config/rs6000/altivec.h (vec_mul): Remove.
(vec_extract): Remove.
(vec_insert): Remove.
(vec_splats): Remove.
(vec_promote): Remove.
* config/rs6000/rs6000-c.c (altivec_build_new_resolved_builtin):
Fix argument list.
(rs6000_new_builtin_type_compatible): New.
(rs6000_builtin_type_compatible): Rewrite.
(altivec_build_resolved_builtin): Don't call
altivec_build_new_resolved_builtin.
(altivec_build_new_resolved_builtin): New.
* config/rs6000/rs6000-call.c (rs6000_invalid_new_builtin): New.
(rs6000_new_builtin_decl): New.
(rs6000_builtin_decl): Call rs6000_new_builtin_decl.
* config/rs6000/r6000-gen-builtins.c (max_ovld_args): New
initialized filescope variable.
(parse_ovld_entry): Update max_ovld_args.
(write_decls): Change RS6000_OVLD_* entries to be one per stanza;
output rs6000_ovld_instances and MAX_OVLD_ARGS; remove hash class
instances; add ovldrecord and change rs6000_overload_info to use
it; output declarations of rs6000_new_builtin_is_supported_p and
rs6000_builtin_decl.
(write_ovld_static_init): Write static initializer for
rs6000_overload_info; update initializer for rs6000_instance_info.
(write_init_bif_table): Remove hashing stuff.
(write_init_ovld_table): Update initialization for each stanza;
remove hashing stuff.
(write_init_file): Remove hashing stuff.
* config/rs6000/rs6000-overload.def (VEC_ADDE): Update commentary.
(VEC_EXTRACTM): Alphabetize.
(VEC_EXTRACT): New empty stanza.
(VEC_INSERT): Likewise.
(VEC_MUL): New partial stanza.
(VEC_PROMOTE): New empty stanza.
(VEC_SPLATS): Likewise.
(VEC_STEP): Likewise.
(VEC_VSIE): Correct builtins mapped to.
Diff:
---
gcc/config.gcc | 1 +
gcc/config/rs6000/altivec.h | 6 -
gcc/config/rs6000/rs6000-c.c | 425 ++++++++++++++------------------
gcc/config/rs6000/rs6000-call.c | 95 ++++++-
gcc/config/rs6000/rs6000-gen-builtins.c | 180 ++++++--------
gcc/config/rs6000/rs6000-overload.def | 77 +++---
6 files changed, 408 insertions(+), 376 deletions(-)
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 8e5a8419f1d..93489914b13 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -511,6 +511,7 @@ powerpc*-*-*)
cpu_type=rs6000
extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
extra_objs="${extra_objs} rs6000-call.o rs6000-builtins.o"
+ extra_objs="${extra_objs} rs6000-c.o"
extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h"
extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h"
extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h"
diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index cfaf4fe2de8..9ffeb3dda17 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -61,12 +61,6 @@
/* Functions that are resolved by the backend to one of the
typed builtins. */
#define vec_rlnm(a,b,c) (__builtin_vec_rlnm((a),((c)<<8)|(b)))
-#define vec_mul __builtin_vec_mul
-
-#define vec_extract __builtin_vec_extract
-#define vec_insert __builtin_vec_insert
-#define vec_splats __builtin_vec_splats
-#define vec_promote __builtin_vec_promote
#ifdef __VSX__
/* VSX additions */
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index c6f0b88ac16..0c00c5881b2 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -39,8 +39,8 @@
static tree
-altivec_build_new_resolved_builtin (tree *, int,
- const struct altivec_builtin_types *);
+altivec_build_new_resolved_builtin (tree *, int, bifdata *,
+ rs6000_gen_builtins, rs6000_gen_builtins);
static tree
altivec_resolve_new_overloaded_builtin (location_t, tree, void *);
@@ -814,20 +814,25 @@ is_float128_p (tree t)
&& t == long_double_type_node));
}
-static inline bool
-rs6000_builtin_type_compatible (tree t, int id)
+static bool
+rs6000_new_builtin_type_compatible (tree t, tree u)
{
- tree builtin_type;
- builtin_type = rs6000_builtin_type (id);
if (t == error_mark_node)
return false;
- if (INTEGRAL_TYPE_P (t) && INTEGRAL_TYPE_P (builtin_type))
+ if (INTEGRAL_TYPE_P (t) && INTEGRAL_TYPE_P (u))
return true;
else if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
- && is_float128_p (t) && is_float128_p (builtin_type))
+ && is_float128_p (t) && is_float128_p (u))
return true;
else
- return lang_hooks.types_compatible_p (t, builtin_type);
+ return lang_hooks.types_compatible_p (t, u);
+}
+
+static inline bool
+rs6000_builtin_type_compatible (tree t, int id)
+{
+ tree builtin_type = rs6000_builtin_type (id);
+ return rs6000_new_builtin_type_compatible (t, builtin_type);
}
@@ -858,9 +863,6 @@ static tree
altivec_build_resolved_builtin (tree *args, int n,
const struct altivec_builtin_types *desc)
{
- if (new_builtins_are_live)
- return altivec_build_new_resolved_builtin (args, n, desc);
-
tree impl_fndecl = rs6000_builtin_decls[desc->overloaded_code];
tree ret_type = rs6000_builtin_type (desc->ret_type);
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl));
@@ -1933,17 +1935,17 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
a small exception for vec_{all,any}_{ge,le} predicates. */
static tree
-altivec_build_new_resolved_builtin (tree *args, int n,
- const struct altivec_builtin_types *desc)
+altivec_build_new_resolved_builtin (tree *args, int n, bifdata *fndata,
+ rs6000_gen_builtins bif_id,
+ rs6000_gen_builtins ovld_id)
{
- tree impl_fndecl = rs6000_builtin_decls[desc->overloaded_code];
- tree ret_type = rs6000_builtin_type (desc->ret_type);
- tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl));
- tree arg_type[4];
+ tree ret_type = TREE_VALUE (fndata->fntype);
+ tree argtypes = TREE_CHAIN (fndata->fntype);
+ tree arg_type[MAX_OVLD_ARGS];
+ tree fndecl = rs6000_builtin_decls_x[bif_id];
tree call;
- int i;
- for (i = 0; i < n; i++)
+ for (int i = 0; i < n; i++)
arg_type[i] = TREE_VALUE (argtypes), argtypes = TREE_CHAIN (argtypes);
/* The AltiVec overloading implementation is overall gross, but this
@@ -1957,9 +1959,9 @@ altivec_build_new_resolved_builtin (tree *args, int n,
argument) is reversed. Patch the arguments here before building
the resolved CALL_EXPR. */
if (n == 3
- && desc->code == ALTIVEC_BUILTIN_VEC_VCMPGE_P
- && desc->overloaded_code != ALTIVEC_BUILTIN_VCMPGEFP_P
- && desc->overloaded_code != VSX_BUILTIN_XVCMPGEDP_P)
+ && ovld_id == RS6000_OVLD_VEC_CMPGE_P
+ && bif_id != RS6000_BIF_VCMPGEFP_P
+ && bif_id != RS6000_BIF_XVCMPGEDP_P)
{
std::swap (args[1], args[2]);
std::swap (arg_type[1], arg_type[2]);
@@ -1968,28 +1970,32 @@ altivec_build_new_resolved_builtin (tree *args, int n,
build_int_cst (NULL_TREE, 2));
}
+ /* If the number of arguments to an overloaded function increases,
+ we must expand this switch. */
+ gcc_assert (MAX_OVLD_ARGS <= 4);
+
switch (n)
{
case 0:
- call = build_call_expr (impl_fndecl, 0);
+ call = build_call_expr (fndecl, 0);
break;
case 1:
- call = build_call_expr (impl_fndecl, 1,
+ call = build_call_expr (fndecl, 1,
fully_fold_convert (arg_type[0], args[0]));
break;
case 2:
- call = build_call_expr (impl_fndecl, 2,
+ call = build_call_expr (fndecl, 2,
fully_fold_convert (arg_type[0], args[0]),
fully_fold_convert (arg_type[1], args[1]));
break;
case 3:
- call = build_call_expr (impl_fndecl, 3,
+ call = build_call_expr (fndecl, 3,
fully_fold_convert (arg_type[0], args[0]),
fully_fold_convert (arg_type[1], args[1]),
fully_fold_convert (arg_type[2], args[2]));
break;
case 4:
- call = build_call_expr (impl_fndecl, 4,
+ call = build_call_expr (fndecl, 4,
fully_fold_convert (arg_type[0], args[0]),
fully_fold_convert (arg_type[1], args[1]),
fully_fold_convert (arg_type[2], args[2]),
@@ -2010,14 +2016,14 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
{
vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
unsigned int nargs = vec_safe_length (arglist);
- enum rs6000_builtins fcode
- = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
+ enum rs6000_gen_builtins fcode
+ = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
- tree types[4], args[4];
- const struct altivec_builtin_types *desc;
+ tree types[MAX_OVLD_ARGS], args[MAX_OVLD_ARGS];
unsigned int n;
- if (!rs6000_overloaded_builtin_p (fcode))
+ /* Return immediately if this isn't an overload. */
+ if (fcode <= RS6000_OVLD_NONE)
return NULL_TREE;
if (TARGET_DEBUG_BUILTIN)
@@ -2025,16 +2031,16 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
(int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)));
/* vec_lvsl and vec_lvsr are deprecated for use with LE element order. */
- if (fcode == ALTIVEC_BUILTIN_VEC_LVSL && !BYTES_BIG_ENDIAN)
+ if (fcode == RS6000_OVLD_VEC_LVSL && !BYTES_BIG_ENDIAN)
warning (OPT_Wdeprecated,
"%<vec_lvsl%> is deprecated for little endian; use "
"assignment for unaligned loads and stores");
- else if (fcode == ALTIVEC_BUILTIN_VEC_LVSR && !BYTES_BIG_ENDIAN)
+ else if (fcode == RS6000_OVLD_VEC_LVSR && !BYTES_BIG_ENDIAN)
warning (OPT_Wdeprecated,
"%<vec_lvsr%> is deprecated for little endian; use "
"assignment for unaligned loads and stores");
- if (fcode == ALTIVEC_BUILTIN_VEC_MUL)
+ if (fcode == RS6000_OVLD_VEC_MUL)
{
/* vec_mul needs to be special cased because there are no instructions
for it for the {un}signed char, {un}signed short, and {un}signed int
@@ -2071,13 +2077,13 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
case E_SFmode:
{
/* For floats use the xvmulsp instruction directly. */
- tree call = rs6000_builtin_decls[VSX_BUILTIN_XVMULSP];
+ tree call = rs6000_builtin_decls_x[RS6000_BIF_XVMULSP];
return build_call_expr (call, 2, arg0, arg1);
}
case E_DFmode:
{
/* For doubles use the xvmuldp instruction directly. */
- tree call = rs6000_builtin_decls[VSX_BUILTIN_XVMULDP];
+ tree call = rs6000_builtin_decls_x[RS6000_BIF_XVMULDP];
return build_call_expr (call, 2, arg0, arg1);
}
/* Other types are errors. */
@@ -2086,7 +2092,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
}
}
- if (fcode == ALTIVEC_BUILTIN_VEC_CMPNE)
+ if (fcode == RS6000_OVLD_VEC_CMPNE)
{
/* vec_cmpne needs to be special cased because there are no instructions
for it (prior to power 9). */
@@ -2135,8 +2141,8 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
vec<tree, va_gc> *params = make_tree_vector ();
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- tree call = altivec_resolve_overloaded_builtin
- (loc, rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_CMPEQ],
+ tree call = altivec_resolve_new_overloaded_builtin
+ (loc, rs6000_builtin_decls_x[RS6000_OVLD_VEC_CMPEQ],
params);
/* Use save_expr to ensure that operands used more than once
that may have side effects (like calls) are only evaluated
@@ -2145,8 +2151,8 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
params = make_tree_vector ();
vec_safe_push (params, call);
vec_safe_push (params, call);
- return altivec_resolve_overloaded_builtin
- (loc, rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_NOR], params);
+ return altivec_resolve_new_overloaded_builtin
+ (loc, rs6000_builtin_decls_x[RS6000_OVLD_VEC_NOR], params);
}
/* Other types are errors. */
default:
@@ -2156,15 +2162,14 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
/* else, fall through and process the Power9 alternative below */
}
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDE
- || fcode == ALTIVEC_BUILTIN_VEC_SUBE)
+ if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
{
/* vec_adde needs to be special cased because there is no instruction
for the {un}signed int version. */
if (nargs != 3)
{
- const char *name = fcode == ALTIVEC_BUILTIN_VEC_ADDE ?
- "vec_adde": "vec_sube";
+ const char *name
+ = fcode == RS6000_OVLD_VEC_ADDE ? "vec_adde": "vec_sube";
error ("builtin %qs only accepts 3 arguments", name);
return error_mark_node;
}
@@ -2199,14 +2204,15 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDE)
- add_sub_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
+ if (fcode == RS6000_OVLD_VEC_ADDE)
+ add_sub_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_ADD];
else
- add_sub_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_SUB];
+ add_sub_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_SUB];
- tree call = altivec_resolve_overloaded_builtin (loc,
- add_sub_builtin,
- params);
+ tree call
+ = altivec_resolve_new_overloaded_builtin (loc,
+ add_sub_builtin,
+ params);
tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
tree ones_vector = build_vector_from_val (arg0_type, const1);
tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
@@ -2214,22 +2220,14 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
params = make_tree_vector ();
vec_safe_push (params, call);
vec_safe_push (params, and_expr);
- return altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
- params);
+ return altivec_resolve_new_overloaded_builtin (loc,
+ add_sub_builtin,
+ params);
}
- /* For {un}signed __int128s use the vaddeuqm instruction
- directly. */
+ /* For {un}signed __int128s use the vaddeuqm/vsubeuqm instruction
+ directly. This is done by the normal processing. */
case E_TImode:
{
- tree bii;
-
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDE)
- bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDEUQM];
-
- else
- bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VSUBEUQM];
-
- return altivec_resolve_overloaded_builtin (loc, bii, arglist);
}
/* Types other than {un}signed int and {un}signed __int128
@@ -2239,14 +2237,13 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
}
}
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC
- || fcode == ALTIVEC_BUILTIN_VEC_SUBEC)
+ if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
{
/* vec_addec and vec_subec needs to be special cased because there is
no instruction for the {un}signed int version. */
if (nargs != 3)
{
- const char *name = fcode == ALTIVEC_BUILTIN_VEC_ADDEC ?
+ const char *name = fcode == RS6000_OVLD_VEC_ADDEC ?
"vec_addec": "vec_subec";
error ("builtin %qs only accepts 3 arguments", name);
return error_mark_node;
@@ -2288,25 +2285,27 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
- as_c_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADDC];
+ if (fcode == RS6000_OVLD_VEC_ADDEC)
+ as_c_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_ADDC];
else
- as_c_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_SUBC];
+ as_c_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_SUBC];
- tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
- params);
+ tree call1 = altivec_resolve_new_overloaded_builtin (loc,
+ as_c_builtin,
+ params);
params = make_tree_vector ();
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
- as_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
+ if (fcode == RS6000_OVLD_VEC_ADDEC)
+ as_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_ADD];
else
- as_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_SUB];
+ as_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_SUB];
- tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin,
- params);
+ tree call2 = altivec_resolve_new_overloaded_builtin (loc,
+ as_builtin,
+ params);
tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
tree ones_vector = build_vector_from_val (arg0_type, const1);
tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
@@ -2314,28 +2313,19 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
params = make_tree_vector ();
vec_safe_push (params, call2);
vec_safe_push (params, and_expr);
- call2 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
- params);
+ call2 = altivec_resolve_new_overloaded_builtin (loc, as_c_builtin,
+ params);
params = make_tree_vector ();
vec_safe_push (params, call1);
vec_safe_push (params, call2);
- tree or_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_OR];
- return altivec_resolve_overloaded_builtin (loc, or_builtin,
- params);
+ tree or_builtin = rs6000_builtin_decls_x[RS6000_OVLD_VEC_OR];
+ return altivec_resolve_new_overloaded_builtin (loc, or_builtin,
+ params);
}
/* For {un}signed __int128s use the vaddecuq/vsubbecuq
- instructions. */
+ instructions. This occurs through normal processing. */
case E_TImode:
{
- tree bii;
-
- if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
- bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDECUQ];
-
- else
- bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VSUBECUQ];
-
- return altivec_resolve_overloaded_builtin (loc, bii, arglist);
}
/* Types other than {un}signed int and {un}signed __int128
are errors. */
@@ -2345,28 +2335,28 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
}
/* For now treat vec_splats and vec_promote as the same. */
- if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS
- || fcode == ALTIVEC_BUILTIN_VEC_PROMOTE)
+ if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
{
tree type, arg;
int size;
int i;
bool unsigned_p;
vec<constructor_elt, va_gc> *vec;
- const char *name = fcode == ALTIVEC_BUILTIN_VEC_SPLATS ? "vec_splats": "vec_promote";
+ const char *name
+ = fcode == RS6000_OVLD_VEC_SPLATS ? "vec_splats": "vec_promote";
- if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS && nargs != 1)
+ if (fcode == RS6000_OVLD_VEC_SPLATS && nargs != 1)
{
error ("builtin %qs only accepts 1 argument", name);
return error_mark_node;
}
- if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE && nargs != 2)
+ if (fcode == RS6000_OVLD_VEC_PROMOTE && nargs != 2)
{
error ("builtin %qs only accepts 2 arguments", name);
return error_mark_node;
}
/* Ignore promote's element argument. */
- if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE
+ if (fcode == RS6000_OVLD_VEC_PROMOTE
&& !INTEGRAL_TYPE_P (TREE_TYPE ((*arglist)[1])))
goto bad;
@@ -2415,7 +2405,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
/* For now use pointer tricks to do the extraction, unless we are on VSX
extracting a double from a constant offset. */
- if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT)
+ if (fcode == RS6000_OVLD_VEC_EXTRACT)
{
tree arg1;
tree arg1_type;
@@ -2466,34 +2456,34 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
break;
case E_V1TImode:
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V1TI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V1TI];
break;
case E_V2DFmode:
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V2DF];
break;
case E_V2DImode:
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V2DI];
break;
case E_V4SFmode:
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SF];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V4SF];
break;
case E_V4SImode:
if (TARGET_DIRECT_MOVE_64BIT)
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V4SI];
break;
case E_V8HImode:
if (TARGET_DIRECT_MOVE_64BIT)
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V8HI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V8HI];
break;
case E_V16QImode:
if (TARGET_DIRECT_MOVE_64BIT)
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V16QI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V16QI];
break;
}
}
@@ -2508,27 +2498,27 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
break;
case E_V2DFmode:
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V2DF];
break;
case E_V2DImode:
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V2DI];
break;
case E_V4SFmode:
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SF];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V4SF];
break;
case E_V4SImode:
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V4SI];
break;
case E_V8HImode:
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V8HI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V8HI];
break;
case E_V16QImode:
- call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V16QI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_EXT_V16QI];
break;
}
}
@@ -2582,7 +2572,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
downstream in fold_build_cleanup_point_expr () it will get a
CLEANUP_POINT_EXPR. If it does not we can run into an ICE
later in gimplify_cleanup_point_expr (). Potentially this
- causes missed optimization because the actually is no side
+ causes missed optimization because there actually is no side
effect. */
if (c_dialect_cxx ())
TREE_SIDE_EFFECTS (stmt) = 1;
@@ -2592,7 +2582,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
/* For now use pointer tricks to do the insertion, unless we are on VSX
inserting a double to a constant offset.. */
- if (fcode == ALTIVEC_BUILTIN_VEC_INSERT)
+ if (fcode == RS6000_OVLD_VEC_INSERT)
{
tree arg0;
tree arg1;
@@ -2631,9 +2621,9 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
if (mode == V2DFmode)
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_SET_V2DF];
else if (mode == V2DImode)
- call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DI];
+ call = rs6000_builtin_decls_x[RS6000_BIF_VEC_SET_V2DI];
/* Note, __builtin_vec_insert_<xxx> has vector and scalar types
reversed. */
@@ -2643,7 +2633,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
else if (mode == V1TImode && VECTOR_UNIT_VSX_P (mode)
&& TREE_CODE (arg2) == INTEGER_CST)
{
- tree call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V1TI];
+ tree call = rs6000_builtin_decls_x[RS6000_BIF_VEC_SET_V1TI];
wide_int selector = wi::zero(32);
arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
@@ -2706,7 +2696,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
if (arg == error_mark_node)
return error_mark_node;
- if (n >= 4)
+ if (n >= MAX_OVLD_ARGS)
abort ();
arg = default_conversion (arg);
@@ -2740,9 +2730,9 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
arg = fold_convert (type, arg);
}
- /* For P9V_BUILTIN_VEC_LXVL, convert any const * to its non constant
+ /* For RS6000_OVLD_VEC_LXVL, convert any const * to its non constant
equivalent to simplify the overload matching below. */
- if (fcode == P9V_BUILTIN_VEC_LXVL)
+ if (fcode == RS6000_OVLD_VEC_LXVL)
{
if (POINTER_TYPE_P (type)
&& TYPE_READONLY (TREE_TYPE (type)))
@@ -2765,7 +2755,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
if (n == 0)
abort ();
- if (fcode == ALTIVEC_BUILTIN_VEC_STEP)
+ if (fcode == RS6000_OVLD_VEC_STEP)
{
if (TREE_CODE (types[0]) != VECTOR_TYPE)
goto bad;
@@ -2775,19 +2765,18 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
{
bool unsupported_builtin = false;
- enum rs6000_builtins overloaded_code;
+ enum rs6000_gen_builtins overloaded_code;
tree result = NULL;
- for (desc = altivec_overloaded_builtins;
- desc->code && desc->code != fcode; desc++)
- continue;
+ ovlddata *instance = rs6000_overload_info[fcode].first_instance;
+ gcc_assert (instance != NULL);
- /* Need to special case __builtin_cmp because the overloaded forms
+ /* Need to special case __builtin_cmpb because the overloaded forms
of this function take (unsigned int, unsigned int) or (unsigned
long long int, unsigned long long int). Since C conventions
allow the respective argument types to be implicitly coerced into
each other, the default handling does not provide adequate
discrimination between the desired forms of the function. */
- if (fcode == P6_OV_BUILTIN_CMPB)
+ if (fcode == RS6000_OVLD_SCAL_CMPB)
{
machine_mode arg1_mode = TYPE_MODE (types[0]);
machine_mode arg2_mode = TYPE_MODE (types[1]);
@@ -2804,38 +2793,38 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
|| (GET_MODE_PRECISION (arg2_mode) > 32))
{
/* Assure all argument and result types are compatible with
- the built-in function represented by P6_BUILTIN_CMPB. */
- overloaded_code = P6_BUILTIN_CMPB;
+ the built-in function represented by RS6000_BIF_CMPB. */
+ overloaded_code = RS6000_BIF_CMPB;
}
else
{
/* Assure all argument and result types are compatible with
- the built-in function represented by P6_BUILTIN_CMPB_32. */
- overloaded_code = P6_BUILTIN_CMPB_32;
+ the built-in function represented by RS6000_BIF_CMPB_32. */
+ overloaded_code = RS6000_BIF_CMPB_32;
}
- while (desc->code && desc->code == fcode
- && desc->overloaded_code != overloaded_code)
- desc++;
+ while (instance && instance->bifid != overloaded_code)
+ instance = instance->next;
- if (desc->code && (desc->code == fcode)
- && rs6000_builtin_type_compatible (types[0], desc->op1)
- && rs6000_builtin_type_compatible (types[1], desc->op2))
+ gcc_assert (instance != NULL);
+ bifdata *fndata = &rs6000_builtin_info_x[instance->bifid];
+ tree fntype = fndata->fntype;
+ tree parmtype0 = TREE_VALUE (TREE_CHAIN (fntype));
+ tree parmtype1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (fntype)));
+
+ if (rs6000_new_builtin_type_compatible (types[0], parmtype0)
+ && rs6000_new_builtin_type_compatible (types[1], parmtype1))
{
- if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
- {
- result = altivec_build_resolved_builtin (args, n, desc);
- /* overloaded_code is set above */
- if (!rs6000_builtin_is_supported_p (overloaded_code))
- unsupported_builtin = true;
- else
- return result;
- }
+ if (rs6000_builtin_decl (instance->bifid, false) != error_mark_node
+ && rs6000_new_builtin_is_supported_p (instance->bifid))
+ return altivec_build_new_resolved_builtin (args, n, fndata,
+ instance->bifid,
+ fcode);
else
unsupported_builtin = true;
}
}
- else if (fcode == P9V_BUILTIN_VEC_VSIEDP)
+ else if (fcode == RS6000_OVLD_VEC_VSIE)
{
machine_mode arg1_mode = TYPE_MODE (types[0]);
@@ -2854,9 +2843,9 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
that expects __ieee128 argument. Otherwise, expect
__int128 argument. */
if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
- overloaded_code = P9V_BUILTIN_VSIEQPF;
+ overloaded_code = RS6000_BIF_VSIEQPF;
else
- overloaded_code = P9V_BUILTIN_VSIEQP;
+ overloaded_code = RS6000_BIF_VSIEQP;
}
else
{
@@ -2864,116 +2853,78 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
that expects double argument. Otherwise, expect
long long int argument. */
if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
- overloaded_code = P9V_BUILTIN_VSIEDPF;
+ overloaded_code = RS6000_BIF_VSIEDPF;
else
- overloaded_code = P9V_BUILTIN_VSIEDP;
+ overloaded_code = RS6000_BIF_VSIEDP;
}
- while (desc->code && desc->code == fcode
- && desc->overloaded_code != overloaded_code)
- desc++;
- if (desc->code && (desc->code == fcode)
- && rs6000_builtin_type_compatible (types[0], desc->op1)
- && rs6000_builtin_type_compatible (types[1], desc->op2))
+ while (instance && instance->bifid != overloaded_code)
+ instance = instance->next;
+
+ gcc_assert (instance != NULL);
+ bifdata *fndata = &rs6000_builtin_info_x[instance->bifid];
+ tree fntype = fndata->fntype;
+ tree parmtype0 = TREE_VALUE (TREE_CHAIN (fntype));
+ tree parmtype1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (fntype)));
+
+ if (rs6000_new_builtin_type_compatible (types[0], parmtype0)
+ && rs6000_new_builtin_type_compatible (types[1], parmtype1))
{
- if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
- {
- result = altivec_build_resolved_builtin (args, n, desc);
- /* overloaded_code is set above. */
- if (!rs6000_builtin_is_supported_p (overloaded_code))
- unsupported_builtin = true;
- else
- return result;
- }
+ if (rs6000_builtin_decl (instance->bifid, false) != error_mark_node
+ && rs6000_new_builtin_is_supported_p (instance->bifid))
+ return altivec_build_new_resolved_builtin (args, n, fndata,
+ instance->bifid,
+ fcode);
else
unsupported_builtin = true;
}
}
- else if ((fcode == P10_BUILTIN_VEC_XXEVAL)
- || (fcode == P10V_BUILTIN_VXXPERMX))
+ else
{
- signed char op3_type;
-
- /* Need to special case P10_BUILTIN_VEC_XXEVAL and
- P10V_BUILTIN_VXXPERMX because they take 4 arguments and the
- existing infrastructure only handles three. */
- if (nargs != 4)
- {
- const char *name = fcode == P10_BUILTIN_VEC_XXEVAL ?
- "__builtin_vec_xxeval":"__builtin_vec_xxpermx";
-
- error ("builtin %qs requires 4 arguments", name);
- return error_mark_node;
- }
-
- for ( ; desc->code == fcode; desc++)
+ for (; instance != NULL; instance = instance->next)
{
- if (fcode == P10_BUILTIN_VEC_XXEVAL)
- op3_type = desc->op3;
- else /* P10V_BUILTIN_VXXPERMX */
- op3_type = RS6000_BTI_V16QI;
+ bool mismatch = false;
+ bifdata *fndata = &rs6000_builtin_info_x[instance->bifid];
+ tree nextparm = TREE_CHAIN (fndata->fntype);
- if (rs6000_builtin_type_compatible (types[0], desc->op1)
- && rs6000_builtin_type_compatible (types[1], desc->op2)
- && rs6000_builtin_type_compatible (types[2], desc->op3)
- && rs6000_builtin_type_compatible (types[2], op3_type)
- && rs6000_builtin_type_compatible (types[3],
- RS6000_BTI_UINTSI))
+ for (int arg_i = 0;
+ arg_i < fndata->nargs && nextparm != NULL;
+ arg_i++)
{
- if (rs6000_builtin_decls[desc->overloaded_code] == NULL_TREE)
- unsupported_builtin = true;
- else
+ tree parmtype = TREE_VALUE (nextparm);
+ if (!rs6000_new_builtin_type_compatible (types[arg_i],
+ parmtype))
{
- result = altivec_build_resolved_builtin (args, n, desc);
- if (rs6000_builtin_is_supported_p (desc->overloaded_code))
- return result;
- /* Allow loop to continue in case a different
- definition is supported. */
- overloaded_code = desc->overloaded_code;
- unsupported_builtin = true;
+ mismatch = true;
+ break;
}
+ nextparm = TREE_CHAIN (nextparm);
}
- }
- }
- else
- {
- /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in
- the opX fields. */
- for (; desc->code == fcode; desc++)
- {
- if ((desc->op1 == RS6000_BTI_NOT_OPAQUE
- || rs6000_builtin_type_compatible (types[0], desc->op1))
- && (desc->op2 == RS6000_BTI_NOT_OPAQUE
- || rs6000_builtin_type_compatible (types[1], desc->op2))
- && (desc->op3 == RS6000_BTI_NOT_OPAQUE
- || rs6000_builtin_type_compatible (types[2], desc->op3)))
+
+ if (mismatch)
+ continue;
+
+ if (rs6000_builtin_decl (instance->bifid, false) != error_mark_node
+ && rs6000_new_builtin_is_supported_p (instance->bifid))
+ return altivec_build_new_resolved_builtin (args, n, fndata,
+ instance->bifid,
+ fcode);
+ else
{
- if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
- {
- result = altivec_build_resolved_builtin (args, n, desc);
- if (!rs6000_builtin_is_supported_p (desc->overloaded_code))
- {
- /* Allow loop to continue in case a different
- definition is supported. */
- overloaded_code = desc->overloaded_code;
- unsupported_builtin = true;
- }
- else
- return result;
- }
- else
- unsupported_builtin = true;
+ unsupported_builtin = true;
+ break;
}
}
+ gcc_assert (unsupported_builtin);
}
if (unsupported_builtin)
{
- const char *name = rs6000_overloaded_builtin_name (fcode);
+ const char *name = rs6000_overload_info[fcode].ovld_name;
if (result != NULL)
{
const char *internal_name
- = rs6000_overloaded_builtin_name (overloaded_code);
+ = rs6000_builtin_info_x[instance->bifid].bifname;
/* An error message making reference to the name of the
non-overloaded function has already been issued. Add
clarification of the previous message. */
@@ -2990,7 +2941,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, tree fndecl,
}
bad:
{
- const char *name = rs6000_overloaded_builtin_name (fcode);
+ const char *name = rs6000_overload_info[fcode].ovld_name;
error ("invalid parameter combination for AltiVec intrinsic %qs", name);
return error_mark_node;
}
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 6b682d733ae..2a4dccf9567 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -11821,6 +11821,80 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
error ("%qs is not supported with the current options", name);
}
+/* Raise an error message for a builtin function that is called without the
+ appropriate target options being set. */
+
+static void
+rs6000_invalid_new_builtin (enum rs6000_gen_builtins fncode)
+{
+ size_t uns_fncode = (size_t) fncode;
+ const char *name = rs6000_builtin_info_x[uns_fncode].bifname;
+
+ switch (rs6000_builtin_info_x[uns_fncode].enable)
+ {
+ case ENB_P5:
+ error ("%qs requires the %qs option", name, "-mcpu=power5");
+ break;
+ case ENB_P6:
+ error ("%qs requires the %qs option", name, "-mcpu=power6");
+ break;
+ case ENB_ALTIVEC:
+ error ("%qs requires the %qs option", name, "-maltivec");
+ break;
+ case ENB_CELL:
+ error ("%qs is only valid for the cell processor", name);
+ break;
+ case ENB_VSX:
+ error ("%qs requires the %qs option", name, "-mvsx");
+ break;
+ case ENB_P7:
+ error ("%qs requires the %qs option", name, "-mcpu=power7");
+ break;
+ case ENB_P7_64:
+ error ("%qs requires the %qs option and either the %qs or %qs option",
+ name, "-mcpu=power7", "-m64", "-mpowerpc64");
+ break;
+ case ENB_P8:
+ error ("%qs requires the %qs option", name, "-mcpu=power8");
+ break;
+ case ENB_P8V:
+ error ("%qs requires the %qs option", name, "-mpower8-vector");
+ break;
+ case ENB_P9:
+ error ("%qs requires the %qs option", name, "-mcpu=power9");
+ break;
+ case ENB_P9_64:
+ error ("%qs requires the %qs option and either the %qs or %qs option",
+ name, "-mcpu=power9", "-m64", "-mpowerpc64");
+ break;
+ case ENB_P9V:
+ error ("%qs requires the %qs option", name, "-mpower9-vector");
+ break;
+ case ENB_IEEE128_HW:
+ error ("%qs requires ISA 3.0 IEEE 128-bit floating point", name);
+ break;
+ case ENB_DFP:
+ error ("%qs requires the %qs option", name, "-mhard-dfp");
+ break;
+ case ENB_CRYPTO:
+ error ("%qs requires the %qs option", name, "-mcrypto");
+ break;
+ case ENB_HTM:
+ error ("%qs requires the %qs option", name, "-mhtm");
+ break;
+ case ENB_P10:
+ error ("%qs requires the %qs option", name, "-mcpu=power10");
+ break;
+ case ENB_MMA:
+ error ("%qs requires the %qs option", name, "-mmma");
+ break;
+ default:
+ case ENB_ALWAYS:
+ gcc_unreachable ();
+ };
+ gcc_unreachable ();
+}
+
/* Target hook for early folding of built-ins, shamelessly stolen
from ia64.c. */
@@ -15913,12 +15987,31 @@ rs6000_init_builtins (void)
#endif
}
+static tree
+rs6000_new_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ rs6000_gen_builtins fcode = (rs6000_gen_builtins) code;
+
+ if (fcode >= RS6000_OVLD_MAX)
+ return error_mark_node;
+
+ if (!rs6000_new_builtin_is_supported_p (fcode))
+ {
+ rs6000_invalid_new_builtin (fcode);
+ return error_mark_node;
+ }
+
+ return rs6000_builtin_decls_x[code];
+}
+
/* Returns the rs6000 builtin decl for CODE. */
-/* #### TODO: Rewrite this. */
tree
rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
+ if (new_builtins_are_live)
+ return rs6000_new_builtin_decl (code, initialize_p);
+
HOST_WIDE_INT fnmask;
if (code >= RS6000_BUILTIN_COUNT)
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c b/gcc/config/rs6000/rs6000-gen-builtins.c
index c7f405e33fd..6fe3b929597 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -408,6 +408,7 @@ struct ovlddata {
static ovlddata ovlds[MAXOVLDS];
static int num_ovlds;
static int curr_ovld;
+static int max_ovld_args = 0;
/* Exit codes for the shell. */
enum exit_codes {
@@ -1899,6 +1900,9 @@ parse_ovld_entry ()
if (parse_prototype (&ovlds[curr_ovld].proto) == PC_PARSEFAIL)
return PC_PARSEFAIL;
+ if (ovlds[curr_ovld].proto.nargs > max_ovld_args)
+ max_ovld_args = ovlds[curr_ovld].proto.nargs;
+
/* Build a function type descriptor identifier from the return type
and argument types, and store it if it does not already exist. */
ovlds[curr_ovld].fndecl = construct_fntype_id (&ovlds[curr_ovld].proto);
@@ -2110,13 +2114,21 @@ write_decls ()
fprintf (header_file, " RS6000_BIF_%s,\n", bifs[bif_order[i]].idname);
fprintf (header_file, " RS6000_BIF_MAX,\n");
fprintf (header_file, " RS6000_OVLD_NONE,\n");
- for (int i = 0; i < num_ovlds; i++)
- fprintf (header_file, " RS6000_OVLD_%s,\n", ovlds[i].ovld_id_name);
+ for (int i = 0; i < num_ovld_stanzas; i++)
+ fprintf (header_file, " RS6000_OVLD_%s,\n", ovld_stanzas[i].stanza_id);
fprintf (header_file, " RS6000_OVLD_MAX\n};\n\n");
fprintf (header_file,
"extern tree rs6000_builtin_decls_x[RS6000_OVLD_MAX];\n\n");
+ fprintf (header_file,
+ "enum rs6000_ovld_instances\n{\n RS6000_INST_NONE,\n");
+ for (int i = 0; i <= curr_ovld; i++)
+ fprintf (header_file, " RS6000_INST_%s,\n", ovlds[i].ovld_id_name);
+ fprintf (header_file, " RS6000_INST_MAX\n};\n\n");
+
+ fprintf (header_file, "#define MAX_OVLD_ARGS %d\n", max_ovld_args);
+
fprintf (header_file, "enum restriction {\n");
fprintf (header_file, " RES_NONE,\n");
fprintf (header_file, " RES_BITS,\n");
@@ -2228,16 +2240,6 @@ write_decls ()
be removed as we progress. */
fprintf (header_file, "extern bifdata rs6000_builtin_info_x[];\n\n");
- fprintf (header_file,
- "struct rs6000_bif_hasher : nofree_ptr_hash<bifdata>\n");
- fprintf (header_file, "{\n");
- fprintf (header_file, " typedef const char *compare_type;\n\n");
- fprintf (header_file, " static hashval_t hash (bifdata *);\n");
- fprintf (header_file, " static bool equal (bifdata *, const char *);\n");
- fprintf (header_file, "};\n\n");
-
- fprintf (header_file, "extern hash_table<rs6000_bif_hasher> bif_hash;\n\n");
-
fprintf (header_file, "struct ovlddata\n");
fprintf (header_file, "{\n");
fprintf (header_file, " const char *bifname;\n");
@@ -2246,20 +2248,22 @@ write_decls ()
fprintf (header_file, " ovlddata *next;\n");
fprintf (header_file, "};\n\n");
- fprintf (header_file, "extern ovlddata rs6000_overload_info[];\n\n");
-
- fprintf (header_file,
- "struct rs6000_ovld_hasher : nofree_ptr_hash<ovlddata>\n");
+ fprintf (header_file, "struct ovldrecord\n");
fprintf (header_file, "{\n");
- fprintf (header_file, " typedef const char *compare_type;\n\n");
- fprintf (header_file, " static hashval_t hash (ovlddata *);\n");
- fprintf (header_file, " static bool equal (ovlddata *, const char *);\n");
+ fprintf (header_file, " const char *ovld_name;\n");
+ fprintf (header_file, " ovlddata *first_instance;\n");
fprintf (header_file, "};\n\n");
- fprintf (header_file,
- "extern hash_table<rs6000_ovld_hasher> ovld_hash;\n\n");
+ fprintf (header_file, "extern ovlddata rs6000_instance_info[];\n");
+ fprintf (header_file, "extern ovldrecord rs6000_overload_info[];\n\n");
fprintf (header_file, "extern void rs6000_autoinit_builtins ();\n\n");
+ fprintf (header_file,
+ "extern bool rs6000_new_builtin_is_supported_p "
+ "(rs6000_gen_builtins);\n");
+ fprintf (header_file,
+ "extern tree rs6000_builtin_decl (unsigned, "
+ "bool ATTRIBUTE_UNUSED);\n");
}
/* Callback functions used for generating trees for function types. */
@@ -2466,18 +2470,38 @@ write_bif_static_init ()
fprintf (init_file, " };\n\n");
}
-/* Write the decl and initializer for rs6000_overload_info[]. */
+/* Write the decls and initializers for rs6000_overload_info[] and
+ rs6000_instance_info[]. */
static void
write_ovld_static_init ()
{
- fprintf (init_file, "ovlddata rs6000_overload_info[RS6000_OVLD_MAX] =\n");
+ fprintf (init_file,
+ "ovldrecord rs6000_overload_info[RS6000_OVLD_MAX "
+ "- RS6000_OVLD_NONE] =\n");
fprintf (init_file, " {\n");
fprintf (init_file, " { /* RS6000_OVLD_NONE: */\n");
+ fprintf (init_file, " \"\", NULL\n");
+ fprintf (init_file, " },\n");
+ for (int i = 0; i <= curr_ovld_stanza; i++)
+ {
+ fprintf (init_file, " { /* RS6000_OVLD_%s: */\n",
+ ovld_stanzas[i].stanza_id);
+ fprintf (init_file, " /* ovld_name */\t\"%s\",\n",
+ ovld_stanzas[i].intern_name);
+ /* First-instance must currently be instantiated at run time. */
+ fprintf (init_file, " /* first_instance */\tNULL\n");
+ fprintf (init_file, " },\n");
+ }
+ fprintf (init_file, " };\n\n");
+
+ fprintf (init_file, "ovlddata rs6000_instance_info[RS6000_INST_MAX] =\n");
+ fprintf (init_file, " {\n");
+ fprintf (init_file, " { /* RS6000_INST_NONE: */\n");
fprintf (init_file, " \"\", RS6000_BIF_NONE, NULL_TREE, NULL\n");
fprintf (init_file, " },\n");
for (int i = 0; i <= curr_ovld; i++)
{
- fprintf (init_file, " { /* RS6000_OVLD_%s: */\n",
+ fprintf (init_file, " { /* RS6000_INST_%s: */\n",
ovlds[i].ovld_id_name);
fprintf (init_file, " /* bifname */\t\"%s\",\n",
ovlds[i].proto.bifname);
@@ -2489,7 +2513,7 @@ write_ovld_static_init ()
if (i < curr_ovld
&& !strcmp (ovlds[i+1].proto.bifname, ovlds[i].proto.bifname))
fprintf (init_file,
- "&rs6000_overload_info[RS6000_OVLD_%s]\n",
+ "&rs6000_instance_info[RS6000_INST_%s]\n",
ovlds[i+1].ovld_id_name);
else
fprintf (init_file, "NULL\n");
@@ -2508,20 +2532,6 @@ write_init_bif_table ()
" rs6000_builtin_info_x[RS6000_BIF_%s].fntype"
"\n = %s;\n",
bifs[i].idname, bifs[i].fndecl);
- fprintf (init_file,
- " bifaddr = &rs6000_builtin_info_x[RS6000_BIF_%s];\n",
- bifs[i].idname);
- fprintf (init_file,
- " hash = rs6000_bif_hasher::hash (bifaddr);\n");
- fprintf (init_file,
- " slot = bif_hash.find_slot_with_hash (\n");
- fprintf (init_file,
- " \"%s\", hash, INSERT\n",
- bifs[i].proto.bifname);
- fprintf (init_file,
- " );\n");
- fprintf (init_file,
- " *slot = bifaddr;\n\n");
fprintf (init_file,
" if (new_builtins_are_live)\n");
@@ -2573,49 +2583,46 @@ write_init_ovld_table ()
for (int i = 0; i <= curr_ovld; i++)
{
fprintf (init_file,
- " rs6000_overload_info[RS6000_OVLD_%s - base].fntype"
+ " rs6000_instance_info[RS6000_INST_%s].fntype"
"\n = %s;\n",
ovlds[i].ovld_id_name, ovlds[i].fndecl);
if (i == 0 || ovlds[i].stanza != ovlds[i-1].stanza)
{
+ ovld_stanza *stanza = &ovld_stanzas[ovlds[i].stanza];
fprintf (init_file, "\n");
+
+ /* The fndecl for an overload is arbitrarily the first one
+ for the overload. We sort out the real types when
+ processing the overload in the gcc front end. */
fprintf (init_file,
- " ovldaddr = &rs6000_overload_info"
- "[RS6000_OVLD_%s - base];\n",
- ovlds[i].ovld_id_name);
+ " if (new_builtins_are_live)\n");
+ fprintf (init_file, " {\n");
fprintf (init_file,
- " hash = rs6000_ovld_hasher::hash (ovldaddr);\n");
+ " rs6000_builtin_decls_x[(int)RS6000_OVLD_%s] = t\n",
+ stanza->stanza_id);
fprintf (init_file,
- " oslot = ovld_hash.find_slot_with_hash (\n");
+ " = add_builtin_function (\"%s\",\n",
+ stanza->extern_name);
fprintf (init_file,
- " \"%s\", hash, INSERT\n",
- ovlds[i].proto.bifname);
+ " %s,\n",
+ ovlds[i].fndecl);
fprintf (init_file,
- " );\n");
+ " (int)RS6000_OVLD_%s,"
+ " BUILT_IN_MD,\n",
+ stanza->stanza_id);
fprintf (init_file,
- " *oslot = ovldaddr;\n\n");
- }
+ " NULL, NULL_TREE);\n");
+ fprintf (init_file, " }\n\n");
- fprintf (init_file,
- " if (new_builtins_are_live)\n");
- fprintf (init_file, " {\n");
- fprintf (init_file,
- " rs6000_builtin_decls_x[(int)RS6000_OVLD_%s] = t\n",
- ovlds[i].ovld_id_name);
- fprintf (init_file,
- " = add_builtin_function (\"%s\",\n",
- ovlds[i].proto.bifname);
- fprintf (init_file,
- " %s,\n",
- ovlds[i].fndecl);
- fprintf (init_file,
- " (int)RS6000_OVLD_%s,"
- " BUILT_IN_MD,\n",
- ovlds[i].ovld_id_name);
- fprintf (init_file,
- " NULL, NULL_TREE);\n");
- fprintf (init_file, " }\n\n");
+ fprintf (init_file,
+ " rs6000_overload_info[RS6000_OVLD_%s - base]"
+ ".first_instance\n",
+ stanza->stanza_id);
+ fprintf (init_file,
+ " = &rs6000_instance_info[RS6000_INST_%s];\n\n",
+ ovlds[i].ovld_id_name);
+ }
}
}
@@ -2651,45 +2658,10 @@ write_init_file ()
rbt_inorder_callback (&fntype_rbt, fntype_rbt.rbt_root, write_fntype);
fprintf (init_file, "\n");
- fprintf (init_file, "hashval_t\n");
- fprintf (init_file, "rs6000_bif_hasher::hash (bifdata *bd)\n");
- fprintf (init_file, "{\n");
- fprintf (init_file, " return htab_hash_string (bd->bifname);\n");
- fprintf (init_file, "}\n\n");
-
- fprintf (init_file, "bool\n");
- fprintf (init_file,
- "rs6000_bif_hasher::equal (bifdata *bd, const char *name)\n");
- fprintf (init_file, "{\n");
- fprintf (init_file, " return bd && name && !strcmp (bd->bifname, name);\n");
- fprintf (init_file, "}\n\n");
-
- fprintf (init_file, "hash_table<rs6000_bif_hasher> bif_hash (1024);\n\n");
-
- fprintf (init_file, "hashval_t\n");
- fprintf (init_file, "rs6000_ovld_hasher::hash (ovlddata *od)\n");
- fprintf (init_file, "{\n");
- fprintf (init_file, " return htab_hash_string (od->bifname);\n");
- fprintf (init_file, "}\n\n");
-
- fprintf (init_file, "bool\n");
- fprintf (init_file,
- "rs6000_ovld_hasher::equal (ovlddata *od, const char *name)\n");
- fprintf (init_file, "{\n");
- fprintf (init_file, " return od && name && !strcmp (od->bifname, name);\n");
- fprintf (init_file, "}\n\n");
-
- fprintf (init_file, "hash_table<rs6000_ovld_hasher> ovld_hash (512);\n\n");
-
fprintf (init_file, "void\n");
fprintf (init_file, "rs6000_autoinit_builtins ()\n");
fprintf (init_file, "{\n");
fprintf (init_file, " tree t;\n");
- fprintf (init_file, " bifdata **slot;\n");
- fprintf (init_file, " bifdata *bifaddr;\n");
- fprintf (init_file, " hashval_t hash;\n");
- fprintf (init_file, " ovlddata **oslot;\n");
- fprintf (init_file, " ovlddata *ovldaddr;\n\n");
fprintf (init_file, " timevar_start (TV_BILL);\n");
rbt_inorder_callback (&fntype_rbt, fntype_rbt.rbt_root, write_fntype_init);
fprintf (init_file, "\n");
diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def
index 2104da7c3f5..21f83f51c8d 100644
--- a/gcc/config/rs6000/rs6000-overload.def
+++ b/gcc/config/rs6000/rs6000-overload.def
@@ -171,7 +171,8 @@
; vsi and vui arguments, but rather than building a define_expand
; for the instruction sequence generated for those, we do some RTL
; hackery. Revisit whether we can remove that. For now, keep this
-; much of the entry here to generate the #define, at least.
+; much of the entry here to generate the #define, at least. Also
+; these entries are needed anyway by the rs6000-c.c logic.
[VEC_ADDE, vec_adde, __builtin_vec_adde]
vsq __builtin_vec_adde (vsq, vsq, vsq);
VADDEUQM VADDEUQM_VSQ
@@ -1017,20 +1018,10 @@
vf __builtin_vec_expte (vf);
VEXPTEFP
-[VEC_EXTRACTM, vec_extractm, __builtin_vec_vextractm, _ARCH_PWR10]
- signed int __builtin_vec_vextractm (vuc);
- VEXTRACTMB
- signed int __builtin_vec_vextractm (vus);
- VEXTRACTMH
- signed int __builtin_vec_vextractm (vui);
- VEXTRACTMW
- signed int __builtin_vec_vextractm (vull);
- VEXTRACTMD
- signed int __builtin_vec_vextractm (vuq);
- VEXTRACTMQ
-
-; There is no entry for vec_extract. There is special handling for
-; this in altivec_resolve_overloaded_builtin in rs6000.c.
+; There are no actual builtins for vec_extract. There is special handling for
+; this in altivec_resolve_overloaded_builtin in rs6000-c.c, where the call
+; is replaced by "pointer tricks."
+[VEC_EXTRACT, vec_extract, __builtin_vec_extract]
[VEC_EXTRACT_FP_FROM_SHORTH, vec_extract_fp32_from_shorth, __builtin_vec_vextract_fp_from_shorth, _ARCH_PWR9]
vf __builtin_vec_vextract_fp_from_shorth (vus);
@@ -1060,6 +1051,18 @@
vull __builtin_vec_extractl (vull, vull, unsigned char);
VEXTRACTDL
+[VEC_EXTRACTM, vec_extractm, __builtin_vec_vextractm, _ARCH_PWR10]
+ signed int __builtin_vec_vextractm (vuc);
+ VEXTRACTMB
+ signed int __builtin_vec_vextractm (vus);
+ VEXTRACTMH
+ signed int __builtin_vec_vextractm (vui);
+ VEXTRACTMW
+ signed int __builtin_vec_vextractm (vull);
+ VEXTRACTMD
+ signed int __builtin_vec_vextractm (vuq);
+ VEXTRACTMQ
+
[VEC_EXTRACT4B, vec_extract4b, __builtin_vec_extract4b, _ARCH_PWR9]
vull __builtin_vec_extract4b (vuc, const int);
EXTRACT4B
@@ -1234,8 +1237,10 @@
vull __builtin_vec_gnb (vuq, unsigned char);
VGNB
-; There is no entry for vec_insert. There is special handling for
-; this in altivec_resolve_overloaded_builtin in rs6000.c.
+; There are no actual builtins for vec_insert. There is special handling for
+; this in altivec_resolve_overloaded_builtin in rs6000-c.c, where the call
+; is replaced by "pointer tricks."
+[VEC_INSERT, vec_insert, __builtin_vec_insert]
[VEC_INSERTH, vec_inserth, __builtin_vec_inserth, _ARCH_PWR10]
vuc __builtin_vec_inserth (unsigned char, vuc, unsigned int);
@@ -1833,9 +1838,17 @@
void __builtin_vec_mtvscr (vui);
MTVSCR MTVSCR_VUI
-; Note that there is no entry for VEC_MUL. See rs6000-c.c:
-; altivec_resolve_overloaded_builtin, where there is special-case
-; code for VEC_MUL. TODO: Is this really necessary? Investigate.
+; Note that the entries for VEC_MUL are currently ignored. See rs6000-c.c:
+; altivec_resolve_overloaded_builtin, where there is special-case code for
+; VEC_MUL. TODO: Is this really necessary? Investigate. Seven missing
+; prototypes here...no corresponding builtins.
+[VEC_MUL, vec_mul, __builtin_vec_mul]
+ vsll __builtin_vec_mul (vsll, vsll);
+ MUL_V2DI
+ vf __builtin_vec_mul (vf, vf);
+ XVMULSP
+ vd __builtin_vec_mul (vd, vd);
+ XVMULDP
[VEC_MULE, vec_mule, __builtin_vec_mule]
vss __builtin_vec_mule (vsc, vsc);
@@ -2205,8 +2218,10 @@
vuq __builtin_vec_vparity_lsbb (vuq);
VPRTYBQ VPRTYBQ_U
-; There is no entry for vec_promote. There is special handling for
-; this in altivec_resolve_overloaded_builtin in rs6000.c.
+; There are no actual builtins for vec_promote. There is special handling for
+; this in altivec_resolve_overloaded_builtin in rs6000-c.c, where the call
+; is replaced by a constructor.
+[VEC_PROMOTE, vec_promote, __builtin_vec_promote]
[VEC_RE, vec_re, __builtin_vec_re]
vf __builtin_vec_re (vf);
@@ -2659,8 +2674,10 @@
vf __builtin_vec_xxsplti32dx (vf, const int, float);
VXXSPLTI32DX_V4SF
-; There is no entry for vec_splats. There is special handling for
-; this in altivec_resolve_overloaded_builtin in rs6000.c.
+; There are no actual builtins for vec_splats. There is special handling for
+; this in altivec_resolve_overloaded_builtin in rs6000-c.c, where the call
+; is replaced by a constructor.
+[VEC_SPLATS, vec_splats, __builtin_vec_splats]
[VEC_SQRT, vec_sqrt, __builtin_vec_sqrt, __VSX__]
vf __builtin_vec_sqrt (vf);
@@ -2888,6 +2905,10 @@
void __builtin_vec_ste (vf, signed long long, float *);
STVEWX STVEWX_F
+; There are no builtins for VEC_STEP; this is handled directly
+; with a constant replacement in rs6000_resolve_overloaded_builtin.
+[VEC_STEP, vec_step, __builtin_vec_step]
+
[VEC_STL, vec_stl, __builtin_vec_stl]
void __builtin_vec_stl (vsc, signed long long, vsc *);
STVXL_V16QI STVXL_VSC
@@ -3428,13 +3449,13 @@
[VEC_VSIE, scalar_insert_exp, __builtin_vec_scalar_insert_exp, _ARCH_PWR9]
double __builtin_vec_scalar_insert_exp (unsigned int, unsigned int);
- VSIEDP VSIEDP_UI
+ VSIEDP
double __builtin_vec_scalar_insert_exp (double, unsigned int);
- VSIEDP VSIEDP_D
+ VSIEDPF
_Float128 __builtin_vec_scalar_insert_exp (unsigned long long, unsigned long long);
- VSIEQP VSIEQP_ULL
+ VSIEQP
_Float128 __builtin_vec_scalar_insert_exp (_Float128, unsigned long long);
- VSIEQP VSIEQP_F128
+ VSIEQPF
[VEC_VSTDC, scalar_test_data_class, __builtin_vec_scalar_test_data_class, _ARCH_PWR9]
bool __builtin_vec_scalar_test_data_class (float, signed int);
More information about the Gcc-cvs
mailing list