00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #if defined(BUILD_OS_DARWIN)
00053 #include <limits.h>
00054 #else
00055 #include <values.h>
00056 #endif
00057 #include "defs.h"
00058 #include "glob.h"
00059 #include "config.h"
00060 #ifdef TARG_X8664
00061 #include "config_opt.h"
00062 #endif
00063 #include "wn.h"
00064 #include "wn_util.h"
00065 #include "targ_sim.h"
00066 #include "const.h"
00067 #include "c_int_model.h"
00068
00069
00070 #include "gnu_config.h"
00071 #ifdef KEY
00072
00073 #include "gnu/hwint.h"
00074 #endif
00075 #include "gnu/flags.h"
00076 #include "gnu/system.h"
00077
00078 #ifdef KEY
00079 extern "C" {
00080 #include "gnu/machmode.h"
00081 }
00082 #else
00083 #include "gnu/machmode.h"
00084 #endif // KEY
00085
00086 extern "C" {
00087 #include "gnu/tree.h"
00088 extern void warning (char*,...);
00089 extern tree c_strlen_exported (tree);
00090 #include "gnu/function.h"
00091 }
00092
00093 #ifdef GPLUSPLUS_FE
00094 #include "gnu/cp/cp-tree.h"
00095 #endif
00096
00097 #include "ir_reader.h"
00098 #include "tree_symtab.h"
00099 #include "wfe_misc.h"
00100 #ifdef KEY // get REAL_VALUE_TYPE
00101 extern "C" {
00102 #include "real.h"
00103 }
00104 #endif // KEY
00105 #include "wfe_decl.h"
00106 #include "wfe_expr.h"
00107 #include "wfe_stmt.h"
00108 #include <cmplrs/rcodes.h>
00109 #include "config_asm.h"
00110
00111 #ifdef KEY
00112
00113
00114 #define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
00115
00116 enum c_tree_code {
00117 C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE,
00118 #include "gnu/c-common.def"
00119 LAST_C_TREE_CODE
00120 };
00121 #undef DEFTREECODE
00122 #endif
00123 #include "tree_cmp.h"
00124
00125
00126
00127 extern void dump_ty_idx (TY_IDX);
00128 #ifdef KEY
00129 extern void WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_ID, ST *);
00130 #endif // KEY
00131
00132 extern "C" int get_expr_stmts_for_value (void);
00133
00134 extern PREG_NUM asm_neg_preg;
00135
00136 struct operator_from_tree_t {
00137 int tree_code;
00138 char* name;
00139 char code;
00140 int nkids;
00141 OPERATOR opr;
00142 } Operator_From_Tree [] = {
00143 ERROR_MARK, "error_mark", 'x', 0, OPERATOR_UNKNOWN,
00144 IDENTIFIER_NODE, "identifier_node", 'x', -1, OPERATOR_UNKNOWN,
00145 OP_IDENTIFIER, "op_identifier", 'x', 2, OPERATOR_UNKNOWN,
00146 TREE_LIST, "tree_list", 'x', 2, OPERATOR_UNKNOWN,
00147 TREE_VEC, "tree_vec", 'x', 2, OPERATOR_UNKNOWN,
00148 BLOCK, "block", 'b', 0, OPERATOR_UNKNOWN,
00149 VOID_TYPE, "void_type", 't', 0, OPERATOR_UNKNOWN,
00150 INTEGER_TYPE, "integer_type", 't', 0, OPERATOR_UNKNOWN,
00151 REAL_TYPE, "real_type", 't', 0, OPERATOR_UNKNOWN,
00152 COMPLEX_TYPE, "complex_type", 't', 0, OPERATOR_UNKNOWN,
00153 VECTOR_TYPE, "vector_type", 't', 0, OPERATOR_UNKNOWN,
00154 ENUMERAL_TYPE, "enumeral_type", 't', 0, OPERATOR_UNKNOWN,
00155 BOOLEAN_TYPE, "boolean_type", 't', 0, OPERATOR_UNKNOWN,
00156 CHAR_TYPE, "char_type", 't', 0, OPERATOR_UNKNOWN,
00157 POINTER_TYPE, "pointer_type", 't', 0, OPERATOR_UNKNOWN,
00158 OFFSET_TYPE, "offset_type", 't', 0, OPERATOR_UNKNOWN,
00159 REFERENCE_TYPE, "reference_type", 't', 0, OPERATOR_UNKNOWN,
00160 METHOD_TYPE, "method_type", 't', 0, OPERATOR_UNKNOWN,
00161 FILE_TYPE, "file_type", 't', 0, OPERATOR_UNKNOWN,
00162 ARRAY_TYPE, "array_type", 't', 0, OPERATOR_UNKNOWN,
00163 SET_TYPE, "set_type", 't', 0, OPERATOR_UNKNOWN,
00164 RECORD_TYPE, "record_type", 't', 0, OPERATOR_UNKNOWN,
00165 UNION_TYPE, "union_type", 't', 0, OPERATOR_UNKNOWN,
00166 QUAL_UNION_TYPE, "qual_union_type", 't', 0, OPERATOR_UNKNOWN,
00167 FUNCTION_TYPE, "function_type", 't', 0, OPERATOR_UNKNOWN,
00168 LANG_TYPE, "lang_type", 't', 0, OPERATOR_UNKNOWN,
00169 INTEGER_CST, "integer_cst", 'c', 2, OPERATOR_UNKNOWN,
00170 REAL_CST, "real_cst", 'c', 3, OPERATOR_UNKNOWN,
00171 COMPLEX_CST, "complex_cst", 'c', 3, OPERATOR_UNKNOWN,
00172 VECTOR_CST, "vector_cst", 'c', 3, OPERATOR_UNKNOWN,
00173 #ifdef KEY
00174 STRING_CST, "string_cst", 'c', 4, OPERATOR_UNKNOWN,
00175 #else
00176 STRING_CST, "string_cst", 'c', 3, OPERATOR_UNKNOWN,
00177 #endif // KEY
00178 FUNCTION_DECL, "function_decl", 'd', 0, OPERATOR_UNKNOWN,
00179 LABEL_DECL, "label_decl", 'd', 0, OPERATOR_UNKNOWN,
00180 CONST_DECL, "const_decl", 'd', 0, OPERATOR_UNKNOWN,
00181 TYPE_DECL, "type_decl", 'd', 0, OPERATOR_UNKNOWN,
00182 VAR_DECL, "var_decl", 'd', 0, OPERATOR_UNKNOWN,
00183 PARM_DECL, "parm_decl", 'd', 0, OPERATOR_UNKNOWN,
00184 RESULT_DECL, "result_decl", 'd', 0, OPERATOR_UNKNOWN,
00185 FIELD_DECL, "field_decl", 'd', 0, OPERATOR_UNKNOWN,
00186 NAMESPACE_DECL, "namespace_decl", 'd', 0, OPERATOR_UNKNOWN,
00187 COMPONENT_REF, "component_ref", 'r', 2, OPERATOR_UNKNOWN,
00188 BIT_FIELD_REF, "bit_field_ref", 'r', 3, OPERATOR_UNKNOWN,
00189 INDIRECT_REF, "indirect_ref", 'r', 1, OPERATOR_UNKNOWN,
00190 BUFFER_REF, "buffer_ref", 'r', 1, OPERATOR_UNKNOWN,
00191 ARRAY_REF, "array_ref", 'r', 2, OPERATOR_UNKNOWN,
00192 ARRAY_RANGE_REF, "array_range_ref", 'r', 2, OPERATOR_UNKNOWN,
00193 VTABLE_REF, "vtable_ref", 'r', 3, OPERATOR_UNKNOWN,
00194 CONSTRUCTOR, "constructor", 'e', 2, OPERATOR_UNKNOWN,
00195 COMPOUND_EXPR, "compound_expr", 'e', 2, OPERATOR_UNKNOWN,
00196 MODIFY_EXPR, "modify_expr", 'e', 2, OPERATOR_UNKNOWN,
00197 INIT_EXPR, "init_expr", 'e', 2, OPERATOR_UNKNOWN,
00198 TARGET_EXPR, "target_expr", 'e', 4, OPERATOR_UNKNOWN,
00199 COND_EXPR, "cond_expr", 'e', 3, OPERATOR_UNKNOWN,
00200 BIND_EXPR, "bind_expr", 'e', 3, OPERATOR_UNKNOWN,
00201 #ifdef KEY
00202 CALL_EXPR, "call_expr", 'e', 2, OPERATOR_UNKNOWN,
00203 #else
00204 CALL_EXPR, "call_expr", 'e', 3, OPERATOR_UNKNOWN,
00205 #endif // KEY
00206 METHOD_CALL_EXPR, "method_call_expr", 'e', 4, OPERATOR_UNKNOWN,
00207 WITH_CLEANUP_EXPR, "with_cleanup_expr", 'e', 3, OPERATOR_UNKNOWN,
00208 CLEANUP_POINT_EXPR, "cleanup_point_expr", 'e', 1, OPERATOR_UNKNOWN,
00209 PLACEHOLDER_EXPR, "placeholder_expr", 'x', 0, OPERATOR_UNKNOWN,
00210 WITH_RECORD_EXPR, "with_record_expr", 'e', 2, OPERATOR_UNKNOWN,
00211 PLUS_EXPR, "plus_expr", '2', 2, OPR_ADD,
00212 MINUS_EXPR, "minus_expr", '2', 2, OPR_SUB,
00213 MULT_EXPR, "mult_expr", '2', 2, OPR_MPY,
00214 TRUNC_DIV_EXPR, "trunc_div_expr", '2', 2, OPR_DIV,
00215 CEIL_DIV_EXPR, "ceil_div_expr", '2', 2, OPR_DIV,
00216 FLOOR_DIV_EXPR, "floor_div_expr", '2', 2, OPERATOR_UNKNOWN,
00217 ROUND_DIV_EXPR, "round_div_expr", '2', 2, OPERATOR_UNKNOWN,
00218 TRUNC_MOD_EXPR, "trunc_mod_expr", '2', 2, OPR_REM,
00219 CEIL_MOD_EXPR, "ceil_mod_expr", '2', 2, OPERATOR_UNKNOWN,
00220 FLOOR_MOD_EXPR, "floor_mod_expr", '2', 2, OPERATOR_UNKNOWN,
00221 ROUND_MOD_EXPR, "round_mod_expr", '2', 2, OPERATOR_UNKNOWN,
00222 RDIV_EXPR, "rdiv_expr", '2', 2, OPR_DIV,
00223 EXACT_DIV_EXPR, "exact_div_expr", '2', 2, OPR_DIV,
00224 FIX_TRUNC_EXPR, "fix_trunc_expr", '1', 1, OPERATOR_UNKNOWN,
00225 FIX_CEIL_EXPR, "fix_ceil_expr", '1', 1, OPERATOR_UNKNOWN,
00226 FIX_FLOOR_EXPR, "fix_floor_expr", '1', 1, OPERATOR_UNKNOWN,
00227 FIX_ROUND_EXPR, "fix_round_expr", '1', 1, OPERATOR_UNKNOWN,
00228 FLOAT_EXPR, "float_expr", '1', 1, OPERATOR_UNKNOWN,
00229 EXPON_EXPR, "expon_expr", '2', 2, OPERATOR_UNKNOWN,
00230 NEGATE_EXPR, "negate_expr", '1', 1, OPR_NEG,
00231 MIN_EXPR, "min_expr", '2', 2, OPR_MIN,
00232 MAX_EXPR, "max_expr", '2', 2, OPR_MAX,
00233 ABS_EXPR, "abs_expr", '1', 1, OPR_ABS,
00234 FFS_EXPR, "ffs_expr", '1', 1, OPERATOR_UNKNOWN,
00235 LSHIFT_EXPR, "lshift_expr", '2', 2, OPR_SHL,
00236 RSHIFT_EXPR, "rshift_expr", '2', 2, OPERATOR_UNKNOWN,
00237 LROTATE_EXPR, "lrotate_expr", '2', 2, OPR_RROTATE,
00238 RROTATE_EXPR, "rrotate_expr", '2', 2, OPR_RROTATE,
00239 BIT_IOR_EXPR, "bit_ior_expr", '2', 2, OPR_BIOR,
00240 BIT_XOR_EXPR, "bit_xor_expr", '2', 2, OPR_BXOR,
00241 BIT_AND_EXPR, "bit_and_expr", '2', 2, OPR_BAND,
00242 BIT_ANDTC_EXPR, "bit_andtc_expr", '2', 2, OPERATOR_UNKNOWN,
00243 BIT_NOT_EXPR, "bit_not_expr", '1', 1, OPR_BNOT,
00244 TRUTH_ANDIF_EXPR, "truth_andif_expr", 'e', 2, OPR_CAND,
00245 TRUTH_ORIF_EXPR, "truth_orif_expr", 'e', 2, OPR_CIOR,
00246 TRUTH_AND_EXPR, "truth_and_expr", 'e', 2, OPR_BAND,
00247 TRUTH_OR_EXPR, "truth_or_expr", 'e', 2, OPR_BIOR,
00248 TRUTH_XOR_EXPR, "truth_xor_expr", 'e', 2, OPR_BXOR,
00249 TRUTH_NOT_EXPR, "truth_not_expr", 'e', 1, OPR_LNOT,
00250 LT_EXPR, "lt_expr", '<', 2, OPR_LT,
00251 LE_EXPR, "le_expr", '<', 2, OPR_LE,
00252 GT_EXPR, "gt_expr", '<', 2, OPR_GT,
00253 GE_EXPR, "ge_expr", '<', 2, OPR_GE,
00254 EQ_EXPR, "eq_expr", '<', 2, OPR_EQ,
00255 NE_EXPR, "ne_expr", '<', 2, OPR_NE,
00256 UNORDERED_EXPR, "unordered_expr", '<', 2, OPERATOR_UNKNOWN,
00257 ORDERED_EXPR, "ordered_expr", '<', 2, OPERATOR_UNKNOWN,
00258 UNLT_EXPR, "unlt_expr", '<', 2, OPERATOR_UNKNOWN,
00259 UNLE_EXPR, "unle_expr", '<', 2, OPERATOR_UNKNOWN,
00260 UNGT_EXPR, "ungt_expr", '<', 2, OPERATOR_UNKNOWN,
00261 UNGE_EXPR, "unge_expr", '<', 2, OPERATOR_UNKNOWN,
00262 UNEQ_EXPR, "uneq_expr", '<', 2, OPERATOR_UNKNOWN,
00263 IN_EXPR, "in_expr", '2', 2, OPERATOR_UNKNOWN,
00264 SET_LE_EXPR, "set_le_expr", '<', 2, OPERATOR_UNKNOWN,
00265 CARD_EXPR, "card_expr", '1', 1, OPERATOR_UNKNOWN,
00266 RANGE_EXPR, "range_expr", '2', 2, OPERATOR_UNKNOWN,
00267 CONVERT_EXPR, "convert_expr", '1', 1, OPERATOR_UNKNOWN,
00268 NOP_EXPR, "nop_expr", '1', 1, OPERATOR_UNKNOWN,
00269 NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1, OPERATOR_UNKNOWN,
00270 VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1, OPERATOR_UNKNOWN,
00271 SAVE_EXPR, "save_expr", 'e', 3, OPERATOR_UNKNOWN,
00272 UNSAVE_EXPR, "unsave_expr", 'e', 1, OPERATOR_UNKNOWN,
00273 RTL_EXPR, "rtl_expr", 'e', 2, OPERATOR_UNKNOWN,
00274 ADDR_EXPR, "addr_expr", 'e', 1, OPERATOR_UNKNOWN,
00275 REFERENCE_EXPR, "reference_expr", 'e', 1, OPERATOR_UNKNOWN,
00276 ENTRY_VALUE_EXPR, "entry_value_expr", 'e', 1, OPERATOR_UNKNOWN,
00277 FDESC_EXPR, "fdesc_expr", 'e', 2, OPERATOR_UNKNOWN,
00278 COMPLEX_EXPR, "complex_expr", '2', 2, OPR_PAIR,
00279 CONJ_EXPR, "conj_expr", '1', 1, OPERATOR_UNKNOWN,
00280 REALPART_EXPR, "realpart_expr", '1', 1, OPR_FIRSTPART,
00281 IMAGPART_EXPR, "imagpart_expr", '1', 1, OPR_SECONDPART,
00282 PREDECREMENT_EXPR, "predecrement_expr", 'e', 2, OPR_SUB,
00283 PREINCREMENT_EXPR, "preincrement_expr", 'e', 2, OPR_ADD,
00284 POSTDECREMENT_EXPR, "postdecrement_expr", 'e', 2, OPR_SUB,
00285 POSTINCREMENT_EXPR, "postincrement_expr", 'e', 2, OPR_ADD,
00286 VA_ARG_EXPR, "va_arg_expr", 'e', 1, OPERATOR_UNKNOWN,
00287 TRY_CATCH_EXPR, "try_catch_expr", 'e', 2, OPERATOR_UNKNOWN,
00288 TRY_FINALLY_EXPR, "try_finally", 'e', 2, OPERATOR_UNKNOWN,
00289 GOTO_SUBROUTINE_EXPR, "goto_subroutine", 'e', 2, OPERATOR_UNKNOWN,
00290 POPDHC_EXPR, "popdhc_expr", 's', 0, OPERATOR_UNKNOWN,
00291 POPDCC_EXPR, "popdcc_expr", 's', 0, OPERATOR_UNKNOWN,
00292 LABEL_EXPR, "label_expr", 's', 1, OPERATOR_UNKNOWN,
00293 GOTO_EXPR, "goto_expr", 's', 1, OPERATOR_UNKNOWN,
00294 RETURN_EXPR, "return_expr", 's', 1, OPERATOR_UNKNOWN,
00295 EXIT_EXPR, "exit_expr", 's', 1, OPERATOR_UNKNOWN,
00296 LOOP_EXPR, "loop_expr", 's', 1, OPERATOR_UNKNOWN,
00297 LABELED_BLOCK_EXPR, "labeled_block_expr", 'e', 2, OPERATOR_UNKNOWN,
00298 EXIT_BLOCK_EXPR, "exit_block_expr", 'e', 2, OPERATOR_UNKNOWN,
00299 EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 3, OPERATOR_UNKNOWN,
00300 SWITCH_EXPR, "switch_expr", 'e', 2, OPERATOR_UNKNOWN,
00301 EXC_PTR_EXPR, "exc_ptr_expr", 'e', 0, OPERATOR_UNKNOWN,
00302 LAST_AND_UNUSED_TREE_CODE,"last_and_unused_tree_code",0, 0, OPERATOR_UNKNOWN,
00303
00304 SRCLOC, "srcloc", 'x', 2, OPERATOR_UNKNOWN,
00305 SIZEOF_EXPR, "sizeof_expr", '1', 1, OPERATOR_UNKNOWN,
00306 ARROW_EXPR, "arrow_expr", 'e', 1, OPERATOR_UNKNOWN,
00307 ALIGNOF_EXPR, "alignof_expr", '1', 1, OPERATOR_UNKNOWN,
00308 EXPR_STMT, "expr_stmt", 'e', 1, OPERATOR_UNKNOWN,
00309 COMPOUND_STMT, "compound_stmt", 'e', 1, OPERATOR_UNKNOWN,
00310 DECL_STMT, "decl_stmt", 'e', 1, OPERATOR_UNKNOWN,
00311 IF_STMT, "if_stmt", 'e', 3, OPERATOR_UNKNOWN,
00312 FOR_STMT, "for_stmt", 'e', 4, OPERATOR_UNKNOWN,
00313 WHILE_STMT, "while_stmt", 'e', 2, OPERATOR_UNKNOWN,
00314 DO_STMT, "do_stmt", 'e', 2, OPERATOR_UNKNOWN,
00315 RETURN_STMT, "return_stmt", 'e', 1, OPERATOR_UNKNOWN,
00316 BREAK_STMT, "break_stmt", 'e', 0, OPERATOR_UNKNOWN,
00317 CONTINUE_STMT, "continue_stmt", 'e', 0, OPERATOR_UNKNOWN,
00318 #ifdef KEY
00319 SWITCH_STMT, "switch_stmt", 'e', 3, OPERATOR_UNKNOWN,
00320 #else
00321 SWITCH_STMT, "switch_stmt", 'e', 2, OPERATOR_UNKNOWN,
00322 #endif // KEY
00323 GOTO_STMT, "goto_stmt", 'e', 1, OPERATOR_UNKNOWN,
00324 LABEL_STMT, "label_stmt", 'e', 1, OPERATOR_UNKNOWN,
00325 ASM_STMT, "asm_stmt", 'e', 5, OPERATOR_UNKNOWN,
00326 SCOPE_STMT, "scope_stmt", 'e', 1, OPERATOR_UNKNOWN,
00327 FILE_STMT, "file_stmt", 'e', 1, OPERATOR_UNKNOWN,
00328 #ifdef KEY
00329 CASE_LABEL, "case_label", 'e', 3, OPERATOR_UNKNOWN,
00330 #else
00331 CASE_LABEL, "case_label", 'e', 2, OPERATOR_UNKNOWN,
00332 #endif // KEY
00333 STMT_EXPR, "stmt_expr", 'e', 1, OPERATOR_UNKNOWN,
00334 COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1, OPERATOR_UNKNOWN,
00335 CLEANUP_STMT, "cleanup_stmt", 'e', 2, OPERATOR_UNKNOWN,
00336 #ifdef KEY
00337 OMP_MARKER_STMT, "omp_marker_stmt", 'e', 0, OPERATOR_UNKNOWN,
00338 #endif // KEY
00339 FREQ_HINT_STMT, "freq_hint_stmt", 'e', 1, OPERATOR_UNKNOWN,
00340 LAST_C_TREE_CODE, "last_c_tree_code", 0, 0, OPERATOR_UNKNOWN,
00341
00342 #ifdef GPLUSPLUS_FE
00343 OFFSET_REF, "offset_ref", 'r', 2, OPERATOR_UNKNOWN,
00344 PTRMEM_CST, "ptrmem_cst", 'c', 2, OPERATOR_UNKNOWN,
00345 NEW_EXPR, "nw_expr", 'e', 3, OPERATOR_UNKNOWN,
00346 VEC_NEW_EXPR, "vec_nw_expr", 'e', 3, OPERATOR_UNKNOWN,
00347 DELETE_EXPR, "dl_expr", 'e', 2, OPERATOR_UNKNOWN,
00348 VEC_DELETE_EXPR, "vec_dl_expr", 'e', 2, OPERATOR_UNKNOWN,
00349 SCOPE_REF, "scope_ref", 'r', 2, OPERATOR_UNKNOWN,
00350 MEMBER_REF, "member_ref", 'r', 2, OPERATOR_UNKNOWN,
00351 TYPE_EXPR, "type_expr", 'e', 1, OPERATOR_UNKNOWN,
00352 AGGR_INIT_EXPR, "aggr_init_expr", 'e', 3, OPERATOR_UNKNOWN,
00353 THROW_EXPR, "throw_expr", 'e', 1, OPERATOR_UNKNOWN,
00354 EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0, OPERATOR_UNKNOWN,
00355 TEMPLATE_DECL, "template_decl", 'd', 0, OPERATOR_UNKNOWN,
00356 TEMPLATE_PARM_INDEX, "template_parm_index", 'x', 0, OPERATOR_UNKNOWN,
00357 TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0, OPERATOR_UNKNOWN,
00358 TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0, OPERATOR_UNKNOWN,
00359 BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm", 't', 0, OPERATOR_UNKNOWN,
00360 TYPENAME_TYPE, "typename_type", 't', 0, OPERATOR_UNKNOWN,
00361 UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0, OPERATOR_UNKNOWN,
00362 TYPEOF_TYPE, "typeof_type", 't', 0, OPERATOR_UNKNOWN,
00363 USING_DECL, "using_decl", 'd', 0, OPERATOR_UNKNOWN,
00364 USING_STMT, "using_directive", 'e', 1, OPERATOR_UNKNOWN,
00365 DEFAULT_ARG, "default_arg", 'c', 2, OPERATOR_UNKNOWN,
00366 TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2, OPERATOR_UNKNOWN,
00367 CPLUS_BINDING, "binding", 'x', 2, OPERATOR_UNKNOWN,
00368 OVERLOAD, "overload", 'x', 1, OPERATOR_UNKNOWN,
00369 WRAPPER, "wrapper", 'x', 1, OPERATOR_UNKNOWN,
00370 LOOKUP_EXPR, "lookup_expr", 'e', 1, OPERATOR_UNKNOWN,
00371 MODOP_EXPR, "modop_expr", 'e', 3, OPERATOR_UNKNOWN,
00372 CAST_EXPR, "cast_expr", '1', 1, OPERATOR_UNKNOWN,
00373 REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00374 CONST_CAST_EXPR, "const_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00375 STATIC_CAST_EXPR, "static_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00376 DYNAMIC_CAST_EXPR, "dynamic_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00377 DOTSTAR_EXPR, "dotstar_expr", 'e', 2, OPERATOR_UNKNOWN,
00378 TYPEID_EXPR, "typeid_expr", 'e', 1, OPERATOR_UNKNOWN,
00379 PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3, OPERATOR_UNKNOWN,
00380 SUBOBJECT, "subobject", 'e', 1, OPERATOR_UNKNOWN,
00381 CTOR_STMT, "ctor_stmt", 'e', 0, OPERATOR_UNKNOWN,
00382 CTOR_INITIALIZER, "ctor_initializer", 'e', 2, OPERATOR_UNKNOWN,
00383 RETURN_INIT, "return_init", 'e', 2, OPERATOR_UNKNOWN,
00384 TRY_BLOCK, "try_block", 'e', 2, OPERATOR_UNKNOWN,
00385 EH_SPEC_BLOCK, "eh_spec_block", 'e', 2, OPERATOR_UNKNOWN,
00386 HANDLER, "handler", 'e', 2, OPERATOR_UNKNOWN,
00387 MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1, OPERATOR_UNKNOWN,
00388 TAG_DEFN, "tag_defn", 'e', 0, OPERATOR_UNKNOWN,
00389 IDENTITY_CONV, "identity_conv", 'e', 1, OPERATOR_UNKNOWN,
00390 LVALUE_CONV, "lvalue_conv", 'e', 1, OPERATOR_UNKNOWN,
00391 QUAL_CONV, "qual_conv", 'e', 1, OPERATOR_UNKNOWN,
00392 STD_CONV, "std_conv", 'e', 1, OPERATOR_UNKNOWN,
00393 PTR_CONV, "ptr_conv", 'e', 1, OPERATOR_UNKNOWN,
00394 PMEM_CONV, "pmem_conv", 'e', 1, OPERATOR_UNKNOWN,
00395 BASE_CONV, "base_conv", 'e', 1, OPERATOR_UNKNOWN,
00396 REF_BIND, "ref_bind", 'e', 1, OPERATOR_UNKNOWN,
00397 USER_CONV, "user_conv", 'e', 2, OPERATOR_UNKNOWN,
00398 AMBIG_CONV, "ambig_conv", 'e', 1, OPERATOR_UNKNOWN,
00399 RVALUE_CONV, "rvalue_conv", 'e', 1, OPERATOR_UNKNOWN,
00400 LAST_CPLUS_TREE_CODE, "last_cplus_tree_code", 0, 0, OPERATOR_UNKNOWN
00401 #endif
00402 };
00403
00404 #ifdef TARG_SL
00405
00406
00407
00408 typedef enum EXTEND_PARM_POS {
00409 P0,
00410 P1,
00411 P2,
00412 P3,
00413 P4,
00414 P0_P2,
00415 P1_P3,
00416 P2_P4,
00417 P3_P4,
00418 }EXTEND_PARM_POS;
00419
00420 typedef struct intrinsicop_attr_extended {
00421 INTRINSIC id;
00422 BOOL need_extend;
00423 int extend_kid;
00424 EXTEND_PARM_POS pos;
00425 INTRINSIC aux_id;
00426 } INTRN_ATTR_EXTEND;
00427
00428 #define INTRN_EATTR_LAST 27
00429 static INTRN_ATTR_EXTEND intrn_eattr[INTRN_EATTR_LAST] = {
00430 INTRN_C2_LD_V, FALSE, 1, P1,INTRN_C3_PTR,
00431 INTRN_C2_LD_G, FALSE, 1, P0,INTRN_C3_PTR,
00432 INTRN_C2_LD_V2G, FALSE, 1, P0,INTRN_C3_PTR,
00433 INTRN_C2_LD_C_IMM, FALSE, 1, P1,INTRN_C3_PTR,
00434 INTRN_C2_LD_V_IMM, FALSE, 1, P4,INTRN_C3_PTR,
00435 INTRN_C2_LD_G_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00436 INTRN_C2_LD_V2G_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00437 INTRN_C2_ST_V, FALSE, 1, P1,INTRN_C3_PTR,
00438 INTRN_C2_ST_G, FALSE, 1, P1,INTRN_C3_PTR,
00439 INTRN_C2_ST_G2V, FALSE, 1, P1,INTRN_C3_PTR,
00440 INTRN_C2_ST_C_IMM, FALSE, 1, P1,INTRN_C3_PTR,
00441 INTRN_C2_ST_V_IMM, FALSE, 1, P3,INTRN_C3_PTR,
00442 INTRN_C2_ST_G_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00443 INTRN_C2_ST_G2V_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00444
00445 INTRN_C3DMAC_A, TRUE, 2, P2_P4, INTRN_C3_PTR,
00446 INTRN_C3DMULA_A, TRUE, 1, P2, INTRN_C3_PTR,
00447 INTRN_C3LD, TRUE, 1, P0, INTRN_C3_PTR,
00448 INTRN_C3ST, TRUE, 1, P1, INTRN_C3_PTR,
00449 INTRN_C3MAC_A, TRUE, 2, P2_P4, INTRN_C3_PTR,
00450 INTRN_C3MAC_AR, TRUE, 1, P3, INTRN_C3_PTR,
00451 INTRN_C3MULA_A, TRUE, 1, P2_P4, INTRN_C3_PTR,
00452 INTRN_C3MULA_AR, TRUE, 1, P3, INTRN_C3_PTR,
00453 INTRN_C3SAADD_A, TRUE, 2, P0_P2, INTRN_C3_PTR,
00454 INTRN_C3SAADDH_A, TRUE, 2, P0_P2, INTRN_C3_PTR,
00455 INTRN_C3SADDA_A, TRUE, 1, P2, INTRN_C3_PTR,
00456 INTRN_C3SAMULH_A, TRUE, 2, P0_P2, INTRN_C3_PTR,
00457 INTRN_C3_SET_CIRCBUF, FALSE, 2, P3_P4, INTRN_C3_PTR,
00458 };
00459
00460 static BOOL intrinsic_op_need_extend (INTRINSIC id) {
00461
00462 INTRN_ATTR_EXTEND *p = &intrn_eattr[0];
00463 int i=0;
00464 while (p && (i<INTRN_EATTR_LAST)) {
00465 if (p->id == id ) {
00466 return p->need_extend;
00467 }
00468 i++;
00469 p++;
00470 }
00471 return FALSE;
00472
00473 }
00474
00475 static BOOL intrinsic_need_deref (INTRINSIC id) {
00476
00477 INTRN_ATTR_EXTEND *p = &intrn_eattr[0];
00478 int i=0;
00479 while (p && (i<INTRN_EATTR_LAST)) {
00480 if (p->id == id ) {
00481 return TRUE;
00482 }
00483 i++;
00484 p++;
00485 }
00486 return FALSE;
00487
00488 }
00489
00490 static INTRN_ATTR_EXTEND *Get_intrinsic_op_Eattr (INTRINSIC id) {
00491 INTRN_ATTR_EXTEND *p = &intrn_eattr[0];
00492 int i =0;
00493 while (p && (i<INTRN_EATTR_LAST)) {
00494 if (p->id == id ) {
00495 return p;
00496 }
00497 p++;
00498 i++;
00499 }
00500 return NULL;
00501 }
00502
00503 static void WN_Set_Deref_If_Needed(WN *wn) {
00504 INTRINSIC intrn=WN_intrinsic(wn);
00505 if(intrinsic_need_deref(intrn)){
00506 INTRN_ATTR_EXTEND *p=Get_intrinsic_op_Eattr(intrn);
00507
00508 switch (p->pos) {
00509 case P0:
00510 WN_Set_Parm_Dereference(WN_kid(wn,0)); break;
00511 case P1:
00512 WN_Set_Parm_Dereference(WN_kid(wn,1)); break;
00513 case P2:
00514 WN_Set_Parm_Dereference(WN_kid(wn,2)); break;
00515 case P3:
00516 WN_Set_Parm_Dereference(WN_kid(wn,3)); break;
00517 case P4:
00518 WN_Set_Parm_Dereference(WN_kid(wn,4)); break;
00519 case P0_P2:
00520 WN_Set_Parm_Dereference(WN_kid(wn,0)); WN_Set_Parm_Dereference(WN_kid(wn,2)); break;
00521 case P1_P3:
00522 WN_Set_Parm_Dereference(WN_kid(wn,1)); WN_Set_Parm_Dereference(WN_kid(wn,3)); break;
00523 case P2_P4:
00524 WN_Set_Parm_Dereference(WN_kid(wn,2)); WN_Set_Parm_Dereference(WN_kid(wn,4)); break;
00525 case P3_P4:
00526 WN_Set_Parm_Dereference(WN_kid(wn,3)); WN_Set_Parm_Dereference(WN_kid(wn,4)); break;
00527 default:
00528 Is_True(0, ("intrinsic has no extended attribution"));
00529 }
00530 }
00531 return;
00532 }
00533
00534 static int intrinsic_op_extend_kid (int index) {
00535 return intrn_eattr[index].extend_kid;
00536 }
00537
00538 static EXTEND_PARM_POS intrinsic_op_parm_pos (int index) {
00539 return intrn_eattr[index].pos;
00540 }
00541
00542 BOOL WN_Need_Append_Intrinsic(WN *rhs) {
00543 OPERATOR opr=WN_operator(rhs);
00544 if (opr == OPR_INTRINSIC_OP || opr == OPR_INTRINSIC_CALL) {
00545 INTRINSIC inid = WN_intrinsic(rhs);
00546 if (intrinsic_op_need_extend(inid)) {
00547 return TRUE;
00548 }
00549 } else if (opr == OPR_CVTL) {
00550 WN *tmp = WN_kid0(rhs);
00551 OPERATOR kid_opr=WN_operator(tmp);
00552 if (kid_opr == OPR_INTRINSIC_OP || kid_opr == OPR_INTRINSIC_CALL) {
00553 INTRINSIC inid = WN_intrinsic(tmp);
00554 if (intrinsic_op_need_extend(inid)) {
00555 return TRUE;
00556 }
00557 }
00558 }
00559 return FALSE;
00560 }
00561
00562
00563
00564
00565
00566
00567
00568 void WFE_Stmt_Append_Extend_Intrinsic(WN *wn, WN *master_variable, SRCPOS src) {
00569 WN *kid1s[5];
00570 WN *op1;
00571 int aux_kid = -1;
00572 int extend_num = -1;
00573 int pos[5]= {-1, -1, -1, -1, -1};
00574 WN *tmp_wn;
00575 INTRN_ATTR_EXTEND *p;
00576
00577 if (WN_kid0(master_variable) && WN_operator(master_variable) == OPR_CVT) {
00578 master_variable = WN_kid0(master_variable);
00579 }
00580 if (WN_operator(WN_kid0(wn)) == OPR_INTRINSIC_OP) {
00581 p = Get_intrinsic_op_Eattr(WN_intrinsic(WN_kid0(wn)));
00582 tmp_wn = wn;
00583 } else if (WN_operator(WN_kid0(wn)) == OPR_CVTL && WN_operator(WN_kid0(WN_kid0(wn))) == OPR_INTRINSIC_OP ) {
00584 p = Get_intrinsic_op_Eattr(WN_intrinsic(WN_kid0(WN_kid0(wn))));
00585 tmp_wn = WN_kid0(wn);
00586 } else if (WN_operator(wn) == OPR_INTRINSIC_CALL) {
00587 p = Get_intrinsic_op_Eattr(WN_intrinsic(wn));
00588 tmp_wn = wn;
00589 }
00590
00591 if (p) {
00592 extend_num = p->extend_kid;
00593 switch (p->aux_id) {
00594 case INTRN_C3_PTR: aux_kid = 2; break;
00595 default:
00596 Is_True(0, ("unsupport internal intrinsic op"));
00597 }
00598 switch (p->pos) {
00599 case P0:
00600 pos[0] = 0; break;
00601 case P1:
00602 pos[0] = 1; break;
00603 case P2:
00604 pos[0] = 2; break;
00605 case P3:
00606 pos[0] = 3; break;
00607 case P0_P2:
00608 pos[0] = 0; pos[1] = 2; break;
00609 case P1_P3:
00610 pos[0] = 1; pos[1] = 3; break;
00611 case P2_P4:
00612 pos[0] = 2; pos[1] = 4; break;
00613 case P3_P4:
00614 pos[0] = 3; pos[1] = 4; break;
00615 default:
00616 Is_True(0, ("intrinsic has no extended attribution"));
00617 }
00618 } else {
00619 Is_True(0, ("intrinsic has no extended attribution"));
00620 }
00621
00622 if (WN_operator(master_variable) == OPR_INTCONST) {
00623
00624 Is_True(WN_opcode(master_variable) == OPC_I4INTCONST,("should be 32-bit immediate"));
00625 master_variable = WN_CreateParm(MTYPE_I4, master_variable, Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
00626 } else {
00627 TY_IDX ti2 = WN_ty(master_variable);
00628 TYPE_ID tm2 = TY_mtype(ti2);
00629 master_variable = WN_CreateParm (Mtype_comparison (tm2), master_variable,
00630 ti2, WN_PARM_BY_VALUE);
00631 }
00632 kid1s[0]= master_variable;
00633 for (int i =0; i < extend_num; i++) {
00634 WN *op1;
00635 if (WN_operator(wn) == OPR_INTRINSIC_CALL) {
00636 op1 = WN_kid0(WN_kid(tmp_wn, pos[i]));
00637 } else {
00638 op1 = WN_kid0(WN_kid(WN_kid0(tmp_wn), pos[i]));
00639 }
00640 ST *st1;
00641 if (WN_has_sym(op1)) {
00642 st1 = WN_st(op1);
00643 } else {
00644
00645 continue;
00646 }
00647 TY_IDX ti1 = WN_ty(op1);
00648 TYPE_ID tm1 = TY_mtype(ti1);
00649 op1 = WN_CreateParm (Mtype_comparison (tm1), op1,
00650 ti1, WN_PARM_BY_VALUE);
00651 kid1s[1]= op1;
00652 WN *app1 = WN_Create_Intrinsic(OPR_INTRINSIC_OP,TY_mtype(ST_type(st1)), MTYPE_V, p->aux_id, aux_kid, kid1s);
00653 WN *stmt1 = WN_Stid(TY_mtype(ST_type(st1)), ST_ofst(st1), st1, ST_type(st1), app1, 0);
00654 WFE_Stmt_Append(stmt1, src);
00655 }
00656 }
00657
00658 #endif
00659
00660
00661 #ifdef KEY
00662
00663
00664 void
00665 WFE_Convert_To_Host_Order (long *buf)
00666 {
00667 if (!Same_Byte_Sex)
00668 {
00669 long t = buf[0];
00670 buf[0] = buf[1];
00671 buf[1] = t;
00672 }
00673 }
00674 #endif
00675
00676
00677
00678 bool
00679 Has_Subsumed_Cvtl(OPERATOR opr)
00680 {
00681 if (OPERATOR_is_load(opr) || OPERATOR_is_leaf(opr))
00682 return TRUE;
00683 if (opr == OPR_CVT || opr == OPR_CVTL || opr == OPR_TAS)
00684 return TRUE;
00685 if (opr == OPR_EQ || opr == OPR_NE ||
00686 opr == OPR_GE || opr == OPR_GT ||
00687 opr == OPR_LE || opr == OPR_LT ||
00688 opr == OPR_LNOT || opr == OPR_LAND || opr == OPR_LIOR ||
00689 opr == OPR_CAND || opr == OPR_CIOR)
00690 return TRUE;
00691 return FALSE;
00692 }
00693
00694
00695
00696
00697 inline UINT64 Parameter_Size(UINT64 sz)
00698 {
00699 # if WORDS_BIG_ENDIAN
00700 return sz;
00701 # else
00702 return (sz + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
00703 # endif
00704 }
00705
00706 TYPE_ID
00707 Widen_Mtype (TYPE_ID t)
00708 {
00709 if (MTYPE_is_m(t))
00710 return t;
00711 if (MTYPE_is_void(t) || t == MTYPE_BS) {
00712 Fail_FmtAssertion ("Widen_Mtype: for MTYPE_V or MTYPE_BS");
00713 return t;
00714 }
00715 if (MTYPE_byte_size(t) >= 4)
00716 return t;
00717 return Mtype_TransferSize(MTYPE_I4, t);
00718 }
00719
00720
00721
00722 void
00723 WFE_Set_ST_Addr_Saved (WN *wn)
00724 {
00725 OPERATOR Operator;
00726 ST *st;
00727
00728 Operator = WN_operator (wn);
00729
00730 switch ( Operator ) {
00731
00732 case OPR_LDA:
00733 case OPR_LDMA:
00734
00735 st = WN_st (wn);
00736
00737 if (ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_FUNC)
00738 Set_ST_addr_saved (st);
00739 break;
00740
00741 case OPR_ARRAY:
00742
00743 WFE_Set_ST_Addr_Saved (WN_kid0 (wn));
00744 break;
00745
00746 case OPR_LDID:
00747
00748 st = WN_st (wn);
00749 if (ST_pt_to_unique_mem (st))
00750 Clear_ST_pt_to_unique_mem (st);
00751 break;
00752
00753 case OPR_CONST:
00754 case OPR_ILOAD:
00755 case OPR_MLOAD:
00756 case OPR_INTCONST:
00757 case OPR_INTRINSIC_OP:
00758 case OPR_CALL:
00759 case OPR_EQ:
00760 case OPR_NE:
00761 case OPR_GT:
00762 case OPR_GE:
00763 case OPR_LT:
00764 case OPR_LE:
00765 case OPR_ALLOCA:
00766 break;
00767
00768 case OPR_EVAL:
00769 case OPR_TAS:
00770 case OPR_CVT:
00771 case OPR_CVTL:
00772 case OPR_NEG:
00773 case OPR_ABS:
00774 case OPR_SQRT:
00775 case OPR_REALPART:
00776 case OPR_IMAGPART:
00777 case OPR_PAREN:
00778 case OPR_RND:
00779 case OPR_TRUNC:
00780 case OPR_CEIL:
00781 case OPR_FLOOR:
00782 case OPR_BNOT:
00783 case OPR_LNOT:
00784 case OPR_LOWPART:
00785 case OPR_HIGHPART:
00786 case OPR_MINPART:
00787 case OPR_MAXPART:
00788 case OPR_RECIP:
00789 case OPR_RSQRT:
00790 case OPR_PARM:
00791 case OPR_EXTRACT_BITS:
00792
00793 WFE_Set_ST_Addr_Saved (WN_kid0(wn));
00794 break;
00795
00796 case OPR_CSELECT:
00797
00798 WFE_Set_ST_Addr_Saved (WN_kid1(wn));
00799 WFE_Set_ST_Addr_Saved (WN_kid2(wn));
00800 break;
00801
00802 case OPR_SELECT:
00803 case OPR_ADD:
00804 case OPR_SUB:
00805 case OPR_MPY:
00806 case OPR_DIV:
00807 case OPR_MOD:
00808 case OPR_REM:
00809 case OPR_DIVREM:
00810 case OPR_MAX:
00811 case OPR_MIN:
00812 case OPR_MINMAX:
00813 case OPR_BAND:
00814 case OPR_BIOR:
00815 case OPR_BXOR:
00816 case OPR_BNOR:
00817 case OPR_LAND:
00818 case OPR_LIOR:
00819 case OPR_SHL:
00820 case OPR_ASHR:
00821 case OPR_LSHR:
00822 case OPR_COMPLEX:
00823 case OPR_HIGHMPY:
00824 case OPR_RROTATE:
00825 case OPR_COMPOSE_BITS:
00826
00827 WFE_Set_ST_Addr_Saved (WN_kid0(wn));
00828 WFE_Set_ST_Addr_Saved (WN_kid1(wn));
00829 break;
00830
00831 case OPR_CAND:
00832 case OPR_CIOR:
00833
00834 break;
00835
00836 case OPR_COMMA:
00837
00838 WFE_Set_ST_Addr_Saved (WN_kid1(wn));
00839 break;
00840
00841 case OPR_RCOMMA:
00842
00843 WFE_Set_ST_Addr_Saved (WN_kid0(wn));
00844 break;
00845
00846 default:
00847
00848 DevWarn ("WFE_Set_ST_Addr_Saved not implemented");
00849 }
00850 }
00851
00852 typedef struct wfe_bind_expr_t {
00853 tree rtl_expr;
00854 WN *block;
00855 } WFE_BIND_EXPR;
00856
00857 WFE_BIND_EXPR *wfe_bind_expr_stack = NULL;
00858 INT32 wfe_bind_expr_stack_last = -1;
00859 INT32 wfe_bind_expr_stack_max = 0;
00860
00861 void
00862 WFE_Expand_Start_Stmt_Expr (tree t)
00863 {
00864 WN *block = WN_CreateBlock ();
00865 WFE_Stmt_Push (block, wfe_stmk_comma, Get_Srcpos ());
00866 }
00867
00868 void
00869 WFE_Expand_End_Stmt_Expr (tree t)
00870 {
00871 WN *block = WFE_Stmt_Pop (wfe_stmk_comma);
00872 ++wfe_bind_expr_stack_last;
00873 if (wfe_bind_expr_stack_last == wfe_bind_expr_stack_max) {
00874 if (wfe_bind_expr_stack == NULL) {
00875 wfe_bind_expr_stack_max = 32;
00876 wfe_bind_expr_stack =
00877 (WFE_BIND_EXPR *) malloc (wfe_bind_expr_stack_max *
00878 sizeof (WFE_BIND_EXPR));
00879 }
00880 else {
00881 wfe_bind_expr_stack_max = wfe_bind_expr_stack_max +
00882 (wfe_bind_expr_stack_max >> 1);
00883 wfe_bind_expr_stack =
00884 (WFE_BIND_EXPR *) realloc (wfe_bind_expr_stack,
00885 wfe_bind_expr_stack_max *
00886 sizeof (WFE_BIND_EXPR));
00887 }
00888 }
00889 wfe_bind_expr_stack [wfe_bind_expr_stack_last].rtl_expr = t;
00890 wfe_bind_expr_stack [wfe_bind_expr_stack_last].block = block;
00891 }
00892
00893 typedef struct wfe_save_expr_t {
00894 tree exp;
00895 ST *st;
00896 } WFE_SAVE_EXPR;
00897
00898 WFE_SAVE_EXPR *wfe_save_expr_stack = NULL;
00899 INT32 wfe_save_expr_stack_last = -1;
00900 INT32 wfe_save_expr_stack_max = 0;
00901
00902 static WN*
00903 WFE_Save_Expr (tree save_exp)
00904 {
00905 INT32 i;
00906 tree exp = TREE_OPERAND (save_exp, 0);
00907 TY_IDX ty_idx = Get_TY (TREE_TYPE (exp));
00908 TYPE_ID mtype = TY_mtype (ty_idx);
00909 ST *st;
00910 WN *wn;
00911
00912 for (i = wfe_save_expr_stack_last; i >= 0; i--) {
00913 #ifndef KEY
00914 if (wfe_save_expr_stack [i].exp == exp) {
00915 #else
00916 if (wfe_save_expr_stack [i].exp == save_exp) {
00917 #endif
00918 st = wfe_save_expr_stack [i].st;
00919 FmtAssert (st != 0,
00920 ("WFE_Save_Expr: st not yet assigned"));
00921 wn = WN_Ldid (mtype, 0, st, ty_idx);
00922 return wn;
00923 }
00924 }
00925 i = ++wfe_save_expr_stack_last;
00926 if (i == wfe_save_expr_stack_max) {
00927 if (wfe_save_expr_stack == NULL) {
00928 wfe_save_expr_stack_max = 32;
00929 wfe_save_expr_stack =
00930 (WFE_SAVE_EXPR *) malloc (wfe_save_expr_stack_max *
00931 sizeof (WFE_SAVE_EXPR));
00932 }
00933 else {
00934 wfe_save_expr_stack_max = wfe_save_expr_stack_max +
00935 (wfe_save_expr_stack_max >> 1);
00936 wfe_save_expr_stack =
00937 (WFE_SAVE_EXPR *) realloc (wfe_save_expr_stack,
00938 wfe_save_expr_stack_max *
00939 sizeof (WFE_SAVE_EXPR));
00940 }
00941 }
00942 #ifndef KEY
00943 wfe_save_expr_stack [i].exp = exp;
00944 #else
00945 wfe_save_expr_stack [i].exp = save_exp;
00946 #endif
00947 wfe_save_expr_stack [i].st = 0;
00948 wn = WFE_Expand_Expr (exp);
00949 st = Gen_Temp_Symbol (ty_idx, "__save_expr");
00950 #ifdef KEY
00951 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
00952 #endif // KEY
00953 WFE_Set_ST_Addr_Saved (wn);
00954 wn = WN_Stid (mtype, 0, st, ty_idx, wn);
00955 WFE_Stmt_Append (wn, Get_Srcpos());
00956 wfe_save_expr_stack [i].st = st;
00957 wn = WN_Ldid (mtype, 0, st, ty_idx);
00958 return wn;
00959 }
00960
00961 static void
00962 WFE_Unsave_Expr (tree save_exp)
00963 {
00964 INT32 i;
00965 tree exp = TREE_OPERAND (save_exp, 0);
00966 TY_IDX ty_idx = Get_TY (TREE_TYPE (exp));
00967 TYPE_ID mtype = TY_mtype (ty_idx);
00968 ST *st;
00969 WN *wn;
00970
00971 for (i = wfe_save_expr_stack_last; i >= 0; i--) {
00972 #ifndef KEY
00973 if (wfe_save_expr_stack [i].exp == exp) {
00974 #else
00975 if (wfe_save_expr_stack [i].exp == save_exp) {
00976 #endif
00977 wfe_save_expr_stack [i].exp == NULL;
00978 wfe_save_expr_stack [i].st == NULL;
00979 break;
00980 }
00981 }
00982 }
00983
00984
00985
00986
00987
00988 static WN *
00989 WFE_Array_Expr(tree exp,
00990 TY_IDX *ty_idx,
00991 TY_IDX component_ty_idx,
00992 INT64 component_offset,
00993 UINT32 field_id)
00994 {
00995 WN *wn;
00996 enum tree_code code = TREE_CODE (exp);
00997 if (code == COMPONENT_REF) {
00998 TY_IDX ty_idx0;
00999 tree arg0 = TREE_OPERAND(exp, 0);
01000 tree arg1 = TREE_OPERAND(exp, 1);
01001 if (component_ty_idx == 0)
01002 ty_idx0 = Get_TY(TREE_TYPE(exp));
01003 else ty_idx0 = component_ty_idx;
01004 #ifdef KEY // bug 10728
01005 if (TREE_THIS_VOLATILE(exp))
01006 Set_TY_is_volatile(ty_idx0);
01007 #endif
01008 Is_True(! DECL_BIT_FIELD(arg1),
01009 ("WFE_Array_Expr: address arithmetic cannot use bitfield addresses"));
01010 INT64 ofst = (BITSPERBYTE * Get_Integer_Value(DECL_FIELD_OFFSET(arg1)) +
01011 Get_Integer_Value(DECL_FIELD_BIT_OFFSET(arg1)))
01012 / BITSPERBYTE;
01013
01014 #ifdef KEY
01015
01016
01017
01018
01019
01020
01021
01022 if (TREE_CODE(arg0) == MODIFY_EXPR) {
01023 WFE_Expand_Expr(arg0);
01024 tree lhs = TREE_OPERAND(arg0, 0);
01025 Is_True (lhs != NULL && TREE_CODE(lhs) == VAR_DECL,
01026 ("Unsupported lhs for `(p=q).x[n]'"));
01027 arg0 = lhs;
01028 }
01029 #endif
01030
01031 #ifdef KEY // bug 9725: If the field is an array of struct, it is considered
01032
01033 return WFE_Array_Expr(arg0, ty_idx, ty_idx0, ofst + component_offset,
01034 DECL_FIELD_ID(arg1));
01035 #else
01036 return WFE_Array_Expr(arg0, ty_idx, ty_idx0, ofst + component_offset,
01037 field_id + DECL_FIELD_ID(arg1));
01038 #endif
01039 }
01040 else if (code == VAR_DECL || code == PARM_DECL) {
01041 ST *st = Get_ST (exp);
01042 ST *base_st = ST_base (st);
01043
01044
01045 if (st != base_st) {
01046 FmtAssert (component_ty_idx == 0,
01047 ("Variable Length Arrays within struct not currently implemented"));
01048 wn = WN_Ldid (Pointer_Mtype, 0, base_st, ST_type (base_st));
01049 }
01050 else
01051 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01052 if (component_ty_idx == 0)
01053 *ty_idx = ST_type(st);
01054 else {
01055 *ty_idx = component_ty_idx;
01056 if (TY_align(ST_type(st)) < TY_align(component_ty_idx))
01057 Set_TY_align(*ty_idx, TY_align(ST_type(st)));
01058 }
01059 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01060 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01061 return wn;
01062 }
01063 else if (code == CONSTRUCTOR) {
01064 ST *st = WFE_Generate_Temp_For_Initialized_Aggregate (exp, "");
01065 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01066 if (component_ty_idx == 0)
01067 *ty_idx = ST_type(st);
01068 else *ty_idx = component_ty_idx;
01069 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01070 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01071 return wn;
01072 }
01073 else if (code == STRING_CST) {
01074 wn = WFE_Expand_Expr(exp);
01075 *ty_idx = ST_type (TREE_STRING_ST (exp));
01076 return wn;
01077 }
01078 else if (code == INDIRECT_REF) {
01079 wn = WFE_Expand_Expr(TREE_OPERAND (exp, 0));
01080 if (component_ty_idx == 0)
01081 *ty_idx = Get_TY (TREE_TYPE(exp));
01082 else {
01083 *ty_idx = component_ty_idx;
01084 INT node_align = TYPE_ALIGN(TREE_TYPE(exp)) / BITSPERBYTE;
01085 if (node_align < TY_align(component_ty_idx))
01086 Set_TY_align(*ty_idx, node_align);
01087 }
01088 if (component_offset != 0) {
01089 WN *wn0 = WN_Intconst(MTYPE_I4, component_offset);
01090 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn, wn0);
01091 }
01092 return wn;
01093 }
01094 else if (code == CALL_EXPR) {
01095 wn = WFE_Expand_Expr(exp);
01096 FmtAssert (WN_opcode (wn) == OPC_MCOMMA,
01097 ("opcode other than OPC_MCOMMA for call underneath ARRAY_REF"));
01098 WFE_Stmt_Append (WN_kid0 (wn), Get_Srcpos ());
01099 ST *st = WN_st (WN_kid1 (wn));
01100 WN_Delete (WN_kid1 (wn));
01101 WN_Delete (wn);
01102 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01103 if (component_ty_idx == 0)
01104 *ty_idx = ST_type(st);
01105 else {
01106 *ty_idx = component_ty_idx;
01107 if (TY_align(ST_type(st)) < TY_align(component_ty_idx))
01108 Set_TY_align(*ty_idx, TY_align(ST_type(st)));
01109 }
01110 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01111 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01112 return wn;
01113 }
01114 else if (code == ARRAY_REF) {
01115 WN *wn0, *wn1, *wn2;
01116 TY_IDX ty_idx0;
01117 #ifdef KEY // Bug 5831.
01118 wn0 = WFE_Array_Expr(TREE_OPERAND (exp, 0), &ty_idx0, 0,
01119 component_offset, field_id);
01120 #else
01121 wn0 = WFE_Array_Expr(TREE_OPERAND (exp, 0), &ty_idx0, component_ty_idx,
01122 component_offset, field_id);
01123 #endif
01124 Is_True(TY_kind(ty_idx0) == KIND_ARRAY,
01125 ("WFE_Array_Expr: arg 0 of ARRAY_REF not of type KIND_ARRAY"));
01126 ARB_HANDLE arb = TY_arb(ty_idx0);
01127 if (ARB_dimension(arb) == 1 &&
01128 ARB_first_dimen(arb) && ARB_last_dimen(arb) &&
01129 ARB_const_lbnd(arb)) {
01130 if (ARB_const_ubnd(arb))
01131 wn1 = WN_Intconst(MTYPE_I4, ARB_ubnd_val(arb) - ARB_lbnd_val(arb) + 1);
01132 #ifdef KEY
01133
01134 else if (ARB_ubnd_var(arb)) {
01135 ST *ubnd_st = &St_Table[ARB_ubnd_var(arb)];
01136 wn1 = WN_Binary(OPR_SUB, MTYPE_I4,
01137 WN_Ldid(MTYPE_I4, 0, ubnd_st, ST_type(ubnd_st)),
01138 WN_Intconst(MTYPE_I4, ARB_lbnd_val(arb) - 1));
01139 }
01140 #endif
01141 else
01142 wn1 = WN_Intconst(MTYPE_I4, 0);
01143 wn2 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
01144 #ifdef TARG_X8664 // bug 11705
01145 if (WN_operator(wn2) == OPR_SUB)
01146 WN_set_rtype(wn2, Mtype_TransferSign(MTYPE_I4, WN_rtype(wn2)));
01147 #endif
01148 #ifdef KEY // bug 14871, OSP_455
01149 if (TARGET_64BIT && OPCODE_is_load(WN_opcode(wn2)))
01150 WN_set_rtype(wn2, Mtype_TransferSize(MTYPE_U8, WN_rtype(wn2)));
01151 #endif
01152 #ifdef KEY
01153
01154
01155 if (TREE_CODE(TREE_OPERAND(exp, 0)) == ARRAY_REF) {
01156 Is_True(WN_operator(wn0) == OPR_ARRAY,
01157 ("WFE_Array_Expr: ARRAY_REF not translated to OPR_ARRAY"));
01158 int old_kid_count = WN_kid_count(wn0);
01159 int new_kid_count = old_kid_count + 2;
01160 wn = WN_Create(OPR_ARRAY, Pointer_Mtype, MTYPE_V, new_kid_count);
01161 for (int kid = 0; kid < (old_kid_count >> 1); kid++) {
01162 WN_kid(wn, kid + 1) = WN_kid(wn0, kid + 1);
01163 WN_kid(wn, (new_kid_count >> 1) + kid + 1) =
01164 WN_kid(wn0, (old_kid_count >> 1) + kid + 1);
01165 }
01166 WN_kid(wn, 0) = WN_kid(wn0, 0);
01167 WN_kid(wn, new_kid_count >> 1) = wn1;
01168 WN_kid(wn, new_kid_count - 1) = wn2;
01169 WN_Delete(wn0);
01170 } else
01171 #endif
01172 wn = WN_Ternary(OPR_ARRAY, Pointer_Mtype, wn0, wn1, wn2);
01173
01174 WN_element_size(wn) = TY_size(Get_TY (TREE_TYPE(exp)));
01175 }
01176 else Is_True(FALSE,
01177 ("WFE_Array_Expr: only const-bounds 1-dimension arrays handled now"));
01178 if (component_ty_idx == 0) {
01179 *ty_idx = TY_etype(ty_idx0);
01180 if (TY_align(ty_idx0) < TY_align(*ty_idx))
01181 Set_TY_align(*ty_idx, TY_align(ty_idx0));
01182 #ifdef KEY // bug 10728
01183 if (TREE_THIS_VOLATILE(exp))
01184 Set_TY_is_volatile(*ty_idx);
01185 #endif
01186 }
01187 else *ty_idx = component_ty_idx;
01188 return wn;
01189 }
01190 #ifdef KEY
01191 else if (code == COMPOUND_LITERAL_EXPR) {
01192 tree arg0 = DECL_INITIAL (TREE_OPERAND (TREE_OPERAND (exp, 0), 0));
01193 ST *st = WFE_Generate_Temp_For_Initialized_Aggregate (arg0, "");
01194 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
01195 *ty_idx = component_ty_idx == 0 ? ST_type(st) : component_ty_idx;
01196 return wn;
01197 }
01198 else if (code == COND_EXPR) {
01199
01200
01201
01202
01203
01204
01205 WN *wn1, *wn2;
01206 wn = WFE_Expand_Expr (TREE_OPERAND(exp, 0));
01207 wn1 = WFE_Array_Expr (TREE_OPERAND(exp, 1), ty_idx, component_ty_idx,
01208 component_offset, field_id);
01209 wn2 = WFE_Array_Expr (TREE_OPERAND(exp, 2), ty_idx, component_ty_idx,
01210 component_offset, field_id);
01211 Set_PU_has_very_high_whirl(Get_Current_PU());
01212 return WN_CreateExp3(OPR_CSELECT, WN_rtype(wn1), MTYPE_V, wn, wn1, wn2);
01213 }
01214 #endif
01215 else {
01216 Is_True(FALSE,
01217 ("WFE_Array_Expr: unsupported node for base of ARRAY_REF"));
01218 return NULL;
01219 }
01220 }
01221
01222
01223
01224
01225
01226
01227 #if defined(TARG_SL)
01228
01229
01230
01231 ST*
01232 WN_Include_Vbuf_Symbol( WN* wn, BOOL need_initialize) {
01233 WN* tmp = wn;
01234 static ST* st = NULL;
01235 if(need_initialize) {
01236 st = NULL;
01237 need_initialize=FALSE;
01238 }
01239 for( INT i = 0; i < WN_kid_count(wn); i++) {
01240 if(WN_operator(WN_kid(wn,i)) != OPR_LDA) {
01241 st = WN_Include_Vbuf_Symbol(WN_kid(wn,i), need_initialize);
01242 }
01243 else {
01244 if(WN_has_sym(WN_kid(wn,i)) && ST_in_vbuf(WN_st(WN_kid(wn,i)))) {
01245 return WN_st(WN_kid(wn,i));
01246 }
01247 }
01248 }
01249 return st;
01250 }
01251
01252
01253
01254 void
01255 WN_Adjust_Vbuf_Ofst(WN* wn, ST* st){
01256 INT shft_num = ST_in_v2buf(st) ? 1 : (ST_in_v4buf(st) ? 2 : 0);
01257
01258 if(WN_operator(wn) == OPR_LDA) {
01259 Is_True(WN_has_sym(wn), ("this symbol don't has base address symbole"));
01260 Is_True(ST_in_vbuf(st), ("this symbol for adjusting offset is not vbuf variable"));
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 if(!WN_vbuf_ofst_adjusted(wn)) {
01271 WN_lda_offset(wn) = (((WN_lda_offset(wn) / 16) * 16) << shft_num ) \
01272 + (WN_lda_offset(wn) % 16);
01273 WN_Set_vbuf_ofst_adjusted(wn);
01274 }
01275 return;
01276 }
01277 else if(WN_operator(wn) == OPR_INTCONST) {
01278 if(WN_vbuf_ofst_adjusted(wn)) return;
01279 else {
01280 WN_const_val(wn) <<= shft_num;
01281 WN_Set_vbuf_ofst_adjusted(wn);
01282 }
01283 return;
01284 }
01285 else if(WN_kid_count(wn)) {
01286 for( INT i = 0; (i < WN_kid_count(wn) || !WN_kid_count(wn)); i++) {
01287
01288
01289
01290
01291 if(WN_operator(wn) == OPR_STID ||
01292 WN_operator(wn) == OPR_LDID ||
01293 WN_operator(wn) == OPR_ISTORE ||
01294 WN_operator(wn) == OPR_ILOAD)
01295 continue;
01296
01297
01298
01299 else if(WN_operator(wn) == OPR_ARRAY && i == 1) {
01300 continue;
01301 }
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316 else if(WN_operator(wn) == OPR_MPY)
01317 {
01318 continue;
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 else if(WN_operator(wn) == OPR_SHL) {
01332 continue;
01333 }
01334 else {
01335 WN_Adjust_Vbuf_Ofst(WN_kid(wn,i), st);
01336 }
01337 }
01338 return;
01339 }
01340 return;
01341 }
01342
01343
01344 WN*
01345 Shft_Vbuf_Array_Ofst(WN* wn, INT shft_num = 0) {
01346 if(WN_operator(wn) == OPR_INTCONST) {
01347 WN_const_val(wn) <<= shft_num;
01348 }
01349 else if(WN_operator(wn) == OPR_LDA) {
01350 WN_lda_offset(wn) <<= shft_num;
01351 }
01352 return wn;
01353 }
01354
01355 WN*
01356 Adjust_Vbuf_Array_Ofst(WN* wn) {
01357 Is_True((WN_operator(wn) == OPR_STID ||
01358 WN_operator(wn) == OPR_LDID ||
01359 WN_operator(wn) == OPR_ISTORE ||
01360 WN_operator(wn) == OPR_ILOAD ||
01361 WN_operator(wn) == OPR_PARM) ,
01362 ( " invalid operator for adjusting vbuf ofst"));
01363 ST* st = WN_Include_Vbuf_Symbol(wn, TRUE);
01364
01365 if(!st || ! (ST_in_v2buf(st) || ST_in_v4buf(st))) return wn;
01366
01367
01368
01369
01370
01371
01372 for( INT i = 0; i < WN_kid_count(wn); i++) {
01373 WN_Adjust_Vbuf_Ofst(WN_kid(wn,i), st);
01374 }
01375 return wn;
01376 }
01377
01378
01379
01380
01381
01382 static BOOL sameness;
01383 static BOOL Same_Var( char* var_name, tree rhs )
01384 {
01385 if (!rhs) {
01386 DevWarn("Same_Var::rhs is NULL");
01387 return FALSE;
01388 }
01389
01390
01391
01392 if( TREE_CODE_CLASS(TREE_CODE(rhs)) == 'c' )
01393 return FALSE;
01394
01395
01396
01397
01398
01399 if( TREE_CODE(rhs) == COMPONENT_REF )
01400 return FALSE;
01401
01402 BOOL tempsame = FALSE;
01403
01404
01405
01406
01407 switch( TREE_CODE(rhs) ) {
01408 case VAR_DECL :
01409 if( DECL_NAME(rhs) && !strcmp(var_name,IDENTIFIER_POINTER(DECL_NAME(rhs))))
01410 return TRUE;
01411 else
01412 return FALSE;
01413 case PARM_DECL:
01414 if( DECL_NAME(rhs) && !strcmp(var_name,IDENTIFIER_POINTER(DECL_NAME(rhs))))
01415 return TRUE;
01416 else if( TREE_CHAIN(rhs) )
01417 tempsame |= Same_Var( var_name, TREE_CHAIN(rhs) );
01418 else
01419 return FALSE;
01420 break;
01421 case FUNCTION_DECL:
01422 tempsame |= Same_Var( var_name, DECL_ARGUMENTS(rhs) );
01423 break;
01424 case INDIRECT_REF:
01425
01426
01427
01428 if( TREE_CODE(TREE_OPERAND(rhs,0))==PARM_DECL ||
01429 TREE_CODE(TREE_OPERAND(rhs,0))==VAR_DECL ) {
01430 tempsame |= Same_Var( var_name, TREE_OPERAND(rhs,0) );
01431 } else
01432 return FALSE;
01433 default:
01434 if( TREE_OPERAND(rhs,0) )
01435 tempsame |= Same_Var( var_name, TREE_OPERAND(rhs,0) );
01436 if( TREE_OPERAND(rhs,1) )
01437 tempsame |= Same_Var( var_name, TREE_OPERAND(rhs,1) );
01438 break;
01439 }
01440
01441
01442
01443
01444 return tempsame;
01445 }
01446
01447 BOOL
01448 Has_LDA_Node(WN* tree) {
01449 BOOL has_lda = FALSE;
01450 for(INT i = 0; i < WN_kid_count(tree); i++) {
01451 has_lda |= Has_LDA_Node(WN_kid(tree, i));
01452 if(has_lda)
01453 break;
01454 }
01455 if( WN_operator(tree) == OPR_LDA) {
01456 return TRUE;
01457 }
01458 return has_lda;
01459 }
01460
01461 BOOL
01462 Mark_LDA_Vbuf_Offset(WN* tree, INTRINSIC iopc) {
01463
01464 BOOL has_v1buf_lda = FALSE;
01465 static vector < WN* > processed;
01466
01467 if(find(processed.begin(), processed.end(), tree) != processed.end())
01468 return has_v1buf_lda;
01469
01470 for(INT i = 0; i < WN_kid_count(tree); i++) {
01471 has_v1buf_lda |= Mark_LDA_Vbuf_Offset(WN_kid(tree, i), iopc);
01472 }
01473
01474 if(WN_operator(tree) == OPR_LDA) {
01475 if(ST_in_vbuf(WN_st(tree)) && iopc == INTRN_VBUF_OFFSET) {
01476 WN_Set_is_internal_mem_ofst(tree);
01477 Set_ST_is_vbuf_ofst(WN_st(tree));
01478 if(ST_in_v1buf(WN_st(tree)))
01479 has_v1buf_lda = TRUE;
01480 }
01481 else if(ST_in_sbuf(WN_st(tree)) && iopc == INTRN_SBUF_OFFSET) {
01482 WN_Set_is_internal_mem_ofst(tree);
01483 Set_ST_is_sbuf_ofst(WN_st(tree));
01484 }
01485 }
01486
01487 processed.push_back(tree);
01488
01489 return has_v1buf_lda;
01490 }
01491
01492 BOOL
01493 May_Include_Vbuf_Offset(INTRINSIC iopc, WN* call) {
01494 switch(iopc) {
01495 case INTRN_C2_LD_V:
01496 case INTRN_C2_ST_V:
01497 case INTRN_C2_ST_G2V:
01498 case INTRN_C2_ST_G:
01499 return Has_LDA_Node(WN_kid0(WN_kid1(call)));
01500 case INTRN_C2_LD_V2G:
01501 case INTRN_C2_LD_G:
01502 return Has_LDA_Node(WN_kid0(WN_kid0(call)));
01503 default:
01504 return FALSE;
01505 }
01506 }
01507 #endif
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523 WN *
01524 WFE_Lhs_Of_Modify_Expr(tree_code assign_code,
01525 tree lhs,
01526 #ifdef TARG_SL
01527
01528
01529
01530 tree rhs,
01531 #endif
01532 bool need_result,
01533 TY_IDX component_ty_idx,
01534 INT64 component_offset,
01535 UINT32 field_id,
01536 bool is_bit_field,
01537 WN *rhs_wn,
01538 PREG_NUM rhs_preg_num,
01539 bool is_realpart,
01540 bool is_imagpart)
01541 {
01542 WN *wn;
01543 ST *st;
01544 bool result_in_temp = FALSE;
01545 ST *result_preg_st;
01546 PREG_NUM result_preg;
01547 PREG_NUM lhs_preg_num = 0;
01548 enum tree_code code = TREE_CODE (lhs);
01549 BOOL volt = FALSE;
01550 #ifdef TARG_SL
01551 BOOL need_append = FALSE;
01552 #endif
01553 if (rhs_wn != NULL) {
01554 WFE_Set_ST_Addr_Saved (rhs_wn);
01555 #ifdef TARG_SL
01556 need_append = WN_Need_Append_Intrinsic(rhs_wn);
01557 #endif
01558 }
01559 if (code == COMPONENT_REF) {
01560 INT64 ofst;
01561 TY_IDX ty_idx0;
01562 tree arg0 = TREE_OPERAND(lhs, 0);
01563 tree arg1 = TREE_OPERAND(lhs, 1);
01564 if (component_ty_idx == 0)
01565 ty_idx0 = Get_TY(TREE_TYPE(lhs));
01566 else ty_idx0 = component_ty_idx;
01567 if (DECL_BIT_FIELD(arg1))
01568 is_bit_field = TRUE;
01569 if (! is_bit_field)
01570 ofst = (BITSPERBYTE * Get_Integer_Value(DECL_FIELD_OFFSET(arg1)) +
01571 Get_Integer_Value(DECL_FIELD_BIT_OFFSET(arg1)))
01572 / BITSPERBYTE;
01573 else ofst = 0;
01574 #ifdef KEY // bug 10422: check if the field is volatile
01575 if (TREE_THIS_VOLATILE(arg1)) {
01576 Set_TY_is_volatile(ty_idx0);
01577 volt = TRUE;
01578 }
01579 #endif
01580 #ifdef TARG_SL
01581 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, ty_idx0,
01582 #else
01583 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, need_result, ty_idx0,
01584 #endif
01585 ofst+component_offset,
01586 field_id + DECL_FIELD_ID(arg1), is_bit_field,
01587 rhs_wn, rhs_preg_num, is_realpart, is_imagpart);
01588 return wn;
01589 }
01590
01591 if (code == REALPART_EXPR) {
01592 tree arg0 = TREE_OPERAND(lhs, 0);
01593 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(arg0));
01594 #ifdef TARG_SL
01595 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, ty_idx0,
01596 #else
01597 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, need_result, ty_idx0,
01598 #endif
01599 component_offset, field_id, is_bit_field,
01600 rhs_wn, rhs_preg_num, TRUE, FALSE);
01601 return wn;
01602 }
01603
01604 if (code == IMAGPART_EXPR) {
01605 tree arg0 = TREE_OPERAND(lhs, 0);
01606 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(arg0));
01607 #ifdef TARG_SL
01608 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, ty_idx0,
01609 #else
01610 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, need_result, ty_idx0,
01611 #endif
01612 component_offset, field_id, is_bit_field,
01613 rhs_wn, rhs_preg_num, FALSE, TRUE);
01614 return wn;
01615 }
01616
01617 if (code == PARM_DECL || code == VAR_DECL) {
01618 TY_IDX hi_ty_idx = Get_TY(TREE_TYPE(lhs));
01619 if (TREE_THIS_VOLATILE(lhs)) {
01620 Set_TY_is_volatile(hi_ty_idx);
01621 volt = TRUE;
01622 }
01623 TY_IDX desc_ty_idx = component_ty_idx;
01624 if (desc_ty_idx == 0)
01625 desc_ty_idx = hi_ty_idx;
01626 if (TY_is_volatile(desc_ty_idx)) {
01627 Clear_TY_is_volatile(desc_ty_idx);
01628 volt = TRUE;
01629 }
01630 st = Get_ST (lhs);
01631 if (ST_assigned_to_dedicated_preg (st)) {
01632 Set_TY_is_volatile(hi_ty_idx);
01633 volt = TRUE;
01634 }
01635 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
01636 ("WFE_Lhs_Of_Modify_Expr: field id for bit-field exceeds limit"));
01637
01638 TYPE_ID rtype = Widen_Mtype(TY_mtype(desc_ty_idx));
01639 TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
01640
01641 if (rhs_wn == NULL) {
01642
01643
01644
01645
01646
01647 if (rtype == MTYPE_M && desc == MTYPE_M) {
01648 FmtAssert(TY_size(desc_ty_idx) == MTYPE_byte_size(Def_Int_Mtype),
01649 ("Size of ASM struct opnd must be equal to register size"));
01650 desc = rtype = Def_Int_Mtype;
01651 desc_ty_idx = hi_ty_idx = MTYPE_To_TY(Def_Int_Mtype);
01652 }
01653 ST *rhs_st = MTYPE_To_PREG(desc);
01654 rhs_wn = WN_CreateLdid (OPR_LDID, rtype,
01655 desc, rhs_preg_num, rhs_st,
01656 desc_ty_idx, 0);
01657 #ifdef KEY
01658
01659
01660 if (MTYPE_byte_size(desc) < 4) {
01661
01662 rhs_wn = WN_CreateCvtl(!MTYPE_signed(desc) ? OPC_U4CVTL : OPC_I4CVTL,
01663 MTYPE_bit_size(desc),
01664 rhs_wn);
01665
01666 }
01667 #endif
01668 }
01669 else {
01670 WN *result_wn;
01671 if (assign_code == MODIFY_EXPR) {
01672 if (is_realpart)
01673 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01674 rhs_wn,
01675 WN_Unary(OPR_IMAGPART,
01676 Mtype_complex_to_real (rtype),
01677 WN_CreateLdid(OPR_LDID, rtype, desc,
01678 ST_ofst(st) + component_offset,
01679 st, hi_ty_idx, field_id)));
01680 else
01681 if (is_imagpart)
01682 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01683 WN_Unary(OPR_REALPART,
01684 Mtype_complex_to_real (rtype),
01685 WN_CreateLdid(OPR_LDID, rtype, desc,
01686 ST_ofst(st) + component_offset,
01687 st, hi_ty_idx, field_id)),
01688 rhs_wn);
01689 }
01690 else {
01691 if (is_realpart)
01692 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01693 rhs_wn,
01694 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0));
01695 else
01696 if (is_imagpart)
01697 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01698 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0),
01699 rhs_wn);
01700 }
01701
01702 if (assign_code == PREINCREMENT_EXPR ||
01703 assign_code == PREDECREMENT_EXPR) {
01704 wn = WN_CreateLdid (OPR_LDID, rtype, desc,
01705 ST_ofst(st) + component_offset,
01706 st, hi_ty_idx, field_id);
01707 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01708 rtype, wn, rhs_wn);
01709 result_wn = rhs_wn;
01710 }
01711 else if (assign_code == POSTINCREMENT_EXPR ||
01712 assign_code == POSTDECREMENT_EXPR) {
01713 result_wn = WN_CreateLdid (OPR_LDID, rtype, desc,
01714 ST_ofst(st) + component_offset,
01715 st, hi_ty_idx, field_id);
01716 }
01717 else result_wn = rhs_wn;
01718
01719
01720 if (need_result && rtype != MTYPE_M &&
01721 (volt ||
01722 assign_code == POSTINCREMENT_EXPR ||
01723 assign_code == POSTDECREMENT_EXPR)) {
01724 result_in_temp = TRUE;
01725 result_preg_st = MTYPE_To_PREG(rtype);
01726 result_preg = Create_Preg(rtype, NULL);
01727 wn = WN_Stid(rtype, result_preg, result_preg_st, desc_ty_idx, result_wn,
01728 0);
01729 WFE_Stmt_Append (wn, Get_Srcpos());
01730 result_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
01731 }
01732
01733 if (assign_code == POSTINCREMENT_EXPR ||
01734 assign_code == POSTDECREMENT_EXPR) {
01735 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01736 rtype, result_wn, rhs_wn);
01737 }
01738 else rhs_wn = result_wn;
01739
01740
01741 }
01742
01743
01744 if (!WFE_Keep_Zero_Length_Structs &&
01745 desc == MTYPE_M &&
01746 TY_size (hi_ty_idx) == 0) {
01747
01748 }
01749 else {
01750 #ifdef KEY // bug 10422: check if the field is volatile
01751 if (volt)
01752 Set_TY_is_volatile(hi_ty_idx);
01753 #endif
01754 wn = WN_Stid (desc, ST_ofst(st) + component_offset + lhs_preg_num, st,
01755 hi_ty_idx, rhs_wn, field_id);
01756 #if defined(TARG_SL)
01757 wn = Adjust_Vbuf_Array_Ofst(wn);
01758 #endif
01759 WFE_Stmt_Append(wn, Get_Srcpos());
01760 #if defined(TARG_SL)
01761 if (need_append) {
01762 WN *ldid_wn;
01763 if (! result_in_temp)
01764 ldid_wn = WN_CreateLdid(OPR_LDID, rtype, desc,
01765 ST_ofst(st) + component_offset, st, hi_ty_idx,
01766 field_id);
01767
01768 else
01769 ldid_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
01770
01771 WFE_Stmt_Append_Extend_Intrinsic(wn, ldid_wn, Get_Srcpos());
01772 }
01773 #endif
01774 }
01775 if (need_result) {
01776 if (! result_in_temp)
01777 wn = WN_CreateLdid(OPR_LDID, rtype, desc,
01778 ST_ofst(st) + component_offset, st, hi_ty_idx,
01779 field_id);
01780 else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
01781 if (is_realpart)
01782 wn = WN_Unary (OPR_REALPART, Mtype_complex_to_real (rtype), wn);
01783 else
01784 if (is_imagpart)
01785 wn = WN_Unary (OPR_IMAGPART, Mtype_complex_to_real (rtype), wn);
01786 }
01787 else wn = NULL;
01788 }
01789 else if (code == INDIRECT_REF) {
01790 WN *addr_wn = WFE_Expand_Expr (TREE_OPERAND (lhs, 0));
01791 TY_IDX hi_ty_idx = Get_TY(TREE_TYPE(lhs));
01792 if (TREE_THIS_VOLATILE(lhs)) {
01793 Set_TY_is_volatile(hi_ty_idx);
01794 volt = TRUE;
01795 }
01796 TY_IDX desc_ty_idx = component_ty_idx;
01797 if (desc_ty_idx == 0)
01798 desc_ty_idx = hi_ty_idx;
01799 if (TY_is_volatile(desc_ty_idx)) {
01800 Clear_TY_is_volatile(desc_ty_idx);
01801 volt = TRUE;
01802 }
01803 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
01804 ("WFE_Lhs_Of_Modify_Expr: field id for bit-field exceeds limit"));
01805 if (WN_has_side_effects(addr_wn) &&
01806 (need_result ||
01807 assign_code == PREINCREMENT_EXPR ||
01808 assign_code == PREDECREMENT_EXPR ||
01809 assign_code == POSTINCREMENT_EXPR ||
01810 assign_code == POSTDECREMENT_EXPR)) {
01811 ST *preg_st;
01812 PREG_NUM preg;
01813 TY_IDX address_ty_idx = Get_TY (TREE_TYPE (TREE_OPERAND (lhs, 0)));
01814 #ifdef KEY
01815
01816 if (TY_is_volatile(address_ty_idx)) {
01817 Clear_TY_is_volatile(address_ty_idx);
01818 volt = TRUE;
01819 }
01820 #endif
01821 preg_st = MTYPE_To_PREG(Pointer_Mtype);
01822 preg = Create_Preg (Pointer_Mtype, NULL);
01823 wn = WN_Stid (Pointer_Mtype, preg, preg_st, address_ty_idx, addr_wn);
01824 WFE_Set_ST_Addr_Saved (addr_wn);
01825 #ifdef KEY
01826
01827
01828 WN *body = WFE_Stmt_Top();
01829 if (body &&
01830 WN_last(body) &&
01831 WN_operator(WN_last(body)) == OPR_ASM_STMT) {
01832 WFE_Stmt_Prepend_Last (wn, Get_Srcpos());
01833 } else
01834 #endif
01835 WFE_Stmt_Append (wn, Get_Srcpos());
01836 addr_wn = WN_Ldid (Pointer_Mtype, preg, preg_st, address_ty_idx);
01837 }
01838
01839 TYPE_ID rtype = Widen_Mtype(TY_mtype(desc_ty_idx));
01840 TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
01841
01842 if (rhs_wn == NULL) {
01843
01844
01845
01846 ST *rhs_st;
01847
01848
01849 #ifdef KEY
01850
01851
01852
01853 if (rtype == MTYPE_M && desc == MTYPE_M) {
01854 if (TY_size(desc_ty_idx) == MTYPE_byte_size(Def_Int_Mtype)) {
01855 desc = rtype = Def_Int_Mtype;
01856 desc_ty_idx = hi_ty_idx = MTYPE_To_TY(Def_Int_Mtype);
01857 } else {
01858 desc = rtype = MTYPE_I4;
01859 desc_ty_idx = hi_ty_idx = MTYPE_To_TY(MTYPE_I4);
01860 }
01861 }
01862 #endif
01863 rhs_st = MTYPE_To_PREG(desc);
01864
01865 rhs_wn = WN_CreateLdid (OPR_LDID, rtype, desc, rhs_preg_num, rhs_st,
01866 desc_ty_idx, 0);
01867 }
01868 else {
01869 WN *result_wn;
01870
01871 if (assign_code == MODIFY_EXPR) {
01872 if (is_realpart)
01873 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01874 rhs_wn,
01875 WN_Unary(OPR_IMAGPART,
01876 Mtype_complex_to_real (rtype),
01877 WN_CreateIload(OPR_ILOAD, rtype, desc,
01878 component_offset,
01879 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01880 Make_Pointer_Type(hi_ty_idx, FALSE),
01881 WN_COPY_Tree (addr_wn),
01882 field_id)));
01883 else
01884 if (is_imagpart)
01885 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01886 WN_Unary(OPR_REALPART,
01887 Mtype_complex_to_real (rtype),
01888 WN_CreateIload(OPR_ILOAD, rtype, desc,
01889 component_offset,
01890 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01891 Make_Pointer_Type(hi_ty_idx, FALSE),
01892 WN_COPY_Tree (addr_wn),
01893 field_id)),
01894 rhs_wn);
01895 }
01896 else {
01897 if (is_realpart)
01898 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01899 rhs_wn,
01900 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0));
01901 else
01902 if (is_imagpart)
01903 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01904 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0),
01905 rhs_wn);
01906 }
01907
01908 if (assign_code == PREINCREMENT_EXPR ||
01909 assign_code == PREDECREMENT_EXPR) {
01910 wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
01911 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01912 Make_Pointer_Type(hi_ty_idx, FALSE),
01913 WN_COPY_Tree (addr_wn),
01914 field_id);
01915 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01916 rtype, wn, rhs_wn);
01917 result_wn = rhs_wn;
01918 }
01919 else if (assign_code == POSTINCREMENT_EXPR ||
01920 assign_code == POSTDECREMENT_EXPR) {
01921 result_wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
01922 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01923 Make_Pointer_Type(hi_ty_idx, FALSE),
01924 WN_COPY_Tree (addr_wn),
01925 field_id);
01926 }
01927 else result_wn = rhs_wn;
01928
01929
01930 if (need_result && rtype != MTYPE_M &&
01931 (volt ||
01932 assign_code == POSTINCREMENT_EXPR ||
01933 assign_code == POSTDECREMENT_EXPR)) {
01934 result_in_temp = TRUE;
01935 result_preg_st = MTYPE_To_PREG(rtype);
01936 result_preg = Create_Preg(rtype, NULL);
01937 wn = WN_Stid(rtype, result_preg, result_preg_st, desc_ty_idx, result_wn,
01938 0);
01939 WFE_Stmt_Append (wn, Get_Srcpos());;
01940 result_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
01941 }
01942
01943 if (assign_code == POSTINCREMENT_EXPR ||
01944 assign_code == POSTDECREMENT_EXPR) {
01945 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01946 rtype, result_wn, rhs_wn);
01947 }
01948 else rhs_wn = result_wn;
01949
01950
01951 }
01952
01953
01954 if (!WFE_Keep_Zero_Length_Structs &&
01955 desc == MTYPE_M &&
01956 TY_size (hi_ty_idx) == 0) {
01957
01958 if (WN_has_side_effects (addr_wn)) {
01959 wn = WN_CreateEval (addr_wn);
01960 WFE_Stmt_Append (wn, Get_Srcpos());
01961 }
01962 wn = NULL;
01963 }
01964 else {
01965 wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset,
01966 Make_Pointer_Type (hi_ty_idx, FALSE),
01967 rhs_wn, addr_wn, field_id);
01968 #ifdef TARG_SL
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980 tree post_inc_dec = TREE_OPERAND(lhs, 0);
01981 tree var_node = TREE_OPERAND(post_inc_dec, 0);
01982 if( TREE_CODE(post_inc_dec) == POSTINCREMENT_EXPR ||
01983 TREE_CODE(post_inc_dec) == POSTDECREMENT_EXPR ){
01984
01985
01986
01987
01988 Is_True( var_node && ( TREE_CODE(var_node)==VAR_DECL
01989 || TREE_CODE(var_node)==PARM_DECL
01990 || TREE_CODE(var_node)==COMPONENT_REF
01991 || TREE_CODE(var_node)==INDIRECT_REF ),
01992 ("Post{Inc|Dec} should be on variables or parameters, or component of struct"));
01993
01994
01995
01996
01997
01998 if( TREE_CODE(var_node) == INDIRECT_REF ) {
01999 if( TREE_CODE(var_node) != PARM_DECL &&
02000 TREE_CODE(var_node) != VAR_DECL ) {
02001 DevWarn(" When handling *p++ consistent with gcc, there is *p++, p is a pointer to non-var-decl, non-parm-decl, NOT HANDLED yet!" );
02002 } else
02003 var_node = TREE_OPERAND(var_node, 0);
02004 }
02005
02006 sameness = FALSE;
02007
02008
02009
02010
02011 if( DECL_NAME(var_node) &&
02012 IDENTIFIER_POINTER(DECL_NAME(var_node)) )
02013 sameness |= Same_Var( IDENTIFIER_POINTER(DECL_NAME(var_node)), rhs );
02014 if( sameness ) {
02015 DevWarn("ANSI C undefined behavior: *p++=...,p,.. or *p--=...,p,...");
02016 WFE_Stmt_Prepend_Last(wn, Get_Srcpos());
02017 }
02018 else
02019 WFE_Stmt_Append(wn, Get_Srcpos());
02020 } else
02021 WFE_Stmt_Append(wn, Get_Srcpos());
02022 #else
02023 WFE_Stmt_Append(wn, Get_Srcpos());
02024 #endif
02025 #if defined(TARG_SL)
02026 if (need_append) {
02027 WN *ldid_wn;
02028 if (! result_in_temp)
02029 ldid_wn = WN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
02030 field_id != 0 ? hi_ty_idx : desc_ty_idx,
02031 Make_Pointer_Type (hi_ty_idx, FALSE),
02032 WN_COPY_Tree (addr_wn),
02033 field_id);
02034 else
02035 ldid_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02036
02037 WFE_Stmt_Append_Extend_Intrinsic(wn, ldid_wn, Get_Srcpos());
02038 }
02039 #endif
02040
02041 if (need_result) {
02042 if (! result_in_temp)
02043 wn = WN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
02044 field_id != 0 ? hi_ty_idx : desc_ty_idx,
02045 Make_Pointer_Type (hi_ty_idx, FALSE),
02046 WN_COPY_Tree (addr_wn),
02047 field_id);
02048 else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02049 if (is_realpart)
02050 wn = WN_Unary (OPR_REALPART, Mtype_complex_to_real (rtype), wn);
02051 else
02052 if (is_imagpart)
02053 wn = WN_Unary (OPR_IMAGPART, Mtype_complex_to_real (rtype), wn);
02054 }
02055 else wn = NULL;
02056 }
02057 }
02058 else if (code == ARRAY_REF) {
02059 TY_IDX elem_ty_idx;
02060
02061 WN *addr_wn = WFE_Array_Expr(lhs, &elem_ty_idx, 0, 0, 0);
02062 if (TY_is_volatile(elem_ty_idx))
02063 volt = TRUE;
02064 TY_IDX desc_ty_idx = component_ty_idx;
02065 if (desc_ty_idx == 0)
02066 desc_ty_idx = Get_TY (TREE_TYPE(lhs));
02067 if (TY_is_volatile(desc_ty_idx)) {
02068 Clear_TY_is_volatile(desc_ty_idx);
02069 volt = TRUE;
02070 }
02071 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
02072 ("WFE_Lhs_Of_Modify_Expr: field id for bit-field exceeds limit"));
02073 if (WN_has_side_effects(addr_wn) &&
02074 (need_result ||
02075 assign_code == PREINCREMENT_EXPR ||
02076 assign_code == PREDECREMENT_EXPR ||
02077 assign_code == POSTINCREMENT_EXPR ||
02078 assign_code == POSTDECREMENT_EXPR)) {
02079 ST *preg_st;
02080 PREG_NUM preg;
02081 TY_IDX address_ty_idx = Make_Pointer_Type(elem_ty_idx, FALSE);
02082 preg_st = MTYPE_To_PREG(Pointer_Mtype);
02083 preg = Create_Preg (Pointer_Mtype, NULL);
02084 wn = WN_Stid (Pointer_Mtype, preg, preg_st, address_ty_idx, addr_wn);
02085 WFE_Set_ST_Addr_Saved (addr_wn);
02086 WFE_Stmt_Append (wn, Get_Srcpos());
02087 addr_wn = WN_Ldid (Pointer_Mtype, preg, preg_st, address_ty_idx);
02088 }
02089
02090 TYPE_ID rtype = Widen_Mtype(TY_mtype(desc_ty_idx));
02091 TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
02092
02093 if (rhs_wn == NULL) {
02094
02095
02096
02097 ST *rhs_st;
02098
02099
02100 rhs_st = MTYPE_To_PREG(desc);
02101 rhs_wn = WN_CreateLdid (OPR_LDID, rtype, desc, rhs_preg_num, rhs_st,
02102 desc_ty_idx, 0);
02103 }
02104 else {
02105 WN *result_wn;
02106
02107 if (assign_code == MODIFY_EXPR) {
02108 if (is_realpart)
02109 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02110 rhs_wn,
02111 WN_Unary(OPR_IMAGPART,
02112 Mtype_complex_to_real (rtype),
02113 WN_CreateIload(OPR_ILOAD, rtype, desc,
02114 component_offset,
02115 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02116 Make_Pointer_Type(elem_ty_idx, FALSE),
02117 WN_COPY_Tree (addr_wn),
02118 field_id)));
02119 else
02120 if (is_imagpart)
02121 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02122 WN_Unary(OPR_REALPART,
02123 Mtype_complex_to_real (rtype),
02124 WN_CreateIload(OPR_ILOAD, rtype, desc,
02125 component_offset,
02126 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02127 Make_Pointer_Type(elem_ty_idx, FALSE),
02128 WN_COPY_Tree (addr_wn),
02129 field_id)),
02130 rhs_wn);
02131 }
02132 else {
02133 if (is_realpart)
02134 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02135 rhs_wn,
02136 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0));
02137 else
02138 if (is_imagpart)
02139 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02140 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0),
02141 rhs_wn);
02142 }
02143
02144 if (assign_code == PREINCREMENT_EXPR ||
02145 assign_code == PREDECREMENT_EXPR) {
02146 wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02147 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02148 Make_Pointer_Type(elem_ty_idx, FALSE),
02149 WN_COPY_Tree (addr_wn),
02150 field_id);
02151 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
02152 rtype, wn, rhs_wn);
02153 result_wn = rhs_wn;
02154 }
02155 else if (assign_code == POSTINCREMENT_EXPR ||
02156 assign_code == POSTDECREMENT_EXPR) {
02157 result_wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02158 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02159 Make_Pointer_Type(elem_ty_idx, FALSE),
02160 WN_COPY_Tree (addr_wn),
02161 field_id);
02162 }
02163 else result_wn = rhs_wn;
02164
02165
02166 if (need_result && rtype != MTYPE_M &&
02167 (volt ||
02168 assign_code == POSTINCREMENT_EXPR ||
02169 assign_code == POSTDECREMENT_EXPR)) {
02170 result_in_temp = TRUE;
02171 result_preg_st = MTYPE_To_PREG(rtype);
02172 result_preg = Create_Preg(rtype, NULL);
02173 wn = WN_Stid(rtype, result_preg, result_preg_st, desc_ty_idx, result_wn,
02174 0);
02175 WFE_Stmt_Append (wn, Get_Srcpos());;
02176 result_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02177 }
02178
02179 if (assign_code == POSTINCREMENT_EXPR ||
02180 assign_code == POSTDECREMENT_EXPR) {
02181 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
02182 rtype, result_wn, rhs_wn);
02183 }
02184 else rhs_wn = result_wn;
02185
02186
02187 }
02188
02189
02190 if (!WFE_Keep_Zero_Length_Structs &&
02191 desc == MTYPE_M &&
02192 TY_size (elem_ty_idx) == 0) {
02193
02194 if (WN_has_side_effects (addr_wn)) {
02195 wn = WN_CreateEval (addr_wn);
02196 WFE_Stmt_Append (wn, Get_Srcpos());
02197 }
02198 wn = NULL;
02199 }
02200 else {
02201 wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset,
02202 Make_Pointer_Type(elem_ty_idx, FALSE), rhs_wn,
02203 addr_wn, field_id);
02204 WFE_Stmt_Append(wn, Get_Srcpos());
02205 #ifdef TARG_SL
02206
02207
02208
02209 if(Mark_LDA_Vbuf_Offset(addr_wn, INTRN_VBUF_OFFSET))
02210 WN_Set_is_internal_mem_ofst(wn);
02211
02212 if (need_append) {
02213 WN *iload;
02214 if (!result_in_temp)
02215 iload = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02216 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02217 Make_Pointer_Type (elem_ty_idx, FALSE),
02218 WN_COPY_Tree (addr_wn),
02219 field_id);
02220 else
02221 iload = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02222 WFE_Stmt_Append_Extend_Intrinsic(wn, iload, Get_Srcpos());
02223 }
02224 #endif
02225 if (need_result) {
02226 if (! result_in_temp)
02227 wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02228 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02229 Make_Pointer_Type (elem_ty_idx, FALSE),
02230 WN_COPY_Tree (addr_wn),
02231 field_id);
02232 else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02233 if (is_realpart)
02234 wn = WN_Unary (OPR_REALPART, Mtype_complex_to_real (rtype), wn);
02235 else
02236 if (is_imagpart)
02237 wn = WN_Unary (OPR_IMAGPART, Mtype_complex_to_real (rtype), wn);
02238 }
02239 else wn = NULL;
02240 }
02241 }
02242 #ifdef KEY
02243 else if (code == COMPOUND_LITERAL_EXPR) {
02244 tree var = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
02245 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(var));
02246 #ifdef TARG_SL
02247 wn = WFE_Lhs_Of_Modify_Expr (assign_code, var, NULL, need_result,
02248 #else
02249 wn = WFE_Lhs_Of_Modify_Expr (assign_code, var, need_result,
02250 #endif
02251 ty_idx0, component_offset, field_id,
02252 is_bit_field, rhs_wn, rhs_preg_num,
02253 is_realpart, is_imagpart);
02254 }
02255 else if (code == RESULT_DECL) {
02256
02257
02258 Fail_FmtAssertion ("Implement RESULT_DECL as lhs of MODIFY_EXPR");
02259 }
02260 #endif // KEY
02261 else Fail_FmtAssertion ("WFE_Lhs_Of_Modify_Expr: unhandled tree node in LHS of MODIFY_EXPR");
02262 return wn;
02263 }
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290 WN*
02291 WFE_Expand_Expr_With_Sequence_Point (tree exp, TYPE_ID mtype)
02292 {
02293 WN *wn;
02294
02295 if (mtype == MTYPE_V)
02296 wn = WFE_Expand_Expr (exp, FALSE);
02297
02298 else {
02299
02300 WN *comma_block = WN_CreateBlock ();
02301
02302 WFE_Stmt_Push (comma_block, wfe_stmk_comma, Get_Srcpos ());
02303 wn = WFE_Expand_Expr (exp);
02304 WFE_Stmt_Pop (wfe_stmk_comma);
02305 if (WN_first (comma_block)) {
02306 if (wn)
02307 wn = WN_CreateComma (OPR_COMMA, Mtype_comparison (mtype), MTYPE_V,
02308 comma_block, wn);
02309 else {
02310 DevWarn("WFE_Expand_Expr_With_Sequence_Point: no wn for COMMA");
02311 WFE_Stmt_Append (comma_block, Get_Srcpos());
02312 }
02313 }
02314 else
02315 WN_Delete (comma_block);
02316 }
02317
02318 return wn;
02319 }
02320
02321 static void
02322 emit_barrier (bool type, tree list, INT32 k)
02323 {
02324 INT32 i;
02325 WN *wn = WN_CreateBarrier (type, k);
02326
02327 for (i = 0; i < k; i++) {
02328 tree exp = TREE_VALUE (list);
02329 ST *st = Get_ST (exp);
02330 WN_kid (wn, i) = WN_Lda (Pointer_Mtype, 0, st,
02331 Make_Pointer_Type (ST_type (st), FALSE));
02332 list = TREE_CHAIN (list);
02333 }
02334
02335 WFE_Stmt_Append (wn, Get_Srcpos());
02336 }
02337
02338 static WN *
02339 emit_builtin_lock_test_and_set (tree exp, INT32 k)
02340 {
02341 WN *wn;
02342 WN *arg_wn;
02343 WN *ikids [2];
02344 TYPE_ID obj_mtype;
02345 TY_IDX arg_ty_idx;
02346 TYPE_ID arg_mtype;
02347 tree list = TREE_OPERAND (exp, 1);
02348 OPCODE opc;
02349 INTRINSIC iopc;
02350
02351 obj_mtype = TY_mtype (TY_pointed (Get_TY(TREE_TYPE(TREE_VALUE(list)))));
02352 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02353 arg_mtype = TY_mtype (arg_ty_idx);
02354 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02355 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02356 ikids [0] = arg_wn;
02357 list = TREE_CHAIN (list);
02358 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02359 arg_mtype = TY_mtype (arg_ty_idx);
02360 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02361 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02362 ikids [1] = arg_wn;
02363 list = TREE_CHAIN (list);
02364
02365 if (obj_mtype == MTYPE_I4) {
02366 opc = OPC_I4INTRINSIC_CALL;
02367 iopc = INTRN_LOCK_TEST_AND_SET_I4;
02368 }
02369 else
02370 if (obj_mtype == MTYPE_U4) {
02371 opc = OPC_U4INTRINSIC_CALL;
02372 iopc = INTRN_LOCK_TEST_AND_SET_I4;
02373 }
02374 else
02375 if (obj_mtype == MTYPE_I8) {
02376 opc = OPC_I8INTRINSIC_CALL;
02377 iopc = INTRN_LOCK_TEST_AND_SET_I8;
02378 }
02379 else
02380 if (obj_mtype == MTYPE_U8) {
02381 opc = OPC_U8INTRINSIC_CALL;
02382 iopc = INTRN_LOCK_TEST_AND_SET_I8;
02383 }
02384 else {
02385 Fail_FmtAssertion ("unknown object type in __builtin_lock_test_and_set");
02386 opc = OPCODE_UNKNOWN;
02387 iopc = INTRINSIC_NONE;
02388 }
02389
02390 wn = WN_Create_Intrinsic (opc, iopc, 2, ikids);
02391 WFE_Stmt_Append (wn, Get_Srcpos());
02392
02393 ST *preg_st = MTYPE_To_PREG(obj_mtype);
02394 TY_IDX preg_ty_idx = Be_Type_Tbl(obj_mtype);
02395 PREG_NUM preg = Create_Preg (obj_mtype, NULL);
02396
02397 wn = WN_Ldid (obj_mtype, -1, Return_Val_Preg, preg_ty_idx);
02398 wn = WN_Stid (obj_mtype, preg, preg_st, preg_ty_idx, wn),
02399 WFE_Stmt_Append (wn, Get_Srcpos());
02400
02401 emit_barrier (FALSE, list, k);
02402
02403 wn = WN_Ldid (obj_mtype, preg, preg_st, preg_ty_idx);
02404
02405 return wn;
02406 }
02407
02408 static void
02409 emit_builtin_lock_release (tree exp, INT32 k)
02410 {
02411 WN *wn;
02412 WN *arg_wn;
02413 WN *ikids [1];
02414 TYPE_ID obj_mtype;
02415 TY_IDX arg_ty_idx;
02416 TYPE_ID arg_mtype;
02417 tree list = TREE_OPERAND (exp, 1);
02418 OPCODE opc;
02419 INTRINSIC iopc;
02420
02421 obj_mtype = TY_mtype (TY_pointed (Get_TY(TREE_TYPE(TREE_VALUE(list)))));
02422 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02423 arg_mtype = TY_mtype (arg_ty_idx);
02424 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02425 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02426 ikids [0] = arg_wn;
02427 list = TREE_CHAIN (list);
02428
02429 emit_barrier (TRUE, list, k);
02430
02431 opc = OPC_VINTRINSIC_CALL;
02432 if (obj_mtype == MTYPE_I4)
02433 iopc = INTRN_LOCK_RELEASE_I4;
02434 else
02435 if (obj_mtype == MTYPE_U4)
02436 iopc = INTRN_LOCK_RELEASE_I4;
02437 else
02438 if (obj_mtype == MTYPE_I8)
02439 iopc = INTRN_LOCK_RELEASE_I8;
02440 else
02441 if (obj_mtype == MTYPE_U8)
02442 iopc = INTRN_LOCK_RELEASE_I8;
02443 else {
02444 Fail_FmtAssertion ("unknown object type in __builtin_lock_test_and_set");
02445 opc = OPCODE_UNKNOWN;
02446 iopc = INTRINSIC_NONE;
02447 }
02448
02449 wn = WN_Create_Intrinsic (opc, iopc, 1, ikids);
02450 WFE_Stmt_Append (wn, Get_Srcpos());
02451 }
02452
02453 static WN *
02454 emit_builtin_compare_and_swap (tree exp, INT32 k)
02455 {
02456 WN *wn;
02457 WN *arg_wn;
02458 WN *ikids [3];
02459 TYPE_ID obj_mtype;
02460 TY_IDX arg_ty_idx;
02461 TYPE_ID arg_mtype;
02462 tree list = TREE_OPERAND (exp, 1);
02463 OPCODE opc;
02464 INTRINSIC iopc;
02465
02466 obj_mtype = TY_mtype (TY_pointed (Get_TY(TREE_TYPE(TREE_VALUE(list)))));
02467 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02468 arg_mtype = TY_mtype (arg_ty_idx);
02469 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02470 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02471 ikids [0] = arg_wn;
02472 list = TREE_CHAIN (list);
02473 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02474 arg_mtype = TY_mtype (arg_ty_idx);
02475 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02476 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02477 ikids [1] = arg_wn;
02478 list = TREE_CHAIN (list);
02479 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02480 arg_mtype = TY_mtype (arg_ty_idx);
02481 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02482 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02483 ikids [2] = arg_wn;
02484 list = TREE_CHAIN (list);
02485
02486 emit_barrier (TRUE, list, k);
02487
02488 opc = OPC_I4INTRINSIC_CALL;
02489 if (obj_mtype == MTYPE_I4)
02490 iopc = INTRN_COMPARE_AND_SWAP_I4;
02491 else
02492 if (obj_mtype == MTYPE_U4)
02493 iopc = INTRN_COMPARE_AND_SWAP_I4;
02494 else
02495 if (obj_mtype == MTYPE_I8)
02496 iopc = INTRN_COMPARE_AND_SWAP_I8;
02497 else
02498 if (obj_mtype == MTYPE_U8)
02499 iopc = INTRN_COMPARE_AND_SWAP_I8;
02500 else {
02501 Fail_FmtAssertion ("unknown object type in __builtin_lock_test_and_set");
02502 opc = OPCODE_UNKNOWN;
02503 iopc = INTRINSIC_NONE;
02504 }
02505
02506 wn = WN_Create_Intrinsic (opc, iopc, 3, ikids);
02507 WFE_Stmt_Append (wn, Get_Srcpos());
02508
02509 ST *preg_st = MTYPE_To_PREG(MTYPE_I4);
02510 TY_IDX preg_ty_idx = Be_Type_Tbl(MTYPE_I4);
02511 PREG_NUM preg = Create_Preg (MTYPE_I4, NULL);
02512
02513 wn = WN_Ldid (MTYPE_I4, -1, Return_Val_Preg, preg_ty_idx);
02514 wn = WN_Stid (MTYPE_I4, preg, preg_st, preg_ty_idx, wn),
02515 WFE_Stmt_Append (wn, Get_Srcpos());
02516
02517 emit_barrier (FALSE, list, k);
02518
02519 wn = WN_Ldid (MTYPE_I4, preg, preg_st, preg_ty_idx);
02520
02521 return wn;
02522 }
02523
02524
02525 static void
02526 emit_builtin_synchronize (tree exp, INT32 k)
02527 {
02528 WN *wn;
02529 tree list = TREE_OPERAND (exp, 1);
02530 emit_barrier (TRUE, list, k);
02531 wn = WN_Create_Intrinsic (OPC_VINTRINSIC_CALL, INTRN_SYNCHRONIZE, 0, NULL);
02532 WFE_Stmt_Append (wn, Get_Srcpos());
02533 emit_barrier (FALSE, list, k);
02534 }
02535
02536 #ifdef TARG_NVISA
02537 static void
02538 emit_builtin_brkpt (void)
02539 {
02540 WN *wn = WN_Create_Intrinsic (OPC_VINTRINSIC_CALL, INTRN_BRKPT, 0, NULL);
02541 WFE_Stmt_Append (wn, Get_Srcpos());
02542 }
02543 static void
02544 emit_builtin_trap (void)
02545 {
02546 WN *wn = WN_Create_Intrinsic (OPC_VINTRINSIC_CALL, INTRN_TRAP, 0, NULL);
02547 WFE_Stmt_Append (wn, Get_Srcpos());
02548 }
02549
02550 static WN*
02551 emit_builtin_clock (void)
02552 {
02553 WN *wn = WN_Create_Intrinsic (OPC_I4INTRINSIC_CALL, INTRN_CLOCK, 0, NULL);
02554 WFE_Stmt_Append (wn, Get_Srcpos());
02555
02556 ST *preg_st = MTYPE_To_PREG(MTYPE_I4);
02557 TY_IDX preg_ty_idx = Be_Type_Tbl(MTYPE_I4);
02558 PREG_NUM preg = Create_Preg (MTYPE_I4, NULL);
02559
02560 wn = WN_Ldid (MTYPE_I4, -1, Return_Val_Preg, preg_ty_idx);
02561 wn = WN_Stid (MTYPE_I4, preg, preg_st, preg_ty_idx, wn),
02562 WFE_Stmt_Append (wn, Get_Srcpos());
02563
02564 wn = WN_Ldid (MTYPE_I4, preg, preg_st, preg_ty_idx);
02565 return wn;
02566 }
02567
02568 static WN*
02569 emit_builtin_atomic (tree exp, UINT nkids, TYPE_ID mtype, INTRINSIC iopc)
02570 {
02571 WN *wn;
02572 WN *arg_wn;
02573 WN *ikids [3];
02574 TY_IDX arg_ty_idx;
02575 TYPE_ID arg_mtype;
02576 tree list = TREE_OPERAND (exp, 1);
02577 OPCODE opc;
02578
02579 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02580 arg_mtype = TY_mtype (arg_ty_idx);
02581 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02582 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02583 ikids [0] = arg_wn;
02584 list = TREE_CHAIN (list);
02585 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02586 arg_mtype = TY_mtype (arg_ty_idx);
02587 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02588 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02589 ikids [1] = arg_wn;
02590 if (nkids == 3) {
02591 list = TREE_CHAIN (list);
02592 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02593 arg_mtype = TY_mtype (arg_ty_idx);
02594 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02595 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02596 ikids [2] = arg_wn;
02597 }
02598
02599 opc = OPCODE_make_op(OPR_INTRINSIC_CALL,mtype,MTYPE_V);
02600 wn = WN_Create_Intrinsic (opc, iopc, nkids, ikids);
02601 WFE_Stmt_Append (wn, Get_Srcpos());
02602
02603 ST *preg_st = MTYPE_To_PREG(mtype);
02604 TY_IDX preg_ty_idx = ST_type(preg_st);
02605 PREG_NUM preg = Create_Preg (mtype, NULL);
02606
02607 wn = WN_Ldid (mtype, -1, Return_Val_Preg, preg_ty_idx);
02608 wn = WN_Stid (mtype, preg, preg_st, preg_ty_idx, wn),
02609 WFE_Stmt_Append (wn, Get_Srcpos());
02610
02611 wn = WN_Ldid (mtype, preg, preg_st, preg_ty_idx);
02612 return wn;
02613 }
02614
02615 static WN*
02616 emit_builtin_vote (tree exp, INTRINSIC iopc)
02617 {
02618
02619
02620 OPCODE opc = OPCODE_make_op (OPR_INTRINSIC_CALL, MTYPE_I4, MTYPE_V);
02621 tree arg = TREE_VALUE (TREE_OPERAND (exp, 1));
02622 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE (arg));
02623 TYPE_ID arg_mtype = TY_mtype (arg_ty_idx);
02624 WN *wn, *arg_wn, *ikids [1];
02625
02626 arg_wn = WFE_Expand_Expr (arg);
02627 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02628 ikids [0] = arg_wn;
02629
02630 wn = WN_Create_Intrinsic (opc, iopc, 1, ikids);
02631 WFE_Stmt_Append (wn, Get_Srcpos());
02632
02633 ST *preg_st = MTYPE_To_PREG(MTYPE_I4);
02634 TY_IDX preg_ty_idx = ST_type(preg_st);
02635 PREG_NUM preg = Create_Preg (MTYPE_I4, NULL);
02636
02637 wn = WN_Ldid (MTYPE_I4, -1, Return_Val_Preg, preg_ty_idx);
02638 wn = WN_Stid (MTYPE_I4, preg, preg_st, preg_ty_idx, wn);
02639 WFE_Stmt_Append (wn, Get_Srcpos());
02640
02641 wn = WN_Ldid (MTYPE_I4, preg, preg_st, preg_ty_idx);
02642
02643 return wn;
02644 }
02645
02646
02647
02648 static WN*
02649 create_asm_output_constraints (INT num_outputs, TYPE_ID mtype)
02650 {
02651 WN *output_constraint_block = WN_CreateBlock ();
02652 UINT opnd_num;
02653 for (opnd_num = 0; opnd_num < num_outputs; ++opnd_num) {
02654 ST *preg_st = MTYPE_To_PREG(mtype);
02655 ST *constraint_st = New_ST(CURRENT_SYMTAB);
02656 ST_Init(constraint_st,
02657 Save_Str(MTYPE_is_float(mtype) ? "=f" : "=r"),
02658 CLASS_NAME, SCLASS_UNKNOWN, EXPORT_LOCAL, (TY_IDX) 0);
02659
02660 WN *constraint_pragma =
02661 WN_CreatePragma (WN_PRAGMA_ASM_CONSTRAINT,
02662 (ST_IDX) ST_st_idx(preg_st),
02663 (INT32) ST_st_idx(constraint_st),
02664 asm_neg_preg,
02665 opnd_num);
02666
02667 WN_INSERT_BlockAfter (output_constraint_block,
02668 WN_last (output_constraint_block),
02669 constraint_pragma);
02670 --asm_neg_preg;
02671 }
02672 return output_constraint_block;
02673 }
02674
02675
02676
02677 static WN*
02678 emit_builtin_texfetch (tree exp, char *name, TYPE_ID rtype, TYPE_ID ctype)
02679 {
02680
02681
02682
02683
02684 tree list = TREE_OPERAND (exp, 1);
02685 WN *texture_arg = WFE_Expand_Expr (TREE_VALUE (list));
02686 list = TREE_CHAIN (list);
02687 WN *coord_arg = WFE_Expand_Expr (TREE_VALUE (list));
02688
02689 char buf[80];
02690 strcpy(buf, name);
02691 strcat(buf, " {%0,%1,%2,%3},[%4,{%5,%6,%7,%8}];");
02692 WN *asm_wn = WN_CreateAsm_Stmt (7 , buf);
02693
02694
02695 WN *clobber_block = WN_CreateBlock ();
02696 WN_kid0(asm_wn) = clobber_block;
02697
02698 UINT opnd_num = 4;
02699 WN_kid1(asm_wn) = create_asm_output_constraints (opnd_num, rtype);
02700
02701
02702 WN_kid (asm_wn, 2) =
02703 WN_CreateAsm_Input ("m", opnd_num, texture_arg);
02704 ++opnd_num;
02705
02706
02707 INT kidnum = 3;
02708 INT offset = 0;
02709 INT field_id = 1;
02710 for (; opnd_num <= 8; ++opnd_num) {
02711 WN *coordf = WN_CreateLdid (OPR_LDID, ctype, ctype,
02712 offset, WN_st(coord_arg), WN_ty(coord_arg), field_id);
02713 WN_kid (asm_wn, kidnum) =
02714 WN_CreateAsm_Input (
02715 (char*) ((ctype == MTYPE_F4) ? "f" : "r"),
02716 opnd_num, coordf);
02717 offset += 4;
02718 ++field_id;
02719 ++kidnum;
02720 }
02721
02722 return asm_wn;
02723 }
02724
02725
02726 static WN*
02727 emit_builtin_double_to_int2 (tree exp)
02728 {
02729 tree list = TREE_OPERAND (exp, 1);
02730 WN *double_arg = WFE_Expand_Expr (TREE_VALUE (list));
02731
02732 WN *asm_wn = WN_CreateAsm_Stmt (3 , "mov.b64 {%0,%1},%2;");
02733
02734
02735 WN *clobber_block = WN_CreateBlock ();
02736 WN_kid0(asm_wn) = clobber_block;
02737
02738 UINT opnd_num = 2;
02739 WN_kid1(asm_wn) = create_asm_output_constraints (opnd_num, MTYPE_I4);
02740
02741
02742 WN_kid (asm_wn, 2) =
02743 WN_CreateAsm_Input ("f", opnd_num, double_arg);
02744 ++opnd_num;
02745
02746 return asm_wn;
02747 }
02748
02749
02750 static WN*
02751 emit_builtin_int2_to_double (tree exp)
02752 {
02753 tree list = TREE_OPERAND (exp, 1);
02754 WN *int2_arg = WFE_Expand_Expr (TREE_VALUE (list));
02755
02756 WN *asm_wn = WN_CreateAsm_Stmt (4 , "mov.b64 %0,{%1,%2};");
02757
02758
02759 WN *clobber_block = WN_CreateBlock ();
02760 WN_kid0(asm_wn) = clobber_block;
02761
02762 UINT opnd_num = 1;
02763 WN_kid1(asm_wn) = create_asm_output_constraints (opnd_num, MTYPE_F8);
02764
02765
02766 INT kidnum = 2;
02767 INT offset = 0;
02768 INT field_id = 1;
02769 for (; opnd_num <= 2; ++opnd_num) {
02770 WN *int2f = WN_CreateLdid (OPR_LDID, MTYPE_I4, MTYPE_I4,
02771 offset, WN_st(int2_arg), WN_ty(int2_arg), field_id);
02772 WN_kid (asm_wn, kidnum) =
02773 WN_CreateAsm_Input ("r", opnd_num, int2f);
02774 offset += 4;
02775 ++field_id;
02776 ++kidnum;
02777 }
02778
02779 return asm_wn;
02780 }
02781 #endif
02782
02783 static char *
02784 get_string_pointer (WN *wn)
02785 {
02786 char *ptr = NULL;
02787
02788 if (WN_operator (wn) == OPR_LDA) {
02789 ST *st = WN_st (wn);
02790 if (ST_class (st) == CLASS_CONST) {
02791 TCON tcon = Tcon_Table [ST_tcon (st)];
02792 if (TCON_ty (tcon) == MTYPE_STRING)
02793 ptr = ((char *) Targ_String_Address (tcon)) + WN_offset (wn);
02794 }
02795 }
02796
02797 return ptr;
02798 }
02799
02800 #ifdef TARG_X8664
02801
02802
02803
02804
02805
02806 static WN *WFE_x8664_va_arg(WN *ap_wn, BOOL isfloat, TY_IDX ty_idx, BOOL twice)
02807 {
02808
02809 WN *wn0 = WN_Iload(MTYPE_I4, !isfloat ? 0 : 4, MTYPE_To_TY(MTYPE_I4),
02810 WN_CopyNode(ap_wn));
02811 WN *wn1 = WN_Intconst(MTYPE_I4, (!isfloat ? 48 : 176) - (twice ? 8 : 0));
02812 WN *wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
02813 LABEL_IDX lab1;
02814 New_LABEL (CURRENT_SYMTAB, lab1);
02815 WN *lab1_wn = WN_CreateLabel ((ST_IDX) 0, lab1, 0, NULL);
02816 wn = WN_CreateTruebr(lab1, wn);
02817 WFE_Stmt_Append (wn, Get_Srcpos ());
02818
02819 ST *arg_temp_st = Gen_Temp_Symbol(Make_Pointer_Type(ty_idx), ".va_arg");
02820
02821 #ifdef KEY
02822 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, arg_temp_st);
02823 #endif
02824
02825 wn0 = WN_Iload(MTYPE_I4, !isfloat ? 0 : 4, MTYPE_To_TY(MTYPE_I4),
02826 WN_CopyNode(ap_wn));
02827 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
02828 WN_CopyNode(ap_wn));
02829 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
02830 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn);
02831 WFE_Stmt_Append (wn, Get_Srcpos ());
02832
02833
02834 wn0 = WN_Iload(MTYPE_I4, !isfloat ? 0 : 4, MTYPE_To_TY(MTYPE_I4),
02835 WN_CopyNode(ap_wn));
02836 wn1 = WN_Intconst(MTYPE_I4, (!isfloat ? 8 : 16) * ((INT)twice+1));
02837 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
02838 wn = WN_Istore(MTYPE_I4, !isfloat ? 0 : 4,
02839 Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
02840 WN_CopyNode(ap_wn), wn);
02841 WFE_Stmt_Append (wn, Get_Srcpos ());
02842
02843
02844 LABEL_IDX lab2;
02845 New_LABEL (CURRENT_SYMTAB, lab2);
02846 WN *lab2_wn = WN_CreateLabel ((ST_IDX) 0, lab2, 0, NULL);
02847 wn = WN_CreateGoto(lab2);
02848 WFE_Stmt_Append (wn, Get_Srcpos ());
02849
02850 WFE_Stmt_Append (lab1_wn, Get_Srcpos ());
02851
02852
02853 wn0 = WN_Iload(Pointer_Mtype, 8, Make_Pointer_Type(ty_idx),
02854 WN_CopyNode(ap_wn));
02855 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn0);
02856 WFE_Stmt_Append (wn, Get_Srcpos ());
02857
02858
02859 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
02860 WN_CopyNode(ap_wn));
02861 wn1 = WN_Intconst(MTYPE_U8, twice ? 16 : 8);
02862 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
02863 wn = WN_Istore(Pointer_Mtype, 8,Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
02864 WN_CopyNode(ap_wn), wn);
02865 WFE_Stmt_Append (wn, Get_Srcpos ());
02866
02867 WFE_Stmt_Append (lab2_wn, Get_Srcpos ());
02868
02869 return WN_Ldid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx));
02870 }
02871
02872
02873
02874
02875
02876
02877 static WN *WFE_x8664_va_arg_2_mixed(WN *ap_wn, BOOL isfloat0, BOOL isfloat1,
02878 TY_IDX ty_idx)
02879 {
02880
02881 WN *wn0 = WN_Iload(MTYPE_I4, 0, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02882 WN *wn1 = WN_Intconst(MTYPE_I4, 48);
02883 WN *wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
02884 LABEL_IDX lab1;
02885 New_LABEL (CURRENT_SYMTAB, lab1);
02886 WN *lab1_wn = WN_CreateLabel ((ST_IDX) 0, lab1, 0, NULL);
02887 wn = WN_CreateTruebr(lab1, wn);
02888 WFE_Stmt_Append (wn, Get_Srcpos ());
02889
02890 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02891 wn1 = WN_Intconst(MTYPE_I4, 176);
02892 wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
02893 wn = WN_CreateTruebr(lab1, wn);
02894 WFE_Stmt_Append (wn, Get_Srcpos ());
02895
02896
02897 ST *struct_temp_st = Gen_Temp_Symbol(ty_idx, ".va_arg_struct");
02898
02899 #ifdef KEY
02900 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, struct_temp_st);
02901 #endif
02902
02903
02904 wn0 = WN_Iload(MTYPE_I4, 0, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02905 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
02906 WN_CopyNode(ap_wn));
02907 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
02908 wn = WN_Iload(MTYPE_I8, 0, MTYPE_To_TY(MTYPE_I8), wn);
02909 wn = WN_Stid(MTYPE_I8, isfloat0 ? 8 : 0, struct_temp_st,
02910 MTYPE_To_TY(MTYPE_I8), wn);
02911 WFE_Stmt_Append (wn, Get_Srcpos ());
02912
02913
02914 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02915 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
02916 WN_CopyNode(ap_wn));
02917 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
02918 wn = WN_Iload(MTYPE_F8, 0, MTYPE_To_TY(MTYPE_F8), wn);
02919 wn = WN_Stid(MTYPE_F8, isfloat0 ? 0 : 8, struct_temp_st,
02920 MTYPE_To_TY(MTYPE_F8), wn);
02921 WFE_Stmt_Append (wn, Get_Srcpos ());
02922
02923
02924 wn0 = WN_Iload(MTYPE_I4, 0, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02925 wn1 = WN_Intconst(MTYPE_I4, 8);
02926 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
02927 wn = WN_Istore(MTYPE_I4, 0, Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
02928 WN_CopyNode(ap_wn), wn);
02929 WFE_Stmt_Append (wn, Get_Srcpos ());
02930
02931 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02932 wn1 = WN_Intconst(MTYPE_I4, 16);
02933 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
02934 wn = WN_Istore(MTYPE_I4, 4, Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
02935 WN_CopyNode(ap_wn), wn);
02936 WFE_Stmt_Append (wn, Get_Srcpos ());
02937
02938
02939 ST *arg_temp_st = Gen_Temp_Symbol(Make_Pointer_Type(ty_idx), ".va_arg");
02940 #ifdef KEY
02941 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, arg_temp_st);
02942 #endif
02943 wn = WN_Lda(Pointer_Mtype, 0, struct_temp_st, 0);
02944 Set_ST_addr_saved(struct_temp_st);
02945 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn);
02946 WFE_Stmt_Append (wn, Get_Srcpos ());
02947
02948
02949 LABEL_IDX lab2;
02950 New_LABEL (CURRENT_SYMTAB, lab2);
02951 WN *lab2_wn = WN_CreateLabel ((ST_IDX) 0, lab2, 0, NULL);
02952 wn = WN_CreateGoto(lab2);
02953 WFE_Stmt_Append (wn, Get_Srcpos ());
02954
02955 WFE_Stmt_Append (lab1_wn, Get_Srcpos ());
02956
02957
02958 wn0 = WN_Iload(Pointer_Mtype, 8, Make_Pointer_Type(ty_idx),
02959 WN_CopyNode(ap_wn));
02960 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn0);
02961 WFE_Stmt_Append (wn, Get_Srcpos ());
02962
02963
02964 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
02965 WN_CopyNode(ap_wn));
02966 wn1 = WN_Intconst(MTYPE_U8, 16);
02967 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
02968 wn = WN_Istore(Pointer_Mtype, 8,Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
02969 WN_CopyNode(ap_wn), wn);
02970 WFE_Stmt_Append (wn, Get_Srcpos ());
02971
02972 WFE_Stmt_Append (lab2_wn, Get_Srcpos ());
02973
02974 return WN_Ldid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx));
02975 }
02976
02977
02978
02979
02980
02981
02982 static WN *WFE_x8664_va_arg_2_float(WN *ap_wn, TY_IDX ty_idx)
02983 {
02984 LABEL_IDX lab1;
02985 New_LABEL (CURRENT_SYMTAB, lab1);
02986 WN *lab1_wn = WN_CreateLabel ((ST_IDX) 0, lab1, 0, NULL);
02987
02988 WN *wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
02989 WN *wn1 = WN_Intconst(MTYPE_I4, 160);
02990 WN *wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
02991 wn = WN_CreateTruebr(lab1, wn);
02992 WFE_Stmt_Append (wn, Get_Srcpos ());
02993
02994
02995 ST *struct_temp_st = Gen_Temp_Symbol(ty_idx, ".va_arg_struct");
02996
02997 #ifdef KEY
02998 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, struct_temp_st);
02999 #endif
03000
03001
03002 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03003 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
03004 WN_CopyNode(ap_wn));
03005 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03006 wn = WN_Iload(MTYPE_F8, 0, MTYPE_To_TY(MTYPE_F8), wn);
03007 wn = WN_Stid(MTYPE_F8, 0, struct_temp_st, MTYPE_To_TY(MTYPE_F8), wn);
03008 WFE_Stmt_Append (wn, Get_Srcpos ());
03009
03010
03011 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03012 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
03013 WN_CopyNode(ap_wn));
03014 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03015 wn = WN_Iload(MTYPE_F8, 16, MTYPE_To_TY(MTYPE_F8), wn);
03016 wn = WN_Stid(MTYPE_F8, 8, struct_temp_st, MTYPE_To_TY(MTYPE_F8), wn);
03017 WFE_Stmt_Append (wn, Get_Srcpos ());
03018
03019
03020 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03021 wn1 = WN_Intconst(MTYPE_I4, 32);
03022 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
03023 wn = WN_Istore(MTYPE_I4, 4, Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
03024 WN_CopyNode(ap_wn), wn);
03025 WFE_Stmt_Append (wn, Get_Srcpos ());
03026
03027
03028 ST *arg_temp_st = Gen_Temp_Symbol(Make_Pointer_Type(ty_idx), ".va_arg");
03029 #ifdef KEY
03030 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, arg_temp_st);
03031 #endif
03032 wn = WN_Lda(Pointer_Mtype, 0, struct_temp_st, 0);
03033 Set_ST_addr_saved(struct_temp_st);
03034 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn);
03035 WFE_Stmt_Append (wn, Get_Srcpos ());
03036
03037
03038 LABEL_IDX lab2;
03039 New_LABEL (CURRENT_SYMTAB, lab2);
03040 WN *lab2_wn = WN_CreateLabel ((ST_IDX) 0, lab2, 0, NULL);
03041 wn = WN_CreateGoto(lab2);
03042 WFE_Stmt_Append (wn, Get_Srcpos ());
03043
03044 WFE_Stmt_Append (lab1_wn, Get_Srcpos ());
03045
03046
03047 wn0 = WN_Iload(Pointer_Mtype, 8, Make_Pointer_Type(ty_idx),
03048 WN_CopyNode(ap_wn));
03049 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn0);
03050 WFE_Stmt_Append (wn, Get_Srcpos ());
03051
03052
03053 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
03054 WN_CopyNode(ap_wn));
03055 wn1 = WN_Intconst(MTYPE_U8, 16);
03056 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03057 wn = WN_Istore(Pointer_Mtype, 8,Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
03058 WN_CopyNode(ap_wn), wn);
03059 WFE_Stmt_Append (wn, Get_Srcpos ());
03060
03061 WFE_Stmt_Append (lab2_wn, Get_Srcpos ());
03062
03063 return WN_Ldid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx));
03064 }
03065 #endif
03066
03067 #ifdef KEY
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077 static inline void
03078 traverse_tree_chain (tree op1)
03079 {
03080 if (TREE_CODE (op1) != COMPOUND_STMT && TREE_CHAIN (op1))
03081 {
03082 tree last = TREE_CHAIN (op1);
03083 while (last)
03084 {
03085 WFE_Expand_Expr (last, FALSE);
03086 last = TREE_CHAIN (last);
03087 }
03088 }
03089 }
03090
03091
03092
03093 struct nesting * wfe_nesting_stack;
03094 struct nesting * wfe_cond_stack;
03095 struct nesting * wfe_loop_stack;
03096 struct nesting * wfe_case_stack;
03097 extern "C"
03098 {
03099
03100 extern struct nesting * alloc_nesting (void);
03101
03102 extern void construct_nesting ( struct nesting *,
03103 struct nesting *,
03104 struct nesting *,
03105 LABEL_IDX);
03106
03107 extern void popstack (struct nesting *);
03108 extern LABEL_IDX get_nesting_label (struct nesting *);
03109 extern struct nesting * wfe_get_matching_scope (struct nesting *);
03110
03111
03112 extern void process_omp_stmt (tree);
03113 }
03114
03115 static TY_IDX
03116 get_field_type (TY_IDX struct_type, UINT field_id)
03117 {
03118 Is_True (TY_kind (struct_type) == KIND_STRUCT, ("expecting KIND_STRUCT"));
03119 UINT cur_field_id = 0;
03120 FLD_HANDLE fld = FLD_get_to_field (struct_type, field_id, cur_field_id);
03121 Is_True (! fld.Is_Null(), ("Invalid field id %d for type 0x%x",
03122 field_id, struct_type));
03123 return FLD_type (fld);
03124 }
03125 #endif // KEY
03126
03127 #ifdef TARG_X8664
03128
03129 static WN *
03130 WFE_target_builtins (tree exp, INTRINSIC * iopc, BOOL * intrinsic_op)
03131 {
03132 WN * wn = NULL;
03133
03134
03135 *intrinsic_op = TRUE;
03136
03137 tree func = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
03138 Is_True (TREE_CODE (func) == FUNCTION_DECL && DECL_BUILT_IN (func) &&
03139 DECL_BUILT_IN_CLASS (func) == BUILT_IN_MD, ("Invalid tree node"));
03140
03141 unsigned int ins_code = DECL_FUNCTION_CODE (func);
03142 TYPE_ID res_type = TY_mtype(Get_TY(TREE_TYPE(exp)));
03143 tree t_list = TREE_OPERAND (exp, 1);
03144 WN * arg0 = NULL, * arg1 = NULL;
03145 if (t_list)
03146 {
03147
03148 arg0 = WFE_Expand_Expr (TREE_VALUE (t_list));
03149 if (TREE_CHAIN (t_list))
03150 arg1 = WFE_Expand_Expr (TREE_VALUE (TREE_CHAIN (t_list)));
03151 }
03152
03153 switch (ins_code)
03154 {
03155
03156 case IX86_BUILTIN_PADDB:
03157 case IX86_BUILTIN_PADDW:
03158 case IX86_BUILTIN_PADDD:
03159 case IX86_BUILTIN_ADDPD:
03160 case IX86_BUILTIN_PADDB128:
03161 case IX86_BUILTIN_PADDW128:
03162 case IX86_BUILTIN_PADDD128:
03163 wn = WN_Add (res_type, arg0, arg1);
03164 *intrinsic_op = FALSE;
03165 break;
03166 case IX86_BUILTIN_PSUBB:
03167 case IX86_BUILTIN_PSUBW:
03168 case IX86_BUILTIN_PSUBD:
03169 case IX86_BUILTIN_SUBPD:
03170 case IX86_BUILTIN_PSUBB128:
03171 case IX86_BUILTIN_PSUBW128:
03172 case IX86_BUILTIN_PSUBD128:
03173 wn = WN_Sub (res_type, arg0, arg1);
03174 *intrinsic_op = FALSE;
03175 break;
03176 case IX86_BUILTIN_PAND:
03177 wn = WN_Band (res_type, arg0, arg1);
03178 *intrinsic_op = FALSE;
03179 break;
03180 case IX86_BUILTIN_PANDN:
03181 wn = WN_Band (res_type, WN_Bnot (res_type, arg0), arg1);
03182 *intrinsic_op = FALSE;
03183 break;
03184 case IX86_BUILTIN_POR:
03185 wn = WN_Bior (res_type, arg0, arg1);
03186 *intrinsic_op = FALSE;
03187 break;
03188 case IX86_BUILTIN_PXOR:
03189 wn = WN_Bxor (res_type, arg0, arg1);
03190 *intrinsic_op = FALSE;
03191 break;
03192
03193
03194 case IX86_BUILTIN_PADDSB:
03195 *iopc = INTRN_PADDSB;
03196 break;
03197 case IX86_BUILTIN_PADDSW:
03198 *iopc = INTRN_PADDSW;
03199 break;
03200 case IX86_BUILTIN_PSUBSB:
03201 *iopc = INTRN_PSUBSB;
03202 break;
03203 case IX86_BUILTIN_PSUBSW:
03204 *iopc = INTRN_PSUBSW;
03205 break;
03206 case IX86_BUILTIN_PADDUSB:
03207 *iopc = INTRN_PADDUSB;
03208 break;
03209 case IX86_BUILTIN_PADDUSW:
03210 *iopc = INTRN_PADDUSW;
03211 break;
03212 case IX86_BUILTIN_PSUBUSB:
03213 *iopc = INTRN_PSUBUSB;
03214 break;
03215 case IX86_BUILTIN_PSUBUSW:
03216 *iopc = INTRN_PSUBUSW;
03217 break;
03218 case IX86_BUILTIN_PMULLW:
03219 *iopc = INTRN_PMULLW;
03220 break;
03221 case IX86_BUILTIN_PMULHW:
03222 *iopc = INTRN_PMULHW;
03223 break;
03224 case IX86_BUILTIN_PCMPEQB:
03225 *iopc = INTRN_PCMPEQB;
03226 break;
03227 case IX86_BUILTIN_PCMPEQW:
03228 *iopc = INTRN_PCMPEQW;
03229 break;
03230 case IX86_BUILTIN_PCMPEQD:
03231 *iopc = INTRN_PCMPEQD;
03232 break;
03233 case IX86_BUILTIN_PCMPGTB:
03234 *iopc = INTRN_PCMPGTB;
03235 break;
03236 case IX86_BUILTIN_PCMPGTW:
03237 *iopc = INTRN_PCMPGTW;
03238 break;
03239 case IX86_BUILTIN_PCMPGTD:
03240 *iopc = INTRN_PCMPGTD;
03241 break;
03242 case IX86_BUILTIN_PUNPCKHBW:
03243 *iopc = INTRN_PUNPCKHBW;
03244 break;
03245 case IX86_BUILTIN_PUNPCKHWD:
03246 *iopc = INTRN_PUNPCKHWD;
03247 break;
03248 case IX86_BUILTIN_PUNPCKHDQ:
03249 *iopc = INTRN_PUNPCKHDQ;
03250 break;
03251 case IX86_BUILTIN_PUNPCKLBW:
03252 *iopc = INTRN_PUNPCKLBW;
03253 break;
03254 case IX86_BUILTIN_PUNPCKLWD:
03255 *iopc = INTRN_PUNPCKLWD;
03256 break;
03257 case IX86_BUILTIN_PUNPCKLDQ:
03258 *iopc = INTRN_PUNPCKLDQ;
03259 break;
03260 case IX86_BUILTIN_PACKSSWB:
03261 *iopc = INTRN_PACKSSWB;
03262 break;
03263 case IX86_BUILTIN_PACKSSDW:
03264 *iopc = INTRN_PACKSSDW;
03265 break;
03266 case IX86_BUILTIN_PACKUSWB:
03267 *iopc = INTRN_PACKUSWB;
03268 break;
03269 case IX86_BUILTIN_PMULHUW:
03270 *iopc = INTRN_PMULHUW;
03271 break;
03272 case IX86_BUILTIN_PAVGB:
03273 *iopc = INTRN_PAVGB;
03274 break;
03275 case IX86_BUILTIN_PAVGW:
03276 *iopc = INTRN_PAVGW;
03277 break;
03278 case IX86_BUILTIN_PSADBW:
03279 *iopc = INTRN_PSADBW;
03280 break;
03281 case IX86_BUILTIN_PMAXUB:
03282 *iopc = INTRN_PMAXUB;
03283 break;
03284 case IX86_BUILTIN_PMAXSW:
03285 *iopc = INTRN_PMAXSW;
03286 break;
03287 case IX86_BUILTIN_PMINUB:
03288 *iopc = INTRN_PMINUB;
03289 break;
03290 case IX86_BUILTIN_PMINSW:
03291 *iopc = INTRN_PMINSW;
03292 break;
03293 case IX86_BUILTIN_PEXTRW:
03294 {
03295 Is_True (TREE_CODE (TREE_VALUE (TREE_CHAIN (t_list))) == INTEGER_CST,
03296 ("Immediate value required by pextrw"));
03297 UINT val = Get_Integer_Value (TREE_VALUE (TREE_CHAIN (t_list)));
03298 switch (val)
03299 {
03300 case 0:
03301 *iopc = INTRN_PEXTRW0;
03302 break;
03303 case 1:
03304 *iopc = INTRN_PEXTRW1;
03305 break;
03306 case 2:
03307 *iopc = INTRN_PEXTRW2;
03308 break;
03309 case 3:
03310 *iopc = INTRN_PEXTRW3;
03311 break;
03312 default:
03313 Fail_FmtAssertion ("Invalid imm value %d to pextrw", val);
03314 }
03315 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(t_list)));
03316 TYPE_ID arg_mtype = TY_mtype(arg_ty_idx);
03317 arg0 = WN_CreateParm (Mtype_comparison (arg_mtype), arg0,
03318 arg_ty_idx, WN_PARM_BY_VALUE);
03319 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, MTYPE_U4, MTYPE_V,
03320 *iopc, 1, &arg0);
03321 break;
03322 }
03323 case IX86_BUILTIN_PINSRW:
03324 {
03325 Is_True (TREE_CODE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (t_list)))) == INTEGER_CST, ("Immediate value required by pinsrw"));
03326 UINT val = Get_Integer_Value (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (t_list))));
03327 switch (val)
03328 {
03329 case 0:
03330 *iopc = INTRN_PINSRW0;
03331 break;
03332 case 1:
03333 *iopc = INTRN_PINSRW1;
03334 break;
03335 case 2:
03336 *iopc = INTRN_PINSRW2;
03337 break;
03338 case 3:
03339 *iopc = INTRN_PINSRW3;
03340 break;
03341 default:
03342 Fail_FmtAssertion ("Invalid imm value %d to pinsrw", val);
03343
03344 }
03345 WN * args[2];
03346 for (int c=0; c<2; c++)
03347 {
03348 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (TREE_VALUE (t_list)));
03349 TYPE_ID arg_mtype = TY_mtype (arg_ty_idx);
03350 args[c] = WN_CreateParm (Mtype_comparison (arg_mtype), arg0,
03351 arg_ty_idx, WN_PARM_BY_VALUE);
03352 t_list = TREE_CHAIN (t_list);
03353 arg0 = arg1;
03354 }
03355
03356 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, MTYPE_M8I2, MTYPE_V,
03357 *iopc, 2, args);
03358 break;
03359 }
03360 case IX86_BUILTIN_PMOVMSKB:
03361 *iopc = INTRN_PMOVMSKB;
03362 break;
03363 case IX86_BUILTIN_ADDPS:
03364 *iopc = INTRN_ADDPS;
03365 break;
03366 case IX86_BUILTIN_SUBPS:
03367 *iopc = INTRN_SUBPS;
03368 break;
03369 case IX86_BUILTIN_MULPS:
03370 *iopc = INTRN_MULPS;
03371 break;
03372 case IX86_BUILTIN_DIVPS:
03373 *iopc = INTRN_DIVPS;
03374 break;
03375 case IX86_BUILTIN_ADDSS:
03376 *iopc = INTRN_ADDSS;
03377 break;
03378 case IX86_BUILTIN_SUBSS:
03379 *iopc = INTRN_SUBSS;
03380 break;
03381 case IX86_BUILTIN_MULSS:
03382 *iopc = INTRN_MULSS;
03383 break;
03384 case IX86_BUILTIN_DIVSS:
03385 *iopc = INTRN_DIVSS;
03386 break;
03387 case IX86_BUILTIN_CMPEQPS:
03388 *iopc = INTRN_CMPEQPS;
03389 break;
03390 case IX86_BUILTIN_CMPLTPS:
03391 *iopc = INTRN_CMPLTPS;
03392 break;
03393 case IX86_BUILTIN_CMPLEPS:
03394 *iopc = INTRN_CMPLEPS;
03395 break;
03396 case IX86_BUILTIN_CMPGTPS:
03397 *iopc = INTRN_CMPGTPS;
03398 break;
03399 case IX86_BUILTIN_CMPGEPS:
03400 *iopc = INTRN_CMPGEPS;
03401 break;
03402 case IX86_BUILTIN_CMPUNORDPS:
03403 *iopc = INTRN_CMPUNORDPS;
03404 break;
03405 case IX86_BUILTIN_CMPNEQPS:
03406 *iopc = INTRN_CMPNEQPS;
03407 break;
03408 case IX86_BUILTIN_CMPNLTPS:
03409 *iopc = INTRN_CMPNLTPS;
03410 break;
03411 case IX86_BUILTIN_CMPNLEPS:
03412 *iopc = INTRN_CMPNLEPS;
03413 break;
03414 case IX86_BUILTIN_CMPNGTPS:
03415 *iopc = INTRN_CMPNGTPS;
03416 break;
03417 case IX86_BUILTIN_CMPNGEPS:
03418 *iopc = INTRN_CMPNGEPS;
03419 break;
03420 case IX86_BUILTIN_CMPORDPS:
03421 *iopc = INTRN_CMPORDPS;
03422 break;
03423 case IX86_BUILTIN_CMPEQSS:
03424 *iopc = INTRN_CMPEQSS;
03425 break;
03426 case IX86_BUILTIN_CMPLTSS:
03427 *iopc = INTRN_CMPLTSS;
03428 break;
03429 case IX86_BUILTIN_CMPLESS:
03430 *iopc = INTRN_CMPLESS;
03431 break;
03432 case IX86_BUILTIN_CMPUNORDSS:
03433 *iopc = INTRN_CMPUNORDSS;
03434 break;
03435 case IX86_BUILTIN_CMPNEQSS:
03436 *iopc = INTRN_CMPNEQSS;
03437 break;
03438 case IX86_BUILTIN_CMPNLTSS:
03439 *iopc = INTRN_CMPNLTSS;
03440 break;
03441 case IX86_BUILTIN_CMPNLESS:
03442 *iopc = INTRN_CMPNLESS;
03443 break;
03444 case IX86_BUILTIN_CMPORDSS:
03445 *iopc = INTRN_CMPORDSS;
03446 break;
03447 case IX86_BUILTIN_MAXPS:
03448 *iopc = INTRN_MAXPS;
03449 break;
03450 case IX86_BUILTIN_MAXSS:
03451 *iopc = INTRN_MAXSS;
03452 break;
03453 case IX86_BUILTIN_MINPS:
03454 *iopc = INTRN_MINPS;
03455 break;
03456 case IX86_BUILTIN_MINSS:
03457 *iopc = INTRN_MINSS;
03458 break;
03459 case IX86_BUILTIN_ANDPS:
03460 *iopc = INTRN_ANDPS;
03461 break;
03462 case IX86_BUILTIN_ANDNPS:
03463 *iopc = INTRN_ANDNPS;
03464 break;
03465 case IX86_BUILTIN_ORPS:
03466 *iopc = INTRN_ORPS;
03467 break;
03468 case IX86_BUILTIN_XORPS:
03469 *iopc = INTRN_XORPS;
03470 break;
03471 case IX86_BUILTIN_MOVSS:
03472 *iopc = INTRN_MOVSS;
03473 break;
03474 case IX86_BUILTIN_MOVHLPS:
03475 *iopc = INTRN_MOVHLPS;
03476 break;
03477 case IX86_BUILTIN_MOVLHPS:
03478 *iopc = INTRN_MOVLHPS;
03479 break;
03480 case IX86_BUILTIN_UNPCKHPS:
03481 *iopc = INTRN_UNPCKHPS;
03482 break;
03483 case IX86_BUILTIN_UNPCKLPS:
03484 *iopc = INTRN_UNPCKLPS;
03485 break;
03486 case IX86_BUILTIN_RCPPS:
03487 *iopc = INTRN_RCPPS;
03488 break;
03489 case IX86_BUILTIN_RSQRTPS:
03490 *iopc = INTRN_RSQRTPS;
03491 break;
03492 case IX86_BUILTIN_SQRTPS:
03493 *iopc = INTRN_SQRTPS;
03494 break;
03495 case IX86_BUILTIN_RCPSS:
03496 *iopc = INTRN_RCPSS;
03497 break;
03498 case IX86_BUILTIN_RSQRTSS:
03499 *iopc = INTRN_RSQRTSS;
03500 break;
03501 case IX86_BUILTIN_SQRTSS:
03502 *iopc = INTRN_SQRTSS;
03503 break;
03504 case IX86_BUILTIN_SHUFPS:
03505 *iopc = INTRN_SHUFPS;
03506 break;
03507 case IX86_BUILTIN_EMMS:
03508 *iopc = INTRN_EMMS;
03509 *intrinsic_op = FALSE;
03510 break;
03511 case IX86_BUILTIN_LOADAPS:
03512 *iopc = INTRN_LOADAPS;
03513 break;
03514 case IX86_BUILTIN_STOREAPS:
03515 *iopc = INTRN_STOREAPS;
03516 *intrinsic_op = FALSE;
03517 break;
03518 case IX86_BUILTIN_PXOR128:
03519 wn = WN_Bxor (res_type, arg0, arg1);
03520 *intrinsic_op = FALSE;
03521 break;
03522 case IX86_BUILTIN_PSLLDQI128:
03523 *iopc = INTRN_PSLLDQ;
03524 break;
03525 case IX86_BUILTIN_PSRLDQI128:
03526 *iopc = INTRN_PSRLDQ;
03527 break;
03528 case IX86_BUILTIN_PSLLW128:
03529 *iopc = INTRN_PSLLW;
03530 break;
03531 case IX86_BUILTIN_PSLLD128:
03532 *iopc = INTRN_PSLLD;
03533 break;
03534 case IX86_BUILTIN_PSLLQ128:
03535 *iopc = INTRN_PSLLQ;
03536 break;
03537 case IX86_BUILTIN_PSRLW128:
03538 *iopc = INTRN_PSRLW;
03539 break;
03540 case IX86_BUILTIN_PSRLD128:
03541 *iopc = INTRN_PSRLD;
03542 break;
03543 case IX86_BUILTIN_PSRLQ128:
03544 *iopc = INTRN_PSRLQ;
03545 break;
03546 case IX86_BUILTIN_PSRAW128:
03547 *iopc = INTRN_PSRAW;
03548 break;
03549 case IX86_BUILTIN_PSRAD128:
03550 *iopc = INTRN_PSRAD;
03551 break;
03552 case IX86_BUILTIN_PSRAWI128:
03553 *iopc = INTRN_PSRAW;
03554 break;
03555 case IX86_BUILTIN_PSRADI128:
03556 *iopc = INTRN_PSRAD;
03557 break;
03558 case IX86_BUILTIN_PSLLWI128:
03559 *iopc = INTRN_PSLLW;
03560 break;
03561 case IX86_BUILTIN_PSLLDI128:
03562 *iopc = INTRN_PSLLD;
03563 break;
03564 case IX86_BUILTIN_PSLLQI128:
03565 *iopc = INTRN_PSLLQ;
03566 break;
03567 case IX86_BUILTIN_PSRLWI128:
03568 *iopc = INTRN_PSRLW;
03569 break;
03570 case IX86_BUILTIN_PSRLDI128:
03571 *iopc = INTRN_PSRLD;
03572 break;
03573 case IX86_BUILTIN_PSRLQI128:
03574 *iopc = INTRN_PSRLQ;
03575 break;
03576 case IX86_BUILTIN_MOVNTDQ:
03577 *iopc = INTRN_MOVNTDQ;
03578 *intrinsic_op = FALSE;
03579 break;
03580 case IX86_BUILTIN_LOADD:
03581 *iopc = INTRN_LOADD;
03582 break;
03583 case IX86_BUILTIN_MOVNTPS:
03584 *iopc = INTRN_MOVNTPS;
03585 *intrinsic_op = FALSE;
03586 break;
03587 case IX86_BUILTIN_SSE_ZERO:
03588 *iopc = INTRN_SSE_ZERO;
03589 *intrinsic_op = FALSE;
03590 break;
03591 case IX86_BUILTIN_CLRTI:
03592 *iopc = INTRN_CLRTI;
03593 *intrinsic_op = FALSE;
03594 break;
03595 case IX86_BUILTIN_PSHUFD:
03596 *iopc = INTRN_PSHUFD;
03597 break;
03598 case IX86_BUILTIN_LOADSS:
03599 *iopc = INTRN_LOADSS;
03600 break;
03601 case IX86_BUILTIN_DIVPD:
03602 wn = WN_Div (res_type, arg0, arg1);
03603 *intrinsic_op = FALSE;
03604 break;
03605 case IX86_BUILTIN_MULPD:
03606 wn = WN_Mpy (res_type, arg0, arg1);
03607 *intrinsic_op = FALSE;
03608 break;
03609 case IX86_BUILTIN_SQRTPD:
03610 wn = WN_Sqrt (res_type, arg0);
03611 *intrinsic_op = FALSE;
03612 break;
03613 case IX86_BUILTIN_MINPD:
03614 wn = WN_Binary (OPR_MIN, res_type, arg0, arg1);
03615 *intrinsic_op = FALSE;
03616 break;
03617 case IX86_BUILTIN_MAXPD:
03618 wn = WN_Binary (OPR_MAX, res_type, arg0, arg1);
03619 *intrinsic_op = FALSE;
03620 break;
03621 case IX86_BUILTIN_SHUFPD:
03622 *iopc = INTRN_SHUFPD;
03623 break;
03624 case IX86_BUILTIN_XORPD:
03625 *iopc = INTRN_XORPD;
03626 break;
03627 case IX86_BUILTIN_ANDPD:
03628 *iopc = INTRN_ANDPD;
03629 break;
03630 case IX86_BUILTIN_ORPD:
03631 *iopc = INTRN_ORPD;
03632 break;
03633 case IX86_BUILTIN_STORELPD:
03634 *iopc = INTRN_STORELPD;
03635 *intrinsic_op = FALSE;
03636 break;
03637 case IX86_BUILTIN_STOREHPD:
03638 *iopc = INTRN_STOREHPD;
03639 *intrinsic_op = FALSE;
03640 break;
03641 case IX86_BUILTIN_LOADLPD:
03642 *iopc = INTRN_LOADLPD;
03643 break;
03644 case IX86_BUILTIN_LOADHPD:
03645 *iopc = INTRN_LOADHPD;
03646 break;
03647 case IX86_BUILTIN_UNPCKLPD:
03648 *iopc = INTRN_UNPCKLPD;
03649 break;
03650 case IX86_BUILTIN_UNPCKHPD:
03651 *iopc = INTRN_UNPCKHPD;
03652 break;
03653 case IX86_BUILTIN_LFENCE:
03654 *iopc = INTRN_LFENCE;
03655 *intrinsic_op = FALSE;
03656 break;
03657 case IX86_BUILTIN_MFENCE:
03658 *iopc = INTRN_MFENCE;
03659 *intrinsic_op = FALSE;
03660 break;
03661 case IX86_BUILTIN_SFENCE:
03662 *iopc = INTRN_SFENCE;
03663 *intrinsic_op = FALSE;
03664 break;
03665 case IX86_BUILTIN_PSHUFW:
03666 *iopc = INTRN_PSHUFW;
03667 break;
03668 case IX86_BUILTIN_LOADDQA:
03669 *iopc = INTRN_LOADDQA;
03670 break;
03671 case IX86_BUILTIN_LOADDQU:
03672 *iopc = INTRN_LOADDQU;
03673 break;
03674 case IX86_BUILTIN_STOREDQA:
03675 *iopc = INTRN_STOREDQA;
03676 *intrinsic_op = FALSE;
03677 break;
03678 case IX86_BUILTIN_STOREDQU:
03679 *iopc = INTRN_STOREDQU;
03680 *intrinsic_op = FALSE;
03681 break;
03682 case IX86_BUILTIN_MOVNTI:
03683 *iopc = INTRN_MOVNTI;
03684 *intrinsic_op = FALSE;
03685 break;
03686
03687 default:
03688 if (Opt_Level > 0)
03689 {
03690 *iopc = INTRN_UNIMP_PURE;
03691 if (res_type == MTYPE_V)
03692 {
03693 *iopc = INTRN_UNIMP;
03694 *intrinsic_op = FALSE;
03695 }
03696 }
03697 else
03698 {
03699 *intrinsic_op = FALSE;
03700
03701
03702 wn = WN_Intconst (MTYPE_U8, 0);
03703 if (res_type != MTYPE_U8 && res_type != MTYPE_V)
03704 wn = WN_Cvt (MTYPE_U8, res_type, wn);
03705 }
03706 break;
03707 }
03708
03709
03710
03711
03712 switch (ins_code)
03713 {
03714 case IX86_BUILTIN_PSRAWI128:
03715 case IX86_BUILTIN_PSRADI128:
03716 case IX86_BUILTIN_PSLLWI128:
03717 case IX86_BUILTIN_PSLLDI128:
03718 case IX86_BUILTIN_PSLLQI128:
03719 case IX86_BUILTIN_PSRLWI128:
03720 case IX86_BUILTIN_PSRLDI128:
03721 case IX86_BUILTIN_PSRLQI128:
03722 Is_True (wn == NULL, ("WFE_target_builtins: null WN expected"));
03723 WN * args[2];
03724
03725 {
03726
03727 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (TREE_VALUE (t_list)));
03728 TYPE_ID arg_mtype = TY_mtype (arg_ty_idx);
03729 args[0] = WN_CreateParm (Mtype_comparison (arg_mtype), arg0,
03730 arg_ty_idx, WN_PARM_BY_VALUE);
03731
03732
03733 arg1 = WN_Cvt (WN_rtype(arg1), MTYPE_V16I8, arg1);
03734 arg_ty_idx = MTYPE_TO_TY_array[WN_rtype (arg1)];
03735 arg_mtype = WN_rtype (arg1);
03736 args[1] = WN_CreateParm (Mtype_comparison (arg_mtype), arg1,
03737 arg_ty_idx, WN_PARM_BY_VALUE);
03738 }
03739
03740 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, res_type, MTYPE_V,
03741 *iopc, 2, args);
03742 break;
03743 }
03744
03745 return wn;
03746 }
03747 #endif // TARG_X8664
03748
03749
03750 WN *
03751 WFE_Expand_Expr (tree exp,
03752 bool need_result,
03753 TY_IDX nop_ty_idx,
03754 TY_IDX component_ty_idx,
03755 INT64 component_offset,
03756 UINT16 field_id,
03757 bool is_bit_field,
03758 bool expect_boolean)
03759 {
03760 enum tree_code code = TREE_CODE (exp);
03761 WN *wn, *wn0, *wn1, *wn2;
03762 ST *st;
03763 TY_IDX ty_idx;
03764 TY_IDX desc_ty_idx;
03765 tree arg0, arg1, arg2;
03766
03767 wn = NULL;
03768
03769 #ifdef WFE_DEBUG
03770 fprintf (stderr,
03771 "{( WFE_Expand_Expr: %s\n", Operator_From_Tree [code].name);
03772 #endif
03773
03774 switch (code)
03775 {
03776
03777 case ADDR_EXPR:
03778 {
03779 arg0 = TREE_OPERAND (exp, 0);
03780 enum tree_code code0 = TREE_CODE (arg0);
03781 switch (code0) {
03782 case VAR_DECL:
03783 case PARM_DECL:
03784 case FUNCTION_DECL:
03785 {
03786 st = Get_ST (arg0);
03787 ty_idx = ST_type (st);
03788 #ifdef KEY
03789
03790
03791 if (code0 == FUNCTION_DECL &&
03792 PU_is_nested_func(Pu_Table[ST_pu(st)]))
03793 Set_PU_has_alloca(Get_Current_PU());
03794 #endif
03795
03796 if (code0 == VAR_DECL &&
03797 st != ST_base(st)) {
03798 FmtAssert (ST_ofst (st) == 0,
03799 ("Variable Length Arrays within struct not currently implemented"));
03800 wn = WN_Ldid (Pointer_Mtype, 0, ST_base(st), ST_type(ST_base(st)));
03801 }
03802 else
03803 if (!WFE_Keep_Zero_Length_Structs &&
03804 code0 == PARM_DECL &&
03805 TY_mtype (ty_idx) == MTYPE_M &&
03806 TY_size (ty_idx) == 0) {
03807
03808 DevWarn ("taking address of zero length struct %s at line %d",
03809 ST_name (st), lineno);
03810 wn = WN_Intconst (Pointer_Mtype, 0);
03811 }
03812 else
03813 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
03814 }
03815 break;
03816
03817 #ifdef KEY // bug 3228
03818 case INDIRECT_REF:
03819 wn = WFE_Expand_Expr (TREE_OPERAND(arg0, 0));
03820 break;
03821 #endif
03822
03823 case STRING_CST:
03824 {
03825 TCON tcon;
03826 tcon = Host_To_Targ_String (MTYPE_STRING,
03827 const_cast<char *>TREE_STRING_POINTER(arg0),
03828 TREE_STRING_LENGTH(arg0));
03829 ty_idx = Get_TY(TREE_TYPE(arg0));
03830 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
03831 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
03832 TREE_STRING_ST (arg0) = st;
03833 }
03834 break;
03835
03836 case CONSTRUCTOR:
03837 {
03838 st = WFE_Generate_Temp_For_Initialized_Aggregate (arg0, "");
03839 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
03840 }
03841 break;
03842
03843 case LABEL_DECL:
03844 {
03845 DevWarn ("taking address of a label at line %d", lineno);
03846 LABEL_IDX label_idx = WFE_Get_LABEL (arg0, FALSE);
03847 FmtAssert (arg0->decl.symtab_idx == CURRENT_SYMTAB,
03848 ("line %d: taking address of a label not defined in current function currently not implemented", lineno));
03849 wn = WN_LdaLabel (Pointer_Mtype, label_idx);
03850 Set_LABEL_addr_saved (label_idx);
03851 #ifdef KEY
03852
03853
03854
03855
03856 if ( ST_export (Get_Current_PU_ST()) != EXPORT_LOCAL)
03857 #endif
03858 Set_PU_no_inline (Get_Current_PU ());
03859 }
03860 break;
03861
03862 case COMPONENT_REF:
03863 {
03864 wn = WFE_Expand_Expr (arg0);
03865 ty_idx = Get_TY(TREE_TYPE(arg0));
03866 if (WN_operator (wn) == OPR_LDID) {
03867 WN_set_operator (wn, OPR_LDA);
03868 WN_set_desc (wn, MTYPE_V);
03869 WN_set_rtype (wn, Pointer_Mtype);
03870 WN_set_ty (wn, Make_Pointer_Type(WN_ty(wn)));
03871 }
03872 else
03873 if (WN_operator (wn) == OPR_ILOAD) {
03874 wn0 = WN_kid0 (wn);
03875 wn1 = WN_Intconst (Pointer_Mtype, WN_offset (wn));
03876 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn0, wn1);
03877 }
03878 else
03879 Fail_FmtAssertion ("WFE_Expand_Expr: ADDR_EXPR has unhandled %s",
03880 Operator_From_Tree [code0].name);
03881 }
03882 break;
03883
03884 #ifdef KEY // bug 3228
03885 case ARRAY_REF:
03886 wn = WFE_Expand_Expr (arg0);
03887 if (WN_operator(wn) == OPR_ILOAD)
03888 wn = WN_kid0(wn);
03889 ty_idx = Get_TY(TREE_TYPE(arg0));
03890 break;
03891 #endif
03892
03893 #ifdef KEY
03894 case COMPOUND_LITERAL_EXPR:
03895 {
03896 tree oper = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
03897 if (TREE_CODE (DECL_INITIAL(oper)) == CONSTRUCTOR)
03898 {
03899 arg0 = DECL_INITIAL (oper);
03900 st = WFE_Generate_Temp_For_Initialized_Aggregate (arg0, "");
03901 }
03902 else
03903 {
03904 arg0 = oper;
03905 st = Get_ST (arg0);
03906 }
03907 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
03908 }
03909 break;
03910
03911 case REALPART_EXPR:
03912 {
03913 wn = WFE_Expand_Expr (TREE_OPERAND (arg0, 0));
03914 if (WN_operator (wn) == OPR_ILOAD)
03915 wn = WN_kid0 (wn);
03916 else if (WN_operator (wn) == OPR_LDID)
03917 wn = WN_Lda (Pointer_Mtype, WN_offset(wn), WN_st(wn));
03918 else Fail_FmtAssertion ("WFE_Expand_Expr: NYI for REALPART_EXPR");
03919 }
03920 break;
03921
03922 case IMAGPART_EXPR:
03923 {
03924 wn = WFE_Expand_Expr (TREE_OPERAND (arg0, 0));
03925 if (WN_operator (wn) == OPR_ILOAD)
03926 {
03927 wn0 = WN_kid0 (wn);
03928 TYPE_ID imag_mtype;
03929 switch (WN_rtype (wn))
03930 {
03931 case MTYPE_C4:
03932 imag_mtype = MTYPE_F4;
03933 break;
03934 case MTYPE_C8:
03935 imag_mtype = MTYPE_F8;
03936 break;
03937 case MTYPE_CQ:
03938 imag_mtype = MTYPE_FQ;
03939 break;
03940 default:
03941 Fail_FmtAssertion ("WFE_Expand_Expr: Unexpected rtype in IMAGPART_EXPR");
03942 }
03943 INT ofst;
03944 if (imag_mtype == MTYPE_FQ)
03945 {
03946 #ifdef TARG_X8664
03947 if (Is_Target_32bit()) ofst = 12; else
03948 #endif // TARG_X8664
03949 ofst = 16;
03950 }
03951 else ofst = MTYPE_byte_size (imag_mtype);
03952
03953 wn1 = WN_Intconst (Pointer_Mtype, ofst);
03954 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn0, wn1);
03955 }
03956 else if (WN_operator (wn) == OPR_LDID)
03957 wn = WN_Lda (Pointer_Mtype,
03958 WN_offset(wn) + MTYPE_byte_size(WN_rtype(wn)) / 2,
03959 WN_st(wn));
03960 else Fail_FmtAssertion ("WFE_Expand_Expr: NYI for IMAGPART_EXPR");
03961 }
03962 break;
03963 #endif
03964
03965 #ifdef KEY // bug 11877
03966 case CALL_EXPR: {
03967 WN *comma = WFE_Expand_Expr (arg0);
03968 if (WN_operator(comma) != OPR_COMMA)
03969 Fail_FmtAssertion ("WFE_Expand_Expr: ADDR_EXPR of call returning void unhandled");
03970 wn = WN_kid1(comma);
03971 if (WN_operator(wn) != OPR_LDID)
03972 Fail_FmtAssertion ("WFE_Expand_Expr: ADDR_EXPR of call returning void unhandled");
03973 WN_set_operator (wn, OPR_LDA);
03974 WN_set_rtype (wn, Pointer_Mtype);
03975 WN_set_desc (wn, MTYPE_V);
03976 WN_set_ty(wn, Make_Pointer_Type(WN_ty(wn)));
03977 WN_set_rtype (comma, Pointer_Mtype);
03978 wn = comma;
03979 break;
03980 }
03981
03982 case MODIFY_EXPR : {
03983
03984
03985
03986
03987 WFE_Expand_Expr (arg0);
03988 tree lhs = TREE_OPERAND(arg0, 0);
03989 Is_True (lhs != NULL && TREE_CODE(lhs) == VAR_DECL,
03990 ("Unsupported lhs for `(p=q).x'"));
03991 st = Get_ST(TREE_OPERAND(arg0, 0));
03992 wn = WN_Lda(Pointer_Mtype, ST_ofst(st), st);
03993 break;
03994 }
03995 #endif
03996
03997 default:
03998 {
03999 Fail_FmtAssertion ("WFE_Expand_Expr: ADDR_EXPR has unhandled %s",
04000 Operator_From_Tree [code0].name);
04001 }
04002 break;
04003 }
04004 }
04005 break;
04006
04007 case FUNCTION_DECL:
04008 {
04009 st = Get_ST (exp);
04010 ty_idx = ST_type (st);
04011 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
04012 }
04013 break;
04014
04015 case BIND_EXPR:
04016 {
04017 INT32 i;
04018 WN *block;
04019 TYPE_ID mtype;
04020 tree t;
04021
04022 DevWarn ("Encountered BIND_EXPR at line %d", lineno);
04023
04024 for (i = wfe_bind_expr_stack_last; i >= 0; --i) {
04025
04026 if (wfe_bind_expr_stack [i].rtl_expr == TREE_OPERAND (exp, 1)) {
04027
04028 block = wfe_bind_expr_stack [i].block;
04029 t = wfe_bind_expr_stack [i].rtl_expr;
04030 wfe_bind_expr_stack [i] = wfe_bind_expr_stack [wfe_bind_expr_stack_last];
04031 --wfe_bind_expr_stack_last;
04032 break;
04033 }
04034 }
04035
04036 FmtAssert (i >= 0,
04037 ("BIND_EXPR: did not find tree"));
04038 ty_idx = Get_TY (TREE_TYPE(t));
04039 mtype = TY_mtype (ty_idx);
04040 if (mtype == MTYPE_V) {
04041 WFE_Stmt_Append (block, Get_Srcpos ());
04042 break;
04043 }
04044 else {
04045 wn1 = WN_last (block);
04046 if (wn1 && WN_operator (wn1) == OPR_EVAL) {
04047 wn1 = WN_COPY_Tree (WN_kid0 (wn1));
04048 wn0 = block;
04049 WN_DELETE_FromBlock (wn0, WN_last (wn0));
04050 WFE_Stmt_Append (wn0, Get_Srcpos ());
04051 if (nop_ty_idx == 0 && component_ty_idx == 0) {
04052 wn = wn1;
04053 break;
04054 }
04055 if (WN_operator (wn1) == OPR_LDID)
04056 st = WN_st (wn1);
04057 else {
04058 st = Gen_Temp_Symbol (ty_idx, "__bind_expr");
04059 #ifdef KEY
04060 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
04061 #endif // KEY
04062 WFE_Set_ST_Addr_Saved (wn1);
04063 wn0 = WN_Stid (mtype, 0, st, ty_idx, wn1);
04064 WFE_Stmt_Append (wn0, Get_Srcpos ());
04065 }
04066 }
04067 else {
04068 WFE_Stmt_Append (block, Get_Srcpos ());
04069 break;
04070 }
04071 }
04072 }
04073
04074
04075 case CONSTRUCTOR:
04076 case PARM_DECL:
04077 case VAR_DECL:
04078 {
04079 PREG_NUM preg_num = 0;
04080 desc_ty_idx = component_ty_idx;
04081 TY_IDX hi_ty_idx = Get_TY (TREE_TYPE(exp));
04082 if (desc_ty_idx == 0)
04083 desc_ty_idx = hi_ty_idx;
04084
04085 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
04086 ty_idx = desc_ty_idx;
04087 else {
04088 ty_idx = nop_ty_idx;
04089 if (ty_idx == 0)
04090 ty_idx = desc_ty_idx;
04091 }
04092
04093 UINT cvtl_size = 0;
04094 if (! is_bit_field) {
04095 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
04096 cvtl_size = TY_size(ty_idx) * 8;
04097 ty_idx = desc_ty_idx;
04098 }
04099 }
04100 else {
04101 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
04102 ty_idx = desc_ty_idx;
04103 }
04104
04105 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
04106 TYPE_ID desc = TY_mtype(desc_ty_idx);
04107 if (MTYPE_is_integral(desc)) {
04108 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
04109 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
04110 is_bit_field)
04111 rtype = Mtype_TransferSign(desc, rtype);
04112 else desc = Mtype_TransferSign(rtype, desc);
04113 }
04114 }
04115
04116 if (TREE_THIS_VOLATILE(exp))
04117 Set_TY_is_volatile(ty_idx);
04118
04119 if (code == PARM_DECL || code == VAR_DECL) {
04120 st = Get_ST (exp);
04121 Is_True(ST_st_idx(st) != 0, ("got null st?"));
04122 Is_True(ST_st_idx(st) != -1, ("got -1 st?"));
04123 if (ST_assigned_to_dedicated_preg (st))
04124 Set_TY_is_volatile(ty_idx);
04125 }
04126 else
04127 if (code == CONSTRUCTOR) {
04128 DevWarn ("Encountered CONSTRUCTOR at line %d", lineno);
04129 st = WFE_Generate_Temp_For_Initialized_Aggregate (exp, "");
04130 }
04131
04132 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
04133 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
04134 #ifdef TARG_X8664
04135
04136
04137 if (MTYPE_is_vector (rtype) || MTYPE_is_vector (desc))
04138 desc = rtype;
04139 #endif
04140 wn = WN_CreateLdid (OPR_LDID, rtype,
04141 is_bit_field ? MTYPE_BS : desc,
04142 ST_ofst(st)+component_offset+preg_num, st,
04143 field_id != 0 ? hi_ty_idx : ty_idx, field_id);
04144 if (cvtl_size != 0)
04145 wn = WN_CreateCvtl(OPR_CVTL, rtype, MTYPE_V, cvtl_size, wn);
04146 }
04147 break;
04148
04149 case INTEGER_CST:
04150 {
04151 ty_idx = Get_TY (TREE_TYPE(exp));
04152 TYPE_ID mtyp = TY_mtype(ty_idx);
04153 mtyp = (mtyp == MTYPE_V) ? MTYPE_I4 : Widen_Mtype(mtyp);
04154 wn = WN_Intconst(mtyp, Get_Integer_Value(exp));
04155 }
04156 break;
04157
04158 case REAL_CST:
04159 {
04160 TCON tcon;
04161 ty_idx = Get_TY (TREE_TYPE(exp));
04162 #if (defined(TARG_IA32) || defined(TARG_X8664)) && !defined(REAL_ARITHMETIC)
04163 tcon = Host_To_Targ_Float (TY_mtype (ty_idx), TREE_REAL_CST(exp));
04164 #else
04165 REAL_VALUE_TYPE real = TREE_REAL_CST(exp);
04166
04167 #ifdef TARG_IA64
04168 switch (TY_mtype (ty_idx)) {
04169 case MTYPE_F4:
04170 tcon = Host_To_Targ_Float_4 (MTYPE_F4,
04171 WFE_Convert_Internal_Real_to_IEEE_Single(real));
04172 break;
04173
04174 case MTYPE_F8:
04175 tcon = Host_To_Targ_Float (MTYPE_F8,
04176 WFE_Convert_Internal_Real_to_IEEE_Double(real));
04177 break;
04178
04179 case MTYPE_F10:
04180 tcon = Host_To_Targ_Float_10 (MTYPE_F10,
04181 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real));
04182 break;
04183
04184 case MTYPE_FQ:
04185 tcon = Host_To_Targ_Quad (WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real));
04186 break;
04187 #else
04188 int rval;
04189 long rbuf [4];
04190 #ifdef KEY
04191 INT32 rbuf_w[4];
04192 INT32 i;
04193 #endif
04194 switch (TY_mtype (ty_idx)) {
04195 case MTYPE_F4:
04196 REAL_VALUE_TO_TARGET_SINGLE (real, rval);
04197 tcon = Host_To_Targ_Float_4 (MTYPE_F4, *(float *) &rval);
04198 break;
04199 case MTYPE_F8:
04200 REAL_VALUE_TO_TARGET_DOUBLE (real, rbuf);
04201 #ifdef KEY
04202 WFE_Convert_To_Host_Order(rbuf);
04203 for (i = 0; i < 4; i++)
04204 rbuf_w[i] = rbuf[i];
04205 tcon = Host_To_Targ_Float (MTYPE_F8, *(double *) &rbuf_w);
04206 #else
04207 tcon = Host_To_Targ_Float (MTYPE_F8, *(double *) &rbuf);
04208 #endif
04209 break;
04210 #if defined(TARG_IA32) || defined(TARG_X8664) || defined(TARG_NVISA)
04211 case MTYPE_FQ:
04212 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, rbuf);
04213 for (i = 0; i < 4; i++)
04214 rbuf_w[i] = rbuf[i];
04215 tcon = Host_To_Targ_Quad (*(long double *) &rbuf_w);
04216 break;
04217 #endif
04218 #endif
04219 default:
04220 FmtAssert(FALSE, ("WFE_Expand_Expr unexpected float size"));
04221 break;
04222 }
04223 #endif
04224 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04225 wn = WN_CreateConst (OPR_CONST, TY_mtype (ty_idx), MTYPE_V, st);
04226 }
04227 break;
04228
04229 case COMPLEX_CST:
04230 {
04231 TCON tcon;
04232 ty_idx = Get_TY (TREE_TYPE(exp));
04233 #ifdef KEY
04234
04235 if (TREE_CODE(TREE_REALPART(exp)) != REAL_CST ||
04236 TREE_CODE(TREE_IMAGPART(exp)) != REAL_CST) {
04237 #ifdef PSC_TO_OPEN64
04238 printf("opencc does not support complex integer data types (a gcc extension)\n");
04239 #endif
04240 exit(2);
04241 }
04242 #endif
04243 #if (defined(TARG_IA32) || defined(TARG_X8664)) && !defined(REAL_ARITHMETIC)
04244 tcon = Host_To_Targ_Complex (TY_mtype (ty_idx),
04245 TREE_REAL_CST(TREE_REALPART(exp)),
04246 TREE_REAL_CST(TREE_IMAGPART(exp)));
04247 #else
04248 REAL_VALUE_TYPE real = TREE_REAL_CST(TREE_REALPART(exp));
04249 REAL_VALUE_TYPE imag = TREE_REAL_CST(TREE_IMAGPART(exp));
04250 #ifdef TARG_IA64
04251 switch (TY_mtype (ty_idx)) {
04252 case MTYPE_C4:
04253 tcon = Host_To_Targ_Complex_4 (MTYPE_C4,
04254 WFE_Convert_Internal_Real_to_IEEE_Single(real),
04255 WFE_Convert_Internal_Real_to_IEEE_Single(imag));
04256 break;
04257
04258 case MTYPE_C8:
04259 tcon = Host_To_Targ_Complex (MTYPE_C8,
04260 WFE_Convert_Internal_Real_to_IEEE_Double(real),
04261 WFE_Convert_Internal_Real_to_IEEE_Double(imag));
04262 break;
04263
04264 case MTYPE_C10:
04265 tcon = Host_To_Targ_Complex_10 (MTYPE_C10,
04266 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real),
04267 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(imag));
04268 break;
04269 case MTYPE_CQ:
04270 tcon = Host_To_Targ_Complex_Quad (
04271 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real),
04272 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(imag));
04273 break;
04274 #else
04275 int rval;
04276 int ival;
04277 long rbuf [4];
04278 long ibuf [4];
04279 #ifdef KEY
04280 INT32 rbuf_w [4];
04281 INT32 ibuf_w [4];
04282 INT32 i;
04283 #endif
04284 switch (TY_mtype (ty_idx)) {
04285 case MTYPE_C4:
04286 REAL_VALUE_TO_TARGET_SINGLE (real, rval);
04287 REAL_VALUE_TO_TARGET_SINGLE (imag, ival);
04288 tcon = Host_To_Targ_Complex_4 (MTYPE_C4,
04289 *(float *) &rval, *(float *) &ival);
04290 break;
04291 case MTYPE_C8:
04292 REAL_VALUE_TO_TARGET_DOUBLE (real, rbuf);
04293 REAL_VALUE_TO_TARGET_DOUBLE (imag, ibuf);
04294 #ifdef KEY
04295 WFE_Convert_To_Host_Order(rbuf);
04296 WFE_Convert_To_Host_Order(ibuf);
04297 for (i = 0; i < 4; i++) {
04298 rbuf_w[i] = rbuf[i];
04299 ibuf_w[i] = ibuf[i];
04300 }
04301 tcon = Host_To_Targ_Complex (MTYPE_C8,
04302 *(double *) &rbuf_w, *(double *) &ibuf_w);
04303 #else
04304 tcon = Host_To_Targ_Complex (MTYPE_C8,
04305 *(double *) &rbuf, *(double *) &ibuf);
04306 #endif
04307 break;
04308 #ifdef KEY
04309 case MTYPE_CQ:
04310 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, rbuf);
04311 REAL_VALUE_TO_TARGET_LONG_DOUBLE (imag, ibuf);
04312 WFE_Convert_To_Host_Order(rbuf);
04313 WFE_Convert_To_Host_Order(ibuf);
04314 for (i = 0; i < 4; i++) {
04315 rbuf_w[i] = rbuf[i];
04316 ibuf_w[i] = ibuf[i];
04317 }
04318 tcon = Host_To_Targ_Complex_Quad( *(long double *) &rbuf_w,
04319 *(long double *) &ibuf_w );
04320 break;
04321 #endif
04322 #endif
04323 default:
04324 FmtAssert(FALSE, ("WFE_Expand_Expr unexpected float size"));
04325 break;
04326 }
04327 #endif
04328 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04329 wn = WN_CreateConst (OPR_CONST, TY_mtype (ty_idx), MTYPE_V, st);
04330 }
04331 break;
04332
04333
04334 case STRING_CST:
04335 {
04336 TCON tcon;
04337 tcon = Host_To_Targ_String (MTYPE_STRING,
04338 const_cast<char *>TREE_STRING_POINTER(exp),
04339 TREE_STRING_LENGTH(exp));
04340 ty_idx = Get_TY(TREE_TYPE(exp));
04341 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04342 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
04343 TREE_STRING_ST (exp) = st;
04344 }
04345 break;
04346
04347
04348 case BIT_NOT_EXPR:
04349 case ABS_EXPR:
04350 case NEGATE_EXPR:
04351 case TRUTH_NOT_EXPR:
04352 case REALPART_EXPR:
04353 case IMAGPART_EXPR:
04354 {
04355 #ifdef TARG_SL
04356 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0), Get_TY(TREE_TYPE(exp)));
04357 #else
04358 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04359 #endif
04360 wn = WN_Unary (Operator_From_Tree [code].opr,
04361 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))), wn0);
04362 #ifdef KEY // bug 2648
04363 TYPE_ID mtyp = TY_mtype(Get_TY(TREE_TYPE(exp)));
04364 if (mtyp != WN_rtype(wn))
04365 wn = WN_CreateCvtl (OPR_CVTL, WN_rtype(wn), MTYPE_V,
04366 MTYPE_size_min(mtyp), wn);
04367 #endif
04368 }
04369 break;
04370
04371 case CONJ_EXPR:
04372 {
04373 ty_idx = Get_TY (TREE_TYPE(exp));
04374 TYPE_ID complex_mtype = TY_mtype(ty_idx);
04375 TYPE_ID float_mtype = Mtype_complex_to_real (complex_mtype);
04376 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04377 if (WN_has_side_effects (wn0)) {
04378 ST *preg_st;
04379 PREG_NUM preg;
04380 preg_st = MTYPE_To_PREG(complex_mtype);
04381 preg = Create_Preg (complex_mtype, NULL);
04382 wn0 = WN_Stid (complex_mtype, preg, preg_st, ty_idx, wn0);
04383 WFE_Stmt_Append (wn0, Get_Srcpos());
04384 wn0 = WN_Ldid (complex_mtype, preg, preg_st, ty_idx);
04385 }
04386 #ifdef KEY
04387
04388 wn = WN_Binary (OPR_COMPLEX, complex_mtype,
04389 WN_Unary (OPR_REALPART, float_mtype, wn0),
04390 WN_Unary (OPR_NEG, float_mtype,
04391 WN_Unary (OPR_IMAGPART, float_mtype, wn0)));
04392 #else
04393 wn = WN_Binary (OPR_COMPLEX, complex_mtype,
04394 WN_Unary (OPR_REALPART, float_mtype, wn0),
04395 WN_Unary (OPR_NEG, float_mtype,
04396 WN_Unary (OPR_REALPART, float_mtype, wn0)));
04397 #endif
04398 }
04399 break;
04400
04401 case NOP_EXPR:
04402 {
04403 ty_idx = Get_TY (TREE_TYPE(exp));
04404 TYPE_ID mtyp = TY_mtype(ty_idx);
04405
04406 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0),
04407 #ifndef KEY
04408 TRUE,
04409 #else
04410 mtyp != MTYPE_V,
04411 #endif
04412 (mtyp == MTYPE_M) ? 0 : ty_idx);
04413 #ifdef KEY
04414
04415
04416 if ((mtyp == MTYPE_M) || (mtyp == MTYPE_V))
04417 #else
04418 if (mtyp == MTYPE_M)
04419 #endif // KEY
04420 break;
04421 if (MTYPE_is_integral(mtyp) && MTYPE_is_integral(WN_rtype(wn))) {
04422
04423
04424 #ifndef TARG_IA64
04425 if (MTYPE_size_min(mtyp) == 64 &&
04426 MTYPE_size_min(WN_rtype(wn)) == 32 &&
04427 MTYPE_is_signed(mtyp) != MTYPE_is_signed(WN_rtype(wn))) {
04428 mtyp = MTYPE_complement(mtyp);
04429 }
04430 #endif
04431 if (MTYPE_size_min(mtyp) < MTYPE_size_min(WN_rtype(wn))) {
04432 if (MTYPE_size_min(mtyp) != 32)
04433 #ifdef TARG_NVISA // maybe should be all targets, but NVISA is stricter
04434 {
04435
04436
04437
04438 TYPE_ID cvtl_mtype = Mtype_TransferSign(mtyp, WN_rtype(wn));
04439 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(cvtl_mtype), MTYPE_V,
04440 MTYPE_size_min(mtyp), wn);
04441
04442
04443 if (MTYPE_size_min(Widen_Mtype(mtyp))
04444 < MTYPE_size_min(cvtl_mtype))
04445 {
04446 wn = WN_Cvt(cvtl_mtype, Widen_Mtype(mtyp), wn);
04447 }
04448 }
04449 #else
04450 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp), MTYPE_V,
04451 MTYPE_size_min(mtyp), wn);
04452 #endif
04453 else wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04454 }
04455 else {
04456 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(TREE_OPERAND (exp, 0)));
04457 TYPE_ID mtyp0 = TY_mtype(ty_idx0);
04458
04459 if (MTYPE_size_min(mtyp) > MTYPE_size_min(mtyp0) &&
04460 #ifndef KEY
04461 ! Has_Subsumed_Cvtl(WN_operator(wn)))
04462 #else
04463 ! Has_Subsumed_Cvtl(WN_operator(wn)) &&
04464 Widen_Mtype(mtyp0) != mtyp0)
04465 #endif
04466 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp0), MTYPE_V,
04467 MTYPE_size_min(mtyp0), wn);
04468
04469 if (MTYPE_size_min(mtyp) > MTYPE_size_min(WN_rtype(wn)))
04470 wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04471 else {
04472 if (mtyp != WN_rtype(wn))
04473 wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04474 }
04475 }
04476 }
04477 else {
04478 if (mtyp != WN_rtype(wn))
04479 wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04480 }
04481 }
04482 break;
04483
04484 case COMPONENT_REF:
04485 {
04486 INT64 ofst;
04487 arg0 = TREE_OPERAND (exp, 0);
04488 arg1 = TREE_OPERAND (exp, 1);
04489 if (component_ty_idx == 0)
04490 ty_idx = Get_TY (TREE_TYPE(exp));
04491 else ty_idx = component_ty_idx;
04492 if (DECL_BIT_FIELD(arg1))
04493 is_bit_field = TRUE;
04494
04495 if (! is_bit_field &&
04496 component_ty_idx == 0) {
04497
04498 tree sizenode = DECL_SIZE(arg1);
04499 if (
04500 #ifdef KEY
04501 sizenode &&
04502 #endif
04503 TREE_CODE(sizenode) == INTEGER_CST) {
04504 TYPE_ID c_mtyp = TY_mtype(ty_idx);
04505 INT32 bsize = Get_Integer_Value(sizenode);
04506 if (MTYPE_size_min(c_mtyp) > bsize) {
04507 FmtAssert(MTYPE_is_integral(c_mtyp),
04508 ("COMPONENT_REF: integer type expected at inconsistent field size"));
04509 c_mtyp = Mtype_AlignmentClass(bsize >> 3, MTYPE_type_class(c_mtyp));
04510 ty_idx = MTYPE_To_TY(c_mtyp);
04511 }
04512 }
04513 }
04514
04515 if (! is_bit_field)
04516 ofst = (BITSPERBYTE * Get_Integer_Value(DECL_FIELD_OFFSET(arg1)) +
04517 Get_Integer_Value(DECL_FIELD_BIT_OFFSET(arg1)))
04518 / BITSPERBYTE;
04519 else ofst = 0;
04520 wn = WFE_Expand_Expr (arg0, TRUE, nop_ty_idx, ty_idx, ofst+component_offset,
04521 field_id + DECL_FIELD_ID(arg1), is_bit_field);
04522 #ifdef KEY
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532 if (TREE_CODE(arg0) == MODIFY_EXPR) {
04533 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
04534 TYPE_ID desc = TY_mtype(ty_idx);
04535 if (WN_operator(wn) == OPR_ILOAD) {
04536 wn = WN_CreateIload(OPR_ILOAD, rtype, desc,
04537 WN_offset(wn) + ofst + component_offset, ty_idx,
04538 WN_load_addr_ty(wn), WN_kid0(wn),
04539 WN_field_id(wn)+field_id + DECL_FIELD_ID(arg1));
04540 }
04541 else if (WN_operator(wn) == OPR_LDID) {
04542 WN_set_rtype(wn, rtype);
04543 WN_set_desc(wn, desc);
04544 WN_offset(wn) = WN_offset(wn)+ofst+component_offset;
04545 WN_set_ty(wn, ty_idx);
04546
04547
04548 if (TY_kind(ty_idx) != KIND_STRUCT)
04549 WN_set_field_id (wn, 0);
04550 else
04551 WN_set_field_id(wn, WN_field_id(wn)+field_id + DECL_FIELD_ID(arg1));
04552 }
04553 }
04554
04555
04556 else if (TREE_CODE(arg0) == COND_EXPR &&
04557 WN_operator(wn) == OPR_CSELECT &&
04558 WN_rtype(wn) == MTYPE_M)
04559 {
04560
04561 Is_True (WN_rtype (WN_kid1(wn)) == MTYPE_M, ("Unexpected type"));
04562
04563 TY_IDX temp_ty_idx = WN_ty (WN_kid1 (wn));
04564
04565 if (WN_field_id (WN_kid1 (wn)))
04566 temp_ty_idx = get_field_type (temp_ty_idx,
04567 WN_field_id (WN_kid1 (wn)));
04568
04569 ST * temp = Gen_Temp_Symbol (temp_ty_idx, ".mcselect_store");
04570 wn = WN_Stid (MTYPE_M, 0, temp, temp_ty_idx, wn);
04571 WFE_Stmt_Append (wn, Get_Srcpos());
04572
04573 wn = WN_Ldid (TY_mtype (ty_idx), ofst + component_offset,
04574 temp, temp_ty_idx, field_id + DECL_FIELD_ID(arg1));
04575 }
04576 #endif
04577 }
04578 break;
04579
04580 case INDIRECT_REF:
04581 {
04582 UINT xtra_BE_ofst = 0;
04583 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04584
04585 #ifdef KEY
04586 if (!need_result) {
04587 if (TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))) {
04588 WFE_Stmt_Append (WN_CreateEval (wn0), Get_Srcpos ());
04589 }
04590 wn = NULL;
04591 break;
04592 }
04593 #endif
04594
04595 TY_IDX hi_ty_idx = Get_TY(TREE_TYPE(exp));
04596
04597 desc_ty_idx = component_ty_idx;
04598 if (desc_ty_idx == 0)
04599 desc_ty_idx = hi_ty_idx;
04600
04601 #ifdef KEY
04602 TY_IDX iload_ty_idx = desc_ty_idx;
04603 #endif
04604
04605 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
04606 ty_idx = desc_ty_idx;
04607 else {
04608 ty_idx = nop_ty_idx;
04609 if (ty_idx == 0)
04610 ty_idx = desc_ty_idx;
04611 }
04612
04613 if (! is_bit_field) {
04614 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
04615 if (Target_Byte_Sex == BIG_ENDIAN)
04616 xtra_BE_ofst = TY_size(desc_ty_idx) - TY_size(ty_idx);
04617 desc_ty_idx = ty_idx;
04618 }
04619 }
04620 else {
04621 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
04622 ty_idx = desc_ty_idx;
04623 }
04624
04625 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
04626 TYPE_ID desc = TY_mtype(desc_ty_idx);
04627 if (MTYPE_is_integral(desc)) {
04628 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
04629 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
04630 is_bit_field)
04631 rtype = Mtype_TransferSign(desc, rtype);
04632 else desc = Mtype_TransferSign(rtype, desc);
04633 }
04634 }
04635
04636 if (TREE_THIS_VOLATILE(exp))
04637 Set_TY_is_volatile(hi_ty_idx);
04638
04639 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
04640 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
04641
04642 if (!WFE_Keep_Zero_Length_Structs &&
04643 rtype == MTYPE_M &&
04644 TY_size (hi_ty_idx) == 0) {
04645 if (WN_has_side_effects (wn0)) {
04646 wn = WN_CreateEval (wn0);
04647 WFE_Stmt_Append (wn, Get_Srcpos());
04648 }
04649 wn = NULL;
04650 }
04651 else {
04652
04653 if (WN_operator (wn0) == OPR_LDA &&
04654 ST_class (WN_st (wn0)) == CLASS_CONST &&
04655 is_bit_field == FALSE &&
04656 field_id == 0) {
04657 st = WN_st (wn0);
04658 TCON tcon = Tcon_Table [ST_tcon (st)];
04659 if (TCON_ty (tcon) == MTYPE_STRING &&
04660 TY_size (Be_Type_Tbl (desc)) == 1) {
04661 mUINT32 len = Targ_String_Length (tcon);
04662 mUINT64 offset = component_offset + xtra_BE_ofst + WN_offset (wn0);
04663 if (offset <= len &&
04664 desc == MTYPE_U1 &&
04665 (rtype == MTYPE_U4 || rtype == MTYPE_U8)) {
04666 unsigned char *cp = (unsigned char *) Targ_String_Address (tcon);
04667 unsigned long long val = cp [offset];
04668 wn = WN_Intconst (rtype, val);
04669 break;
04670 }
04671 else
04672 if (offset <= len &&
04673 desc == MTYPE_I1 &&
04674 (rtype == MTYPE_I4 || rtype == MTYPE_I8)) {
04675 signed char *cp = (signed char *) Targ_String_Address (tcon);
04676 signed long long val = cp [offset];
04677 wn = WN_Intconst (rtype, val);
04678 break;
04679 }
04680 }
04681 }
04682 wn = WN_CreateIload(OPR_ILOAD, rtype,
04683 is_bit_field ? MTYPE_BS : desc,
04684 component_offset+xtra_BE_ofst,
04685 #ifndef KEY
04686 field_id != 0 ? hi_ty_idx : ty_idx,
04687 #else
04688 field_id != 0 ? hi_ty_idx : iload_ty_idx,
04689 #endif
04690 Make_Pointer_Type (hi_ty_idx, FALSE),
04691 wn0, field_id);
04692 }
04693 }
04694 break;
04695
04696 case CONVERT_EXPR:
04697 case FLOAT_EXPR:
04698 {
04699 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04700 ty_idx = Get_TY (TREE_TYPE(exp));
04701 TYPE_ID mtyp = TY_mtype(ty_idx);
04702 if (mtyp == MTYPE_V)
04703 wn = wn0;
04704 else {
04705 mtyp = Widen_Mtype(TY_mtype(ty_idx));
04706 if (mtyp == WN_rtype(wn0) || mtyp == MTYPE_V)
04707 wn = wn0;
04708 else {
04709 #ifdef KEY // prevent zero extension when converting to 64-bit address type
04710 if (TREE_CODE(TREE_TYPE(exp)) == POINTER_TYPE &&
04711 MTYPE_byte_size(FE_Pointer_Type_To_Mtype()) == 8) {
04712 if (WN_operator(wn0) == OPR_CVT && WN_desc(wn0) == MTYPE_U4) {
04713 WN_set_desc(wn0, MTYPE_I4);
04714 wn = WN_Cvt(WN_rtype(wn0), mtyp, wn0);
04715 }
04716 else if (MTYPE_byte_size(WN_rtype(wn0) == 4))
04717 wn = WN_Cvt(MTYPE_I4, mtyp, wn0);
04718 else wn = WN_Cvt(WN_rtype(wn0), mtyp, wn0);
04719 }
04720 else
04721 #endif
04722 wn = WN_Cvt(WN_rtype(wn0), mtyp, wn0);
04723
04724 if (WN_opcode(wn) == OPC_I4U4CVT ||
04725 WN_opcode(wn) == OPC_U4I4CVT ||
04726 WN_opcode(wn) == OPC_I8U8CVT ||
04727 WN_opcode(wn) == OPC_U8I8CVT) {
04728 wn = WN_kid0 (wn);
04729 }
04730 }
04731 }
04732 }
04733 break;
04734
04735 case FIX_TRUNC_EXPR:
04736 {
04737 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04738 ty_idx = Get_TY (TREE_TYPE(exp));
04739 TYPE_ID mtyp = Widen_Mtype(TY_mtype(ty_idx));
04740 wn = WN_Trunc(WN_rtype(wn0), mtyp, wn0);
04741 }
04742 break;
04743
04744
04745 case PLUS_EXPR:
04746 case MINUS_EXPR:
04747 case MULT_EXPR:
04748 case MAX_EXPR:
04749 case MIN_EXPR:
04750 case LSHIFT_EXPR:
04751 case BIT_AND_EXPR:
04752 case BIT_IOR_EXPR:
04753 case BIT_XOR_EXPR:
04754 case TRUNC_DIV_EXPR:
04755 case TRUNC_MOD_EXPR:
04756 case RDIV_EXPR:
04757 case EXACT_DIV_EXPR:
04758 case TRUTH_AND_EXPR:
04759 case TRUTH_OR_EXPR:
04760 case TRUTH_XOR_EXPR:
04761 case COMPLEX_EXPR:
04762 case CEIL_DIV_EXPR:
04763 {
04764 TYPE_ID etype = TY_mtype(Get_TY(TREE_TYPE(exp)));
04765 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04766 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04767 wn = WN_Binary (Operator_From_Tree [code].opr, Widen_Mtype(etype), wn0, wn1);
04768
04769 #if defined(TARG_SL)
04770 if(WN_operator(wn) == OPR_ADD &&
04771 (WN_operator(WN_kid0(wn)) == OPR_LDA ||
04772 WN_operator(WN_kid(wn, 1)) == OPR_LDA))
04773 {
04774 if(WN_operator(WN_kid0(wn)) == OPR_LDA && WN_has_sym(WN_kid0(wn))) {
04775 ST* vbuf_sym = WN_st(WN_kid0(wn));
04776 if(ST_in_v2buf(vbuf_sym) || ST_in_v4buf(vbuf_sym)) {
04777 if(WN_operator(WN_kid1(wn)) == OPR_MPY) {
04778 WN* tmp = WN_Intconst(MTYPE_U4, ST_in_v2buf(vbuf_sym) ? 2 : 4);
04779 WN_Set_vbuf_ofst_adjusted(tmp);
04780 WN* new_wn = WN_Binary(OPR_MPY, MTYPE_I4, WN_kid1(wn), tmp);
04781 WN_Set_vbuf_ofst_adjusted(new_wn);
04782 WN_kid1(wn) = new_wn;
04783 }
04784 }
04785 }
04786 }
04787 #endif // TARG_SL
04788
04789
04790 if ((MTYPE_is_integral(etype)) &&
04791 (Widen_Mtype(etype) != etype) &&
04792 (TY_size (Get_TY(TREE_TYPE(exp))) < 32) &&
04793 #ifdef KEY
04794 (code == PLUS_EXPR || code == MINUS_EXPR ||
04795 code == MULT_EXPR || code == LSHIFT_EXPR ||
04796 code == BIT_XOR_EXPR || code == BIT_IOR_EXPR)
04797 #else
04798 (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
04799 #endif
04800 )
04801 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(etype), MTYPE_V,
04802 TY_size (Get_TY(TREE_TYPE(exp))) * 8, wn);
04803
04804 }
04805 break;
04806
04807 case LROTATE_EXPR:
04808 {
04809 ty_idx = Get_TY(TREE_TYPE(exp));
04810 TYPE_ID mtype = TY_mtype (ty_idx);
04811 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04812 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04813 wn1 = WN_Binary (OPR_SUB, Widen_Mtype (mtype),
04814 WN_Intconst (Widen_Mtype (mtype),
04815 TY_size (ty_idx) * 8),
04816 wn1);
04817 wn = WN_Rrotate (TY_mtype(Get_TY(TREE_TYPE(exp))), wn0, wn1);
04818 }
04819 break;
04820
04821 case RROTATE_EXPR:
04822 {
04823 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04824 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04825 wn = WN_Rrotate (TY_mtype(Get_TY(TREE_TYPE(exp))), wn0, wn1);
04826 }
04827 break;
04828
04829 case RSHIFT_EXPR:
04830 {
04831 TYPE_ID mtyp = Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp))));
04832 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04833 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04834 wn = WN_Binary (MTYPE_signed(mtyp) ? OPR_ASHR : OPR_LSHR,
04835 mtyp, wn0, wn1);
04836 }
04837 break;
04838
04839 case TRUTH_ANDIF_EXPR:
04840 case TRUTH_ORIF_EXPR:
04841 {
04842 #ifdef KEY // bug 2651
04843 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04844 #else
04845 wn0 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 0),
04846 Boolean_type);
04847 #endif // KEY
04848 wn1 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 1),
04849 Boolean_type);
04850 wn = WN_Binary (Operator_From_Tree [code].opr,
04851 Boolean_type, wn0, wn1);
04852 if (Boolean_type != MTYPE_B &&
04853 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))) != Boolean_type)
04854 wn = WN_Cvt (Boolean_type, Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))), wn);
04855 }
04856 break;
04857
04858 case LT_EXPR:
04859 case LE_EXPR:
04860 case GT_EXPR:
04861 case GE_EXPR:
04862 case EQ_EXPR:
04863 case NE_EXPR:
04864 {
04865 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04866 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04867
04868
04869 ty_idx = Get_TY (TREE_TYPE(exp));
04870 TYPE_ID mtyp = TY_mtype(ty_idx);
04871 #ifdef TARG_NVISA
04872 if (expect_boolean
04873 && (Mtype_TransferSign(Boolean_type, mtyp) != Boolean_type))
04874 {
04875
04876 mtyp = Boolean_type;
04877 }
04878 #endif
04879 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(TREE_OPERAND (exp, 0)));
04880 TYPE_ID mtyp0 = TY_mtype(ty_idx0);
04881 TY_IDX ty_idx1 = Get_TY(TREE_TYPE(TREE_OPERAND (exp, 1)));
04882 TYPE_ID mtyp1 = TY_mtype(ty_idx1);
04883
04884 if (MTYPE_size_min(mtyp1) > MTYPE_size_min(mtyp0) &&
04885 ! Has_Subsumed_Cvtl(WN_operator(wn0)))
04886 wn0 = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp0), MTYPE_V,
04887 MTYPE_size_min(mtyp0), wn0);
04888 if (MTYPE_size_min(mtyp0) > MTYPE_size_min(mtyp1) &&
04889 ! Has_Subsumed_Cvtl(WN_operator(wn1)))
04890 wn1 = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp1), MTYPE_V,
04891 MTYPE_size_min(mtyp1), wn1);
04892
04893 #ifdef TARG_NVISA
04894
04895
04896 wn = WN_CreateExp2(Operator_From_Tree [code].opr, Boolean_type,
04897 Widen_Mtype(mtyp0), wn0, wn1);
04898 #else
04899 wn = WN_CreateExp2(Operator_From_Tree [code].opr, Widen_Mtype(mtyp),
04900 Widen_Mtype(mtyp0), wn0, wn1);
04901 #endif
04902 #ifdef KEY
04903 #ifdef TARG_SL // 32bit target
04904 if ( (Widen_Mtype(mtyp) != Boolean_type) &&
04905 (!MTYPE_is_size_double(mtyp)))
04906 #else
04907 if (Widen_Mtype(mtyp) != Boolean_type)
04908 #endif
04909 wn = WN_Cvt(Boolean_type, Widen_Mtype(mtyp), wn);
04910 #endif
04911 }
04912 break;
04913
04914 case COND_EXPR:
04915 {
04916 ty_idx = Get_TY (TREE_TYPE(exp));
04917 #ifdef KEY // bug 2645
04918 #ifdef TARG_NVISA
04919
04920
04921
04922
04923
04924
04925 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0), TRUE, 0,0,0,0,FALSE,
04926 TRUE );
04927 #else
04928 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04929 #endif
04930 #else
04931 wn0 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 0),
04932 Boolean_type);
04933 #endif
04934 if (TY_mtype (ty_idx) == MTYPE_V) {
04935 WN *then_block = WN_CreateBlock ();
04936 WN *else_block = WN_CreateBlock ();
04937 WN *if_stmt = WN_CreateIf (wn0, then_block, else_block);
04938 WFE_Stmt_Append (if_stmt, Get_Srcpos());
04939 WFE_Stmt_Push (then_block, wfe_stmk_if_then, Get_Srcpos());
04940 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1), FALSE);
04941 if (wn1) {
04942 wn1 = WN_CreateEval (wn1);
04943 WFE_Stmt_Append (wn1, Get_Srcpos());
04944 }
04945 WFE_Stmt_Pop (wfe_stmk_if_then);
04946 WFE_Stmt_Push (else_block, wfe_stmk_if_else, Get_Srcpos());
04947 wn2 = WFE_Expand_Expr (TREE_OPERAND (exp, 2), FALSE);
04948 if (wn2) {
04949 wn2 = WN_CreateEval (wn2);
04950 WFE_Stmt_Append (wn2, Get_Srcpos());
04951 }
04952 WFE_Stmt_Pop (wfe_stmk_if_else);
04953 }
04954 else {
04955 wn1 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 1),
04956 TY_mtype (ty_idx));
04957 wn2 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 2),
04958 TY_mtype (ty_idx));
04959 wn = WN_CreateExp3 (OPR_CSELECT, Mtype_comparison (TY_mtype (ty_idx)),
04960 MTYPE_V, wn0, wn1, wn2);
04961 Set_PU_has_very_high_whirl (Get_Current_PU ());
04962 }
04963 }
04964 break;
04965
04966 case MODIFY_EXPR:
04967 case PREDECREMENT_EXPR:
04968 case PREINCREMENT_EXPR:
04969 case POSTDECREMENT_EXPR:
04970 case POSTINCREMENT_EXPR:
04971 {
04972 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04973 #ifdef TARG_SL
04974 wn = WFE_Lhs_Of_Modify_Expr(code, TREE_OPERAND (exp, 0), TREE_OPERAND(exp,1), need_result,
04975 #else
04976 wn = WFE_Lhs_Of_Modify_Expr(code, TREE_OPERAND (exp, 0), need_result,
04977 #endif
04978 0, 0, 0, FALSE, wn1, 0, FALSE, FALSE);
04979 #if defined(TARG_SL)
04980 Mark_LDA_Vbuf_Offset(wn1, INTRN_VBUF_OFFSET);
04981 #endif
04982
04983 }
04984 break;
04985
04986
04987
04988 case BIT_FIELD_REF:
04989 {
04990 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), TRUE, nop_ty_idx,
04991 component_ty_idx, component_offset,
04992 field_id, FALSE);
04993 #ifdef PATHSCALE_MERGE
04994 #ifdef Is_True_On
04995 {
04996 WN* tmp = wn;
04997 while (WN_operator (tmp) == OPR_CVTL || WN_operator (tmp) == OPR_CVT) {
04998 tmp = WN_kid0(tmp);
04999 }
05000 Is_True (WN_operator(tmp) == OPR_LDID ||
05001 WN_operator(tmp) == OPR_LDBITS ||
05002 WN_operator(tmp) == OPR_ILOAD ||
05003
05004 WN_operator(tmp) == OPR_BAND ||
05005
05006 WN_operator(tmp) == OPR_ILDBITS,
05007 ("Not expected operator"));
05008 }
05009 #endif
05010 INT bofst = Get_Integer_Value(TREE_OPERAND(exp, 2));
05011 INT bsiz =Get_Integer_Value(TREE_OPERAND(exp, 1));
05012 #endif
05013 ty_idx = Get_TY (TREE_TYPE(exp));
05014 TYPE_ID rtype = TY_mtype(ty_idx);
05015 UINT siz = TY_size(ty_idx);
05016 TYPE_ID desc;
05017 if (siz <= 8) {
05018 if (MTYPE_signed(rtype))
05019 desc = Mtype_AlignmentClass(siz, MTYPE_CLASS_INTEGER);
05020 else desc = Mtype_AlignmentClass(siz, MTYPE_CLASS_UNSIGNED_INTEGER);
05021 rtype = Widen_Mtype(desc);
05022 }
05023 else desc = rtype;
05024 #ifdef KEY
05025 while (1) {
05026 if ((WN_operator(wn) == OPR_CVT)
05027 && (desc == rtype)
05028 #ifdef TARG_SL
05029
05030
05031
05032 && WN_operator(WN_kid0(wn)) != OPR_LDA
05033 && WN_operator(WN_kid0(wn)) != OPR_LDID
05034 && WN_operator(WN_kid0(wn)) != OPR_LDBITS
05035 && WN_operator(WN_kid0(wn)) != OPR_ILOAD
05036 #endif
05037 )
05038 {
05039 WN * del = wn;
05040 wn = WN_kid0 (wn);
05041 WN_Delete (del);
05042 }
05043 else break;
05044 }
05045 #endif // KEY
05046 WN_set_rtype(wn, rtype);
05047 #ifdef PATHSCALE_MERGE
05048 #ifdef TARG_IA64
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059 if (!MTYPE_is_void (WN_desc(wn)) &&
05060 (!MTYPE_is_integral (WN_desc(wn)) || MTYPE_bit_size (WN_desc(wn)) >= bsiz))
05061 {
05062 WN_set_desc (wn, desc);
05063 }
05064 #else
05065 if (WN_desc(wn) != MTYPE_V)
05066 WN_set_desc(wn, desc);
05067 #endif
05068 #endif
05069 if ((bsiz & 7) == 0 &&
05070 MTYPE_size_min(desc) % bsiz == 0 &&
05071 bofst % bsiz == 0) {
05072
05073 #ifdef PATHSCALE_MERGE
05074 #ifdef TARG_IA64
05075 BOOL change_desc = FALSE;
05076
05077
05078 if (MTYPE_is_void (WN_desc(wn))) {
05079
05080
05081 } else if (!MTYPE_is_integral (WN_desc(wn))) {
05082
05083
05084 change_desc = TRUE;
05085 } else {
05086
05087
05088 change_desc = (MTYPE_bit_size (WN_desc(wn)) >= bsiz);
05089 }
05090
05091 if (change_desc)
05092 #else
05093 if (WN_desc(wn) != MTYPE_V)
05094 #endif
05095 #endif
05096 if (MTYPE_signed(rtype))
05097 WN_set_desc(wn, Mtype_AlignmentClass(bsiz >> 3, MTYPE_CLASS_INTEGER));
05098 else WN_set_desc(wn, Mtype_AlignmentClass(bsiz >> 3, MTYPE_CLASS_UNSIGNED_INTEGER));
05099 WN_load_offset(wn) = WN_load_offset(wn) + (bofst >> 3);
05100 } else {
05101 #ifdef KEY
05102
05103
05104
05105
05106 mUINT16 base_type_size = MTYPE_bit_size (desc);
05107 WN_load_offset(wn) += (bofst / base_type_size) * MTYPE_byte_size (desc);
05108 bofst = bofst % base_type_size;
05109 #endif
05110 if (WN_operator(wn) == OPR_LDID)
05111 WN_set_operator(wn, OPR_LDBITS);
05112 else WN_set_operator(wn, OPR_ILDBITS);
05113 WN_set_bit_offset_size(wn, bofst, bsiz);
05114 #ifdef PATHSCALE_MERGE
05115 TY_IDX ty = MTYPE_To_TY (WN_desc(wn));
05116 WN_set_ty (wn, ty);
05117 if (WN_operator(wn) == OPR_ILDBITS)
05118 WN_set_load_addr_ty(wn, Make_Pointer_Type(ty));
05119 break;
05120 #endif
05121 }
05122 if (MTYPE_byte_size (WN_desc(wn)) != TY_size(WN_ty(wn)))
05123
05124 #ifdef KEY
05125 {
05126 TY_IDX ty = MTYPE_To_TY (WN_desc(wn));
05127 if ((TY_kind(Ty_Table[WN_ty(wn)]) == KIND_STRUCT)
05128 && (TY_kind(Ty_Table[ty]) != KIND_STRUCT))
05129
05130
05131 WN_set_field_id (wn, 0);
05132 WN_set_ty (wn, ty);
05133 #ifdef PATHSCALE_MERGE
05134 if (WN_operator(wn) == OPR_ILOAD || WN_operator(wn) == OPR_ILDBITS)
05135 WN_set_load_addr_ty(wn, Make_Pointer_Type(ty));
05136 #endif
05137 }
05138 #else
05139 WN_set_ty (wn, MTYPE_To_TY (WN_desc(wn)));
05140 #endif // KEY
05141 }
05142 break;
05143
05144
05145
05146 case ARRAY_REF:
05147 {
05148 UINT xtra_BE_ofst = 0;
05149 TY_IDX elem_ty_idx;
05150
05151 wn0 = WFE_Array_Expr(exp, &elem_ty_idx, 0, 0, 0);
05152
05153
05154 TY_IDX hi_ty_idx = Get_TY (TREE_TYPE(exp));
05155 desc_ty_idx = component_ty_idx;
05156 if (desc_ty_idx == 0)
05157 desc_ty_idx = hi_ty_idx;
05158
05159 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
05160 ty_idx = desc_ty_idx;
05161 else {
05162 ty_idx = nop_ty_idx;
05163 if (ty_idx == 0)
05164 ty_idx = desc_ty_idx;
05165 }
05166
05167 if (! is_bit_field) {
05168 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
05169 if (Target_Byte_Sex == BIG_ENDIAN)
05170 xtra_BE_ofst = TY_size(desc_ty_idx) - TY_size(ty_idx);
05171 desc_ty_idx = ty_idx;
05172 }
05173 }
05174 else {
05175 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
05176 ty_idx = desc_ty_idx;
05177 }
05178
05179 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
05180 TYPE_ID desc = TY_mtype(desc_ty_idx);
05181 if (MTYPE_is_integral(desc)) {
05182 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
05183 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
05184 is_bit_field)
05185 rtype = Mtype_TransferSign(desc, rtype);
05186 else desc = Mtype_TransferSign(rtype, desc);
05187 }
05188 }
05189
05190 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
05191 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
05192 wn = WN_CreateIload(OPR_ILOAD, rtype,
05193 is_bit_field ? MTYPE_BS : desc,
05194 component_offset+xtra_BE_ofst,
05195 field_id != 0 ? hi_ty_idx : ty_idx,
05196 Make_Pointer_Type(elem_ty_idx, FALSE),
05197 wn0, field_id);
05198 }
05199
05200 #if defined(TARG_SL)
05201
05202
05203
05204 if(Mark_LDA_Vbuf_Offset(wn, INTRN_VBUF_OFFSET))
05205 WN_Set_is_internal_mem_ofst(wn);
05206
05207
05208
05209
05210
05211
05212 wn = Adjust_Vbuf_Array_Ofst(wn);
05213
05214 #endif // TARG_SL
05215
05216 break;
05217
05218 case CALL_EXPR:
05219 {
05220 INTRINSIC iopc = INTRINSIC_NONE;
05221 tree arglist = TREE_OPERAND (exp, 1);
05222 TYPE_ID ret_mtype;
05223 WN *call_wn;
05224 WN *arg_wn;
05225 TY_IDX arg_ty_idx;
05226 TYPE_ID arg_mtype;
05227 INT num_args = 0;
05228 INT i;
05229 tree list;
05230 arg0 = TREE_OPERAND (exp, 0);
05231 enum tree_code code0 = TREE_CODE (arg0);
05232 if (LANG_Ansi_Setjmp_On == FALSE) {
05233 if (current_function_calls_setjmp)
05234 Set_PU_calls_setjmp (Get_Current_PU ());
05235 if (current_function_calls_longjmp)
05236 Set_PU_calls_longjmp (Get_Current_PU ());
05237 }
05238 for (list = TREE_OPERAND (exp, 1); list; list = TREE_CHAIN (list)) {
05239 if (TREE_CODE(TREE_VALUE(list)) == ERROR_MARK)
05240 exit (RC_USER_ERROR);
05241 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
05242 if (!WFE_Keep_Zero_Length_Structs &&
05243 TY_mtype (arg_ty_idx) == MTYPE_M &&
05244 TY_size (arg_ty_idx) == 0) {
05245
05246 }
05247 else
05248 num_args++;
05249 }
05250 ty_idx = Get_TY(TREE_TYPE(exp));
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261 if (!WFE_Keep_Zero_Length_Structs &&
05262 TY_mtype (ty_idx) == MTYPE_M &&
05263 TY_size (ty_idx) == 0) {
05264
05265 ret_mtype = MTYPE_V;
05266 }
05267 else
05268 ret_mtype = TY_mtype (ty_idx);
05269
05270
05271
05272 st = NULL;
05273 if (code0 == ADDR_EXPR &&
05274 TREE_CODE (TREE_OPERAND (arg0, 0))) {
05275 tree func = TREE_OPERAND (arg0, 0);
05276 BOOL intrinsic_op = FALSE;
05277 BOOL whirl_generated = FALSE;
05278 BOOL asm_generated = FALSE;
05279 #ifdef KEY
05280
05281
05282 TYPE_ID cvt_to = MTYPE_UNKNOWN;
05283 #endif // KEY
05284
05285 if (DECL_BUILT_IN (func)) {
05286 if (DECL_BUILT_IN_CLASS (func) != BUILT_IN_MD) {
05287
05288 switch (DECL_FUNCTION_CODE (func)) {
05289
05290 case END_BUILTINS:
05291 break;
05292
05293 case BUILT_IN_STDARG_START:
05294 #ifdef KEY
05295 case BUILT_IN_VA_START:
05296 #endif
05297 {
05298 #ifdef TARG_X8664
05299 if( TARGET_64BIT ){
05300 iopc = INTRN_VA_START;
05301 break;
05302 }
05303 #endif
05304 arg1 = TREE_VALUE (arglist);
05305 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
05306 WN *arg_wn = WFE_Expand_Expr (arg1);
05307 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (arg1));
05308 while (TREE_CODE (arg2) == NOP_EXPR
05309 || TREE_CODE (arg2) == CONVERT_EXPR
05310 || TREE_CODE (arg2) == NON_LVALUE_EXPR
05311 || TREE_CODE (arg2) == INDIRECT_REF)
05312 arg2 = TREE_OPERAND (arg2, 0);
05313 ST *st2 = Get_ST (arg2);
05314 #if defined(TARG_X8664) || defined(TARG_SL) || defined(TARG_MIPS)
05315 const int align = PARM_BOUNDARY / BITS_PER_UNIT;
05316 wn = WN_Lda (Pointer_Mtype,
05317 ((TY_size (ST_type (st2)) + align-1) & (-align)),
05318 st2);
05319 #else
05320 wn = WN_Lda (Pointer_Mtype,
05321 ((TY_size (ST_type (st2)) + 7) & (-8)),
05322 st2);
05323 #endif
05324 if (WN_operator (arg_wn) == OPR_LDA) {
05325 wn = WN_Stid (Pointer_Mtype, WN_offset (arg_wn),
05326 WN_st (arg_wn), arg_ty_idx, wn);
05327 }
05328 else {
05329 wn = WN_CreateIstore (OPR_ISTORE, MTYPE_V,
05330 Pointer_Mtype, 0, arg_ty_idx,
05331 wn, arg_wn, 0);
05332 }
05333
05334 WFE_Stmt_Append (wn, Get_Srcpos());
05335 whirl_generated = TRUE;
05336 wn = NULL;
05337 break;
05338 }
05339
05340 #ifndef KEY // Does not exist any more
05341 case BUILT_IN_VARARGS_START:
05342 {
05343 arg1 = TREE_VALUE (arglist);
05344 WN *arg_wn = WFE_Expand_Expr (arg1);
05345 wn = WN_Lda (Pointer_Mtype, 0, WFE_Vararg_Start_ST);
05346 wn = WN_Stid (Pointer_Mtype, WN_offset (arg_wn),
05347 WN_st (arg_wn), arg_ty_idx, wn);
05348
05349 WFE_Stmt_Append (wn, Get_Srcpos());
05350 whirl_generated = TRUE;
05351 wn = NULL;
05352 break;
05353 }
05354 #endif // KEY
05355
05356 case BUILT_IN_VA_COPY:
05357 {
05358 arg1 = TREE_VALUE (arglist);
05359 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
05360 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (arg1));
05361
05362 #ifdef KEY
05363
05364
05365
05366
05367
05368
05369 #if defined(TARG_X8664) || defined(TARG_SL) || defined(TARG_MIPS)
05370 if( !TARGET_64BIT )
05371 #endif
05372 {
05373 FmtAssert( TREE_CODE(arglist) != ARRAY_TYPE,
05374 ("unexpected array type for intrinsic 'va_copy'") );
05375 WN* addr = WFE_Expand_Expr( arg1 );
05376 WN* value = WFE_Expand_Expr( arg2 );
05377 wn = WN_CreateIstore( OPR_ISTORE, MTYPE_V, Pointer_Mtype,
05378 0, arg_ty_idx, value, addr, 0 );
05379
05380 WFE_Stmt_Append( wn, Get_Srcpos() );
05381 whirl_generated = TRUE;
05382 wn = NULL;
05383 break;
05384 }
05385 #endif // KEY
05386
05387 WN *dst = WN_CreateParm (Pointer_Mtype, WFE_Expand_Expr (arg1),
05388 arg_ty_idx, WN_PARM_BY_VALUE);
05389 WN *src = WN_CreateParm (Pointer_Mtype, WFE_Expand_Expr (arg2),
05390 arg_ty_idx, WN_PARM_BY_VALUE);
05391 WN *size = WN_CreateParm (MTYPE_I4,
05392 WN_Intconst(MTYPE_I4,TY_size(TY_pointed(arg_ty_idx))),
05393 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
05394 wn = WN_Create (OPR_INTRINSIC_CALL, ret_mtype, MTYPE_V, 3);
05395 WN_intrinsic (wn) = INTRN_MEMCPY;
05396 WN_kid0 (wn) = dst;
05397 WN_kid1 (wn) = src;
05398 WN_kid2 (wn) = size;
05399 WFE_Stmt_Append (wn, Get_Srcpos());
05400 whirl_generated = TRUE;
05401 wn = NULL;
05402 break;
05403 }
05404
05405 case BUILT_IN_VA_END:
05406 {
05407 arg1 = TREE_VALUE (arglist);
05408 wn = WN_CreateEval ( WFE_Expand_Expr (arg1) );
05409 WFE_Stmt_Append (wn, Get_Srcpos());
05410 whirl_generated = TRUE;
05411 wn = NULL;
05412 break;
05413 }
05414
05415 case BUILT_IN_NEXT_ARG:
05416 {
05417 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
05418 while (TREE_CODE (last_parm) == NOP_EXPR
05419 || TREE_CODE (last_parm) == CONVERT_EXPR
05420 || TREE_CODE (last_parm) == NON_LVALUE_EXPR
05421 || TREE_CODE (last_parm) == INDIRECT_REF)
05422 last_parm = TREE_OPERAND (last_parm, 0);
05423 ST *st = Get_ST (last_parm);
05424 arg_wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
05425 wn = WN_Binary (OPR_ADD, Pointer_Mtype, arg_wn,
05426 WN_Intconst (Pointer_Mtype,
05427 Parameter_Size(ST_size(st))));
05428 whirl_generated = TRUE;
05429 break;
05430 }
05431
05432 case BUILT_IN_ALLOCA:
05433 Set_PU_has_alloca (Get_Current_PU ());
05434 Set_PU_has_user_alloca (Get_Current_PU ());
05435 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05436 wn = WN_CreateAlloca (arg_wn);
05437 whirl_generated = TRUE;
05438 break;
05439
05440 #ifdef TARG_SL
05441 case BUILT_IN_BZERO:
05442 iopc = INTRN_BZERO;
05443 break;
05444 #endif
05445
05446 case BUILT_IN_MEMCPY:
05447 iopc = INTRN_MEMCPY;
05448 break;
05449
05450 case BUILT_IN_MEMCMP:
05451 iopc = INTRN_MEMCMP;
05452 break;
05453
05454 case BUILT_IN_MEMSET:
05455 iopc = INTRN_MEMSET;
05456 break;
05457
05458 case BUILT_IN_STRCPY:
05459 iopc = INTRN_STRCPY;
05460 break;
05461
05462 #ifdef KEY // bug 4872
05463 case BUILT_IN_STRNCPY:
05464 iopc = INTRN_STRNCPY;
05465 break;
05466 #endif // KEY
05467
05468 case BUILT_IN_STRCMP:
05469 if (arglist == 0
05470
05471 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
05472 || TREE_CHAIN (arglist) == 0
05473 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
05474 break;
05475 else {
05476 arg1 = TREE_VALUE (arglist);
05477 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
05478 tree len1 = c_strlen_exported (arg1);
05479 if (len1) {
05480 tree len2 = c_strlen_exported (arg2);
05481 if (len2) {
05482 char *ptr1 = get_string_pointer (WFE_Expand_Expr (arg1));
05483 char *ptr2 = get_string_pointer (WFE_Expand_Expr (arg2));
05484 if (ptr1 && ptr2) {
05485 wn = WN_Intconst (MTYPE_I4,
05486 strcmp (ptr1, ptr2));
05487 whirl_generated = TRUE;
05488 break;
05489 }
05490 }
05491 }
05492 iopc = INTRN_STRCMP;
05493
05494 }
05495 break;
05496
05497 case BUILT_IN_STRLEN:
05498 if (arglist == 0
05499
05500 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
05501 break;
05502 else {
05503 tree src = TREE_VALUE (arglist);
05504 tree len = c_strlen_exported (src);
05505 if (len) {
05506 wn = WFE_Expand_Expr (len);
05507 whirl_generated = TRUE;
05508 }
05509 else {
05510 iopc = INTRN_STRLEN;
05511
05512 }
05513 }
05514 break;
05515
05516 #ifdef KEY
05517 case BUILT_IN_FLOOR:
05518 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05519 #if defined TARG_MIPS
05520 iopc = INTRN_FLOOR;
05521 intrinsic_op = TRUE;
05522 #else
05523 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype , MTYPE_F8, arg_wn);
05524 whirl_generated = TRUE;
05525 #endif
05526 break;
05527
05528 case BUILT_IN_FLOORF:
05529 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05530 #if defined TARG_MIPS
05531 iopc = INTRN_FLOORF;
05532 intrinsic_op = TRUE;
05533 #else
05534 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype, MTYPE_F4, arg_wn);
05535 whirl_generated = TRUE;
05536 #endif
05537 break;
05538
05539 #ifndef TARG_MIPS
05540 case BUILT_IN_FLOORL:
05541 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05542 #ifdef TARG_IA64
05543 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype, MTYPE_F10, arg_wn);
05544 #else
05545 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype, MTYPE_FQ, arg_wn);
05546 #endif // TARG_IA64
05547 whirl_generated = TRUE;
05548 break;
05549 #endif // ! TARG_MIPS
05550 #endif // KEY
05551
05552 #ifdef TARG_NVISA
05553 case BUILT_IN_CEIL:
05554 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05555 wn = WN_CreateExp1 (OPR_CEIL, ret_mtype, MTYPE_F8, arg_wn);
05556 whirl_generated = TRUE;
05557 break;
05558 case BUILT_IN_CEILF:
05559 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05560 wn = WN_CreateExp1 (OPR_CEIL, ret_mtype, MTYPE_F4, arg_wn);
05561 whirl_generated = TRUE;
05562 break;
05563 case BUILT_IN_ROUND:
05564 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05565 wn = WN_CreateExp1 (OPR_RND, ret_mtype, MTYPE_F8, arg_wn);
05566 whirl_generated = TRUE;
05567 break;
05568 case BUILT_IN_ROUNDF:
05569 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05570 wn = WN_CreateExp1 (OPR_RND, ret_mtype, MTYPE_F4, arg_wn);
05571 whirl_generated = TRUE;
05572 break;
05573 case BUILT_IN_TRUNC:
05574 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05575 wn = WN_CreateExp1 (OPR_TRUNC, ret_mtype, MTYPE_F8, arg_wn);
05576 whirl_generated = TRUE;
05577 break;
05578 case BUILT_IN_TRUNCF:
05579 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05580 wn = WN_CreateExp1 (OPR_TRUNC, ret_mtype, MTYPE_F4, arg_wn);
05581 whirl_generated = TRUE;
05582 break;
05583
05584 case BUILT_IN_MIN:
05585 case BUILT_IN_UMIN:
05586 case BUILT_IN_FMINF:
05587 case BUILT_IN_FMIN:
05588 arg1 = TREE_VALUE (arglist);
05589 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
05590 wn = WN_CreateExp2 (OPR_MIN, ret_mtype, MTYPE_V,
05591 WFE_Expand_Expr (arg1), WFE_Expand_Expr(arg2) );
05592 whirl_generated = TRUE;
05593 break;
05594 case BUILT_IN_MAX:
05595 case BUILT_IN_UMAX:
05596 case BUILT_IN_FMAXF:
05597 case BUILT_IN_FMAX:
05598 arg1 = TREE_VALUE (arglist);
05599 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
05600 wn = WN_CreateExp2 (OPR_MAX, ret_mtype, MTYPE_V,
05601 WFE_Expand_Expr (arg1), WFE_Expand_Expr(arg2) );
05602 whirl_generated = TRUE;
05603 break;
05604 case BUILT_IN_MULHI:
05605 case BUILT_IN_UMULHI:
05606 case BUILT_IN_MUL64HI:
05607 case BUILT_IN_UMUL64HI:
05608 arg1 = TREE_VALUE (arglist);
05609 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
05610 wn = WN_CreateExp2 (OPR_HIGHMPY, ret_mtype, MTYPE_V,
05611 WFE_Expand_Expr (arg1), WFE_Expand_Expr(arg2) );
05612 whirl_generated = TRUE;
05613 break;
05614 case BUILT_IN_INT2FLOAT:
05615 case BUILT_IN_FLOAT2INT:
05616 case BUILT_IN_LONGLONG2DOUBLE:
05617 case BUILT_IN_DOUBLE2LONGLONG:
05618 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05619 wn = WN_Tas (ret_mtype, MTYPE_To_TY(ret_mtype), arg_wn);
05620 whirl_generated = TRUE;
05621 break;
05622 #endif
05623
05624 #ifdef TARG_NVISA
05625 case BUILT_IN_SQRT:
05626 case BUILT_IN_SQRTF:
05627
05628 #else
05629 #ifdef KEY
05630 case BUILT_IN_SQRT:
05631 if( flag_errno_math ){
05632 break;
05633 }
05634 #else
05635 case BUILT_IN_FSQRT:
05636 #endif
05637 #endif
05638 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05639 wn = WN_CreateExp1 (OPR_SQRT, ret_mtype, MTYPE_V, arg_wn);
05640 whirl_generated = TRUE;
05641 break;
05642
05643 #ifdef TARG_NVISA
05644
05645
05646
05647
05648
05649
05650 case BUILT_IN_GETSHAREDMEM:
05651 iopc = INTRN_GETSHAREDMEM;
05652 intrinsic_op = TRUE;
05653 break;
05654 case BUILT_IN_GETBLOCKIDPTR:
05655 iopc = INTRN_GETBLOCKIDPTR;
05656 intrinsic_op = TRUE;
05657 break;
05658 case BUILT_IN_RSQRT:
05659 case BUILT_IN_RSQRTF:
05660 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
05661 wn = WN_CreateExp1 (OPR_RSQRT, ret_mtype, MTYPE_V, arg_wn);
05662 whirl_generated = TRUE;
05663 break;
05664 case BUILT_IN_SINF:
05665 iopc = INTRN_F4SIN;
05666 intrinsic_op = TRUE;
05667 break;
05668 case BUILT_IN_COSF:
05669 iopc = INTRN_F4COS;
05670 intrinsic_op = TRUE;
05671 break;
05672 case BUILT_IN_EXP2F:
05673 iopc = INTRN_F4EXP2;
05674 intrinsic_op = TRUE;
05675 break;
05676 case BUILT_IN_EXP2:
05677 iopc = INTRN_F8EXP2;
05678 intrinsic_op = TRUE;
05679 break;
05680 case BUILT_IN_LOG2F:
05681 iopc = INTRN_F4LOG2;
05682 intrinsic_op = TRUE;
05683 break;
05684 case BUILT_IN_LOG2:
05685 iopc = INTRN_F8LOG2;
05686 intrinsic_op = TRUE;
05687 break;
05688 case BUILT_IN_SATURATE:
05689 iopc = INTRN_F8SATURATE;
05690 intrinsic_op = TRUE;
05691 break;
05692 case BUILT_IN_SATURATEF:
05693 iopc = INTRN_F4SATURATE;
05694 intrinsic_op = TRUE;
05695 break;
05696 case BUILT_IN_MUL24:
05697 iopc = INTRN_MUL24;
05698 intrinsic_op = TRUE;
05699 break;
05700 case BUILT_IN_UMUL24:
05701 iopc = INTRN_UMUL24;
05702 intrinsic_op = TRUE;
05703 break;
05704 case BUILT_IN_F4ADD_ROUND:
05705 iopc = INTRN_F4ADD_ROUND;
05706 intrinsic_op = TRUE;
05707 break;
05708 case BUILT_IN_F4ADD_TRUNC:
05709 iopc = INTRN_F4ADD_TRUNC;
05710 intrinsic_op = TRUE;
05711 break;
05712 case BUILT_IN_F8ADD_ROUND:
05713 iopc = INTRN_F8ADD_ROUND;
05714 intrinsic_op = TRUE;
05715 break;
05716 case BUILT_IN_F8ADD_TRUNC:
05717 iopc = INTRN_F8ADD_TRUNC;
05718 intrinsic_op = TRUE;
05719 break;
05720 case BUILT_IN_F8ADD_FLOOR:
05721 iopc = INTRN_F8ADD_FLOOR;
05722 intrinsic_op = TRUE;
05723 break;
05724 case BUILT_IN_F8ADD_CEIL:
05725 iopc = INTRN_F8ADD_CEIL;
05726 intrinsic_op = TRUE;
05727 break;
05728 case BUILT_IN_F4MUL_ROUND:
05729 iopc = INTRN_F4MUL_ROUND;
05730 intrinsic_op = TRUE;
05731 break;
05732 case BUILT_IN_F4MUL_TRUNC:
05733 iopc = INTRN_F4MUL_TRUNC;
05734 intrinsic_op = TRUE;
05735 break;
05736 case BUILT_IN_F8MUL_ROUND:
05737 iopc = INTRN_F8MUL_ROUND;
05738 intrinsic_op = TRUE;
05739 break;
05740 case BUILT_IN_F8MUL_TRUNC:
05741 iopc = INTRN_F8MUL_TRUNC;
05742 intrinsic_op = TRUE;
05743 break;
05744 case BUILT_IN_F8MUL_FLOOR:
05745 iopc = INTRN_F8MUL_FLOOR;
05746 intrinsic_op = TRUE;
05747 break;
05748 case BUILT_IN_F8MUL_CEIL:
05749 iopc = INTRN_F8MUL_CEIL;
05750 intrinsic_op = TRUE;
05751 break;
05752
05753
05754
05755
05756 case BUILT_IN_FMA_ROUND:
05757 iopc = INTRN_F8MA_ROUND;
05758 intrinsic_op = TRUE;
05759 break;
05760 case BUILT_IN_FMA_TRUNC:
05761 iopc = INTRN_F8MA_TRUNC;
05762 intrinsic_op = TRUE;
05763 break;
05764 case BUILT_IN_FMA_FLOOR:
05765 iopc = INTRN_F8MA_FLOOR;
05766 intrinsic_op = TRUE;
05767 break;
05768 case BUILT_IN_FMA_CEIL:
05769 iopc = INTRN_F8MA_CEIL;
05770 intrinsic_op = TRUE;
05771 break;
05772 case BUILT_IN_FMAF:
05773 iopc = INTRN_F4MA;
05774 intrinsic_op = TRUE;
05775 break;
05776 case BUILT_IN_SAD:
05777 iopc = INTRN_I4SAD;
05778 intrinsic_op = TRUE;
05779 break;
05780 case BUILT_IN_USAD:
05781 iopc = INTRN_U4SAD;
05782 intrinsic_op = TRUE;
05783 break;
05784
05785 case BUILT_IN_HILOINT_TO_DOUBLE:
05786 iopc = INTRN_F8HLI2D;
05787 intrinsic_op = TRUE;
05788 break;
05789 case BUILT_IN_DOUBLE_TO_LOINT:
05790 iopc = INTRN_I4D2LI;
05791 intrinsic_op = TRUE;
05792 break;
05793 case BUILT_IN_DOUBLE_TO_HIINT:
05794 iopc = INTRN_I4D2HI;
05795 intrinsic_op = TRUE;
05796 break;
05797 case BUILT_IN_DOUBLE_TO_FLOAT_ROUND:
05798 iopc = INTRN_F4F8CVT_ROUND;
05799 intrinsic_op = TRUE;
05800 break;
05801 case BUILT_IN_DOUBLE_TO_FLOAT_TRUNC:
05802 iopc = INTRN_F4F8CVT_TRUNC;
05803 intrinsic_op = TRUE;
05804 break;
05805 case BUILT_IN_DOUBLE_TO_FLOAT_CEIL:
05806 iopc = INTRN_F4F8CVT_CEIL;
05807 intrinsic_op = TRUE;
05808 break;
05809 case BUILT_IN_DOUBLE_TO_FLOAT_FLOOR:
05810 iopc = INTRN_F4F8CVT_FLOOR;
05811 intrinsic_op = TRUE;
05812 break;
05813 case BUILT_IN_DOUBLE_TO_INT_ROUND:
05814 iopc = INTRN_I4F8CVT_ROUND;
05815 intrinsic_op = TRUE;
05816 break;
05817 case BUILT_IN_DOUBLE_TO_INT_TRUNC:
05818 iopc = INTRN_I4F8CVT_TRUNC;
05819 intrinsic_op = TRUE;
05820 break;
05821 case BUILT_IN_DOUBLE_TO_INT_CEIL:
05822 iopc = INTRN_I4F8CVT_CEIL;
05823 intrinsic_op = TRUE;
05824 break;
05825 case BUILT_IN_DOUBLE_TO_INT_FLOOR:
05826 iopc = INTRN_I4F8CVT_FLOOR;
05827 intrinsic_op = TRUE;
05828 break;
05829 case BUILT_IN_DOUBLE_TO_UINT_ROUND:
05830 iopc = INTRN_U4F8CVT_ROUND;
05831 intrinsic_op = TRUE;
05832 break;
05833 case BUILT_IN_DOUBLE_TO_UINT_TRUNC:
05834 iopc = INTRN_U4F8CVT_TRUNC;
05835 intrinsic_op = TRUE;
05836 break;
05837 case BUILT_IN_DOUBLE_TO_UINT_CEIL:
05838 iopc = INTRN_U4F8CVT_CEIL;
05839 intrinsic_op = TRUE;
05840 break;
05841 case BUILT_IN_DOUBLE_TO_UINT_FLOOR:
05842 iopc = INTRN_U4F8CVT_FLOOR;
05843 intrinsic_op = TRUE;
05844 break;
05845 case BUILT_IN_INT_TO_DOUBLE_ROUND:
05846 iopc = INTRN_F8I4CVT_ROUND;
05847 intrinsic_op = TRUE;
05848 break;
05849 case BUILT_IN_INT_TO_DOUBLE_TRUNC:
05850 iopc = INTRN_F8I4CVT_TRUNC;
05851 intrinsic_op = TRUE;
05852 break;
05853 case BUILT_IN_INT_TO_DOUBLE_FLOOR:
05854 iopc = INTRN_F8I4CVT_FLOOR;
05855 intrinsic_op = TRUE;
05856 break;
05857 case BUILT_IN_INT_TO_DOUBLE_CEIL:
05858 iopc = INTRN_F8I4CVT_CEIL;
05859 intrinsic_op = TRUE;
05860 break;
05861 case BUILT_IN_UINT_TO_DOUBLE_ROUND:
05862 iopc = INTRN_F8U4CVT_ROUND;
05863 intrinsic_op = TRUE;
05864 break;
05865 case BUILT_IN_UINT_TO_DOUBLE_TRUNC:
05866 iopc = INTRN_F8U4CVT_TRUNC;
05867 intrinsic_op = TRUE;
05868 break;
05869 case BUILT_IN_UINT_TO_DOUBLE_FLOOR:
05870 iopc = INTRN_F8U4CVT_FLOOR;
05871 intrinsic_op = TRUE;
05872 break;
05873 case BUILT_IN_UINT_TO_DOUBLE_CEIL:
05874 iopc = INTRN_F8U4CVT_CEIL;
05875 intrinsic_op = TRUE;
05876 break;
05877 case BUILT_IN_INT_TO_FLOAT_ROUND:
05878 iopc = INTRN_F4I4CVT_ROUND;
05879 intrinsic_op = TRUE;
05880 break;
05881 case BUILT_IN_INT_TO_FLOAT_TRUNC:
05882 iopc = INTRN_F4I4CVT_TRUNC;
05883 intrinsic_op = TRUE;
05884 break;
05885 case BUILT_IN_INT_TO_FLOAT_FLOOR:
05886 iopc = INTRN_F4I4CVT_FLOOR;
05887 intrinsic_op = TRUE;
05888 break;
05889 case BUILT_IN_INT_TO_FLOAT_CEIL:
05890 iopc = INTRN_F4I4CVT_CEIL;
05891 intrinsic_op = TRUE;
05892 break;
05893 case BUILT_IN_UINT_TO_FLOAT_ROUND:
05894 iopc = INTRN_F4U4CVT_ROUND;
05895 intrinsic_op = TRUE;
05896 break;
05897 case BUILT_IN_UINT_TO_FLOAT_TRUNC:
05898 iopc = INTRN_F4U4CVT_TRUNC;
05899 intrinsic_op = TRUE;
05900 break;
05901 case BUILT_IN_UINT_TO_FLOAT_FLOOR:
05902 iopc = INTRN_F4U4CVT_FLOOR;
05903 intrinsic_op = TRUE;
05904 break;
05905 case BUILT_IN_UINT_TO_FLOAT_CEIL:
05906 iopc = INTRN_F4U4CVT_CEIL;
05907 intrinsic_op = TRUE;
05908 break;
05909 case BUILT_IN_FLOAT_TO_INT_ROUND:
05910 iopc = INTRN_I4F4CVT_ROUND;
05911 intrinsic_op = TRUE;
05912 break;
05913 case BUILT_IN_FLOAT_TO_INT_TRUNC:
05914 iopc = INTRN_I4F4CVT_TRUNC;
05915 intrinsic_op = TRUE;
05916 break;
05917 case BUILT_IN_FLOAT_TO_INT_FLOOR:
05918 iopc = INTRN_I4F4CVT_FLOOR;
05919 intrinsic_op = TRUE;
05920 break;
05921 case BUILT_IN_FLOAT_TO_INT_CEIL:
05922 iopc = INTRN_I4F4CVT_CEIL;
05923 intrinsic_op = TRUE;
05924 break;
05925 case BUILT_IN_FLOAT_TO_UINT_ROUND:
05926 iopc = INTRN_U4F4CVT_ROUND;
05927 intrinsic_op = TRUE;
05928 break;
05929 case BUILT_IN_FLOAT_TO_UINT_TRUNC:
05930 iopc = INTRN_U4F4CVT_TRUNC;
05931 intrinsic_op = TRUE;
05932 break;
05933 case BUILT_IN_FLOAT_TO_UINT_FLOOR:
05934 iopc = INTRN_U4F4CVT_FLOOR;
05935 intrinsic_op = TRUE;
05936 break;
05937 case BUILT_IN_FLOAT_TO_UINT_CEIL:
05938 iopc = INTRN_U4F4CVT_CEIL;
05939 intrinsic_op = TRUE;
05940 break;
05941 case BUILT_IN_FLOAT_TO_LONGLONG_ROUND:
05942 iopc = INTRN_I8F4CVT_ROUND;
05943 intrinsic_op = TRUE;
05944 break;
05945 case BUILT_IN_FLOAT_TO_LONGLONG_TRUNC:
05946 iopc = INTRN_I8F4CVT_TRUNC;
05947 intrinsic_op = TRUE;
05948 break;
05949 case BUILT_IN_FLOAT_TO_LONGLONG_FLOOR:
05950 iopc = INTRN_I8F4CVT_FLOOR;
05951 intrinsic_op = TRUE;
05952 break;
05953 case BUILT_IN_FLOAT_TO_LONGLONG_CEIL:
05954 iopc = INTRN_I8F4CVT_CEIL;
05955 intrinsic_op = TRUE;
05956 break;
05957 case BUILT_IN_FLOAT_TO_ULONGLONG_ROUND:
05958 iopc = INTRN_U8F4CVT_ROUND;
05959 intrinsic_op = TRUE;
05960 break;
05961 case BUILT_IN_FLOAT_TO_ULONGLONG_TRUNC:
05962 iopc = INTRN_U8F4CVT_TRUNC;
05963 intrinsic_op = TRUE;
05964 break;
05965 case BUILT_IN_FLOAT_TO_ULONGLONG_FLOOR:
05966 iopc = INTRN_U8F4CVT_FLOOR;
05967 intrinsic_op = TRUE;
05968 break;
05969 case BUILT_IN_FLOAT_TO_ULONGLONG_CEIL:
05970 iopc = INTRN_U8F4CVT_CEIL;
05971 intrinsic_op = TRUE;
05972 break;
05973 case BUILT_IN_DOUBLE_TO_LONGLONG_ROUND:
05974 iopc = INTRN_I8F8CVT_ROUND;
05975 intrinsic_op = TRUE;
05976 break;
05977 case BUILT_IN_DOUBLE_TO_LONGLONG_TRUNC:
05978 iopc = INTRN_I8F8CVT_TRUNC;
05979 intrinsic_op = TRUE;
05980 break;
05981 case BUILT_IN_DOUBLE_TO_LONGLONG_FLOOR:
05982 iopc = INTRN_I8F8CVT_FLOOR;
05983 intrinsic_op = TRUE;
05984 break;
05985 case BUILT_IN_DOUBLE_TO_LONGLONG_CEIL:
05986 iopc = INTRN_I8F8CVT_CEIL;
05987 intrinsic_op = TRUE;
05988 break;
05989 case BUILT_IN_DOUBLE_TO_ULONGLONG_ROUND:
05990 iopc = INTRN_U8F8CVT_ROUND;
05991 intrinsic_op = TRUE;
05992 break;
05993 case BUILT_IN_DOUBLE_TO_ULONGLONG_TRUNC:
05994 iopc = INTRN_U8F8CVT_TRUNC;
05995 intrinsic_op = TRUE;
05996 break;
05997 case BUILT_IN_DOUBLE_TO_ULONGLONG_FLOOR:
05998 iopc = INTRN_U8F8CVT_FLOOR;
05999 intrinsic_op = TRUE;
06000 break;
06001 case BUILT_IN_DOUBLE_TO_ULONGLONG_CEIL:
06002 iopc = INTRN_U8F8CVT_CEIL;
06003 intrinsic_op = TRUE;
06004 break;
06005 case BUILT_IN_LONGLONG_TO_FLOAT_ROUND:
06006 iopc = INTRN_F4I8CVT_ROUND;
06007 intrinsic_op = TRUE;
06008 break;
06009 case BUILT_IN_LONGLONG_TO_FLOAT_TRUNC:
06010 iopc = INTRN_F4I8CVT_TRUNC;
06011 intrinsic_op = TRUE;
06012 break;
06013 case BUILT_IN_LONGLONG_TO_FLOAT_FLOOR:
06014 iopc = INTRN_F4I8CVT_FLOOR;
06015 intrinsic_op = TRUE;
06016 break;
06017 case BUILT_IN_LONGLONG_TO_FLOAT_CEIL:
06018 iopc = INTRN_F4I8CVT_CEIL;
06019 intrinsic_op = TRUE;
06020 break;
06021 case BUILT_IN_ULONGLONG_TO_FLOAT_ROUND:
06022 iopc = INTRN_F4U8CVT_ROUND;
06023 intrinsic_op = TRUE;
06024 break;
06025 case BUILT_IN_ULONGLONG_TO_FLOAT_TRUNC:
06026 iopc = INTRN_F4U8CVT_TRUNC;
06027 intrinsic_op = TRUE;
06028 break;
06029 case BUILT_IN_ULONGLONG_TO_FLOAT_FLOOR:
06030 iopc = INTRN_F4U8CVT_FLOOR;
06031 intrinsic_op = TRUE;
06032 break;
06033 case BUILT_IN_ULONGLONG_TO_FLOAT_CEIL:
06034 iopc = INTRN_F4U8CVT_CEIL;
06035 intrinsic_op = TRUE;
06036 break;
06037 case BUILT_IN_LONGLONG_TO_DOUBLE_ROUND:
06038 iopc = INTRN_F8I8CVT_ROUND;
06039 intrinsic_op = TRUE;
06040 break;
06041 case BUILT_IN_LONGLONG_TO_DOUBLE_TRUNC:
06042 iopc = INTRN_F8I8CVT_TRUNC;
06043 intrinsic_op = TRUE;
06044 break;
06045 case BUILT_IN_LONGLONG_TO_DOUBLE_FLOOR:
06046 iopc = INTRN_F8I8CVT_FLOOR;
06047 intrinsic_op = TRUE;
06048 break;
06049 case BUILT_IN_LONGLONG_TO_DOUBLE_CEIL:
06050 iopc = INTRN_F8I8CVT_CEIL;
06051 intrinsic_op = TRUE;
06052 break;
06053 case BUILT_IN_ULONGLONG_TO_DOUBLE_ROUND:
06054 iopc = INTRN_F8U8CVT_ROUND;
06055 intrinsic_op = TRUE;
06056 break;
06057 case BUILT_IN_ULONGLONG_TO_DOUBLE_TRUNC:
06058 iopc = INTRN_F8U8CVT_TRUNC;
06059 intrinsic_op = TRUE;
06060 break;
06061 case BUILT_IN_ULONGLONG_TO_DOUBLE_FLOOR:
06062 iopc = INTRN_F8U8CVT_FLOOR;
06063 intrinsic_op = TRUE;
06064 break;
06065 case BUILT_IN_ULONGLONG_TO_DOUBLE_CEIL:
06066 iopc = INTRN_F8U8CVT_CEIL;
06067 intrinsic_op = TRUE;
06068 break;
06069 #endif
06070
06071 case BUILT_IN_SIN:
06072 intrinsic_op = TRUE;
06073 #ifdef TARG_X8664
06074 if (!Force_IEEE_Comparisons)
06075 {
06076 iopc = INTRN_SINL;
06077 if (ret_mtype != MTYPE_FQ)
06078 {
06079
06080 cvt_to = ret_mtype;
06081 ret_mtype = MTYPE_FQ;
06082 }
06083 break;
06084 }
06085 #endif
06086
06087 #ifdef KEY
06088
06089 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06090 #endif
06091 if (ret_mtype == MTYPE_F4) iopc = INTRN_F4SIN;
06092 else if (ret_mtype == MTYPE_F8) iopc = INTRN_F8SIN;
06093 else Fail_FmtAssertion ("unexpected mtype for intrinsic 'sin'");
06094 break;
06095
06096 case BUILT_IN_COS:
06097 intrinsic_op = TRUE;
06098 #ifdef TARG_X8664
06099 if (!Force_IEEE_Comparisons)
06100 {
06101 iopc = INTRN_COSL;
06102 if (ret_mtype != MTYPE_FQ)
06103 {
06104
06105 cvt_to = ret_mtype;
06106 ret_mtype = MTYPE_FQ;
06107 }
06108 break;
06109 }
06110 #endif
06111
06112 #ifdef KEY
06113
06114 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06115 #endif
06116 if (ret_mtype == MTYPE_F4) iopc = INTRN_F4COS;
06117 else if (ret_mtype == MTYPE_F8) iopc = INTRN_F8COS;
06118 else Fail_FmtAssertion ("unexpected mtype for intrinsic 'cos'");
06119 break;
06120
06121 #ifdef KEY
06122 case BUILT_IN_EXP:
06123 case BUILT_IN_EXPF:
06124
06125
06126
06127
06128 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06129
06130 if (ret_mtype == MTYPE_F4) iopc = INTRN_F4EXP;
06131 else if (ret_mtype == MTYPE_F8) iopc = INTRN_F8EXP;
06132 else Fail_FmtAssertion ("unexpected mtype for intrinsic 'exp'");
06133 intrinsic_op = TRUE;
06134 break;
06135
06136 case BUILT_IN_POW:
06137
06138
06139
06140
06141
06142
06143
06144
06145
06146
06147 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06148
06149 FmtAssert(ret_mtype == MTYPE_F8,
06150 ("unexpected mtype for intrinsic 'pow'"));
06151 iopc = INTRN_F8EXPEXPR;
06152 intrinsic_op = TRUE;
06153 break;
06154 #endif // KEY
06155
06156 case BUILT_IN_CONSTANT_P:
06157 {
06158 tree arg = TREE_VALUE (TREE_OPERAND (exp, 1));
06159 STRIP_NOPS (arg);
06160 if (really_constant_p (arg)
06161 || (TREE_CODE (arg) == ADDR_EXPR
06162 && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
06163 {
06164 wn = WN_Intconst (MTYPE_I4, 1);
06165 whirl_generated = TRUE;
06166 }
06167 #ifdef KEY
06168
06169
06170 else
06171 {
06172 iopc = INTRN_CONSTANT_P;
06173 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_I4;
06174 intrinsic_op = TRUE;
06175 }
06176 #else
06177 else
06178 wn = WN_Intconst (MTYPE_I4, 0);
06179
06180 whirl_generated = TRUE;
06181 #endif // KEY
06182 break;
06183 }
06184
06185 #if 0
06186 case BUILT_IN_LOCK_TEST_AND_SET:
06187 wn = emit_builtin_lock_test_and_set (exp, num_args-2);
06188 whirl_generated = TRUE;
06189 break;
06190
06191 case BUILT_IN_LOCK_RELEASE:
06192 emit_builtin_lock_release (exp, num_args-1);
06193 whirl_generated = TRUE;
06194 break;
06195
06196 case BUILT_IN_COMPARE_AND_SWAP:
06197 wn = emit_builtin_compare_and_swap (exp, num_args-3);
06198 whirl_generated = TRUE;
06199 break;
06200
06201 case BUILT_IN_SYNCHRONIZE:
06202 emit_builtin_synchronize (exp, num_args);
06203 whirl_generated = TRUE;
06204 break;
06205 #endif
06206
06207 #ifdef TARG_NVISA
06208 case BUILT_IN_SYNCHRONIZE:
06209 emit_builtin_synchronize (exp, num_args);
06210 whirl_generated = TRUE;
06211 break;
06212 case BUILT_IN_BRKPT:
06213 emit_builtin_brkpt ();
06214 whirl_generated = TRUE;
06215 break;
06216 case BUILT_IN_TRAP:
06217 emit_builtin_trap ();
06218 whirl_generated = TRUE;
06219 break;
06220 case BUILT_IN_CLOCK:
06221
06222 wn = emit_builtin_clock ();
06223 whirl_generated = TRUE;
06224 break;
06225 case BUILT_IN_IATOMICADD:
06226 wn = emit_builtin_atomic (exp, 2, MTYPE_I4, INTRN_I4ATOMICADD);
06227 whirl_generated = TRUE;
06228 break;
06229 case BUILT_IN_UATOMICADD:
06230 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICADD);
06231 whirl_generated = TRUE;
06232 break;
06233 case BUILT_IN_ULLATOMICADD:
06234 wn = emit_builtin_atomic (exp, 2, MTYPE_U8, INTRN_U8ATOMICADD);
06235 whirl_generated = TRUE;
06236 break;
06237 case BUILT_IN_FATOMICADD:
06238 wn = emit_builtin_atomic (exp, 2, MTYPE_F4, INTRN_F4ATOMICADD);
06239 whirl_generated = TRUE;
06240 break;
06241 case BUILT_IN_DATOMICADD:
06242 wn = emit_builtin_atomic (exp, 2, MTYPE_F8, INTRN_F8ATOMICADD);
06243 whirl_generated = TRUE;
06244 break;
06245 case BUILT_IN_IATOMICMIN:
06246 wn = emit_builtin_atomic (exp, 2, MTYPE_I4, INTRN_I4ATOMICMIN);
06247 whirl_generated = TRUE;
06248 break;
06249 case BUILT_IN_UATOMICMIN:
06250 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICMIN);
06251 whirl_generated = TRUE;
06252 break;
06253 case BUILT_IN_FATOMICMIN:
06254 wn = emit_builtin_atomic (exp, 2, MTYPE_F4, INTRN_F4ATOMICMIN);
06255 whirl_generated = TRUE;
06256 break;
06257 case BUILT_IN_IATOMICMAX:
06258 wn = emit_builtin_atomic (exp, 2, MTYPE_I4, INTRN_I4ATOMICMAX);
06259 whirl_generated = TRUE;
06260 break;
06261 case BUILT_IN_UATOMICMAX:
06262 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICMAX);
06263 whirl_generated = TRUE;
06264 break;
06265 case BUILT_IN_FATOMICMAX:
06266 wn = emit_builtin_atomic (exp, 2, MTYPE_F4, INTRN_F4ATOMICMAX);
06267 whirl_generated = TRUE;
06268 break;
06269 case BUILT_IN_IATOMICEXCH:
06270 wn = emit_builtin_atomic (exp, 2, MTYPE_I4, INTRN_I4ATOMICEXCH);
06271 whirl_generated = TRUE;
06272 break;
06273 case BUILT_IN_UATOMICEXCH:
06274 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICEXCH);
06275 whirl_generated = TRUE;
06276 break;
06277 case BUILT_IN_ULLATOMICEXCH:
06278 wn = emit_builtin_atomic (exp, 2, MTYPE_U8, INTRN_U8ATOMICEXCH);
06279 whirl_generated = TRUE;
06280 break;
06281 case BUILT_IN_FATOMICEXCH:
06282 wn = emit_builtin_atomic (exp, 2, MTYPE_F4, INTRN_F4ATOMICEXCH);
06283 whirl_generated = TRUE;
06284 break;
06285 case BUILT_IN_DATOMICEXCH:
06286 wn = emit_builtin_atomic (exp, 2, MTYPE_F8, INTRN_F8ATOMICEXCH);
06287 whirl_generated = TRUE;
06288 break;
06289 case BUILT_IN_IATOMICAND:
06290 case BUILT_IN_UATOMICAND:
06291 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICAND);
06292 whirl_generated = TRUE;
06293 break;
06294 case BUILT_IN_IATOMICOR:
06295 case BUILT_IN_UATOMICOR:
06296 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICOR);
06297 whirl_generated = TRUE;
06298 break;
06299 case BUILT_IN_IATOMICXOR:
06300 case BUILT_IN_UATOMICXOR:
06301 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICXOR);
06302 whirl_generated = TRUE;
06303 break;
06304 case BUILT_IN_UATOMICINC:
06305 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICINC);
06306 whirl_generated = TRUE;
06307 break;
06308 case BUILT_IN_UATOMICDEC:
06309 wn = emit_builtin_atomic (exp, 2, MTYPE_U4, INTRN_U4ATOMICDEC);
06310 whirl_generated = TRUE;
06311 break;
06312 case BUILT_IN_IATOMICCAS:
06313 wn = emit_builtin_atomic (exp, 3, MTYPE_I4, INTRN_I4ATOMICCAS);
06314 whirl_generated = TRUE;
06315 break;
06316 case BUILT_IN_UATOMICCAS:
06317 wn = emit_builtin_atomic (exp, 3, MTYPE_U4, INTRN_U4ATOMICCAS);
06318 whirl_generated = TRUE;
06319 break;
06320 case BUILT_IN_ULLATOMICCAS:
06321 wn = emit_builtin_atomic (exp, 3, MTYPE_U8, INTRN_U8ATOMICCAS);
06322 whirl_generated = TRUE;
06323 break;
06324 case BUILT_IN_FATOMICCAS:
06325 wn = emit_builtin_atomic (exp, 3, MTYPE_F4, INTRN_F4ATOMICCAS);
06326 whirl_generated = TRUE;
06327 break;
06328 case BUILT_IN_DATOMICCAS:
06329 wn = emit_builtin_atomic (exp, 3, MTYPE_F8, INTRN_F8ATOMICCAS);
06330 whirl_generated = TRUE;
06331 break;
06332
06333 case BUILT_IN_ALL:
06334 wn = emit_builtin_vote (exp, INTRN_VOTEALL);
06335 whirl_generated = TRUE;
06336 break;
06337 case BUILT_IN_ANY:
06338 wn = emit_builtin_vote (exp, INTRN_VOTEANY);
06339 whirl_generated = TRUE;
06340 break;
06341
06342 #endif
06343
06344 case BUILT_IN_RETURN_ADDRESS:
06345 i = Get_Integer_Value (TREE_VALUE (TREE_OPERAND (exp, 1)));
06346 if (i > 0) {
06347
06348
06349
06350 warning("non-zero levels not supported for builtin_return_address");
06351 wn = WN_Intconst(Pointer_Mtype, 0);
06352 }
06353 else {
06354 st = WFE_Get_Return_Address_ST (i);
06355 wn = WN_Ldid (Pointer_Mtype, 0, st, ST_type (st));
06356 }
06357 whirl_generated = TRUE;
06358 break;
06359
06360 #ifdef KEY
06361 case BUILT_IN_EXTRACT_RETURN_ADDR:
06362 list = TREE_OPERAND (exp, 1);
06363 wn = WFE_Expand_Expr (TREE_VALUE (list));
06364 wn = WN_Binary (OPR_BAND, Pointer_Mtype, wn,
06365 WN_Intconst(Pointer_Mtype, -2));
06366 whirl_generated = TRUE;
06367 break;
06368
06369 case BUILT_IN_FRAME_ADDRESS:
06370 Set_PU_has_alloca(Get_Current_PU());
06371 iopc = MTYPE_byte_size(Pointer_Mtype) == 4 ?
06372 INTRN_U4READFRAMEPOINTER : INTRN_U4READFRAMEPOINTER;
06373 intrinsic_op = TRUE;
06374 break;
06375 case BUILT_IN_APPLY_ARGS:
06376 Set_PU_has_alloca(Get_Current_PU());
06377 iopc = INTRN_APPLY_ARGS;
06378 break;
06379 case BUILT_IN_APPLY:
06380 {
06381 WN *load_wn, *sp_addr;
06382
06383 Set_PU_has_alloca(Get_Current_PU());
06384
06385 iopc = INTRN_APPLY;
06386 call_wn = WN_Create (OPR_INTRINSIC_CALL, ret_mtype, MTYPE_V,
06387 num_args);
06388 WN_intrinsic (call_wn) = iopc;
06389 WN_Set_Linenum (call_wn, Get_Srcpos());
06390 WN_Set_Call_Default_Flags (call_wn);
06391 i = 0;
06392 BOOL generate_mload = FALSE;
06393 WN *kid1 = NULL;
06394 WN *kid2 = NULL;
06395 for (list = TREE_OPERAND (exp, 1);
06396 list;
06397 list = TREE_CHAIN (list)) {
06398 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
06399 if (i == 1)
06400 kid1 = arg_wn;
06401 if (i == 2 &&
06402 WN_operator(arg_wn) != OPR_INTCONST) {
06403 generate_mload = TRUE;
06404 kid2 = arg_wn;
06405 } else if (i == 2)
06406 kid2 = arg_wn;
06407 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
06408 arg_mtype = TY_mtype(arg_ty_idx);
06409 arg_wn = WN_CreateParm (Mtype_comparison (arg_mtype),
06410 arg_wn,
06411 arg_ty_idx, WN_PARM_BY_VALUE);
06412 WN_kid (call_wn, i++) = arg_wn;
06413 }
06414
06415
06416 TY_IDX ty_idx =
06417 Make_Pointer_Type (Be_Type_Tbl (MTYPE_V), FALSE);
06418 ST* alloca_st_0 =
06419 Gen_Temp_Symbol (ty_idx,
06420 "__builtin_apply_alloca0");
06421 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL,
06422 alloca_st_0);
06423 WN *alloca_0 =
06424 WN_CreateAlloca (WN_CreateIntconst (OPC_I4INTCONST, 0));
06425 WN *alloca_kid0 = alloca_0;
06426 alloca_kid0 =
06427 WN_Stid (Pointer_Mtype,
06428 0, alloca_st_0, ty_idx, alloca_kid0);
06429 WFE_Stmt_Append (alloca_kid0, Get_Srcpos());
06430 ST *alloca_st_1 =
06431 Gen_Temp_Symbol (ty_idx,
06432 "__builtin_apply_alloca1");
06433 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL,
06434 alloca_st_1);
06435 WN *alloca_1 = WN_CreateAlloca (kid2);
06436 WN *alloca_kid1 = alloca_1;
06437 alloca_kid1 = WN_Stid (Pointer_Mtype,
06438 0, alloca_st_1, ty_idx, alloca_kid1);
06439 WFE_Stmt_Append (alloca_kid1, Get_Srcpos());
06440
06441
06442 kid1 =
06443 WN_CreateIload (OPR_ILOAD, MTYPE_I4, MTYPE_I4, 0,
06444 MTYPE_To_TY(MTYPE_I4),
06445 Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8)),
06446 kid1, 0);
06447 load_wn =
06448 WN_CreateMload (0,
06449 Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8)),
06450 kid1, kid2);
06451 sp_addr = WN_LdidPreg(MTYPE_U4, 29);
06452 WFE_Stmt_Append(WN_CreateMstore (0,
06453 Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8)),
06454 load_wn,
06455 sp_addr,
06456 kid2),
06457 Get_Srcpos());
06458
06459 WFE_Stmt_Append (call_wn, Get_Srcpos());
06460
06461 call_wn = WN_Create (OPR_ICALL, ret_mtype, MTYPE_V, 1);
06462 WN_kid(call_wn, 0) =
06463 WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06464 WN_set_ty (call_wn, TY_pointed(Get_TY(
06465 TREE_TYPE (TREE_VALUE(TREE_OPERAND (exp, 1))))));
06466 WFE_Stmt_Append (call_wn, Get_Srcpos());
06467
06468 TY_IDX tyi;
06469 TY& ty = New_TY(tyi);
06470 TY_Init(ty, 16, KIND_STRUCT, MTYPE_M,
06471 Save_Str("__apply"));
06472 Set_TY_align(tyi, 8);
06473 ST *tmpst = New_ST(CURRENT_SYMTAB);
06474 ST_Init(tmpst, TY_name_idx(ty),
06475 CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, tyi);
06476 Set_ST_is_temp_var(tmpst);
06477 WN *load, *store;
06478 load = WN_LdidPreg(MTYPE_I8, 2);
06479 store = WN_Stid(MTYPE_I8,
06480 (WN_OFFSET)0, tmpst, Spill_Int_Type, load);
06481 WFE_Stmt_Append (store, Get_Srcpos());
06482 load = WN_LdidPreg(MTYPE_F8, 32);
06483 store = WN_Stid(MTYPE_F8,
06484 (WN_OFFSET)8, tmpst, Spill_Int_Type, load);
06485 WFE_Stmt_Append (store, Get_Srcpos());
06486 wn = WN_Lda (Pointer_Mtype, 0, tmpst,
06487 Make_Pointer_Type (ST_type(tmpst), FALSE));
06488
06489
06490 WN *dealloca_wn = WN_CreateDealloca (2);
06491 WN_kid0 (dealloca_wn) =
06492 WN_Ldid (Pointer_Mtype,
06493 0, alloca_st_0, ST_type (alloca_st_0));
06494 WN_kid1 (dealloca_wn) =
06495 WN_Ldid (Pointer_Mtype,
06496 0, alloca_st_1, ST_type (alloca_st_1));
06497 WFE_Stmt_Append (dealloca_wn, Get_Srcpos());
06498
06499 whirl_generated = TRUE;
06500 break;
06501 }
06502 case BUILT_IN_RETURN:
06503 Set_PU_has_alloca(Get_Current_PU());
06504 iopc = INTRN_RETURN;
06505 break;
06506
06507
06508
06509
06510 case BUILT_IN_ISGREATER:
06511 iopc = INTRN_ISGREATER;
06512 intrinsic_op = TRUE;
06513 break;
06514 case BUILT_IN_ISGREATEREQUAL:
06515 iopc = INTRN_ISGREATEREQUAL;
06516 intrinsic_op = TRUE;
06517 break;
06518 case BUILT_IN_ISLESS:
06519 iopc = INTRN_ISLESS;
06520 intrinsic_op = TRUE;
06521 break;
06522 case BUILT_IN_ISLESSEQUAL:
06523 iopc = INTRN_ISLESSEQUAL;
06524 intrinsic_op = TRUE;
06525 break;
06526 case BUILT_IN_ISLESSGREATER:
06527 iopc = INTRN_ISLESSGREATER;
06528 intrinsic_op = TRUE;
06529 break;
06530 case BUILT_IN_ISUNORDERED:
06531 iopc = INTRN_ISUNORDERED;
06532 intrinsic_op = TRUE;
06533 break;
06534 #endif
06535
06536 case BUILT_IN_EXPECT:
06537 {
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547
06548
06549 #ifdef KEY
06550 iopc = INTRN_EXPECT;
06551 intrinsic_op = TRUE;
06552 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_I4;
06553 #else
06554 list = TREE_OPERAND (exp, 1);
06555 wn = WFE_Expand_Expr (TREE_VALUE (list));
06556 whirl_generated = TRUE;
06557 #endif
06558 break;
06559 }
06560
06561 case BUILT_IN_FFS:
06562 iopc = INTRN_I4FFS;
06563 intrinsic_op = TRUE;
06564 if (ret_mtype == MTYPE_V)
06565 ret_mtype = MTYPE_I4;
06566 break;
06567 case BUILT_IN_CTYPE_B_LOC:
06568 iopc = INTRN_CTYPE_B_LOC;
06569 intrinsic_op = TRUE;
06570 break;
06571
06572 case BUILT_IN_CTYPE_TOUPPER_LOC:
06573 iopc = INTRN_CTYPE_TOUPPER_LOC;
06574 intrinsic_op = TRUE;
06575 break;
06576
06577 case BUILT_IN_CTYPE_TOLOWER_LOC:
06578 iopc = INTRN_CTYPE_TOLOWER_LOC;
06579 intrinsic_op = TRUE;
06580 break;
06581
06582 #ifdef KEY
06583 case BUILT_IN_EXTEND_POINTER:
06584 wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06585 whirl_generated = TRUE;
06586 break;
06587
06588 #ifndef TARG_NVISA // handle elsewhere
06589 case BUILT_IN_TRAP:
06590 call_wn = WN_Create (OPR_CALL, MTYPE_V, MTYPE_V, 0);
06591 st = Get_ST (TREE_OPERAND (arg0, 0));
06592 Set_ST_name_idx (st, Save_Str ("abort"));
06593 WN_st_idx (call_wn) = ST_st_idx (st);
06594 WN_Set_Linenum (call_wn, Get_Srcpos());
06595 WN_Set_Call_Default_Flags (call_wn);
06596 WFE_Stmt_Append (call_wn, Get_Srcpos());
06597 whirl_generated = TRUE;
06598 break;
06599 #endif
06600
06601 case BUILT_IN_PREFETCH:
06602 {
06603
06604 tree pf_arg = TREE_OPERAND (exp, 1);
06605 WN * pf_addr = WFE_Expand_Expr (TREE_VALUE (pf_arg));
06606
06607
06608 pf_arg = TREE_CHAIN (pf_arg);
06609 UINT32 pf_flag = 0;
06610 int access = 0;
06611 if (pf_arg && TREE_CODE (TREE_VALUE (pf_arg)) == INTEGER_CST)
06612 access = Get_Integer_Value (TREE_VALUE (pf_arg));
06613 if (access == 0)
06614 PF_SET_READ (pf_flag);
06615 else
06616 PF_SET_WRITE (pf_flag);
06617
06618
06619
06620 PF_SET_MANUAL (pf_flag);
06621 WFE_Stmt_Append (WN_CreatePrefetch (0, pf_flag, pf_addr),
06622 Get_Srcpos());
06623 whirl_generated = TRUE;
06624 }
06625 break;
06626 #endif // KEY
06627
06628 #ifdef TARG_X8664
06629 case BUILT_IN_COSF:
06630 case BUILT_IN_COSL:
06631 if (!Force_IEEE_Comparisons)
06632 {
06633 iopc = INTRN_COSL;
06634 intrinsic_op = TRUE;
06635 if (ret_mtype != MTYPE_FQ)
06636 {
06637
06638 cvt_to = ret_mtype;
06639 ret_mtype = MTYPE_FQ;
06640 }
06641 }
06642 break;
06643
06644 case BUILT_IN_SINF:
06645 case BUILT_IN_SINL:
06646 if (!Force_IEEE_Comparisons)
06647 {
06648 iopc = INTRN_SINL;
06649 intrinsic_op = TRUE;
06650 if (ret_mtype != MTYPE_FQ)
06651 {
06652
06653 cvt_to = ret_mtype;
06654 ret_mtype = MTYPE_FQ;
06655 }
06656 }
06657 break;
06658 #endif // TARG_X8664
06659
06660 #ifdef KEY
06661 case BUILT_IN_TAN:
06662
06663 if (ret_mtype == MTYPE_F8)
06664 {
06665 iopc = INTRN_TAN;
06666 intrinsic_op = TRUE;
06667 }
06668 break;
06669 #endif
06670
06671 #if 0
06672 case BUILT_IN_ROUND_F2LL:
06673 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06674 wn = WN_CreateExp1 (OPR_RND, MTYPE_I8, MTYPE_F4, arg_wn);
06675 whirl_generated = TRUE;
06676 break;
06677
06678 case BUILT_IN_ROUND_D2LL:
06679 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06680 wn = WN_CreateExp1 (OPR_RND, MTYPE_I8, MTYPE_F8, arg_wn);
06681 whirl_generated = TRUE;
06682 break;
06683
06684 case BUILT_IN_ROUND_ED2LL:
06685 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06686 wn = WN_CreateExp1 (OPR_RND, MTYPE_I8, MTYPE_F10, arg_wn);
06687 whirl_generated = TRUE;
06688 break;
06689
06690 case BUILT_IN_CAST_I2F:
06691 list = TREE_OPERAND (exp, 1);
06692 wn = WFE_Expand_Expr (TREE_VALUE (list));
06693 wn = WN_Tas (MTYPE_F4, Be_Type_Tbl(MTYPE_I4), wn);
06694 whirl_generated = TRUE;
06695 break;
06696
06697 case BUILT_IN_CAST_F2I:
06698 list = TREE_OPERAND (exp, 1);
06699 wn = WFE_Expand_Expr (TREE_VALUE (list));
06700 wn = WN_Tas (MTYPE_I4, Be_Type_Tbl(MTYPE_F4), wn);
06701 whirl_generated = TRUE;
06702 break;
06703
06704 case BUILT_IN_CAST_LL2D:
06705 list = TREE_OPERAND (exp, 1);
06706 wn = WFE_Expand_Expr (TREE_VALUE (list));
06707 wn = WN_Tas (MTYPE_F8, Be_Type_Tbl(MTYPE_I8), wn);
06708 whirl_generated = TRUE;
06709 break;
06710
06711 case BUILT_IN_CAST_D2LL:
06712 list = TREE_OPERAND (exp, 1);
06713 wn = WFE_Expand_Expr (TREE_VALUE (list));
06714 wn = WN_Tas (MTYPE_I8, Be_Type_Tbl(MTYPE_F8), wn);
06715 whirl_generated = TRUE;
06716 break;
06717
06718 case BUILT_IN_GETF_EXP:
06719 iopc = INTRN_GETF_EXP;
06720 intrinsic_op = TRUE;
06721 break;
06722
06723 case BUILT_IN_GETF_SIG:
06724 iopc = INTRN_GETF_SIG;
06725 intrinsic_op = TRUE;
06726 break;
06727
06728 case BUILT_IN_SETF_EXP:
06729 iopc = INTRN_SETF_EXP;
06730 intrinsic_op = TRUE;
06731 break;
06732
06733 case BUILT_IN_SETF_SIG:
06734 iopc = INTRN_SETF_SIG;
06735 intrinsic_op = TRUE;
06736 break;
06737
06738 case BUILT_IN_FMERGE_NS:
06739 iopc = INTRN_FMERGE_NS;
06740 intrinsic_op = TRUE;
06741 break;
06742
06743 case BUILT_IN_FMERGE_S:
06744 iopc = INTRN_FMERGE_S;
06745 intrinsic_op = TRUE;
06746 break;
06747
06748 case BUILT_IN_FMERGE_SE:
06749 iopc = INTRN_FMERGE_SE;
06750 intrinsic_op = TRUE;
06751 break;
06752 #endif
06753
06754 #if defined(TARG_SL)
06755 case BUILT_IN_PERIPHERAL_RW_BEGIN:
06756 iopc = INTRN_PERIPHERAL_RW_BEGIN;
06757 break;
06758 case BUILT_IN_PERIPHERAL_RW_END:
06759 iopc = INTRN_PERIPHERAL_RW_END;
06760 break;
06761 case BUILT_IN_VBUF_OFFSET:
06762 iopc = INTRN_VBUF_OFFSET;
06763 intrinsic_op = TRUE;
06764 break;
06765 case BUILT_IN_VBUF_ABSOLUTE:
06766 iopc = INTRN_VBUF_ABSOLUTE;
06767 intrinsic_op = TRUE;
06768 break;
06769 case BUILT_IN_SBUF_OFFSET:
06770 iopc = INTRN_SBUF_OFFSET;
06771 intrinsic_op = TRUE;
06772 break;
06773 case BUILT_IN_C3_INIT_ACC:
06774 iopc = INTRN_C3_INIT_ACC;
06775 break;
06776 case BUILT_IN_C3_SAVE_ACC:
06777 iopc = INTRN_C3_SAVE_ACC;
06778 break;
06779 case BUILT_IN_C3_MVFS:
06780 iopc = INTRN_C3_MVFS;
06781 intrinsic_op = TRUE;
06782 break;
06783 case BUILT_IN_C3_INIT_ADDR:
06784 iopc = INTRN_C3_INIT_ADDR;
06785 break;
06786 case BUILT_IN_C3_SAVE_ADDR:
06787 iopc = INTRN_C3_SAVE_ADDR;
06788 break;
06789 case BUILT_IN_C3_INIT_DACC:
06790 iopc = INTRN_C3_INIT_DACC;
06791 break;
06792 case BUILT_IN_C3_SAVE_DACC:
06793 iopc = INTRN_C3_SAVE_DACC;
06794 break;
06795 case BUILT_IN_SET_ADDR:
06796 iopc = INTRN_C3_SET_ADDR;
06797 break;
06798 case BUILT_IN_SET_CIRCBUF:
06799 iopc = INTRN_C3_SET_CIRCBUF;
06800 break;
06801 case BUILT_IN_C3AADDA:
06802 iopc = INTRN_C3AADDA;
06803 intrinsic_op = TRUE;
06804 break;
06805 case BUILT_IN_C3BITR:
06806 iopc = INTRN_C3BITR;
06807 intrinsic_op = TRUE;
06808 break;
06809 case BUILT_IN_C3CS:
06810 iopc = INTRN_C3CS;
06811 intrinsic_op = TRUE;
06812 break;
06813 case BUILT_IN_C3DADD:
06814 iopc = INTRN_C3DADD;
06815 intrinsic_op = TRUE;
06816 break;
06817 case BUILT_IN_C3DMAC:
06818 iopc = INTRN_C3DMAC;
06819 intrinsic_op = TRUE;
06820 break;
06821 case BUILT_IN_C3DMACA:
06822 iopc = INTRN_C3DMAC_A;
06823 intrinsic_op = TRUE;
06824 break;
06825 case BUILT_IN_C3DMULA:
06826 iopc = INTRN_C3DMULA;
06827 intrinsic_op = TRUE;
06828 break;
06829 case BUILT_IN_C3DMULAA:
06830 iopc = INTRN_C3DMULA_A;
06831 intrinsic_op = TRUE;
06832 break;
06833 case BUILT_IN_C3DSHLLI:
06834 iopc = INTRN_C3DSHLL_I;
06835 intrinsic_op = TRUE;
06836 break;
06837 case BUILT_IN_C3FFE:
06838 iopc = INTRN_C3FFE;
06839 break;
06840 case BUILT_IN_C3LD:
06841 iopc = INTRN_C3LD;
06842 intrinsic_op = TRUE;
06843 break;
06844 case BUILT_IN_C3ST:
06845 iopc = INTRN_C3ST;
06846 break;
06847 case BUILT_IN_C3LEAD:
06848 iopc = INTRN_C3LEAD;
06849 intrinsic_op = TRUE;
06850 break;
06851 case BUILT_IN_C3MAC:
06852 iopc = INTRN_C3MAC;
06853 intrinsic_op = TRUE;
06854 break;
06855 case BUILT_IN_C3MACA:
06856 iopc = INTRN_C3MAC_A;
06857 intrinsic_op = TRUE;
06858 break;
06859 case BUILT_IN_C3MACAR:
06860 iopc = INTRN_C3MAC_AR;
06861 intrinsic_op = TRUE;
06862 break;
06863 case BUILT_IN_C3MACI:
06864 iopc = INTRN_C3MAC_I;
06865 intrinsic_op = TRUE;
06866 break;
06867 case BUILT_IN_C3MULA:
06868 iopc = INTRN_C3MULA;
06869 intrinsic_op = TRUE;
06870 break;
06871 case BUILT_IN_C3MULAA:
06872 iopc = INTRN_C3MULA_A;
06873 intrinsic_op = TRUE;
06874 break;
06875 case BUILT_IN_C3MULAAR:
06876 iopc = INTRN_C3MULA_AR;
06877 intrinsic_op = TRUE;
06878 break;
06879 case BUILT_IN_C3MULAI:
06880 iopc = INTRN_C3MULA_I;
06881 intrinsic_op = TRUE;
06882 break;
06883 case BUILT_IN_C3MULS:
06884 iopc = INTRN_C3MULS;
06885 intrinsic_op = TRUE;
06886 break;
06887 case BUILT_IN_C3MULUS:
06888 iopc = INTRN_C3MULUS;
06889 intrinsic_op = TRUE;
06890 break;
06891 case BUILT_IN_C3REVB:
06892 iopc = INTRN_C3REVB;
06893 intrinsic_op = TRUE;
06894 break;
06895 case BUILT_IN_C3ROUND:
06896 iopc = INTRN_C3ROUND;
06897 intrinsic_op = TRUE;
06898 break;
06899 case BUILT_IN_C3SAADDA:
06900 iopc = INTRN_C3SAADD_A;
06901 intrinsic_op = TRUE;
06902 break;
06903 case BUILT_IN_C3SAADDHA:
06904 iopc = INTRN_C3SAADDH_A;
06905 intrinsic_op = TRUE;
06906 break;
06907 case BUILT_IN_C3SAADDS:
06908 iopc = INTRN_C3SAADDS;
06909 intrinsic_op = TRUE;
06910 break;
06911 case BUILT_IN_C3SAADDSH:
06912 iopc = INTRN_C3SAADDSH;
06913 intrinsic_op = TRUE;
06914 break;
06915 case BUILT_IN_C3SADDA:
06916 iopc = INTRN_C3SADDA;
06917 intrinsic_op = TRUE;
06918 break;
06919 case BUILT_IN_C3SADDAA:
06920 iopc = INTRN_C3SADDA_A;
06921 intrinsic_op = TRUE;
06922 break;
06923 case BUILT_IN_C3SAMULHA:
06924 iopc = INTRN_C3SAMULH_A;
06925 intrinsic_op = TRUE;
06926 break;
06927 case BUILT_IN_C3SAMULSH:
06928 iopc = INTRN_C3SAMULSH;
06929 intrinsic_op = TRUE;
06930 break;
06931 case BUILT_IN_C3SHAV:
06932 iopc = INTRN_C3SHAV;
06933 intrinsic_op = TRUE;
06934 break;
06935 case BUILT_IN_C3SHLAFAI:
06936 iopc = INTRN_C3SHLAFA_I;
06937 intrinsic_op = TRUE;
06938 break;
06939 case BUILT_IN_C3SHLATAI:
06940 iopc = INTRN_C3SHLATA_I;
06941 intrinsic_op = TRUE;
06942 break;
06943 case BUILT_IN_C3SHLAI:
06944 iopc = INTRN_C3SHLA_I;
06945 intrinsic_op = TRUE;
06946 break;
06947 case BUILT_IN_C3SUBC:
06948 iopc = INTRN_C3SUBC;
06949 intrinsic_op = TRUE;
06950 break;
06951 case BUILT_IN_C3NEGA:
06952 iopc = INTRN_C3NEGA;
06953 intrinsic_op = TRUE;
06954 break;
06955 case BUILT_IN_INIT_HI:
06956 iopc = INTRN_INIT_HI;
06957 break;
06958 case BUILT_IN_COPY_HI:
06959 iopc = INTRN_COPY_HI;
06960 intrinsic_op = TRUE;
06961 break;
06962 case BUILT_IN_C2_MVGR_R2G:
06963 iopc = INTRN_C2_MVGR_R2G;
06964 break;
06965 case BUILT_IN_C2_MVGR_G2R:
06966 iopc = INTRN_C2_MVGR_G2R;
06967 break;
06968 case BUILT_IN_C2_MVGC_G2C:
06969 iopc = INTRN_C2_MVGC_G2C;
06970 break;
06971 case BUILT_IN_C2_MVGC_C2G:
06972 iopc = INTRN_C2_MVGC_C2G;
06973 break;
06974 case BUILT_IN_C2_LD_V:
06975 iopc = INTRN_C2_LD_V;
06976 break;
06977 case BUILT_IN_C2_LD_G:
06978 iopc = INTRN_C2_LD_G;
06979 break;
06980 case BUILT_IN_C2_LD_S:
06981 iopc = INTRN_C2_LD_S;
06982 break;
06983 case BUILT_IN_C2_ST_V:
06984 iopc = INTRN_C2_ST_V;
06985 break;
06986 case BUILT_IN_C2_ST_G:
06987 iopc = INTRN_C2_ST_G;
06988 break;
06989 case BUILT_IN_C2_LD_G_IMM:
06990 iopc = INTRN_C2_LD_G_IMM;
06991 break;
06992 case BUILT_IN_C2_LD_C_IMM:
06993 iopc = INTRN_C2_LD_C_IMM;
06994 break;
06995 case BUILT_IN_C2_LD_V_IMM:
06996 iopc = INTRN_C2_LD_V_IMM;
06997 break;
06998 case BUILT_IN_C2_ST_V_IMM:
06999 iopc = INTRN_C2_ST_V_IMM;
07000 break;
07001 case BUILT_IN_C2_ST_C_IMM:
07002 iopc = INTRN_C2_ST_C_IMM;
07003 break;
07004 case BUILT_IN_C2_ST_G_IMM:
07005 iopc = INTRN_C2_ST_G_IMM;
07006 break;
07007 case BUILT_IN_C2_VADDS:
07008 iopc = INTRN_C2_VADDS;
07009 break;
07010 case BUILT_IN_C2_VSUBS:
07011 iopc = INTRN_C2_VSUBS;
07012 break;
07013 case BUILT_IN_C2_VMUL:
07014 iopc = INTRN_C2_VMUL;
07015 break;
07016 case BUILT_IN_C2_VNEG:
07017 iopc = INTRN_C2_VNEG;
07018 break;
07019 case BUILT_IN_C2_VSHFT:
07020 iopc = INTRN_C2_VSHFT;
07021 break;
07022 case BUILT_IN_C2_VCLP:
07023 iopc = INTRN_C2_VCLP;
07024 break;
07025 case BUILT_IN_C2_VCLG:
07026 iopc = INTRN_C2_VCLG;
07027 break;
07028 case BUILT_IN_C2_VCMOV:
07029 iopc = INTRN_C2_VCMOV;
07030 break;
07031 case BUILT_IN_C2_LCZERO:
07032 iopc = INTRN_C2_LCZERO;
07033 break;
07034 case BUILT_IN_C2_VRND:
07035 iopc = INTRN_C2_VRND;
07036 break;
07037 case BUILT_IN_C2_VSPAS:
07038 iopc = INTRN_C2_VSPAS;
07039 break;
07040 case BUILT_IN_C2_VSPEL:
07041 iopc = INTRN_C2_VSPEL;
07042 break;
07043 case BUILT_IN_C2_VSPEL_MAC:
07044 iopc = INTRN_C2_VSPEL_MAC;
07045 break;
07046 case BUILT_IN_C2_MMUL:
07047 iopc = INTRN_C2_MMUL;
07048 break;
07049 case BUILT_IN_C2_VMOV:
07050 iopc = INTRN_C2_VMOV;
07051 break;
07052 case BUILT_IN_C2_VCOPY:
07053 iopc = INTRN_C2_VCOPY;
07054 break;
07055 case BUILT_IN_C2_VCMPR:
07056 iopc = INTRN_C2_VCMPR;
07057 break;
07058 case BUILT_IN_C2_SAD:
07059 iopc = INTRN_C2_SAD;
07060 break;
07061 case BUILT_IN_C2_SATD:
07062 iopc = INTRN_C2_SATD;
07063 break;
07064 case BUILT_IN_C2_INTRA:
07065 iopc = INTRN_C2_INTRA;
07066 break;
07067 case BUILT_IN_C2_MVSEL:
07068 iopc = INTRN_C2_MVSEL;
07069 break;
07070 case BUILT_IN_C2_BCST:
07071 iopc = INTRN_C2_BCST;
07072 break;
07073 case BUILT_IN_C2_VLCS:
07074 iopc = INTRN_C2_VLCS;
07075 break;
07076 case BUILT_IN_C2_VLCS_R:
07077 iopc = INTRN_C2_VLCS_R;
07078 break;
07079 case BUILT_IN_C2_ADDS:
07080 iopc = INTRN_C2_ADDS;
07081 break;
07082 case BUILT_IN_C2_ADDS_R:
07083 iopc = INTRN_C2_ADDS_R;
07084 break;
07085 case BUILT_IN_C2_SUBS:
07086 iopc = INTRN_C2_SUBS;
07087 break;
07088 case BUILT_IN_C2_SUBS_R:
07089 iopc = INTRN_C2_SUBS_R;
07090 break;
07091 case BUILT_IN_C2_MULS:
07092 iopc = INTRN_C2_MULS;
07093 break;
07094 case BUILT_IN_C2_MADS:
07095 iopc = INTRN_C2_MADS;
07096 break;
07097 case BUILT_IN_C2_SMADS:
07098 iopc = INTRN_C2_SMADS;
07099 break;
07100 case BUILT_IN_C2_CMOV:
07101 iopc = INTRN_C2_CMOV;
07102 break;
07103 case BUILT_IN_C2_MOV:
07104 iopc = INTRN_C2_MOV;
07105 break;
07106 case BUILT_IN_C2_MOV_R:
07107 iopc = INTRN_C2_MOV_R;
07108 break;
07109 case BUILT_IN_C2_CLP:
07110 iopc = INTRN_C2_CLP;
07111 break;
07112 case BUILT_IN_C2_CHKRNG:
07113 iopc = INTRN_C2_CHKRNG;
07114 break;
07115 case BUILT_IN_C2_SCOND:
07116 iopc = INTRN_C2_SCOND;
07117 break;
07118 case BUILT_IN_C2_SCOND_R:
07119 iopc = INTRN_C2_SCOND_R;
07120 break;
07121 case BUILT_IN_C2_SCOND_R_WB:
07122 iopc = INTRN_C2_SCOND_R_WB;
07123 break;
07124 case BUILT_IN_C2_BOP:
07125 iopc = INTRN_C2_BOP;
07126 break;
07127 case BUILT_IN_C2_BDEP:
07128 iopc = INTRN_C2_BDEP;
07129 break;
07130 case BUILT_IN_C2_WRAP:
07131 iopc = INTRN_C2_WRAP;
07132 break;
07133 case BUILT_IN_C2_BXTR:
07134 iopc = INTRN_C2_BXTR;
07135 break;
07136 case BUILT_IN_C2_BXTRR48:
07137 iopc = INTRN_C2_BXTRR48;
07138 break;
07139 case BUILT_IN_C2_SUM4:
07140 iopc = INTRN_C2_SUM4;
07141 break;
07142 case BUILT_IN_C2_SUM3_SADDR:
07143 iopc = INTRN_C2_SUM3_SADDR;
07144 break;
07145 case BUILT_IN_C2_SUM4_R:
07146 iopc = INTRN_C2_SUM4_R;
07147 break;
07148 case BUILT_IN_C2_MED:
07149 iopc = INTRN_C2_MED;
07150 break;
07151 case BUILT_IN_C2_LD_V2G:
07152 iopc = INTRN_C2_LD_V2G;
07153 break;
07154 case BUILT_IN_C2_LD_V2G_IMM:
07155 iopc = INTRN_C2_LD_V2G_IMM;
07156 break;
07157 case BUILT_IN_C2_ST_G2V:
07158 iopc = INTRN_C2_ST_G2V;
07159 break;
07160 case BUILT_IN_C2_ST_G2V_IMM:
07161 iopc = INTRN_C2_ST_G2V_IMM;
07162 break;
07163 case BUILT_IN_C2_MVGR_R2S:
07164 iopc = INTRN_C2_MVGR_R2S;
07165 break;
07166 case BUILT_IN_C2_GSUMS:
07167 iopc = INTRN_C2_GSUMS;
07168 break;
07169 case BUILT_IN_C2_FORK:
07170 iopc = INTRN_C2_FORK;
07171 break;
07172 case BUILT_IN_C2_JOINT:
07173 iopc = INTRN_C2_JOINT;
07174 break;
07175 case BUILT_IN_C2_CLZOB:
07176 iopc = INTRN_C2_CLZOB;
07177 break;
07178 case BUILT_IN_C2_THCTRL:
07179 iopc = INTRN_C2_THCTRL;
07180 break;
07181 #endif // TARG_SL
07182
07183
07184 default:
07185 #ifndef KEY
07186 Fatal_Error ("Encountered not-yet-supported BUILT_IN: %d at line %d\n",
07187 DECL_FUNCTION_CODE (func), lineno);
07188 #endif
07189 break;
07190 }
07191 }
07192 else
07193 {
07194 #ifdef TARG_X8664
07195 wn = WFE_target_builtins (exp, &iopc, &intrinsic_op);
07196 if (wn) break;
07197 #else
07198 Fail_FmtAssertion ("Target-specific builtins NYI");
07199 #endif
07200 }
07201 }
07202 #ifdef TARG_NVISA
07203 else if (DECL_NAME (func)) {
07204
07205
07206
07207
07208
07209
07210
07211
07212 char *name = IDENTIFIER_POINTER(DECL_NAME(func));
07213 if (strcmp(name, "__utexfetchi1D") == 0) {
07214 wn = emit_builtin_texfetch(exp,
07215 "tex.1d.v4.u32.s32", MTYPE_U4, MTYPE_I4);
07216 asm_generated = TRUE;
07217 }
07218 else if (strcmp(name, "__itexfetchi1D") == 0) {
07219 wn = emit_builtin_texfetch(exp,
07220 "tex.1d.v4.s32.s32", MTYPE_I4, MTYPE_I4);
07221 asm_generated = TRUE;
07222 }
07223 else if (strcmp(name, "__ftexfetchi1D") == 0) {
07224 wn = emit_builtin_texfetch(exp,
07225 "tex.1d.v4.f32.s32", MTYPE_F4, MTYPE_I4);
07226 asm_generated = TRUE;
07227 }
07228 else if (strcmp(name, "__utexfetch1D") == 0) {
07229 wn = emit_builtin_texfetch(exp,
07230 "tex.1d.v4.u32.f32", MTYPE_U4, MTYPE_F4);
07231 asm_generated = TRUE;
07232 }
07233 else if (strcmp(name, "__itexfetch1D") == 0) {
07234 wn = emit_builtin_texfetch(exp,
07235 "tex.1d.v4.s32.f32", MTYPE_I4, MTYPE_F4);
07236 asm_generated = TRUE;
07237 }
07238 else if (strcmp(name, "__ftexfetch1D") == 0) {
07239 wn = emit_builtin_texfetch(exp,
07240 "tex.1d.v4.f32.f32", MTYPE_F4, MTYPE_F4);
07241 asm_generated = TRUE;
07242 }
07243 else if (strcmp(name, "__utexfetch2D") == 0) {
07244 wn = emit_builtin_texfetch(exp,
07245 "tex.2d.v4.u32.f32", MTYPE_U4, MTYPE_F4);
07246 asm_generated = TRUE;
07247 }
07248 else if (strcmp(name, "__itexfetch2D") == 0) {
07249 wn = emit_builtin_texfetch(exp,
07250 "tex.2d.v4.s32.f32", MTYPE_I4, MTYPE_F4);
07251 asm_generated = TRUE;
07252 }
07253 else if (strcmp(name, "__ftexfetch2D") == 0) {
07254 wn = emit_builtin_texfetch(exp,
07255 "tex.2d.v4.f32.f32", MTYPE_F4, MTYPE_F4);
07256 asm_generated = TRUE;
07257 }
07258 else if (strcmp(name, "__utexfetch3D") == 0) {
07259 wn = emit_builtin_texfetch(exp,
07260 "tex.3d.v4.u32.f32", MTYPE_U4, MTYPE_F4);
07261 asm_generated = TRUE;
07262 }
07263 else if (strcmp(name, "__itexfetch3D") == 0) {
07264 wn = emit_builtin_texfetch(exp,
07265 "tex.3d.v4.s32.f32", MTYPE_I4, MTYPE_F4);
07266 asm_generated = TRUE;
07267 }
07268 else if (strcmp(name, "__ftexfetch3D") == 0) {
07269 wn = emit_builtin_texfetch(exp,
07270 "tex.3d.v4.f32.f32", MTYPE_F4, MTYPE_F4);
07271 asm_generated = TRUE;
07272 }
07273 else if (strcmp(name, "__double_to_int2") == 0) {
07274 wn = emit_builtin_double_to_int2 (exp);
07275 asm_generated = TRUE;
07276 }
07277 else if (strcmp(name, "__int2_to_double") == 0) {
07278 wn = emit_builtin_int2_to_double (exp);
07279 asm_generated = TRUE;
07280 }
07281 if (asm_generated) {
07282
07283
07284
07285
07286 TYPE_ID mtype;
07287 PREG_NUM preg_num;
07288 ST *preg_st;
07289 if (!need_result) {
07290 break;
07291 }
07292 desc_ty_idx = component_ty_idx;
07293 if (desc_ty_idx == 0)
07294 desc_ty_idx = Get_TY (TREE_TYPE(exp));
07295 ty_idx = desc_ty_idx;
07296 mtype = TY_mtype(ty_idx);
07297 if (TY_can_be_vector(ty_idx)) {
07298
07299
07300
07301 preg_num = asm_neg_preg + TY_vector_count(ty_idx);
07302 preg_st = MTYPE_To_PREG(TY_mtype(TY_vector_elem_ty(ty_idx)));
07303 }
07304 else {
07305
07306 preg_num = asm_neg_preg + 1;
07307 preg_st = MTYPE_To_PREG(mtype);
07308 }
07309 wn1 = WN_CreateLdid (OPR_LDID, mtype, mtype,
07310 preg_num, preg_st, ty_idx, 0);
07311
07312 wn0 = WN_CreateBlock ();
07313 WN_INSERT_BlockLast (wn0, wn);
07314
07315 wn = WN_CreateComma (OPR_COMMA, WN_rtype(wn1), MTYPE_V,
07316 wn0, wn1);
07317 whirl_generated = TRUE;
07318 }
07319 }
07320 #endif
07321
07322 if (whirl_generated) {
07323 break;
07324 }
07325
07326 if (intrinsic_op) {
07327 WN *ikids [16];
07328 for (i = 0, list = TREE_OPERAND (exp, 1);
07329 list;
07330 i++, list = TREE_CHAIN (list)) {
07331 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
07332 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
07333 arg_mtype = TY_mtype(arg_ty_idx);
07334 arg_wn = WN_CreateParm (Mtype_comparison (arg_mtype), arg_wn,
07335 arg_ty_idx, WN_PARM_BY_VALUE);
07336 ikids [i] = arg_wn;
07337 }
07338 #if defined(TARG_SL)
07339
07340
07341 if( iopc == INTRN_SBUF_OFFSET || iopc == INTRN_VBUF_OFFSET ||
07342 iopc == INTRN_VBUF_ABSOLUTE) {
07343 Mark_LDA_Vbuf_Offset(ikids[0], iopc);
07344 Adjust_Vbuf_Array_Ofst(ikids[0]);
07345 wn = WN_kid0(ikids[0]);
07346 break;
07347 }
07348 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, ret_mtype, MTYPE_V,
07349 iopc, num_args, ikids);
07350
07351 WN_Set_Deref_If_Needed(wn);
07352 #else
07353
07354 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, ret_mtype, MTYPE_V,
07355 iopc, num_args, ikids);
07356 #endif //TARG_SL
07357 #ifdef KEY
07358 if (cvt_to != MTYPE_UNKNOWN)
07359 wn = WN_Cvt (ret_mtype, cvt_to, wn);
07360 #endif
07361 break;
07362 }
07363
07364 if (!need_result) {
07365 ret_mtype = MTYPE_V;
07366 }
07367
07368 if (iopc) {
07369 call_wn = WN_Create (OPR_INTRINSIC_CALL, ret_mtype, MTYPE_V, num_args);
07370 WN_intrinsic (call_wn) = iopc;
07371 }
07372 else {
07373 call_wn = WN_Create (OPR_CALL, ret_mtype, MTYPE_V, num_args);
07374 ST *st2 = DECL_ST2 (TREE_OPERAND (arg0, 0));
07375 if (Opt_Level > 0 && st2) {
07376 WN_st_idx (call_wn) = ST_st_idx (st2);
07377 }
07378 else {
07379 st = Get_ST (TREE_OPERAND (arg0, 0));
07380 WN_st_idx (call_wn) = ST_st_idx (st);
07381 }
07382 }
07383 }
07384
07385 else {
07386 if (!need_result) {
07387 ret_mtype = MTYPE_V;
07388 }
07389 num_args++;
07390 call_wn = WN_Create (OPR_ICALL, ret_mtype, MTYPE_V, num_args);
07391 WN_kid(call_wn, num_args-1) = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
07392 WN_set_ty (call_wn, TY_pointed(Get_TY(TREE_TYPE (TREE_OPERAND (exp, 0)))));
07393 }
07394
07395 WN_Set_Linenum (call_wn, Get_Srcpos());
07396 WN_Set_Call_Default_Flags (call_wn);
07397
07398 if (st) {
07399 tree func = TREE_OPERAND (arg0, 0);
07400 if (DECL_INLINE (func)) {
07401 wfe_invoke_inliner = TRUE;
07402 }
07403 #ifdef TARG_IA64
07404 int flags = flags_from_decl_or_type (func);
07405 PU& pu_ent = Pu_Table[ST_pu(st)];
07406 if (flags & ECF_MALLOC) {
07407 Set_PU_has_attr_malloc (pu_ent);
07408 } else if (flags & ECF_PURE) {
07409 Set_PU_has_attr_pure (pu_ent);
07410 } else if (TREE_READONLY(func)) {
07411 Set_PU_is_pure (pu_ent);
07412 }
07413
07414 if (flags & ECF_NORETURN) {
07415 Set_PU_has_attr_noreturn (pu_ent);
07416 }
07417 #endif
07418 }
07419
07420 i = 0;
07421 for (list = TREE_OPERAND (exp, 1);
07422 list;
07423 list = TREE_CHAIN (list)) {
07424 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
07425 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
07426 arg_mtype = TY_mtype(arg_ty_idx);
07427 if (!WFE_Keep_Zero_Length_Structs &&
07428 TY_mtype (arg_ty_idx) == MTYPE_M &&
07429 TY_size (arg_ty_idx) == 0) {
07430
07431 if (arg_wn && WN_has_side_effects (arg_wn)) {
07432 arg_wn = WN_CreateEval (arg_wn);
07433 WFE_Stmt_Append (arg_wn, Get_Srcpos());
07434 }
07435 }
07436 else {
07437 #ifdef KEY // bug 11585
07438 if (WN_operator(arg_wn) == OPR_LDA) {
07439 ST *st = WN_st(arg_wn);
07440 Set_ST_addr_passed(*st);
07441 Set_ST_addr_saved(*st);
07442 }
07443 #endif // KEY
07444
07445
07446 if (arg_mtype == MTYPE_M)
07447 arg_mtype = WN_rtype(arg_wn);
07448 arg_wn = WN_CreateParm (Mtype_comparison (arg_mtype), arg_wn,
07449 arg_ty_idx, WN_PARM_BY_VALUE);
07450 #if defined(TARG_SL)
07451
07452
07453
07454
07455
07456
07457
07458
07459 arg_wn = Adjust_Vbuf_Array_Ofst(arg_wn);
07460 #endif // TARG_SL
07461
07462 WN_kid (call_wn, i++) = arg_wn;
07463 }
07464 }
07465
07466 #if defined(TARG_SL)
07467
07468
07469
07470 if(May_Include_Vbuf_Offset(iopc, call_wn))
07471 {
07472
07473
07474
07475
07476
07477
07478
07479
07480 INTRINSIC id;
07481 WN* intrn_ofst_wn;
07482 UINT64 nth_child;
07483
07484 if(iopc == INTRN_C2_LD_V2G || iopc == INTRN_C2_LD_G) {
07485 nth_child = 0;
07486 id = ((iopc == INTRN_C2_LD_V2G) ? INTRN_VBUF_OFFSET : INTRN_SBUF_OFFSET);
07487 }
07488 else {
07489 id = ((iopc == INTRN_C2_ST_G) ? INTRN_SBUF_OFFSET : INTRN_VBUF_OFFSET);
07490 nth_child = 1;
07491 }
07492 Mark_LDA_Vbuf_Offset(WN_kid(call_wn, nth_child), id);
07493 }
07494
07495
07496 WN_Set_Deref_If_Needed(call_wn);
07497
07498 #endif // TARG_SL
07499
07500 if (ret_mtype == MTYPE_V) {
07501 WFE_Stmt_Append (call_wn, Get_Srcpos());
07502 #ifdef TARG_SL
07503
07504 if (WN_Need_Append_Intrinsic(call_wn)) {
07505 WFE_Stmt_Append_Extend_Intrinsic(call_wn, WN_kid0(WN_kid0(call_wn)), Get_Srcpos());
07506 }
07507 #endif
07508 }
07509
07510 else {
07511 wn0 = WN_CreateBlock ();
07512 WN_INSERT_BlockLast (wn0, call_wn);
07513
07514 #ifdef KEY
07515
07516
07517 if (nop_ty_idx && TY_kind(ty_idx) == KIND_POINTER &&
07518 TY_mtype(TY_pointed(ty_idx)) == MTYPE_V)
07519 ty_idx = nop_ty_idx;
07520 #endif
07521
07522 wn1 = WN_Ldid (ret_mtype, -1, Return_Val_Preg, ty_idx);
07523
07524 if (ret_mtype == MTYPE_M) {
07525 TY_IDX ret_ty_idx = ty_idx;
07526 #ifndef KEY
07527
07528
07529 if (Aggregate_Alignment > 0 &&
07530 Aggregate_Alignment > TY_align (ret_ty_idx))
07531 Set_TY_align (ret_ty_idx, Aggregate_Alignment);
07532 #endif // !KEY
07533 if (TY_align (ret_ty_idx) < MTYPE_align_best(Spill_Int_Mtype))
07534 Set_TY_align (ret_ty_idx, MTYPE_align_best(Spill_Int_Mtype));
07535
07536 char *mrname = Label_Name_Separator "Mreturn" Label_Name_Separator;
07537 ST *ret_st = Gen_Temp_Symbol(ret_ty_idx,
07538 st ? Index_To_Str(Save_Str2(mrname, ST_name(ST_st_idx(st))))
07539 : mrname);
07540 #ifdef KEY
07541 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, ret_st);
07542 #endif // KEY
07543 wn1 = WN_Stid (ret_mtype, 0, ret_st, ty_idx, wn1);
07544 WN_INSERT_BlockLast (wn0, wn1);
07545
07546
07547 UINT xtra_BE_ofst = 0;
07548 desc_ty_idx = component_ty_idx;
07549 if (desc_ty_idx == 0)
07550 desc_ty_idx = Get_TY (TREE_TYPE(exp));
07551
07552 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
07553 ty_idx = desc_ty_idx;
07554 else {
07555 ty_idx = nop_ty_idx;
07556 if (ty_idx == 0)
07557 ty_idx = desc_ty_idx;
07558 }
07559
07560 if (! is_bit_field) {
07561 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
07562 if (Target_Byte_Sex == BIG_ENDIAN)
07563 xtra_BE_ofst = TY_size(desc_ty_idx) - TY_size(ty_idx);
07564 desc_ty_idx = ty_idx;
07565 }
07566 }
07567 else {
07568 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
07569 ty_idx = desc_ty_idx;
07570 }
07571
07572 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
07573 TYPE_ID desc = TY_mtype(desc_ty_idx);
07574 if (MTYPE_is_integral(desc)) {
07575 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
07576 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
07577 is_bit_field)
07578 rtype = Mtype_TransferSign(desc, rtype);
07579 else desc = Mtype_TransferSign(rtype, desc);
07580 }
07581 }
07582
07583 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
07584 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
07585
07586 wn1 = WN_CreateLdid(OPR_LDID, rtype,
07587 is_bit_field ? MTYPE_BS : desc,
07588 ST_ofst(ret_st)+component_offset+xtra_BE_ofst,
07589 ret_st,
07590 (field_id != 0 && component_ty_idx != 0) ?
07591 Get_TY (TREE_TYPE(exp)) : ty_idx,
07592 field_id);
07593 }
07594
07595 wn = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V,
07596 wn0, wn1);
07597 }
07598 }
07599 break;
07600
07601 case COMPOUND_EXPR:
07602 {
07603 #ifndef KEY
07604 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), FALSE);
07605 #else
07606 wn = WFE_Expand_Expr_With_Sequence_Point(TREE_OPERAND(exp,0), MTYPE_V);
07607 #endif
07608 if (wn) {
07609 wn = WN_CreateEval (wn);
07610 WFE_Stmt_Append (wn, Get_Srcpos ());
07611 }
07612 #ifndef KEY
07613 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
07614 #else
07615 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 1), need_result);
07616 #endif
07617 }
07618 break;
07619
07620 case NON_LVALUE_EXPR:
07621 {
07622 #ifdef KEY
07623
07624 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), need_result, nop_ty_idx,
07625 component_ty_idx, component_offset, field_id);
07626 #else
07627 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
07628 #endif
07629 }
07630 break;
07631
07632 case SAVE_EXPR:
07633 {
07634 #ifndef TARG_NVISA // we see this too often
07635 DevWarn ("Encountered SAVE_EXPR at line %d", lineno);
07636 #endif
07637 wn = WFE_Save_Expr (exp);
07638 }
07639 break;
07640
07641 case UNSAVE_EXPR:
07642 {
07643 DevWarn ("Encountered UNSAVE_EXPR at line %d", lineno);
07644 wn = WFE_Save_Expr (exp);
07645 WFE_Unsave_Expr (exp);
07646 }
07647 break;
07648
07649 case TARGET_EXPR:
07650 {
07651 DevWarn ("Encountered TARGET_EXPR at line %d", lineno);
07652 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
07653 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
07654 }
07655 break;
07656
07657 #ifdef GPLUSPLUS_FE
07658 case INIT_EXPR:
07659 {
07660 tree initiand = TREE_OPERAND(exp, 0);
07661 tree initializer = TREE_OPERAND(exp, 1);
07662 tree init_expr;
07663
07664 if (TREE_CODE(initiand) != VAR_DECL) {
07665 DevWarn("expected VAR_DECL");
07666 break;
07667 }
07668
07669 if (TREE_CODE(initializer) != TARGET_EXPR) {
07670 DevWarn("expected TARGET_EXPR");
07671 break;
07672 }
07673
07674 init_expr = TREE_OPERAND(initializer, 3);
07675 if (TREE_CODE(init_expr) != AGGR_INIT_EXPR) {
07676 DevWarn("expected AGGR_INIT_EXPR");
07677 break;
07678 }
07679
07680 {
07681 tree func = TREE_OPERAND(init_expr, 0);
07682 tree args = TREE_OPERAND(init_expr, 1);
07683 INT num_args = 0;
07684 INT i;
07685 tree list;
07686 WN * call_wn;
07687 ST * initiand_st = Get_ST(initiand);
07688 WN * initiand_wn = WN_Lda(Pointer_Mtype,
07689 ST_ofst(initiand_st),
07690 initiand_st);
07691 WN * arg_wn;
07692
07693 for (list = args; list; list = TREE_CHAIN(list))
07694 ++num_args;
07695 call_wn = WN_Create(OPR_CALL, MTYPE_V, MTYPE_V, num_args);
07696 st = Get_ST(TREE_OPERAND(func, 0));
07697 WN_st_idx(call_wn) = ST_st_idx(st);
07698 WN_Set_Call_Default_Flags(call_wn);
07699
07700
07701 for (i = 0, list = TREE_OPERAND(init_expr, 1);
07702 list;
07703 ++i, list = TREE_CHAIN(list)) {
07704 arg_wn = (i == 0) ? initiand_wn
07705 : WFE_Expand_Expr(TREE_VALUE(list));
07706 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
07707 TYPE_ID arg_mtype = TY_mtype(arg_ty_idx);
07708 if (arg_mtype == MTYPE_M)
07709 arg_mtype = WN_rtype(arg_wn);
07710 arg_wn = WN_CreateParm(Mtype_comparison(arg_mtype),
07711 arg_wn,
07712 arg_ty_idx,
07713 WN_PARM_BY_VALUE);
07714 WN_kid(call_wn, i) = arg_wn;
07715 WN_kid (call_wn, i) = arg_wn;
07716 }
07717
07718 WFE_Stmt_Append(call_wn, Get_Srcpos());
07719 }
07720 break;
07721 }
07722
07723 case UNSAVE_EXPR:
07724 {
07725 wn = WFE_Expand_Expr( TREE_OPERAND (exp, 0));
07726 break;
07727 }
07728 case NEW_EXPR:
07729 {
07730 wn = WFE_Expand_Expr(build_new_1(exp));
07731 break;
07732 }
07733 case RTL_EXPR:
07734 break;
07735 #endif
07736
07737 case VA_ARG_EXPR:
07738 {
07739 #ifdef TARG_X8664
07740 if( TARGET_64BIT ){
07741 tree kid0 = TREE_OPERAND(exp, 0);
07742 WN *ap_wn;
07743 ap_wn = WFE_Expand_Expr(kid0);
07744 if (WN_rtype(ap_wn) == MTYPE_M) {
07745 if (OPCODE_is_leaf(WN_opcode(ap_wn)))
07746 #ifdef TARG_IA64
07747 ap_wn = WN_Lda(Pointer_Mtype, 0, WN_st(ap_wn), 0);
07748 #else
07749 ap_wn = WN_Lda(Pointer_Mtype, WN_offset(ap_wn), WN_st(ap_wn), 0);
07750 #endif
07751 else {
07752 Is_True(OPCODE_is_load(WN_opcode(ap_wn)),
07753 ("WFE_Expand_Expr: unexpected VA_ARG_EXPR argument"));
07754 if ( WN_offset(ap_wn) == 0 )
07755 ap_wn = WN_kid0(ap_wn);
07756 else
07757 ap_wn = WN_Add(Pointer_Mtype, WN_kid0(ap_wn), WN_Intconst(Pointer_Mtype, WN_offset(ap_wn)));
07758 }
07759 }
07760 TY_IDX ty_idx = Get_TY (TREE_TYPE(exp));
07761 TYPE_ID mtype = Fix_TY_mtype(ty_idx);
07762
07763 if ( mtype != MTYPE_FQ && mtype != MTYPE_M && !MTYPE_is_complex(mtype)) {
07764 wn = WFE_x8664_va_arg(ap_wn, MTYPE_float(mtype), ty_idx, FALSE);
07765 wn = WN_CreateIload(OPR_ILOAD, Widen_Mtype (mtype), mtype, 0,
07766 ty_idx, Make_Pointer_Type(ty_idx), wn);
07767 }
07768 else if (mtype == MTYPE_C4) {
07769 wn = WFE_x8664_va_arg(ap_wn, MTYPE_float(mtype), ty_idx, FALSE);
07770 wn = WN_CreateIload(OPR_ILOAD, MTYPE_M, MTYPE_M, 0, ty_idx,
07771 Make_Pointer_Type(ty_idx), wn);
07772 }
07773 else {
07774 enum X86_64_PARM_CLASS classes[MAX_CLASSES];
07775 INT n = Classify_Aggregate(ty_idx, classes);
07776 if (n == 0) {
07777
07778 INT delta = ((TY_size(ty_idx) + 7) / 8) * 8;
07779 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
07780 WN_CopyNode(ap_wn));
07781 wn1 = WN_Intconst(MTYPE_U8, delta);
07782 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
07783 wn = WN_Istore(Pointer_Mtype, 8,
07784 Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
07785 WN_CopyNode(ap_wn), wn);
07786 WFE_Stmt_Append (wn, Get_Srcpos ());
07787
07788 wn = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
07789 WN_CopyNode(ap_wn));
07790
07791 wn1 = WN_Intconst(MTYPE_I8, -delta);
07792 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
07793 }
07794 else if (n == 1) {
07795 wn = WFE_x8664_va_arg(ap_wn, classes[0] == X86_64_SSE_CLASS,
07796 ty_idx, FALSE);
07797 }
07798 else if (n > 1) {
07799 if (classes[0] == classes[1]) {
07800 if (classes[0] == X86_64_INTEGER_CLASS)
07801 wn = WFE_x8664_va_arg(ap_wn, classes[0] == X86_64_SSE_CLASS,
07802 ty_idx, TRUE);
07803 else wn = WFE_x8664_va_arg_2_float(ap_wn, ty_idx);
07804 }
07805 else {
07806 wn = WFE_x8664_va_arg_2_mixed(ap_wn,
07807 classes[0] == X86_64_SSE_CLASS,
07808 classes[1] == X86_64_SSE_CLASS, ty_idx);
07809 }
07810 }
07811
07812 if( mtype == MTYPE_FQ ){
07813 wn = WN_CreateIload(OPR_ILOAD, Widen_Mtype (mtype), mtype, 0,
07814 ty_idx, Make_Pointer_Type(ty_idx), wn);
07815 } else {
07816 wn = WN_CreateIload(OPR_ILOAD, MTYPE_M, MTYPE_M, 0, ty_idx,
07817 Make_Pointer_Type(ty_idx), wn);
07818 }
07819 }
07820
07821 break;
07822 }
07823 #endif
07824
07825 tree type = TREE_TYPE (exp);
07826 TY_IDX ty_idx = Get_TY (type);
07827 TYPE_ID mtype = TY_mtype (ty_idx);
07828
07829
07830 #ifdef TARG_IA64
07831 INT64 ty_align = TYPE_ALIGN (type) / BITSPERBYTE;
07832 INT64 ty_size = int_size_in_bytes (type);
07833
07834 INT64 align = PARM_BOUNDARY / BITS_PER_UNIT;
07835 ty_size = ((ty_size + align - 1) / align) * align;
07836 ty_align = ((ty_align + align - 1) / align) * align;
07837 #else
07838 INT64 align;
07839 INT64 rounded_size;
07840
07841 align = PARM_BOUNDARY / BITS_PER_UNIT;
07842 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
07843 #endif
07844
07845
07846 WN *ap_load = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
07847 TY_IDX ap_ty_idx = Get_TY (TREE_TYPE (TREE_OPERAND (exp, 0)));
07848 WN *ap_addr;
07849 TY_IDX ap_addr_ty;
07850 ST *ap_st;
07851 WN_OFFSET ap_offset;
07852 UINT32 ap_field_id = 0;
07853
07854 if (WN_operator(ap_load) == OPR_LDID) {
07855 ap_st = WN_st (ap_load);
07856 ap_offset = WN_offset (ap_load);
07857 }
07858 else
07859 if (WN_operator(ap_load) == OPR_ILOAD) {
07860 ap_st = NULL;
07861 ap_offset = WN_offset (ap_load);
07862 ap_field_id = WN_field_id(ap_load);
07863 ap_addr = WN_COPY_Tree (WN_kid0 (ap_load));
07864 ap_addr_ty = WN_load_addr_ty(ap_load);
07865 if (WN_has_side_effects (ap_addr))
07866 Fail_FmtAssertion ("VA_ARG_EXPR: ap address has side effects");
07867 }
07868 else
07869 Fail_FmtAssertion ("VA_ARG_EXPR: unknown operator for ap");
07870
07871 #ifdef TARG_IA64
07872 wn = WN_COPY_Tree(ap_load);
07873
07874
07875 if (ty_align > align) {
07876 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn,
07877 WN_Intconst (Pointer_Mtype, ty_align - 1));
07878 wn = WN_Binary (OPR_BAND, Pointer_Mtype, wn,
07879 WN_Intconst (Pointer_Mtype, -ty_align));
07880 }
07881
07882
07883 if (Target_Byte_Sex == BIG_ENDIAN) {
07884 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn,
07885 WN_Intconst (Pointer_Mtype, 3));
07886 wn = WN_Binary (OPR_BAND, Pointer_Mtype, wn,
07887 WN_Intconst (Pointer_Mtype, -8));
07888 }
07889 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn,
07890 WN_Intconst (Pointer_Mtype, ty_size));
07891
07892 #else
07893 #ifndef KEY
07894 if (Target_Byte_Sex == BIG_ENDIAN) {
07895 Fail_FmtAssertion ("VA_ARG_EXPR not implemented for BIG_ENDIAN");
07896 INT64 adj;
07897 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
07898 if (rounded_size > align)
07899 adj = rounded_size;
07900 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn,
07901 WN_Intconst (Pointer_Mtype, rounded_size - adj));
07902 }
07903
07904 wn = WN_Binary (OPR_ADD, Pointer_Mtype, WN_COPY_Tree (ap_load),
07905 WN_Intconst (Pointer_Mtype, rounded_size));
07906 #else
07907 if (Target_Byte_Sex == BIG_ENDIAN) {
07908 INT64 adj;
07909 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
07910 if (rounded_size > align)
07911 adj = rounded_size;
07912 wn = WN_Binary (OPR_ADD, Pointer_Mtype, WN_COPY_Tree (ap_load),
07913 WN_Intconst (Pointer_Mtype, 3));
07914 wn = WN_Binary (OPR_BAND, Pointer_Mtype, wn,
07915 WN_Intconst (Pointer_Mtype, -8));
07916 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn,
07917 WN_Intconst (Pointer_Mtype, rounded_size));
07918 } else
07919
07920 #if defined(TARG_SL) && (defined(EMULATE_LONGLONG) || defined(EMULATE_FLOAT_POINT))
07921 if ((mtype == MTYPE_F8) || (mtype == MTYPE_I8) || (mtype == MTYPE_U8)
07922 || (mtype == MTYPE_M && TY_fld(ty_idx).Entry()
07923 && MTYPE_byte_size(TY_mtype(FLD_type(TY_fld(ty_idx))))==8)) {
07924
07925
07926 wn = WN_Binary (OPR_ADD, Pointer_Mtype, WN_COPY_Tree (ap_load),
07927 WN_Intconst (Pointer_Mtype, 8*2-1));
07928
07929 wn = WN_Binary (OPR_LSHR, Pointer_Mtype, wn, WN_Intconst (Pointer_Mtype, 3));
07930 wn = WN_Binary (OPR_SHL, Pointer_Mtype, wn, WN_Intconst (Pointer_Mtype, 3));
07931 if (mtype == MTYPE_M && TY_fld(ty_idx).Entry()
07932 && MTYPE_byte_size(TY_mtype(FLD_type(TY_fld(ty_idx))))==8)
07933 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn, WN_Intconst (Pointer_Mtype, rounded_size-8));
07934 } else
07935 #endif
07936 {
07937 wn = WN_Binary (OPR_ADD, Pointer_Mtype, WN_COPY_Tree (ap_load),
07938 WN_Intconst (Pointer_Mtype, rounded_size));
07939 }
07940
07941 #ifdef TARG_X8664 // bug 12118: pad since under -m32, vector types are 8-byte aligned
07942 if (MTYPE_is_vector(mtype) && ! TARGET_64BIT) {
07943 wn = WN_Add(Pointer_Mtype, wn, WN_Intconst(Pointer_Mtype, 7));
07944 wn = WN_Div(Pointer_Mtype, wn, WN_Intconst(Pointer_Mtype, 8));
07945 wn = WN_Mpy(Pointer_Mtype, wn, WN_Intconst(Pointer_Mtype, 8));
07946 }
07947 #endif // TARG_X8664
07948 #ifdef TARG_MIPS // bug 12945: pad since long doubles are 16-byte aligned
07949 if (mtype == MTYPE_FQ) {
07950 wn = WN_Add(Pointer_Mtype, wn, WN_Intconst(Pointer_Mtype, 15));
07951 wn = WN_Div(Pointer_Mtype, wn, WN_Intconst(Pointer_Mtype, 16));
07952 wn = WN_Mpy(Pointer_Mtype, wn, WN_Intconst(Pointer_Mtype, 16));
07953 }
07954 #endif // TARG_MIPS
07955 #endif // ! KEY
07956
07957 #endif // TARG_IA64
07958 if (ap_st)
07959 wn = WN_Stid (Pointer_Mtype, ap_offset, ap_st, ap_ty_idx, wn);
07960 else {
07961 wn = WN_CreateIstore (OPR_ISTORE, MTYPE_V, Pointer_Mtype, ap_offset,
07962 #if defined(TARG_SL)
07963 ap_addr_ty, wn, ap_addr, ap_field_id);
07964 DevWarn("Forcing var-arg istore to aligned");
07965 #else
07966 ap_addr_ty, wn, ap_addr, ap_field_id);
07967 #endif
07968 }
07969 WFE_Stmt_Append (wn, Get_Srcpos ());
07970
07971 #ifdef KEY
07972 if (Target_Byte_Sex != Host_Byte_Sex)
07973 #ifdef TARG_IA64
07974 wn = WN_CreateIload (OPR_ILOAD, Widen_Mtype (mtype), mtype,
07975 ((MTYPE_size_min(mtype)==32)?4:0)-ty_size,
07976 ty_idx, Make_Pointer_Type (ty_idx, FALSE),
07977 ap_load);
07978 #else
07979 wn = WN_CreateIload (OPR_ILOAD, Widen_Mtype (mtype), mtype,
07980 ((MTYPE_size_min(mtype)==32)?4:0)-rounded_size,
07981 ty_idx, Make_Pointer_Type (ty_idx, FALSE),
07982 ap_load);
07983 #endif
07984 else
07985 #endif
07986
07987 #ifdef TARG_IA64
07988 wn = WN_CreateIload (OPR_ILOAD, Widen_Mtype (mtype), mtype, -ty_size,
07989 ty_idx, Make_Pointer_Type (ty_idx, FALSE),
07990 ap_load);
07991 #else
07992 wn = WN_CreateIload (OPR_ILOAD, Widen_Mtype (mtype), mtype, -rounded_size,
07993 ty_idx, Make_Pointer_Type (ty_idx, FALSE),
07994 ap_load);
07995 #endif
07996
07997 }
07998 break;
07999
08000 case ERROR_MARK:
08001
08002 exit (RC_USER_ERROR);
08003 break;
08004
08005 #ifdef KEY
08006 case COMPOUND_LITERAL_EXPR:
08007 {
08008 tree oper = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
08009 if (TREE_CODE (DECL_INITIAL (oper)) == CONSTRUCTOR)
08010 exp = DECL_INITIAL (oper);
08011 else exp = oper;
08012
08013 PREG_NUM preg_num = 0;
08014 desc_ty_idx = component_ty_idx;
08015 TY_IDX hi_ty_idx = Get_TY (TREE_TYPE(exp));
08016 if (desc_ty_idx == 0)
08017 desc_ty_idx = hi_ty_idx;
08018
08019 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
08020 ty_idx = desc_ty_idx;
08021 else {
08022 ty_idx = nop_ty_idx;
08023 if (ty_idx == 0)
08024 ty_idx = desc_ty_idx;
08025 }
08026
08027 UINT cvtl_size = 0;
08028 if (! is_bit_field) {
08029 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
08030 cvtl_size = TY_size(ty_idx) * 8;
08031 ty_idx = desc_ty_idx;
08032 }
08033 }
08034 else {
08035 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
08036 ty_idx = desc_ty_idx;
08037 }
08038
08039 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
08040 TYPE_ID desc = TY_mtype(desc_ty_idx);
08041 if (MTYPE_is_integral(desc)) {
08042 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
08043 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
08044 is_bit_field)
08045 rtype = Mtype_TransferSign(desc, rtype);
08046 else desc = Mtype_TransferSign(rtype, desc);
08047 }
08048 }
08049
08050 if (TREE_THIS_VOLATILE(exp))
08051 Set_TY_is_volatile(ty_idx);
08052
08053 if (TREE_CODE (exp) == CONSTRUCTOR)
08054 {
08055 DevWarn ("Encountered CONSTRUCTOR at line %d", lineno);
08056 st = WFE_Generate_Temp_For_Initialized_Aggregate (exp, "");
08057 }
08058 else
08059 {
08060 st = Get_ST (exp);
08061 if (ST_assigned_to_dedicated_preg (st))
08062 Set_TY_is_volatile(ty_idx);
08063 }
08064
08065 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
08066 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
08067 wn = WN_CreateLdid (OPR_LDID, rtype,
08068 is_bit_field ? MTYPE_BS : desc,
08069 ST_ofst(st)+component_offset+preg_num, st,
08070 field_id != 0 ? hi_ty_idx : ty_idx, field_id);
08071 if (cvtl_size != 0)
08072 wn = WN_CreateCvtl(OPR_CVTL, rtype, MTYPE_V, cvtl_size, wn);
08073 }
08074 break;
08075
08076 case STMT_EXPR:
08077 {
08078
08079
08080
08081
08082
08083 tree expr = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
08084 if (!expr) break;
08085 tree last = TREE_CHAIN (expr);
08086
08087 while (TREE_CHAIN (last))
08088 {
08089 WN *dummy = WFE_Expand_Expr(expr, FALSE);
08090 expr = last;
08091 last = TREE_CHAIN (last);
08092 }
08093
08094 if (TREE_OPERAND (expr, 0) && TREE_CODE (expr) == EXPR_STMT)
08095 wn = WFE_Expand_Expr(TREE_OPERAND(expr, 0), need_result, nop_ty_idx,
08096 component_ty_idx, component_offset, field_id,
08097 is_bit_field);
08098 else {
08099 WFE_Expand_Expr(expr, FALSE);
08100 wn = WN_Intconst(MTYPE_I4, 0);
08101 }
08102
08103 }
08104 break;
08105 case EXPR_WITH_FILE_LOCATION:
08106 {
08107 wn = WFE_Expand_Expr(TREE_OPERAND(exp, 0));
08108 }
08109 break;
08110
08111 case LABEL_DECL:
08112 {
08113 DevWarn ("taking address of a label at line %d", lineno);
08114 LABEL_IDX label_idx = WFE_Get_LABEL (arg0, FALSE);
08115 FmtAssert (arg0->decl.symtab_idx == CURRENT_SYMTAB,
08116 ("line %d: taking address of a label not defined in current function currently not implemented", lineno));
08117 wn = WN_LdaLabel (Pointer_Mtype, label_idx);
08118 Set_LABEL_addr_saved (label_idx);
08119 Set_PU_no_inline (Get_Current_PU ());
08120 }
08121 break;
08122
08123 case SCOPE_STMT:
08124 {
08125
08126
08127
08128
08129
08130 }
08131 break;
08132
08133 case DECL_STMT:
08134 {
08135
08136
08137
08138 tree decl = TREE_OPERAND (exp, 0);
08139 if (TREE_CODE (decl) != FUNCTION_DECL
08140 && TREE_CODE (decl) != PARM_DECL
08141 && DECL_INITIAL (decl) != 0
08142 && DECL_INITIAL (decl) != error_mark_node)
08143 WFE_Initialize_Nested_Decl (decl);
08144 WFE_Decl (decl);
08145 }
08146 break;
08147
08148 case EXPR_STMT:
08149 {
08150
08151
08152
08153 wn = WFE_Expand_Expr ( TREE_OPERAND(exp, 0), FALSE );
08154
08155 if (wn &&
08156 WN_operator (wn) == OPR_COMMA &&
08157 WN_operator (WN_kid1 (wn)) == OPR_LDID &&
08158 WN_st (WN_kid1 (wn)) == Return_Val_Preg &&
08159 (WN_operator (WN_last (WN_kid0 (wn))) == OPR_CALL ||
08160 WN_operator (WN_last (WN_kid0 (wn))) == OPR_ICALL))
08161 {
08162 WN_set_rtype (WN_last (WN_kid0 (wn)), MTYPE_V);
08163 WFE_Stmt_Append (WN_kid0 (wn), Get_Srcpos ());
08164 WN_Delete (wn);
08165 }
08166 wn = NULL;
08167 }
08168 break;
08169
08170 case COMPOUND_STMT:
08171 {
08172
08173
08174
08175 tree expr = TREE_OPERAND (exp, 0);
08176 if (expr)
08177 {
08178 tree last = TREE_CHAIN (expr);
08179
08180 while (TREE_CHAIN (last))
08181 {
08182 WFE_Expand_Expr(expr, FALSE);
08183 expr = last;
08184 last = TREE_CHAIN (last);
08185 }
08186 WFE_Expand_Expr(expr, FALSE);
08187
08188 wn = WFE_Expand_Expr(last, FALSE);
08189 }
08190 }
08191 break;
08192
08193 case IF_STMT:
08194 {
08195
08196
08197
08198
08199 struct nesting * cond_nest = alloc_nesting();
08200 construct_nesting (cond_nest, wfe_cond_stack, wfe_nesting_stack, 0);
08201
08202 wfe_nesting_stack = wfe_cond_stack = cond_nest;
08203
08204 tree cond = TREE_OPERAND (exp, 0);
08205 if (cond && TREE_CODE (cond) == TREE_LIST)
08206 {
08207 WFE_Expand_Expr (TREE_PURPOSE (cond), FALSE);
08208 cond = TREE_VALUE (cond);
08209 }
08210 WFE_Expand_Start_Cond (cond, 0);
08211 if (TREE_OPERAND (exp, 1))
08212 {
08213 WFE_Expand_Expr (TREE_OPERAND (exp, 1), FALSE);
08214 traverse_tree_chain (TREE_OPERAND (exp,1));
08215 }
08216 if (TREE_OPERAND (exp, 2)) {
08217 WFE_Expand_Start_Else ();
08218 WFE_Expand_Expr (TREE_OPERAND (exp, 2), FALSE);
08219 traverse_tree_chain (TREE_OPERAND (exp,2));
08220 }
08221 WFE_Expand_End_Cond ();
08222 popstack (cond_nest);
08223 }
08224 break;
08225
08226 case GOTO_STMT:
08227 {
08228 tree destination = TREE_OPERAND (exp, 0);
08229
08230 if (TREE_CODE (destination) == LABEL_DECL)
08231 WFE_Expand_Goto (destination);
08232 else
08233 WFE_Expand_Computed_Goto (destination);
08234 }
08235 break;
08236
08237 case LABEL_STMT:
08238 {
08239 tree label = TREE_OPERAND (exp, 0);
08240 LABEL_IDX label_idx = WFE_Get_LABEL (label, TRUE);
08241 label->decl.symtab_idx = CURRENT_SYMTAB;
08242 label->decl.label_defined = TRUE;
08243 WN *wn_tmp = WN_CreateLabel ((ST_IDX) 0, label_idx, 0, NULL);
08244 WFE_Stmt_Append (wn_tmp, Get_Srcpos ());
08245 }
08246 break;
08247
08248 case FOR_STMT:
08249 {
08250
08251
08252
08253
08254
08255
08256
08257
08258 tree init = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
08259 if (init)
08260 WFE_Expand_Expr (init, FALSE);
08261
08262 struct nesting *loop_nest= alloc_nesting();
08263 LABEL_IDX for_exit_label_idx;
08264
08265 New_LABEL (CURRENT_SYMTAB, for_exit_label_idx);
08266 construct_nesting (loop_nest, wfe_loop_stack, wfe_nesting_stack,
08267 for_exit_label_idx);
08268
08269 wfe_nesting_stack = wfe_loop_stack = loop_nest;
08270
08271 WFE_Expand_Start_Loop (1, loop_nest);
08272 WFE_Expand_Start_Loop_Continue_Elsewhere (1, loop_nest);
08273
08274 tree cond = TREE_OPERAND (exp, 1);
08275 FmtAssert (!cond || TREE_CODE (cond) != TREE_LIST,
08276 ("Handle this case"));
08277 WFE_Expand_Exit_Loop_If_False (loop_nest, cond);
08278
08279
08280 if (TREE_OPERAND (exp, 3))
08281 {
08282 WFE_Expand_Expr (TREE_OPERAND (exp, 3), FALSE);
08283 traverse_tree_chain (TREE_OPERAND (exp, 3));
08284 }
08285 WFE_Expand_Loop_Continue_Here ();
08286
08287
08288 if (TREE_OPERAND (exp, 2))
08289 WFE_One_Stmt (TREE_OPERAND (exp, 2));
08290
08291 WFE_Expand_End_Loop ();
08292 popstack (loop_nest);
08293 wn = WN_CreateLabel ((ST_IDX) 0,
08294 for_exit_label_idx,
08295 0, NULL);
08296 WFE_Stmt_Append (wn, Get_Srcpos ());
08297
08298 break;
08299 }
08300
08301 case WHILE_STMT:
08302 {
08303
08304
08305
08306 struct nesting *loop_nest = alloc_nesting();
08307 LABEL_IDX while_exit_label_idx;
08308
08309 New_LABEL (CURRENT_SYMTAB, while_exit_label_idx);
08310 construct_nesting (loop_nest, wfe_loop_stack, wfe_nesting_stack,
08311 while_exit_label_idx);
08312
08313 wfe_nesting_stack = wfe_loop_stack = loop_nest;
08314
08315 WFE_Expand_Start_Loop (1, loop_nest);
08316
08317
08318 tree cond = TREE_OPERAND (exp, 0);
08319 FmtAssert (TREE_CODE (cond) != TREE_LIST,
08320 ("Handle this case"));
08321 WFE_Expand_Exit_Loop_If_False (loop_nest, cond);
08322
08323
08324 if (TREE_OPERAND (exp, 1))
08325 {
08326 WFE_Expand_Expr (TREE_OPERAND (exp, 1), FALSE);
08327 traverse_tree_chain (TREE_OPERAND (exp, 1));
08328 }
08329
08330 WFE_Expand_End_Loop ();
08331 popstack (loop_nest);
08332 wn = WN_CreateLabel ((ST_IDX) 0,
08333 while_exit_label_idx,
08334 0, NULL);
08335 WFE_Stmt_Append (wn, Get_Srcpos ());
08336 break;
08337 }
08338
08339
08340 case DO_STMT:
08341 {
08342
08343
08344
08345 struct nesting *loop_nest = alloc_nesting();
08346 LABEL_IDX dostmt_exit_label_idx;
08347
08348 New_LABEL (CURRENT_SYMTAB, dostmt_exit_label_idx);
08349 construct_nesting (loop_nest, wfe_loop_stack, wfe_nesting_stack, dostmt_exit_label_idx);
08350
08351 wfe_nesting_stack = wfe_loop_stack = loop_nest;
08352
08353 WFE_Expand_Start_Loop (1, loop_nest);
08354 WFE_Expand_Start_Loop_Continue_Elsewhere (1, loop_nest);
08355
08356
08357 if (TREE_OPERAND (exp, 1))
08358 {
08359 WFE_Expand_Expr (TREE_OPERAND (exp, 1), FALSE);
08360 traverse_tree_chain (TREE_OPERAND (exp, 1));
08361 }
08362
08363 WFE_Expand_Loop_Continue_Here();
08364
08365
08366 tree cond = TREE_OPERAND (exp, 0);
08367 FmtAssert (TREE_CODE (cond) != TREE_LIST,
08368 ("Handle this case"));
08369 WFE_Expand_Exit_Loop_If_False (loop_nest, cond);
08370
08371 WFE_Expand_End_Loop ();
08372 popstack (loop_nest);
08373 wn = WN_CreateLabel ((ST_IDX) 0,
08374 dostmt_exit_label_idx,
08375 0, NULL);
08376 WFE_Stmt_Append (wn, Get_Srcpos ());
08377 break;
08378 }
08379
08380 case RETURN_STMT:
08381 {
08382
08383
08384
08385 if ( TREE_OPERAND (exp, 0))
08386 WFE_Expand_Return (TREE_OPERAND (exp, 0));
08387 else
08388 WFE_Null_Return ();
08389 break;
08390 }
08391
08392 case SWITCH_STMT:
08393 {
08394
08395
08396
08397 LABEL_IDX switch_exit_label_idx;
08398
08399 New_LABEL (CURRENT_SYMTAB, switch_exit_label_idx);
08400 struct nesting * case_nest = alloc_nesting();
08401 construct_nesting (case_nest, wfe_case_stack, wfe_nesting_stack,
08402 switch_exit_label_idx);
08403
08404 wfe_nesting_stack = wfe_case_stack = case_nest;
08405
08406
08407 tree cond = TREE_OPERAND (exp, 0);
08408 FmtAssert (TREE_CODE (cond) != TREE_LIST,
08409 ("Handle this case"));
08410 const char *print_name = "switch statement";
08411
08412 WFE_Expand_Start_Case (1, cond, TREE_TYPE(cond), (char *)print_name);
08413
08414
08415 if (TREE_OPERAND (exp, 1))
08416 {
08417 WFE_Expand_Expr (TREE_OPERAND (exp, 1), FALSE);
08418 traverse_tree_chain (TREE_OPERAND (exp, 1));
08419 }
08420
08421 wn = WN_CreateLabel ((ST_IDX) 0,
08422 switch_exit_label_idx,
08423 0, NULL);
08424 WFE_Stmt_Append (wn, Get_Srcpos ());
08425 WFE_Expand_End_Case (cond);
08426 popstack (case_nest);
08427 break;
08428 }
08429
08430 case CASE_LABEL:
08431 {
08432
08433
08434
08435
08436 tree low = TREE_OPERAND (exp, 0);
08437 tree high = TREE_OPERAND (exp, 1);
08438 tree label_decl = TREE_OPERAND (exp, 2);
08439 if (!high)
08440 high = low;
08441 if (!high && !low)
08442 WFE_Record_Switch_Default_Label(label_decl);
08443 else
08444 WFE_Add_Case_Node (low, high, label_decl);
08445
08446 WFE_Expand_Label (label_decl);
08447 break;
08448 }
08449
08450 case BREAK_STMT:
08451 {
08452
08453
08454
08455 LABEL_IDX *label_idx = (LABEL_IDX *)malloc(sizeof(LABEL_IDX));
08456 *label_idx = 0;
08457
08458
08459 struct nesting * n = wfe_get_matching_scope (wfe_nesting_stack);
08460 Is_True (n, ("WFE_Expand_Expr: break stmt without enclosing scope"));
08461 *label_idx = get_nesting_label (n);
08462
08463 WFE_Expand_Exit_Something (n, wfe_cond_stack,
08464 wfe_loop_stack, wfe_case_stack, label_idx);
08465 free (label_idx);
08466
08467 break;
08468 }
08469
08470
08471 case CONTINUE_STMT:
08472 {
08473
08474
08475
08476 WFE_Expand_Continue_Loop (NULL);
08477 break;
08478 }
08479
08480 case ASM_STMT:
08481 {
08482
08483
08484
08485 Wfe_Expand_Asm_Operands (TREE_OPERAND (exp, 1),
08486 TREE_OPERAND (exp, 2),
08487 TREE_OPERAND (exp, 3),
08488 TREE_OPERAND (exp, 4),
08489 TREE_OPERAND (exp, 0) != NULL,
08490 NULL,
08491 0);
08492 break;
08493 }
08494 case OMP_MARKER_STMT:
08495 {
08496
08497
08498
08499 process_omp_stmt (exp);
08500 break;
08501 }
08502 case VECTOR_CST:
08503 {
08504 ST * init_st = Gen_Temp_Symbol (Get_TY(TREE_TYPE(exp)), "__vec_cst");
08505 Traverse_Aggregate_Vector_Const (init_st, exp, 0, 0);
08506 TY_IDX ty = ST_type (init_st);
08507 TYPE_ID mtype = TY_mtype (ty);
08508 wn = WN_CreateLdid (OPR_LDID, mtype, mtype, 0, init_st, ty, 0);
08509 break;
08510 }
08511 #endif
08512
08513 default:
08514 {
08515 Fail_FmtAssertion ("WFE_Expand_Expr: not implemented %s",
08516 Operator_From_Tree [code].name);
08517 }
08518 break;
08519 }
08520
08521 #ifdef WFE_DEBUG
08522 if (wn)
08523 fdump_tree (stderr, wn);
08524
08525 fprintf (stderr,
08526 ")} WFE_Expand_Expr: %s\n", Operator_From_Tree [code].name);
08527 #endif
08528
08529 if (need_result)
08530 FmtAssert (wn != 0 || code == CALL_EXPR || code == BIND_EXPR ||
08531 code == COMPOUND_EXPR ||
08532 code == INDIRECT_REF ||
08533 code == COMPONENT_REF ||
08534 code == STMT_EXPR ||
08535 ((code == COND_EXPR) && (TY_mtype (ty_idx) == MTYPE_V)),
08536 ("WFE_Expand_Expr: NULL WHIRL tree for %s at line %d",
08537 Operator_From_Tree [code].name, lineno));
08538
08539 return wn;
08540 }
08541
08542 void WFE_One_Stmt (tree exp)
08543 {
08544 WN *wn;
08545 wfe_save_expr_stack_last = -1;
08546 if (get_expr_stmts_for_value ())
08547 wn = WFE_Expand_Expr_With_Sequence_Point (exp, TY_mtype (Get_TY (TREE_TYPE (exp))));
08548 else
08549 wn = WFE_Expand_Expr_With_Sequence_Point (exp, MTYPE_V);
08550 if (wn) {
08551 if (get_expr_stmts_for_value ()) {
08552 wn = WN_CreateEval (wn);
08553 WFE_Stmt_Append (wn, Get_Srcpos ());
08554 return;
08555 }
08556 for (;;) {
08557 if (WN_operator (wn) == OPR_COMMA) {
08558 WN *crwn = wn;
08559 if (WN_operator (WN_kid1 (wn)) == OPR_LDID &&
08560 WN_st (WN_kid1 (wn)) == Return_Val_Preg &&
08561 (WN_operator (WN_last (WN_kid0 (wn))) == OPR_CALL ||
08562 WN_operator (WN_last (WN_kid0 (wn))) == OPR_ICALL)) {
08563 WN_set_rtype (WN_last (WN_kid0 (wn)), MTYPE_V);
08564 WFE_Stmt_Append (WN_kid0 (wn), Get_Srcpos ());
08565 WN_Delete (crwn);
08566 break;
08567 }
08568 else {
08569 WFE_Stmt_Append (WN_kid0 (wn), Get_Srcpos ());
08570 wn = WN_kid1 (wn);
08571 WN_Delete (crwn);
08572 }
08573 }
08574 else {
08575 BOOL need_eval = TRUE;
08576 if (WN_operator (wn) == OPR_LDID &&
08577 !TY_is_volatile (ST_type (WN_st (wn))))
08578 need_eval = FALSE;
08579 else
08580 if (WN_operator (wn) == OPR_ILOAD &&
08581 WN_has_side_effects (wn) == FALSE)
08582 need_eval = FALSE;
08583 if (need_eval) {
08584 wn = WN_CreateEval (wn);
08585 WFE_Stmt_Append (wn, Get_Srcpos ());
08586 }
08587 break;
08588 }
08589 }
08590 }
08591 }
08592
08593 void WFE_Null_Return (void)
08594 {
08595 WN *wn = WN_CreateReturn ();
08596 WFE_Stmt_Append (wn, Get_Srcpos());
08597 }
08598
08599 UINT64
08600 Get_Integer_Value (tree exp)
08601 {
08602 FmtAssert (TREE_CODE(exp) == INTEGER_CST,
08603 ("Get_Integer_Value unexpected tree"));
08604 #ifdef _LP64
08605 return TREE_INT_CST_LOW (exp);
08606 #else
08607 UINT64 h = TREE_INT_CST_HIGH (exp);
08608 UINT64 l = TREE_INT_CST_LOW (exp);
08609 #ifndef KEY
08610 l = l << 32 >> 32;
08611 h = h << 32;
08612 return (h | l);
08613 #else
08614
08615
08616 return (l);
08617 #endif
08618 #endif
08619 }
08620
08621 void
08622 WFE_Expr_Init (void)
08623 {
08624 INT i;
08625 for (i = 0; i < LAST_AND_UNUSED_TREE_CODE; i++)
08626 FmtAssert (Operator_From_Tree [i].tree_code == i,
08627 ("Operator_From_Tree table incorrect at %d", i));
08628 }
08629
08630 char *
08631 WFE_Tree_Node_Name (tree op)
08632 {
08633 return Operator_From_Tree [TREE_CODE (op)].name;
08634 }