1 /* Copyright (C) 2006 Free Software Foundation, Inc.
3 This file is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 2 of the License, or (at your option)
8 This file is distributed in the hope that it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 You should have received a copy of the GNU General Public License
14 along with this file; see the file COPYING. If not, write to the Free
15 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 #include "coretypes.h"
31 #include "langhooks.h"
32 #include "insn-config.h"
33 #include "insn-codes.h"
36 #include "spu-builtins.h"
39 /* Helper for spu_resolve_overloaded_builtin. */
41 spu_build_overload_builtin (tree fndecl, tree fnargs)
43 tree param, param_type;
44 tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
45 tree arg, arglist = NULL_TREE;
48 for (param = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), arg = fnargs;
49 param != void_list_node;
50 param = TREE_CHAIN (param), arg = TREE_CHAIN (arg))
52 gcc_assert (arg != NULL_TREE);
53 param_type = TREE_VALUE (param);
54 val = default_conversion (TREE_VALUE (arg));
55 val = fold_convert (param_type, val);
57 arglist = tree_cons (NULL_TREE, val, arglist);
59 gcc_assert (arg == NULL_TREE);
60 arglist = nreverse (arglist);
62 return fold_convert (ret_type, build_function_call_expr (fndecl, arglist));
65 /* target hook for resolve_overloaded_builtin(). Returns a function call
66 RTX if we can resolve the overloaded builtin */
68 spu_resolve_overloaded_builtin (tree fndecl, tree fnargs)
70 spu_function_code new_fcode, fcode =
71 DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
72 struct spu_builtin_description *desc;
73 tree match = NULL_TREE;
75 /* The vector types are not available if the backend is not initalized */
76 gcc_assert (!flag_preprocess_only);
78 desc = &spu_builtins[fcode];
79 if (desc->type != B_OVERLOAD)
82 /* Compare the signature of each internal builtin function with the
83 function arguments until a match is found. */
85 for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
88 tree decl = spu_builtins[new_fcode].fndecl;
89 tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
93 for (param = params, arg = fnargs, p = 0;
94 param != void_list_node;
95 param = TREE_CHAIN (param), arg = TREE_CHAIN (arg), p++)
97 tree var, arg_type, param_type = TREE_VALUE (param);
101 error ("insufficient arguments to overloaded function %s",
103 return error_mark_node;
106 var = TREE_VALUE (arg);
108 if (TREE_CODE (var) == NON_LVALUE_EXPR)
109 var = TREE_OPERAND (var, 0);
111 if (TREE_CODE (var) == ERROR_MARK)
112 return NULL_TREE; /* Let somebody else deal with the problem. */
114 arg_type = TREE_TYPE (var);
116 /* The intrinsics spec does not specify precisely how to
117 resolve generic intrinsics. We require an exact match
118 for vector types and let C do it's usual parameter type
119 checking/promotions for scalar arguments, except for the
120 first argument of intrinsics which don't have a vector
122 if ((TREE_CODE (param_type) == VECTOR_TYPE
123 || ((fcode == SPU_SPLATS || fcode == SPU_PROMOTE
124 || fcode == SPU_HCMPEQ || fcode == SPU_HCMPGT
125 || fcode == SPU_MASKB || fcode == SPU_MASKH
126 || fcode == SPU_MASKW) && p == 0))
127 && !comptypes (TYPE_MAIN_VARIANT (param_type),
128 TYPE_MAIN_VARIANT (arg_type)))
131 if (param == void_list_node)
135 error ("too many arguments to overloaded function %s",
137 return error_mark_node;
145 if (match == NULL_TREE)
147 error ("parameter list does not match a valid signature for %s()",
149 return error_mark_node;
152 return spu_build_overload_builtin (match, fnargs);
157 spu_cpu_cpp_builtins (struct cpp_reader *pfile)
159 builtin_define_std ("__SPU__");
160 cpp_assert (pfile, "cpu=spu");
161 cpp_assert (pfile, "machine=spu");
162 builtin_define_std ("__vector=__attribute__((__spu_vector__))");