xref: /openbsd/gnu/usr.bin/gcc/gcc/java/builtins.c (revision c87b03e5)
1*c87b03e5Sespie /* Built-in and inline functions for gcj
2*c87b03e5Sespie    Copyright (C) 2001
3*c87b03e5Sespie    Free Software Foundation, Inc.
4*c87b03e5Sespie 
5*c87b03e5Sespie This file is part of GNU CC.
6*c87b03e5Sespie 
7*c87b03e5Sespie GNU CC is free software; you can redistribute it and/or modify
8*c87b03e5Sespie it under the terms of the GNU General Public License as published by
9*c87b03e5Sespie the Free Software Foundation; either version 2, or (at your option)
10*c87b03e5Sespie any later version.
11*c87b03e5Sespie 
12*c87b03e5Sespie GNU CC is distributed in the hope that it will be useful,
13*c87b03e5Sespie but WITHOUT ANY WARRANTY; without even the implied warranty of
14*c87b03e5Sespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*c87b03e5Sespie GNU General Public License for more details.
16*c87b03e5Sespie 
17*c87b03e5Sespie You should have received a copy of the GNU General Public License
18*c87b03e5Sespie along with GNU CC; see the file COPYING.  If not, write to
19*c87b03e5Sespie the Free Software Foundation, 59 Temple Place - Suite 330,
20*c87b03e5Sespie Boston, MA 02111-1307, USA.
21*c87b03e5Sespie 
22*c87b03e5Sespie Java and all Java-based marks are trademarks or registered trademarks
23*c87b03e5Sespie of Sun Microsystems, Inc. in the United States and other countries.
24*c87b03e5Sespie The Free Software Foundation is independent of Sun Microsystems, Inc.  */
25*c87b03e5Sespie 
26*c87b03e5Sespie /* Written by Tom Tromey <tromey@redhat.com>.  */
27*c87b03e5Sespie 
28*c87b03e5Sespie #include "config.h"
29*c87b03e5Sespie #include "system.h"
30*c87b03e5Sespie #include "tree.h"
31*c87b03e5Sespie #include "ggc.h"
32*c87b03e5Sespie #include "flags.h"
33*c87b03e5Sespie #include "langhooks.h"
34*c87b03e5Sespie #include "java-tree.h"
35*c87b03e5Sespie 
36*c87b03e5Sespie enum builtin_type
37*c87b03e5Sespie {
38*c87b03e5Sespie #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
39*c87b03e5Sespie #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
40*c87b03e5Sespie #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
41*c87b03e5Sespie #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
42*c87b03e5Sespie #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
43*c87b03e5Sespie #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
44*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
45*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
46*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
47*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
48*c87b03e5Sespie #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
49*c87b03e5Sespie #include "builtin-types.def"
50*c87b03e5Sespie #undef DEF_PRIMITIVE_TYPE
51*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_0
52*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_1
53*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_2
54*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_3
55*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_4
56*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_VAR_0
57*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_VAR_1
58*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_VAR_2
59*c87b03e5Sespie #undef DEF_FUNCTION_TYPE_VAR_3
60*c87b03e5Sespie #undef DEF_POINTER_TYPE
61*c87b03e5Sespie   BT_LAST
62*c87b03e5Sespie };
63*c87b03e5Sespie 
64*c87b03e5Sespie static tree max_builtin PARAMS ((tree, tree));
65*c87b03e5Sespie static tree min_builtin PARAMS ((tree, tree));
66*c87b03e5Sespie static tree abs_builtin PARAMS ((tree, tree));
67*c87b03e5Sespie static tree cos_builtin PARAMS ((tree, tree));
68*c87b03e5Sespie static tree sin_builtin PARAMS ((tree, tree));
69*c87b03e5Sespie static tree sqrt_builtin PARAMS ((tree, tree));
70*c87b03e5Sespie 
71*c87b03e5Sespie static tree build_function_call_expr PARAMS ((tree, tree));
72*c87b03e5Sespie static void define_builtin PARAMS ((enum built_in_function,
73*c87b03e5Sespie 				    const char *,
74*c87b03e5Sespie 				    enum built_in_class,
75*c87b03e5Sespie 				    tree, int));
76*c87b03e5Sespie static tree define_builtin_type PARAMS ((int, int, int, int, int));
77*c87b03e5Sespie 
78*c87b03e5Sespie 
79*c87b03e5Sespie 
80*c87b03e5Sespie /* Functions of this type are used to inline a given call.  Such a
81*c87b03e5Sespie    function should either return an expression, if the call is to be
82*c87b03e5Sespie    inlined, or NULL_TREE if a real call should be emitted.  Arguments
83*c87b03e5Sespie    are method return type and arguments to call.  */
84*c87b03e5Sespie typedef tree builtin_creator_function PARAMS ((tree, tree));
85*c87b03e5Sespie 
86*c87b03e5Sespie /* Hold a char*, before initialization, or a tree, after
87*c87b03e5Sespie    initialization.  */
88*c87b03e5Sespie union string_or_tree GTY(())
89*c87b03e5Sespie {
90*c87b03e5Sespie   const char * GTY ((tag ("0"))) s;
91*c87b03e5Sespie   tree GTY ((tag ("1"))) t;
92*c87b03e5Sespie };
93*c87b03e5Sespie 
94*c87b03e5Sespie /* Used to hold a single builtin record.  */
95*c87b03e5Sespie struct builtin_record GTY(())
96*c87b03e5Sespie {
97*c87b03e5Sespie   union string_or_tree GTY ((desc ("1"))) class_name;
98*c87b03e5Sespie   union string_or_tree GTY ((desc ("1"))) method_name;
99*c87b03e5Sespie   builtin_creator_function * GTY((skip (""))) creator;
100*c87b03e5Sespie };
101*c87b03e5Sespie 
102*c87b03e5Sespie static GTY(()) struct builtin_record java_builtins[] =
103*c87b03e5Sespie {
104*c87b03e5Sespie   { { "java.lang.Math" }, { "min" }, min_builtin },
105*c87b03e5Sespie   { { "java.lang.Math" }, { "max" }, max_builtin },
106*c87b03e5Sespie   { { "java.lang.Math" }, { "abs" }, abs_builtin },
107*c87b03e5Sespie   { { "java.lang.Math" }, { "cos" }, cos_builtin },
108*c87b03e5Sespie   { { "java.lang.Math" }, { "sin" }, sin_builtin },
109*c87b03e5Sespie   { { "java.lang.Math" }, { "sqrt" }, sqrt_builtin },
110*c87b03e5Sespie   { { NULL }, { NULL }, NULL }
111*c87b03e5Sespie };
112*c87b03e5Sespie 
113*c87b03e5Sespie /* This is only used transiently, so we don't mark it as roots for the
114*c87b03e5Sespie    GC.  */
115*c87b03e5Sespie static tree builtin_types[(int) BT_LAST];
116*c87b03e5Sespie 
117*c87b03e5Sespie 
118*c87b03e5Sespie /* Internal functions which implement various builtin conversions.  */
119*c87b03e5Sespie 
120*c87b03e5Sespie static tree
max_builtin(method_return_type,method_arguments)121*c87b03e5Sespie max_builtin (method_return_type, method_arguments)
122*c87b03e5Sespie      tree method_return_type, method_arguments;
123*c87b03e5Sespie {
124*c87b03e5Sespie   return build (MAX_EXPR, method_return_type,
125*c87b03e5Sespie 		TREE_VALUE (method_arguments),
126*c87b03e5Sespie 		TREE_VALUE (TREE_CHAIN (method_arguments)));
127*c87b03e5Sespie }
128*c87b03e5Sespie 
129*c87b03e5Sespie static tree
min_builtin(method_return_type,method_arguments)130*c87b03e5Sespie min_builtin (method_return_type, method_arguments)
131*c87b03e5Sespie      tree method_return_type, method_arguments;
132*c87b03e5Sespie {
133*c87b03e5Sespie   return build (MIN_EXPR, method_return_type,
134*c87b03e5Sespie 		TREE_VALUE (method_arguments),
135*c87b03e5Sespie 		TREE_VALUE (TREE_CHAIN (method_arguments)));
136*c87b03e5Sespie }
137*c87b03e5Sespie 
138*c87b03e5Sespie static tree
abs_builtin(method_return_type,method_arguments)139*c87b03e5Sespie abs_builtin (method_return_type, method_arguments)
140*c87b03e5Sespie      tree method_return_type, method_arguments;
141*c87b03e5Sespie {
142*c87b03e5Sespie   return build1 (ABS_EXPR, method_return_type,
143*c87b03e5Sespie 		 TREE_VALUE (method_arguments));
144*c87b03e5Sespie }
145*c87b03e5Sespie 
146*c87b03e5Sespie /* Mostly copied from ../builtins.c.  */
147*c87b03e5Sespie static tree
build_function_call_expr(tree fn,tree arglist)148*c87b03e5Sespie build_function_call_expr (tree fn, tree arglist)
149*c87b03e5Sespie {
150*c87b03e5Sespie   tree call_expr;
151*c87b03e5Sespie 
152*c87b03e5Sespie   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
153*c87b03e5Sespie   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
154*c87b03e5Sespie 		     call_expr, arglist);
155*c87b03e5Sespie   TREE_SIDE_EFFECTS (call_expr) = 1;
156*c87b03e5Sespie   return call_expr;
157*c87b03e5Sespie }
158*c87b03e5Sespie 
159*c87b03e5Sespie static tree
cos_builtin(method_return_type,method_arguments)160*c87b03e5Sespie cos_builtin (method_return_type, method_arguments)
161*c87b03e5Sespie      tree method_return_type ATTRIBUTE_UNUSED, method_arguments;
162*c87b03e5Sespie {
163*c87b03e5Sespie   /* FIXME: this assumes that jdouble and double are the same.  */
164*c87b03e5Sespie   tree fn = built_in_decls[BUILT_IN_COS];
165*c87b03e5Sespie   if (fn == NULL_TREE)
166*c87b03e5Sespie     return NULL_TREE;
167*c87b03e5Sespie   return build_function_call_expr (fn, method_arguments);
168*c87b03e5Sespie }
169*c87b03e5Sespie 
170*c87b03e5Sespie static tree
sin_builtin(method_return_type,method_arguments)171*c87b03e5Sespie sin_builtin (method_return_type, method_arguments)
172*c87b03e5Sespie      tree method_return_type ATTRIBUTE_UNUSED, method_arguments;
173*c87b03e5Sespie {
174*c87b03e5Sespie   /* FIXME: this assumes that jdouble and double are the same.  */
175*c87b03e5Sespie   tree fn = built_in_decls[BUILT_IN_SIN];
176*c87b03e5Sespie   if (fn == NULL_TREE)
177*c87b03e5Sespie     return NULL_TREE;
178*c87b03e5Sespie   return build_function_call_expr (fn, method_arguments);
179*c87b03e5Sespie }
180*c87b03e5Sespie 
181*c87b03e5Sespie static tree
sqrt_builtin(method_return_type,method_arguments)182*c87b03e5Sespie sqrt_builtin (method_return_type, method_arguments)
183*c87b03e5Sespie      tree method_return_type ATTRIBUTE_UNUSED, method_arguments;
184*c87b03e5Sespie {
185*c87b03e5Sespie   /* FIXME: this assumes that jdouble and double are the same.  */
186*c87b03e5Sespie   tree fn = built_in_decls[BUILT_IN_SQRT];
187*c87b03e5Sespie   if (fn == NULL_TREE)
188*c87b03e5Sespie     return NULL_TREE;
189*c87b03e5Sespie   return build_function_call_expr (fn, method_arguments);
190*c87b03e5Sespie }
191*c87b03e5Sespie 
192*c87b03e5Sespie 
193*c87b03e5Sespie 
194*c87b03e5Sespie /* Define a single builtin.  */
195*c87b03e5Sespie static void
define_builtin(val,name,class,type,fallback_p)196*c87b03e5Sespie define_builtin (val, name, class, type, fallback_p)
197*c87b03e5Sespie      enum built_in_function val;
198*c87b03e5Sespie      const char *name;
199*c87b03e5Sespie      enum built_in_class class;
200*c87b03e5Sespie      tree type;
201*c87b03e5Sespie      int fallback_p;
202*c87b03e5Sespie {
203*c87b03e5Sespie   tree decl;
204*c87b03e5Sespie 
205*c87b03e5Sespie   if (! name || ! type)
206*c87b03e5Sespie     return;
207*c87b03e5Sespie 
208*c87b03e5Sespie   if (strncmp (name, "__builtin_", strlen ("__builtin_")) != 0)
209*c87b03e5Sespie     abort ();
210*c87b03e5Sespie   decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
211*c87b03e5Sespie   DECL_EXTERNAL (decl) = 1;
212*c87b03e5Sespie   TREE_PUBLIC (decl) = 1;
213*c87b03e5Sespie   if (fallback_p)
214*c87b03e5Sespie     SET_DECL_ASSEMBLER_NAME (decl,
215*c87b03e5Sespie 			     get_identifier (name + strlen ("__builtin_")));
216*c87b03e5Sespie   make_decl_rtl (decl, NULL);
217*c87b03e5Sespie   pushdecl (decl);
218*c87b03e5Sespie   DECL_BUILT_IN_CLASS (decl) = class;
219*c87b03e5Sespie   DECL_FUNCTION_CODE (decl) = val;
220*c87b03e5Sespie   built_in_decls[val] = decl;
221*c87b03e5Sespie }
222*c87b03e5Sespie 
223*c87b03e5Sespie /* Compute the type for a builtin.  */
224*c87b03e5Sespie static tree
define_builtin_type(ret,arg1,arg2,arg3,arg4)225*c87b03e5Sespie define_builtin_type (ret, arg1, arg2, arg3, arg4)
226*c87b03e5Sespie      int ret, arg1, arg2, arg3, arg4;
227*c87b03e5Sespie {
228*c87b03e5Sespie   tree args;
229*c87b03e5Sespie 
230*c87b03e5Sespie   if (builtin_types[ret] == NULL_TREE)
231*c87b03e5Sespie     return NULL_TREE;
232*c87b03e5Sespie 
233*c87b03e5Sespie   args = void_list_node;
234*c87b03e5Sespie 
235*c87b03e5Sespie   if (arg4 != -1)
236*c87b03e5Sespie     {
237*c87b03e5Sespie       if (builtin_types[arg4] == NULL_TREE)
238*c87b03e5Sespie 	return NULL_TREE;
239*c87b03e5Sespie       args = tree_cons (NULL_TREE, builtin_types[arg4], args);
240*c87b03e5Sespie     }
241*c87b03e5Sespie   if (arg3 != -1)
242*c87b03e5Sespie     {
243*c87b03e5Sespie       if (builtin_types[arg3] == NULL_TREE)
244*c87b03e5Sespie 	return NULL_TREE;
245*c87b03e5Sespie       args = tree_cons (NULL_TREE, builtin_types[arg3], args);
246*c87b03e5Sespie     }
247*c87b03e5Sespie   if (arg2 != -1)
248*c87b03e5Sespie     {
249*c87b03e5Sespie       if (builtin_types[arg2] == NULL_TREE)
250*c87b03e5Sespie 	return NULL_TREE;
251*c87b03e5Sespie       args = tree_cons (NULL_TREE, builtin_types[arg2], args);
252*c87b03e5Sespie     }
253*c87b03e5Sespie   if (arg1 != -1)
254*c87b03e5Sespie     {
255*c87b03e5Sespie       if (builtin_types[arg1] == NULL_TREE)
256*c87b03e5Sespie 	return NULL_TREE;
257*c87b03e5Sespie       args = tree_cons (NULL_TREE, builtin_types[arg1], args);
258*c87b03e5Sespie     }
259*c87b03e5Sespie 
260*c87b03e5Sespie   return build_function_type (builtin_types[ret], args);
261*c87b03e5Sespie }
262*c87b03e5Sespie 
263*c87b03e5Sespie 
264*c87b03e5Sespie 
265*c87b03e5Sespie /* Initialize the builtins.  */
266*c87b03e5Sespie void
initialize_builtins()267*c87b03e5Sespie initialize_builtins ()
268*c87b03e5Sespie {
269*c87b03e5Sespie   int i;
270*c87b03e5Sespie 
271*c87b03e5Sespie   for (i = 0; java_builtins[i].creator != NULL; ++i)
272*c87b03e5Sespie     {
273*c87b03e5Sespie       tree klass_id = get_identifier (java_builtins[i].class_name.s);
274*c87b03e5Sespie       tree m = get_identifier (java_builtins[i].method_name.s);
275*c87b03e5Sespie 
276*c87b03e5Sespie       java_builtins[i].class_name.t = klass_id;
277*c87b03e5Sespie       java_builtins[i].method_name.t = m;
278*c87b03e5Sespie     }
279*c87b03e5Sespie 
280*c87b03e5Sespie   void_list_node = end_params_node;
281*c87b03e5Sespie 
282*c87b03e5Sespie   /* Work around C-specific junk in builtin-types.def.  */
283*c87b03e5Sespie #define intmax_type_node NULL_TREE
284*c87b03e5Sespie #define c_size_type_node NULL_TREE
285*c87b03e5Sespie #define const_string_type_node NULL_TREE
286*c87b03e5Sespie #define va_list_ref_type_node NULL_TREE
287*c87b03e5Sespie #define va_list_arg_type_node NULL_TREE
288*c87b03e5Sespie #define flag_isoc99 0
289*c87b03e5Sespie 
290*c87b03e5Sespie #define DEF_PRIMITIVE_TYPE(ENUM, VALUE)					      \
291*c87b03e5Sespie   builtin_types[(int) ENUM] = VALUE;
292*c87b03e5Sespie #define DEF_FUNCTION_TYPE_0(ENUM, RETURN)		\
293*c87b03e5Sespie   builtin_types[(int) ENUM]				\
294*c87b03e5Sespie     = define_builtin_type (RETURN, -1, -1, -1, -1);
295*c87b03e5Sespie #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1)				\
296*c87b03e5Sespie   builtin_types[(int) ENUM]						\
297*c87b03e5Sespie     = define_builtin_type (RETURN, ARG1, -1, -1, -1);
298*c87b03e5Sespie #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2)	\
299*c87b03e5Sespie   builtin_types[(int) ENUM]				\
300*c87b03e5Sespie     = define_builtin_type (RETURN, ARG1, ARG2, -1, -1);
301*c87b03e5Sespie #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3)		 \
302*c87b03e5Sespie   builtin_types[(int) ENUM]						 \
303*c87b03e5Sespie     = define_builtin_type (RETURN, ARG1, ARG2, ARG3, -1);
304*c87b03e5Sespie #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)	\
305*c87b03e5Sespie   builtin_types[(int) ENUM]						\
306*c87b03e5Sespie     = define_builtin_type (RETURN, ARG1, ARG2, ARG3, ARG4);
307*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN)			\
308*c87b03e5Sespie   builtin_types[(int) ENUM] = NULL_TREE;
309*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1)		\
310*c87b03e5Sespie    builtin_types[(int) ENUM] = NULL_TREE;
311*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2)	\
312*c87b03e5Sespie    builtin_types[(int) ENUM] = NULL_TREE;
313*c87b03e5Sespie #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3)	\
314*c87b03e5Sespie    builtin_types[(int) ENUM] = NULL_TREE;
315*c87b03e5Sespie #define DEF_POINTER_TYPE(ENUM, TYPE)			\
316*c87b03e5Sespie   builtin_types[(int) ENUM] = NULL_TREE;
317*c87b03e5Sespie 
318*c87b03e5Sespie #include "builtin-types.def"
319*c87b03e5Sespie 
320*c87b03e5Sespie #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, \
321*c87b03e5Sespie                     FALLBACK_P, NONANSI_P, ATTRS) \
322*c87b03e5Sespie   define_builtin (ENUM, NAME, CLASS, builtin_types[TYPE], FALLBACK_P);
323*c87b03e5Sespie #include "builtins.def"
324*c87b03e5Sespie }
325*c87b03e5Sespie 
326*c87b03e5Sespie /* If the call matches a builtin, return the
327*c87b03e5Sespie    appropriate builtin expression instead.  */
328*c87b03e5Sespie tree
check_for_builtin(method,call)329*c87b03e5Sespie check_for_builtin (method, call)
330*c87b03e5Sespie      tree method;
331*c87b03e5Sespie      tree call;
332*c87b03e5Sespie {
333*c87b03e5Sespie   if (! flag_emit_class_files && optimize && TREE_CODE (call) == CALL_EXPR)
334*c87b03e5Sespie     {
335*c87b03e5Sespie       int i;
336*c87b03e5Sespie       tree method_arguments = TREE_OPERAND (call, 1);
337*c87b03e5Sespie       tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
338*c87b03e5Sespie       tree method_name = DECL_NAME (method);
339*c87b03e5Sespie       tree method_return_type = TREE_TYPE (TREE_TYPE (method));
340*c87b03e5Sespie 
341*c87b03e5Sespie       for (i = 0; java_builtins[i].creator != NULL; ++i)
342*c87b03e5Sespie 	{
343*c87b03e5Sespie 	  if (method_class == java_builtins[i].class_name.t
344*c87b03e5Sespie 	      && method_name == java_builtins[i].method_name.t)
345*c87b03e5Sespie 	    {
346*c87b03e5Sespie 	      return (*java_builtins[i].creator) (method_return_type,
347*c87b03e5Sespie 						  method_arguments);
348*c87b03e5Sespie 	    }
349*c87b03e5Sespie 	}
350*c87b03e5Sespie     }
351*c87b03e5Sespie   return call;
352*c87b03e5Sespie }
353*c87b03e5Sespie 
354*c87b03e5Sespie #include "gt-java-builtins.h"
355