gcc/java/ * java-gimplify.c (java_gimplify_block): New argument to build_empty_stmt. * expr.c (force_evaluation_order): Same. * typeck.c: Add location to build_decl or PUSH_FIELD calls. * class.c: Same. * decl.c: Same. * jcf-parse.c: Same. * constants.c: Same. * resource.c: Same. * except.c: Same. * builtins.c: Same. * expr.c: Same. * java-tree.h (PUSH_FIELD): Add location field. gcc/objc/ * objc-act.c (finish_var_decl): Pass location to finish_decl. (objc_get_parm_info): Same. (get_super_receiver): Same. * objc-act.c (objc_build_component_ref): Pass location to build_compound_ref. (build_module_initializer_routine): Pass location to c_end_compound_stmt. (objc_generate_static_init_call): Pass location to build_stmt. (build_typed_selector_reference): New location argument. (build_selector_reference): Same. (objc_substitute_decl): Pass location to build_array_ref. (next_sjlj_build_try_catch_finally): Pass location to build_stmt. (objc_begin_catch_clause): Same. (objc_finish_try_stmt): Same. (objc_finish_catch_clause): Pass location to c_end_compound_stmt. (objc_build_throw_stmt): New argument. (generate_shared_structures): Pass location to build_c_cast. (objc_build_message_expr): Use local location. (objc_finish_message_expr): Use input_location. (build_objc_method_call): New argument. (objc_build_selector_expr): Same. (get_super_receiver): Pass location to build_c_cast, build_modify_expr, build_compound_expr. * objc-act.c: Add location to all calls to start_struct, build_decl, finish_struct. gcc/ * tree-pretty-print.c (dump_generic_node): Dump column numbers. * gimple-pretty-print.c (dump_gimple_stmt): Same. * gimplify.c (gimplify_modify_expr): Set location for GIMPLE_ASSIGNs created. * c-parser.c (c_parser_binary_expression): Use current column while building binary operations. * common.opt (fshow-column): Enable by default. * tree-vrp.c (check_array_ref): Use warning_at. (check_array_bounds): Use location from call back if expr has no location. * tree.h: Add location argument to maybe_fold_*. * tree-ssa-ccp.c (ccp_fold): Pass location to maybe_fold_*. (maybe_fold_offset_to_array_ref): Add location argument and use it. (maybe_fold_offset_to_component_ref): Same. (maybe_fold_offset_to_reference): Same. (maybe_fold_offset_to_address): Same. (maybe_fold_stmt_indirect): Same. (maybe_fold_stmt_addition): Same. (fold_stmt_r): Pass location to maybe_fold_*. (fold_gimple_assign): Same. * c-tree.h: Add location argument to finish_decl, default_function_array_conversion, store_init_value. * c-decl.c (define_label): Use error_at. (c_make_fname_decl): Pass location to finish_decl. (finish_decl): New location argument. (build_compound_literal): Pass location to store_init_value. (grokdeclarator): Pass location to finish_decl. (grokfield): Same. * c-typeck.c (array_to_pointer_conversion): New location argument. (function_to_pointer_conversion): Same. (default_function_array_conversion): Same. (parser_build_unary_op): Pass location to overflow_warning. (parser_build_binary_op): Same. Use warning_at. (build_unary_op): Pass location to array_to_pointer_conversion. (build_c_cast): Pass location to digest_init. (build_modify_expr): New location argument. (convert_for_assignment): Same. (store_init_value): Same. (digest_init): Same. (output_init_element): Pass location to digest_init and array_to_pointer_conversion. (c_finish_return): Pass location to convert_for_assignment. * gimplify.c (gimplify_conversion): Pass location to maybe_fold_offset_to_address. * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Pass location to maybe_fold_stmt_addition. * c-omp.c (c_finish_omp_atomic): Pass new location to build_modify_expr. (c_finish_omp_for): Same. * c-common.c (overflow_warning): New argument. * c-common.h: New argument to build_modify_expr, overflow_warning. * c-parser.c (c_parser_declaration_or_fndef): Pass location to finish_decl. (c_parser_initializer): Pass location to default_function_array_conversion. (c_parser_initelt): Same. (c_parser_initval): Same. (c_parser_asm_operands): Same. (c_parser_expr_no_commas): Same. Pass location to build_modify_expr. (c_parser_conditional_expression): Same. (c_parser_binary_expression): Add location info to stack. Use it. (c_parser_unary_expression): Pass location to default_function_array_conversion, parser_build_unary_op, build_indirect_ref, c_parser_postfix_expression_after_primary. (c_parser_postfix_expression_after_primary): New location argument. Use it. (c_parser_expression_conv): Pass location to default_function_array_conversion. (c_parser_expr_list): Same. (c_parser_omp_atomic): Same. (c_parser_omp_for_loop): Same. * c-tree.h: (struct c_declarator): Add comment to id_loc. (build_array_declarator): New argument. * c-decl.c (build_array_declarator): Add location argument. (grokdeclarator): Set id_loc for cdk_array. * c-parser.c (c_parser_direct_declarator_inner): Pass location to build_array_declarator. * tree.c (build_omp_clause): Add location argument. * tree.h (OMP_CLAUSE_HAS_LOCATION): New macro. (OMP_CLAUSE_LOCATION): New macro. (struct tree_omp_clause): Add location field. (build_omp_clause): Add argument. * testsuite/gcc.dg/gomp/for-1.c: Fix column. * cp/pt.c (tsubst_omp_for_iterator): Pass location to build_omp_clause. * cp/parser.c (cp_parser_omp_var_list_no_open): Same. (cp_parser_omp_clause_collapse): Same. (cp_parser_omp_clause_default): Same. (cp_parser_omp_clause_if): Same. (cp_parser_omp_clause_nowait): Same. (cp_parser_omp_clause_num_threads): Same. (cp_parser_omp_clause_ordered): Same. (cp_parser_omp_clause_schedule): Same. (cp_parser_omp_clause_untied): Same. (cp_parser_omp_for_loop): Same. (cp_parser_omp_parallel): Pass location to c_split_parallel_clauses. * c-tree.h (c_start_case): Add location argument. (c_process_expr_stmt): Same. (c_finish_goto_*): Same. * tree-parloops.c (initialize_reductions): Pass location to build_omp_clause. (create_parallel_loop): Same. * fortran/trans-openmp.c (gfc_trans_omp_variable_list): Same. (gfc_trans_omp_reduction_list): Same. (gfc_trans_omp_clauses): Same. (gfc_trans_omp_do): Same. * c-typeck.c (c_finish_goto_label): Same. (c_finish_goto_ptr): New location argument. (c_start_case): Same. (emit_side_effect_warnings): Same. (c_process_expr_stmt): Same. (c_finish_stmt_expr): Same. (c_finish_omp_clauses): Use error_at instead of error. * gimplify.c (gimplify_adjust_omp_clauses_1): Pass location to build_omp_clause. * c-omp.c (c_split_parallel_clauses): New location argument. * tree-nested.c (convert_nonlocal_reference_stmt): Pass location to build_omp_clause. (convert_local_reference_stmt): Same. (convert_gimple_call): Same. * c-common.h (c_split_parallel_clauses): New argument. * c-parser.c (c_parser_statement_after_labels): Pass location to c_finish_goto_label. (c_parser_switch_statement): Pass location to c_start_case. (c_parser_for_statement): Pass location to c_finish_expr_stmt, and c_process_expr_stmt. (c_parser_omp_variable_list): Add location argument. (c_parser_omp_clause_collapse): Pass location to build_omp_clause. (c_parser_omp_clause_default): Same. (c_parser_omp_clause_if): Same. (c_parser_omp_clause_num_threads): Same. (-c_parser_omp_clause_ordered): Same. (c_parser_omp_clause_reduction): Pass location to c_parser_omp_variable_list. (c_parser_omp_clause_schedule): Pass location to build_omp_clause. (c_parser_omp_clause_untied): Same. (c_parser_omp_for_loop): Pass location to c_process_expr_stmt. (c_parser_omp_parallel): Pass location to c_split_parallel_clauses. * c-tree.h (check_for_loop_decls, undeclared_variable, build_component_ref, build_array_ref, build_external_ref, c_expr_sizeof_expr, c_expr_sizeof_type, parser_build_unary_op, build_conditional_expr, build_compound_expr, c_cast_expr, build_c_cast, build_asm_expr, c_end_compound_stmt, c_finish_stmt_expr, c_finish_return, c_finish_omp_parallel, c_finish_omp_task): New argument. * c-semantics.c (build_stmt): Same. (build_case_label): Same. * c-decl.c (c_finish_incomplete_decl): Pass location on down. (undeclared_variable): New argument. (make_label): Same. (lookup_label): Pass location on down. (define_label): Same. (finish_decl): Same. (build_compound_literal): Same. (finish_struct): Same. (finish_function): Do not set location here. (check_for_loop_decls): New argument. * tree.c (save_expr): Set location. (build_empty_stmt): New argument. * tree.h (build_empty_stmt): New argument to build_empty_stmt. (CAN_HAVE_LOCATION_P): Make sure we have a non empty node. * builtins.c (gimplify_va_arg_expr): Use locations. (expand_builtin_sync_operation): Same. * c-typeck.c (build_component_ref): New argument. (build_array_ref): Same. (build_external_ref): Same. (c_expr_sizeof_expr): Same. (c_expr_sizeof_type): Same. (parser_build_unary_op): Same. (build_conditional_expr): Same. (build_compound_expr): Pass location on down. (build_compound_expr): New argument. (build_c_cast): Same. (c_cast_expr): Same. (build_asm_expr): Same. (c_finish_return): Same. (c_process_expr_stmt): Pass location on down. (c_finish_stmt_expr): New argument. (push_clenaup): Same. (c_finish_omp_parallel): Same. (c_finish_omp_task): Same. * gimplify.c (gimplify_call_expr): Pass location on down. * c-omp.c (c_finish_omp_master): New argument. (c_finish_omp_critical): Same. (c_finish_omp_ordered): Same. (c_finish_omp_barrier): Same. (-c_finish_omp_taskwait): Same. (c_finish_omp_atomic): Same. (c_finish_omp_flush): Same. * tree-inline.c (copy_tree_body_r): Pass location on down. (inline_forbidden_p): Remove use of input_location. * c-gimplify.c (c_build_bind_expr): New argument. * c-common.c (c_common_truthvalue_conversion): Pass location on down. (c_sizeof_or_alignof_type): New argument. (c_alignof_expr): Same. (build_va_arg): Same. (c_add_case_label): Same. * c-common.h (c_sizeof_or_alignof_type, c_alignof_expr, c_sizeof, c_alignof, build_va_arg, build_stmt, build_case_label, c_build_bind_expr, objc_build_selector_expr, objc_build_throw_stmt, c_finish_omp_master, c_finish_omp_critical, c_finish_omp_ordered, c_finish_omp_barrier, c_finish_omp_atomic, c_finish_omp_flush, c_finish_omp_taskwait, c_finish_omp_for, c_split_parallel_clauses): New argument. * stub-objc.c (objc_build_selector_expr): Same. (objc_build_throw_stmt): Same. * c-parser.c (c_parser_declaration_or_fndef): Pass location on down. (c_parser_initelt): Same. (c_parser_compound_statement): Same. (c_parser_compound_statement_nostart): Same. (c_parser_label): Same. (c_parser_statement_after_labels): Same. (c_parser_if_body): Same. (c_parser_else_body): Same. (c_parser_if_statement): Same. (c_parser_switch_statement): Same. (c_parser_while_statement): Same. (c_parser_do_statement): Same. (c_parser_for_statement): Same. (c_parser_asm_statement): Same. (c_parser_conditional_expression): Same. (c_parser_binary_expression): Same. (c_parser_cast_expression): Same. (c_parser_unary_expression): Same. (c_parser_sizeof_expression): Same. (c_parser_alignof_expression): Same. (c_parser_postfix_expression): Same. (c_parser_expression): Same. (c_parser_objc_receiver): Same. (c_parser_omp_variable_list): Same. (c_parser_omp_structured_block): Same. (c_parser_omp_atomic): New argument. (c_parser_omp_barrier): Same. (c_parser_omp_critical): Same. (c_parser_omp_flush): Pass location on down. (c_parser_omp_for_loop): New argument. (c_parser_omp_for): Same. (c_parser_omp_master): Same. (c_parser_omp_ordered): Same. (c_parser_omp_sections_scope): Same. (c_parser_omp_sections): Same. (c_parser_omp_parallel): Same. (c_parser_omp_single): Same. (c_parser_omp_task): Same. (c_parser_omp_taskwait): Pass location on down. (c_parser_omp_construct): Same. (c_parser_omp_threadprivate): Same. * dwarf2asm.c, targhooks.c, optabs.c, tree.c, tree.h, target.h, builtins.c, omp-low.c, cgraphunit.c, tree-call-cdce.c, tree-ssa-alias.c, gimple-low.c, c-tree.h, expr.c, tree-parloops.c, c-decl.c, tree-eh.c, langhooks.c, function.c, stor-layout.c, c-typeck.c, gimplify.c, c-pragma.c, expmed.c, except.c, coverage.c, emit-rtl.c, cfgexpand.c, tree-mudflap.c, varasm.c, tree-nested.c, rtl.h, tree-inline.c, tree-profile.c, c-common.c, c-common.h, tree-switch-conversion.c, tree-cfg.c, ipa-struct-reorg.c, c-parser.c, config/i386/i386.c, stmt.c: Add location argument to the following function definitions and/or function calls: build_decl, objcp_start_struct, objcp_finish_struct, start_struct, finish_struct, PUSH_FIELD, create_artificial_label, cp_make_fname_decl, pushtag, implicitly_declare, c_make_fname_decl, build_compound_literal, parser_xref_tag, resolve_overloaded_builtin, do_case, c_finish_bc_stmt, build_compound_literal, build_function_call. * c-decl.c (build_compound_literal): Add location argument. Make all diagnostic calls use location. (start_struct): Same. (finish_struct): Same. (start_enum): Same. (build_enumerator): Same. (start_function): Same. (grokdeclarator): Make all diagnostic calls use location. (store_parm_decls_oldstyle): Same. * c-typeck.c (build_function_call): Add location argument. Make all diagnostic calls use location. (do_case): Same. (c_finish_bc_stmt): Same. * tree-nested.c (get_trampoline_type): Add argument. Pass location to build_decl. (lookup_tramp_for_decl): Pass location to get_trampoline_type. * rtl.h (RTL_LOCATION): New. * c-common.c (c_add_case_label): Add location argument. Make all diagnostic calls use location. * c-common.h: Add location argument to make_fname_decl, do_case, c_add_case_label, build_function_call, resolve_overloaded_builtin. * c-parser.c (c_parser_enum_specifier): Rename ident_loc to enum_loc. Set it appropriately for every case. Pass enum_loc to start_enum call. Pass value_loc first to build_enumerator. Pass enum_loc to parser_xref_tag. (c_parser_struct_or_union_specifier): Save location. Use it for start_struct, finish_struct, and parser_xref_tag. gcc/testsuite/ * gcc.dg/old-style-prom-3.c: Add column info. * gcc.dg/overflow-warn-1.c * gcc.dg/gomp/pr27415.c * gcc.dg/gomp/for-1.c: Same. * gcc.dg/enum-compat-1.c: Same. * gcc.dg/c99-tag-3.c: Same. * gcc.dg/Wredundant-decls-2.c: Same. * gcc.dg/func-ptr-conv-1.c: Same. * gcc.dg/asm-wide-1.c: Same. * gcc.dg/nofixed-point-2.c: Same. * gcc.dg/cpp/line3.c: Same. * gcc.dg/array-10.c: Same. * gcc.dg/c99-vla-jump-1.c: Same. * gcc.dg/pr20368-1.c: Same. * gcc.dg/Wshadow-3.c: Same. * gcc.dg/c90-const-expr-8.c: Same. * gcc.dg/label-decl-2.c: Same. * gcc.dg/dremf-type-compat-2.c: Same. * gcc.dg/c90-const-expr-5.c: Same. * gcc.dg/builtins-30.c: Same. * gcc.dg/Warray-bounds.c: Same. * gcc.dg/Wcxx-compat-2.c: Same. * gcc.dg/tree-ssa/col-1.c: Same. * gcc.dg/old-style-prom-2.c: Same. * gcc.dg/cast-function-1.c: Same. * gcc.dg/pr15698-1.c: Same. * gcc.dg/dremf-type-compat-3.c: Same. * gcc.dg/vla-8.c: Same. * gcc.dg/gomp/pr27415.c: Move firstprivate diagnostics to correct line. * gcc.dg/label-decl-2.c: Move label diagnostic to correct line. * gcc.dg/old-style-prom-3.c: Check for error on the correct line. * gcc.dg/enum-compat-1.c: Same. * gcc.dg/dremf-type-compat-2.c: Same. * gcc.dg/old-style-prom-2.c: Same. * gcc.dg/pr15698-1.c: Same. * gcc.dg/pr20368-1.c: Same. * gcc.dg/dremf-type-compat-3.c: Same. * gcc.dg/builtins-30.c: Same. Test for columns. gcc/objcp/ * objcp-decl.h (c_end_compound_stmt): New argument. * objcp-decl.c (objcp_start_struct): Add argument. (objcp_finish_struct): Same. gcc/cp/ * typeck.c (cp_build_binary_op): Pass location to overflow_warning. (build_modify_expr): New arg. * semantics.c (finish_unary_op_expr): Pass location to overflow_warning. (handle_omp_for_class_iterator): Pass location to build_modify_expr. * typeck.c (cxx_sizeof_or_alignof_type): Pass location to c_sizeof_or_alignof_type. (build_array_ref): New argument. (build_compound_expr): Same. (build_const_cast): Same. (build_ptrmemfunc): Pass location to build_c_cast. * init.c (avoid_placement_new_aliasing): Pass location to build_stmt. (build_vec_delete_1): Pass location to cp_build_modify_expr, build_compound_expr. * class.c (build_vtbl_ref_1): Pass location to build_array_ref. * decl.c (poplevel): Pass location to c_build_bind_expr. (finish_case_label): Pass location to build_case_label. (finish_constructor_body): Same. (finish_destructor_body): Pass location to build_stmt. (cxx_maybe_build_cleanup): Same, but to build_compound_expr. * call.c (build_new_op): Pass location to build_array_ref. (build_x_va_arg): Pass location to build_va_arg. * except.c (expand_end_catch_block): Pass location to build_stmt. * cp-tree.h (build_array_ref): New argument. (build_compound_expr): Same. (build_c_cast): Same. * cp-gimplify.c (gimplify_if_stmt): Pass location on down. (gimplify_switch_stmt): Same. * typeck2.c (split_nonconstant_init_1): Same. * pt.c (tsubst_copy): Same. * semantics.c (add_decl_expr): Same. (do_poplevel): Same. (push_cleanup): Same. (finish_goto_stmt): Same. (finish_expr_stmt): Same. (begin_if_stmt): Same. (begin_while_stmt): Same. (begin_do_stmt): Same. (finish_return_stmt): Same. (begin_for_stmt): Same. (finish_break_stmt): Same. (finish_continue_stmt): Same. (begin_switch_stmt): Same. (begin_try_block): Same. (begin_handler): Same. (finish_asm_stmt): Same. (finish_label_stmt): Same. (finish_stmt_expr_expr): Same. (finalize_nrv_r): Same. (finish_omp_atomic): Same. * name-lookup.c (do_using_directive): Same. * decl2.c (grok_array_decl): Same. * parser.c (cp_parser_cast_expression): Same. (cp_parser_selection_statement): Same. (cp_parser_implicitly_scoped_statement): Same. (cp_parser_objc_selector_expression): Same. (cp_parser_objc_synchronized_statement): Same. (cp_parser_objc_throw_statement): Same. (cp_parser_omp_critical): Same. (cp_parser_omp_master): Same. * typeck.c (build_function_call): Add location argument. * init.c: Add location argument to all build_decl calls. * class.c: Same. * method.c: Same. * rtti.c: Same. * tree.c: Same. * pt.c: Same. * semantics.c: Same. * lex.c: Same. * decl2.c: Same. * cp-gimplify.c: Same. * decl.c: Same. (cp_make_fname_decl): Add location argument. Pass location ot build_decl. (finish_case_label): Same. * cp-tree.h (finish_case_label): Add location argument. * parser.c (cp_parser_label_for_labeled_statement): Pass location to finish_case_label. gcc/fortran/ * trans-array.c (gfc_trans_allocate_array_storage): Pass location on down. (gfc_trans_array_constructor_value): Same. (gfc_trans_scalarized_loop_end): Same. (gfc_conv_ss_startstride): Same. (gfc_trans_g77_array): Same. (gfc_trans_dummy_array_bias): Same. (gfc_conv_array_parameter): Same. (structure_alloc_comps): Same. * trans-expr.c (gfc_conv_function_call): Same. (fill_with_spaces): Same. (gfc_trans_string_copy): Same. (gfc_trans_scalar_assign): Same. * trans-stmt.c (gfc_trans_goto): Same. (gfc_trans_if_1): Same. (gfc_trans_simple_do): Same. (gfc_trans_do): Same. (gfc_trans_do_while): Same. (gfc_trans_logical_select): Same. (gfc_trans_select): Same. (gfc_trans_forall_loop): Same. (gfc_trans_nested_forall_loop): Same. (generate_loop_for_temp_to_lhs): Same. (generate_loop_for_rhs_to_temp): Same. (gfc_trans_forall_1): Same. (gfc_trans_where_assign): Same. (gfc_trans_where_3): Same. (gfc_trans_allocate): Same. * trans.c (gfc_finish_block): Same. (gfc_trans_runtime_check): Same. (gfc_call_malloc): Same. (gfc_allocate_with_status): Same. (gfc_call_free): Same. (gfc_deallocate_with_status): Same. (gfc_call_realloc): Same. (gfc_trans_code): Same. * trans-decl.c (gfc_init_default_dt): Same. (gfc_generate_constructors): Same. * trans-io.c (gfc_trans_io_runtime_check): Same. * trans-intrinsic.c (gfc_conv_intrinsic_ctime): Same. (gfc_conv_intrinsic_fdate): Same. (gfc_conv_intrinsic_ttynam): Same. (gfc_conv_intrinsic_minmax): Same. (gfc_conv_intrinsic_minmax_char): Same. (gfc_conv_intrinsic_anyall): Same. (gfc_conv_intrinsic_count): Same. (gfc_conv_intrinsic_arith): Same. (gfc_conv_intrinsic_minmaxloc): Same. (gfc_conv_intrinsic_minmaxval): Same. (gfc_conv_intrinsic_rrspacing): Same. (gfc_conv_intrinsic_array_transfer): Same. (gfc_conv_intrinsic_trim): Same. (gfc_conv_intrinsic_repeat): Same. From-SVN: r148442
624 lines
20 KiB
C
624 lines
20 KiB
C
/* Built-in and inline functions for gcj
|
||
Copyright (C) 2001, 2003, 2004, 2005, 2006, 2007, 2009
|
||
Free Software Foundation, Inc.
|
||
|
||
This file is part of GCC.
|
||
|
||
GCC is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation; either version 3, or (at your option)
|
||
any later version.
|
||
|
||
GCC is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
.
|
||
|
||
.
|
||
|
||
Java and all Java-based marks are trademarks or registered trademarks
|
||
of Sun Microsystems, Inc. in the United States and other countries.
|
||
The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
||
|
||
/* Written by Tom Tromey <tromey@redhat.com>. */
|
||
|
||
#include "config.h"
|
||
#include "system.h"
|
||
#include "coretypes.h"
|
||
#include "tm.h"
|
||
#include "tree.h"
|
||
#include "ggc.h"
|
||
#include "flags.h"
|
||
#include "langhooks.h"
|
||
#include "java-tree.h"
|
||
#include <stdarg.h>
|
||
#include "convert.h"
|
||
#include "rtl.h"
|
||
#include "insn-codes.h"
|
||
#include "expr.h"
|
||
#include "optabs.h"
|
||
|
||
static tree max_builtin (tree, tree);
|
||
static tree min_builtin (tree, tree);
|
||
static tree abs_builtin (tree, tree);
|
||
static tree convert_real (tree, tree);
|
||
|
||
static tree java_build_function_call_expr (tree, tree);
|
||
|
||
static tree putObject_builtin (tree, tree);
|
||
static tree compareAndSwapInt_builtin (tree, tree);
|
||
static tree compareAndSwapLong_builtin (tree, tree);
|
||
static tree compareAndSwapObject_builtin (tree, tree);
|
||
static tree putVolatile_builtin (tree, tree);
|
||
static tree getVolatile_builtin (tree, tree);
|
||
static tree VMSupportsCS8_builtin (tree, tree);
|
||
|
||
|
||
/* Functions of this type are used to inline a given call. Such a
|
||
function should either return an expression, if the call is to be
|
||
inlined, or NULL_TREE if a real call should be emitted. Arguments
|
||
are method return type and the original CALL_EXPR containing the
|
||
arguments to the call. */
|
||
typedef tree builtin_creator_function (tree, tree);
|
||
|
||
/* Hold a char*, before initialization, or a tree, after
|
||
initialization. */
|
||
union GTY(()) string_or_tree {
|
||
const char * GTY ((tag ("0"))) s;
|
||
tree GTY ((tag ("1"))) t;
|
||
};
|
||
|
||
/* Used to hold a single builtin record. */
|
||
struct GTY(()) builtin_record {
|
||
union string_or_tree GTY ((desc ("1"))) class_name;
|
||
union string_or_tree GTY ((desc ("1"))) method_name;
|
||
builtin_creator_function * GTY((skip)) creator;
|
||
enum built_in_function builtin_code;
|
||
};
|
||
|
||
static GTY(()) struct builtin_record java_builtins[] =
|
||
{
|
||
{ { "java.lang.Math" }, { "min" }, min_builtin, (enum built_in_function) 0 },
|
||
{ { "java.lang.Math" }, { "max" }, max_builtin, (enum built_in_function) 0 },
|
||
{ { "java.lang.Math" }, { "abs" }, abs_builtin, (enum built_in_function) 0 },
|
||
{ { "java.lang.Math" }, { "acos" }, NULL, BUILT_IN_ACOS },
|
||
{ { "java.lang.Math" }, { "asin" }, NULL, BUILT_IN_ASIN },
|
||
{ { "java.lang.Math" }, { "atan" }, NULL, BUILT_IN_ATAN },
|
||
{ { "java.lang.Math" }, { "atan2" }, NULL, BUILT_IN_ATAN2 },
|
||
{ { "java.lang.Math" }, { "ceil" }, NULL, BUILT_IN_CEIL },
|
||
{ { "java.lang.Math" }, { "cos" }, NULL, BUILT_IN_COS },
|
||
{ { "java.lang.Math" }, { "exp" }, NULL, BUILT_IN_EXP },
|
||
{ { "java.lang.Math" }, { "floor" }, NULL, BUILT_IN_FLOOR },
|
||
{ { "java.lang.Math" }, { "log" }, NULL, BUILT_IN_LOG },
|
||
{ { "java.lang.Math" }, { "pow" }, NULL, BUILT_IN_POW },
|
||
{ { "java.lang.Math" }, { "sin" }, NULL, BUILT_IN_SIN },
|
||
{ { "java.lang.Math" }, { "sqrt" }, NULL, BUILT_IN_SQRT },
|
||
{ { "java.lang.Math" }, { "tan" }, NULL, BUILT_IN_TAN },
|
||
{ { "java.lang.Float" }, { "intBitsToFloat" }, convert_real,
|
||
(enum built_in_function) 0 },
|
||
{ { "java.lang.Double" }, { "longBitsToDouble" }, convert_real,
|
||
(enum built_in_function) 0 },
|
||
{ { "java.lang.Float" }, { "floatToRawIntBits" }, convert_real,
|
||
(enum built_in_function) 0 },
|
||
{ { "java.lang.Double" }, { "doubleToRawLongBits" }, convert_real,
|
||
(enum built_in_function) 0 },
|
||
{ { "sun.misc.Unsafe" }, { "putInt" }, putObject_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putLong" }, putObject_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putObject" }, putObject_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "compareAndSwapInt" },
|
||
compareAndSwapInt_builtin, (enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "compareAndSwapLong" },
|
||
compareAndSwapLong_builtin, (enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "compareAndSwapObject" },
|
||
compareAndSwapObject_builtin, (enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putOrderedInt" }, putVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putOrderedLong" }, putVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putOrderedObject" }, putVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putIntVolatile" }, putVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putLongVolatile" }, putVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "putObjectVolatile" }, putVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "getObjectVolatile" }, getVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "getIntVolatile" }, getVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "getLongVolatile" }, getVolatile_builtin, (enum built_in_function) 0},
|
||
{ { "sun.misc.Unsafe" }, { "getLong" }, getVolatile_builtin,
|
||
(enum built_in_function) 0},
|
||
{ { "java.util.concurrent.atomic.AtomicLong" }, { "VMSupportsCS8" },
|
||
VMSupportsCS8_builtin, (enum built_in_function) 0},
|
||
{ { NULL }, { NULL }, NULL, END_BUILTINS }
|
||
};
|
||
|
||
|
||
/* Internal functions which implement various builtin conversions. */
|
||
|
||
static tree
|
||
max_builtin (tree method_return_type, tree orig_call)
|
||
{
|
||
/* MAX_EXPR does not handle -0.0 in the Java style. */
|
||
if (TREE_CODE (method_return_type) == REAL_TYPE)
|
||
return NULL_TREE;
|
||
return fold_build2 (MAX_EXPR, method_return_type,
|
||
CALL_EXPR_ARG (orig_call, 0),
|
||
CALL_EXPR_ARG (orig_call, 1));
|
||
}
|
||
|
||
static tree
|
||
min_builtin (tree method_return_type, tree orig_call)
|
||
{
|
||
/* MIN_EXPR does not handle -0.0 in the Java style. */
|
||
if (TREE_CODE (method_return_type) == REAL_TYPE)
|
||
return NULL_TREE;
|
||
return fold_build2 (MIN_EXPR, method_return_type,
|
||
CALL_EXPR_ARG (orig_call, 0),
|
||
CALL_EXPR_ARG (orig_call, 1));
|
||
}
|
||
|
||
static tree
|
||
abs_builtin (tree method_return_type, tree orig_call)
|
||
{
|
||
return fold_build1 (ABS_EXPR, method_return_type,
|
||
CALL_EXPR_ARG (orig_call, 0));
|
||
}
|
||
|
||
/* Construct a new call to FN using the arguments from ORIG_CALL. */
|
||
|
||
static tree
|
||
java_build_function_call_expr (tree fn, tree orig_call)
|
||
{
|
||
int nargs = call_expr_nargs (orig_call);
|
||
switch (nargs)
|
||
{
|
||
/* Although we could handle the 0-3 argument cases using the general
|
||
logic in the default case, splitting them out permits folding to
|
||
be performed without constructing a temporary CALL_EXPR. */
|
||
case 0:
|
||
return build_call_expr (fn, 0);
|
||
case 1:
|
||
return build_call_expr (fn, 1, CALL_EXPR_ARG (orig_call, 0));
|
||
case 2:
|
||
return build_call_expr (fn, 2,
|
||
CALL_EXPR_ARG (orig_call, 0),
|
||
CALL_EXPR_ARG (orig_call, 1));
|
||
case 3:
|
||
return build_call_expr (fn, 3,
|
||
CALL_EXPR_ARG (orig_call, 0),
|
||
CALL_EXPR_ARG (orig_call, 1),
|
||
CALL_EXPR_ARG (orig_call, 2));
|
||
default:
|
||
{
|
||
tree fntype = TREE_TYPE (fn);
|
||
fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fn);
|
||
return fold (build_call_array (TREE_TYPE (fntype),
|
||
fn, nargs, CALL_EXPR_ARGP (orig_call)));
|
||
}
|
||
}
|
||
}
|
||
|
||
static tree
|
||
convert_real (tree method_return_type, tree orig_call)
|
||
{
|
||
return build1 (VIEW_CONVERT_EXPR, method_return_type,
|
||
CALL_EXPR_ARG (orig_call, 0));
|
||
}
|
||
|
||
|
||
|
||
/* Provide builtin support for atomic operations. These are
|
||
documented at length in libjava/sun/misc/Unsafe.java. */
|
||
|
||
/* FIXME. There are still a few things wrong with this logic. In
|
||
particular, atomic writes of multi-word integers are not truly
|
||
atomic: this requires more work.
|
||
|
||
In general, double-word compare-and-swap cannot portably be
|
||
implemented, so we need some kind of fallback for 32-bit machines.
|
||
|
||
*/
|
||
|
||
|
||
/* Macros to unmarshal arguments from a CALL_EXPR into a few
|
||
variables. We also convert the offset arg from a long to an
|
||
integer that is the same size as a pointer. */
|
||
|
||
#define UNMARSHAL3(METHOD_CALL) \
|
||
tree this_arg, obj_arg, offset_arg; \
|
||
do \
|
||
{ \
|
||
tree orig_method_call = METHOD_CALL; \
|
||
this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
|
||
obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
|
||
offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
|
||
CALL_EXPR_ARG (orig_method_call, 2)); \
|
||
} \
|
||
while (0)
|
||
|
||
#define UNMARSHAL4(METHOD_CALL) \
|
||
tree value_type, this_arg, obj_arg, offset_arg, value_arg; \
|
||
do \
|
||
{ \
|
||
tree orig_method_call = METHOD_CALL; \
|
||
this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
|
||
obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
|
||
offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
|
||
CALL_EXPR_ARG (orig_method_call, 2)); \
|
||
value_arg = CALL_EXPR_ARG (orig_method_call, 3); \
|
||
value_type = TREE_TYPE (value_arg); \
|
||
} \
|
||
while (0)
|
||
|
||
#define UNMARSHAL5(METHOD_CALL) \
|
||
tree value_type, this_arg, obj_arg, offset_arg, expected_arg, value_arg; \
|
||
do \
|
||
{ \
|
||
tree orig_method_call = METHOD_CALL; \
|
||
this_arg = CALL_EXPR_ARG (orig_method_call, 0); \
|
||
obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \
|
||
offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \
|
||
CALL_EXPR_ARG (orig_method_call, 2)); \
|
||
expected_arg = CALL_EXPR_ARG (orig_method_call, 3); \
|
||
value_arg = CALL_EXPR_ARG (orig_method_call, 4); \
|
||
value_type = TREE_TYPE (value_arg); \
|
||
} \
|
||
while (0)
|
||
|
||
/* Add an address to an offset, forming a sum. */
|
||
|
||
static tree
|
||
build_addr_sum (tree type, tree addr, tree offset)
|
||
{
|
||
tree ptr_type = build_pointer_type (type);
|
||
return fold_build2 (POINTER_PLUS_EXPR,
|
||
ptr_type,
|
||
fold_convert (ptr_type, addr),
|
||
fold_convert (sizetype, offset));
|
||
}
|
||
|
||
/* Make sure that this-arg is non-NULL. This is a security check. */
|
||
|
||
static tree
|
||
build_check_this (tree stmt, tree this_arg)
|
||
{
|
||
return build2 (COMPOUND_EXPR, TREE_TYPE (stmt),
|
||
java_check_reference (this_arg, 1), stmt);
|
||
}
|
||
|
||
/* Now the builtins. These correspond to the primitive functions in
|
||
libjava/sun/misc/natUnsafe.cc. */
|
||
|
||
static tree
|
||
putObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
|
||
tree orig_call)
|
||
{
|
||
tree addr, stmt;
|
||
UNMARSHAL4 (orig_call);
|
||
|
||
addr = build_addr_sum (value_type, obj_arg, offset_arg);
|
||
stmt = fold_build2 (MODIFY_EXPR, value_type,
|
||
build_java_indirect_ref (value_type, addr,
|
||
flag_check_references),
|
||
value_arg);
|
||
|
||
return build_check_this (stmt, this_arg);
|
||
}
|
||
|
||
static tree
|
||
compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED,
|
||
tree orig_call)
|
||
{
|
||
enum machine_mode mode = TYPE_MODE (int_type_node);
|
||
if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
|
||
{
|
||
tree addr, stmt;
|
||
UNMARSHAL5 (orig_call);
|
||
|
||
addr = build_addr_sum (int_type_node, obj_arg, offset_arg);
|
||
stmt = build_call_expr (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_4],
|
||
3, addr, expected_arg, value_arg);
|
||
|
||
return build_check_this (stmt, this_arg);
|
||
}
|
||
return NULL_TREE;
|
||
}
|
||
|
||
static tree
|
||
compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED,
|
||
tree orig_call)
|
||
{
|
||
enum machine_mode mode = TYPE_MODE (long_type_node);
|
||
if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
|
||
{
|
||
tree addr, stmt;
|
||
UNMARSHAL5 (orig_call);
|
||
|
||
addr = build_addr_sum (long_type_node, obj_arg, offset_arg);
|
||
stmt = build_call_expr (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_8],
|
||
3, addr, expected_arg, value_arg);
|
||
|
||
return build_check_this (stmt, this_arg);
|
||
}
|
||
return NULL_TREE;
|
||
}
|
||
static tree
|
||
compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED,
|
||
tree orig_call)
|
||
{
|
||
enum machine_mode mode = TYPE_MODE (ptr_type_node);
|
||
if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
|
||
{
|
||
tree addr, stmt;
|
||
int builtin;
|
||
|
||
UNMARSHAL5 (orig_call);
|
||
builtin = (POINTER_SIZE == 32
|
||
? BUILT_IN_BOOL_COMPARE_AND_SWAP_4
|
||
: BUILT_IN_BOOL_COMPARE_AND_SWAP_8);
|
||
|
||
addr = build_addr_sum (value_type, obj_arg, offset_arg);
|
||
stmt = build_call_expr (built_in_decls[builtin],
|
||
3, addr, expected_arg, value_arg);
|
||
|
||
return build_check_this (stmt, this_arg);
|
||
}
|
||
return NULL_TREE;
|
||
}
|
||
|
||
static tree
|
||
putVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
|
||
tree orig_call)
|
||
{
|
||
tree addr, stmt, modify_stmt;
|
||
UNMARSHAL4 (orig_call);
|
||
|
||
addr = build_addr_sum (value_type, obj_arg, offset_arg);
|
||
addr
|
||
= fold_convert (build_pointer_type (build_type_variant (value_type, 0, 1)),
|
||
addr);
|
||
|
||
stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0);
|
||
modify_stmt = fold_build2 (MODIFY_EXPR, value_type,
|
||
build_java_indirect_ref (value_type, addr,
|
||
flag_check_references),
|
||
value_arg);
|
||
stmt = build2 (COMPOUND_EXPR, TREE_TYPE (modify_stmt),
|
||
stmt, modify_stmt);
|
||
|
||
return build_check_this (stmt, this_arg);
|
||
}
|
||
|
||
static tree
|
||
getVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
|
||
tree orig_call)
|
||
{
|
||
tree addr, stmt, modify_stmt, tmp;
|
||
UNMARSHAL3 (orig_call);
|
||
|
||
addr = build_addr_sum (method_return_type, obj_arg, offset_arg);
|
||
addr
|
||
= fold_convert (build_pointer_type (build_type_variant
|
||
(method_return_type, 0, 1)), addr);
|
||
|
||
stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0);
|
||
|
||
tmp = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL, method_return_type);
|
||
DECL_IGNORED_P (tmp) = 1;
|
||
DECL_ARTIFICIAL (tmp) = 1;
|
||
pushdecl (tmp);
|
||
|
||
modify_stmt = fold_build2 (MODIFY_EXPR, method_return_type,
|
||
tmp,
|
||
build_java_indirect_ref (method_return_type, addr,
|
||
flag_check_references));
|
||
|
||
stmt = build2 (COMPOUND_EXPR, void_type_node, modify_stmt, stmt);
|
||
stmt = build2 (COMPOUND_EXPR, method_return_type, stmt, tmp);
|
||
|
||
return stmt;
|
||
}
|
||
|
||
static tree
|
||
VMSupportsCS8_builtin (tree method_return_type,
|
||
tree orig_call ATTRIBUTE_UNUSED)
|
||
{
|
||
enum machine_mode mode = TYPE_MODE (long_type_node);
|
||
gcc_assert (method_return_type == boolean_type_node);
|
||
if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
|
||
return boolean_true_node;
|
||
else
|
||
return boolean_false_node;
|
||
}
|
||
|
||
|
||
|
||
#define BUILTIN_NOTHROW 1
|
||
#define BUILTIN_CONST 2
|
||
/* Define a single builtin. */
|
||
static void
|
||
define_builtin (enum built_in_function val,
|
||
const char *name,
|
||
tree type,
|
||
const char *libname,
|
||
int flags)
|
||
{
|
||
tree decl;
|
||
|
||
decl = build_decl (BUILTINS_LOCATION,
|
||
FUNCTION_DECL, get_identifier (name), type);
|
||
DECL_EXTERNAL (decl) = 1;
|
||
TREE_PUBLIC (decl) = 1;
|
||
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
|
||
pushdecl (decl);
|
||
DECL_BUILT_IN_CLASS (decl) = BUILT_IN_NORMAL;
|
||
DECL_FUNCTION_CODE (decl) = val;
|
||
if (flags & BUILTIN_NOTHROW)
|
||
TREE_NOTHROW (decl) = 1;
|
||
if (flags & BUILTIN_CONST)
|
||
TREE_READONLY (decl) = 1;
|
||
|
||
implicit_built_in_decls[val] = decl;
|
||
built_in_decls[val] = decl;
|
||
}
|
||
|
||
|
||
|
||
/* Initialize the builtins. */
|
||
void
|
||
initialize_builtins (void)
|
||
{
|
||
tree double_ftype_double, double_ftype_double_double;
|
||
tree float_ftype_float, float_ftype_float_float;
|
||
tree boolean_ftype_boolean_boolean;
|
||
tree t;
|
||
int i;
|
||
|
||
for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i)
|
||
{
|
||
tree klass_id = get_identifier (java_builtins[i].class_name.s);
|
||
tree m = get_identifier (java_builtins[i].method_name.s);
|
||
|
||
java_builtins[i].class_name.t = klass_id;
|
||
java_builtins[i].method_name.t = m;
|
||
}
|
||
|
||
void_list_node = end_params_node;
|
||
|
||
t = tree_cons (NULL_TREE, float_type_node, end_params_node);
|
||
float_ftype_float = build_function_type (float_type_node, t);
|
||
t = tree_cons (NULL_TREE, float_type_node, t);
|
||
float_ftype_float_float = build_function_type (float_type_node, t);
|
||
|
||
t = tree_cons (NULL_TREE, double_type_node, end_params_node);
|
||
double_ftype_double = build_function_type (double_type_node, t);
|
||
t = tree_cons (NULL_TREE, double_type_node, t);
|
||
double_ftype_double_double = build_function_type (double_type_node, t);
|
||
|
||
define_builtin (BUILT_IN_FMOD, "__builtin_fmod",
|
||
double_ftype_double_double, "fmod", BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_FMODF, "__builtin_fmodf",
|
||
float_ftype_float_float, "fmodf", BUILTIN_CONST);
|
||
|
||
define_builtin (BUILT_IN_ACOS, "__builtin_acos",
|
||
double_ftype_double, "_ZN4java4lang4Math4acosEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_ASIN, "__builtin_asin",
|
||
double_ftype_double, "_ZN4java4lang4Math4asinEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_ATAN, "__builtin_atan",
|
||
double_ftype_double, "_ZN4java4lang4Math4atanEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_ATAN2, "__builtin_atan2",
|
||
double_ftype_double_double, "_ZN4java4lang4Math5atan2EJddd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_CEIL, "__builtin_ceil",
|
||
double_ftype_double, "_ZN4java4lang4Math4ceilEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_COS, "__builtin_cos",
|
||
double_ftype_double, "_ZN4java4lang4Math3cosEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_EXP, "__builtin_exp",
|
||
double_ftype_double, "_ZN4java4lang4Math3expEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_FLOOR, "__builtin_floor",
|
||
double_ftype_double, "_ZN4java4lang4Math5floorEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_LOG, "__builtin_log",
|
||
double_ftype_double, "_ZN4java4lang4Math3logEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_POW, "__builtin_pow",
|
||
double_ftype_double_double, "_ZN4java4lang4Math3powEJddd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_SIN, "__builtin_sin",
|
||
double_ftype_double, "_ZN4java4lang4Math3sinEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_SQRT, "__builtin_sqrt",
|
||
double_ftype_double, "_ZN4java4lang4Math4sqrtEJdd",
|
||
BUILTIN_CONST);
|
||
define_builtin (BUILT_IN_TAN, "__builtin_tan",
|
||
double_ftype_double, "_ZN4java4lang4Math3tanEJdd",
|
||
BUILTIN_CONST);
|
||
|
||
t = tree_cons (NULL_TREE, boolean_type_node, end_params_node);
|
||
t = tree_cons (NULL_TREE, boolean_type_node, t);
|
||
boolean_ftype_boolean_boolean = build_function_type (boolean_type_node, t);
|
||
define_builtin (BUILT_IN_EXPECT, "__builtin_expect",
|
||
boolean_ftype_boolean_boolean,
|
||
"__builtin_expect",
|
||
BUILTIN_CONST | BUILTIN_NOTHROW);
|
||
define_builtin (BUILT_IN_BOOL_COMPARE_AND_SWAP_4,
|
||
"__sync_bool_compare_and_swap_4",
|
||
build_function_type_list (boolean_type_node,
|
||
int_type_node,
|
||
build_pointer_type (int_type_node),
|
||
int_type_node, NULL_TREE),
|
||
"__sync_bool_compare_and_swap_4", 0);
|
||
define_builtin (BUILT_IN_BOOL_COMPARE_AND_SWAP_8,
|
||
"__sync_bool_compare_and_swap_8",
|
||
build_function_type_list (boolean_type_node,
|
||
long_type_node,
|
||
build_pointer_type (long_type_node),
|
||
int_type_node, NULL_TREE),
|
||
"__sync_bool_compare_and_swap_8", 0);
|
||
define_builtin (BUILT_IN_SYNCHRONIZE, "__sync_synchronize",
|
||
build_function_type (void_type_node, void_list_node),
|
||
"__sync_synchronize", BUILTIN_NOTHROW);
|
||
|
||
define_builtin (BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
|
||
build_function_type_list (ptr_type_node, int_type_node, NULL_TREE),
|
||
"__builtin_return_address", BUILTIN_NOTHROW);
|
||
|
||
build_common_builtin_nodes ();
|
||
}
|
||
|
||
/* If the call matches a builtin, return the
|
||
appropriate builtin expression instead. */
|
||
tree
|
||
check_for_builtin (tree method, tree call)
|
||
{
|
||
if (optimize && TREE_CODE (call) == CALL_EXPR)
|
||
{
|
||
int i;
|
||
tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
|
||
tree method_name = DECL_NAME (method);
|
||
tree method_return_type = TREE_TYPE (TREE_TYPE (method));
|
||
|
||
for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i)
|
||
{
|
||
if (method_class == java_builtins[i].class_name.t
|
||
&& method_name == java_builtins[i].method_name.t)
|
||
{
|
||
tree fn;
|
||
|
||
if (java_builtins[i].creator != NULL)
|
||
{
|
||
tree result
|
||
= (*java_builtins[i].creator) (method_return_type, call);
|
||
return result == NULL_TREE ? call : result;
|
||
}
|
||
|
||
/* Builtin functions emit a direct call which is incompatible
|
||
with the BC-ABI. */
|
||
if (flag_indirect_dispatch)
|
||
return call;
|
||
fn = built_in_decls[java_builtins[i].builtin_code];
|
||
if (fn == NULL_TREE)
|
||
return call;
|
||
return java_build_function_call_expr (fn, call);
|
||
}
|
||
}
|
||
}
|
||
return call;
|
||
}
|
||
|
||
#include "gt-java-builtins.h"
|