]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/java/builtins.c
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / java / builtins.c
CommitLineData
fec763fc 1/* Built-in and inline functions for gcj
23a5b65a 2 Copyright (C) 2001-2014 Free Software Foundation, Inc.
fec763fc 3
f309ff0a 4This file is part of GCC.
fec763fc 5
f309ff0a 6GCC is free software; you can redistribute it and/or modify
fec763fc 7it under the terms of the GNU General Public License as published by
8328d52a 8the Free Software Foundation; either version 3, or (at your option)
fec763fc
TT
9any later version.
10
f309ff0a 11GCC is distributed in the hope that it will be useful,
fec763fc
TT
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
8328d52a
NC
16.
17
18.
fec763fc
TT
19
20Java and all Java-based marks are trademarks or registered trademarks
21of Sun Microsystems, Inc. in the United States and other countries.
22The Free Software Foundation is independent of Sun Microsystems, Inc. */
23
24/* Written by Tom Tromey <tromey@redhat.com>. */
25
7a3b4887
SB
26/* FIXME: Still need to include rtl.h here (see below). */
27#undef IN_GCC_FRONTEND
28
fec763fc
TT
29#include "config.h"
30#include "system.h"
4977bab6
ZW
31#include "coretypes.h"
32#include "tm.h"
fec763fc 33#include "tree.h"
d8a2d370
DN
34#include "stor-layout.h"
35#include "stringpool.h"
fec763fc
TT
36#include "ggc.h"
37#include "flags.h"
b0c48229 38#include "langhooks.h"
fec763fc 39#include "java-tree.h"
f67cc87d
SB
40
41/* FIXME: All these headers are necessary for sync_compare_and_swap.
42 Front ends should never have to look at that. */
97b8365c
TT
43#include "rtl.h"
44#include "insn-codes.h"
45#include "expr.h"
46#include "optabs.h"
fec763fc 47
d2097937
KG
48static tree max_builtin (tree, tree);
49static tree min_builtin (tree, tree);
50static tree abs_builtin (tree, tree);
855dd2bc 51static tree convert_real (tree, tree);
fec763fc 52
f981519d 53static tree java_build_function_call_expr (tree, tree);
fec763fc 54
97b8365c
TT
55static tree putObject_builtin (tree, tree);
56static tree compareAndSwapInt_builtin (tree, tree);
57static tree compareAndSwapLong_builtin (tree, tree);
58static tree compareAndSwapObject_builtin (tree, tree);
59static tree putVolatile_builtin (tree, tree);
60static tree getVolatile_builtin (tree, tree);
c863b570 61static tree VMSupportsCS8_builtin (tree, tree);
fec763fc
TT
62\f
63
64/* Functions of this type are used to inline a given call. Such a
65 function should either return an expression, if the call is to be
66 inlined, or NULL_TREE if a real call should be emitted. Arguments
5039610b
SL
67 are method return type and the original CALL_EXPR containing the
68 arguments to the call. */
35222de2 69typedef tree builtin_creator_function (tree, tree);
fec763fc
TT
70
71/* Hold a char*, before initialization, or a tree, after
72 initialization. */
d1b38208 73union GTY(()) string_or_tree {
e2500fed
GK
74 const char * GTY ((tag ("0"))) s;
75 tree GTY ((tag ("1"))) t;
fec763fc
TT
76};
77
78/* Used to hold a single builtin record. */
d1b38208 79struct GTY(()) builtin_record {
e2500fed
GK
80 union string_or_tree GTY ((desc ("1"))) class_name;
81 union string_or_tree GTY ((desc ("1"))) method_name;
1431042e 82 builtin_creator_function * GTY((skip)) creator;
833e1a77 83 enum built_in_function builtin_code;
fec763fc
TT
84};
85
e2500fed 86static GTY(()) struct builtin_record java_builtins[] =
fec763fc 87{
81f40b79
ILT
88 { { "java.lang.Math" }, { "min" }, min_builtin, (enum built_in_function) 0 },
89 { { "java.lang.Math" }, { "max" }, max_builtin, (enum built_in_function) 0 },
90 { { "java.lang.Math" }, { "abs" }, abs_builtin, (enum built_in_function) 0 },
2d99c042
RS
91 { { "java.lang.Math" }, { "acos" }, NULL, BUILT_IN_ACOS },
92 { { "java.lang.Math" }, { "asin" }, NULL, BUILT_IN_ASIN },
833e1a77
RS
93 { { "java.lang.Math" }, { "atan" }, NULL, BUILT_IN_ATAN },
94 { { "java.lang.Math" }, { "atan2" }, NULL, BUILT_IN_ATAN2 },
2d99c042 95 { { "java.lang.Math" }, { "ceil" }, NULL, BUILT_IN_CEIL },
833e1a77
RS
96 { { "java.lang.Math" }, { "cos" }, NULL, BUILT_IN_COS },
97 { { "java.lang.Math" }, { "exp" }, NULL, BUILT_IN_EXP },
2d99c042 98 { { "java.lang.Math" }, { "floor" }, NULL, BUILT_IN_FLOOR },
833e1a77
RS
99 { { "java.lang.Math" }, { "log" }, NULL, BUILT_IN_LOG },
100 { { "java.lang.Math" }, { "pow" }, NULL, BUILT_IN_POW },
101 { { "java.lang.Math" }, { "sin" }, NULL, BUILT_IN_SIN },
102 { { "java.lang.Math" }, { "sqrt" }, NULL, BUILT_IN_SQRT },
103 { { "java.lang.Math" }, { "tan" }, NULL, BUILT_IN_TAN },
81f40b79
ILT
104 { { "java.lang.Float" }, { "intBitsToFloat" }, convert_real,
105 (enum built_in_function) 0 },
106 { { "java.lang.Double" }, { "longBitsToDouble" }, convert_real,
107 (enum built_in_function) 0 },
108 { { "java.lang.Float" }, { "floatToRawIntBits" }, convert_real,
109 (enum built_in_function) 0 },
110 { { "java.lang.Double" }, { "doubleToRawLongBits" }, convert_real,
111 (enum built_in_function) 0 },
112 { { "sun.misc.Unsafe" }, { "putInt" }, putObject_builtin,
113 (enum built_in_function) 0},
114 { { "sun.misc.Unsafe" }, { "putLong" }, putObject_builtin,
115 (enum built_in_function) 0},
116 { { "sun.misc.Unsafe" }, { "putObject" }, putObject_builtin,
117 (enum built_in_function) 0},
118 { { "sun.misc.Unsafe" }, { "compareAndSwapInt" },
119 compareAndSwapInt_builtin, (enum built_in_function) 0},
120 { { "sun.misc.Unsafe" }, { "compareAndSwapLong" },
121 compareAndSwapLong_builtin, (enum built_in_function) 0},
122 { { "sun.misc.Unsafe" }, { "compareAndSwapObject" },
123 compareAndSwapObject_builtin, (enum built_in_function) 0},
124 { { "sun.misc.Unsafe" }, { "putOrderedInt" }, putVolatile_builtin,
125 (enum built_in_function) 0},
126 { { "sun.misc.Unsafe" }, { "putOrderedLong" }, putVolatile_builtin,
127 (enum built_in_function) 0},
128 { { "sun.misc.Unsafe" }, { "putOrderedObject" }, putVolatile_builtin,
129 (enum built_in_function) 0},
130 { { "sun.misc.Unsafe" }, { "putIntVolatile" }, putVolatile_builtin,
131 (enum built_in_function) 0},
132 { { "sun.misc.Unsafe" }, { "putLongVolatile" }, putVolatile_builtin,
133 (enum built_in_function) 0},
134 { { "sun.misc.Unsafe" }, { "putObjectVolatile" }, putVolatile_builtin,
135 (enum built_in_function) 0},
136 { { "sun.misc.Unsafe" }, { "getObjectVolatile" }, getVolatile_builtin,
137 (enum built_in_function) 0},
138 { { "sun.misc.Unsafe" }, { "getIntVolatile" }, getVolatile_builtin,
139 (enum built_in_function) 0},
140 { { "sun.misc.Unsafe" }, { "getLongVolatile" }, getVolatile_builtin, (enum built_in_function) 0},
141 { { "sun.misc.Unsafe" }, { "getLong" }, getVolatile_builtin,
142 (enum built_in_function) 0},
143 { { "java.util.concurrent.atomic.AtomicLong" }, { "VMSupportsCS8" },
144 VMSupportsCS8_builtin, (enum built_in_function) 0},
833e1a77 145 { { NULL }, { NULL }, NULL, END_BUILTINS }
fec763fc
TT
146};
147
fec763fc
TT
148\f
149/* Internal functions which implement various builtin conversions. */
150
151static tree
5039610b 152max_builtin (tree method_return_type, tree orig_call)
fec763fc 153{
05d8200d
TT
154 /* MAX_EXPR does not handle -0.0 in the Java style. */
155 if (TREE_CODE (method_return_type) == REAL_TYPE)
156 return NULL_TREE;
c298ec4e 157 return fold_build2 (MAX_EXPR, method_return_type,
5039610b
SL
158 CALL_EXPR_ARG (orig_call, 0),
159 CALL_EXPR_ARG (orig_call, 1));
fec763fc
TT
160}
161
162static tree
5039610b 163min_builtin (tree method_return_type, tree orig_call)
fec763fc 164{
05d8200d
TT
165 /* MIN_EXPR does not handle -0.0 in the Java style. */
166 if (TREE_CODE (method_return_type) == REAL_TYPE)
167 return NULL_TREE;
c298ec4e 168 return fold_build2 (MIN_EXPR, method_return_type,
5039610b
SL
169 CALL_EXPR_ARG (orig_call, 0),
170 CALL_EXPR_ARG (orig_call, 1));
fec763fc
TT
171}
172
173static tree
5039610b 174abs_builtin (tree method_return_type, tree orig_call)
fec763fc 175{
c298ec4e 176 return fold_build1 (ABS_EXPR, method_return_type,
5039610b 177 CALL_EXPR_ARG (orig_call, 0));
fec763fc
TT
178}
179
5039610b
SL
180/* Construct a new call to FN using the arguments from ORIG_CALL. */
181
fec763fc 182static tree
5039610b 183java_build_function_call_expr (tree fn, tree orig_call)
fec763fc 184{
5039610b
SL
185 int nargs = call_expr_nargs (orig_call);
186 switch (nargs)
187 {
188 /* Although we could handle the 0-3 argument cases using the general
189 logic in the default case, splitting them out permits folding to
190 be performed without constructing a temporary CALL_EXPR. */
191 case 0:
192 return build_call_expr (fn, 0);
193 case 1:
194 return build_call_expr (fn, 1, CALL_EXPR_ARG (orig_call, 0));
195 case 2:
196 return build_call_expr (fn, 2,
197 CALL_EXPR_ARG (orig_call, 0),
198 CALL_EXPR_ARG (orig_call, 1));
199 case 3:
200 return build_call_expr (fn, 3,
201 CALL_EXPR_ARG (orig_call, 0),
202 CALL_EXPR_ARG (orig_call, 1),
203 CALL_EXPR_ARG (orig_call, 2));
204 default:
205 {
206 tree fntype = TREE_TYPE (fn);
207 fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fn);
208 return fold (build_call_array (TREE_TYPE (fntype),
209 fn, nargs, CALL_EXPR_ARGP (orig_call)));
210 }
211 }
fec763fc
TT
212}
213
855dd2bc 214static tree
5039610b 215convert_real (tree method_return_type, tree orig_call)
855dd2bc
TT
216{
217 return build1 (VIEW_CONVERT_EXPR, method_return_type,
5039610b 218 CALL_EXPR_ARG (orig_call, 0));
855dd2bc
TT
219}
220
fec763fc
TT
221\f
222
97b8365c
TT
223/* Provide builtin support for atomic operations. These are
224 documented at length in libjava/sun/misc/Unsafe.java. */
225
226/* FIXME. There are still a few things wrong with this logic. In
227 particular, atomic writes of multi-word integers are not truly
228 atomic: this requires more work.
229
230 In general, double-word compare-and-swap cannot portably be
231 implemented, so we need some kind of fallback for 32-bit machines.
232
233*/
234
235
5039610b 236/* Macros to unmarshal arguments from a CALL_EXPR into a few
97b8365c
TT
237 variables. We also convert the offset arg from a long to an
238 integer that is the same size as a pointer. */
239
5039610b 240#define UNMARSHAL3(METHOD_CALL) \
97b8365c
TT
241tree this_arg, obj_arg, offset_arg; \
242do \
243{ \
5039610b
SL
244 tree orig_method_call = METHOD_CALL; \
245 this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
246 obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
97b8365c 247 offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
5039610b 248 CALL_EXPR_ARG (orig_method_call, 2)); \
97b8365c
TT
249} \
250while (0)
251
5039610b 252#define UNMARSHAL4(METHOD_CALL) \
97b8365c
TT
253tree value_type, this_arg, obj_arg, offset_arg, value_arg; \
254do \
255{ \
5039610b
SL
256 tree orig_method_call = METHOD_CALL; \
257 this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
258 obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
97b8365c 259 offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
5039610b
SL
260 CALL_EXPR_ARG (orig_method_call, 2)); \
261 value_arg = CALL_EXPR_ARG (orig_method_call, 3); \
97b8365c
TT
262 value_type = TREE_TYPE (value_arg); \
263} \
264while (0)
265
5039610b 266#define UNMARSHAL5(METHOD_CALL) \
97b8365c
TT
267tree value_type, this_arg, obj_arg, offset_arg, expected_arg, value_arg; \
268do \
269{ \
5039610b
SL
270 tree orig_method_call = METHOD_CALL; \
271 this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
272 obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
97b8365c 273 offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
5039610b
SL
274 CALL_EXPR_ARG (orig_method_call, 2)); \
275 expected_arg = CALL_EXPR_ARG (orig_method_call, 3); \
276 value_arg = CALL_EXPR_ARG (orig_method_call, 4); \
97b8365c
TT
277 value_type = TREE_TYPE (value_arg); \
278} \
279while (0)
280
97b8365c
TT
281/* Add an address to an offset, forming a sum. */
282
283static tree
284build_addr_sum (tree type, tree addr, tree offset)
285{
286 tree ptr_type = build_pointer_type (type);
5d49b6a7 287 return fold_build_pointer_plus (fold_convert (ptr_type, addr), offset);
97b8365c
TT
288}
289
290/* Make sure that this-arg is non-NULL. This is a security check. */
291
292static tree
293build_check_this (tree stmt, tree this_arg)
294{
295 return build2 (COMPOUND_EXPR, TREE_TYPE (stmt),
296 java_check_reference (this_arg, 1), stmt);
297}
298
299/* Now the builtins. These correspond to the primitive functions in
300 libjava/sun/misc/natUnsafe.cc. */
301
302static tree
303putObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
5039610b 304 tree orig_call)
97b8365c
TT
305{
306 tree addr, stmt;
5039610b 307 UNMARSHAL4 (orig_call);
97b8365c
TT
308
309 addr = build_addr_sum (value_type, obj_arg, offset_arg);
310 stmt = fold_build2 (MODIFY_EXPR, value_type,
311 build_java_indirect_ref (value_type, addr,
312 flag_check_references),
313 value_arg);
314
315 return build_check_this (stmt, this_arg);
316}
317
318static tree
319compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED,
5039610b 320 tree orig_call)
97b8365c
TT
321{
322 enum machine_mode mode = TYPE_MODE (int_type_node);
cedb4a1a 323 if (can_compare_and_swap_p (mode, flag_use_atomic_builtins))
97b8365c 324 {
5039610b 325 tree addr, stmt;
e79983f4 326 enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4;
5039610b 327 UNMARSHAL5 (orig_call);
60d3aec4 328 (void) value_type; /* Avoid set but not used warning. */
97b8365c
TT
329
330 addr = build_addr_sum (int_type_node, obj_arg, offset_arg);
e79983f4
MM
331 stmt = build_call_expr (builtin_decl_explicit (fncode),
332 3, addr, expected_arg, value_arg);
97b8365c
TT
333
334 return build_check_this (stmt, this_arg);
335 }
336 return NULL_TREE;
337}
338
339static tree
340compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED,
5039610b 341 tree orig_call)
97b8365c
TT
342{
343 enum machine_mode mode = TYPE_MODE (long_type_node);
cedb4a1a
RH
344 /* We don't trust flag_use_atomic_builtins for multi-word compareAndSwap.
345 Some machines such as ARM have atomic libfuncs but not the multi-word
346 versions. */
347 if (can_compare_and_swap_p (mode,
348 (flag_use_atomic_builtins
349 && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)))
97b8365c 350 {
5039610b 351 tree addr, stmt;
e79983f4 352 enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8;
5039610b 353 UNMARSHAL5 (orig_call);
60d3aec4 354 (void) value_type; /* Avoid set but not used warning. */
97b8365c
TT
355
356 addr = build_addr_sum (long_type_node, obj_arg, offset_arg);
e79983f4
MM
357 stmt = build_call_expr (builtin_decl_explicit (fncode),
358 3, addr, expected_arg, value_arg);
97b8365c
TT
359
360 return build_check_this (stmt, this_arg);
361 }
362 return NULL_TREE;
363}
364static tree
365compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
5039610b 366 tree orig_call)
97b8365c
TT
367{
368 enum machine_mode mode = TYPE_MODE (ptr_type_node);
cedb4a1a 369 if (can_compare_and_swap_p (mode, flag_use_atomic_builtins))
97b8365c 370 {
5039610b 371 tree addr, stmt;
e79983f4 372 enum built_in_function builtin;
97b8365c 373
5039610b 374 UNMARSHAL5 (orig_call);
97b8365c 375 builtin = (POINTER_SIZE == 32
e0a8ecf2
AM
376 ? BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4
377 : BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8);
97b8365c
TT
378
379 addr = build_addr_sum (value_type, obj_arg, offset_arg);
e79983f4 380 stmt = build_call_expr (builtin_decl_explicit (builtin),
5039610b 381 3, addr, expected_arg, value_arg);
97b8365c
TT
382
383 return build_check_this (stmt, this_arg);
384 }
385 return NULL_TREE;
386}
387
388static tree
389putVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
5039610b 390 tree orig_call)
97b8365c 391{
5039610b
SL
392 tree addr, stmt, modify_stmt;
393 UNMARSHAL4 (orig_call);
97b8365c
TT
394
395 addr = build_addr_sum (value_type, obj_arg, offset_arg);
396 addr
397 = fold_convert (build_pointer_type (build_type_variant (value_type, 0, 1)),
398 addr);
399
e79983f4 400 stmt = build_call_expr (builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE), 0);
97b8365c
TT
401 modify_stmt = fold_build2 (MODIFY_EXPR, value_type,
402 build_java_indirect_ref (value_type, addr,
403 flag_check_references),
404 value_arg);
405 stmt = build2 (COMPOUND_EXPR, TREE_TYPE (modify_stmt),
406 stmt, modify_stmt);
407
408 return build_check_this (stmt, this_arg);
409}
410
411static tree
412getVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
5039610b 413 tree orig_call)
97b8365c 414{
5039610b
SL
415 tree addr, stmt, modify_stmt, tmp;
416 UNMARSHAL3 (orig_call);
60d3aec4
JJ
417 (void) this_arg; /* Avoid set but not used warning. */
418
97b8365c
TT
419 addr = build_addr_sum (method_return_type, obj_arg, offset_arg);
420 addr
421 = fold_convert (build_pointer_type (build_type_variant
422 (method_return_type, 0, 1)), addr);
423
e79983f4 424 stmt = build_call_expr (builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE), 0);
c2255bc4 425 tmp = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL, method_return_type);
97b8365c
TT
426 DECL_IGNORED_P (tmp) = 1;
427 DECL_ARTIFICIAL (tmp) = 1;
428 pushdecl (tmp);
429
430 modify_stmt = fold_build2 (MODIFY_EXPR, method_return_type,
431 tmp,
432 build_java_indirect_ref (method_return_type, addr,
433 flag_check_references));
434
435 stmt = build2 (COMPOUND_EXPR, void_type_node, modify_stmt, stmt);
436 stmt = build2 (COMPOUND_EXPR, method_return_type, stmt, tmp);
437
438 return stmt;
439}
c863b570
AH
440
441static tree
442VMSupportsCS8_builtin (tree method_return_type,
5039610b 443 tree orig_call ATTRIBUTE_UNUSED)
c863b570
AH
444{
445 enum machine_mode mode = TYPE_MODE (long_type_node);
446 gcc_assert (method_return_type == boolean_type_node);
cedb4a1a 447 if (can_compare_and_swap_p (mode, false))
c863b570
AH
448 return boolean_true_node;
449 else
450 return boolean_false_node;
451}
452
97b8365c
TT
453\f
454
fec763fc
TT
455/* Define a single builtin. */
456static void
0a2f0c54
KG
457define_builtin (enum built_in_function val,
458 const char *name,
0a2f0c54 459 tree type,
6e0fbdd9
JH
460 const char *libname,
461 int flags)
fec763fc
TT
462{
463 tree decl;
464
c2255bc4
AH
465 decl = build_decl (BUILTINS_LOCATION,
466 FUNCTION_DECL, get_identifier (name), type);
fec763fc
TT
467 DECL_EXTERNAL (decl) = 1;
468 TREE_PUBLIC (decl) = 1;
5f158b44 469 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
fec763fc 470 pushdecl (decl);
5f158b44 471 DECL_BUILT_IN_CLASS (decl) = BUILT_IN_NORMAL;
fec763fc 472 DECL_FUNCTION_CODE (decl) = val;
3aac5aad 473 set_call_expr_flags (decl, flags);
fec763fc 474
e79983f4 475 set_builtin_decl (val, decl, true);
fec763fc
TT
476}
477
478\f
479
480/* Initialize the builtins. */
481void
0a2f0c54 482initialize_builtins (void)
fec763fc 483{
5f158b44 484 tree double_ftype_double, double_ftype_double_double;
c750c208 485 tree float_ftype_float_float;
2c80f015 486 tree boolean_ftype_boolean_boolean;
fec763fc
TT
487 int i;
488
833e1a77 489 for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i)
fec763fc
TT
490 {
491 tree klass_id = get_identifier (java_builtins[i].class_name.s);
492 tree m = get_identifier (java_builtins[i].method_name.s);
493
494 java_builtins[i].class_name.t = klass_id;
495 java_builtins[i].method_name.t = m;
fec763fc
TT
496 }
497
498 void_list_node = end_params_node;
499
9dc1704f
NF
500 float_ftype_float_float
501 = build_function_type_list (float_type_node,
502 float_type_node, float_type_node, NULL_TREE);
5f158b44 503
9dc1704f
NF
504 double_ftype_double
505 = build_function_type_list (double_type_node, double_type_node, NULL_TREE);
506 double_ftype_double_double
507 = build_function_type_list (double_type_node,
508 double_type_node, double_type_node, NULL_TREE);
5f158b44
RS
509
510 define_builtin (BUILT_IN_FMOD, "__builtin_fmod",
3aac5aad 511 double_ftype_double_double, "fmod", ECF_CONST);
5f158b44 512 define_builtin (BUILT_IN_FMODF, "__builtin_fmodf",
3aac5aad 513 float_ftype_float_float, "fmodf", ECF_CONST);
5f158b44 514
2d99c042 515 define_builtin (BUILT_IN_ACOS, "__builtin_acos",
92aed1cb 516 double_ftype_double, "_ZN4java4lang4Math4acosEJdd",
3aac5aad 517 ECF_CONST);
2d99c042 518 define_builtin (BUILT_IN_ASIN, "__builtin_asin",
92aed1cb 519 double_ftype_double, "_ZN4java4lang4Math4asinEJdd",
3aac5aad 520 ECF_CONST);
5f158b44 521 define_builtin (BUILT_IN_ATAN, "__builtin_atan",
92aed1cb 522 double_ftype_double, "_ZN4java4lang4Math4atanEJdd",
3aac5aad 523 ECF_CONST);
5f158b44 524 define_builtin (BUILT_IN_ATAN2, "__builtin_atan2",
92aed1cb 525 double_ftype_double_double, "_ZN4java4lang4Math5atan2EJddd",
3aac5aad 526 ECF_CONST);
2d99c042 527 define_builtin (BUILT_IN_CEIL, "__builtin_ceil",
92aed1cb 528 double_ftype_double, "_ZN4java4lang4Math4ceilEJdd",
3aac5aad 529 ECF_CONST);
5f158b44 530 define_builtin (BUILT_IN_COS, "__builtin_cos",
92aed1cb 531 double_ftype_double, "_ZN4java4lang4Math3cosEJdd",
3aac5aad 532 ECF_CONST);
5f158b44 533 define_builtin (BUILT_IN_EXP, "__builtin_exp",
92aed1cb 534 double_ftype_double, "_ZN4java4lang4Math3expEJdd",
3aac5aad 535 ECF_CONST);
2d99c042 536 define_builtin (BUILT_IN_FLOOR, "__builtin_floor",
92aed1cb 537 double_ftype_double, "_ZN4java4lang4Math5floorEJdd",
3aac5aad 538 ECF_CONST);
5f158b44 539 define_builtin (BUILT_IN_LOG, "__builtin_log",
92aed1cb 540 double_ftype_double, "_ZN4java4lang4Math3logEJdd",
3aac5aad 541 ECF_CONST);
5f158b44 542 define_builtin (BUILT_IN_POW, "__builtin_pow",
92aed1cb 543 double_ftype_double_double, "_ZN4java4lang4Math3powEJddd",
3aac5aad 544 ECF_CONST);
5f158b44 545 define_builtin (BUILT_IN_SIN, "__builtin_sin",
92aed1cb 546 double_ftype_double, "_ZN4java4lang4Math3sinEJdd",
3aac5aad 547 ECF_CONST);
5f158b44 548 define_builtin (BUILT_IN_SQRT, "__builtin_sqrt",
92aed1cb 549 double_ftype_double, "_ZN4java4lang4Math4sqrtEJdd",
3aac5aad 550 ECF_CONST);
5f158b44 551 define_builtin (BUILT_IN_TAN, "__builtin_tan",
92aed1cb 552 double_ftype_double, "_ZN4java4lang4Math3tanEJdd",
3aac5aad 553 ECF_CONST);
2c80f015 554
9dc1704f
NF
555 boolean_ftype_boolean_boolean
556 = build_function_type_list (boolean_type_node,
557 boolean_type_node, boolean_type_node,
558 NULL_TREE);
2c80f015
AH
559 define_builtin (BUILT_IN_EXPECT, "__builtin_expect",
560 boolean_ftype_boolean_boolean,
6e0fbdd9 561 "__builtin_expect",
3aac5aad 562 ECF_CONST | ECF_NOTHROW);
e0a8ecf2 563 define_builtin (BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4,
97b8365c
TT
564 "__sync_bool_compare_and_swap_4",
565 build_function_type_list (boolean_type_node,
566 int_type_node,
567 build_pointer_type (int_type_node),
568 int_type_node, NULL_TREE),
3aac5aad 569 "__sync_bool_compare_and_swap_4", ECF_NOTHROW | ECF_LEAF);
e0a8ecf2 570 define_builtin (BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8,
97b8365c
TT
571 "__sync_bool_compare_and_swap_8",
572 build_function_type_list (boolean_type_node,
573 long_type_node,
574 build_pointer_type (long_type_node),
575 int_type_node, NULL_TREE),
3aac5aad 576 "__sync_bool_compare_and_swap_8", ECF_NOTHROW | ECF_LEAF);
e0a8ecf2 577 define_builtin (BUILT_IN_SYNC_SYNCHRONIZE, "__sync_synchronize",
9dc1704f 578 build_function_type_list (void_type_node, NULL_TREE),
3aac5aad 579 "__sync_synchronize", ECF_NOTHROW | ECF_LEAF);
97b8365c
TT
580
581 define_builtin (BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
582 build_function_type_list (ptr_type_node, int_type_node, NULL_TREE),
3aac5aad 583 "__builtin_return_address", ECF_NOTHROW | ECF_LEAF);
89d3d605
JL
584 define_builtin (BUILT_IN_TRAP, "__builtin_trap",
585 build_function_type_list (void_type_node, NULL_TREE),
586 "__builtin_trap", ECF_NOTHROW | ECF_LEAF | ECF_NORETURN);
384c400a 587 build_common_builtin_nodes ();
fec763fc
TT
588}
589
9fe2cc05 590/* If the call matches a builtin, return the
fec763fc
TT
591 appropriate builtin expression instead. */
592tree
0a2f0c54 593check_for_builtin (tree method, tree call)
fec763fc 594{
6e63e240 595 if (optimize && TREE_CODE (call) == CALL_EXPR)
fec763fc
TT
596 {
597 int i;
9fe2cc05
PB
598 tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
599 tree method_name = DECL_NAME (method);
600 tree method_return_type = TREE_TYPE (TREE_TYPE (method));
fec763fc 601
833e1a77 602 for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i)
fec763fc
TT
603 {
604 if (method_class == java_builtins[i].class_name.t
605 && method_name == java_builtins[i].method_name.t)
606 {
833e1a77
RS
607 tree fn;
608
609 if (java_builtins[i].creator != NULL)
05d8200d
TT
610 {
611 tree result
5039610b 612 = (*java_builtins[i].creator) (method_return_type, call);
05d8200d
TT
613 return result == NULL_TREE ? call : result;
614 }
0ed431d4
BM
615
616 /* Builtin functions emit a direct call which is incompatible
617 with the BC-ABI. */
618 if (flag_indirect_dispatch)
619 return call;
e79983f4 620 fn = builtin_decl_explicit (java_builtins[i].builtin_code);
833e1a77 621 if (fn == NULL_TREE)
05d8200d 622 return call;
5039610b 623 return java_build_function_call_expr (fn, call);
fec763fc
TT
624 }
625 }
626 }
fec763fc
TT
627 return call;
628}
e2500fed
GK
629
630#include "gt-java-builtins.h"