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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [java/] [builtins.c] - Blame information for rev 287

Details | Compare with Previous | View Log

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