OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [java/] [builtins.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.