]>
Commit | Line | Data |
---|---|---|
fec763fc | 1 | /* Built-in and inline functions for gcj |
f309ff0a | 2 | Copyright (C) 2001, 2003 |
fec763fc TT |
3 | Free Software Foundation, Inc. |
4 | ||
f309ff0a | 5 | This file is part of GCC. |
fec763fc | 6 | |
f309ff0a | 7 | GCC is free software; you can redistribute it and/or modify |
fec763fc TT |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
f309ff0a | 12 | GCC is distributed in the hope that it will be useful, |
fec763fc TT |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
f309ff0a | 18 | along with GCC; see the file COPYING. If not, write to |
fec763fc TT |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. | |
21 | ||
22 | Java and all Java-based marks are trademarks or registered trademarks | |
23 | of Sun Microsystems, Inc. in the United States and other countries. | |
24 | The Free Software Foundation is independent of Sun Microsystems, Inc. */ | |
25 | ||
26 | /* Written by Tom Tromey <tromey@redhat.com>. */ | |
27 | ||
28 | #include "config.h" | |
29 | #include "system.h" | |
4977bab6 ZW |
30 | #include "coretypes.h" |
31 | #include "tm.h" | |
fec763fc TT |
32 | #include "tree.h" |
33 | #include "ggc.h" | |
34 | #include "flags.h" | |
b0c48229 | 35 | #include "langhooks.h" |
fec763fc TT |
36 | #include "java-tree.h" |
37 | ||
fec763fc | 38 | |
d2097937 KG |
39 | static tree max_builtin (tree, tree); |
40 | static tree min_builtin (tree, tree); | |
41 | static tree abs_builtin (tree, tree); | |
fec763fc | 42 | |
f981519d | 43 | static tree java_build_function_call_expr (tree, tree); |
d2097937 | 44 | static void define_builtin (enum built_in_function, const char *, |
5f158b44 | 45 | tree, const char *); |
fec763fc TT |
46 | |
47 | \f | |
48 | ||
49 | /* Functions of this type are used to inline a given call. Such a | |
50 | function should either return an expression, if the call is to be | |
51 | inlined, or NULL_TREE if a real call should be emitted. Arguments | |
52 | are method return type and arguments to call. */ | |
35222de2 | 53 | typedef tree builtin_creator_function (tree, tree); |
fec763fc TT |
54 | |
55 | /* Hold a char*, before initialization, or a tree, after | |
56 | initialization. */ | |
e2500fed | 57 | union string_or_tree GTY(()) |
fec763fc | 58 | { |
e2500fed GK |
59 | const char * GTY ((tag ("0"))) s; |
60 | tree GTY ((tag ("1"))) t; | |
fec763fc TT |
61 | }; |
62 | ||
63 | /* Used to hold a single builtin record. */ | |
e2500fed | 64 | struct builtin_record GTY(()) |
fec763fc | 65 | { |
e2500fed GK |
66 | union string_or_tree GTY ((desc ("1"))) class_name; |
67 | union string_or_tree GTY ((desc ("1"))) method_name; | |
1431042e | 68 | builtin_creator_function * GTY((skip)) creator; |
833e1a77 | 69 | enum built_in_function builtin_code; |
fec763fc TT |
70 | }; |
71 | ||
e2500fed | 72 | static GTY(()) struct builtin_record java_builtins[] = |
fec763fc | 73 | { |
833e1a77 RS |
74 | { { "java.lang.Math" }, { "min" }, min_builtin, 0 }, |
75 | { { "java.lang.Math" }, { "max" }, max_builtin, 0 }, | |
76 | { { "java.lang.Math" }, { "abs" }, abs_builtin, 0 }, | |
2d99c042 RS |
77 | { { "java.lang.Math" }, { "acos" }, NULL, BUILT_IN_ACOS }, |
78 | { { "java.lang.Math" }, { "asin" }, NULL, BUILT_IN_ASIN }, | |
833e1a77 RS |
79 | { { "java.lang.Math" }, { "atan" }, NULL, BUILT_IN_ATAN }, |
80 | { { "java.lang.Math" }, { "atan2" }, NULL, BUILT_IN_ATAN2 }, | |
2d99c042 | 81 | { { "java.lang.Math" }, { "ceil" }, NULL, BUILT_IN_CEIL }, |
833e1a77 RS |
82 | { { "java.lang.Math" }, { "cos" }, NULL, BUILT_IN_COS }, |
83 | { { "java.lang.Math" }, { "exp" }, NULL, BUILT_IN_EXP }, | |
2d99c042 | 84 | { { "java.lang.Math" }, { "floor" }, NULL, BUILT_IN_FLOOR }, |
833e1a77 RS |
85 | { { "java.lang.Math" }, { "log" }, NULL, BUILT_IN_LOG }, |
86 | { { "java.lang.Math" }, { "pow" }, NULL, BUILT_IN_POW }, | |
87 | { { "java.lang.Math" }, { "sin" }, NULL, BUILT_IN_SIN }, | |
88 | { { "java.lang.Math" }, { "sqrt" }, NULL, BUILT_IN_SQRT }, | |
89 | { { "java.lang.Math" }, { "tan" }, NULL, BUILT_IN_TAN }, | |
90 | { { NULL }, { NULL }, NULL, END_BUILTINS } | |
fec763fc TT |
91 | }; |
92 | ||
fec763fc TT |
93 | \f |
94 | /* Internal functions which implement various builtin conversions. */ | |
95 | ||
96 | static tree | |
0a2f0c54 | 97 | max_builtin (tree method_return_type, tree method_arguments) |
fec763fc | 98 | { |
833e1a77 RS |
99 | return fold (build (MAX_EXPR, method_return_type, |
100 | TREE_VALUE (method_arguments), | |
101 | TREE_VALUE (TREE_CHAIN (method_arguments)))); | |
fec763fc TT |
102 | } |
103 | ||
104 | static tree | |
0a2f0c54 | 105 | min_builtin (tree method_return_type, tree method_arguments) |
fec763fc | 106 | { |
833e1a77 RS |
107 | return fold (build (MIN_EXPR, method_return_type, |
108 | TREE_VALUE (method_arguments), | |
109 | TREE_VALUE (TREE_CHAIN (method_arguments)))); | |
fec763fc TT |
110 | } |
111 | ||
112 | static tree | |
0a2f0c54 | 113 | abs_builtin (tree method_return_type, tree method_arguments) |
fec763fc | 114 | { |
833e1a77 RS |
115 | return fold (build1 (ABS_EXPR, method_return_type, |
116 | TREE_VALUE (method_arguments))); | |
fec763fc TT |
117 | } |
118 | ||
119 | /* Mostly copied from ../builtins.c. */ | |
120 | static tree | |
f981519d | 121 | java_build_function_call_expr (tree fn, tree arglist) |
fec763fc TT |
122 | { |
123 | tree call_expr; | |
124 | ||
125 | call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); | |
126 | call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), | |
127 | call_expr, arglist); | |
128 | TREE_SIDE_EFFECTS (call_expr) = 1; | |
833e1a77 | 129 | return fold (call_expr); |
fec763fc TT |
130 | } |
131 | ||
132 | \f | |
133 | ||
134 | /* Define a single builtin. */ | |
135 | static void | |
0a2f0c54 KG |
136 | define_builtin (enum built_in_function val, |
137 | const char *name, | |
0a2f0c54 | 138 | tree type, |
5f158b44 | 139 | const char *libname) |
fec763fc TT |
140 | { |
141 | tree decl; | |
142 | ||
fec763fc TT |
143 | decl = build_decl (FUNCTION_DECL, get_identifier (name), type); |
144 | DECL_EXTERNAL (decl) = 1; | |
145 | TREE_PUBLIC (decl) = 1; | |
5f158b44 | 146 | SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname)); |
fec763fc TT |
147 | make_decl_rtl (decl, NULL); |
148 | pushdecl (decl); | |
5f158b44 | 149 | DECL_BUILT_IN_CLASS (decl) = BUILT_IN_NORMAL; |
fec763fc | 150 | DECL_FUNCTION_CODE (decl) = val; |
fec763fc | 151 | |
5f158b44 RS |
152 | implicit_built_in_decls[val] = decl; |
153 | built_in_decls[val] = decl; | |
fec763fc TT |
154 | } |
155 | ||
156 | \f | |
157 | ||
158 | /* Initialize the builtins. */ | |
159 | void | |
0a2f0c54 | 160 | initialize_builtins (void) |
fec763fc | 161 | { |
5f158b44 RS |
162 | tree double_ftype_double, double_ftype_double_double; |
163 | tree float_ftype_float, float_ftype_float_float; | |
164 | tree t; | |
fec763fc TT |
165 | int i; |
166 | ||
833e1a77 | 167 | for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i) |
fec763fc TT |
168 | { |
169 | tree klass_id = get_identifier (java_builtins[i].class_name.s); | |
170 | tree m = get_identifier (java_builtins[i].method_name.s); | |
171 | ||
172 | java_builtins[i].class_name.t = klass_id; | |
173 | java_builtins[i].method_name.t = m; | |
fec763fc TT |
174 | } |
175 | ||
176 | void_list_node = end_params_node; | |
177 | ||
5f158b44 RS |
178 | t = tree_cons (NULL_TREE, float_type_node, end_params_node); |
179 | float_ftype_float = build_function_type (float_type_node, t); | |
180 | t = tree_cons (NULL_TREE, float_type_node, t); | |
181 | float_ftype_float_float = build_function_type (float_type_node, t); | |
182 | ||
183 | t = tree_cons (NULL_TREE, double_type_node, end_params_node); | |
184 | double_ftype_double = build_function_type (double_type_node, t); | |
185 | t = tree_cons (NULL_TREE, double_type_node, t); | |
186 | double_ftype_double_double = build_function_type (double_type_node, t); | |
187 | ||
188 | define_builtin (BUILT_IN_FMOD, "__builtin_fmod", | |
189 | double_ftype_double_double, "fmod"); | |
190 | define_builtin (BUILT_IN_FMODF, "__builtin_fmodf", | |
191 | float_ftype_float_float, "fmodf"); | |
192 | ||
2d99c042 RS |
193 | define_builtin (BUILT_IN_ACOS, "__builtin_acos", |
194 | double_ftype_double, "_ZN4java4lang4Math4acosEd"); | |
195 | define_builtin (BUILT_IN_ASIN, "__builtin_asin", | |
196 | double_ftype_double, "_ZN4java4lang4Math4asinEd"); | |
5f158b44 RS |
197 | define_builtin (BUILT_IN_ATAN, "__builtin_atan", |
198 | double_ftype_double, "_ZN4java4lang4Math4atanEd"); | |
199 | define_builtin (BUILT_IN_ATAN2, "__builtin_atan2", | |
200 | double_ftype_double_double, "_ZN4java4lang4Math5atan2Edd"); | |
2d99c042 RS |
201 | define_builtin (BUILT_IN_CEIL, "__builtin_ceil", |
202 | double_ftype_double, "_ZN4java4lang4Math4ceilEd"); | |
5f158b44 RS |
203 | define_builtin (BUILT_IN_COS, "__builtin_cos", |
204 | double_ftype_double, "_ZN4java4lang4Math3cosEd"); | |
205 | define_builtin (BUILT_IN_EXP, "__builtin_exp", | |
206 | double_ftype_double, "_ZN4java4lang4Math3expEd"); | |
2d99c042 RS |
207 | define_builtin (BUILT_IN_FLOOR, "__builtin_floor", |
208 | double_ftype_double, "_ZN4java4lang4Math5floorEd"); | |
5f158b44 RS |
209 | define_builtin (BUILT_IN_LOG, "__builtin_log", |
210 | double_ftype_double, "_ZN4java4lang4Math3logEd"); | |
211 | define_builtin (BUILT_IN_POW, "__builtin_pow", | |
212 | double_ftype_double_double, "_ZN4java4lang4Math3powEdd"); | |
213 | define_builtin (BUILT_IN_SIN, "__builtin_sin", | |
214 | double_ftype_double, "_ZN4java4lang4Math3sinEd"); | |
215 | define_builtin (BUILT_IN_SQRT, "__builtin_sqrt", | |
216 | double_ftype_double, "_ZN4java4lang4Math4sqrtEd"); | |
217 | define_builtin (BUILT_IN_TAN, "__builtin_tan", | |
218 | double_ftype_double, "_ZN4java4lang4Math3tanEd"); | |
fec763fc TT |
219 | } |
220 | ||
9fe2cc05 | 221 | /* If the call matches a builtin, return the |
fec763fc TT |
222 | appropriate builtin expression instead. */ |
223 | tree | |
0a2f0c54 | 224 | check_for_builtin (tree method, tree call) |
fec763fc | 225 | { |
9fe2cc05 | 226 | if (! flag_emit_class_files && optimize && TREE_CODE (call) == CALL_EXPR) |
fec763fc TT |
227 | { |
228 | int i; | |
9fe2cc05 PB |
229 | tree method_arguments = TREE_OPERAND (call, 1); |
230 | tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method))); | |
231 | tree method_name = DECL_NAME (method); | |
232 | tree method_return_type = TREE_TYPE (TREE_TYPE (method)); | |
fec763fc | 233 | |
833e1a77 | 234 | for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i) |
fec763fc TT |
235 | { |
236 | if (method_class == java_builtins[i].class_name.t | |
237 | && method_name == java_builtins[i].method_name.t) | |
238 | { | |
833e1a77 RS |
239 | tree fn; |
240 | ||
241 | if (java_builtins[i].creator != NULL) | |
242 | return (*java_builtins[i].creator) (method_return_type, | |
243 | method_arguments); | |
244 | fn = built_in_decls[java_builtins[i].builtin_code]; | |
245 | if (fn == NULL_TREE) | |
246 | return NULL_TREE; | |
247 | return java_build_function_call_expr (fn, method_arguments); | |
fec763fc TT |
248 | } |
249 | } | |
250 | } | |
fec763fc TT |
251 | return call; |
252 | } | |
e2500fed GK |
253 | |
254 | #include "gt-java-builtins.h" |