00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "tree.h"
00031 #include "ggc.h"
00032 #include "flags.h"
00033
00034 #include "java-tree.h"
00035
00036 enum builtin_type
00037 {
00038 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
00039 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
00040 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
00041 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
00042 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
00043 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
00044 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
00045 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
00046 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
00047 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
00048 #include "builtin-types.def"
00049 #undef DEF_PRIMITIVE_TYPE
00050 #undef DEF_FUNCTION_TYPE_0
00051 #undef DEF_FUNCTION_TYPE_1
00052 #undef DEF_FUNCTION_TYPE_2
00053 #undef DEF_FUNCTION_TYPE_3
00054 #undef DEF_FUNCTION_TYPE_4
00055 #undef DEF_FUNCTION_TYPE_VAR_0
00056 #undef DEF_FUNCTION_TYPE_VAR_1
00057 #undef DEF_FUNCTION_TYPE_VAR_2
00058 #undef DEF_POINTER_TYPE
00059 BT_LAST
00060 };
00061
00062 static tree max_builtin PARAMS ((tree, tree));
00063 static tree min_builtin PARAMS ((tree, tree));
00064 static tree abs_builtin PARAMS ((tree, tree));
00065 static tree cos_builtin PARAMS ((tree, tree));
00066 static tree sin_builtin PARAMS ((tree, tree));
00067 static tree sqrt_builtin PARAMS ((tree, tree));
00068
00069 static tree build_function_call_expr PARAMS ((tree, tree));
00070 static void define_builtin PARAMS ((enum built_in_function,
00071 const char *,
00072 enum built_in_class,
00073 tree, int));
00074 static tree define_builtin_type PARAMS ((int, int, int, int, int));
00075
00076
00077
00078
00079
00080
00081
00082 typedef tree builtin_creator_function PARAMS ((tree, tree));
00083
00084
00085
00086 union string_or_tree
00087 {
00088 const char *s;
00089 tree t;
00090 };
00091
00092
00093 struct builtin_record
00094 {
00095 union string_or_tree class_name;
00096 union string_or_tree method_name;
00097 builtin_creator_function *creator;
00098 };
00099
00100 static struct builtin_record java_builtins[] =
00101 {
00102 { { "java.lang.Math" }, { "min" }, min_builtin },
00103 { { "java.lang.Math" }, { "max" }, max_builtin },
00104 { { "java.lang.Math" }, { "abs" }, abs_builtin },
00105 { { "java.lang.Math" }, { "cos" }, cos_builtin },
00106 { { "java.lang.Math" }, { "sin" }, sin_builtin },
00107 { { "java.lang.Math" }, { "sqrt" }, sqrt_builtin },
00108 { { NULL }, { NULL }, NULL }
00109 };
00110
00111
00112
00113 static tree builtin_types[(int) BT_LAST];
00114
00115
00116
00117
00118 static tree
00119 max_builtin (method_return_type, method_arguments)
00120 tree method_return_type, method_arguments;
00121 {
00122 return build (MAX_EXPR, method_return_type,
00123 TREE_VALUE (method_arguments),
00124 TREE_VALUE (TREE_CHAIN (method_arguments)));
00125 }
00126
00127 static tree
00128 min_builtin (method_return_type, method_arguments)
00129 tree method_return_type, method_arguments;
00130 {
00131 return build (MIN_EXPR, method_return_type,
00132 TREE_VALUE (method_arguments),
00133 TREE_VALUE (TREE_CHAIN (method_arguments)));
00134 }
00135
00136 static tree
00137 abs_builtin (method_return_type, method_arguments)
00138 tree method_return_type, method_arguments;
00139 {
00140 return build1 (ABS_EXPR, method_return_type,
00141 TREE_VALUE (method_arguments));
00142 }
00143
00144
00145 static tree
00146 build_function_call_expr (tree fn, tree arglist)
00147 {
00148 tree call_expr;
00149
00150 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
00151 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
00152 call_expr, arglist);
00153 TREE_SIDE_EFFECTS (call_expr) = 1;
00154 return call_expr;
00155 }
00156
00157 static tree
00158 cos_builtin (method_return_type, method_arguments)
00159 tree method_return_type ATTRIBUTE_UNUSED, method_arguments;
00160 {
00161
00162 tree fn = built_in_decls[BUILT_IN_COS];
00163 if (fn == NULL_TREE)
00164 return NULL_TREE;
00165 return build_function_call_expr (fn, method_arguments);
00166 }
00167
00168 static tree
00169 sin_builtin (method_return_type, method_arguments)
00170 tree method_return_type ATTRIBUTE_UNUSED, method_arguments;
00171 {
00172
00173 tree fn = built_in_decls[BUILT_IN_SIN];
00174 if (fn == NULL_TREE)
00175 return NULL_TREE;
00176 return build_function_call_expr (fn, method_arguments);
00177 }
00178
00179 static tree
00180 sqrt_builtin (method_return_type, method_arguments)
00181 tree method_return_type ATTRIBUTE_UNUSED, method_arguments;
00182 {
00183
00184 tree fn = built_in_decls[BUILT_IN_SQRT];
00185 if (fn == NULL_TREE)
00186 return NULL_TREE;
00187 return build_function_call_expr (fn, method_arguments);
00188 }
00189
00190
00191
00192
00193 static void
00194 define_builtin (val, name, class, type, fallback_p)
00195 enum built_in_function val;
00196 const char *name;
00197 enum built_in_class class;
00198 tree type;
00199 int fallback_p;
00200 {
00201 tree decl;
00202
00203 if (! name || ! type)
00204 return;
00205
00206 if (strncmp (name, "__builtin_", strlen ("__builtin_")) != 0)
00207 abort ();
00208 decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
00209 DECL_EXTERNAL (decl) = 1;
00210 TREE_PUBLIC (decl) = 1;
00211 if (fallback_p)
00212 SET_DECL_ASSEMBLER_NAME (decl,
00213 get_identifier (name + strlen ("__builtin_")));
00214 make_decl_rtl (decl, NULL);
00215 pushdecl (decl);
00216 DECL_BUILT_IN_CLASS (decl) = class;
00217 DECL_FUNCTION_CODE (decl) = val;
00218 built_in_decls[val] = decl;
00219 }
00220
00221
00222 static tree
00223 define_builtin_type (ret, arg1, arg2, arg3, arg4)
00224 int ret, arg1, arg2, arg3, arg4;
00225 {
00226 tree args;
00227
00228 if (builtin_types[ret] == NULL_TREE)
00229 return NULL_TREE;
00230
00231 args = void_list_node;
00232
00233 if (arg4 != -1)
00234 {
00235 if (builtin_types[arg4] == NULL_TREE)
00236 return NULL_TREE;
00237 args = tree_cons (NULL_TREE, builtin_types[arg4], args);
00238 }
00239 if (arg3 != -1)
00240 {
00241 if (builtin_types[arg3] == NULL_TREE)
00242 return NULL_TREE;
00243 args = tree_cons (NULL_TREE, builtin_types[arg3], args);
00244 }
00245 if (arg2 != -1)
00246 {
00247 if (builtin_types[arg2] == NULL_TREE)
00248 return NULL_TREE;
00249 args = tree_cons (NULL_TREE, builtin_types[arg2], args);
00250 }
00251 if (arg1 != -1)
00252 {
00253 if (builtin_types[arg1] == NULL_TREE)
00254 return NULL_TREE;
00255 args = tree_cons (NULL_TREE, builtin_types[arg1], args);
00256 }
00257
00258 return build_function_type (builtin_types[ret], args);
00259 }
00260
00261
00262
00263
00264 void
00265 initialize_builtins ()
00266 {
00267 int i;
00268
00269 for (i = 0; java_builtins[i].creator != NULL; ++i)
00270 {
00271 tree klass_id = get_identifier (java_builtins[i].class_name.s);
00272 tree m = get_identifier (java_builtins[i].method_name.s);
00273
00274 java_builtins[i].class_name.t = klass_id;
00275 java_builtins[i].method_name.t = m;
00276 ggc_add_tree_root (&java_builtins[i].class_name.t, 1);
00277 ggc_add_tree_root (&java_builtins[i].method_name.t, 1);
00278 }
00279
00280 void_list_node = end_params_node;
00281
00282
00283 #define intmax_type_node NULL_TREE
00284 #define traditional_ptr_type_node NULL_TREE
00285 #define traditional_cptr_type_node NULL_TREE
00286 #define c_size_type_node NULL_TREE
00287 #define const_string_type_node NULL_TREE
00288 #define traditional_len_type_node NULL_TREE
00289 #define va_list_ref_type_node NULL_TREE
00290 #define va_list_arg_type_node NULL_TREE
00291 #define flag_isoc99 0
00292
00293 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
00294 builtin_types[(int) ENUM] = VALUE;
00295 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
00296 builtin_types[(int) ENUM] \
00297 = define_builtin_type (RETURN, -1, -1, -1, -1);
00298 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
00299 builtin_types[(int) ENUM] \
00300 = define_builtin_type (RETURN, ARG1, -1, -1, -1);
00301 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
00302 builtin_types[(int) ENUM] \
00303 = define_builtin_type (RETURN, ARG1, ARG2, -1, -1);
00304 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
00305 builtin_types[(int) ENUM] \
00306 = define_builtin_type (RETURN, ARG1, ARG2, ARG3, -1);
00307 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
00308 builtin_types[(int) ENUM] \
00309 = define_builtin_type (RETURN, ARG1, ARG2, ARG3, ARG4);
00310 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
00311 builtin_types[(int) ENUM] = NULL_TREE;
00312 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
00313 builtin_types[(int) ENUM] = NULL_TREE;
00314 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
00315 builtin_types[(int) ENUM] = NULL_TREE;
00316 #define DEF_POINTER_TYPE(ENUM, TYPE) \
00317 builtin_types[(int) ENUM] = NULL_TREE;
00318
00319 #include "builtin-types.def"
00320
00321 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, \
00322 FALLBACK_P, NONANSI_P) \
00323 define_builtin (ENUM, NAME, CLASS, builtin_types[TYPE], FALLBACK_P);
00324 #include "builtins.def"
00325 }
00326
00327
00328
00329 tree
00330 check_for_builtin (method, call)
00331 tree method;
00332 tree call;
00333 {
00334 if (! flag_emit_class_files && optimize && TREE_CODE (call) == CALL_EXPR)
00335 {
00336 int i;
00337 tree method_arguments = TREE_OPERAND (call, 1);
00338 tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
00339 tree method_name = DECL_NAME (method);
00340 tree method_return_type = TREE_TYPE (TREE_TYPE (method));
00341
00342 for (i = 0; java_builtins[i].creator != NULL; ++i)
00343 {
00344 if (method_class == java_builtins[i].class_name.t
00345 && method_name == java_builtins[i].method_name.t)
00346 {
00347 return (*java_builtins[i].creator) (method_return_type,
00348 method_arguments);
00349 }
00350 }
00351 }
00352 return call;
00353 }