OSDN Git Service

* config/host-hpux.c: Change copyright header to refer to version 3 of the GNU
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / spu-c.c
1 /* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
2
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 3 of the License, or (at your option) 
6    any later version.
7
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
11    for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with GCC; see the file COPYING3.  If not see
15    <http://www.gnu.org/licenses/>.  */
16
17 #include "config.h"
18 #include "system.h"
19 #include "coretypes.h"
20 #include "tm.h"
21 #include "cpplib.h"
22 #include "tree.h"
23 #include "c-tree.h"
24 #include "c-pragma.h"
25 #include "function.h"
26 #include "rtl.h"
27 #include "expr.h"
28 #include "errors.h"
29 #include "tm_p.h"
30 #include "langhooks.h"
31 #include "insn-config.h"
32 #include "insn-codes.h"
33 #include "recog.h"
34 #include "optabs.h"
35 #include "spu-builtins.h"
36 \f
37
38 /* target hook for resolve_overloaded_builtin(). Returns a function call
39    RTX if we can resolve the overloaded builtin */
40 tree
41 spu_resolve_overloaded_builtin (tree fndecl, tree fnargs)
42 {
43 #define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
44                           || SCALAR_FLOAT_TYPE_P (t) \
45                           || POINTER_TYPE_P (t))
46   spu_function_code new_fcode, fcode =
47     DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
48   struct spu_builtin_description *desc;
49   tree match = NULL_TREE;
50
51   /* The vector types are not available if the backend is not initialized.  */
52   gcc_assert (!flag_preprocess_only);
53
54   desc = &spu_builtins[fcode];
55   if (desc->type != B_OVERLOAD)
56     return NULL_TREE;
57
58   /* Compare the signature of each internal builtin function with the
59      function arguments until a match is found. */
60
61   for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
62        new_fcode++)
63     {
64       tree decl = spu_builtins[new_fcode].fndecl;
65       tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
66       tree arg, param;
67       int p;
68
69       for (param = params, arg = fnargs, p = 0;
70            param != void_list_node;
71            param = TREE_CHAIN (param), arg = TREE_CHAIN (arg), p++)
72         {
73           tree var, arg_type, param_type = TREE_VALUE (param);
74
75           if (!arg)
76             {
77               error ("insufficient arguments to overloaded function %s",
78                      desc->name);
79               return error_mark_node;
80             }
81
82           var = TREE_VALUE (arg);
83
84           if (TREE_CODE (var) == NON_LVALUE_EXPR)
85             var = TREE_OPERAND (var, 0);
86
87           if (TREE_CODE (var) == ERROR_MARK)
88             return NULL_TREE;   /* Let somebody else deal with the problem. */
89
90           arg_type = TREE_TYPE (var);
91
92           /* The intrinsics spec does not specify precisely how to
93              resolve generic intrinsics.  We require an exact match
94              for vector types and let C do it's usual parameter type
95              checking/promotions for scalar arguments, except for the
96              first argument of intrinsics which don't have a vector
97              parameter. */
98           if ((!SCALAR_TYPE_P (param_type)
99                || !SCALAR_TYPE_P (arg_type)
100                || ((fcode == SPU_SPLATS || fcode == SPU_PROMOTE
101                     || fcode == SPU_HCMPEQ || fcode == SPU_HCMPGT
102                     || fcode == SPU_MASKB || fcode == SPU_MASKH
103                     || fcode == SPU_MASKW) && p == 0))
104               && !comptypes (TYPE_MAIN_VARIANT (param_type),
105                              TYPE_MAIN_VARIANT (arg_type)))
106             break;
107         }
108       if (param == void_list_node)
109         {
110           if (arg)
111             {
112               error ("too many arguments to overloaded function %s",
113                      desc->name);
114               return error_mark_node;
115             }
116
117           match = decl;
118           break;
119         }
120     }
121
122   if (match == NULL_TREE)
123     {
124       error ("parameter list does not match a valid signature for %s()",
125              desc->name);
126       return error_mark_node;
127     }
128
129   return build_function_call (match, fnargs);
130 #undef SCALAR_TYPE_P
131 }
132
133
134 void
135 spu_cpu_cpp_builtins (struct cpp_reader *pfile)
136 {
137   builtin_define_std ("__SPU__");
138   cpp_assert (pfile, "cpu=spu");
139   cpp_assert (pfile, "machine=spu");
140   if (spu_arch == PROCESSOR_CELLEDP)
141     builtin_define_std ("__SPU_EDP__");
142   builtin_define_std ("__vector=__attribute__((__spu_vector__))");
143 }
144
145 void
146 spu_c_common_override_options (void)
147
148   if (!TARGET_STD_MAIN)
149     {
150       /* Don't give warnings about the main() function.  */
151       warn_main = 0;
152     }
153 }