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 #include <values.h>
00053 #include "defs.h"
00054 #include "glob.h"
00055 #include "config.h"
00056 #ifdef TARG_X8664
00057 #include "config_opt.h"
00058 #endif
00059 #include "wn.h"
00060 #include "wn_util.h"
00061 #include "targ_sim.h"
00062 #include "const.h"
00063 #include "c_int_model.h"
00064
00065 extern "C" {
00066 #include "gnu_config.h"
00067 }
00068 #include "gnu/system.h"
00069
00070 extern "C" {
00071 #include "gnu/flags.h"
00072 #include "gnu/machmode.h"
00073 }
00074
00075 extern "C" {
00076 #include "gnu/system.h"
00077 #include "gnu/tree.h"
00078 extern void warning (char*,...);
00079 #ifdef GPLUSPLUS_FE
00080 #include "gnu/cp/cp-tree.h"
00081 #endif
00082 #ifdef KEY
00083 #include "real.h"
00084 #endif // KEY
00085 }
00086
00087 #include "ir_reader.h"
00088 #include "wfe_misc.h"
00089 #include "wfe_dst.h"
00090 #include "tree_symtab.h"
00091 #include "wfe_decl.h"
00092 #include "wfe_expr.h"
00093 #include "wfe_stmt.h"
00094 #include "tree_cmp.h"
00095
00096
00097 #ifdef KEY
00098 extern void WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_ID, ST *);
00099 #endif // KEY
00100
00101 LABEL_IDX loop_expr_exit_label = 0;
00102
00103 struct operator_from_tree_t {
00104 int tree_code;
00105 char* name;
00106 char code;
00107 int nkids;
00108 OPERATOR opr;
00109 } Operator_From_Tree [] = {
00110 ERROR_MARK, "error_mark", 'x', 0, OPERATOR_UNKNOWN,
00111 IDENTIFIER_NODE, "identifier_node", 'x', -1, OPERATOR_UNKNOWN,
00112 OP_IDENTIFIER, "op_identifier", 'x', 2, OPERATOR_UNKNOWN,
00113 TREE_LIST, "tree_list", 'x', 2, OPERATOR_UNKNOWN,
00114 TREE_VEC, "tree_vec", 'x', 2, OPERATOR_UNKNOWN,
00115 BLOCK, "block", 'b', 0, OPERATOR_UNKNOWN,
00116 VOID_TYPE, "void_type", 't', 0, OPERATOR_UNKNOWN,
00117 INTEGER_TYPE, "integer_type", 't', 0, OPERATOR_UNKNOWN,
00118 REAL_TYPE, "real_type", 't', 0, OPERATOR_UNKNOWN,
00119 COMPLEX_TYPE, "complex_type", 't', 0, OPERATOR_UNKNOWN,
00120 VECTOR_TYPE, "vector_type", 't', 0, OPERATOR_UNKNOWN,
00121 ENUMERAL_TYPE, "enumeral_type", 't', 0, OPERATOR_UNKNOWN,
00122 BOOLEAN_TYPE, "boolean_type", 't', 0, OPERATOR_UNKNOWN,
00123 CHAR_TYPE, "char_type", 't', 0, OPERATOR_UNKNOWN,
00124 POINTER_TYPE, "pointer_type", 't', 0, OPERATOR_UNKNOWN,
00125 OFFSET_TYPE, "offset_type", 't', 0, OPERATOR_UNKNOWN,
00126 REFERENCE_TYPE, "reference_type", 't', 0, OPERATOR_UNKNOWN,
00127 METHOD_TYPE, "method_type", 't', 0, OPERATOR_UNKNOWN,
00128 FILE_TYPE, "file_type", 't', 0, OPERATOR_UNKNOWN,
00129 ARRAY_TYPE, "array_type", 't', 0, OPERATOR_UNKNOWN,
00130 SET_TYPE, "set_type", 't', 0, OPERATOR_UNKNOWN,
00131 RECORD_TYPE, "record_type", 't', 0, OPERATOR_UNKNOWN,
00132 UNION_TYPE, "union_type", 't', 0, OPERATOR_UNKNOWN,
00133 QUAL_UNION_TYPE, "qual_union_type", 't', 0, OPERATOR_UNKNOWN,
00134 FUNCTION_TYPE, "function_type", 't', 0, OPERATOR_UNKNOWN,
00135 LANG_TYPE, "lang_type", 't', 0, OPERATOR_UNKNOWN,
00136 INTEGER_CST, "integer_cst", 'c', 2, OPERATOR_UNKNOWN,
00137 REAL_CST, "real_cst", 'c', 3, OPERATOR_UNKNOWN,
00138 COMPLEX_CST, "complex_cst", 'c', 3, OPERATOR_UNKNOWN,
00139 VECTOR_CST, "vector_cst", 'c', 3, OPERATOR_UNKNOWN,
00140 STRING_CST, "string_cst", 'c', 3, OPERATOR_UNKNOWN,
00141 FUNCTION_DECL, "function_decl", 'd', 0, OPERATOR_UNKNOWN,
00142 LABEL_DECL, "label_decl", 'd', 0, OPERATOR_UNKNOWN,
00143 CONST_DECL, "const_decl", 'd', 0, OPERATOR_UNKNOWN,
00144 TYPE_DECL, "type_decl", 'd', 0, OPERATOR_UNKNOWN,
00145 VAR_DECL, "var_decl", 'd', 0, OPERATOR_UNKNOWN,
00146 PARM_DECL, "parm_decl", 'd', 0, OPERATOR_UNKNOWN,
00147 RESULT_DECL, "result_decl", 'd', 0, OPERATOR_UNKNOWN,
00148 FIELD_DECL, "field_decl", 'd', 0, OPERATOR_UNKNOWN,
00149 NAMESPACE_DECL, "namespace_decl", 'd', 0, OPERATOR_UNKNOWN,
00150 COMPONENT_REF, "component_ref", 'r', 2, OPERATOR_UNKNOWN,
00151 BIT_FIELD_REF, "bit_field_ref", 'r', 3, OPERATOR_UNKNOWN,
00152 INDIRECT_REF, "indirect_ref", 'r', 1, OPERATOR_UNKNOWN,
00153 BUFFER_REF, "buffer_ref", 'r', 1, OPERATOR_UNKNOWN,
00154 ARRAY_REF, "array_ref", 'r', 2, OPERATOR_UNKNOWN,
00155 ARRAY_RANGE_REF, "array_range_ref", 'r', 2, OPERATOR_UNKNOWN,
00156 VTABLE_REF, "vtable_ref", 'r', 3, OPERATOR_UNKNOWN,
00157 CONSTRUCTOR, "constructor", 'e', 2, OPERATOR_UNKNOWN,
00158 COMPOUND_EXPR, "compound_expr", 'e', 2, OPERATOR_UNKNOWN,
00159 MODIFY_EXPR, "modify_expr", 'e', 2, OPERATOR_UNKNOWN,
00160 INIT_EXPR, "init_expr", 'e', 2, OPERATOR_UNKNOWN,
00161 TARGET_EXPR, "target_expr", 'e', 4, OPERATOR_UNKNOWN,
00162 COND_EXPR, "cond_expr", 'e', 3, OPERATOR_UNKNOWN,
00163 BIND_EXPR, "bind_expr", 'e', 3, OPERATOR_UNKNOWN,
00164 CALL_EXPR, "call_expr", 'e', 3, OPERATOR_UNKNOWN,
00165 METHOD_CALL_EXPR, "method_call_expr", 'e', 4, OPERATOR_UNKNOWN,
00166 WITH_CLEANUP_EXPR, "with_cleanup_expr", 'e', 3, OPERATOR_UNKNOWN,
00167 CLEANUP_POINT_EXPR, "cleanup_point_expr", 'e', 1, OPERATOR_UNKNOWN,
00168 PLACEHOLDER_EXPR, "placeholder_expr", 'x', 0, OPERATOR_UNKNOWN,
00169 WITH_RECORD_EXPR, "with_record_expr", 'e', 2, OPERATOR_UNKNOWN,
00170 PLUS_EXPR, "plus_expr", '2', 2, OPR_ADD,
00171 MINUS_EXPR, "minus_expr", '2', 2, OPR_SUB,
00172 MULT_EXPR, "mult_expr", '2', 2, OPR_MPY,
00173 TRUNC_DIV_EXPR, "trunc_div_expr", '2', 2, OPR_DIV,
00174 CEIL_DIV_EXPR, "ceil_div_expr", '2', 2, OPR_DIV,
00175 FLOOR_DIV_EXPR, "floor_div_expr", '2', 2, OPERATOR_UNKNOWN,
00176 ROUND_DIV_EXPR, "round_div_expr", '2', 2, OPERATOR_UNKNOWN,
00177 TRUNC_MOD_EXPR, "trunc_mod_expr", '2', 2, OPR_REM,
00178 CEIL_MOD_EXPR, "ceil_mod_expr", '2', 2, OPERATOR_UNKNOWN,
00179 FLOOR_MOD_EXPR, "floor_mod_expr", '2', 2, OPERATOR_UNKNOWN,
00180 ROUND_MOD_EXPR, "round_mod_expr", '2', 2, OPERATOR_UNKNOWN,
00181 RDIV_EXPR, "rdiv_expr", '2', 2, OPR_DIV,
00182 EXACT_DIV_EXPR, "exact_div_expr", '2', 2, OPR_DIV,
00183 FIX_TRUNC_EXPR, "fix_trunc_expr", '1', 1, OPERATOR_UNKNOWN,
00184 FIX_CEIL_EXPR, "fix_ceil_expr", '1', 1, OPERATOR_UNKNOWN,
00185 FIX_FLOOR_EXPR, "fix_floor_expr", '1', 1, OPERATOR_UNKNOWN,
00186 FIX_ROUND_EXPR, "fix_round_expr", '1', 1, OPERATOR_UNKNOWN,
00187 FLOAT_EXPR, "float_expr", '1', 1, OPERATOR_UNKNOWN,
00188 EXPON_EXPR, "expon_expr", '2', 2, OPERATOR_UNKNOWN,
00189 NEGATE_EXPR, "negate_expr", '1', 1, OPR_NEG,
00190 MIN_EXPR, "min_expr", '2', 2, OPR_MIN,
00191 MAX_EXPR, "max_expr", '2', 2, OPR_MAX,
00192 ABS_EXPR, "abs_expr", '1', 1, OPR_ABS,
00193 FFS_EXPR, "ffs_expr", '1', 1, OPERATOR_UNKNOWN,
00194 LSHIFT_EXPR, "lshift_expr", '2', 2, OPR_SHL,
00195 RSHIFT_EXPR, "rshift_expr", '2', 2, OPERATOR_UNKNOWN,
00196 LROTATE_EXPR, "lrotate_expr", '2', 2, OPR_RROTATE,
00197 RROTATE_EXPR, "rrotate_expr", '2', 2, OPR_RROTATE,
00198 BIT_IOR_EXPR, "bit_ior_expr", '2', 2, OPR_BIOR,
00199 BIT_XOR_EXPR, "bit_xor_expr", '2', 2, OPR_BXOR,
00200 BIT_AND_EXPR, "bit_and_expr", '2', 2, OPR_BAND,
00201 BIT_ANDTC_EXPR, "bit_andtc_expr", '2', 2, OPERATOR_UNKNOWN,
00202 BIT_NOT_EXPR, "bit_not_expr", '1', 1, OPR_BNOT,
00203 TRUTH_ANDIF_EXPR, "truth_andif_expr", 'e', 2, OPR_CAND,
00204 TRUTH_ORIF_EXPR, "truth_orif_expr", 'e', 2, OPR_CIOR,
00205 TRUTH_AND_EXPR, "truth_and_expr", 'e', 2, OPR_BAND,
00206 TRUTH_OR_EXPR, "truth_or_expr", 'e', 2, OPR_BIOR,
00207 TRUTH_XOR_EXPR, "truth_xor_expr", 'e', 2, OPR_BXOR,
00208 TRUTH_NOT_EXPR, "truth_not_expr", 'e', 1, OPR_LNOT,
00209 LT_EXPR, "lt_expr", '<', 2, OPR_LT,
00210 LE_EXPR, "le_expr", '<', 2, OPR_LE,
00211 GT_EXPR, "gt_expr", '<', 2, OPR_GT,
00212 GE_EXPR, "ge_expr", '<', 2, OPR_GE,
00213 EQ_EXPR, "eq_expr", '<', 2, OPR_EQ,
00214 NE_EXPR, "ne_expr", '<', 2, OPR_NE,
00215 UNORDERED_EXPR, "unordered_expr", '<', 2, OPERATOR_UNKNOWN,
00216 ORDERED_EXPR, "ordered_expr", '<', 2, OPERATOR_UNKNOWN,
00217 UNLT_EXPR, "unlt_expr", '<', 2, OPERATOR_UNKNOWN,
00218 UNLE_EXPR, "unle_expr", '<', 2, OPERATOR_UNKNOWN,
00219 UNGT_EXPR, "ungt_expr", '<', 2, OPERATOR_UNKNOWN,
00220 UNGE_EXPR, "unge_expr", '<', 2, OPERATOR_UNKNOWN,
00221 UNEQ_EXPR, "uneq_expr", '<', 2, OPERATOR_UNKNOWN,
00222 IN_EXPR, "in_expr", '2', 2, OPERATOR_UNKNOWN,
00223 SET_LE_EXPR, "set_le_expr", '<', 2, OPERATOR_UNKNOWN,
00224 CARD_EXPR, "card_expr", '1', 1, OPERATOR_UNKNOWN,
00225 RANGE_EXPR, "range_expr", '2', 2, OPERATOR_UNKNOWN,
00226 CONVERT_EXPR, "convert_expr", '1', 1, OPERATOR_UNKNOWN,
00227 NOP_EXPR, "nop_expr", '1', 1, OPERATOR_UNKNOWN,
00228 NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1, OPERATOR_UNKNOWN,
00229 VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1, OPERATOR_UNKNOWN,
00230 SAVE_EXPR, "save_expr", 'e', 3, OPERATOR_UNKNOWN,
00231 UNSAVE_EXPR, "unsave_expr", 'e', 1, OPERATOR_UNKNOWN,
00232 RTL_EXPR, "rtl_expr", 'e', 2, OPERATOR_UNKNOWN,
00233 ADDR_EXPR, "addr_expr", 'e', 1, OPERATOR_UNKNOWN,
00234 REFERENCE_EXPR, "reference_expr", 'e', 1, OPERATOR_UNKNOWN,
00235 ENTRY_VALUE_EXPR, "entry_value_expr", 'e', 1, OPERATOR_UNKNOWN,
00236 FDESC_EXPR, "fdesc_expr", 'e', 2, OPERATOR_UNKNOWN,
00237 COMPLEX_EXPR, "complex_expr", '2', 2, OPR_PAIR,
00238 CONJ_EXPR, "conj_expr", '1', 1, OPERATOR_UNKNOWN,
00239 REALPART_EXPR, "realpart_expr", '1', 1, OPR_FIRSTPART,
00240 IMAGPART_EXPR, "imagpart_expr", '1', 1, OPR_SECONDPART,
00241 PREDECREMENT_EXPR, "predecrement_expr", 'e', 2, OPR_SUB,
00242 PREINCREMENT_EXPR, "preincrement_expr", 'e', 2, OPR_ADD,
00243 POSTDECREMENT_EXPR, "postdecrement_expr", 'e', 2, OPR_SUB,
00244 POSTINCREMENT_EXPR, "postincrement_expr", 'e', 2, OPR_ADD,
00245 VA_ARG_EXPR, "va_arg_expr", 'e', 1, OPERATOR_UNKNOWN,
00246 TRY_CATCH_EXPR, "try_catch_expr", 'e', 2, OPERATOR_UNKNOWN,
00247 TRY_FINALLY_EXPR, "try_finally", 'e', 2, OPERATOR_UNKNOWN,
00248 GOTO_SUBROUTINE_EXPR, "goto_subroutine", 'e', 2, OPERATOR_UNKNOWN,
00249 POPDHC_EXPR, "popdhc_expr", 's', 0, OPERATOR_UNKNOWN,
00250 POPDCC_EXPR, "popdcc_expr", 's', 0, OPERATOR_UNKNOWN,
00251 LABEL_EXPR, "label_expr", 's', 1, OPERATOR_UNKNOWN,
00252 GOTO_EXPR, "goto_expr", 's', 1, OPERATOR_UNKNOWN,
00253 RETURN_EXPR, "return_expr", 's', 1, OPERATOR_UNKNOWN,
00254 EXIT_EXPR, "exit_expr", 's', 1, OPERATOR_UNKNOWN,
00255 LOOP_EXPR, "loop_expr", 's', 1, OPERATOR_UNKNOWN,
00256 LABELED_BLOCK_EXPR, "labeled_block_expr", 'e', 2, OPERATOR_UNKNOWN,
00257 EXIT_BLOCK_EXPR, "exit_block_expr", 'e', 2, OPERATOR_UNKNOWN,
00258 EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 3, OPERATOR_UNKNOWN,
00259 SWITCH_EXPR, "switch_expr", 'e', 2, OPERATOR_UNKNOWN,
00260 EXC_PTR_EXPR, "exc_ptr_expr", 'e', 0, OPERATOR_UNKNOWN,
00261 LAST_AND_UNUSED_TREE_CODE,"last_and_unused_tree_code",0, 0, OPERATOR_UNKNOWN,
00262
00263 SRCLOC, "srcloc", 'x', 2, OPERATOR_UNKNOWN,
00264 SIZEOF_EXPR, "sizeof_expr", '1', 1, OPERATOR_UNKNOWN,
00265 ARROW_EXPR, "arrow_expr", 'e', 1, OPERATOR_UNKNOWN,
00266 ALIGNOF_EXPR, "alignof_expr", '1', 1, OPERATOR_UNKNOWN,
00267 EXPR_STMT, "expr_stmt", 'e', 1, OPERATOR_UNKNOWN,
00268 COMPOUND_STMT, "compound_stmt", 'e', 1, OPERATOR_UNKNOWN,
00269 DECL_STMT, "decl_stmt", 'e', 1, OPERATOR_UNKNOWN,
00270 IF_STMT, "if_stmt", 'e', 3, OPERATOR_UNKNOWN,
00271 FOR_STMT, "for_stmt", 'e', 4, OPERATOR_UNKNOWN,
00272 WHILE_STMT, "while_stmt", 'e', 2, OPERATOR_UNKNOWN,
00273 DO_STMT, "do_stmt", 'e', 2, OPERATOR_UNKNOWN,
00274 RETURN_STMT, "return_stmt", 'e', 1, OPERATOR_UNKNOWN,
00275 BREAK_STMT, "break_stmt", 'e', 0, OPERATOR_UNKNOWN,
00276 CONTINUE_STMT, "continue_stmt", 'e', 0, OPERATOR_UNKNOWN,
00277 SWITCH_STMT, "switch_stmt", 'e', 2, OPERATOR_UNKNOWN,
00278 GOTO_STMT, "goto_stmt", 'e', 1, OPERATOR_UNKNOWN,
00279 LABEL_STMT, "label_stmt", 'e', 1, OPERATOR_UNKNOWN,
00280 ASM_STMT, "asm_stmt", 'e', 5, OPERATOR_UNKNOWN,
00281 SCOPE_STMT, "scope_stmt", 'e', 1, OPERATOR_UNKNOWN,
00282 FILE_STMT, "file_stmt", 'e', 1, OPERATOR_UNKNOWN,
00283 CASE_LABEL, "case_label", 'e', 2, OPERATOR_UNKNOWN,
00284 STMT_EXPR, "stmt_expr", 'e', 1, OPERATOR_UNKNOWN,
00285 COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1, OPERATOR_UNKNOWN,
00286 CLEANUP_STMT, "cleanup_stmt", 'e', 2, OPERATOR_UNKNOWN,
00287 #ifdef KEY
00288 OMP_MARKER_STMT, "omp_marker_stmt", 'e', 0, OPERATOR_UNKNOWN,
00289 #endif // KEY
00290 FREQ_HINT_STMT, "freq_hint_stmt", 'e', 1, OPERATOR_UNKNOWN,
00291 LAST_C_TREE_CODE, "last_c_tree_code", 0, 0, OPERATOR_UNKNOWN,
00292
00293 #ifdef GPLUSPLUS_FE
00294 OFFSET_REF, "offset_ref", 'r', 2, OPERATOR_UNKNOWN,
00295 PTRMEM_CST, "ptrmem_cst", 'c', 2, OPERATOR_UNKNOWN,
00296 NEW_EXPR, "nw_expr", 'e', 3, OPERATOR_UNKNOWN,
00297 VEC_NEW_EXPR, "vec_nw_expr", 'e', 3, OPERATOR_UNKNOWN,
00298 DELETE_EXPR, "dl_expr", 'e', 2, OPERATOR_UNKNOWN,
00299 VEC_DELETE_EXPR, "vec_dl_expr", 'e', 2, OPERATOR_UNKNOWN,
00300 SCOPE_REF, "scope_ref", 'r', 2, OPERATOR_UNKNOWN,
00301 MEMBER_REF, "member_ref", 'r', 2, OPERATOR_UNKNOWN,
00302 TYPE_EXPR, "type_expr", 'e', 1, OPERATOR_UNKNOWN,
00303 AGGR_INIT_EXPR, "aggr_init_expr", 'e', 3, OPERATOR_UNKNOWN,
00304 THROW_EXPR, "throw_expr", 'e', 1, OPERATOR_UNKNOWN,
00305 EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0, OPERATOR_UNKNOWN,
00306 #ifdef KEY
00307 BASELINK, "baselink", 'e', 3, OPERATOR_UNKNOWN,
00308 #endif // KEY
00309 TEMPLATE_DECL, "template_decl", 'd', 0, OPERATOR_UNKNOWN,
00310 TEMPLATE_PARM_INDEX, "template_parm_index", 'x', 0, OPERATOR_UNKNOWN,
00311 TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0, OPERATOR_UNKNOWN,
00312 TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0, OPERATOR_UNKNOWN,
00313 BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm", 't', 0, OPERATOR_UNKNOWN,
00314 TYPENAME_TYPE, "typename_type", 't', 0, OPERATOR_UNKNOWN,
00315 UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0, OPERATOR_UNKNOWN,
00316 TYPEOF_TYPE, "typeof_type", 't', 0, OPERATOR_UNKNOWN,
00317 USING_DECL, "using_decl", 'd', 0, OPERATOR_UNKNOWN,
00318 USING_STMT, "using_directive", 'e', 1, OPERATOR_UNKNOWN,
00319 #ifdef KEY
00320 DEFAULT_ARG, "default_arg", 'x', 2, OPERATOR_UNKNOWN,
00321 #else
00322 DEFAULT_ARG, "default_arg", 'c', 2, OPERATOR_UNKNOWN,
00323 #endif // KEY
00324 TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2, OPERATOR_UNKNOWN,
00325 #ifndef KEY // CPLUS_BINDING does not exist
00326 CPLUS_BINDING, "binding", 'x', 2, OPERATOR_UNKNOWN,
00327 #endif // !KEY
00328 OVERLOAD, "overload", 'x', 1, OPERATOR_UNKNOWN,
00329 WRAPPER, "wrapper", 'x', 1, OPERATOR_UNKNOWN,
00330 LOOKUP_EXPR, "lookup_expr", 'e', 1, OPERATOR_UNKNOWN,
00331 MODOP_EXPR, "modop_expr", 'e', 3, OPERATOR_UNKNOWN,
00332 CAST_EXPR, "cast_expr", '1', 1, OPERATOR_UNKNOWN,
00333 REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00334 CONST_CAST_EXPR, "const_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00335 STATIC_CAST_EXPR, "static_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00336 DYNAMIC_CAST_EXPR, "dynamic_cast_expr", '1', 1, OPERATOR_UNKNOWN,
00337 DOTSTAR_EXPR, "dotstar_expr", 'e', 2, OPERATOR_UNKNOWN,
00338 TYPEID_EXPR, "typeid_expr", 'e', 1, OPERATOR_UNKNOWN,
00339 PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3, OPERATOR_UNKNOWN,
00340 #ifndef KEY // SUBOBJECT, CTOR_STMT removed
00341 SUBOBJECT, "subobject", 'e', 1, OPERATOR_UNKNOWN,
00342 CTOR_STMT, "ctor_stmt", 'e', 0, OPERATOR_UNKNOWN,
00343 CTOR_INITIALIZER, "ctor_initializer", 'e', 2, OPERATOR_UNKNOWN,
00344 #else
00345 CTOR_INITIALIZER, "ctor_initializer", 'e', 1, OPERATOR_UNKNOWN,
00346 #endif // !KEY
00347 RETURN_INIT, "return_init", 'e', 2, OPERATOR_UNKNOWN,
00348 TRY_BLOCK, "try_block", 'e', 2, OPERATOR_UNKNOWN,
00349 EH_SPEC_BLOCK, "eh_spec_block", 'e', 2, OPERATOR_UNKNOWN,
00350 HANDLER, "handler", 'e', 2, OPERATOR_UNKNOWN,
00351 MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1, OPERATOR_UNKNOWN,
00352 TAG_DEFN, "tag_defn", 'e', 0, OPERATOR_UNKNOWN,
00353 IDENTITY_CONV, "identity_conv", 'e', 1, OPERATOR_UNKNOWN,
00354 LVALUE_CONV, "lvalue_conv", 'e', 1, OPERATOR_UNKNOWN,
00355 QUAL_CONV, "qual_conv", 'e', 1, OPERATOR_UNKNOWN,
00356 STD_CONV, "std_conv", 'e', 1, OPERATOR_UNKNOWN,
00357 PTR_CONV, "ptr_conv", 'e', 1, OPERATOR_UNKNOWN,
00358 PMEM_CONV, "pmem_conv", 'e', 1, OPERATOR_UNKNOWN,
00359 BASE_CONV, "base_conv", 'e', 1, OPERATOR_UNKNOWN,
00360 REF_BIND, "ref_bind", 'e', 1, OPERATOR_UNKNOWN,
00361 USER_CONV, "user_conv", 'e', 2, OPERATOR_UNKNOWN,
00362 AMBIG_CONV, "ambig_conv", 'e', 1, OPERATOR_UNKNOWN,
00363 RVALUE_CONV, "rvalue_conv", 'e', 1, OPERATOR_UNKNOWN,
00364 LAST_CPLUS_TREE_CODE, "last_cplus_tree_code", 0, 0, OPERATOR_UNKNOWN
00365 #endif
00366 };
00367
00368 #ifdef TARG_SL
00369
00370
00371
00372 typedef enum EXTEND_PARM_POS {
00373 PZERO,
00374 P0,
00375 P1,
00376 P2,
00377 P3,
00378 P4,
00379 P0_P2,
00380 P1_P3,
00381 P2_P4,
00382 P3_P4,
00383 }EXTEND_PARM_POS;
00384
00385 typedef struct intrinsicop_attr_extended {
00386 INTRINSIC id;
00387 BOOL need_extend;
00388 int extend_kid;
00389 EXTEND_PARM_POS pos;
00390 INTRINSIC aux_id;
00391 } INTRN_ATTR_EXTEND;
00392
00393 #define INTRN_EATTR_LAST 27
00394 static INTRN_ATTR_EXTEND intrn_eattr[INTRN_EATTR_LAST] = {
00395 INTRN_C2_LD_V, FALSE, 1, P1,INTRN_C3_PTR,
00396 INTRN_C2_LD_G, FALSE, 1, P0,INTRN_C3_PTR,
00397 INTRN_C2_LD_V2G, FALSE, 1, P0,INTRN_C3_PTR,
00398 INTRN_C2_LD_C_IMM, FALSE, 1, P1,INTRN_C3_PTR,
00399 INTRN_C2_LD_V_IMM, FALSE, 1, P4,INTRN_C3_PTR,
00400 INTRN_C2_LD_G_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00401 INTRN_C2_LD_V2G_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00402 INTRN_C2_ST_V, FALSE, 1, P1,INTRN_C3_PTR,
00403 INTRN_C2_ST_G, FALSE, 1, P1,INTRN_C3_PTR,
00404 INTRN_C2_ST_G2V, FALSE, 1, P1,INTRN_C3_PTR,
00405 INTRN_C2_ST_C_IMM, FALSE, 1, P1,INTRN_C3_PTR,
00406 INTRN_C2_ST_V_IMM, FALSE, 1, P3,INTRN_C3_PTR,
00407 INTRN_C2_ST_G_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00408 INTRN_C2_ST_G2V_IMM, FALSE, 1, P2,INTRN_C3_PTR,
00409
00410 INTRN_C3DMAC_A, TRUE, 2, P2_P4, INTRN_C3_PTR,
00411 INTRN_C3DMULA_A, TRUE, 1, P2, INTRN_C3_PTR,
00412 INTRN_C3LD, TRUE, 1, P0, INTRN_C3_PTR,
00413 INTRN_C3ST, TRUE, 1, P1, INTRN_C3_PTR,
00414 INTRN_C3MAC_A, TRUE, 2, P2_P4, INTRN_C3_PTR,
00415 INTRN_C3MAC_AR, TRUE, 1, P3, INTRN_C3_PTR,
00416 INTRN_C3MULA_A, TRUE, 1, P2_P4, INTRN_C3_PTR,
00417 INTRN_C3MULA_AR, TRUE, 1, P3, INTRN_C3_PTR,
00418 INTRN_C3SAADD_A, TRUE, 2, P0_P2, INTRN_C3_PTR,
00419 INTRN_C3SAADDH_A, TRUE, 2, P0_P2, INTRN_C3_PTR,
00420 INTRN_C3SADDA_A, TRUE, 1, P2, INTRN_C3_PTR,
00421 INTRN_C3SAMULH_A, TRUE, 2, P0_P2, INTRN_C3_PTR,
00422 INTRN_C3_SET_CIRCBUF, FALSE, 2, P3_P4, INTRN_C3_PTR,
00423 };
00424
00425 static BOOL intrinsic_op_need_extend (INTRINSIC id) {
00426
00427 INTRN_ATTR_EXTEND *p = &intrn_eattr[0];
00428 int i=0;
00429 while (p && (i<INTRN_EATTR_LAST)) {
00430 if (p->id == id ) {
00431 return p->need_extend;
00432 }
00433 i++;
00434 p++;
00435 }
00436 return FALSE;
00437
00438 }
00439
00440 static BOOL intrinsic_need_deref (INTRINSIC id) {
00441
00442 INTRN_ATTR_EXTEND *p = &intrn_eattr[0];
00443 int i=0;
00444 while (p && (i<INTRN_EATTR_LAST)) {
00445 if (p->id == id ) {
00446 return TRUE;
00447 }
00448 i++;
00449 p++;
00450 }
00451 return FALSE;
00452
00453 }
00454
00455 static INTRN_ATTR_EXTEND *Get_intrinsic_op_Eattr (INTRINSIC id) {
00456 INTRN_ATTR_EXTEND *p = &intrn_eattr[0];
00457 int i =0;
00458 while (p && (i<INTRN_EATTR_LAST)) {
00459 if (p->id == id ) {
00460 return p;
00461 }
00462 p++;
00463 i++;
00464 }
00465 return NULL;
00466 }
00467
00468 static void WN_Set_Deref_If_Needed(WN *wn) {
00469 INTRINSIC intrn=WN_intrinsic(wn);
00470 if(intrinsic_need_deref(intrn)){
00471 INTRN_ATTR_EXTEND *p=Get_intrinsic_op_Eattr(intrn);
00472
00473 switch (p->pos) {
00474 case P0:
00475 WN_Set_Parm_Dereference(WN_kid(wn,0)); break;
00476 case P1:
00477 WN_Set_Parm_Dereference(WN_kid(wn,1)); break;
00478 case P2:
00479 WN_Set_Parm_Dereference(WN_kid(wn,2)); break;
00480 case P3:
00481 WN_Set_Parm_Dereference(WN_kid(wn,3)); break;
00482 case P4:
00483 WN_Set_Parm_Dereference(WN_kid(wn,4)); break;
00484 case P0_P2:
00485 WN_Set_Parm_Dereference(WN_kid(wn,0)); WN_Set_Parm_Dereference(WN_kid(wn,2)); break;
00486 case P1_P3:
00487 WN_Set_Parm_Dereference(WN_kid(wn,1)); WN_Set_Parm_Dereference(WN_kid(wn,3)); break;
00488 case P2_P4:
00489 WN_Set_Parm_Dereference(WN_kid(wn,2)); WN_Set_Parm_Dereference(WN_kid(wn,4)); break;
00490 case P3_P4:
00491 WN_Set_Parm_Dereference(WN_kid(wn,3)); WN_Set_Parm_Dereference(WN_kid(wn,4)); break;
00492 default:
00493 Is_True(0, ("intrinsic has no extended attribution"));
00494 }
00495 }
00496 return;
00497 }
00498
00499 static int intrinsic_op_extend_kid (int index) {
00500 return intrn_eattr[index].extend_kid;
00501 }
00502
00503 static EXTEND_PARM_POS intrinsic_op_parm_pos (int index) {
00504 return intrn_eattr[index].pos;
00505 }
00506
00507 static BOOL WN_Need_Append_Intrinsic(WN *rhs) {
00508 OPERATOR opr=WN_operator(rhs);
00509 if (opr == OPR_INTRINSIC_OP || opr == OPR_INTRINSIC_CALL) {
00510 INTRINSIC inid = WN_intrinsic(rhs);
00511 if (intrinsic_op_need_extend(inid)) {
00512 return TRUE;
00513 }
00514 } else if (opr == OPR_CVTL) {
00515 WN *tmp = WN_kid0(rhs);
00516 OPERATOR kid_opr=WN_operator(tmp);
00517 if (kid_opr == OPR_INTRINSIC_OP || kid_opr == OPR_INTRINSIC_CALL) {
00518 INTRINSIC inid = WN_intrinsic(tmp);
00519 if (intrinsic_op_need_extend(inid)) {
00520 return TRUE;
00521 }
00522 }
00523 }
00524 return FALSE;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 static void WFE_Stmt_Append_Extend_Intrinsic(WN *wn, WN *master_variable, SRCPOS src) {
00534 WN *kid1s[5];
00535 WN *op1;
00536 int aux_kid = -1;
00537 int extend_num = -1;
00538 int pos[5]= {-1, -1, -1, -1, -1};
00539
00540 WN *tmp_wn;
00541 INTRN_ATTR_EXTEND *p ;
00542 if (WN_operator(WN_kid0(wn)) == OPR_INTRINSIC_OP) {
00543 p = Get_intrinsic_op_Eattr(WN_intrinsic(WN_kid0(wn)));
00544 tmp_wn = wn;
00545 } else if (WN_operator(WN_kid0(wn)) == OPR_CVTL && WN_operator(WN_kid0(WN_kid0(wn))) == OPR_INTRINSIC_OP ) {
00546 p = Get_intrinsic_op_Eattr(WN_intrinsic(WN_kid0(WN_kid0(wn))));
00547 tmp_wn = WN_kid0(wn);
00548 } else if (WN_operator(wn) == OPR_INTRINSIC_CALL) {
00549 p = Get_intrinsic_op_Eattr(WN_intrinsic(wn));
00550 tmp_wn = wn;
00551 }
00552
00553 if (p) {
00554 extend_num = p->extend_kid;
00555 switch (p->aux_id) {
00556 case INTRN_C3_PTR: aux_kid = 2; break;
00557 default:
00558 Is_True(0, ("unsupport internal intrinsic op"));
00559 }
00560 switch (p->pos) {
00561 case P0:
00562 pos[0] = 0; break;
00563 case P1:
00564 pos[0] = 1; break;
00565 case P2:
00566 pos[0] = 2; break;
00567 case P3:
00568 pos[0] = 3; break;
00569 case P0_P2:
00570 pos[0] = 0; pos[1] = 2; break;
00571 case P1_P3:
00572 pos[0] = 1; pos[1] = 3; break;
00573 case P2_P4:
00574 pos[0] = 2; pos[1] = 4; break;
00575 case P3_P4:
00576 pos[0] = 3; pos[1] = 4; break;
00577 default:
00578 Is_True(0, ("intrinsic has no extended attribution"));
00579 }
00580 } else {
00581 Is_True(0, ("intrinsic has no extended attribution"));
00582 }
00583
00584 TY_IDX ti2 = WN_ty(master_variable);
00585 TYPE_ID tm2 = TY_mtype(ti2);
00586 master_variable = WN_CreateParm (Mtype_comparison (tm2), master_variable,
00587 ti2, WN_PARM_BY_VALUE);
00588 kid1s[0]= master_variable;
00589 for (int i =0; i < extend_num; i++) {
00590 WN *op1;
00591 if (WN_operator(wn) == OPR_INTRINSIC_CALL) {
00592 op1 = WN_kid0(WN_kid(tmp_wn, pos[i]));
00593 } else {
00594 op1 = WN_kid0(WN_kid(WN_kid0(tmp_wn), pos[i]));
00595 }
00596
00597 ST *st1;
00598 if (WN_has_sym(op1)) {
00599 st1 = WN_st(op1);
00600 } else {
00601
00602 continue;
00603 }
00604 TY_IDX ti1 = WN_ty(op1);
00605 TYPE_ID tm1 = TY_mtype(ti1);
00606 op1 = WN_CreateParm (Mtype_comparison (tm1), op1,
00607 ti1, WN_PARM_BY_VALUE);
00608 kid1s[1]= op1;
00609 WN *app1 = WN_Create_Intrinsic(OPR_INTRINSIC_OP,TY_mtype(ST_type(st1)), MTYPE_V, p->aux_id, aux_kid, kid1s);
00610 WN *stmt1 = WN_Stid(TY_mtype(ST_type(st1)), ST_ofst(st1), st1, ST_type(st1), app1, 0);
00611 WFE_Stmt_Append(stmt1, src);
00612 }
00613 }
00614
00615 #endif
00616
00617
00618 #ifdef KEY
00619 static bool WFE_Call_Returns_Ptr_To_Member_Func (tree exp);
00620
00621 static WN *WFE_Expand_Ptr_To_Member_Func_Call_Expr (tree exp,
00622 TY_IDX nop_ty_idx, TYPE_ID rtype, TYPE_ID desc,
00623 WN_OFFSET offset = 0, UINT field_id = 0);
00624
00625
00626
00627 void
00628 WFE_Convert_To_Host_Order (long *buf)
00629 {
00630 if (!Same_Byte_Sex)
00631 {
00632 int t = buf[0];
00633 buf[0] = buf[1];
00634 buf[1] = t;
00635 }
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 static void
00647 WFE_add_guard_var (tree guard_var, WN *value_wn)
00648 {
00649 WN *stid, *comma;
00650
00651
00652 WN *zero_wn = WN_Intconst(MTYPE_I4, 0);
00653 stid = WN_Stid(MTYPE_I4, 0, Get_ST(guard_var), MTYPE_To_TY(MTYPE_I4),
00654 zero_wn, 0);
00655 WFE_Stmt_Append(stid, Get_Srcpos());
00656
00657
00658
00659 WN *one_wn = WN_Intconst(MTYPE_I4, 1);
00660 stid = WN_Stid(MTYPE_I4, 0, Get_ST(guard_var), MTYPE_To_TY(MTYPE_I4),
00661 one_wn, 0);
00662 if (WN_operator(value_wn) == OPR_COMMA) {
00663 comma = value_wn;
00664 } else if (WN_operator(WN_kid0(value_wn)) == OPR_COMMA) {
00665 comma = WN_kid0(value_wn);
00666 } else {
00667
00668 WN *wn0 = WN_CreateBlock();
00669 WN *wn1 = WN_kid0(value_wn);
00670 WN_Set_Linenum (wn0, Get_Srcpos());
00671 comma = WN_CreateComma (OPR_COMMA, WN_rtype(wn1), MTYPE_V, wn0, wn1);
00672 WN_kid0(value_wn) = comma;
00673 }
00674 WN *wn = WN_kid0(comma);
00675 FmtAssert(WN_operator(wn) == OPR_BLOCK,
00676 ("WFE_add_guard_var: unexpected WN operator"));
00677 WN_INSERT_BlockFirst(wn, stid);
00678 }
00679 #endif
00680
00681
00682
00683 bool
00684 Has_Subsumed_Cvtl(OPERATOR opr)
00685 {
00686 if (OPERATOR_is_load(opr) || OPERATOR_is_leaf(opr))
00687 return TRUE;
00688 if (opr == OPR_CVT || opr == OPR_CVTL || opr == OPR_TAS)
00689 return TRUE;
00690 if (opr == OPR_EQ || opr == OPR_NE ||
00691 opr == OPR_GE || opr == OPR_GT ||
00692 opr == OPR_LE || opr == OPR_LT ||
00693 opr == OPR_LNOT || opr == OPR_LAND || opr == OPR_LIOR ||
00694 opr == OPR_CAND || opr == OPR_CIOR)
00695 return TRUE;
00696 return FALSE;
00697 }
00698
00699
00700
00701
00702 inline UINT64 Parameter_Size(UINT64 sz)
00703 {
00704 # if WORDS_BIG_ENDIAN
00705 return sz;
00706 # else
00707 return (sz + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
00708 # endif
00709 }
00710
00711 inline TYPE_ID
00712 Widen_Mtype (TYPE_ID t)
00713 {
00714 if (MTYPE_is_m(t))
00715 return t;
00716 if (MTYPE_is_void(t) || t == MTYPE_BS) {
00717 Fail_FmtAssertion ("Widen_Mtype: for MTYPE_V or MTYPE_BS");
00718 return t;
00719 }
00720 if (MTYPE_byte_size(t) >= 4)
00721 return t;
00722 return Mtype_TransferSize(MTYPE_I4, t);
00723 }
00724
00725
00726
00727 void
00728 WFE_Set_ST_Addr_Saved (WN *wn)
00729 {
00730 OPERATOR Operator;
00731 ST *st;
00732
00733 Operator = WN_operator (wn);
00734
00735 switch ( Operator ) {
00736
00737 case OPR_LDA:
00738 case OPR_LDMA:
00739
00740 st = WN_st (wn);
00741
00742 if (ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_FUNC)
00743 Set_ST_addr_saved (st);
00744 break;
00745
00746 case OPR_ARRAY:
00747
00748 WFE_Set_ST_Addr_Saved (WN_kid0 (wn));
00749 break;
00750
00751 case OPR_LDID:
00752
00753 st = WN_st (wn);
00754 if (ST_pt_to_unique_mem (st))
00755 Clear_ST_pt_to_unique_mem (st);
00756 break;
00757
00758 case OPR_CONST:
00759 case OPR_ILOAD:
00760 case OPR_MLOAD:
00761 case OPR_INTCONST:
00762 case OPR_INTRINSIC_OP:
00763 case OPR_CALL:
00764 case OPR_EQ:
00765 case OPR_NE:
00766 case OPR_GT:
00767 case OPR_GE:
00768 case OPR_LT:
00769 case OPR_LE:
00770 case OPR_ALLOCA:
00771 break;
00772
00773 case OPR_EVAL:
00774 case OPR_TAS:
00775 case OPR_CVT:
00776 case OPR_CVTL:
00777 case OPR_NEG:
00778 case OPR_ABS:
00779 case OPR_SQRT:
00780 case OPR_REALPART:
00781 case OPR_IMAGPART:
00782 case OPR_PAREN:
00783 case OPR_RND:
00784 case OPR_TRUNC:
00785 case OPR_CEIL:
00786 case OPR_FLOOR:
00787 case OPR_BNOT:
00788 case OPR_LNOT:
00789 case OPR_LOWPART:
00790 case OPR_HIGHPART:
00791 case OPR_MINPART:
00792 case OPR_MAXPART:
00793 case OPR_RECIP:
00794 case OPR_RSQRT:
00795 case OPR_PARM:
00796 case OPR_EXTRACT_BITS:
00797
00798 WFE_Set_ST_Addr_Saved (WN_kid0(wn));
00799 break;
00800
00801 case OPR_CSELECT:
00802
00803 WFE_Set_ST_Addr_Saved (WN_kid1(wn));
00804 WFE_Set_ST_Addr_Saved (WN_kid2(wn));
00805 break;
00806
00807 case OPR_SELECT:
00808 case OPR_ADD:
00809 case OPR_SUB:
00810 case OPR_MPY:
00811 case OPR_DIV:
00812 case OPR_MOD:
00813 case OPR_REM:
00814 case OPR_DIVREM:
00815 case OPR_MAX:
00816 case OPR_MIN:
00817 case OPR_MINMAX:
00818 case OPR_BAND:
00819 case OPR_BIOR:
00820 case OPR_BXOR:
00821 case OPR_BNOR:
00822 case OPR_LAND:
00823 case OPR_LIOR:
00824 case OPR_SHL:
00825 case OPR_ASHR:
00826 case OPR_LSHR:
00827 case OPR_COMPLEX:
00828 case OPR_HIGHMPY:
00829 case OPR_RROTATE:
00830 case OPR_COMPOSE_BITS:
00831
00832 WFE_Set_ST_Addr_Saved (WN_kid0(wn));
00833 WFE_Set_ST_Addr_Saved (WN_kid1(wn));
00834 break;
00835
00836 case OPR_CAND:
00837 case OPR_CIOR:
00838
00839 break;
00840
00841 case OPR_COMMA:
00842
00843 WFE_Set_ST_Addr_Saved (WN_kid1(wn));
00844 break;
00845
00846 case OPR_RCOMMA:
00847
00848 WFE_Set_ST_Addr_Saved (WN_kid0(wn));
00849 break;
00850
00851 default:
00852
00853 DevWarn ("WFE_Set_ST_Addr_Saved not implemented");
00854 }
00855 }
00856
00857 #ifndef GPLUSPLUS_FE
00858 typedef struct wfe_bind_expr_t {
00859 tree rtl_expr;
00860 WN *block;
00861 } WFE_BIND_EXPR;
00862
00863 WFE_BIND_EXPR *wfe_bind_expr_stack = NULL;
00864 INT32 wfe_bind_expr_stack_last = -1;
00865 INT32 wfe_bind_expr_stack_max = 0;
00866
00867 void
00868 WFE_Expand_Start_Stmt_Expr (tree t)
00869 {
00870 WN *block = WN_CreateBlock ();
00871 WFE_Stmt_Push (block, wfe_stmk_comma, Get_Srcpos ());
00872 }
00873
00874 void
00875 WFE_Expand_End_Stmt_Expr (tree t)
00876 {
00877 WN *block = WFE_Stmt_Pop (wfe_stmk_comma);
00878 ++wfe_bind_expr_stack_last;
00879 if (wfe_bind_expr_stack_last == wfe_bind_expr_stack_max) {
00880 if (wfe_bind_expr_stack == NULL) {
00881 wfe_bind_expr_stack_max = 32;
00882 wfe_bind_expr_stack =
00883 (WFE_BIND_EXPR *) malloc (wfe_bind_expr_stack_max *
00884 sizeof (WFE_BIND_EXPR));
00885 }
00886 else {
00887 wfe_bind_expr_stack_max = wfe_bind_expr_stack_max +
00888 (wfe_bind_expr_stack_max >> 1);
00889 wfe_bind_expr_stack =
00890 (WFE_BIND_EXPR *) realloc (wfe_bind_expr_stack,
00891 wfe_bind_expr_stack_max *
00892 sizeof (WFE_BIND_EXPR));
00893 }
00894 }
00895 wfe_bind_expr_stack [wfe_bind_expr_stack_last].rtl_expr = t;
00896 wfe_bind_expr_stack [wfe_bind_expr_stack_last].block = block;
00897 }
00898 #endif
00899
00900 typedef struct wfe_save_expr_t {
00901 tree exp;
00902 ST *st;
00903 #ifdef KEY
00904 INT32 level;
00905 #endif
00906 } WFE_SAVE_EXPR;
00907
00908 WFE_SAVE_EXPR *wfe_save_expr_stack = NULL;
00909 INT32 wfe_save_expr_stack_last = -1;
00910 INT32 wfe_save_expr_stack_max = 0;
00911
00912 #ifdef KEY
00913 INT32 wfe_save_expr_level;
00914 INT32 wfe_last_save_expr_level;
00915 #endif
00916
00917 static WN*
00918 WFE_Save_Expr (tree save_exp,
00919 bool need_result,
00920 TY_IDX nop_ty_idx,
00921 TY_IDX component_ty_idx,
00922 INT64 component_offset,
00923 UINT16 field_id)
00924 {
00925 INT32 i;
00926 tree exp = TREE_OPERAND (save_exp, 0);
00927 TY_IDX ty_idx = Get_TY (TREE_TYPE (exp));
00928 TYPE_ID mtype = TY_mtype (ty_idx);
00929 ST *st;
00930 WN *wn;
00931 bool found = false;
00932
00933 for (i = wfe_save_expr_stack_last; i >= 0; i--) {
00934 #ifndef KEY
00935 if (wfe_save_expr_stack [i].exp == exp) {
00936 #else
00937 if (wfe_save_expr_stack [i].exp == save_exp &&
00938 wfe_save_expr_stack [i].level == wfe_save_expr_level) {
00939 #endif
00940 st = wfe_save_expr_stack [i].st;
00941 FmtAssert (st != 0,
00942 ("WFE_Save_Expr: st not yet assigned"));
00943 found = true;
00944 break;
00945 }
00946 }
00947
00948 if (!found) {
00949 i = ++wfe_save_expr_stack_last;
00950 if (i == wfe_save_expr_stack_max) {
00951 if (wfe_save_expr_stack == NULL) {
00952 wfe_save_expr_stack_max = 32;
00953 wfe_save_expr_stack =
00954 (WFE_SAVE_EXPR *) malloc (wfe_save_expr_stack_max *
00955 sizeof (WFE_SAVE_EXPR));
00956 }
00957 else {
00958 wfe_save_expr_stack_max = wfe_save_expr_stack_max +
00959 (wfe_save_expr_stack_max >> 1);
00960 wfe_save_expr_stack =
00961 (WFE_SAVE_EXPR *) realloc (wfe_save_expr_stack,
00962 wfe_save_expr_stack_max *
00963 sizeof (WFE_SAVE_EXPR));
00964 }
00965 }
00966 #ifndef KEY
00967 wfe_save_expr_stack [i].exp = exp;
00968 #else
00969 wfe_save_expr_stack [i].exp = save_exp;
00970 wfe_save_expr_stack [i].level = wfe_save_expr_level;
00971 #endif
00972 wfe_save_expr_stack [i].st = 0;
00973 #ifdef KEY
00974
00975
00976
00977 if (WFE_Call_Returns_Ptr_To_Member_Func(exp)) {
00978 TYPE_ID desc = TY_mtype(Get_TY(TREE_TYPE(exp)));
00979 wn = WFE_Expand_Ptr_To_Member_Func_Call_Expr(exp, nop_ty_idx,
00980 Widen_Mtype(desc), desc);
00981 } else
00982 #endif
00983 wn = WFE_Expand_Expr (exp);
00984
00985 st = Gen_Temp_Symbol (ty_idx, "__save_expr");
00986 #ifdef KEY
00987 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
00988 #endif
00989 WFE_Set_ST_Addr_Saved (wn);
00990 wn = WN_Stid (mtype, 0, st, ty_idx, wn);
00991 WFE_Stmt_Append (wn, Get_Srcpos());
00992 wfe_save_expr_stack [i].st = st;
00993 }
00994
00995 if (component_ty_idx == 0)
00996 wn = WN_Ldid (mtype, 0, st, ty_idx);
00997 else {
00998 TYPE_ID desc = TY_mtype(component_ty_idx);
00999 TYPE_ID rtype = Widen_Mtype(desc);
01000 wn = WN_CreateLdid(OPR_LDID, rtype, desc, component_offset, st,
01001 field_id? ty_idx : component_ty_idx, field_id);
01002 }
01003 return wn;
01004 }
01005
01006
01007
01008
01009
01010 static WN *
01011 WFE_Array_Expr(tree exp,
01012 TY_IDX *ty_idx,
01013 TY_IDX component_ty_idx,
01014 INT64 component_offset,
01015 UINT32 field_id)
01016 {
01017 WN *wn;
01018 enum tree_code code = TREE_CODE (exp);
01019 if (code == COMPONENT_REF) {
01020 TY_IDX ty_idx0;
01021 tree arg0 = TREE_OPERAND(exp, 0);
01022 tree arg1 = TREE_OPERAND(exp, 1);
01023 if (component_ty_idx == 0)
01024 ty_idx0 = Get_TY(TREE_TYPE(exp));
01025 else ty_idx0 = component_ty_idx;
01026 #ifdef KEY // bug 10728
01027 if (TREE_THIS_VOLATILE(exp))
01028 Set_TY_is_volatile(ty_idx0);
01029 #endif
01030 Is_True(! DECL_BIT_FIELD(arg1),
01031 ("WFE_Array_Expr: address arithmetic cannot use bitfield addresses"));
01032 INT64 ofst = (BITSPERBYTE * Get_Integer_Value(DECL_FIELD_OFFSET(arg1)) +
01033 Get_Integer_Value(DECL_FIELD_BIT_OFFSET(arg1)))
01034 / BITSPERBYTE;
01035 #ifdef KEY
01036
01037
01038
01039
01040
01041
01042
01043 if (TREE_CODE(arg0) == MODIFY_EXPR) {
01044 WFE_Expand_Expr(arg0);
01045 tree lhs = TREE_OPERAND(arg0, 0);
01046 Is_True (lhs != NULL &&
01047 (TREE_CODE(lhs) == VAR_DECL || TREE_CODE(lhs) == INDIRECT_REF),
01048 ("Unsupported lhs for `(p=q).x[n]'"));
01049 arg0 = lhs;
01050 }
01051 #endif
01052
01053 #ifdef KEY // bug 9725: If the field is an array of struct, it is considered
01054
01055 return WFE_Array_Expr(arg0, ty_idx, ty_idx0, ofst + component_offset,
01056 DECL_FIELD_ID(arg1));
01057 #else
01058 return WFE_Array_Expr(arg0, ty_idx, ty_idx0, ofst + component_offset,
01059 field_id + DECL_FIELD_ID(arg1));
01060 #endif
01061 }
01062 else if (code == VAR_DECL || code == PARM_DECL) {
01063 ST *st = Get_ST (exp);
01064 ST *base_st = ST_base (st);
01065
01066
01067 if (st != base_st) {
01068 FmtAssert (component_ty_idx == 0,
01069 ("Variable Length Arrays within struct not currently implemented"));
01070 wn = WN_Ldid (Pointer_Mtype, 0, base_st, ST_type (base_st));
01071 }
01072 else
01073 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01074 if (component_ty_idx == 0)
01075 *ty_idx = ST_type(st);
01076 else {
01077 *ty_idx = component_ty_idx;
01078 if (TY_align(ST_type(st)) < TY_align(component_ty_idx))
01079 Set_TY_align(*ty_idx, TY_align(ST_type(st)));
01080 }
01081 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01082 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01083 return wn;
01084 }
01085 else if (code == CONSTRUCTOR) {
01086 ST *st = WFE_Generate_Temp_For_Initialized_Aggregate (exp, "");
01087 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01088 if (component_ty_idx == 0)
01089 *ty_idx = ST_type(st);
01090 else *ty_idx = component_ty_idx;
01091 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01092 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01093 return wn;
01094 }
01095 else if (code == STRING_CST) {
01096 wn = WFE_Expand_Expr(exp);
01097 *ty_idx = ST_type (TREE_STRING_ST (exp));
01098 return wn;
01099 }
01100 else if (code == INDIRECT_REF) {
01101 wn = WFE_Expand_Expr(TREE_OPERAND (exp, 0));
01102 if (component_ty_idx == 0)
01103 *ty_idx = Get_TY (TREE_TYPE(exp));
01104 else {
01105 *ty_idx = component_ty_idx;
01106 INT node_align = TYPE_ALIGN(TREE_TYPE(exp)) / BITSPERBYTE;
01107 if (node_align < TY_align(component_ty_idx))
01108 Set_TY_align(*ty_idx, node_align);
01109 }
01110 if (component_offset != 0) {
01111 WN *wn0 = WN_Intconst(MTYPE_I4, component_offset);
01112 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn, wn0);
01113 }
01114 return wn;
01115 }
01116 else if (code == CALL_EXPR) {
01117 wn = WFE_Expand_Expr(exp);
01118 FmtAssert (WN_opcode (wn) == OPC_MCOMMA,
01119 ("opcode other than OPC_MCOMMA for call underneath ARRAY_REF"));
01120 WFE_Stmt_Append (WN_kid0 (wn), Get_Srcpos ());
01121 ST *st = WN_st (WN_kid1 (wn));
01122 WN_Delete (WN_kid1 (wn));
01123 WN_Delete (wn);
01124 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01125 if (component_ty_idx == 0)
01126 *ty_idx = ST_type(st);
01127 else {
01128 *ty_idx = component_ty_idx;
01129 if (TY_align(ST_type(st)) < TY_align(component_ty_idx))
01130 Set_TY_align(*ty_idx, TY_align(ST_type(st)));
01131 }
01132 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01133 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01134 return wn;
01135 }
01136 else if (code == ARRAY_REF) {
01137 WN *wn0, *wn1, *wn2;
01138 TY_IDX ty_idx0;
01139 #ifdef KEY // Bug 5831.
01140 wn0 = WFE_Array_Expr(TREE_OPERAND (exp, 0), &ty_idx0, 0,
01141 component_offset, field_id);
01142 #else
01143 wn0 = WFE_Array_Expr(TREE_OPERAND (exp, 0), &ty_idx0, component_ty_idx,
01144 component_offset, field_id);
01145 #endif
01146 Is_True(TY_kind(ty_idx0) == KIND_ARRAY,
01147 ("WFE_Array_Expr: arg 0 of ARRAY_REF not of type KIND_ARRAY"));
01148 ARB_HANDLE arb = TY_arb(ty_idx0);
01149 if (ARB_dimension(arb) == 1 &&
01150 ARB_first_dimen(arb) && ARB_last_dimen(arb) &&
01151 ARB_const_lbnd(arb)) {
01152 if (ARB_const_ubnd(arb))
01153 wn1 = WN_Intconst(MTYPE_I4, ARB_ubnd_val(arb) - ARB_lbnd_val(arb) + 1);
01154 #ifdef KEY
01155
01156 else if (ARB_ubnd_var(arb)) {
01157 ST *ubnd_st = &St_Table[ARB_ubnd_var(arb)];
01158 wn1 = WN_Binary(OPR_SUB, MTYPE_I4,
01159 WN_Ldid(MTYPE_I4, 0, ubnd_st, ST_type(ubnd_st)),
01160 WN_Intconst(MTYPE_I4, ARB_lbnd_val(arb) - 1));
01161 }
01162 #endif
01163 else
01164 wn1 = WN_Intconst(MTYPE_I4, 0);
01165 wn2 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
01166 #ifdef TARG_X8664 // bug 11705
01167 if (WN_operator(wn2) == OPR_SUB)
01168 WN_set_rtype(wn2, Mtype_TransferSign(MTYPE_I4, WN_rtype(wn2)));
01169 #endif
01170 #ifdef KEY // bug 14871, OSP_455
01171 if (TARGET_64BIT && OPCODE_is_load(WN_opcode(wn2)))
01172 WN_set_rtype(wn2, Mtype_TransferSize(MTYPE_U8, WN_rtype(wn2)));
01173 #endif
01174 #ifdef KEY
01175
01176
01177 if (TREE_CODE(TREE_OPERAND(exp, 0)) == ARRAY_REF) {
01178 Is_True(WN_operator(wn0) == OPR_ARRAY,
01179 ("WFE_Array_Expr: ARRAY_REF not translated to OPR_ARRAY"));
01180 int old_kid_count = WN_kid_count(wn0);
01181 int new_kid_count = old_kid_count + 2;
01182 wn = WN_Create(OPR_ARRAY, Pointer_Mtype, MTYPE_V, new_kid_count);
01183 for (int kid = 0; kid < (old_kid_count >> 1); kid++) {
01184 WN_kid(wn, kid + 1) = WN_kid(wn0, kid + 1);
01185 WN_kid(wn, (new_kid_count >> 1) + kid + 1) =
01186 WN_kid(wn0, (old_kid_count >> 1) + kid + 1);
01187 }
01188 WN_kid(wn, 0) = WN_kid(wn0, 0);
01189 WN_kid(wn, new_kid_count >> 1) = wn1;
01190 WN_kid(wn, new_kid_count - 1) = wn2;
01191 WN_Delete(wn0);
01192 } else
01193 #endif
01194 wn = WN_Ternary(OPR_ARRAY, Pointer_Mtype, wn0, wn1, wn2);
01195
01196 WN_element_size(wn) = TY_size(Get_TY (TREE_TYPE(exp)));
01197 }
01198 else Is_True(FALSE,
01199 ("WFE_Array_Expr: only const-bounds 1-dimension arrays handled now"));
01200 if (component_ty_idx == 0) {
01201 *ty_idx = TY_etype(ty_idx0);
01202 if (TY_align(ty_idx0) < TY_align(*ty_idx))
01203 Set_TY_align(*ty_idx, TY_align(ty_idx0));
01204 #ifdef KEY // bug 10728
01205 if (TREE_THIS_VOLATILE(exp))
01206 Set_TY_is_volatile(*ty_idx);
01207 #endif
01208 }
01209 else *ty_idx = component_ty_idx;
01210 return wn;
01211 }
01212 #ifdef KEY
01213 else if (code == COMPOUND_LITERAL_EXPR) {
01214 tree arg0 = DECL_INITIAL (TREE_OPERAND (TREE_OPERAND (exp, 0), 0));
01215 ST *st = WFE_Generate_Temp_For_Initialized_Aggregate (arg0, "");
01216 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
01217 *ty_idx = component_ty_idx == 0 ? ST_type(st) : component_ty_idx;
01218 return wn;
01219 } else if (code == TARGET_EXPR) {
01220 wn = WFE_Expand_Expr(exp);
01221 Is_True(WN_operator(wn) == OPR_LDID,
01222 ("WFE_Array_Expr: OPR_LDID not found"));
01223 ST *st = WN_st(wn);
01224 wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
01225 if (component_ty_idx == 0)
01226 *ty_idx = ST_type(st);
01227 else {
01228 *ty_idx = component_ty_idx;
01229 if (TY_align(ST_type(st)) < TY_align(component_ty_idx))
01230 Set_TY_align(*ty_idx, TY_align(ST_type(st)));
01231 }
01232 Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
01233 ("WFE_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
01234 return wn;
01235 }
01236 #endif
01237 else {
01238 Is_True(FALSE,
01239 ("WFE_Array_Expr: unsupported node for base of ARRAY_REF"));
01240 return NULL;
01241 }
01242 }
01243
01244
01245
01246
01247
01248 #if defined(TARG_SL)
01249
01250
01251
01252 ST*
01253 WN_Include_Vbuf_Symbol( WN* wn, BOOL need_initialize) {
01254 WN* tmp = wn;
01255 static ST* st = NULL;
01256 if(need_initialize) {
01257 st = NULL;
01258 need_initialize=FALSE;
01259 }
01260 for( INT i = 0; i < WN_kid_count(wn); i++) {
01261 if(WN_operator(WN_kid(wn,i)) != OPR_LDA) {
01262 st = WN_Include_Vbuf_Symbol(WN_kid(wn,i), need_initialize);
01263 }
01264 else {
01265 if(WN_has_sym(WN_kid(wn,i)) && ST_in_vbuf(WN_st(WN_kid(wn,i)))) {
01266 return WN_st(WN_kid(wn,i));
01267 }
01268 }
01269 }
01270 return st;
01271 }
01272
01273
01274
01275 void
01276 WN_Adjust_Vbuf_Ofst(WN* wn, ST* st){
01277 INT shft_num = ST_in_v2buf(st) ? 1 : (ST_in_v4buf(st) ? 2 : 0);
01278
01279 if(WN_operator(wn) == OPR_LDA) {
01280 Is_True(WN_has_sym(wn), ("this symbol don't has base address symbole"));
01281 Is_True(ST_in_vbuf(st), ("this symbol for adjusting offset is not vbuf variable"));
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291 if(!WN_vbuf_ofst_adjusted(wn)) {
01292 WN_lda_offset(wn) = (((WN_lda_offset(wn) / 16) * 16) << shft_num ) \
01293 + (WN_lda_offset(wn) % 16);
01294 WN_Set_vbuf_ofst_adjusted(wn);
01295 }
01296 return;
01297 }
01298 else if(WN_operator(wn) == OPR_INTCONST) {
01299 if(WN_vbuf_ofst_adjusted(wn)) return;
01300 else {
01301 WN_const_val(wn) <<= shft_num;
01302 WN_Set_vbuf_ofst_adjusted(wn);
01303 }
01304 return;
01305 }
01306 else if(WN_kid_count(wn)) {
01307 for( INT i = 0; (i < WN_kid_count(wn) || !WN_kid_count(wn)); i++) {
01308
01309
01310
01311
01312 if(WN_operator(wn) == OPR_STID ||
01313 WN_operator(wn) == OPR_LDID ||
01314 WN_operator(wn) == OPR_ISTORE ||
01315 WN_operator(wn) == OPR_ILOAD)
01316 continue;
01317
01318
01319
01320 else if(WN_operator(wn) == OPR_ARRAY && i == 1) {
01321 continue;
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 else if(WN_operator(wn) == OPR_MPY)
01338 {
01339 continue;
01340 }
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352 else if(WN_operator(wn) == OPR_SHL) {
01353 continue;
01354 }
01355 else {
01356 WN_Adjust_Vbuf_Ofst(WN_kid(wn,i), st);
01357 }
01358 }
01359 return;
01360 }
01361 return;
01362 }
01363
01364
01365 WN*
01366 Shft_Vbuf_Array_Ofst(WN* wn, INT shft_num = 0) {
01367 if(WN_operator(wn) == OPR_INTCONST) {
01368 WN_const_val(wn) <<= shft_num;
01369 }
01370 else if(WN_operator(wn) == OPR_LDA) {
01371 WN_lda_offset(wn) <<= shft_num;
01372 }
01373 return wn;
01374 }
01375
01376 WN*
01377 Adjust_Vbuf_Array_Ofst(WN* wn) {
01378 Is_True((WN_operator(wn) == OPR_STID ||
01379 WN_operator(wn) == OPR_LDID ||
01380 WN_operator(wn) == OPR_ISTORE ||
01381 WN_operator(wn) == OPR_ILOAD ||
01382 WN_operator(wn) == OPR_PARM) ,
01383 ( " invalid operator for adjusting vbuf ofst"));
01384 ST* st = WN_Include_Vbuf_Symbol(wn, TRUE);
01385
01386 if(!st || ! (ST_in_v2buf(st) || ST_in_v4buf(st))) return wn;
01387
01388
01389
01390
01391
01392
01393 for( INT i = 0; i < WN_kid_count(wn); i++) {
01394 WN_Adjust_Vbuf_Ofst(WN_kid(wn,i), st);
01395 }
01396 return wn;
01397 }
01398 #endif
01399 #ifdef TARG_SL
01400
01401
01402
01403
01404 static BOOL sameness;
01405 static BOOL Same_Var( char* var_name, tree rhs )
01406 {
01407 if (!rhs) {
01408 DevWarn("Same_Var::rhs is NULL");
01409 return FALSE;
01410 }
01411
01412
01413
01414 if( TREE_CODE_CLASS(TREE_CODE(rhs)) == 'c' )
01415 return FALSE;
01416
01417
01418
01419
01420
01421 if( TREE_CODE(rhs) == COMPONENT_REF )
01422 return FALSE;
01423
01424 BOOL tempsame = FALSE;
01425
01426
01427
01428
01429 switch( TREE_CODE(rhs) ) {
01430 case VAR_DECL :
01431 if( DECL_NAME(rhs) && !strcmp(var_name,IDENTIFIER_POINTER(DECL_NAME(rhs))))
01432 return TRUE;
01433 else
01434 return FALSE;
01435 case PARM_DECL:
01436 if( DECL_NAME(rhs) && !strcmp(var_name,IDENTIFIER_POINTER(DECL_NAME(rhs))))
01437 return TRUE;
01438 else if( TREE_CHAIN(rhs) )
01439 tempsame |= Same_Var( var_name, TREE_CHAIN(rhs) );
01440 else
01441 return FALSE;
01442 break;
01443 case FUNCTION_DECL:
01444 tempsame |= Same_Var( var_name, DECL_ARGUMENTS(rhs) );
01445 break;
01446 case INDIRECT_REF:
01447
01448
01449
01450 if( TREE_CODE(TREE_OPERAND(rhs,0))==PARM_DECL ||
01451 TREE_CODE(TREE_OPERAND(rhs,0))==VAR_DECL ) {
01452 tempsame |= Same_Var( var_name, TREE_OPERAND(rhs,0) );
01453 } else
01454 return FALSE;
01455 default:
01456 if( TREE_OPERAND(rhs,0) )
01457 tempsame |= Same_Var( var_name, TREE_OPERAND(rhs,0) );
01458 if( TREE_OPERAND(rhs,1) )
01459 tempsame |= Same_Var( var_name, TREE_OPERAND(rhs,1) );
01460 break;
01461 }
01462
01463
01464
01465
01466 return tempsame;
01467 }
01468 #endif
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485 WN *
01486 WFE_Lhs_Of_Modify_Expr(tree_code assign_code,
01487 tree lhs,
01488 #ifdef TARG_SL
01489
01490
01491
01492 tree rhs,
01493 #endif
01494 bool need_result,
01495 TY_IDX component_ty_idx,
01496 INT64 component_offset,
01497 UINT32 field_id,
01498 bool is_bit_field,
01499 WN *rhs_wn,
01500 PREG_NUM rhs_preg_num,
01501 bool is_realpart,
01502 bool is_imagpart)
01503 {
01504 WN *wn = NULL;
01505 ST *st;
01506 bool result_in_temp = FALSE;
01507 ST *result_preg_st;
01508 PREG_NUM result_preg;
01509 PREG_NUM lhs_preg_num = 0;
01510 enum tree_code code = TREE_CODE (lhs);
01511 BOOL volt = FALSE;
01512 #ifdef TARG_SL
01513 BOOL need_append = FALSE;
01514 #endif
01515 if (rhs_wn != NULL) {
01516 WFE_Set_ST_Addr_Saved (rhs_wn);
01517 #ifdef TARG_SL
01518 need_append = WN_Need_Append_Intrinsic(rhs_wn);
01519 #endif
01520 }
01521
01522 switch (code) {
01523 case COMPONENT_REF:
01524 {
01525 INT64 ofst;
01526 TY_IDX ty_idx0;
01527
01528 tree arg0 = TREE_OPERAND(lhs, 0);
01529 tree arg1 = TREE_OPERAND(lhs, 1);
01530 #ifdef GPLUSPLUS_FE
01531
01532
01533 (void) Get_TY (TREE_TYPE (arg0));
01534 #endif
01535 if (component_ty_idx == 0)
01536 ty_idx0 = Get_TY(TREE_TYPE(lhs));
01537 else ty_idx0 = component_ty_idx;
01538 if (DECL_BIT_FIELD(arg1))
01539 is_bit_field = TRUE;
01540 if (! is_bit_field)
01541 ofst = (BITSPERBYTE * Get_Integer_Value(DECL_FIELD_OFFSET(arg1)) +
01542 Get_Integer_Value(DECL_FIELD_BIT_OFFSET(arg1)))
01543 / BITSPERBYTE;
01544 else ofst = 0;
01545 #ifdef KEY // bug 10422: check if the field is volatile
01546 if (TREE_THIS_VOLATILE(arg1)) {
01547 Set_TY_is_volatile(ty_idx0);
01548 volt = TRUE;
01549 }
01550 #endif
01551 #ifdef KEY
01552 FmtAssert (DECL_FIELD_ID(arg1) != 0,
01553 ("WFE_Lhs_Of_Modify_Expr: DECL_FIELD_ID used but not set"));
01554 #endif
01555 #ifdef TARG_SL
01556 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, ty_idx0,
01557 #else
01558 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, need_result, ty_idx0,
01559 #endif
01560 ofst+component_offset,
01561 field_id + DECL_FIELD_ID(arg1), is_bit_field,
01562 rhs_wn, rhs_preg_num, is_realpart,
01563 is_imagpart);
01564 }
01565 return wn;
01566
01567 case REALPART_EXPR:
01568 {
01569 tree arg0 = TREE_OPERAND(lhs, 0);
01570 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(arg0));
01571 #ifdef TARG_SL
01572 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, ty_idx0,
01573 #else
01574 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, need_result, ty_idx0,
01575 #endif
01576 component_offset, field_id, is_bit_field,
01577 rhs_wn, rhs_preg_num, TRUE, FALSE);
01578 }
01579 return wn;
01580
01581 case IMAGPART_EXPR:
01582 {
01583 tree arg0 = TREE_OPERAND(lhs, 0);
01584 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(arg0));
01585 #ifdef TARG_SL
01586 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, ty_idx0,
01587 #else
01588 wn = WFE_Lhs_Of_Modify_Expr(assign_code, arg0, need_result, ty_idx0,
01589 #endif
01590 component_offset, field_id, is_bit_field,
01591 rhs_wn, rhs_preg_num, FALSE, TRUE);
01592 }
01593 return wn;
01594
01595 #ifdef KEY
01596 case TARGET_EXPR:
01597 {
01598 WN *wn = WFE_Expand_Expr(lhs);
01599 Is_True(WN_operator(wn) == OPR_LDID,
01600 ("WFE_Lhs_Of_Modify_Expr: wrong operator from TARGET_EXPR"));
01601 st = WN_st(wn);
01602 }
01603
01604 #endif
01605
01606 case PARM_DECL:
01607 case VAR_DECL:
01608 case RESULT_DECL:
01609 {
01610 TY_IDX hi_ty_idx = Get_TY(TREE_TYPE(lhs));
01611 if (TREE_THIS_VOLATILE(lhs)) {
01612 Set_TY_is_volatile(hi_ty_idx);
01613 volt = TRUE;
01614 }
01615 TY_IDX desc_ty_idx = component_ty_idx;
01616 if (desc_ty_idx == 0)
01617 desc_ty_idx = hi_ty_idx;
01618 if (TY_is_volatile(desc_ty_idx)) {
01619 Clear_TY_is_volatile(desc_ty_idx);
01620 volt = TRUE;
01621 }
01622
01623 #ifdef KEY
01624 if (code != TARGET_EXPR)
01625 #endif
01626 st = Get_ST (lhs);
01627
01628 if (ST_assigned_to_dedicated_preg (st)) {
01629 Set_TY_is_volatile(hi_ty_idx);
01630 volt = TRUE;
01631 }
01632 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
01633 ("WFE_Lhs_Of_Modify_Expr: field id for bit-field exceeds limit"));
01634
01635 TYPE_ID rtype = Widen_Mtype(TY_mtype(desc_ty_idx));
01636 TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
01637
01638 if (rhs_wn == NULL) {
01639
01640
01641
01642
01643
01644 if (rtype == MTYPE_M && desc == MTYPE_M) {
01645 #ifndef KEY
01646 FmtAssert(TY_size(desc_ty_idx) == MTYPE_byte_size(Def_Int_Mtype),
01647 ("Size of ASM struct opnd must be equal to register size"));
01648 desc = rtype = Def_Int_Mtype;
01649 desc_ty_idx = hi_ty_idx = MTYPE_To_TY(Def_Int_Mtype);
01650 #else
01651
01652
01653
01654 if (rtype == MTYPE_M && desc == MTYPE_M) {
01655 if (TY_size(desc_ty_idx) == MTYPE_byte_size(Def_Int_Mtype)) {
01656 desc = rtype = Def_Int_Mtype;
01657 desc_ty_idx = hi_ty_idx = MTYPE_To_TY(Def_Int_Mtype);
01658 } else {
01659 desc = rtype = MTYPE_I4;
01660 desc_ty_idx = hi_ty_idx = MTYPE_To_TY(MTYPE_I4);
01661 }
01662 }
01663 #endif
01664 }
01665 ST *rhs_st = MTYPE_To_PREG(desc);
01666 rhs_wn = WN_CreateLdid (OPR_LDID, rtype,
01667 desc, rhs_preg_num, rhs_st,
01668 desc_ty_idx, 0);
01669 }
01670 else {
01671 WN *result_wn;
01672 if (assign_code == MODIFY_EXPR) {
01673 if (is_realpart)
01674 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01675 rhs_wn,
01676 WN_Unary(OPR_IMAGPART,
01677 Mtype_complex_to_real (rtype),
01678 WN_CreateLdid(OPR_LDID, rtype, desc,
01679 ST_ofst(st) + component_offset,
01680 st, hi_ty_idx, field_id)));
01681 else
01682 if (is_imagpart)
01683 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01684 WN_Unary(OPR_REALPART,
01685 Mtype_complex_to_real (rtype),
01686 WN_CreateLdid(OPR_LDID, rtype, desc,
01687 ST_ofst(st) + component_offset,
01688 st, hi_ty_idx, field_id)),
01689 rhs_wn);
01690 }
01691 else {
01692 if (is_realpart)
01693 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01694 rhs_wn,
01695 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0));
01696 else
01697 if (is_imagpart)
01698 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01699 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0),
01700 rhs_wn);
01701 }
01702
01703 if (assign_code == PREINCREMENT_EXPR ||
01704 assign_code == PREDECREMENT_EXPR) {
01705 wn = WN_CreateLdid (OPR_LDID, rtype, desc,
01706 ST_ofst(st) + component_offset,
01707 st, hi_ty_idx, field_id);
01708 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01709 rtype, wn, rhs_wn);
01710 result_wn = rhs_wn;
01711 }
01712 else if (assign_code == POSTINCREMENT_EXPR ||
01713 assign_code == POSTDECREMENT_EXPR) {
01714 result_wn = WN_CreateLdid (OPR_LDID, rtype, desc,
01715 ST_ofst(st) + component_offset,
01716 st, hi_ty_idx, field_id);
01717 }
01718 else result_wn = rhs_wn;
01719
01720
01721 if (need_result && rtype != MTYPE_M &&
01722 (volt ||
01723 assign_code == POSTINCREMENT_EXPR ||
01724 assign_code == POSTDECREMENT_EXPR)) {
01725 result_in_temp = TRUE;
01726 result_preg_st = MTYPE_To_PREG(rtype);
01727 result_preg = Create_Preg(rtype, NULL);
01728 wn = WN_Stid(rtype, result_preg, result_preg_st, desc_ty_idx,
01729 result_wn, 0);
01730 WFE_Stmt_Append (wn, Get_Srcpos());
01731 result_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx,
01732 0);
01733 }
01734
01735 if (assign_code == POSTINCREMENT_EXPR ||
01736 assign_code == POSTDECREMENT_EXPR) {
01737 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01738 rtype, result_wn, rhs_wn);
01739 }
01740 else rhs_wn = result_wn;
01741
01742
01743 }
01744
01745
01746 if (!WFE_Keep_Zero_Length_Structs &&
01747 desc == MTYPE_M &&
01748 TY_size (hi_ty_idx) == 0) {
01749
01750 }
01751 else {
01752 #ifdef KEY // bug 10422: check if the field is volatile
01753 if (volt)
01754 Set_TY_is_volatile(hi_ty_idx);
01755 #endif
01756 wn = WN_Stid (desc, ST_ofst(st) + component_offset + lhs_preg_num, st,
01757 hi_ty_idx, rhs_wn, field_id);
01758 #if defined(TARG_SL)
01759 wn = Adjust_Vbuf_Array_Ofst(wn);
01760 #endif
01761 WFE_Stmt_Append(wn, Get_Srcpos());
01762 #if defined(TARG_SL)
01763 if (need_append) {
01764 WN *ldid_wn;
01765 if (! result_in_temp)
01766 ldid_wn = WN_CreateLdid(OPR_LDID, rtype, desc,
01767 ST_ofst(st) + component_offset, st, hi_ty_idx,
01768 field_id);
01769
01770 else
01771 ldid_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
01772
01773 WFE_Stmt_Append_Extend_Intrinsic(wn, ldid_wn, Get_Srcpos());
01774 }
01775 #endif
01776 }
01777 if (need_result) {
01778 if (! result_in_temp)
01779 wn = WN_CreateLdid(OPR_LDID, rtype, desc,
01780 ST_ofst(st) + component_offset, st, hi_ty_idx,
01781 field_id);
01782 else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
01783 if (is_realpart)
01784 wn = WN_Unary (OPR_REALPART, Mtype_complex_to_real (rtype), wn);
01785 else
01786 if (is_imagpart)
01787 wn = WN_Unary (OPR_IMAGPART, Mtype_complex_to_real (rtype), wn);
01788 }
01789 else wn = NULL;
01790 }
01791 break;
01792
01793 case INDIRECT_REF:
01794 {
01795 TY_IDX hi_ty_idx = Get_TY(TREE_TYPE(lhs));
01796 if (TREE_THIS_VOLATILE(lhs)) {
01797 Set_TY_is_volatile(hi_ty_idx);
01798 volt = TRUE;
01799 }
01800 tree op = TREE_OPERAND(lhs, 0);
01801 WN *addr_wn = WFE_Expand_Expr (TREE_OPERAND (lhs, 0));
01802 TY_IDX desc_ty_idx = component_ty_idx;
01803 if (desc_ty_idx == 0)
01804 desc_ty_idx = hi_ty_idx;
01805 if (TY_is_volatile(desc_ty_idx)) {
01806 Clear_TY_is_volatile(desc_ty_idx);
01807 volt = TRUE;
01808 }
01809 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
01810 ("WFE_Lhs_Of_Modify_Expr: field id for bit-field exceeds limit"));
01811 if (WN_has_side_effects(addr_wn) &&
01812 (need_result ||
01813 assign_code == PREINCREMENT_EXPR ||
01814 assign_code == PREDECREMENT_EXPR ||
01815 assign_code == POSTINCREMENT_EXPR ||
01816 assign_code == POSTDECREMENT_EXPR)) {
01817 ST *preg_st;
01818 PREG_NUM preg;
01819 TY_IDX address_ty_idx = Get_TY (TREE_TYPE (TREE_OPERAND (lhs, 0)));
01820 #ifdef KEY
01821
01822 if (TY_is_volatile(address_ty_idx)) {
01823 Clear_TY_is_volatile(address_ty_idx);
01824 volt = TRUE;
01825 }
01826 #endif
01827 preg_st = MTYPE_To_PREG(Pointer_Mtype);
01828 preg = Create_Preg (Pointer_Mtype, NULL);
01829 wn = WN_Stid (Pointer_Mtype, preg, preg_st, address_ty_idx, addr_wn);
01830 WFE_Set_ST_Addr_Saved (addr_wn);
01831 WFE_Stmt_Append (wn, Get_Srcpos());
01832 addr_wn = WN_Ldid (Pointer_Mtype, preg, preg_st, address_ty_idx);
01833 }
01834
01835 TYPE_ID rtype = Widen_Mtype(TY_mtype(desc_ty_idx));
01836 TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
01837
01838 if (rhs_wn == NULL) {
01839
01840
01841
01842 ST *rhs_st;
01843
01844
01845 rhs_st = MTYPE_To_PREG(desc);
01846
01847 rhs_wn = WN_CreateLdid (OPR_LDID, rtype, desc, rhs_preg_num, rhs_st,
01848 desc_ty_idx, 0);
01849 #ifdef KEY
01850
01851
01852 if (MTYPE_byte_size(desc) < 4) {
01853
01854 rhs_wn = WN_CreateCvtl(!MTYPE_signed(desc) ? OPC_U4CVTL : OPC_I4CVTL,
01855 MTYPE_bit_size(desc),
01856 rhs_wn);
01857
01858 }
01859 #endif
01860 }
01861 else {
01862 WN *result_wn;
01863
01864 if (assign_code == MODIFY_EXPR) {
01865 if (is_realpart)
01866 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01867 rhs_wn,
01868 WN_Unary(OPR_IMAGPART,
01869 Mtype_complex_to_real (rtype),
01870 WN_CreateIload(OPR_ILOAD, rtype, desc,
01871 component_offset,
01872 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01873 Make_Pointer_Type(hi_ty_idx, FALSE),
01874 WN_COPY_Tree (addr_wn),
01875 field_id)));
01876 else
01877 if (is_imagpart)
01878 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01879 WN_Unary(OPR_REALPART,
01880 Mtype_complex_to_real (rtype),
01881 WN_CreateIload(OPR_ILOAD, rtype, desc,
01882 component_offset,
01883 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01884 Make_Pointer_Type(hi_ty_idx, FALSE),
01885 WN_COPY_Tree (addr_wn),
01886 field_id)),
01887 rhs_wn);
01888 }
01889 else {
01890 if (is_realpart)
01891 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01892 rhs_wn,
01893 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0));
01894 else
01895 if (is_imagpart)
01896 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
01897 WN_Floatconst(Mtype_complex_to_real(rtype), 0.0),
01898 rhs_wn);
01899 }
01900
01901 if (assign_code == PREINCREMENT_EXPR ||
01902 assign_code == PREDECREMENT_EXPR) {
01903 wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
01904 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01905 Make_Pointer_Type(hi_ty_idx, FALSE),
01906 WN_COPY_Tree (addr_wn),
01907 field_id);
01908 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01909 rtype, wn, rhs_wn);
01910 result_wn = rhs_wn;
01911 }
01912 else if (assign_code == POSTINCREMENT_EXPR ||
01913 assign_code == POSTDECREMENT_EXPR) {
01914 result_wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
01915 field_id != 0 ? hi_ty_idx : desc_ty_idx,
01916 Make_Pointer_Type(hi_ty_idx, FALSE),
01917 WN_COPY_Tree (addr_wn),
01918 field_id);
01919 }
01920 else result_wn = rhs_wn;
01921
01922
01923 if (need_result && rtype != MTYPE_M &&
01924 (volt ||
01925 assign_code == POSTINCREMENT_EXPR ||
01926 assign_code == POSTDECREMENT_EXPR)) {
01927 result_in_temp = TRUE;
01928 result_preg_st = MTYPE_To_PREG(rtype);
01929 result_preg = Create_Preg(rtype, NULL);
01930 wn = WN_Stid(rtype, result_preg, result_preg_st, desc_ty_idx,
01931 result_wn, 0);
01932 WFE_Stmt_Append (wn, Get_Srcpos());;
01933 result_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx,
01934 0);
01935 }
01936
01937 if (assign_code == POSTINCREMENT_EXPR ||
01938 assign_code == POSTDECREMENT_EXPR) {
01939 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
01940 rtype, result_wn, rhs_wn);
01941 }
01942 else rhs_wn = result_wn;
01943
01944
01945 }
01946
01947
01948 if (!WFE_Keep_Zero_Length_Structs &&
01949 desc == MTYPE_M &&
01950 TY_size (hi_ty_idx) == 0) {
01951
01952 if (WN_has_side_effects (addr_wn)) {
01953 wn = WN_CreateEval (addr_wn);
01954 WFE_Stmt_Append (wn, Get_Srcpos());
01955 }
01956 wn = NULL;
01957 }
01958 else {
01959 #ifdef KEY
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974 tree addr = TREE_OPERAND(lhs, 0);
01975 WN *first_formal = WN_formal(Current_Entry_WN(), 0);
01976 if (TY_return_in_mem(hi_ty_idx) &&
01977 field_id == 0 &&
01978
01979
01980
01981 first_formal != NULL && WN_operator(first_formal) != OPR_BLOCK &&
01982 TREE_CODE(addr) == VAR_DECL &&
01983 DECL_ST(addr) == WN_st(first_formal)) {
01984 FmtAssert(TY_mtype(hi_ty_idx) == MTYPE_M,
01985 ("WFE_Lhs_Of_Modify_Expr: return_in_mem type not MTYPE_M"));
01986 tree ptr_type = TREE_TYPE(TREE_OPERAND(lhs, 0));
01987 tree type = TREE_TYPE(ptr_type);
01988 FmtAssert(TREE_CODE(ptr_type) == POINTER_TYPE,
01989 ("WFE_Lhs_Of_Modify_Expr: INDIRECT_REF opnd0 is not POINTER_TYPE"));
01990 FmtAssert(component_offset == 0,
01991 ("WFE_Lhs_Of_Modify_Expr: component_offset nonzero"));
01992 TY_IDX tidx = Get_TY(ptr_type);
01993
01994 FmtAssert(!WFE_has_copy_constructor(type),
01995 ("WFE_Lhs_Of_Modify_Expr: object needs copy constructor"));
01996 }
01997 #endif
01998 wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset,
01999 Make_Pointer_Type (hi_ty_idx, FALSE),
02000 rhs_wn, addr_wn, field_id);
02001 #ifdef TARG_SL
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013 tree post_inc_dec = TREE_OPERAND(lhs, 0);
02014 tree var_node = TREE_OPERAND(post_inc_dec, 0);
02015 if( TREE_CODE(post_inc_dec) == POSTINCREMENT_EXPR ||
02016 TREE_CODE(post_inc_dec) == POSTDECREMENT_EXPR ){
02017
02018
02019
02020
02021 Is_True( var_node && ( TREE_CODE(var_node)==VAR_DECL
02022 || TREE_CODE(var_node)==PARM_DECL
02023 || TREE_CODE(var_node)==COMPONENT_REF
02024 || TREE_CODE(var_node)==INDIRECT_REF ),
02025 ("Post{Inc|Dec} should be on variables or parameters, or component of struct"));
02026
02027
02028
02029
02030
02031 if( TREE_CODE(var_node) == INDIRECT_REF ) {
02032 if( TREE_CODE(var_node) != PARM_DECL &&
02033 TREE_CODE(var_node) != VAR_DECL ) {
02034 DevWarn(" When handling *p++ consistent with gcc, there is *p++, p is a pointer to non-var-decl, non-parm-decl, NOT HANDLED yet!" );
02035 } else
02036 var_node = TREE_OPERAND(var_node, 0);
02037 }
02038
02039 sameness = FALSE;
02040
02041
02042
02043
02044 if( DECL_NAME(var_node) &&
02045 IDENTIFIER_POINTER(DECL_NAME(var_node)) )
02046 sameness |= Same_Var( IDENTIFIER_POINTER(DECL_NAME(var_node)), rhs );
02047 if( sameness ) {
02048 DevWarn("ANSI C undefined behavior: *p++=...,p,.. or *p--=...,p,...");
02049 WFE_Stmt_Prepend_Last(wn, Get_Srcpos());
02050 }
02051 else
02052 WFE_Stmt_Append(wn, Get_Srcpos());
02053 } else
02054 WFE_Stmt_Append(wn, Get_Srcpos());
02055 #else
02056 WFE_Stmt_Append(wn, Get_Srcpos());
02057 #endif
02058 #if defined(TARG_SL)
02059 if (need_append) {
02060 WN *ldid_wn;
02061 if (! result_in_temp)
02062 ldid_wn = WN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
02063 field_id != 0 ? hi_ty_idx : desc_ty_idx,
02064 Make_Pointer_Type (hi_ty_idx, FALSE),
02065 WN_COPY_Tree (addr_wn),
02066 field_id);
02067 else
02068 ldid_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02069
02070 WFE_Stmt_Append_Extend_Intrinsic(wn, ldid_wn, Get_Srcpos());
02071 }
02072 #endif
02073
02074 if (need_result) {
02075 if (! result_in_temp)
02076 wn = WN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
02077 field_id != 0 ? hi_ty_idx : desc_ty_idx,
02078 Make_Pointer_Type (hi_ty_idx, FALSE),
02079 WN_COPY_Tree (addr_wn),
02080 field_id);
02081 else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02082 if (is_realpart)
02083 wn = WN_Unary (OPR_REALPART, Mtype_complex_to_real (rtype), wn);
02084 else
02085 if (is_imagpart)
02086 wn = WN_Unary (OPR_IMAGPART, Mtype_complex_to_real (rtype), wn);
02087 }
02088 else wn = NULL;
02089 }
02090 }
02091 break;
02092
02093 case ARRAY_REF:
02094 {
02095 TY_IDX elem_ty_idx;
02096
02097 WN *addr_wn = WFE_Array_Expr(lhs, &elem_ty_idx, 0, 0, 0);
02098 if (TY_is_volatile(elem_ty_idx))
02099 volt = TRUE;
02100 TY_IDX desc_ty_idx = component_ty_idx;
02101 if (desc_ty_idx == 0)
02102 desc_ty_idx = Get_TY (TREE_TYPE(lhs));
02103 if (TY_is_volatile(desc_ty_idx)) {
02104 Clear_TY_is_volatile(desc_ty_idx);
02105 volt = TRUE;
02106 }
02107 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
02108 ("WFE_Lhs_Of_Modify_Expr: field id for bit-field exceeds limit"));
02109 if (WN_has_side_effects(addr_wn) &&
02110 (need_result ||
02111 assign_code == PREINCREMENT_EXPR ||
02112 assign_code == PREDECREMENT_EXPR ||
02113 assign_code == POSTINCREMENT_EXPR ||
02114 assign_code == POSTDECREMENT_EXPR)) {
02115 ST *preg_st;
02116 PREG_NUM preg;
02117 TY_IDX address_ty_idx = Make_Pointer_Type(elem_ty_idx, FALSE);
02118 preg_st = MTYPE_To_PREG(Pointer_Mtype);
02119 preg = Create_Preg (Pointer_Mtype, NULL);
02120 wn = WN_Stid (Pointer_Mtype, preg, preg_st, address_ty_idx, addr_wn);
02121 WFE_Set_ST_Addr_Saved (addr_wn);
02122 WFE_Stmt_Append (wn, Get_Srcpos());
02123 addr_wn = WN_Ldid (Pointer_Mtype, preg, preg_st, address_ty_idx);
02124 }
02125
02126 TYPE_ID rtype = Widen_Mtype(TY_mtype(desc_ty_idx));
02127 TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
02128
02129 if (rhs_wn == NULL) {
02130
02131
02132
02133 ST *rhs_st;
02134
02135
02136 rhs_st = MTYPE_To_PREG(desc);
02137 rhs_wn = WN_CreateLdid (OPR_LDID, rtype, desc, rhs_preg_num, rhs_st,
02138 desc_ty_idx, 0);
02139 }
02140 else {
02141 WN *result_wn;
02142
02143 if (assign_code == MODIFY_EXPR) {
02144 if (is_realpart)
02145 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02146 rhs_wn,
02147 WN_Unary(OPR_IMAGPART,
02148 Mtype_complex_to_real (rtype),
02149 WN_CreateIload(OPR_ILOAD, rtype, desc,
02150 component_offset,
02151 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02152 Make_Pointer_Type(elem_ty_idx, FALSE),
02153 WN_COPY_Tree (addr_wn),
02154 field_id)));
02155 else
02156 if (is_imagpart)
02157 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02158 WN_Unary(OPR_REALPART,
02159 Mtype_complex_to_real (rtype),
02160 WN_CreateIload(OPR_ILOAD, rtype, desc,
02161 component_offset,
02162 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02163 Make_Pointer_Type(elem_ty_idx, FALSE),
02164 WN_COPY_Tree (addr_wn),
02165 field_id)),
02166 rhs_wn);
02167 }
02168 else {
02169 if (is_realpart)
02170 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02171 rhs_wn,
02172 WN_Floatconst (Mtype_complex_to_real (rtype), 0.0));
02173 else
02174 if (is_imagpart)
02175 rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
02176 WN_Floatconst(Mtype_complex_to_real(rtype), 0.0),
02177 rhs_wn);
02178 }
02179
02180 if (assign_code == PREINCREMENT_EXPR ||
02181 assign_code == PREDECREMENT_EXPR) {
02182 wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02183 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02184 Make_Pointer_Type(elem_ty_idx, FALSE),
02185 WN_COPY_Tree (addr_wn),
02186 field_id);
02187 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
02188 rtype, wn, rhs_wn);
02189 result_wn = rhs_wn;
02190 }
02191 else if (assign_code == POSTINCREMENT_EXPR ||
02192 assign_code == POSTDECREMENT_EXPR) {
02193 result_wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02194 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02195 Make_Pointer_Type(elem_ty_idx, FALSE),
02196 WN_COPY_Tree (addr_wn),
02197 field_id);
02198 }
02199 else result_wn = rhs_wn;
02200
02201
02202 if (need_result && rtype != MTYPE_M &&
02203 (volt ||
02204 assign_code == POSTINCREMENT_EXPR ||
02205 assign_code == POSTDECREMENT_EXPR)) {
02206 result_in_temp = TRUE;
02207 result_preg_st = MTYPE_To_PREG(rtype);
02208 result_preg = Create_Preg(rtype, NULL);
02209 wn = WN_Stid(rtype, result_preg, result_preg_st, desc_ty_idx,
02210 result_wn, 0);
02211 WFE_Stmt_Append (wn, Get_Srcpos());;
02212 result_wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx,
02213 0);
02214 }
02215
02216 if (assign_code == POSTINCREMENT_EXPR ||
02217 assign_code == POSTDECREMENT_EXPR) {
02218 rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
02219 rtype, result_wn, rhs_wn);
02220 }
02221 else rhs_wn = result_wn;
02222
02223
02224 }
02225
02226
02227 if (!WFE_Keep_Zero_Length_Structs &&
02228 desc == MTYPE_M &&
02229 TY_size (elem_ty_idx) == 0) {
02230
02231 if (WN_has_side_effects (addr_wn)) {
02232 wn = WN_CreateEval (addr_wn);
02233 WFE_Stmt_Append (wn, Get_Srcpos());
02234 }
02235 wn = NULL;
02236 }
02237 else {
02238 wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset,
02239 Make_Pointer_Type(elem_ty_idx, FALSE), rhs_wn,
02240 addr_wn, field_id);
02241 WFE_Stmt_Append(wn, Get_Srcpos());
02242 #ifdef TARG_SL
02243 if (need_append) {
02244 WN *iload;
02245 if (!result_in_temp)
02246 iload = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02247 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02248 Make_Pointer_Type (elem_ty_idx, FALSE),
02249 WN_COPY_Tree (addr_wn),
02250 field_id);
02251 else
02252 iload = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02253 WFE_Stmt_Append_Extend_Intrinsic(wn, iload, Get_Srcpos());
02254 }
02255 #endif
02256 if (need_result) {
02257 if (! result_in_temp)
02258 wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
02259 field_id != 0 ? elem_ty_idx : desc_ty_idx,
02260 Make_Pointer_Type (elem_ty_idx, FALSE),
02261 WN_COPY_Tree (addr_wn),
02262 field_id);
02263 else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
02264 if (is_realpart)
02265 wn = WN_Unary (OPR_REALPART, Mtype_complex_to_real (rtype), wn);
02266 else
02267 if (is_imagpart)
02268 wn = WN_Unary (OPR_IMAGPART, Mtype_complex_to_real (rtype), wn);
02269 }
02270 else wn = NULL;
02271 }
02272 }
02273 break;
02274 #ifdef KEY // bug 10073
02275 case MIN_EXPR:
02276 case MAX_EXPR:
02277 {
02278 tree arg0 = TREE_OPERAND(lhs, 0);
02279 tree arg1 = TREE_OPERAND(lhs, 1);
02280
02281 WN *then_block = WN_CreateBlock ();
02282 WN *else_block = WN_CreateBlock ();
02283
02284 WFE_Stmt_Push (then_block, wfe_stmk_if_then, Get_Srcpos());
02285 #ifdef TARG_SL
02286 WN * wn1 = WFE_Lhs_Of_Modify_Expr (assign_code, arg0, NULL,
02287 #else
02288 WN * wn1 = WFE_Lhs_Of_Modify_Expr (assign_code, arg0,
02289 #endif
02290 TRUE,
02291 component_ty_idx, component_offset,
02292 field_id, is_bit_field,
02293 rhs_wn, rhs_preg_num, is_realpart,
02294 is_imagpart);
02295 WFE_Stmt_Pop (wfe_stmk_if_then);
02296
02297 WFE_Stmt_Push (else_block, wfe_stmk_if_else, Get_Srcpos());
02298 #ifdef TARG_SL
02299 WN * wn2 = WFE_Lhs_Of_Modify_Expr (assign_code, arg1, NULL,
02300 #else
02301 WN * wn2 = WFE_Lhs_Of_Modify_Expr (assign_code, arg1,
02302 #endif
02303 TRUE,
02304 component_ty_idx, component_offset,
02305 field_id, is_bit_field,
02306 rhs_wn, rhs_preg_num, is_realpart,
02307 is_imagpart);
02308 WFE_Stmt_Pop (wfe_stmk_if_else);
02309
02310 Is_True (wn1 && wn2,
02311 ("WFE_Lhs_Of_Modify_Expr: null operands of MIN/MAX_EXPR?"));
02312 WN * wn0 = WN_Relational (code == MIN_EXPR ? OPR_LE : OPR_GE,
02313 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(lhs)))),
02314 wn1, wn2);
02315 WN *if_stmt = WN_CreateIf (wn0, then_block, else_block);
02316 WFE_Stmt_Append (if_stmt, Get_Srcpos());
02317 }
02318 break;
02319 #endif
02320
02321 default:
02322 Fail_FmtAssertion ("WFE_Lhs_Of_Modify_Expr: unhandled tree node in LHS of MODIFY_EXPR");
02323 }
02324
02325 return wn;
02326 }
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353 WN*
02354 WFE_Expand_Expr_With_Sequence_Point (tree exp, TYPE_ID mtype, WN* target_wn)
02355 {
02356 WN *wn;
02357
02358 if (mtype == MTYPE_V)
02359 #ifdef KEY
02360 wn = WFE_Expand_Expr (exp, FALSE, 0, 0, 0, 0, FALSE, FALSE, target_wn);
02361 #else
02362 wn = WFE_Expand_Expr (exp, FALSE);
02363 #endif
02364
02365 else {
02366
02367 WN *comma_block = WN_CreateBlock ();
02368
02369 WFE_Stmt_Push (comma_block, wfe_stmk_comma, Get_Srcpos ());
02370 #ifdef KEY
02371 wn = WFE_Expand_Expr (exp, TRUE, 0, 0, 0, 0, FALSE, FALSE, target_wn);
02372 #else
02373 wn = WFE_Expand_Expr (exp);
02374 #endif
02375
02376
02377 if (TREE_TYPE (exp) == boolean_type_node) {
02378 if (WN_operator (wn) == OPR_LDID ||
02379 WN_operator (wn) == OPR_ILOAD) {
02380 WN *zero = WN_Intconst (WN_rtype (wn), 0);
02381 wn = WN_Relational (OPR_NE, MTYPE_I4, wn, zero);
02382 }
02383 }
02384
02385 WFE_Stmt_Pop (wfe_stmk_comma);
02386 if (WN_first (comma_block)) {
02387 if (wn)
02388 wn = WN_CreateComma (OPR_COMMA, Mtype_comparison (mtype), MTYPE_V,
02389 comma_block, wn);
02390 else
02391 WFE_Stmt_Append (comma_block, Get_Srcpos());
02392 }
02393 else
02394 WN_Delete (comma_block);
02395 }
02396
02397 return wn;
02398 }
02399
02400 static void
02401 emit_barrier (bool type, tree list, INT32 k)
02402 {
02403 INT32 i;
02404 WN *wn = WN_CreateBarrier (type, k);
02405
02406 for (i = 0; i < k; i++) {
02407 tree exp = TREE_VALUE (list);
02408 ST *st = Get_ST (exp);
02409 WN_kid (wn, i) = WN_Lda (Pointer_Mtype, 0, st,
02410 Make_Pointer_Type (ST_type (st), FALSE));
02411 list = TREE_CHAIN (list);
02412 }
02413
02414 WFE_Stmt_Append (wn, Get_Srcpos());
02415 }
02416
02417 static WN *
02418 emit_builtin_lock_test_and_set (tree exp, INT32 k)
02419 {
02420 WN *wn;
02421 WN *arg_wn;
02422 WN *ikids [2];
02423 TYPE_ID obj_mtype;
02424 TY_IDX arg_ty_idx;
02425 TYPE_ID arg_mtype;
02426 tree list = TREE_OPERAND (exp, 1);
02427 OPCODE opc;
02428 INTRINSIC iopc;
02429
02430 obj_mtype = TY_mtype (TY_pointed (Get_TY(TREE_TYPE(TREE_VALUE(list)))));
02431 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02432 arg_mtype = TY_mtype (arg_ty_idx);
02433 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02434 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02435 ikids [0] = arg_wn;
02436 list = TREE_CHAIN (list);
02437 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02438 arg_mtype = TY_mtype (arg_ty_idx);
02439 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02440 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02441 ikids [1] = arg_wn;
02442 list = TREE_CHAIN (list);
02443
02444 if (obj_mtype == MTYPE_I4) {
02445 opc = OPC_I4INTRINSIC_CALL;
02446 iopc = INTRN_LOCK_TEST_AND_SET_I4;
02447 }
02448 else
02449 if (obj_mtype == MTYPE_U4) {
02450 opc = OPC_U4INTRINSIC_CALL;
02451 iopc = INTRN_LOCK_TEST_AND_SET_I4;
02452 }
02453 else
02454 if (obj_mtype == MTYPE_I8) {
02455 opc = OPC_I8INTRINSIC_CALL;
02456 iopc = INTRN_LOCK_TEST_AND_SET_I8;
02457 }
02458 else
02459 if (obj_mtype == MTYPE_U8) {
02460 opc = OPC_U8INTRINSIC_CALL;
02461 iopc = INTRN_LOCK_TEST_AND_SET_I8;
02462 }
02463 else {
02464 Fail_FmtAssertion ("unknown object type in __builtin_lock_test_and_set");
02465 opc = OPCODE_UNKNOWN;
02466 iopc = INTRINSIC_NONE;
02467 }
02468
02469 wn = WN_Create_Intrinsic (opc, iopc, 2, ikids);
02470 WFE_Stmt_Append (wn, Get_Srcpos());
02471
02472 ST *preg_st = MTYPE_To_PREG(obj_mtype);
02473 TY_IDX preg_ty_idx = Be_Type_Tbl(obj_mtype);
02474 PREG_NUM preg = Create_Preg (obj_mtype, NULL);
02475
02476 wn = WN_Ldid (obj_mtype, -1, Return_Val_Preg, preg_ty_idx);
02477 wn = WN_Stid (obj_mtype, preg, preg_st, preg_ty_idx, wn),
02478 WFE_Stmt_Append (wn, Get_Srcpos());
02479
02480 emit_barrier (FALSE, list, k);
02481
02482 wn = WN_Ldid (obj_mtype, preg, preg_st, preg_ty_idx);
02483
02484 return wn;
02485 }
02486
02487 static void
02488 emit_builtin_lock_release (tree exp, INT32 k)
02489 {
02490 WN *wn;
02491 WN *arg_wn;
02492 WN *ikids [1];
02493 TYPE_ID obj_mtype;
02494 TY_IDX arg_ty_idx;
02495 TYPE_ID arg_mtype;
02496 tree list = TREE_OPERAND (exp, 1);
02497 OPCODE opc;
02498 INTRINSIC iopc;
02499
02500 obj_mtype = TY_mtype (TY_pointed (Get_TY(TREE_TYPE(TREE_VALUE(list)))));
02501 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02502 arg_mtype = TY_mtype (arg_ty_idx);
02503 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02504 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02505 ikids [0] = arg_wn;
02506 list = TREE_CHAIN (list);
02507
02508 emit_barrier (TRUE, list, k);
02509
02510 opc = OPC_VINTRINSIC_CALL;
02511 if (obj_mtype == MTYPE_I4)
02512 iopc = INTRN_LOCK_RELEASE_I4;
02513 else
02514 if (obj_mtype == MTYPE_U4)
02515 iopc = INTRN_LOCK_RELEASE_I4;
02516 else
02517 if (obj_mtype == MTYPE_I8)
02518 iopc = INTRN_LOCK_RELEASE_I8;
02519 else
02520 if (obj_mtype == MTYPE_U8)
02521 iopc = INTRN_LOCK_RELEASE_I8;
02522 else {
02523 Fail_FmtAssertion ("unknown object type in __builtin_lock_test_and_set");
02524 opc = OPCODE_UNKNOWN;
02525 iopc = INTRINSIC_NONE;
02526 }
02527
02528 wn = WN_Create_Intrinsic (opc, iopc, 1, ikids);
02529 WFE_Stmt_Append (wn, Get_Srcpos());
02530 }
02531
02532 static WN *
02533 emit_builtin_compare_and_swap (tree exp, INT32 k)
02534 {
02535 WN *wn;
02536 WN *arg_wn;
02537 WN *ikids [3];
02538 TYPE_ID obj_mtype;
02539 TY_IDX arg_ty_idx;
02540 TYPE_ID arg_mtype;
02541 tree list = TREE_OPERAND (exp, 1);
02542 OPCODE opc;
02543 INTRINSIC iopc;
02544
02545 obj_mtype = TY_mtype (TY_pointed (Get_TY(TREE_TYPE(TREE_VALUE(list)))));
02546 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02547 arg_mtype = TY_mtype (arg_ty_idx);
02548 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02549 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02550 ikids [0] = arg_wn;
02551 list = TREE_CHAIN (list);
02552 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02553 arg_mtype = TY_mtype (arg_ty_idx);
02554 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02555 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02556 ikids [1] = arg_wn;
02557 list = TREE_CHAIN (list);
02558 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
02559 arg_mtype = TY_mtype (arg_ty_idx);
02560 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
02561 arg_wn = WN_CreateParm (arg_mtype, arg_wn, arg_ty_idx, WN_PARM_BY_VALUE);
02562 ikids [2] = arg_wn;
02563 list = TREE_CHAIN (list);
02564
02565 emit_barrier (TRUE, list, k);
02566
02567 opc = OPC_I4INTRINSIC_CALL;
02568 if (obj_mtype == MTYPE_I4)
02569 iopc = INTRN_COMPARE_AND_SWAP_I4;
02570 else
02571 if (obj_mtype == MTYPE_U4)
02572 iopc = INTRN_COMPARE_AND_SWAP_I4;
02573 else
02574 if (obj_mtype == MTYPE_I8)
02575 iopc = INTRN_COMPARE_AND_SWAP_I8;
02576 else
02577 if (obj_mtype == MTYPE_U8)
02578 iopc = INTRN_COMPARE_AND_SWAP_I8;
02579 else {
02580 Fail_FmtAssertion ("unknown object type in __builtin_lock_test_and_set");
02581 opc = OPCODE_UNKNOWN;
02582 iopc = INTRINSIC_NONE;
02583 }
02584
02585 wn = WN_Create_Intrinsic (opc, iopc, 3, ikids);
02586 WFE_Stmt_Append (wn, Get_Srcpos());
02587
02588 ST *preg_st = MTYPE_To_PREG(MTYPE_I4);
02589 TY_IDX preg_ty_idx = Be_Type_Tbl(MTYPE_I4);
02590 PREG_NUM preg = Create_Preg (MTYPE_I4, NULL);
02591
02592 wn = WN_Ldid (MTYPE_I4, -1, Return_Val_Preg, preg_ty_idx);
02593 wn = WN_Stid (MTYPE_I4, preg, preg_st, preg_ty_idx, wn),
02594 WFE_Stmt_Append (wn, Get_Srcpos());
02595
02596 emit_barrier (FALSE, list, k);
02597
02598 wn = WN_Ldid (MTYPE_I4, preg, preg_st, preg_ty_idx);
02599
02600 return wn;
02601 }
02602
02603 static void
02604 emit_builtin_synchronize (tree exp, INT32 k)
02605 {
02606 WN *wn;
02607 tree list = TREE_OPERAND (exp, 1);
02608 emit_barrier (TRUE, list, k);
02609 wn = WN_Create_Intrinsic (OPC_VINTRINSIC_CALL, INTRN_SYNCHRONIZE, 0, NULL);
02610 WFE_Stmt_Append (wn, Get_Srcpos());
02611 emit_barrier (FALSE, list, k);
02612 }
02613
02614 static char *
02615 get_string_pointer (WN *wn)
02616 {
02617 char *ptr = NULL;
02618
02619 if (WN_operator (wn) == OPR_LDA) {
02620 ST *st = WN_st (wn);
02621 if (ST_class (st) == CLASS_CONST) {
02622 TCON tcon = Tcon_Table [ST_tcon (st)];
02623 if (TCON_ty (tcon) == MTYPE_STRING)
02624 ptr = ((char *) Targ_String_Address (tcon)) + WN_offset (wn);
02625 }
02626 }
02627
02628 return ptr;
02629 }
02630
02631 #ifdef KEY
02632
02633
02634 int
02635 tinfo_decl_p (tree t)
02636 {
02637 if (
02638 TREE_CODE (t) == VAR_DECL
02639
02640 && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
02641
02642 && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
02643
02644 && TYPE_FIELDS (TREE_TYPE (t))
02645
02646 && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
02647 return 1;
02648 return 0;
02649 }
02650 #endif
02651
02652
02653
02654 WN*
02655 WFE_Address_Of(tree arg0)
02656 {
02657 enum tree_code code0 = TREE_CODE (arg0);
02658 ST *st = 0;
02659 WN* wn = 0;
02660 WN* wn0;
02661 WN* wn1;
02662 TY_IDX ty_idx;
02663
02664 switch (code0) {
02665 case VAR_DECL:
02666 case PARM_DECL:
02667 case FUNCTION_DECL:
02668 #ifdef KEY
02669 case RESULT_DECL:
02670 #endif
02671 {
02672 st = Get_ST (arg0);
02673 ty_idx = ST_type (st);
02674 #ifdef KEY
02675
02676
02677 if (code0 == VAR_DECL) {
02678 if (DECL_INITIAL(arg0) &&
02679 #ifdef PATHSCALE_MERGE
02680 (DECL_VIRTUAL_P(arg0) || tinfo_decl_p(arg0) ) &&
02681 #else
02682 DECL_VIRTUAL_P(arg0) &&
02683 #endif
02684 !DECL_EXTERNAL(arg0)) {
02685 tree init = DECL_INITIAL(arg0);
02686 if (TREE_CODE(init) != ERROR_MARK) {
02687 FmtAssert (TREE_CODE(init) == CONSTRUCTOR,
02688 ("Unexpected initializer for virtual table"));
02689 WFE_Initialize_Decl(arg0);
02690 }
02691 }
02692 }
02693 #endif
02694
02695 if (code0 == VAR_DECL &&
02696 st != ST_base(st)) {
02697 FmtAssert (ST_ofst (st) == 0,
02698 ("Variable Length Arrays within struct not currently implemented"));
02699 wn = WN_Ldid (Pointer_Mtype, 0, ST_base(st), ST_type(ST_base(st)));
02700 }
02701 else
02702 if (!WFE_Keep_Zero_Length_Structs &&
02703 code0 == PARM_DECL &&
02704 TY_mtype (ty_idx) == MTYPE_M &&
02705 TY_size (ty_idx) == 0) {
02706
02707 DevWarn ("taking address of zero length struct %s at line %d",
02708 ST_name (st), lineno);
02709 wn = WN_Intconst (Pointer_Mtype, 0);
02710 }
02711 else
02712 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
02713 }
02714 break;
02715
02716 case INDIRECT_REF:
02717 wn = WFE_Expand_Expr (TREE_OPERAND(arg0, 0));
02718 break;
02719
02720 case STRING_CST:
02721 {
02722 TCON tcon;
02723 tcon = Host_To_Targ_String (MTYPE_STRING,
02724 const_cast<char*>TREE_STRING_POINTER(arg0),
02725 TREE_STRING_LENGTH(arg0));
02726 ty_idx = Get_TY(TREE_TYPE(arg0));
02727 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
02728 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
02729 TREE_STRING_ST (arg0) = st;
02730 }
02731 break;
02732
02733 case CONSTRUCTOR:
02734 {
02735 st = WFE_Generate_Temp_For_Initialized_Aggregate (arg0, "");
02736 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
02737 }
02738 break;
02739
02740 case LABEL_DECL:
02741 {
02742 DevWarn ("taking address of a label at line %d", lineno);
02743 LABEL_IDX label_idx = WFE_Get_LABEL (arg0, FALSE);
02744 #if 0
02745 FmtAssert (arg0->decl.symtab_idx == CURRENT_SYMTAB,
02746 ("line %d: taking address of a label not defined in current function currently not implemented", lineno));
02747 #endif
02748 wn = WN_LdaLabel (Pointer_Mtype, label_idx);
02749 Set_LABEL_addr_saved (label_idx);
02750 }
02751 break;
02752
02753 case TARGET_EXPR:
02754 {
02755 WFE_Expand_Expr (arg0);
02756 st = Get_ST (TREE_OPERAND(arg0, 0));
02757 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
02758 }
02759 break;
02760
02761 case COMPOUND_EXPR:
02762 {
02763 #ifdef KEY
02764 wn = WFE_Expand_Expr(arg0);
02765 if (WN_operator(wn) == OPR_CSELECT) {
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777 int i;
02778 ST *st1 = NULL, *st2 = NULL;
02779 for (i = 0; i < 2; i++) {
02780 WN *kid = (i == 0) ? WN_kid1(wn) : WN_kid2(wn);
02781 WN *comma_kid1;
02782 ST **st_ptr = (i == 0) ? &st1 : &st2;
02783 switch (WN_operator(kid)) {
02784 case OPR_LDID:
02785 *st_ptr = WN_st(kid);
02786 break;
02787 case OPR_COMMA:
02788 comma_kid1 = WN_kid1(kid);
02789 Is_True(WN_operator(comma_kid1) == OPR_LDID,
02790 ("WFE_Address_Of: kid1 of COMMA is not LDID"));
02791 *st_ptr = WN_st(comma_kid1);
02792 break;
02793 default:
02794 FmtAssert(FALSE, ("WFE_Address_Of: CSELECT kid NYI"));
02795 }
02796 }
02797 Is_True((st1 != NULL) && (st1 == st2),
02798 ("WFE_Address_Of: CSELECT kids returns different STs"));
02799 st = st1;
02800 } else
02801 st = WN_st(wn);
02802 #else
02803 st = WN_st (WFE_Expand_Expr (arg0));
02804 #endif
02805 wn = WN_Lda (Pointer_Mtype, ST_ofst (st), st);
02806 }
02807 break;
02808
02809 case NOP_EXPR:
02810 {
02811 wn = WFE_Address_Of(TREE_OPERAND(arg0, 0));
02812 }
02813 break;
02814
02815 case MIN_EXPR:
02816 case MAX_EXPR:
02817 {
02818
02819 tree op0 = TREE_OPERAND(arg0, 0);
02820 tree op1 = TREE_OPERAND(arg0, 1);
02821 WN* a = WFE_Expand_Expr(op0);
02822 WN* b = WFE_Expand_Expr(op1);
02823 FmtAssert(!WN_has_side_effects(a) && !WN_has_side_effects(b),
02824 ("Addr of MIN/MAX_EXPR with side effects not yet supported"));
02825
02826 FmtAssert(same_type_p(TREE_TYPE(op0), TREE_TYPE(op1)),
02827 ("Types of MIN/MAX_EXPR operands differ"));
02828 TY_IDX ptr_ty = Make_Pointer_Type (Get_TY(TREE_TYPE(op0)), FALSE);
02829 TYPE_ID ptr_mtype = TY_mtype(ptr_ty);
02830 TY_IDX arg_ty = Get_TY(TREE_TYPE(TREE_OPERAND(arg0, 0)));
02831 TYPE_ID arg_mtype = TY_mtype(arg_ty);
02832
02833 WN* aptr = WFE_Address_Of(op0);
02834 WN* bptr = WFE_Address_Of(op1);
02835 wn = WN_Select(Widen_Mtype(ptr_mtype),
02836 WN_Relational(code0 == MIN_EXPR ? OPR_LT : OPR_GT,
02837 Widen_Mtype(arg_mtype),
02838 a, b),
02839 aptr, bptr);
02840 Set_PU_has_very_high_whirl (Get_Current_PU ());
02841 }
02842 break;
02843
02844 case COMPONENT_REF:
02845 {
02846 wn = WFE_Expand_Expr (arg0);
02847 ty_idx = Get_TY(TREE_TYPE(arg0));
02848 if (WN_operator (wn) == OPR_LDID) {
02849 WN_set_operator (wn, OPR_LDA);
02850 WN_set_desc (wn, MTYPE_V);
02851 WN_set_rtype(wn, Pointer_Mtype);
02852 WN_set_ty (wn, Make_Pointer_Type(WN_ty(wn)));
02853 }
02854 else
02855 if (WN_operator (wn) == OPR_ILOAD) {
02856 wn0 = WN_kid0 (wn);
02857 wn1 = WN_Intconst (Pointer_Mtype, WN_offset (wn));
02858 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn0, wn1);
02859 }
02860 else
02861 Fail_FmtAssertion ("WFE_Address_Of has unhandled %s",
02862 Operator_From_Tree [code0].name);
02863 }
02864 break;
02865
02866 #ifdef KEY // bug 3228
02867 case ARRAY_REF:
02868 wn = WFE_Expand_Expr (arg0);
02869 if (WN_operator(wn) == OPR_ILOAD)
02870 wn = WN_kid0(wn);
02871 ty_idx = Get_TY(TREE_TYPE(arg0));
02872 break;
02873 #endif
02874
02875 #ifdef KEY
02876 case COMPOUND_LITERAL_EXPR:
02877 {
02878 arg0 = DECL_INITIAL (TREE_OPERAND (TREE_OPERAND (arg0, 0), 0));
02879 st = WFE_Generate_Temp_For_Initialized_Aggregate (arg0, "");
02880 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
02881 }
02882 break;
02883
02884
02885 case SAVE_EXPR:
02886 {
02887 st = WN_st (WFE_Expand_Expr (arg0));
02888 wn = WN_Lda (Pointer_Mtype, ST_ofst (st), st);
02889 }
02890 break;
02891
02892
02893 case REALPART_EXPR:
02894 {
02895 wn = WFE_Expand_Expr (TREE_OPERAND (arg0, 0));
02896 if (WN_operator (wn) == OPR_ILOAD)
02897 wn = WN_kid0 (wn);
02898 else if (WN_operator (wn) == OPR_LDID)
02899 wn = WN_Lda (Pointer_Mtype, WN_offset(wn), WN_st(wn));
02900 else Fail_FmtAssertion ("WFE_Address_Of: NYI for REALPART_EXPR");
02901 }
02902 break;
02903
02904 case IMAGPART_EXPR:
02905 {
02906 wn = WFE_Expand_Expr (TREE_OPERAND (arg0, 0));
02907 if (WN_operator (wn) == OPR_ILOAD)
02908 {
02909 wn0 = WN_kid0 (wn);
02910 TYPE_ID imag_mtype;
02911 switch (WN_rtype (wn))
02912 {
02913 case MTYPE_C4:
02914 imag_mtype = MTYPE_F4;
02915 break;
02916 case MTYPE_C8:
02917 imag_mtype = MTYPE_F8;
02918 break;
02919 case MTYPE_C10:
02920 imag_mtype = MTYPE_F10;
02921 break;
02922 case MTYPE_CQ:
02923 imag_mtype = MTYPE_FQ;
02924 break;
02925 default:
02926 Fail_FmtAssertion ("WFE_Address_Of: Unexpected rtype in IMAGPART_EXPR");
02927 }
02928 INT ofst;
02929 if (imag_mtype == MTYPE_FQ)
02930 {
02931 #ifdef TARG_X8664
02932 if (Is_Target_32bit()) ofst = 12; else
02933 #endif // TARG_X8664
02934 ofst = 16;
02935 }
02936 else ofst = MTYPE_byte_size (imag_mtype);
02937
02938 wn1 = WN_Intconst (Pointer_Mtype, ofst);
02939 wn = WN_Binary (OPR_ADD, Pointer_Mtype, wn0, wn1);
02940 }
02941 else if (WN_operator (wn) == OPR_LDID)
02942 wn = WN_Lda (Pointer_Mtype,
02943 WN_offset(wn) + MTYPE_byte_size(WN_rtype(wn)) / 2,
02944 WN_st(wn));
02945 else Fail_FmtAssertion ("WFE_Address_Of: NYI for IMAGPART_EXPR");
02946 }
02947 break;
02948 #endif
02949
02950 default:
02951 {
02952 Fail_FmtAssertion ("WFE_Address_Of: Unexpected operand %s",
02953 Operator_From_Tree [code0].name);
02954 }
02955 break;
02956 }
02957
02958 FmtAssert(wn != 0, ("WFE_Address_Of: null WHIRL tree for %s",
02959 Operator_From_Tree [code0].name));
02960 return wn;
02961 }
02962
02963 #ifdef TARG_X8664
02964
02965
02966
02967
02968
02969 static WN *WFE_x8664_va_arg(WN *ap_wn, BOOL isfloat, TY_IDX ty_idx, BOOL twice)
02970 {
02971
02972 WN *wn0 = WN_Iload(MTYPE_I4, !isfloat ? 0 : 4, MTYPE_To_TY(MTYPE_I4),
02973 WN_CopyNode(ap_wn));
02974 WN *wn1 = WN_Intconst(MTYPE_I4, (!isfloat ? 48 : 176) - (twice ? 8 : 0));
02975 WN *wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
02976 LABEL_IDX lab1;
02977 New_LABEL (CURRENT_SYMTAB, lab1);
02978 WN *lab1_wn = WN_CreateLabel ((ST_IDX) 0, lab1, 0, NULL);
02979 wn = WN_CreateTruebr(lab1, wn);
02980 WFE_Stmt_Append (wn, Get_Srcpos ());
02981
02982 ST *arg_temp_st = Gen_Temp_Symbol(Make_Pointer_Type(ty_idx), ".va_arg");
02983 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, arg_temp_st);
02984
02985 wn0 = WN_Iload(MTYPE_I4, !isfloat ? 0 : 4, MTYPE_To_TY(MTYPE_I4),
02986 WN_CopyNode(ap_wn));
02987 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
02988 WN_CopyNode(ap_wn));
02989 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
02990 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn);
02991 WFE_Stmt_Append (wn, Get_Srcpos ());
02992
02993
02994 wn0 = WN_Iload(MTYPE_I4, !isfloat ? 0 : 4, MTYPE_To_TY(MTYPE_I4),
02995 WN_CopyNode(ap_wn));
02996 wn1 = WN_Intconst(MTYPE_I4, (!isfloat ? 8 : 16) * ((INT)twice+1));
02997 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
02998 wn = WN_Istore(MTYPE_I4, !isfloat ? 0 : 4,
02999 Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
03000 WN_CopyNode(ap_wn), wn);
03001 WFE_Stmt_Append (wn, Get_Srcpos ());
03002
03003
03004 LABEL_IDX lab2;
03005 New_LABEL (CURRENT_SYMTAB, lab2);
03006 WN *lab2_wn = WN_CreateLabel ((ST_IDX) 0, lab2, 0, NULL);
03007 wn = WN_CreateGoto(lab2);
03008 WFE_Stmt_Append (wn, Get_Srcpos ());
03009
03010 WFE_Stmt_Append (lab1_wn, Get_Srcpos ());
03011
03012
03013 wn0 = WN_Iload(Pointer_Mtype, 8, Make_Pointer_Type(ty_idx),
03014 WN_CopyNode(ap_wn));
03015 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn0);
03016 WFE_Stmt_Append (wn, Get_Srcpos ());
03017
03018
03019 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
03020 WN_CopyNode(ap_wn));
03021 wn1 = WN_Intconst(MTYPE_U8, twice ? 16 : 8);
03022 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03023 wn = WN_Istore(Pointer_Mtype, 8,Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
03024 WN_CopyNode(ap_wn), wn);
03025 WFE_Stmt_Append (wn, Get_Srcpos ());
03026
03027 WFE_Stmt_Append (lab2_wn, Get_Srcpos ());
03028
03029 return WN_Ldid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx));
03030 }
03031
03032
03033
03034
03035
03036
03037 static WN *WFE_x8664_va_arg_2_mixed(WN *ap_wn, BOOL isfloat0, BOOL isfloat1,
03038 TY_IDX ty_idx)
03039 {
03040
03041 WN *wn0 = WN_Iload(MTYPE_I4, 0, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03042 WN *wn1 = WN_Intconst(MTYPE_I4, 48);
03043 WN *wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
03044 LABEL_IDX lab1;
03045 New_LABEL (CURRENT_SYMTAB, lab1);
03046 WN *lab1_wn = WN_CreateLabel ((ST_IDX) 0, lab1, 0, NULL);
03047 wn = WN_CreateTruebr(lab1, wn);
03048 WFE_Stmt_Append (wn, Get_Srcpos ());
03049
03050 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03051 wn1 = WN_Intconst(MTYPE_I4, 176);
03052 wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
03053 wn = WN_CreateTruebr(lab1, wn);
03054 WFE_Stmt_Append (wn, Get_Srcpos ());
03055
03056
03057 ST *struct_temp_st = Gen_Temp_Symbol(ty_idx, ".va_arg_struct");
03058 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, struct_temp_st);
03059
03060
03061
03062 wn0 = WN_Iload(MTYPE_I4, 0, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03063 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
03064 WN_CopyNode(ap_wn));
03065 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03066 wn = WN_Iload(MTYPE_I8, 0, MTYPE_To_TY(MTYPE_I8), wn);
03067 wn = WN_Stid(MTYPE_I8, isfloat0 ? 8 : 0, struct_temp_st,
03068 MTYPE_To_TY(MTYPE_I8), wn);
03069 WFE_Stmt_Append (wn, Get_Srcpos ());
03070
03071
03072 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03073 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
03074 WN_CopyNode(ap_wn));
03075 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03076 wn = WN_Iload(MTYPE_F8, 0, MTYPE_To_TY(MTYPE_F8), wn);
03077 wn = WN_Stid(MTYPE_F8, isfloat0 ? 0 : 8, struct_temp_st,
03078 MTYPE_To_TY(MTYPE_F8), wn);
03079 WFE_Stmt_Append (wn, Get_Srcpos ());
03080
03081
03082 wn0 = WN_Iload(MTYPE_I4, 0, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03083 wn1 = WN_Intconst(MTYPE_I4, 8);
03084 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
03085 wn = WN_Istore(MTYPE_I4, 0, Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
03086 WN_CopyNode(ap_wn), wn);
03087 WFE_Stmt_Append (wn, Get_Srcpos ());
03088
03089 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03090 wn1 = WN_Intconst(MTYPE_I4, 16);
03091 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
03092 wn = WN_Istore(MTYPE_I4, 4, Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
03093 WN_CopyNode(ap_wn), wn);
03094 WFE_Stmt_Append (wn, Get_Srcpos ());
03095
03096
03097 ST *arg_temp_st = Gen_Temp_Symbol(Make_Pointer_Type(ty_idx), ".va_arg");
03098 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, arg_temp_st);
03099 wn = WN_Lda(Pointer_Mtype, 0, struct_temp_st, 0);
03100 Set_ST_addr_saved(struct_temp_st);
03101 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn);
03102 WFE_Stmt_Append (wn, Get_Srcpos ());
03103
03104
03105 LABEL_IDX lab2;
03106 New_LABEL (CURRENT_SYMTAB, lab2);
03107 WN *lab2_wn = WN_CreateLabel ((ST_IDX) 0, lab2, 0, NULL);
03108 wn = WN_CreateGoto(lab2);
03109 WFE_Stmt_Append (wn, Get_Srcpos ());
03110
03111 WFE_Stmt_Append (lab1_wn, Get_Srcpos ());
03112
03113
03114 wn0 = WN_Iload(Pointer_Mtype, 8, Make_Pointer_Type(ty_idx),
03115 WN_CopyNode(ap_wn));
03116 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn0);
03117 WFE_Stmt_Append (wn, Get_Srcpos ());
03118
03119
03120 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
03121 WN_CopyNode(ap_wn));
03122 wn1 = WN_Intconst(MTYPE_U8, 16);
03123 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03124 wn = WN_Istore(Pointer_Mtype, 8,Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
03125 WN_CopyNode(ap_wn), wn);
03126 WFE_Stmt_Append (wn, Get_Srcpos ());
03127
03128 WFE_Stmt_Append (lab2_wn, Get_Srcpos ());
03129
03130 return WN_Ldid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx));
03131 }
03132
03133
03134
03135
03136
03137
03138 static WN *WFE_x8664_va_arg_2_float(WN *ap_wn, TY_IDX ty_idx)
03139 {
03140 LABEL_IDX lab1;
03141 New_LABEL (CURRENT_SYMTAB, lab1);
03142 WN *lab1_wn = WN_CreateLabel ((ST_IDX) 0, lab1, 0, NULL);
03143
03144 WN *wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03145 WN *wn1 = WN_Intconst(MTYPE_I4, 160);
03146 WN *wn = WN_Relational(OPR_GE, MTYPE_I4, wn0, wn1);
03147 wn = WN_CreateTruebr(lab1, wn);
03148 WFE_Stmt_Append (wn, Get_Srcpos ());
03149
03150
03151 ST *struct_temp_st = Gen_Temp_Symbol(ty_idx, ".va_arg_struct");
03152 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, struct_temp_st);
03153
03154
03155
03156 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03157 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
03158 WN_CopyNode(ap_wn));
03159 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03160 wn = WN_Iload(MTYPE_F8, 0, MTYPE_To_TY(MTYPE_F8), wn);
03161 wn = WN_Stid(MTYPE_F8, 0, struct_temp_st, MTYPE_To_TY(MTYPE_F8), wn);
03162 WFE_Stmt_Append (wn, Get_Srcpos ());
03163
03164
03165 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03166 wn1 = WN_Iload(Pointer_Mtype, 16, MTYPE_To_TY(Pointer_Mtype),
03167 WN_CopyNode(ap_wn));
03168 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03169 wn = WN_Iload(MTYPE_F8, 16, MTYPE_To_TY(MTYPE_F8), wn);
03170 wn = WN_Stid(MTYPE_F8, 8, struct_temp_st, MTYPE_To_TY(MTYPE_F8), wn);
03171 WFE_Stmt_Append (wn, Get_Srcpos ());
03172
03173
03174 wn0 = WN_Iload(MTYPE_I4, 4, MTYPE_To_TY(MTYPE_I4), WN_CopyNode(ap_wn));
03175 wn1 = WN_Intconst(MTYPE_I4, 32);
03176 wn = WN_Binary(OPR_ADD, MTYPE_I4, wn0, wn1);
03177 wn = WN_Istore(MTYPE_I4, 4, Make_Pointer_Type(MTYPE_To_TY(MTYPE_I4)),
03178 WN_CopyNode(ap_wn), wn);
03179 WFE_Stmt_Append (wn, Get_Srcpos ());
03180
03181
03182 ST *arg_temp_st = Gen_Temp_Symbol(Make_Pointer_Type(ty_idx), ".va_arg");
03183 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, arg_temp_st);
03184 wn = WN_Lda(Pointer_Mtype, 0, struct_temp_st, 0);
03185 Set_ST_addr_saved(struct_temp_st);
03186 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn);
03187 WFE_Stmt_Append (wn, Get_Srcpos ());
03188
03189
03190 LABEL_IDX lab2;
03191 New_LABEL (CURRENT_SYMTAB, lab2);
03192 WN *lab2_wn = WN_CreateLabel ((ST_IDX) 0, lab2, 0, NULL);
03193 wn = WN_CreateGoto(lab2);
03194 WFE_Stmt_Append (wn, Get_Srcpos ());
03195
03196 WFE_Stmt_Append (lab1_wn, Get_Srcpos ());
03197
03198
03199 wn0 = WN_Iload(Pointer_Mtype, 8, Make_Pointer_Type(ty_idx),
03200 WN_CopyNode(ap_wn));
03201 wn = WN_Stid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx), wn0);
03202 WFE_Stmt_Append (wn, Get_Srcpos ());
03203
03204
03205 wn0 = WN_Iload(Pointer_Mtype, 8, MTYPE_To_TY(Pointer_Mtype),
03206 WN_CopyNode(ap_wn));
03207 wn1 = WN_Intconst(MTYPE_U8, 16);
03208 wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn0, wn1);
03209 wn = WN_Istore(Pointer_Mtype, 8,Make_Pointer_Type(MTYPE_To_TY(Pointer_Mtype)),
03210 WN_CopyNode(ap_wn), wn);
03211 WFE_Stmt_Append (wn, Get_Srcpos ());
03212
03213 WFE_Stmt_Append (lab2_wn, Get_Srcpos ());
03214
03215 return WN_Ldid(Pointer_Mtype, 0, arg_temp_st, Make_Pointer_Type(ty_idx));
03216 }
03217 #endif
03218
03219 #ifdef KEY
03220 static bool inside_eh_region = false;
03221
03222 void
03223 Setup_EH_Region (bool for_unwinding)
03224 {
03225 WN * region_body;
03226
03227 if (for_unwinding)
03228 region_body = WFE_Stmt_Pop (wfe_stmk_region_body);
03229 else
03230 {
03231 region_body = WFE_Stmt_Pop (wfe_stmk_call_region_body);
03232 inside_eh_region = false;
03233 }
03234 INITV_IDX iv;
03235 LABEL_IDX pad = 0;
03236
03237 if (!for_unwinding) pad = lookup_cleanups (iv);
03238 else
03239 {
03240 iv = New_INITV();
03241 INITV_Set_ZERO (Initv_Table[iv], MTYPE_U4, 1);
03242 }
03243
03244 INITV_IDX initv_label = New_INITV();
03245 if (pad)
03246 INITV_Init_Label (initv_label, pad, 1);
03247 else
03248 INITV_Set_ZERO (Initv_Table[initv_label], MTYPE_U4, 1);
03249 INITV_IDX blk = New_INITV();
03250 INITV_Init_Block (blk, initv_label);
03251
03252 Set_INITV_next (initv_label, iv);
03253
03254 TY_IDX ty = MTYPE_TO_TY_array[MTYPE_U4];
03255 ST * ereg = Gen_Temp_Named_Symbol (ty, "dummy1", CLASS_VAR,
03256 SCLASS_EH_REGION_SUPP);
03257 Set_ST_is_initialized (*ereg);
03258 Set_ST_is_not_used (*ereg);
03259 INITO_IDX ereg_supp = New_INITO (ST_st_idx(ereg), blk);
03260
03261 WFE_Stmt_Append (WN_CreateRegion (REGION_KIND_EH, region_body,
03262 WN_CreateBlock(), WN_CreateBlock(), New_Region_Id(), ereg_supp), Get_Srcpos());
03263 Set_PU_has_region (Get_Current_PU());
03264 Set_PU_has_exc_scopes (Get_Current_PU());
03265
03266
03267
03268
03269
03270 TY_IDX tyi;
03271 TY& zty = New_TY (tyi);
03272 UINT inito_size = Get_INITO_Size(ereg_supp);
03273 TY_Init (zty, inito_size, KIND_STRUCT, MTYPE_M,ereg->u1.name_idx);
03274 Set_TY_align (tyi, 4);
03275 ST_Init (ereg, TY_name_idx (zty),
03276 CLASS_VAR, SCLASS_EH_REGION_SUPP, EXPORT_LOCAL, tyi);
03277 Set_ST_is_initialized (ereg);
03278 }
03279 #endif // KEY
03280
03281 static TY_IDX
03282 get_field_type (TY_IDX struct_type, UINT field_id)
03283 {
03284 Is_True (TY_kind (struct_type) == KIND_STRUCT, ("expecting KIND_STRUCT"));
03285 UINT cur_field_id = 0;
03286 FLD_HANDLE fld = FLD_get_to_field (struct_type, field_id, cur_field_id);
03287 Is_True (! fld.Is_Null(), ("Invalid field id %d for type 0x%x",
03288 field_id, struct_type));
03289 return FLD_type (fld);
03290 }
03291
03292 #ifdef TARG_X8664
03293
03294 static WN *
03295 WFE_target_builtins (tree exp, INTRINSIC * iopc, BOOL * intrinsic_op)
03296 {
03297 WN * wn = NULL;
03298
03299
03300 *intrinsic_op = TRUE;
03301
03302 tree func = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
03303 Is_True (TREE_CODE (func) == FUNCTION_DECL && DECL_BUILT_IN (func) &&
03304 DECL_BUILT_IN_CLASS (func) == BUILT_IN_MD, ("Invalid tree node"));
03305
03306 unsigned int ins_code = DECL_FUNCTION_CODE (func);
03307 TYPE_ID res_type = TY_mtype(Get_TY(TREE_TYPE(exp)));
03308 tree t_list = TREE_OPERAND (exp, 1);
03309 WN * arg0 = NULL, * arg1 = NULL;
03310 if (t_list)
03311 {
03312
03313 arg0 = WFE_Expand_Expr (TREE_VALUE (t_list));
03314 if (TREE_CHAIN (t_list))
03315 arg1 = WFE_Expand_Expr (TREE_VALUE (TREE_CHAIN (t_list)));
03316 }
03317
03318 switch (ins_code)
03319 {
03320
03321 case IX86_BUILTIN_PADDB:
03322 case IX86_BUILTIN_PADDW:
03323 case IX86_BUILTIN_PADDD:
03324 case IX86_BUILTIN_ADDPD:
03325 case IX86_BUILTIN_PADDB128:
03326 case IX86_BUILTIN_PADDW128:
03327 case IX86_BUILTIN_PADDD128:
03328 wn = WN_Add (res_type, arg0, arg1);
03329 *intrinsic_op = FALSE;
03330 break;
03331 case IX86_BUILTIN_PSUBB:
03332 case IX86_BUILTIN_PSUBW:
03333 case IX86_BUILTIN_PSUBD:
03334 case IX86_BUILTIN_SUBPD:
03335 case IX86_BUILTIN_PSUBB128:
03336 case IX86_BUILTIN_PSUBW128:
03337 case IX86_BUILTIN_PSUBD128:
03338 wn = WN_Sub (res_type, arg0, arg1);
03339 *intrinsic_op = FALSE;
03340 break;
03341 case IX86_BUILTIN_PAND:
03342 wn = WN_Band (res_type, arg0, arg1);
03343 *intrinsic_op = FALSE;
03344 break;
03345 case IX86_BUILTIN_PANDN:
03346 wn = WN_Band (res_type, WN_Bnot (res_type, arg0), arg1);
03347 *intrinsic_op = FALSE;
03348 break;
03349 case IX86_BUILTIN_POR:
03350 wn = WN_Bior (res_type, arg0, arg1);
03351 *intrinsic_op = FALSE;
03352 break;
03353 case IX86_BUILTIN_PXOR:
03354 wn = WN_Bxor (res_type, arg0, arg1);
03355 *intrinsic_op = FALSE;
03356 break;
03357
03358
03359 case IX86_BUILTIN_PADDSB:
03360 *iopc = INTRN_PADDSB;
03361 break;
03362 case IX86_BUILTIN_PADDSW:
03363 *iopc = INTRN_PADDSW;
03364 break;
03365 case IX86_BUILTIN_PSUBSB:
03366 *iopc = INTRN_PSUBSB;
03367 break;
03368 case IX86_BUILTIN_PSUBSW:
03369 *iopc = INTRN_PSUBSW;
03370 break;
03371 case IX86_BUILTIN_PADDUSB:
03372 *iopc = INTRN_PADDUSB;
03373 break;
03374 case IX86_BUILTIN_PADDUSW:
03375 *iopc = INTRN_PADDUSW;
03376 break;
03377 case IX86_BUILTIN_PSUBUSB:
03378 *iopc = INTRN_PSUBUSB;
03379 break;
03380 case IX86_BUILTIN_PSUBUSW:
03381 *iopc = INTRN_PSUBUSW;
03382 break;
03383 case IX86_BUILTIN_PMULLW:
03384 *iopc = INTRN_PMULLW;
03385 break;
03386 case IX86_BUILTIN_PMULHW:
03387 *iopc = INTRN_PMULHW;
03388 break;
03389 case IX86_BUILTIN_PCMPEQB:
03390 *iopc = INTRN_PCMPEQB;
03391 break;
03392 case IX86_BUILTIN_PCMPEQW:
03393 *iopc = INTRN_PCMPEQW;
03394 break;
03395 case IX86_BUILTIN_PCMPEQD:
03396 *iopc = INTRN_PCMPEQD;
03397 break;
03398 case IX86_BUILTIN_PCMPGTB:
03399 *iopc = INTRN_PCMPGTB;
03400 break;
03401 case IX86_BUILTIN_PCMPGTW:
03402 *iopc = INTRN_PCMPGTW;
03403 break;
03404 case IX86_BUILTIN_PCMPGTD:
03405 *iopc = INTRN_PCMPGTD;
03406 break;
03407 case IX86_BUILTIN_PUNPCKHBW:
03408 *iopc = INTRN_PUNPCKHBW;
03409 break;
03410 case IX86_BUILTIN_PUNPCKHWD:
03411 *iopc = INTRN_PUNPCKHWD;
03412 break;
03413 case IX86_BUILTIN_PUNPCKHDQ:
03414 *iopc = INTRN_PUNPCKHDQ;
03415 break;
03416 case IX86_BUILTIN_PUNPCKLBW:
03417 *iopc = INTRN_PUNPCKLBW;
03418 break;
03419 case IX86_BUILTIN_PUNPCKLWD:
03420 *iopc = INTRN_PUNPCKLWD;
03421 break;
03422 case IX86_BUILTIN_PUNPCKLDQ:
03423 *iopc = INTRN_PUNPCKLDQ;
03424 break;
03425 case IX86_BUILTIN_PACKSSWB:
03426 *iopc = INTRN_PACKSSWB;
03427 break;
03428 case IX86_BUILTIN_PACKSSDW:
03429 *iopc = INTRN_PACKSSDW;
03430 break;
03431 case IX86_BUILTIN_PACKUSWB:
03432 *iopc = INTRN_PACKUSWB;
03433 break;
03434 case IX86_BUILTIN_PMULHUW:
03435 *iopc = INTRN_PMULHUW;
03436 break;
03437 case IX86_BUILTIN_PAVGB:
03438 *iopc = INTRN_PAVGB;
03439 break;
03440 case IX86_BUILTIN_PAVGW:
03441 *iopc = INTRN_PAVGW;
03442 break;
03443 case IX86_BUILTIN_PSADBW:
03444 *iopc = INTRN_PSADBW;
03445 break;
03446 case IX86_BUILTIN_PMAXUB:
03447 *iopc = INTRN_PMAXUB;
03448 break;
03449 case IX86_BUILTIN_PMAXSW:
03450 *iopc = INTRN_PMAXSW;
03451 break;
03452 case IX86_BUILTIN_PMINUB:
03453 *iopc = INTRN_PMINUB;
03454 break;
03455 case IX86_BUILTIN_PMINSW:
03456 *iopc = INTRN_PMINSW;
03457 break;
03458 case IX86_BUILTIN_PEXTRW:
03459 {
03460 Is_True (TREE_CODE (TREE_VALUE (TREE_CHAIN (t_list))) == INTEGER_CST,
03461 ("Immediate value required by pextrw"));
03462 UINT val = Get_Integer_Value (TREE_VALUE (TREE_CHAIN (t_list)));
03463 switch (val)
03464 {
03465 case 0:
03466 *iopc = INTRN_PEXTRW0;
03467 break;
03468 case 1:
03469 *iopc = INTRN_PEXTRW1;
03470 break;
03471 case 2:
03472 *iopc = INTRN_PEXTRW2;
03473 break;
03474 case 3:
03475 *iopc = INTRN_PEXTRW3;
03476 break;
03477 default:
03478 Fail_FmtAssertion ("Invalid imm value %d to pextrw", val);
03479 }
03480 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(t_list)));
03481 TYPE_ID arg_mtype = TY_mtype(arg_ty_idx);
03482 arg0 = WN_CreateParm (Mtype_comparison (arg_mtype), arg0,
03483 arg_ty_idx, WN_PARM_BY_VALUE);
03484 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, MTYPE_U4, MTYPE_V,
03485 *iopc, 1, &arg0);
03486 break;
03487 }
03488 case IX86_BUILTIN_PINSRW:
03489 {
03490 Is_True (TREE_CODE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (t_list)))) == INTEGER_CST, ("Immediate value required by pinsrw"));
03491 UINT val = Get_Integer_Value (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (t_list))));
03492 switch (val)
03493 {
03494 case 0:
03495 *iopc = INTRN_PINSRW0;
03496 break;
03497 case 1:
03498 *iopc = INTRN_PINSRW1;
03499 break;
03500 case 2:
03501 *iopc = INTRN_PINSRW2;
03502 break;
03503 case 3:
03504 *iopc = INTRN_PINSRW3;
03505 break;
03506 default:
03507 Fail_FmtAssertion ("Invalid imm value %d to pinsrw", val);
03508
03509 }
03510 WN * args[2];
03511 for (int c=0; c<2; c++)
03512 {
03513 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (TREE_VALUE (t_list)));
03514 TYPE_ID arg_mtype = TY_mtype (arg_ty_idx);
03515 args[c] = WN_CreateParm (Mtype_comparison (arg_mtype), arg0,
03516 arg_ty_idx, WN_PARM_BY_VALUE);
03517 t_list = TREE_CHAIN (t_list);
03518 arg0 = arg1;
03519 }
03520
03521 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, MTYPE_M8I2, MTYPE_V,
03522 *iopc, 2, args);
03523 break;
03524 }
03525 case IX86_BUILTIN_PMOVMSKB:
03526 *iopc = INTRN_PMOVMSKB;
03527 break;
03528 case IX86_BUILTIN_ADDPS:
03529 *iopc = INTRN_ADDPS;
03530 break;
03531 case IX86_BUILTIN_SUBPS:
03532 *iopc = INTRN_SUBPS;
03533 break;
03534 case IX86_BUILTIN_MULPS:
03535 *iopc = INTRN_MULPS;
03536 break;
03537 case IX86_BUILTIN_DIVPS:
03538 *iopc = INTRN_DIVPS;
03539 break;
03540 case IX86_BUILTIN_ADDSS:
03541 *iopc = INTRN_ADDSS;
03542 break;
03543 case IX86_BUILTIN_SUBSS:
03544 *iopc = INTRN_SUBSS;
03545 break;
03546 case IX86_BUILTIN_MULSS:
03547 *iopc = INTRN_MULSS;
03548 break;
03549 case IX86_BUILTIN_DIVSS:
03550 *iopc = INTRN_DIVSS;
03551 break;
03552 case IX86_BUILTIN_CMPEQPS:
03553 *iopc = INTRN_CMPEQPS;
03554 break;
03555 case IX86_BUILTIN_CMPLTPS:
03556 *iopc = INTRN_CMPLTPS;
03557 break;
03558 case IX86_BUILTIN_CMPLEPS:
03559 *iopc = INTRN_CMPLEPS;
03560 break;
03561 case IX86_BUILTIN_CMPGTPS:
03562 *iopc = INTRN_CMPGTPS;
03563 break;
03564 case IX86_BUILTIN_CMPGEPS:
03565 *iopc = INTRN_CMPGEPS;
03566 break;
03567 case IX86_BUILTIN_CMPUNORDPS:
03568 *iopc = INTRN_CMPUNORDPS;
03569 break;
03570 case IX86_BUILTIN_CMPNEQPS:
03571 *iopc = INTRN_CMPNEQPS;
03572 break;
03573 case IX86_BUILTIN_CMPNLTPS:
03574 *iopc = INTRN_CMPNLTPS;
03575 break;
03576 case IX86_BUILTIN_CMPNLEPS:
03577 *iopc = INTRN_CMPNLEPS;
03578 break;
03579 case IX86_BUILTIN_CMPNGTPS:
03580 *iopc = INTRN_CMPNGTPS;
03581 break;
03582 case IX86_BUILTIN_CMPNGEPS:
03583 *iopc = INTRN_CMPNGEPS;
03584 break;
03585 case IX86_BUILTIN_CMPORDPS:
03586 *iopc = INTRN_CMPORDPS;
03587 break;
03588 case IX86_BUILTIN_CMPEQSS:
03589 *iopc = INTRN_CMPEQSS;
03590 break;
03591 case IX86_BUILTIN_CMPLTSS:
03592 *iopc = INTRN_CMPLTSS;
03593 break;
03594 case IX86_BUILTIN_CMPLESS:
03595 *iopc = INTRN_CMPLESS;
03596 break;
03597 case IX86_BUILTIN_CMPUNORDSS:
03598 *iopc = INTRN_CMPUNORDSS;
03599 break;
03600 case IX86_BUILTIN_CMPNEQSS:
03601 *iopc = INTRN_CMPNEQSS;
03602 break;
03603 case IX86_BUILTIN_CMPNLTSS:
03604 *iopc = INTRN_CMPNLTSS;
03605 break;
03606 case IX86_BUILTIN_CMPNLESS:
03607 *iopc = INTRN_CMPNLESS;
03608 break;
03609 case IX86_BUILTIN_CMPORDSS:
03610 *iopc = INTRN_CMPORDSS;
03611 break;
03612 case IX86_BUILTIN_MAXPS:
03613 *iopc = INTRN_MAXPS;
03614 break;
03615 case IX86_BUILTIN_MAXSS:
03616 *iopc = INTRN_MAXSS;
03617 break;
03618 case IX86_BUILTIN_MINPS:
03619 *iopc = INTRN_MINPS;
03620 break;
03621 case IX86_BUILTIN_MINSS:
03622 *iopc = INTRN_MINSS;
03623 break;
03624 case IX86_BUILTIN_ANDPS:
03625 *iopc = INTRN_ANDPS;
03626 break;
03627 case IX86_BUILTIN_ANDNPS:
03628 *iopc = INTRN_ANDNPS;
03629 break;
03630 case IX86_BUILTIN_ORPS:
03631 *iopc = INTRN_ORPS;
03632 break;
03633 case IX86_BUILTIN_XORPS:
03634 *iopc = INTRN_XORPS;
03635 break;
03636 case IX86_BUILTIN_MOVSS:
03637 *iopc = INTRN_MOVSS;
03638 break;
03639 case IX86_BUILTIN_MOVHLPS:
03640 *iopc = INTRN_MOVHLPS;
03641 break;
03642 case IX86_BUILTIN_MOVLHPS:
03643 *iopc = INTRN_MOVLHPS;
03644 break;
03645 case IX86_BUILTIN_UNPCKHPS:
03646 *iopc = INTRN_UNPCKHPS;
03647 break;
03648 case IX86_BUILTIN_UNPCKLPS:
03649 *iopc = INTRN_UNPCKLPS;
03650 break;
03651 case IX86_BUILTIN_RCPPS:
03652 *iopc = INTRN_RCPPS;
03653 break;
03654 case IX86_BUILTIN_RSQRTPS:
03655 *iopc = INTRN_RSQRTPS;
03656 break;
03657 case IX86_BUILTIN_SQRTPS:
03658 *iopc = INTRN_SQRTPS;
03659 break;
03660 case IX86_BUILTIN_RCPSS:
03661 *iopc = INTRN_RCPSS;
03662 break;
03663 case IX86_BUILTIN_RSQRTSS:
03664 *iopc = INTRN_RSQRTSS;
03665 break;
03666 case IX86_BUILTIN_SQRTSS:
03667 *iopc = INTRN_SQRTSS;
03668 break;
03669 case IX86_BUILTIN_SHUFPS:
03670 *iopc = INTRN_SHUFPS;
03671 break;
03672 case IX86_BUILTIN_EMMS:
03673 *iopc = INTRN_EMMS;
03674 *intrinsic_op = FALSE;
03675 break;
03676 case IX86_BUILTIN_LOADAPS:
03677 *iopc = INTRN_LOADAPS;
03678 break;
03679 case IX86_BUILTIN_STOREAPS:
03680 *iopc = INTRN_STOREAPS;
03681 *intrinsic_op = FALSE;
03682 break;
03683 case IX86_BUILTIN_PXOR128:
03684 wn = WN_Bxor (res_type, arg0, arg1);
03685 *intrinsic_op = FALSE;
03686 break;
03687 case IX86_BUILTIN_PSLLDQI128:
03688 *iopc = INTRN_PSLLDQ;
03689 break;
03690 case IX86_BUILTIN_PSRLDQI128:
03691 *iopc = INTRN_PSRLDQ;
03692 break;
03693 case IX86_BUILTIN_PSLLW128:
03694 *iopc = INTRN_PSLLW;
03695 break;
03696 case IX86_BUILTIN_PSLLD128:
03697 *iopc = INTRN_PSLLD;
03698 break;
03699 case IX86_BUILTIN_PSLLQ128:
03700 *iopc = INTRN_PSLLQ;
03701 break;
03702 case IX86_BUILTIN_PSRLW128:
03703 *iopc = INTRN_PSRLW;
03704 break;
03705 case IX86_BUILTIN_PSRLD128:
03706 *iopc = INTRN_PSRLD;
03707 break;
03708 case IX86_BUILTIN_PSRLQ128:
03709 *iopc = INTRN_PSRLQ;
03710 break;
03711 case IX86_BUILTIN_PSRAW128:
03712 *iopc = INTRN_PSRAW;
03713 break;
03714 case IX86_BUILTIN_PSRAD128:
03715 *iopc = INTRN_PSRAD;
03716 break;
03717 case IX86_BUILTIN_PSRAWI128:
03718 *iopc = INTRN_PSRAW;
03719 break;
03720 case IX86_BUILTIN_PSRADI128:
03721 *iopc = INTRN_PSRAD;
03722 break;
03723 case IX86_BUILTIN_PSLLWI128:
03724 *iopc = INTRN_PSLLW;
03725 break;
03726 case IX86_BUILTIN_PSLLDI128:
03727 *iopc = INTRN_PSLLD;
03728 break;
03729 case IX86_BUILTIN_PSLLQI128:
03730 *iopc = INTRN_PSLLQ;
03731 break;
03732 case IX86_BUILTIN_PSRLWI128:
03733 *iopc = INTRN_PSRLW;
03734 break;
03735 case IX86_BUILTIN_PSRLDI128:
03736 *iopc = INTRN_PSRLD;
03737 break;
03738 case IX86_BUILTIN_PSRLQI128:
03739 *iopc = INTRN_PSRLQ;
03740 break;
03741 case IX86_BUILTIN_MOVNTDQ:
03742 *iopc = INTRN_MOVNTDQ;
03743 *intrinsic_op = FALSE;
03744 break;
03745 case IX86_BUILTIN_LOADD:
03746 *iopc = INTRN_LOADD;
03747 break;
03748 case IX86_BUILTIN_MOVNTPS:
03749 *iopc = INTRN_MOVNTPS;
03750 *intrinsic_op = FALSE;
03751 break;
03752 case IX86_BUILTIN_SSE_ZERO:
03753 *iopc = INTRN_SSE_ZERO;
03754 *intrinsic_op = FALSE;
03755 break;
03756 case IX86_BUILTIN_CLRTI:
03757 *iopc = INTRN_CLRTI;
03758 *intrinsic_op = FALSE;
03759 break;
03760 case IX86_BUILTIN_PSHUFD:
03761 *iopc = INTRN_PSHUFD;
03762 break;
03763 case IX86_BUILTIN_LOADSS:
03764 *iopc = INTRN_LOADSS;
03765 break;
03766 case IX86_BUILTIN_DIVPD:
03767 wn = WN_Div (res_type, arg0, arg1);
03768 *intrinsic_op = FALSE;
03769 break;
03770 case IX86_BUILTIN_MULPD:
03771 wn = WN_Mpy (res_type, arg0, arg1);
03772 *intrinsic_op = FALSE;
03773 break;
03774 case IX86_BUILTIN_SQRTPD:
03775 wn = WN_Sqrt (res_type, arg0);
03776 *intrinsic_op = FALSE;
03777 break;
03778 case IX86_BUILTIN_MINPD:
03779 wn = WN_Binary (OPR_MIN, res_type, arg0, arg1);
03780 *intrinsic_op = FALSE;
03781 break;
03782 case IX86_BUILTIN_MAXPD:
03783 wn = WN_Binary (OPR_MAX, res_type, arg0, arg1);
03784 *intrinsic_op = FALSE;
03785 break;
03786 case IX86_BUILTIN_SHUFPD:
03787 *iopc = INTRN_SHUFPD;
03788 break;
03789 case IX86_BUILTIN_XORPD:
03790 *iopc = INTRN_XORPD;
03791 break;
03792 case IX86_BUILTIN_ANDPD:
03793 *iopc = INTRN_ANDPD;
03794 break;
03795 case IX86_BUILTIN_ORPD:
03796 *iopc = INTRN_ORPD;
03797 break;
03798 case IX86_BUILTIN_STORELPD:
03799 *iopc = INTRN_STORELPD;
03800 *intrinsic_op = FALSE;
03801 break;
03802 case IX86_BUILTIN_STOREHPD:
03803 *iopc = INTRN_STOREHPD;
03804 *intrinsic_op = FALSE;
03805 break;
03806 case IX86_BUILTIN_LOADLPD:
03807 *iopc = INTRN_LOADLPD;
03808 break;
03809 case IX86_BUILTIN_LOADHPD:
03810 *iopc = INTRN_LOADHPD;
03811 break;
03812 case IX86_BUILTIN_UNPCKLPD:
03813 *iopc = INTRN_UNPCKLPD;
03814 break;
03815 case IX86_BUILTIN_UNPCKHPD:
03816 *iopc = INTRN_UNPCKHPD;
03817 break;
03818 case IX86_BUILTIN_LFENCE:
03819 *iopc = INTRN_LFENCE;
03820 *intrinsic_op = FALSE;
03821 break;
03822 case IX86_BUILTIN_MFENCE:
03823 *iopc = INTRN_MFENCE;
03824 *intrinsic_op = FALSE;
03825 break;
03826 case IX86_BUILTIN_SFENCE:
03827 *iopc = INTRN_SFENCE;
03828 *intrinsic_op = FALSE;
03829 break;
03830 case IX86_BUILTIN_PSHUFW:
03831 *iopc = INTRN_PSHUFW;
03832 break;
03833 case IX86_BUILTIN_LOADDQA:
03834 *iopc = INTRN_LOADDQA;
03835 break;
03836 case IX86_BUILTIN_LOADDQU:
03837 *iopc = INTRN_LOADDQU;
03838 break;
03839 case IX86_BUILTIN_STOREDQA:
03840 *iopc = INTRN_STOREDQA;
03841 *intrinsic_op = FALSE;
03842 break;
03843 case IX86_BUILTIN_STOREDQU:
03844 *iopc = INTRN_STOREDQU;
03845 *intrinsic_op = FALSE;
03846 break;
03847 case IX86_BUILTIN_MOVNTI:
03848 *iopc = INTRN_MOVNTI;
03849 *intrinsic_op = FALSE;
03850 break;
03851
03852 default:
03853 if (Opt_Level > 0)
03854 {
03855 *iopc = INTRN_UNIMP_PURE;
03856 if (res_type == MTYPE_V)
03857 {
03858 *iopc = INTRN_UNIMP;
03859 *intrinsic_op = FALSE;
03860 }
03861 }
03862 else
03863 {
03864 *intrinsic_op = FALSE;
03865
03866
03867 wn = WN_Intconst (MTYPE_U8, 0);
03868 if (res_type != MTYPE_U8 && res_type != MTYPE_V)
03869 wn = WN_Cvt (MTYPE_U8, res_type, wn);
03870 }
03871 break;
03872 }
03873
03874
03875
03876
03877 switch (ins_code)
03878 {
03879 case IX86_BUILTIN_PSRAWI128:
03880 case IX86_BUILTIN_PSRADI128:
03881 case IX86_BUILTIN_PSLLWI128:
03882 case IX86_BUILTIN_PSLLDI128:
03883 case IX86_BUILTIN_PSLLQI128:
03884 case IX86_BUILTIN_PSRLWI128:
03885 case IX86_BUILTIN_PSRLDI128:
03886 case IX86_BUILTIN_PSRLQI128:
03887 Is_True (wn == NULL, ("WFE_target_builtins: null WN expected"));
03888 WN * args[2];
03889
03890 {
03891
03892 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (TREE_VALUE (t_list)));
03893 TYPE_ID arg_mtype = TY_mtype (arg_ty_idx);
03894 args[0] = WN_CreateParm (Mtype_comparison (arg_mtype), arg0,
03895 arg_ty_idx, WN_PARM_BY_VALUE);
03896
03897
03898 arg1 = WN_Cvt (WN_rtype(arg1), MTYPE_V16I8, arg1);
03899 arg_ty_idx = MTYPE_TO_TY_array[WN_rtype (arg1)];
03900 arg_mtype = WN_rtype (arg1);
03901 args[1] = WN_CreateParm (Mtype_comparison (arg_mtype), arg1,
03902 arg_ty_idx, WN_PARM_BY_VALUE);
03903 }
03904
03905 wn = WN_Create_Intrinsic (OPR_INTRINSIC_OP, res_type, MTYPE_V,
03906 *iopc, 2, args);
03907 break;
03908 }
03909
03910 return wn;
03911 }
03912 #endif // TARG_X8664
03913
03914 #ifdef TARG_SL
03915 BOOL
03916 Has_LDA_Node(WN* tree) {
03917 BOOL has_lda = FALSE;
03918 for(INT i = 0; i < WN_kid_count(tree); i++) {
03919 has_lda |= Has_LDA_Node(WN_kid(tree, i));
03920 if(has_lda)
03921 break;
03922 }
03923 if( WN_operator(tree) == OPR_LDA) {
03924 return TRUE;
03925 }
03926 return has_lda;
03927 }
03928
03929 BOOL
03930 Mark_LDA_Vbuf_Offset(WN* tree, INTRINSIC iopc ) {
03931
03932 BOOL has_v1buf_lda = FALSE;
03933 static vector < WN* > processed;
03934
03935 if(find(processed.begin(), processed.end(), tree) != processed.end())
03936 return has_v1buf_lda;
03937
03938 for(INT i = 0; i < WN_kid_count(tree); i++) {
03939 has_v1buf_lda |= Mark_LDA_Vbuf_Offset(WN_kid(tree, i), iopc);
03940 }
03941
03942 if(WN_operator(tree) == OPR_LDA) {
03943 if( ST_in_vbuf(WN_st(tree)) && iopc == INTRN_VBUF_OFFSET) {
03944 WN_Set_is_internal_mem_ofst(tree);
03945 Set_ST_is_vbuf_ofst(WN_st(tree));
03946 if(ST_in_v1buf(WN_st(tree)))
03947 has_v1buf_lda = TRUE;
03948 }
03949 else if(ST_in_sbuf(WN_st(tree)) && iopc == INTRN_SBUF_OFFSET) {
03950 WN_Set_is_internal_mem_ofst(tree);
03951 Set_ST_is_sbuf_ofst(WN_st(tree));
03952 }
03953 }
03954
03955 processed.push_back(tree);
03956
03957 return has_v1buf_lda;
03958 }
03959
03960
03961 BOOL
03962 May_Include_Vbuf_Offset(INTRINSIC iopc, WN* call) {
03963 switch(iopc) {
03964 case INTRN_C2_LD_V:
03965 case INTRN_C2_ST_V:
03966 case INTRN_C2_ST_G2V:
03967 case INTRN_C2_ST_G:
03968 return Has_LDA_Node(WN_kid0(WN_kid1(call)));
03969 case INTRN_C2_LD_V2G:
03970 case INTRN_C2_LD_G:
03971 return Has_LDA_Node(WN_kid0(WN_kid0(call)));
03972 default:
03973 return FALSE;
03974 }
03975 }
03976 #endif
03977
03978
03979 WN *
03980 WFE_Expand_Expr (tree exp,
03981 bool need_result,
03982 TY_IDX nop_ty_idx,
03983 TY_IDX component_ty_idx,
03984 INT64 component_offset,
03985 UINT16 field_id,
03986 bool is_bit_field,
03987 bool is_aggr_init_via_ctor
03988 #ifdef KEY
03989 , WN *target_wn
03990 #endif
03991 )
03992 {
03993 FmtAssert(exp != NULL_TREE, ("WFE_Expand_Expr: null argument"));
03994 enum tree_code code = TREE_CODE (exp);
03995 WN *wn, *wn0, *wn1, *wn2;
03996 ST *st;
03997 TY_IDX ty_idx;
03998 TY_IDX desc_ty_idx;
03999 tree arg0, arg1, arg2;
04000 #ifdef KEY
04001 static BOOL must_not_throw = FALSE;
04002 #endif
04003
04004 wn = NULL;
04005
04006 #ifdef WFE_DEBUG
04007 fprintf (stderr,
04008 "{( WFE_Expand_Expr: %s\n", Operator_From_Tree [code].name);
04009 #endif
04010
04011 switch (code)
04012 {
04013
04014 case ADDR_EXPR:
04015 wn = WFE_Address_Of(TREE_OPERAND(exp, 0));
04016 break;
04017
04018
04019
04020
04021
04022
04023 case FDESC_EXPR:
04024 {
04025 tree exp_operand = TREE_OPERAND(exp, 0);
04026 FmtAssert(TREE_CODE(exp_operand) == FUNCTION_DECL,("Unexpected Tree Code!!"));
04027 st = Get_ST (exp_operand);
04028 ty_idx = ST_type (st);
04029 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
04030 }
04031 break;
04032
04033 case FUNCTION_DECL:
04034 {
04035 st = Get_ST (exp);
04036 ty_idx = ST_type (st);
04037 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
04038 }
04039 break;
04040
04041 case TREE_LIST:
04042 {
04043 tree stmt;
04044 for (stmt = TREE_PURPOSE(exp); stmt; stmt = TREE_CHAIN(stmt))
04045 WFE_Expand_Stmt (stmt);
04046 wn = WFE_Expand_Expr (TREE_VALUE(exp));
04047 }
04048 break;
04049
04050 case DECL_STMT:
04051 {
04052 tree decl = DECL_STMT_DECL(exp);
04053 WFE_Expand_Decl (decl);
04054 wn = WFE_Expand_Expr (decl);
04055 }
04056 break;
04057
04058 case BIND_EXPR:
04059 #ifdef GPLUSPLUS_FE
04060 DevWarn ("Encountered BIND_EXPR at line %d", lineno);
04061
04062 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
04063 break;
04064 #else
04065 {
04066 INT32 i;
04067 WN *block;
04068 TYPE_ID mtype;
04069 tree t;
04070
04071 DevWarn ("Encountered BIND_EXPR at line %d", lineno);
04072
04073 for (i = wfe_bind_expr_stack_last; i >= 0; --i) {
04074
04075 if (wfe_bind_expr_stack [i].rtl_expr == TREE_OPERAND (exp, 1)) {
04076
04077 block = wfe_bind_expr_stack [i].block;
04078 t = wfe_bind_expr_stack [i].rtl_expr;
04079 wfe_bind_expr_stack [i] = wfe_bind_expr_stack [wfe_bind_expr_stack_last];
04080 --wfe_bind_expr_stack_last;
04081 break;
04082 }
04083 }
04084
04085 FmtAssert (i >= 0,
04086 ("BIND_EXPR: did not find tree"));
04087 ty_idx = Get_TY (TREE_TYPE(t));
04088 mtype = TY_mtype (ty_idx);
04089 if (mtype == MTYPE_V) {
04090 WFE_Stmt_Append (block, Get_Srcpos ());
04091 break;
04092 }
04093 else {
04094 wn0 = block;
04095 wn1 = WN_COPY_Tree (WN_last (wn0));
04096 WN_DELETE_FromBlock (wn0, WN_last (wn0));
04097 WFE_Stmt_Append (wn0, Get_Srcpos ());
04098 if (nop_ty_idx == 0 && component_ty_idx == 0) {
04099 wn = WN_kid0 (wn1);
04100 break;
04101 }
04102 if (WN_operator (WN_kid0 (wn1)) == OPR_LDID)
04103 st = WN_st (WN_kid0 (wn1));
04104 else {
04105 st = Gen_Temp_Symbol (ty_idx, "__bind_expr");
04106 #ifdef KEY
04107 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
04108 #endif
04109 WFE_Set_ST_Addr_Saved (WN_kid0 (wn1));
04110 wn0 = WN_Stid (mtype, 0, st, ty_idx, WN_kid0 (wn1));
04111 WFE_Stmt_Append (wn0, Get_Srcpos ());
04112 }
04113 }
04114 }
04115
04116 #endif
04117
04118 case TARGET_EXPR:
04119 {
04120 tree opnd0 = TREE_OPERAND(exp, 0);
04121 st = NULL;
04122 TY_IDX ty;
04123 TYPE_ID mtype;
04124 #ifdef KEY
04125
04126
04127 if (target_wn != NULL) {
04128 if (WN_operator(target_wn) == OPR_LDA) {
04129 FmtAssert(TREE_CODE(opnd0) != INDIRECT_REF,
04130 ("WFE_Expand_Expr: write target mismtach"));
04131 set_DECL_ST(opnd0, WN_st(target_wn));
04132 } else if (WN_operator(target_wn) == OPR_LDID) {
04133
04134
04135 if (TREE_CODE(opnd0) == VAR_DECL) {
04136 tree ptr_var = build_decl(VAR_DECL, NULL_TREE,
04137 build_pointer_type(TREE_TYPE(opnd0)));
04138 TREE_SET_CODE(opnd0, INDIRECT_REF);
04139 TREE_OPERAND(opnd0, 0) = ptr_var;
04140 set_DECL_ST(ptr_var, WN_st(target_wn));
04141 }
04142 }
04143 }
04144
04145
04146
04147 if (TREE_CODE(opnd0) != INDIRECT_REF)
04148 #endif
04149 {
04150 st = Get_ST (TREE_OPERAND(exp, 0));
04151 ty = ST_type(st);
04152 mtype = TY_mtype (ty);
04153 }
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175
04176 tree t = TREE_OPERAND(exp, 1);
04177 #ifdef KEY
04178 if (t == NULL_TREE) {
04179 t = TREE_OPERAND(exp, 3);
04180 FmtAssert(t != NULL_TREE,
04181 ("WFE_Expand_Expr: no initializer found for TARGET_EXPR"));
04182 }
04183 #endif
04184 if (TREE_CODE(t) == TARGET_EXPR)
04185 TREE_OPERAND(t, 2) = 0;
04186 if (TREE_CODE(t) == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P(t)) {
04187 tree args = TREE_OPERAND(t, 1);
04188 TREE_VALUE(args) = TREE_OPERAND(exp, 0);
04189 WFE_Expand_Expr (t, false, 0, 0, 0, 0, false, true);
04190 }
04191 else {
04192 #ifdef KEY
04193
04194
04195
04196
04197
04198
04199
04200 if (TREE_CODE(opnd0) == INDIRECT_REF) {
04201 if (TREE_CODE_CLASS(TREE_CODE(TREE_OPERAND(opnd0,0))) != 'd') {
04202 WN * target_wn = WFE_Address_Of (opnd0);
04203 WFE_Expand_Expr (t, TRUE ,
04204 0, 0, 0, 0, FALSE, FALSE, target_wn);
04205 }
04206 else {
04207 ST *st = Get_ST(TREE_OPERAND(opnd0, 0));
04208 WN *ldid_wn = WN_Ldid (Pointer_Mtype, 0, st, ST_type(st));
04209 WN *result_wn = WFE_Expand_Expr (t, TRUE, 0, 0, 0, 0, FALSE, FALSE,
04210 ldid_wn);
04211
04212
04213
04214 if (result_wn &&
04215 !(WN_operator(result_wn) == OPR_ILOAD &&
04216 WN_operator(WN_kid0(result_wn)) == OPR_LDID &&
04217 WN_st(WN_kid0(result_wn)) == st)) {
04218 WFE_Stmt_Append(WN_Istore(WN_rtype(result_wn), 0, ST_type(st),
04219 WN_CopyNode(ldid_wn), result_wn),
04220 Get_Srcpos());
04221 }
04222 }
04223 }
04224
04225
04226
04227
04228
04229
04230
04231 else if (TY_return_in_mem(Get_TY(TREE_TYPE(t))) ||
04232 ((TY_mtype (Get_TY(TREE_TYPE(t))) == MTYPE_M) &&
04233 (TREE_CODE(t) == COND_EXPR))) {
04234 if (TREE_CODE(t) == VAR_DECL ||
04235 TREE_CODE(t) == PARM_DECL) {
04236
04237
04238 WN *rhs_wn = WFE_Expand_Expr (t);
04239 tree type = TREE_TYPE(TREE_OPERAND(exp, 0));
04240 Is_True(!WFE_has_copy_constructor(type),
04241 ("WFE_Expand_Expr: type require copy constructor"));
04242 WFE_Stmt_Append(WN_Stid (mtype, ST_ofst(st), st, ty, rhs_wn),
04243 Get_Srcpos());
04244 } else {
04245
04246
04247 WN *target_wn = WN_Lda (Pointer_Mtype, 0, st, 0);
04248 WN *result_wn = WFE_Expand_Expr (t, TRUE, 0, 0, 0, 0, FALSE,
04249 FALSE, target_wn);
04250
04251
04252 if (result_wn) {
04253
04254
04255 if (WN_operator(result_wn) == OPR_ILOAD) {
04256 WFE_Stmt_Append(WN_Stid (mtype, ST_ofst(st), st, ty,
04257 result_wn), Get_Srcpos());
04258 } else if (WN_operator(result_wn) == OPR_CSELECT) {
04259 WN *wn = WN_CreateEval(result_wn);
04260 WFE_Stmt_Append(wn, Get_Srcpos());
04261 }
04262 }
04263 }
04264 } else {
04265
04266 WN * init = WFE_Expand_Expr (t);
04267 if (WN_operator (init) == OPR_LDA)
04268 WFE_Set_ST_Addr_Saved (init);
04269 WFE_Stmt_Append(WN_Stid (mtype, ST_ofst(st), st, ty, init),
04270 Get_Srcpos());
04271 }
04272 #else
04273 WFE_Stmt_Append(WN_Stid (mtype, ST_ofst(st), st, ty,
04274 WFE_Expand_Expr (t)),
04275 Get_Srcpos());
04276 #endif
04277 }
04278 if (TREE_OPERAND(exp, 2)
04279 #ifdef KEY
04280
04281 && TREE_LANG_FLAG_7 (exp)
04282 #endif
04283 )
04284 #ifdef KEY
04285 Push_Temp_Cleanup(TREE_OPERAND(exp, 2), true, CLEANUP_EH_ONLY (exp));
04286 #else
04287 Push_Temp_Cleanup(TREE_OPERAND(exp, 2), true);
04288 #endif
04289
04290 #ifdef KEY
04291
04292
04293
04294
04295
04296 if (TREE_CODE(opnd0) == INDIRECT_REF) {
04297 if (TREE_CODE_CLASS(TREE_CODE(TREE_OPERAND(opnd0,0))) == 'd') {
04298 ST *st = Get_ST(TREE_OPERAND(opnd0, 0));
04299 TY_IDX ty_idx = Get_TY (TREE_TYPE(exp));
04300 WN *ldid_wn = WN_Ldid (Pointer_Mtype, 0, st, ST_type(st));
04301 wn = WN_Iload(TY_mtype(ty_idx), 0, ty_idx, ldid_wn);
04302 break;
04303 }
04304 else {
04305 wn = WFE_Expand_Expr(opnd0);
04306 break;
04307 }
04308 }
04309 #endif
04310 }
04311
04312 case CONSTRUCTOR:
04313 #ifdef KEY
04314
04315
04316
04317
04318 if (!need_result &&
04319 !TREE_SIDE_EFFECTS(exp)) {
04320 return NULL;
04321 }
04322 #endif
04323
04324 case PARM_DECL:
04325 case VAR_DECL:
04326 {
04327 UINT xtra_BE_ofst = 0;
04328 PREG_NUM preg_num = 0;
04329 desc_ty_idx = component_ty_idx;
04330 TY_IDX hi_ty_idx = Get_TY (TREE_TYPE(exp));
04331 if (desc_ty_idx == 0)
04332 desc_ty_idx = hi_ty_idx;
04333
04334 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
04335 ty_idx = desc_ty_idx;
04336 else {
04337 ty_idx = nop_ty_idx;
04338 if (ty_idx == 0)
04339 ty_idx = desc_ty_idx;
04340 }
04341
04342 UINT cvtl_size = 0;
04343 if (! is_bit_field) {
04344 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
04345 if (Target_Byte_Sex == BIG_ENDIAN)
04346 xtra_BE_ofst = TY_size(desc_ty_idx) - TY_size(ty_idx);
04347 cvtl_size = TY_size(ty_idx) * 8;
04348 ty_idx = desc_ty_idx;
04349 }
04350 }
04351 else {
04352 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
04353 ty_idx = desc_ty_idx;
04354 }
04355
04356 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
04357 TYPE_ID desc = TY_mtype(desc_ty_idx);
04358 if (MTYPE_is_integral(desc)) {
04359 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
04360 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
04361 is_bit_field)
04362 rtype = Mtype_TransferSign(desc, rtype);
04363 else desc = Mtype_TransferSign(rtype, desc);
04364 }
04365 }
04366
04367 if (TREE_THIS_VOLATILE(exp))
04368 Set_TY_is_volatile(ty_idx);
04369
04370 if (code == PARM_DECL || code == VAR_DECL) {
04371 st = Get_ST (exp);
04372 if (ST_assigned_to_dedicated_preg (st))
04373 Set_TY_is_volatile(ty_idx);
04374 }
04375 else
04376 if (code == CONSTRUCTOR) {
04377 DevWarn ("Encountered CONSTRUCTOR at line %d", lineno);
04378 st = WFE_Generate_Temp_For_Initialized_Aggregate (exp, "");
04379 }
04380
04381 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
04382 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
04383
04384 #ifdef TARG_X8664
04385
04386
04387 if (MTYPE_is_vector (rtype) || MTYPE_is_vector (desc))
04388 desc = rtype;
04389 #endif
04390
04391 wn = WN_CreateLdid (OPR_LDID, rtype,
04392 is_bit_field ? MTYPE_BS : desc,
04393 ST_ofst(st)+component_offset+xtra_BE_ofst+preg_num, st,
04394 field_id != 0 ? hi_ty_idx : ty_idx, field_id);
04395 if (cvtl_size != 0)
04396 wn = WN_CreateCvtl(OPR_CVTL, rtype, MTYPE_V, cvtl_size, wn);
04397 }
04398 break;
04399
04400 case CONST_DECL:
04401 wn = WFE_Expand_Expr(DECL_INITIAL(exp), need_result);
04402 break;
04403
04404 case INTEGER_CST:
04405 {
04406 ty_idx = Get_TY (TREE_TYPE(exp));
04407 TYPE_ID mtyp = TY_mtype(ty_idx);
04408 mtyp = (mtyp == MTYPE_V) ? MTYPE_I4 : Widen_Mtype(mtyp);
04409 wn = WN_Intconst(mtyp, Get_Integer_Value(exp));
04410 }
04411 break;
04412
04413 case PTRMEM_CST:
04414 {
04415 wn = WFE_Expand_Expr(cplus_expand_constant (exp),
04416 need_result, nop_ty_idx, component_ty_idx,
04417 component_offset, field_id);
04418 }
04419 break;
04420
04421 #ifdef KEY // Use the code from kgccfe, which is newer and can handle
04422
04423 case REAL_CST:
04424 {
04425 TCON tcon;
04426 ty_idx = Get_TY (TREE_TYPE(exp));
04427 #if (defined(TARG_IA32) || defined(TARG_X8664)) && !defined(REAL_ARITHMETIC)
04428 tcon = Host_To_Targ_Float (TY_mtype (ty_idx), TREE_REAL_CST(exp));
04429 #else
04430 REAL_VALUE_TYPE real = TREE_REAL_CST(exp);
04431 #ifndef TARG_IA64
04432 int rval;
04433
04434 long rbuf [4];
04435 #ifdef KEY
04436 INT32 rbuf_w[4];
04437 INT32 i;
04438 #endif
04439 #endif
04440 switch (TY_mtype (ty_idx)) {
04441 #ifdef TARG_IA64
04442 case MTYPE_F4:
04443 tcon = Host_To_Targ_Float_4 (MTYPE_F4,
04444 WFE_Convert_Internal_Real_to_IEEE_Single(real));
04445 break;
04446
04447 case MTYPE_F8:
04448 tcon = Host_To_Targ_Float (MTYPE_F8,
04449 WFE_Convert_Internal_Real_to_IEEE_Double(real));
04450 break;
04451
04452 case MTYPE_F10:
04453 tcon = Host_To_Targ_Float_10 (MTYPE_F10,
04454 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real));
04455 break;
04456
04457 case MTYPE_FQ:
04458 tcon = Host_To_Targ_Quad (WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real));
04459 break;
04460
04461 #else
04462 case MTYPE_F4:
04463 REAL_VALUE_TO_TARGET_SINGLE (real, rval);
04464 tcon = Host_To_Targ_Float_4 (MTYPE_F4, *(float *) &rval);
04465 break;
04466 case MTYPE_F8:
04467 REAL_VALUE_TO_TARGET_DOUBLE (real, rbuf);
04468 #ifdef KEY
04469 WFE_Convert_To_Host_Order(rbuf);
04470 for (i = 0; i < 4; i++)
04471 rbuf_w[i] = rbuf[i];
04472 tcon = Host_To_Targ_Float (MTYPE_F8, *(double *) &rbuf_w);
04473 #else
04474 tcon = Host_To_Targ_Float (MTYPE_F8, *(double *) &rbuf);
04475 #endif
04476 break;
04477 #if defined(TARG_IA32) || defined(TARG_X8664)
04478 case MTYPE_FQ:
04479 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, rbuf);
04480 for (i = 0; i < 4; i++)
04481 rbuf_w[i] = rbuf[i];
04482 tcon = Host_To_Targ_Quad (*(long double *) &rbuf_w);
04483 break;
04484 #endif
04485 #endif
04486 default:
04487 FmtAssert(FALSE, ("WFE_Expand_Expr unexpected float size"));
04488 break;
04489 }
04490 #endif
04491 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04492 wn = WN_CreateConst (OPR_CONST, TY_mtype (ty_idx), MTYPE_V, st);
04493 }
04494 break;
04495
04496 case COMPLEX_CST:
04497 {
04498 TCON tcon;
04499 ty_idx = Get_TY (TREE_TYPE(exp));
04500 #if (defined(TARG_IA32) || defined(TARG_X8664)) && !defined(REAL_ARITHMETIC)
04501 tcon = Host_To_Targ_Complex (TY_mtype (ty_idx),
04502 TREE_REAL_CST(TREE_REALPART(exp)),
04503 TREE_REAL_CST(TREE_IMAGPART(exp)));
04504 #else
04505 #ifdef TARG_IA64
04506 REAL_VALUE_TYPE real = TREE_REAL_CST(TREE_REALPART(exp));
04507 REAL_VALUE_TYPE imag = TREE_REAL_CST(TREE_IMAGPART(exp));
04508
04509 switch (TY_mtype (ty_idx)) {
04510 case MTYPE_C4:
04511 tcon = Host_To_Targ_Complex_4 (MTYPE_C4,
04512 WFE_Convert_Internal_Real_to_IEEE_Single(real),
04513 WFE_Convert_Internal_Real_to_IEEE_Single(imag));
04514 break;
04515
04516 case MTYPE_C8:
04517 tcon = Host_To_Targ_Complex (MTYPE_C8,
04518 WFE_Convert_Internal_Real_to_IEEE_Double(real),
04519 WFE_Convert_Internal_Real_to_IEEE_Double(imag));
04520 break;
04521
04522 case MTYPE_C10:
04523 tcon = Host_To_Targ_Complex_10 (MTYPE_C10,
04524 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real),
04525 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(imag));
04526 break;
04527
04528 case MTYPE_CQ:
04529 tcon = Host_To_Targ_Complex_Quad (
04530 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real),
04531 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(imag));
04532 break;
04533 #else
04534
04535 REAL_VALUE_TYPE real = TREE_REAL_CST(TREE_REALPART(exp));
04536 REAL_VALUE_TYPE imag = TREE_REAL_CST(TREE_IMAGPART(exp));
04537 int rval;
04538 int ival;
04539 long rbuf [4];
04540 long ibuf [4];
04541 #ifdef KEY
04542 INT32 rbuf_w [4];
04543 INT32 ibuf_w [4];
04544 INT32 i;
04545 #endif
04546 switch (TY_mtype (ty_idx)) {
04547 case MTYPE_C4:
04548 REAL_VALUE_TO_TARGET_SINGLE (real, rval);
04549 REAL_VALUE_TO_TARGET_SINGLE (imag, ival);
04550 tcon = Host_To_Targ_Complex_4 (MTYPE_C4,
04551 *(float *) &rval,
04552 *(float *) &ival);
04553 break;
04554 case MTYPE_C8:
04555 REAL_VALUE_TO_TARGET_DOUBLE (real, rbuf);
04556 REAL_VALUE_TO_TARGET_DOUBLE (imag, ibuf);
04557 #ifdef KEY
04558 WFE_Convert_To_Host_Order(rbuf);
04559 WFE_Convert_To_Host_Order(ibuf);
04560 for (i = 0; i < 4; i++) {
04561 rbuf_w[i] = rbuf[i];
04562 ibuf_w[i] = ibuf[i];
04563 }
04564 tcon = Host_To_Targ_Complex (MTYPE_C8,
04565 *(double *) &rbuf_w,
04566 *(double *) &ibuf_w);
04567 #else
04568 tcon = Host_To_Targ_Complex (MTYPE_C8,
04569 *(double *) &rbuf,
04570 *(double *) &ibuf);
04571 #endif
04572 break;
04573 #ifdef KEY
04574 case MTYPE_CQ:
04575 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, rbuf);
04576 REAL_VALUE_TO_TARGET_LONG_DOUBLE (imag, ibuf);
04577 WFE_Convert_To_Host_Order(rbuf);
04578 WFE_Convert_To_Host_Order(ibuf);
04579 for (i = 0; i < 4; i++) {
04580 rbuf_w[i] = rbuf[i];
04581 ibuf_w[i] = ibuf[i];
04582 }
04583 tcon = Host_To_Targ_Complex_Quad( *(long double *) &rbuf_w,
04584 *(long double *) &ibuf_w );
04585 break;
04586 #endif
04587 #endif
04588 default:
04589 FmtAssert(FALSE, ("WFE_Expand_Expr unexpected float size"));
04590 break;
04591 }
04592 #endif
04593 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04594 wn = WN_CreateConst (OPR_CONST, TY_mtype (ty_idx), MTYPE_V, st);
04595 }
04596 break;
04597
04598 #else // KEY
04599
04600 case REAL_CST:
04601 {
04602 TCON tcon;
04603 ty_idx = Get_TY (TREE_TYPE(exp));
04604 tcon = Host_To_Targ_Float (TY_mtype (ty_idx), TREE_REAL_CST(exp));
04605 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04606 wn = WN_CreateConst (OPR_CONST, TY_mtype (ty_idx), MTYPE_V, st);
04607 }
04608 break;
04609
04610 case COMPLEX_CST:
04611 {
04612 TCON tcon;
04613 ty_idx = Get_TY (TREE_TYPE(exp));
04614 tcon = Host_To_Targ_Complex (TY_mtype (ty_idx),
04615 TREE_REAL_CST(TREE_REALPART(exp)),
04616 TREE_REAL_CST(TREE_IMAGPART(exp)));
04617 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04618 wn = WN_CreateConst (OPR_CONST, TY_mtype (ty_idx), MTYPE_V, st);
04619 }
04620 break;
04621 #endif // KEY
04622
04623
04624 case STRING_CST:
04625 {
04626 TCON tcon;
04627 tcon = Host_To_Targ_String (MTYPE_STRING,
04628 const_cast<char*>TREE_STRING_POINTER(exp),
04629 TREE_STRING_LENGTH(exp));
04630 ty_idx = Get_TY(TREE_TYPE(exp));
04631 st = New_Const_Sym (Enter_tcon (tcon), ty_idx);
04632 wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
04633 TREE_STRING_ST (exp) = st;
04634 }
04635 break;
04636
04637
04638 case BIT_NOT_EXPR:
04639 case ABS_EXPR:
04640 case NEGATE_EXPR:
04641 case REALPART_EXPR:
04642 case IMAGPART_EXPR:
04643 {
04644 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04645 wn = WN_Unary (Operator_From_Tree [code].opr,
04646 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))), wn0);
04647 #ifdef KEY // bug 2648
04648 TYPE_ID mtyp = TY_mtype(Get_TY(TREE_TYPE(exp)));
04649 if (mtyp != WN_rtype(wn))
04650 wn = WN_CreateCvtl (OPR_CVTL, WN_rtype(wn), MTYPE_V,
04651 MTYPE_size_min(mtyp), wn);
04652 #endif
04653 }
04654 break;
04655
04656 case TRUTH_NOT_EXPR:
04657 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04658 wn1 = WN_Intconst (MTYPE_I4, 0);
04659 wn = WN_Relational (OPR_EQ, MTYPE_I4, wn0, wn1);
04660 break;
04661
04662 case CONJ_EXPR:
04663 {
04664 ty_idx = Get_TY (TREE_TYPE(exp));
04665 TYPE_ID complex_mtype = TY_mtype(ty_idx);
04666 TYPE_ID float_mtype = Mtype_complex_to_real (complex_mtype);
04667 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04668 if (WN_has_side_effects (wn0)) {
04669 ST *preg_st;
04670 PREG_NUM preg;
04671 preg_st = MTYPE_To_PREG(complex_mtype);
04672 preg = Create_Preg (complex_mtype, NULL);
04673 wn0 = WN_Stid (complex_mtype, preg, preg_st, ty_idx, wn0);
04674 WFE_Stmt_Append (wn0, Get_Srcpos());
04675 wn0 = WN_Ldid (complex_mtype, preg, preg_st, ty_idx);
04676 }
04677 #ifdef KEY
04678
04679 wn = WN_Binary (OPR_COMPLEX, complex_mtype,
04680 WN_Unary (OPR_REALPART, float_mtype, wn0),
04681 WN_Unary (OPR_NEG, float_mtype,
04682 WN_Unary (OPR_IMAGPART, float_mtype, wn0)));
04683 #else
04684 wn = WN_Binary (OPR_COMPLEX, complex_mtype,
04685 WN_Unary (OPR_REALPART, float_mtype, wn0),
04686 WN_Unary (OPR_NEG, float_mtype,
04687 WN_Unary (OPR_REALPART, float_mtype, wn0)));
04688 #endif
04689 }
04690 break;
04691
04692 case NOP_EXPR:
04693 {
04694 ty_idx = Get_TY (TREE_TYPE(exp));
04695 TYPE_ID mtyp = TY_mtype(ty_idx);
04696
04697 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), TRUE,
04698 (mtyp == MTYPE_M) ? 0 : ty_idx,
04699 component_ty_idx, component_offset,
04700 field_id, is_bit_field
04701 #ifdef KEY
04702 , FALSE, target_wn
04703 #endif
04704 );
04705 if (mtyp == MTYPE_V)
04706 break;
04707 if (mtyp == MTYPE_M)
04708 break;
04709 if (MTYPE_is_integral(mtyp) && MTYPE_is_integral(WN_rtype(wn))) {
04710
04711
04712 if (MTYPE_size_min(mtyp) == 64 &&
04713 MTYPE_size_min(WN_rtype(wn)) == 32 &&
04714 MTYPE_is_signed(mtyp) != MTYPE_is_signed(WN_rtype(wn))) {
04715 mtyp = MTYPE_complement(mtyp);
04716 }
04717
04718 if (MTYPE_size_min(mtyp) < MTYPE_size_min(WN_rtype(wn))) {
04719 if (MTYPE_size_min(mtyp) != 32)
04720 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp), MTYPE_V,
04721 MTYPE_size_min(mtyp), wn);
04722 else wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04723 }
04724 else {
04725 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(TREE_OPERAND (exp, 0)));
04726 TYPE_ID mtyp0 = TY_mtype(ty_idx0);
04727
04728 if (MTYPE_size_min(mtyp) > MTYPE_size_min(mtyp0) &&
04729 ! Has_Subsumed_Cvtl(WN_operator(wn)))
04730 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp0), MTYPE_V,
04731 MTYPE_size_min(mtyp0), wn);
04732
04733 if (MTYPE_size_min(mtyp) > MTYPE_size_min(WN_rtype(wn)))
04734 wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04735 else {
04736 if (mtyp != WN_rtype(wn))
04737 wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04738 }
04739 }
04740 }
04741 else {
04742 if (mtyp != WN_rtype(wn))
04743 wn = WN_Cvt(WN_rtype(wn), mtyp, wn);
04744 }
04745 }
04746 break;
04747
04748 case COMPONENT_REF:
04749 {
04750 INT64 ofst;
04751 arg0 = TREE_OPERAND (exp, 0);
04752 arg1 = TREE_OPERAND (exp, 1);
04753
04754
04755 (void) Get_TY(TREE_TYPE(arg0));
04756
04757 if (component_ty_idx == 0)
04758 ty_idx = Get_TY (TREE_TYPE(exp));
04759 else ty_idx = component_ty_idx;
04760 if (DECL_BIT_FIELD(arg1))
04761 is_bit_field = TRUE;
04762
04763 if (! is_bit_field &&
04764 component_ty_idx == 0) {
04765
04766 tree sizenode = DECL_SIZE(arg1);
04767 if (
04768 #ifdef KEY
04769 sizenode &&
04770 #endif
04771 TREE_CODE(sizenode) == INTEGER_CST) {
04772 TYPE_ID c_mtyp = TY_mtype(ty_idx);
04773 INT32 bsize = Get_Integer_Value(sizenode);
04774 if (MTYPE_size_min(c_mtyp) > bsize) {
04775 FmtAssert(MTYPE_is_integral(c_mtyp),
04776 ("COMPONENT_REF: integer type expected at inconsistent field size"));
04777 c_mtyp = Mtype_AlignmentClass(bsize >> 3, MTYPE_type_class(c_mtyp));
04778 ty_idx = MTYPE_To_TY(c_mtyp);
04779 }
04780 }
04781 }
04782
04783 if (! is_bit_field)
04784 ofst = (BITSPERBYTE * Get_Integer_Value(DECL_FIELD_OFFSET(arg1)) +
04785 Get_Integer_Value(DECL_FIELD_BIT_OFFSET(arg1)))
04786 / BITSPERBYTE;
04787 else ofst = 0;
04788 #ifdef KEY
04789 FmtAssert (DECL_FIELD_ID(arg1) != 0,
04790 ("WFE_Expand_Expr: DECL_FIELD_ID used but not set"));
04791
04792
04793
04794
04795
04796 if (WFE_Call_Returns_Ptr_To_Member_Func(arg0)) {
04797 tree field0 = TYPE_FIELDS(TREE_TYPE(arg0));
04798
04799
04800 TYPE_ID desc = TY_mtype(Get_TY(TREE_TYPE(field0)));
04801 wn = WFE_Expand_Ptr_To_Member_Func_Call_Expr (arg0, nop_ty_idx,
04802 Pointer_Mtype, desc, component_offset,
04803 field_id + DECL_FIELD_ID(arg1));
04804 } else
04805 #endif
04806 wn = WFE_Expand_Expr (arg0, TRUE, nop_ty_idx, ty_idx, ofst+component_offset,
04807 field_id + DECL_FIELD_ID(arg1), is_bit_field);
04808
04809 #ifdef KEY
04810
04811
04812
04813
04814
04815
04816
04817
04818
04819
04820
04821
04822 if (TREE_CODE(arg0) == MODIFY_EXPR || TREE_CODE(arg0) == NON_LVALUE_EXPR) {
04823 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
04824 TYPE_ID desc = TY_mtype(ty_idx);
04825 if (WN_operator(wn) == OPR_ILOAD) {
04826 #ifdef PATHSCALE_MERGE
04827 wn = WN_CreateIload(OPR_ILOAD, rtype, desc,
04828 WN_offset(wn) + ofst + component_offset, ty_idx,
04829 WN_load_addr_ty(wn), WN_kid0(wn),
04830 WN_field_id(wn)+field_id + DECL_FIELD_ID(arg1));
04831 #else
04832 wn = WN_CreateIload(OPR_ILOAD, rtype, desc,
04833 ofst + component_offset, ty_idx,
04834 Make_Pointer_Type (ty_idx, FALSE), WN_kid0(wn),
04835 field_id + DECL_FIELD_ID(arg1));
04836 #endif
04837 }
04838 else if (WN_operator(wn) == OPR_LDID) {
04839 WN_set_rtype(wn, rtype);
04840 WN_set_desc(wn, desc);
04841 WN_offset(wn) = WN_offset(wn)+ofst+component_offset;
04842 WN_set_ty(wn, ty_idx);
04843
04844
04845 if (TY_kind(ty_idx) != KIND_STRUCT)
04846 WN_set_field_id (wn, 0);
04847 else
04848 #ifdef PATHSCALE_MERGE
04849 WN_set_field_id(wn, WN_field_id(wn)+field_id + DECL_FIELD_ID(arg1));
04850 #else
04851 WN_set_field_id(wn, field_id + DECL_FIELD_ID(arg1));
04852 #endif
04853 }
04854 }
04855
04856
04857 else if (TREE_CODE(arg0) == COND_EXPR &&
04858 WN_operator(wn) == OPR_CSELECT &&
04859 WN_rtype(wn) == MTYPE_M)
04860 {
04861
04862 Is_True (WN_rtype (WN_kid1(wn)) == MTYPE_M, ("Unexpected type"));
04863
04864 TY_IDX temp_ty_idx = WN_ty (WN_kid1 (wn));
04865
04866 if (WN_field_id (WN_kid1 (wn)))
04867 temp_ty_idx = get_field_type (temp_ty_idx,
04868 WN_field_id (WN_kid1 (wn)));
04869
04870 ST * temp = Gen_Temp_Symbol (temp_ty_idx, ".mcselect_store");
04871 wn = WN_Stid (MTYPE_M, 0, temp, temp_ty_idx, wn);
04872 WFE_Stmt_Append (wn, Get_Srcpos());
04873
04874 wn = WN_Ldid (TY_mtype (ty_idx), ofst + component_offset,
04875 temp, temp_ty_idx, field_id + DECL_FIELD_ID(arg1));
04876 }
04877 #endif
04878 }
04879 break;
04880
04881 case INDIRECT_REF:
04882 {
04883 UINT xtra_BE_ofst = 0;
04884 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04885
04886 TY_IDX hi_ty_idx = Get_TY(TREE_TYPE(exp));
04887
04888 desc_ty_idx = component_ty_idx;
04889 if (desc_ty_idx == 0)
04890 desc_ty_idx = hi_ty_idx;
04891
04892 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
04893 ty_idx = desc_ty_idx;
04894 else {
04895 ty_idx = nop_ty_idx;
04896 if (ty_idx == 0)
04897 ty_idx = desc_ty_idx;
04898 }
04899
04900 if (! is_bit_field) {
04901 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
04902 if (Target_Byte_Sex == BIG_ENDIAN)
04903 xtra_BE_ofst = TY_size(desc_ty_idx) - TY_size(ty_idx);
04904 desc_ty_idx = ty_idx;
04905 }
04906 }
04907 else {
04908 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
04909 ty_idx = desc_ty_idx;
04910 }
04911
04912 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
04913 TYPE_ID desc = TY_mtype(desc_ty_idx);
04914 if (MTYPE_is_integral(desc)) {
04915 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
04916 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
04917 is_bit_field)
04918 rtype = Mtype_TransferSign(desc, rtype);
04919 else desc = Mtype_TransferSign(rtype, desc);
04920 }
04921 }
04922
04923 if (TREE_THIS_VOLATILE(exp))
04924 Set_TY_is_volatile(hi_ty_idx);
04925
04926 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
04927 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
04928
04929 if (!WFE_Keep_Zero_Length_Structs &&
04930 rtype == MTYPE_M &&
04931 TY_size (hi_ty_idx) == 0) {
04932 if (WN_has_side_effects (wn0)) {
04933 wn = WN_CreateEval (wn0);
04934 WFE_Stmt_Append (wn, Get_Srcpos());
04935 }
04936 wn = NULL;
04937 }
04938 else {
04939
04940 if (WN_operator (wn0) == OPR_LDA &&
04941 ST_class (WN_st (wn0)) == CLASS_CONST &&
04942 is_bit_field == FALSE &&
04943 field_id == 0) {
04944 st = WN_st (wn0);
04945 TCON tcon = Tcon_Table [ST_tcon (st)];
04946 if (TCON_ty (tcon) == MTYPE_STRING &&
04947 TY_size (Be_Type_Tbl (desc)) == 1) {
04948 mUINT32 len = Targ_String_Length (tcon);
04949 mUINT64 offset = component_offset + xtra_BE_ofst + WN_offset (wn0);
04950 if (offset <= len &&
04951 desc == MTYPE_U1 &&
04952 (rtype == MTYPE_U4 || rtype == MTYPE_U8)) {
04953 unsigned char *cp = (unsigned char *) Targ_String_Address (tcon);
04954 unsigned long long val = cp [offset];
04955 wn = WN_Intconst (rtype, val);
04956 break;
04957 }
04958 else
04959 if (offset <= len &&
04960 desc == MTYPE_I1 &&
04961 (rtype == MTYPE_I4 || rtype == MTYPE_I8)) {
04962 signed char *cp = (signed char *) Targ_String_Address (tcon);
04963 signed long long val = cp [offset];
04964 wn = WN_Intconst (rtype, val);
04965 break;
04966 }
04967 }
04968 }
04969 if (need_result)
04970 wn = WN_CreateIload(OPR_ILOAD, rtype,
04971 is_bit_field ? MTYPE_BS : desc,
04972 component_offset+xtra_BE_ofst,
04973 field_id != 0 ? hi_ty_idx : ty_idx,
04974 Make_Pointer_Type (hi_ty_idx, FALSE),
04975 wn0, field_id);
04976 else
04977 if (WN_has_side_effects (wn0))
04978 wn = wn0;
04979 }
04980 }
04981 break;
04982
04983 case CONVERT_EXPR:
04984 case FLOAT_EXPR:
04985 {
04986 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
04987 ty_idx = Get_TY (TREE_TYPE(exp));
04988 TYPE_ID mtyp = TY_mtype(ty_idx);
04989 if (mtyp == MTYPE_V)
04990 wn = wn0;
04991 else {
04992 mtyp = Widen_Mtype(TY_mtype(ty_idx));
04993 if (mtyp == WN_rtype(wn0) || mtyp == MTYPE_V)
04994 wn = wn0;
04995 else {
04996 #ifdef KEY // prevent zero extension when converting to 64-bit address type
04997 if (TREE_CODE(TREE_TYPE(exp)) == POINTER_TYPE &&
04998 MTYPE_byte_size(FE_Pointer_Type_To_Mtype()) == 8) {
04999 if (WN_operator(wn0) == OPR_CVT && WN_desc(wn0) == MTYPE_U4) {
05000 WN_set_desc(wn0, MTYPE_I4);
05001 wn = WN_Cvt(WN_rtype(wn0), mtyp, wn0);
05002 }
05003 else if (MTYPE_byte_size(WN_rtype(wn0) == 4))
05004 wn = WN_Cvt(MTYPE_I4, mtyp, wn0);
05005 else wn = WN_Cvt(WN_rtype(wn0), mtyp, wn0);
05006 }
05007 else
05008 #endif
05009 wn = WN_Cvt(WN_rtype(wn0), mtyp, wn0);
05010
05011 if (WN_opcode(wn) == OPC_I4U4CVT ||
05012 WN_opcode(wn) == OPC_U4I4CVT ||
05013 WN_opcode(wn) == OPC_I8U8CVT ||
05014 WN_opcode(wn) == OPC_U8I8CVT) {
05015 wn = WN_kid0 (wn);
05016 }
05017 }
05018 }
05019 }
05020 break;
05021
05022 case FIX_TRUNC_EXPR:
05023 {
05024 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05025 ty_idx = Get_TY (TREE_TYPE(exp));
05026 TYPE_ID mtype = Widen_Mtype(TY_mtype(ty_idx));
05027 if(WN_operator(wn0) == OPR_CVT &&
05028 MTYPE_is_integral(WN_desc(wn0)) &&
05029 MTYPE_is_float(WN_rtype(wn0))){
05030 wn1 = WN_kid0(wn0);
05031 TYPE_ID kid_type = WN_rtype(wn1);
05032 if(mtype == kid_type){
05033 wn = wn1;
05034 }
05035 else{
05036 wn = WN_Cvt(WN_rtype(wn1), mtype, wn1);
05037 }
05038 }
05039 else
05040 wn = WN_Trunc(WN_rtype(wn0), mtype, wn0);
05041
05042 }
05043 break;
05044
05045 #ifdef GPLUSPLUS_FE
05046 case EXPR_STMT:
05047 {
05048 #ifdef KEY
05049 wn = WFE_Expand_Expr (EXPR_STMT_EXPR(exp), false, nop_ty_idx,
05050 component_ty_idx, component_offset, field_id,
05051 is_bit_field, is_aggr_init_via_ctor);
05052 #else
05053 wn = WFE_Expand_Expr (EXPR_STMT_EXPR(exp), false);
05054 #endif
05055 }
05056 break;
05057
05058 case STMT_EXPR:
05059 {
05060 #ifdef KEY
05061 bool write_to_target_wn = TRUE;
05062
05063
05064
05065
05066
05067 if (target_wn != NULL
05068 && TREE_CODE (STMT_EXPR_STMT (exp)) == COMPOUND_STMT
05069 && TREE_CODE (COMPOUND_BODY (STMT_EXPR_STMT (exp))) == SCOPE_STMT) {
05070 tree expr = COMPOUND_BODY (STMT_EXPR_STMT (exp));
05071 tree last = TREE_CHAIN (expr);
05072
05073 while (TREE_CHAIN (last)) {
05074 expr = last;
05075 last = TREE_CHAIN (last);
05076 }
05077
05078 if (TREE_CODE (last) == SCOPE_STMT
05079 && TREE_CODE (expr) == EXPR_STMT) {
05080 if (TREE_CODE (EXPR_STMT_EXPR (expr)) == VAR_DECL) {
05081
05082
05083 tree var_decl = EXPR_STMT_EXPR (expr);
05084 ST *st = DECL_ST (var_decl);
05085 if (st == NULL) {
05086
05087
05088 if (WN_operator(target_wn) == OPR_LDA) {
05089 set_DECL_ST(var_decl, WN_st(target_wn));
05090 } else if (WN_operator(target_wn) == OPR_LDID) {
05091
05092
05093
05094 tree ptr_var =
05095 build_decl(VAR_DECL, NULL_TREE,
05096 build_pointer_type(TREE_TYPE(var_decl)));
05097 TREE_SET_CODE(var_decl, INDIRECT_REF);
05098 TREE_OPERAND(var_decl, 0) = ptr_var;
05099 set_DECL_ST(ptr_var, WN_st(target_wn));
05100 } else {
05101 FmtAssert(FALSE,
05102 ("WFE_Expand_Expr: unexpected operator in target_wn"));
05103 }
05104 } else {
05105
05106
05107 FmtAssert(st == WN_st(target_wn),
05108 ("WFE_Expand_Expr: STs are different"));
05109 }
05110
05111
05112 write_to_target_wn = FALSE;
05113
05114 } else if (TREE_CODE (EXPR_STMT_EXPR (expr)) == INDIRECT_REF) {
05115
05116
05117
05118 write_to_target_wn = FALSE;
05119 }
05120 }
05121 }
05122 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), need_result, nop_ty_idx,
05123 component_ty_idx, component_offset, field_id,
05124 is_bit_field, is_aggr_init_via_ctor,
05125 write_to_target_wn ? target_wn : NULL);
05126 #else
05127 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), need_result);
05128 #endif
05129 }
05130 break;
05131
05132 #ifndef KEY
05133 case SUBOBJECT:
05134 break;
05135 #endif // !KEY
05136
05137 case CLEANUP_POINT_EXPR:
05138 {
05139 Push_Temp_Cleanup(exp, false);
05140 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05141 WN * cleanup_block = WN_CreateBlock ();
05142 WFE_Stmt_Push (cleanup_block, wfe_stmk_temp_cleanup, Get_Srcpos ());
05143 Do_Temp_Cleanups(exp);
05144 WFE_Stmt_Pop (wfe_stmk_temp_cleanup);
05145 if (wn && WN_has_side_effects (wn) && WN_first (cleanup_block)) {
05146 DevWarn("CLEANUP_POINT_EXPR: expressson has side effects");
05147 ty_idx = Get_TY (TREE_TYPE(exp));
05148 st = Gen_Temp_Symbol (ty_idx, "__cleanup_point_expr");
05149 #ifdef KEY
05150 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
05151 #endif
05152 TYPE_ID mtype = TY_mtype (ty_idx);
05153 WFE_Set_ST_Addr_Saved (wn);
05154 wn = WN_Stid (mtype, 0, st, ty_idx, wn);
05155 WFE_Stmt_Append (wn, Get_Srcpos ());
05156 wn = WN_Ldid (mtype, 0, st, ty_idx);
05157 }
05158 WFE_Stmt_Append (cleanup_block, Get_Srcpos ());
05159 }
05160 break;
05161
05162 case THROW_EXPR:
05163 WFE_One_Stmt (TREE_OPERAND (exp, 0));
05164 Call_Throw();
05165 break;
05166
05167 case TRY_CATCH_EXPR:
05168 DevWarn ("Encountered TRY_CATCH_EXPR at line %d: ignored", lineno);
05169 break;
05170
05171 case COMPOUND_STMT:
05172 {
05173 tree t = COMPOUND_BODY(exp);
05174 tree last_expr_stmt = 0;
05175 wn = NULL;
05176 while (t) {
05177 if (TREE_CODE(t) == EXPR_STMT)
05178 last_expr_stmt = t;
05179 t = TREE_CHAIN(t);
05180 }
05181
05182 t = COMPOUND_BODY(exp);
05183
05184 while (t != last_expr_stmt) {
05185 WFE_Expand_Stmt (t, target_wn);
05186 t = TREE_CHAIN(t);
05187 }
05188
05189 if (t) {
05190 #ifdef KEY
05191 wn = WFE_Expand_Expr(t, need_result, nop_ty_idx, component_ty_idx,
05192 component_offset, field_id, is_bit_field,
05193 is_aggr_init_via_ctor, target_wn);
05194 #else
05195 wn = WFE_Expand_Expr(t, need_result);
05196 #endif
05197 t = TREE_CHAIN(t);
05198 }
05199
05200 while (t) {
05201 WFE_Expand_Stmt(t, target_wn);
05202 t = TREE_CHAIN(t);
05203 }
05204
05205 }
05206 break;
05207
05208 case EMPTY_CLASS_EXPR:
05209 DevWarn ("Encountered EMPTY_CLASS_EXPR at line %d\n", lineno);
05210 ty_idx = Get_TY (TREE_TYPE(exp));
05211 st = Gen_Temp_Symbol (ty_idx, "__empty_class_expr");
05212 #ifdef KEY
05213 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st);
05214 #endif
05215 wn = WN_Ldid (TY_mtype (ty_idx), 0, st, ty_idx);
05216 break;
05217 #endif
05218
05219
05220 case PLUS_EXPR:
05221 case MINUS_EXPR:
05222 case MULT_EXPR:
05223 case MAX_EXPR:
05224 case MIN_EXPR:
05225 case LSHIFT_EXPR:
05226 case BIT_AND_EXPR:
05227 case BIT_IOR_EXPR:
05228 case BIT_XOR_EXPR:
05229 case TRUNC_DIV_EXPR:
05230 case TRUNC_MOD_EXPR:
05231 case RDIV_EXPR:
05232 case EXACT_DIV_EXPR:
05233 case TRUTH_AND_EXPR:
05234 case TRUTH_OR_EXPR:
05235 case TRUTH_XOR_EXPR:
05236 case COMPLEX_EXPR:
05237 case CEIL_DIV_EXPR:
05238 {
05239 #ifdef KEY
05240 TYPE_ID etype = TY_mtype(Get_TY(TREE_TYPE(exp)));
05241 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05242 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05243 wn = WN_Binary (Operator_From_Tree [code].opr,
05244 Widen_Mtype(etype), wn0, wn1);
05245
05246 #if defined(TARG_SL)
05247 if(WN_operator(wn) == OPR_ADD &&
05248 (WN_operator(WN_kid0(wn)) == OPR_LDA ||
05249 WN_operator(WN_kid(wn, 1)) == OPR_LDA)) {
05250
05251 if(WN_operator(WN_kid0(wn)) == OPR_LDA && WN_has_sym(WN_kid0(wn))) {
05252 ST* vbuf_sym = WN_st(WN_kid0(wn));
05253 if(ST_in_v2buf(vbuf_sym) || ST_in_v4buf(vbuf_sym)) {
05254 if(WN_operator(WN_kid1(wn)) == OPR_MPY) {
05255 WN* tmp = WN_Intconst(MTYPE_U4, ST_in_v2buf(vbuf_sym) ? 2 : 4);
05256 WN_Set_vbuf_ofst_adjusted(tmp);
05257 WN* new_wn = WN_Binary(OPR_MPY, MTYPE_I4, WN_kid1(wn), tmp);
05258 WN_Set_vbuf_ofst_adjusted(new_wn);
05259 WN_kid1(wn) = new_wn;
05260 }
05261 }
05262 }
05263 }
05264 #endif // TARG_SL
05265
05266
05267 if ((MTYPE_is_integral(etype)) &&
05268 (Widen_Mtype(etype) != etype) &&
05269 (TY_size (Get_TY(TREE_TYPE(exp))) < 32) &&
05270 (code == PLUS_EXPR || code == MINUS_EXPR ||
05271 code == MULT_EXPR || code == LSHIFT_EXPR ||
05272 code == BIT_XOR_EXPR || code == BIT_IOR_EXPR))
05273 wn = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(etype), MTYPE_V,
05274 TY_size (Get_TY(TREE_TYPE(exp))) * 8, wn);
05275 #else
05276 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05277 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05278 wn = WN_Binary (Operator_From_Tree [code].opr,
05279 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))), wn0, wn1);
05280 #endif
05281 }
05282 break;
05283
05284 case LROTATE_EXPR:
05285 {
05286 ty_idx = Get_TY(TREE_TYPE(exp));
05287 TYPE_ID mtype = TY_mtype (ty_idx);
05288 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05289 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05290 wn1 = WN_Binary (OPR_SUB, Widen_Mtype (mtype),
05291 WN_Intconst (Widen_Mtype (mtype),
05292 TY_size (ty_idx) * 8),
05293 wn1);
05294 wn = WN_Rrotate (TY_mtype(Get_TY(TREE_TYPE(exp))), wn0, wn1);
05295 }
05296 break;
05297
05298 case RROTATE_EXPR:
05299 {
05300 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05301 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05302 wn = WN_Rrotate (TY_mtype(Get_TY(TREE_TYPE(exp))), wn0, wn1);
05303 }
05304 break;
05305
05306 case RSHIFT_EXPR:
05307 {
05308 TYPE_ID mtyp = Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp))));
05309 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05310 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05311 wn = WN_Binary (MTYPE_signed(mtyp) ? OPR_ASHR : OPR_LSHR,
05312 mtyp, wn0, wn1);
05313 }
05314 break;
05315
05316 case TRUTH_ANDIF_EXPR:
05317 case TRUTH_ORIF_EXPR:
05318 {
05319 #ifdef KEY
05320
05321 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05322
05323
05324
05325 WFE_Guard_Var_Push();
05326 wn1 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 1),
05327 Boolean_type);
05328 tree guard_var = WFE_Guard_Var_Pop();
05329 if (guard_var != NULL_TREE) {
05330 WFE_add_guard_var(guard_var, wn1);
05331 }
05332 #else
05333 wn0 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 0),
05334 Boolean_type);
05335 wn1 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 1),
05336 Boolean_type);
05337 #endif
05338 wn = WN_Binary (Operator_From_Tree [code].opr,
05339 Boolean_type, wn0, wn1);
05340 if (Boolean_type != MTYPE_B &&
05341 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))) != Boolean_type)
05342 wn = WN_Cvt (Boolean_type, Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(exp)))), wn);
05343 }
05344 break;
05345
05346 case LT_EXPR:
05347 case LE_EXPR:
05348 case GT_EXPR:
05349 case GE_EXPR:
05350 case EQ_EXPR:
05351 case NE_EXPR:
05352 {
05353 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05354 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05355
05356
05357 ty_idx = Get_TY (TREE_TYPE(exp));
05358 TYPE_ID mtyp = TY_mtype(ty_idx);
05359 TY_IDX ty_idx0 = Get_TY(TREE_TYPE(TREE_OPERAND (exp, 0)));
05360 TYPE_ID mtyp0 = TY_mtype(ty_idx0);
05361 TY_IDX ty_idx1 = Get_TY(TREE_TYPE(TREE_OPERAND (exp, 1)));
05362 TYPE_ID mtyp1 = TY_mtype(ty_idx1);
05363
05364 if (MTYPE_size_min(mtyp1) > MTYPE_size_min(mtyp0) &&
05365 ! Has_Subsumed_Cvtl(WN_operator(wn0)))
05366 wn0 = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp0), MTYPE_V,
05367 MTYPE_size_min(mtyp0), wn0);
05368 if (MTYPE_size_min(mtyp0) > MTYPE_size_min(mtyp1) &&
05369 ! Has_Subsumed_Cvtl(WN_operator(wn1)))
05370 wn1 = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp1), MTYPE_V,
05371 MTYPE_size_min(mtyp1), wn1);
05372
05373 wn = WN_Relational (Operator_From_Tree [code].opr,
05374 Widen_Mtype(TY_mtype(Get_TY(TREE_TYPE(TREE_OPERAND(exp, 0))))),
05375 wn0, wn1);
05376 #if defined(TARG_SL)
05377
05378 if ((Widen_Mtype(mtyp0) != Boolean_type ) && !MTYPE_float(mtyp0))
05379 wn = WN_Cvt( Boolean_type, Widen_Mtype(mtyp0), wn);
05380 #endif
05381 }
05382 break;
05383
05384 case COND_EXPR:
05385 {
05386 TY_IDX ty_idx1 = Get_TY (TREE_TYPE(TREE_OPERAND (exp, 1)));
05387 TY_IDX ty_idx2 = Get_TY (TREE_TYPE(TREE_OPERAND (exp, 2)));
05388 ty_idx = Get_TY (TREE_TYPE(exp));
05389 if(ty_idx != ty_idx1 && TY_mtype(ty_idx1) != MTYPE_V)
05390 DevWarn("The type of COND_EXPR and its first kid mismatch!");
05391 if(ty_idx != ty_idx2 && TY_mtype(ty_idx2) != MTYPE_V)
05392 DevWarn("The type of COND_EXPR and its second kid mismatch!");
05393 #ifdef KEY // bug 2645
05394 wn0 = WFE_Expand_Expr (TREE_OPERAND (exp, 0));
05395 #else
05396 wn0 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 0),
05397 Boolean_type);
05398 #endif
05399
05400
05401
05402 if (TY_mtype (ty_idx) == MTYPE_V ||
05403 TY_mtype (ty_idx1) == MTYPE_V ||
05404 TY_mtype (ty_idx2) == MTYPE_V) {
05405 WN *then_block = WN_CreateBlock ();
05406 WN *else_block = WN_CreateBlock ();
05407 WN *if_stmt = WN_CreateIf (wn0, then_block, else_block);
05408 WFE_Stmt_Append (if_stmt, Get_Srcpos());
05409 WFE_Stmt_Push (then_block, wfe_stmk_if_then, Get_Srcpos());
05410 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1), FALSE);
05411 if (wn1) {
05412 wn1 = WN_CreateEval (wn1);
05413 WFE_Stmt_Append (wn1, Get_Srcpos());
05414 }
05415 WFE_Stmt_Pop (wfe_stmk_if_then);
05416 WFE_Stmt_Push (else_block, wfe_stmk_if_else, Get_Srcpos());
05417 wn2 = WFE_Expand_Expr (TREE_OPERAND (exp, 2), FALSE);
05418 if (wn2) {
05419 wn2 = WN_CreateEval (wn2);
05420 WFE_Stmt_Append (wn2, Get_Srcpos());
05421 }
05422 WFE_Stmt_Pop (wfe_stmk_if_else);
05423 }
05424 else {
05425 #ifdef KEY
05426
05427
05428
05429
05430
05431 WFE_Guard_Var_Push();
05432 if(ty_idx != ty_idx1 &&
05433 Ty_Table[ty_idx].kind == KIND_POINTER &&
05434 Ty_Table[ty_idx1].kind == KIND_STRUCT) {
05435 wn1 = WFE_Address_Of (TREE_OPERAND (exp, 1));
05436 }
05437 else{
05438 wn1 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 1),
05439 TY_mtype (ty_idx),
05440 target_wn);
05441 }
05442
05443 tree guard_var1 = WFE_Guard_Var_Pop();
05444
05445 WFE_Guard_Var_Push();
05446 if(ty_idx != ty_idx2 &&
05447 Ty_Table[ty_idx].kind == KIND_POINTER &&
05448 Ty_Table[ty_idx2].kind == KIND_STRUCT) {
05449 wn2 = WFE_Address_Of (TREE_OPERAND (exp, 2));
05450 }
05451 else{
05452 wn2 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 2),
05453 TY_mtype (ty_idx),
05454 target_wn);
05455 }
05456 tree guard_var2 = WFE_Guard_Var_Pop();
05457
05458
05459 if (guard_var1 != NULL_TREE) {
05460 WFE_add_guard_var(guard_var1, wn1);
05461 }
05462 if (guard_var2 != NULL_TREE) {
05463 WFE_add_guard_var(guard_var2, wn2);
05464 }
05465 #else
05466 wn1 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 1),
05467 TY_mtype (ty_idx));
05468 wn2 = WFE_Expand_Expr_With_Sequence_Point (TREE_OPERAND (exp, 2),
05469 TY_mtype (ty_idx));
05470 #endif
05471 wn = WN_CreateExp3 (OPR_CSELECT, Mtype_comparison (TY_mtype (ty_idx)),
05472 MTYPE_V, wn0, wn1, wn2);
05473 Set_PU_has_very_high_whirl (Get_Current_PU ());
05474 }
05475
05476
05477
05478 FmtAssert ((wn != 0 ||
05479 TY_mtype(ty_idx) == MTYPE_V ||
05480 TY_mtype(ty_idx1) == MTYPE_V ||
05481 TY_mtype(ty_idx2) == MTYPE_V),
05482 ("WFE_Expand_Expr: NULL WHIRL tree for %s",
05483 Operator_From_Tree [code].name));
05484 }
05485 break;
05486
05487 case INIT_EXPR:
05488 #ifdef KEY
05489
05490 if (target_wn != NULL &&
05491 (TREE_CODE(TREE_OPERAND(exp, 0)) == VAR_DECL ||
05492 TREE_CODE(TREE_OPERAND(exp, 0)) == RESULT_DECL ||
05493 TREE_CODE(TREE_OPERAND(exp, 0)) == PARM_DECL)) {
05494 if (WN_operator(target_wn) == OPR_LDA) {
05495
05496 set_DECL_ST(TREE_OPERAND(exp, 0), WN_st(target_wn));
05497 } else if (WN_operator(target_wn) == OPR_LDID) {
05498
05499
05500
05501
05502
05503
05504 tree opnd0 = TREE_OPERAND(exp, 0);
05505 tree ptr_var = build_decl(VAR_DECL, NULL_TREE,
05506 build_pointer_type(TREE_TYPE(opnd0)));
05507 TREE_SET_CODE(opnd0, INDIRECT_REF);
05508 TREE_OPERAND(opnd0, 0) = ptr_var;
05509 set_DECL_ST(ptr_var, WN_st(target_wn));
05510 }
05511 }
05512
05513 #ifdef NEW_INITIALIZER
05514 {
05515 tree opnd0 = TREE_OPERAND(exp, 0);
05516 tree opnd1 = TREE_OPERAND(exp, 1);
05517 if( TREE_CODE(opnd0) == INDIRECT_REF &&
05518 TREE_CODE(opnd1) == CONSTRUCTOR ) {
05519 WN* target = WFE_Address_Of(opnd0);
05520 ST* copy_st = WFE_Generate_Initialized_Aggregate(target, opnd1);
05521 ST* orig_st = WN_st(target);
05522 if ( ST_st_idx(copy_st) != ST_st_idx(orig_st) ) {
05523
05524
05525
05526
05527
05528
05529 TY_IDX copy_ty = ST_type(copy_st);
05530 WN* ldid = WN_Ldid(TY_mtype(copy_ty), 0, copy_st, copy_ty);
05531 if ( WN_operator(target) == OPR_LDA ) {
05532 WFE_Stmt_Append(
05533 WN_Stid (TY_mtype(copy_ty), WN_lda_offset(target),
05534 orig_st, ST_type(orig_st), ldid),
05535 Get_Srcpos() );
05536 }
05537 else if ( WN_operator(target) == OPR_LDID ) {
05538 WFE_Stmt_Append(
05539 WN_Istore(TY_mtype(copy_ty), 0,
05540 ST_type(orig_st), target, ldid),
05541 Get_Srcpos() );
05542 }
05543 else {
05544 FmtAssert(FALSE, ("Bad operator for target, not LDA/LDID"));
05545 }
05546 }
05547 break;
05548 }
05549 }
05550 #endif
05551
05552
05553 #endif
05554 case MODIFY_EXPR:
05555
05556
05557
05558
05559
05560
05561
05562 #ifdef KEY
05563
05564
05565
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608
05609
05610
05611
05612
05613
05614
05615
05616
05617
05618
05619
05620
05621
05622
05623
05624
05625
05626
05627
05628
05629
05630
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641 {
05642 tree init_expr_opnd0 = TREE_OPERAND(exp, 0);
05643 if (TREE_CODE(TREE_OPERAND(exp, 1)) == NOP_EXPR &&
05644 TREE_CODE(TREE_OPERAND(TREE_OPERAND(exp, 1), 0)) == TARGET_EXPR &&
05645 TREE_CODE(init_expr_opnd0) == INDIRECT_REF &&
05646 TREE_CODE(TREE_OPERAND(init_expr_opnd0, 0)) == VAR_DECL) {
05647 tree t = TREE_OPERAND(exp, 1);
05648 ST *st = Get_ST(TREE_OPERAND(init_expr_opnd0, 0));
05649 WN *target_wn = WN_Ldid(Pointer_Mtype, 0, st, ST_type(st));
05650 wn = WFE_Expand_Expr(t, TRUE, 0, 0, 0, 0, FALSE, FALSE, target_wn);
05651 break;
05652 }
05653 }
05654 #endif
05655 {
05656 tree t = NULL;
05657 if (TREE_CODE(TREE_OPERAND(exp, 1)) == TARGET_EXPR) {
05658 t = TREE_OPERAND(exp, 1);
05659 TREE_OPERAND(t, 2) = NULL_TREE;
05660 }
05661 #ifdef KEY
05662
05663 else if (TREE_CODE(TREE_OPERAND(exp, 1)) == NOP_EXPR &&
05664 TREE_CODE(TREE_OPERAND(TREE_OPERAND(exp, 1), 0))
05665 == TARGET_EXPR) {
05666 t = TREE_OPERAND(TREE_OPERAND(exp, 1), 0);
05667 TREE_OPERAND(t, 2) = NULL_TREE;
05668 }
05669 #endif
05670
05671 if (t != NULL) {
05672 #ifdef KEY
05673
05674
05675
05676 tree init_expr_opnd0 = TREE_OPERAND(exp, 0);
05677 tree initializer = NULL;
05678 if (TREE_CODE(init_expr_opnd0) == INDIRECT_REF &&
05679 TREE_CODE(TREE_OPERAND(init_expr_opnd0, 0)) == VAR_DECL) {
05680 tree target_expr_opnd0 = TREE_OPERAND(t, 0);
05681 tree ptr_var =
05682 build_decl(VAR_DECL, NULL_TREE,
05683 TREE_TYPE(TREE_OPERAND(init_expr_opnd0, 0)));
05684 TREE_SET_CODE(target_expr_opnd0, INDIRECT_REF);
05685 TREE_OPERAND(target_expr_opnd0, 0) = ptr_var;
05686 set_DECL_ST(ptr_var, DECL_ST(TREE_OPERAND(init_expr_opnd0, 0)));
05687 wn = WFE_Expand_Expr(t);
05688 break;
05689 }
05690 #ifdef PATHSCALE_MERGE
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700 else if (TREE_CODE(init_expr_opnd0) == INDIRECT_REF &&
05701 TREE_CODE(TREE_OPERAND(init_expr_opnd0, 0)) == NOP_EXPR &&
05702 TREE_CODE(TREE_OPERAND(TREE_OPERAND(init_expr_opnd0,0),0))
05703 == VAR_DECL) {
05704 tree target_expr_opnd0 = TREE_OPERAND(t, 0);
05705 tree target_var = TREE_OPERAND(TREE_OPERAND(init_expr_opnd0, 0), 0);
05706 tree ptr_var =
05707 build_decl(VAR_DECL, NULL_TREE, TREE_TYPE(target_var));
05708 TREE_SET_CODE(target_expr_opnd0, INDIRECT_REF);
05709 TREE_OPERAND(target_expr_opnd0, 0) = ptr_var;
05710 set_DECL_ST(ptr_var, DECL_ST(target_var));
05711 wn = WFE_Expand_Expr(t);
05712 break;
05713 }
05714 #endif // PATHSCALE_MERGE
05715 #endif
05716 if (TREE_CODE(TREE_OPERAND(exp, 0)) == VAR_DECL ||
05717 TREE_CODE(TREE_OPERAND(exp, 0)) == RESULT_DECL ||
05718 TREE_CODE(TREE_OPERAND(exp, 0)) == PARM_DECL) {
05719 #ifdef KEY
05720 ST *st = Get_ST(TREE_OPERAND(exp, 0));
05721 set_DECL_ST(TREE_OPERAND(t, 0), st);
05722 #else
05723 TREE_OPERAND(t, 0) = TREE_OPERAND(exp, 0);
05724 #endif
05725 wn = WFE_Expand_Expr(t);
05726 break;
05727 }
05728
05729
05730
05731
05732 else if (TREE_CODE(init_expr_opnd0) == INDIRECT_REF &&
05733 ((initializer = TREE_OPERAND(t,1)) ||
05734 (initializer = TREE_OPERAND(t,3))) &&
05735 (TREE_CODE(initializer) == CALL_EXPR ||
05736 TREE_CODE(initializer) == AGGR_INIT_EXPR)) {
05737 TREE_OPERAND(t,0) = init_expr_opnd0;
05738 wn = WFE_Expand_Expr(t);
05739 break;
05740 }
05741 DevWarn ("INIT_EXPR/MODIFY_EXPR kid1 is TARGET_EXPR, kid0 is %s\n",
05742 Operator_From_Tree [TREE_CODE(TREE_OPERAND(exp, 0))].name);
05743 }
05744 }
05745
05746 case PREDECREMENT_EXPR:
05747 case PREINCREMENT_EXPR:
05748 case POSTDECREMENT_EXPR:
05749 case POSTINCREMENT_EXPR:
05750 {
05751 if (TREE_CODE(TREE_OPERAND(exp, 1)) == ERROR_MARK)
05752 break;
05753 #ifdef KEY
05754
05755
05756
05757
05758 tree exp_opnd1 = TREE_OPERAND(exp, 1);
05759 if (WFE_Call_Returns_Ptr_To_Member_Func(exp_opnd1)) {
05760 TYPE_ID desc = TY_mtype(Get_TY(TREE_TYPE(exp_opnd1)));
05761 wn1 = WFE_Expand_Ptr_To_Member_Func_Call_Expr(exp_opnd1, 0,
05762 Widen_Mtype(desc), desc);
05763 } else
05764 #endif
05765 wn1 = WFE_Expand_Expr (TREE_OPERAND (exp, 1));
05766
05767 #ifdef TARG_SL
05768 wn = WFE_Lhs_Of_Modify_Expr(code, TREE_OPERAND (exp, 0), TREE_OPERAND(exp,1), need_result,
05769 #else
05770 wn = WFE_Lhs_Of_Modify_Expr(code, TREE_OPERAND (exp, 0), need_result,
05771 #endif
05772 0, 0, 0, FALSE, wn1, 0, FALSE, FALSE);
05773 }
05774 break;
05775
05776
05777
05778 case BIT_FIELD_REF:
05779 {
05780 wn = WFE_Expand_Expr (TREE_OPERAND (exp, 0), TRUE, nop_ty_idx,
05781 component_ty_idx, component_offset,
05782 field_id, FALSE);
05783 ty_idx = Get_TY (TREE_TYPE(exp));
05784 TYPE_ID rtype = TY_mtype(ty_idx);
05785 UINT siz = TY_size(ty_idx);
05786 TYPE_ID desc;
05787 if (siz <= 8) {
05788 if (MTYPE_signed(rtype))
05789 desc = Mtype_AlignmentClass(siz, MTYPE_CLASS_INTEGER);
05790 else desc = Mtype_AlignmentClass(siz, MTYPE_CLASS_UNSIGNED_INTEGER);
05791 rtype = Widen_Mtype(desc);
05792 }
05793 else desc = rtype;
05794 #ifdef KEY
05795
05796 while (1) {
05797 if ((WN_operator(wn) == OPR_CVT)
05798 && (desc == rtype)
05799 #ifdef TARG_SL
05800
05801
05802
05803 && WN_operator(WN_kid0(wn)) != OPR_LDA
05804 && WN_operator(WN_kid0(wn)) != OPR_LDID
05805 && WN_operator(WN_kid0(wn)) != OPR_LDBITS
05806 #endif
05807 )
05808 {
05809 WN * del = wn;
05810 wn = WN_kid0 (wn);
05811 WN_Delete (del);
05812 }
05813 else break;
05814 }
05815 #endif // KEY
05816 WN_set_rtype(wn, rtype);
05817 if (WN_desc(wn) != MTYPE_V)
05818 WN_set_desc(wn, desc);
05819 INT bofst = Get_Integer_Value(TREE_OPERAND(exp, 2));
05820 INT bsiz =Get_Integer_Value(TREE_OPERAND(exp, 1));
05821 if ((bsiz & 7) == 0 &&
05822 MTYPE_size_min(desc) % bsiz == 0 &&
05823 bofst % bsiz == 0) {
05824
05825 if (WN_desc(wn) != MTYPE_V)
05826 if (MTYPE_signed(rtype))
05827 WN_set_desc(wn, Mtype_AlignmentClass(bsiz >> 3, MTYPE_CLASS_INTEGER));
05828 else WN_set_desc(wn, Mtype_AlignmentClass(bsiz >> 3, MTYPE_CLASS_UNSIGNED_INTEGER));
05829 WN_load_offset(wn) = WN_load_offset(wn) + (bofst >> 3);
05830 } else {
05831 #ifdef KEY
05832
05833
05834
05835
05836 mUINT16 base_type_size = MTYPE_bit_size (desc);
05837 WN_load_offset(wn) += (bofst / base_type_size) * MTYPE_byte_size (desc);
05838 bofst = bofst % base_type_size;
05839 #endif
05840 if (WN_operator(wn) == OPR_LDID)
05841 WN_set_operator(wn, OPR_LDBITS);
05842 else WN_set_operator(wn, OPR_ILDBITS);
05843 WN_set_bit_offset_size(wn, bofst, bsiz);
05844 #ifdef KEY
05845 TY_IDX ty = MTYPE_To_TY (WN_desc(wn));
05846 WN_set_ty (wn, ty);
05847 if (WN_operator(wn) == OPR_ILDBITS)
05848 WN_set_load_addr_ty(wn, Make_Pointer_Type(ty));
05849 break;
05850 #endif
05851 }
05852 if (MTYPE_byte_size (WN_desc(wn)) != TY_size(WN_ty(wn)))
05853
05854 #ifdef KEY
05855 {
05856 TY_IDX ty = MTYPE_To_TY (WN_desc(wn));
05857 if ((TY_kind(Ty_Table[WN_ty(wn)]) == KIND_STRUCT)
05858 && (TY_kind(Ty_Table[ty]) != KIND_STRUCT))
05859
05860
05861 WN_set_field_id (wn, 0);
05862 WN_set_ty (wn, ty);
05863 if (WN_operator(wn) == OPR_ILOAD || WN_operator(wn) == OPR_ILDBITS)
05864 WN_set_load_addr_ty(wn, Make_Pointer_Type(ty));
05865 }
05866 #else
05867 WN_set_ty (wn, MTYPE_To_TY (WN_desc(wn)));
05868 #endif
05869 }
05870 break;
05871
05872
05873
05874 case ARRAY_REF:
05875 {
05876 UINT xtra_BE_ofst = 0;
05877 TY_IDX elem_ty_idx;
05878
05879 wn0 = WFE_Array_Expr(exp, &elem_ty_idx, 0, 0, 0);
05880
05881
05882 TY_IDX hi_ty_idx = Get_TY (TREE_TYPE(exp));
05883 desc_ty_idx = component_ty_idx;
05884 if (desc_ty_idx == 0)
05885 desc_ty_idx = hi_ty_idx;
05886
05887 if (! MTYPE_is_integral(TY_mtype(desc_ty_idx)))
05888 ty_idx = desc_ty_idx;
05889 else {
05890 ty_idx = nop_ty_idx;
05891 if (ty_idx == 0)
05892 ty_idx = desc_ty_idx;
05893 }
05894
05895 if (! is_bit_field) {
05896 if (TY_size(desc_ty_idx) > TY_size(ty_idx)) {
05897 if (Target_Byte_Sex == BIG_ENDIAN)
05898 xtra_BE_ofst = TY_size(desc_ty_idx) - TY_size(ty_idx);
05899 desc_ty_idx = ty_idx;
05900 }
05901 }
05902 else {
05903 if (TY_size(desc_ty_idx) > TY_size(ty_idx))
05904 ty_idx = desc_ty_idx;
05905 }
05906
05907 TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
05908 TYPE_ID desc = TY_mtype(desc_ty_idx);
05909 if (MTYPE_is_integral(desc)) {
05910 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) {
05911 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc) ||
05912 is_bit_field)
05913 rtype = Mtype_TransferSign(desc, rtype);
05914 else desc = Mtype_TransferSign(rtype, desc);
05915 }
05916 }
05917
05918 Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
05919 ("WFE_Expand_Expr: field id for bit-field exceeds limit"));
05920 wn = WN_CreateIload(OPR_ILOAD, rtype,
05921 is_bit_field ? MTYPE_BS : desc,
05922 component_offset+xtra_BE_ofst,
05923 field_id != 0 ? hi_ty_idx : ty_idx,
05924 Make_Pointer_Type(elem_ty_idx, FALSE),
05925 wn0, field_id);
05926 }
05927 #if defined(TARG_SL)
05928
05929
05930
05931 if(Mark_LDA_Vbuf_Offset(wn, INTRN_VBUF_OFFSET))
05932 WN_Set_is_internal_mem_ofst(wn);
05933
05934
05935
05936
05937
05938
05939
05940 wn = Adjust_Vbuf_Array_Ofst(wn);
05941 #endif // TARG_SL
05942
05943 break;
05944
05945 case AGGR_INIT_EXPR:
05946 case CALL_EXPR:
05947 {
05948 INTRINSIC iopc = INTRINSIC_NONE;
05949 tree arglist = TREE_OPERAND (exp, 1);
05950 TYPE_ID ret_mtype;
05951 WN *call_wn;
05952 WN *arg_wn;
05953 TY_IDX arg_ty_idx;
05954 TYPE_ID arg_mtype;
05955 INT num_args = 0;
05956 INT num_handlers = 0;
05957 INT i;
05958 tree list;
05959 arg0 = TREE_OPERAND (exp, 0);
05960 enum tree_code code0 = TREE_CODE (arg0);
05961
05962 BOOL return_in_mem = FALSE;
05963 #ifdef KEY
05964 ST *ret_st = NULL;
05965 #endif
05966 for (list = TREE_OPERAND (exp, 1); list; list = TREE_CHAIN (list)) {
05967 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
05968 if (!WFE_Keep_Zero_Length_Structs &&
05969 TY_mtype (arg_ty_idx) == MTYPE_M &&
05970 TY_size (arg_ty_idx) == 0) {
05971
05972 }
05973 else
05974 num_args++;
05975 }
05976 ty_idx = Get_TY(TREE_TYPE(exp));
05977 if (need_result) {
05978 if (!WFE_Keep_Zero_Length_Structs &&
05979 TY_mtype (ty_idx) == MTYPE_M &&
05980 TY_size (ty_idx) == 0) {
05981
05982 ret_mtype = MTYPE_V;
05983 }
05984 else
05985 ret_mtype = TY_mtype (ty_idx);
05986 #ifdef KEY
05987
05988
05989 if (TY_return_in_mem (ty_idx)) {
05990 ret_mtype = MTYPE_V;
05991 return_in_mem = TRUE;
05992 num_args++;
05993 }
05994 #endif
05995 }
05996 else
05997 ret_mtype = MTYPE_V;
05998 st = NULL;
05999 if (code0 == ADDR_EXPR &&
06000 TREE_CODE (TREE_OPERAND (arg0, 0))) {
06001 tree func = TREE_OPERAND (arg0, 0);
06002 BOOL intrinsic_op = FALSE;
06003 BOOL whirl_generated = FALSE;
06004
06005 #ifdef KEY
06006
06007
06008 TYPE_ID cvt_to = MTYPE_UNKNOWN;
06009
06010 if (DECL_ASSEMBLER_NAME(func))
06011 TREE_SYMBOL_REFERENCED_BY_WHIRL(DECL_ASSEMBLER_NAME(func)) = 1;
06012 #endif
06013
06014 if (DECL_BUILT_IN (func)) {
06015 if (DECL_BUILT_IN_CLASS (func) != BUILT_IN_MD) {
06016
06017 switch (DECL_FUNCTION_CODE (func)) {
06018
06019 case END_BUILTINS:
06020 break;
06021
06022 case BUILT_IN_STDARG_START:
06023 #ifdef KEY
06024 case BUILT_IN_VA_START:
06025 #endif
06026 {
06027 #ifdef TARG_X8664
06028 if( TARGET_64BIT ){
06029 iopc = INTRN_VA_START;
06030 break;
06031 }
06032 #endif
06033 arg1 = TREE_VALUE (arglist);
06034 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
06035 WN *arg_wn = WFE_Expand_Expr (arg1);
06036 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (arg1));
06037 while (TREE_CODE (arg2) == NOP_EXPR
06038 || TREE_CODE (arg2) == CONVERT_EXPR
06039 || TREE_CODE (arg2) == NON_LVALUE_EXPR
06040 || TREE_CODE (arg2) == INDIRECT_REF)
06041 arg2 = TREE_OPERAND (arg2, 0);
06042 ST *st2 = Get_ST (arg2);
06043 #if defined(TARG_X8664) || defined(TARG_SL) || defined(TARG_MIPS)
06044 const int align = PARM_BOUNDARY / BITS_PER_UNIT;
06045 wn = WN_Lda (Pointer_Mtype,
06046 ((TY_size (ST_type (st2)) + align-1) & (-align)),
06047 st2);
06048 #else
06049 wn = WN_Lda (Pointer_Mtype,
06050 ((TY_size (ST_type (st2)) + 7) & (-8)),
06051 st2);
06052 #endif
06053 if (WN_operator (arg_wn) == OPR_LDA) {
06054 wn = WN_Stid (Pointer_Mtype, WN_offset (arg_wn),
06055 WN_st (arg_wn), arg_ty_idx, wn);
06056 }
06057 else {
06058 wn = WN_CreateIstore (OPR_ISTORE, MTYPE_V,
06059 Pointer_Mtype, 0, arg_ty_idx,
06060 wn, arg_wn, 0);
06061 }
06062
06063 WFE_Stmt_Append (wn, Get_Srcpos());
06064 whirl_generated = TRUE;
06065 wn = NULL;
06066 break;
06067 }
06068
06069 case BUILT_IN_VA_COPY:
06070 {
06071 arg1 = TREE_VALUE (arglist);
06072 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
06073 TY_IDX arg_ty_idx = Get_TY (TREE_TYPE (arg1));
06074
06075
06076 #ifdef KEY
06077
06078
06079
06080
06081
06082
06083 #if defined(TARG_X8664) || defined(TARG_SL) || defined(TARG_MIPS)
06084 if( !TARGET_64BIT )
06085 #endif
06086 {
06087 FmtAssert( TREE_CODE(arglist) != ARRAY_TYPE,
06088 ("unexpected array type for intrinsic 'va_copy'") );
06089 WN* addr = WFE_Expand_Expr( arg1 );
06090 WN* value = WFE_Expand_Expr( arg2 );
06091 wn = WN_CreateIstore( OPR_ISTORE, MTYPE_V, Pointer_Mtype,
06092 0, arg_ty_idx, value, addr, 0 );
06093
06094 WFE_Stmt_Append( wn, Get_Srcpos() );
06095 whirl_generated = TRUE;
06096 wn = NULL;
06097 break;
06098 }
06099 #endif // KEY
06100
06101 WN *dst = WN_CreateParm (Pointer_Mtype, WFE_Expand_Expr (arg1),
06102 arg_ty_idx, WN_PARM_BY_VALUE);
06103 WN *src = WN_CreateParm (Pointer_Mtype, WFE_Expand_Expr (arg2),
06104 arg_ty_idx, WN_PARM_BY_VALUE);
06105 WN *size = WN_CreateParm (MTYPE_I4,
06106 WN_Intconst(MTYPE_I4,TY_size(TY_pointed(arg_ty_idx))),
06107 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
06108 wn = WN_Create (OPR_INTRINSIC_CALL, ret_mtype, MTYPE_V, 3);
06109 WN_intrinsic (wn) = INTRN_MEMCPY;
06110 WN_kid0 (wn) = dst;
06111 WN_kid1 (wn) = src;
06112 WN_kid2 (wn) = size;
06113 WFE_Stmt_Append (wn, Get_Srcpos());
06114 whirl_generated = TRUE;
06115 wn = NULL;
06116 break;
06117 }
06118
06119 case BUILT_IN_VA_END:
06120 {
06121 arg1 = TREE_VALUE (arglist);
06122 wn = WN_CreateEval ( WFE_Expand_Expr (arg1) );
06123 WFE_Stmt_Append (wn, Get_Srcpos());
06124 whirl_generated = TRUE;
06125 wn = NULL;
06126 break;
06127 }
06128
06129 case BUILT_IN_NEXT_ARG:
06130 {
06131 tree last_parm = tree_last
06132 (DECL_ARGUMENTS (Current_Function_Decl()));
06133 while (TREE_CODE (last_parm) == NOP_EXPR
06134 || TREE_CODE (last_parm) == CONVERT_EXPR
06135 || TREE_CODE (last_parm) == NON_LVALUE_EXPR
06136 || TREE_CODE (last_parm) == INDIRECT_REF)
06137 last_parm = TREE_OPERAND (last_parm, 0);
06138 ST *st = Get_ST (last_parm);
06139 arg_wn = WN_Lda (Pointer_Mtype, ST_ofst(st), st);
06140 wn = WN_Binary (OPR_ADD, Pointer_Mtype, arg_wn,
06141 WN_Intconst (Pointer_Mtype,
06142 Parameter_Size(ST_size(st))));
06143 whirl_generated = TRUE;
06144 break;
06145 }
06146
06147 case BUILT_IN_ALLOCA:
06148 Set_PU_has_alloca (Get_Current_PU ());
06149 Set_PU_has_user_alloca (Get_Current_PU ());
06150 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06151 wn = WN_CreateAlloca (arg_wn);
06152 whirl_generated = TRUE;
06153 break;
06154
06155 case BUILT_IN_MEMCPY:
06156 iopc = INTRN_MEMCPY;
06157 break;
06158
06159 case BUILT_IN_MEMCMP:
06160 iopc = INTRN_MEMCMP;
06161 break;
06162
06163 case BUILT_IN_MEMSET:
06164 iopc = INTRN_MEMSET;
06165 break;
06166
06167 case BUILT_IN_STRCPY:
06168 iopc = INTRN_STRCPY;
06169 break;
06170
06171 case BUILT_IN_STRCMP:
06172 #ifdef GPLUSPLUS_FE
06173 iopc = INTRN_STRCMP;
06174 #else
06175 if (arglist == 0
06176
06177 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
06178 || TREE_CHAIN (arglist) == 0
06179 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
06180 break;
06181 else {
06182 arg1 = TREE_VALUE (arglist);
06183 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
06184 tree len1 = c_strlen (arg1);
06185 if (len1) {
06186 tree len2 = c_strlen (arg2);
06187 if (len2) {
06188 char *ptr1 = get_string_pointer (WFE_Expand_Expr (arg1));
06189 char *ptr2 = get_string_pointer (WFE_Expand_Expr (arg2));
06190 if (ptr1 && ptr2) {
06191 wn = WN_Intconst (MTYPE_I4,
06192 strcmp (ptr1, ptr2));
06193 whirl_generated = TRUE;
06194 break;
06195 }
06196 }
06197 }
06198 iopc = INTRN_STRCMP;
06199
06200 }
06201 #endif
06202 break;
06203
06204 case BUILT_IN_STRLEN:
06205 #ifdef GPLUSPLUS_FE
06206 iopc = INTRN_STRLEN;
06207 #else
06208 if (arglist == 0
06209
06210 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
06211 break;
06212 else {
06213 tree src = TREE_VALUE (arglist);
06214 tree len = c_strlen (src);
06215 if (len) {
06216 wn = WFE_Expand_Expr (len);
06217 whirl_generated = TRUE;
06218 }
06219 else {
06220 iopc = INTRN_STRLEN;
06221
06222 }
06223 }
06224 #endif
06225 break;
06226
06227 #ifdef KEY
06228 case BUILT_IN_FLOOR:
06229 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06230 #if defined TARG_MIPS
06231 iopc = INTRN_FLOOR;
06232 intrinsic_op = TRUE;
06233 #else
06234 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype , MTYPE_F8, arg_wn);
06235 whirl_generated = TRUE;
06236 #endif
06237 break;
06238
06239 case BUILT_IN_FLOORF:
06240 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06241 #if defined TARG_MIPS
06242 iopc = INTRN_FLOORF;
06243 intrinsic_op = TRUE;
06244 #else
06245 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype, MTYPE_F4, arg_wn);
06246 whirl_generated = TRUE;
06247 #endif
06248 break;
06249
06250 #ifndef TARG_MIPS
06251 case BUILT_IN_FLOORL:
06252 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06253 #ifdef TARG_IA64
06254 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype, MTYPE_F10, arg_wn);
06255 #else
06256 wn = WN_CreateExp1 (OPR_FLOOR, ret_mtype, MTYPE_FQ, arg_wn);
06257 #endif // TARG_IA64
06258 whirl_generated = TRUE;
06259 break;
06260 #endif // ! TARG_MIPS
06261 #endif // KEY
06262
06263 #ifdef KEY
06264 case BUILT_IN_SQRT:
06265 if( flag_errno_math ){
06266 break;
06267 }
06268 #else
06269 case BUILT_IN_FSQRT:
06270 #endif
06271 arg_wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06272 wn = WN_CreateExp1 (OPR_SQRT, ret_mtype, MTYPE_V, arg_wn);
06273 whirl_generated = TRUE;
06274 break;
06275
06276 case BUILT_IN_SIN:
06277 intrinsic_op = TRUE;
06278 #ifdef TARG_X8664
06279 if (!Force_IEEE_Comparisons)
06280 {
06281 iopc = INTRN_SINL;
06282 if (ret_mtype != MTYPE_FQ)
06283 {
06284
06285 cvt_to = ret_mtype;
06286 ret_mtype = MTYPE_FQ;
06287 }
06288 break;
06289 }
06290 #endif
06291 #ifdef KEY
06292 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06293 #endif
06294 if (ret_mtype == MTYPE_F4) iopc = INTRN_F4SIN;
06295 else if (ret_mtype == MTYPE_F8) iopc = INTRN_F8SIN;
06296 else Fail_FmtAssertion ("unexpected mtype for intrinsic 'sin'");
06297 break;
06298
06299 case BUILT_IN_COS:
06300 intrinsic_op = TRUE;
06301 #ifdef TARG_X8664
06302 if (!Force_IEEE_Comparisons)
06303 {
06304 iopc = INTRN_COSL;
06305 if (ret_mtype != MTYPE_FQ)
06306 {
06307
06308 cvt_to = ret_mtype;
06309 ret_mtype = MTYPE_FQ;
06310 }
06311 break;
06312 }
06313 #endif
06314 #ifdef KEY
06315 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06316 #endif
06317 if (ret_mtype == MTYPE_F4) iopc = INTRN_F4COS;
06318 else if (ret_mtype == MTYPE_F8) iopc = INTRN_F8COS;
06319 else Fail_FmtAssertion ("unexpected mtype for intrinsic 'cos'");
06320 break;
06321
06322 #ifdef KEY
06323 case BUILT_IN_EXP:
06324 case BUILT_IN_EXPF:
06325
06326
06327
06328
06329 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06330
06331 if (ret_mtype == MTYPE_F4) iopc = INTRN_F4EXP;
06332 else if (ret_mtype == MTYPE_F8) iopc = INTRN_F8EXP;
06333 else Fail_FmtAssertion ("unexpected mtype for intrinsic 'exp'");
06334 intrinsic_op = TRUE;
06335 break;
06336
06337 case BUILT_IN_POW:
06338
06339
06340
06341
06342
06343
06344
06345
06346
06347
06348 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_F8;
06349
06350 FmtAssert(ret_mtype == MTYPE_F8,
06351 ("unexpected mtype for intrinsic 'pow'"));
06352 iopc = INTRN_F8EXPEXPR;
06353 intrinsic_op = TRUE;
06354 break;
06355 #endif // KEY
06356
06357 case BUILT_IN_CONSTANT_P:
06358 {
06359 tree arg = TREE_VALUE (TREE_OPERAND (exp, 1));
06360 STRIP_NOPS (arg);
06361 if (really_constant_p (arg)
06362 || (TREE_CODE (arg) == ADDR_EXPR
06363 && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
06364 {
06365 wn = WN_Intconst (MTYPE_I4, 1);
06366 whirl_generated = TRUE;
06367 }
06368 #ifdef KEY
06369
06370
06371 else
06372 {
06373 iopc = INTRN_CONSTANT_P;
06374 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_I4;
06375 intrinsic_op = TRUE;
06376 }
06377 #else
06378
06379 else
06380 wn = WN_Intconst (MTYPE_I4, 0);
06381
06382 whirl_generated = TRUE;
06383 #endif // KEY
06384 break;
06385 }
06386 #if 0
06387 case BUILT_IN_LOCK_TEST_AND_SET:
06388 wn = emit_builtin_lock_test_and_set (exp, num_args-2);
06389 whirl_generated = TRUE;
06390 break;
06391
06392 case BUILT_IN_LOCK_RELEASE:
06393 emit_builtin_lock_release (exp, num_args-1);
06394 whirl_generated = TRUE;
06395 break;
06396
06397 case BUILT_IN_COMPARE_AND_SWAP:
06398 wn = emit_builtin_compare_and_swap (exp, num_args-3);
06399 whirl_generated = TRUE;
06400 break;
06401
06402 case BUILT_IN_SYNCHRONIZE:
06403 emit_builtin_synchronize (exp, num_args);
06404 whirl_generated = TRUE;
06405 break;
06406 #endif
06407
06408 case BUILT_IN_RETURN_ADDRESS:
06409 i = Get_Integer_Value (TREE_VALUE (TREE_OPERAND (exp, 1)));
06410 if (i > 0) {
06411
06412
06413
06414 warning("non-zero levels not supported for builtin_return_address");
06415 wn = WN_Intconst(Pointer_Mtype, 0);
06416 }
06417 else {
06418 st = WFE_Get_Return_Address_ST (i);
06419 wn = WN_Ldid (Pointer_Mtype, 0, st, ST_type (st));
06420 }
06421 whirl_generated = TRUE;
06422 break;
06423
06424 #ifdef KEY
06425 case BUILT_IN_EXTRACT_RETURN_ADDR:
06426 list = TREE_OPERAND (exp, 1);
06427 wn = WFE_Expand_Expr (TREE_VALUE (list));
06428 wn = WN_Binary (OPR_BAND, Pointer_Mtype, wn,
06429 WN_Intconst(Pointer_Mtype, -2));
06430 whirl_generated = TRUE;
06431 break;
06432
06433 case BUILT_IN_FRAME_ADDRESS:
06434 Set_PU_has_alloca(Get_Current_PU());
06435 iopc = MTYPE_byte_size(Pointer_Mtype) == 4 ?
06436 INTRN_U4READFRAMEPOINTER : INTRN_U4READFRAMEPOINTER;
06437 intrinsic_op = TRUE;
06438 break;
06439 case BUILT_IN_APPLY_ARGS:
06440 Set_PU_has_alloca(Get_Current_PU());
06441 iopc = INTRN_APPLY_ARGS;
06442 break;
06443 case BUILT_IN_APPLY:
06444 {
06445 WN *load_wn, *sp_addr;
06446
06447 Set_PU_has_alloca(Get_Current_PU());
06448
06449 iopc = INTRN_APPLY;
06450 call_wn = WN_Create (OPR_INTRINSIC_CALL, ret_mtype, MTYPE_V,
06451 num_args);
06452 WN_intrinsic (call_wn) = iopc;
06453 WN_Set_Linenum (call_wn, Get_Srcpos());
06454 WN_Set_Call_Default_Flags (call_wn);
06455 i = 0;
06456 BOOL generate_mload = FALSE;
06457 WN *kid1 = NULL;
06458 WN *kid2 = NULL;
06459 for (list = TREE_OPERAND (exp, 1);
06460 list;
06461 list = TREE_CHAIN (list)) {
06462 arg_wn = WFE_Expand_Expr (TREE_VALUE (list));
06463 if (i == 1)
06464 kid1 = arg_wn;
06465 if (i == 2 &&
06466 WN_operator(arg_wn) != OPR_INTCONST) {
06467 generate_mload = TRUE;
06468 kid2 = arg_wn;
06469 } else if (i == 2)
06470 kid2 = arg_wn;
06471 arg_ty_idx = Get_TY(TREE_TYPE(TREE_VALUE(list)));
06472 arg_mtype = TY_mtype(arg_ty_idx);
06473 arg_wn = WN_CreateParm (Mtype_comparison (arg_mtype),
06474 arg_wn,
06475 arg_ty_idx, WN_PARM_BY_VALUE);
06476 WN_kid (call_wn, i++) = arg_wn;
06477 }
06478
06479
06480 TY_IDX ty_idx =
06481 Make_Pointer_Type (Be_Type_Tbl (MTYPE_V), FALSE);
06482 ST* alloca_st_0 =
06483 Gen_Temp_Symbol (ty_idx,
06484 "__builtin_apply_alloca0");
06485 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL,
06486 alloca_st_0);
06487 WN *alloca_0 =
06488 WN_CreateAlloca (WN_CreateIntconst (OPC_I4INTCONST, 0));
06489 WN *alloca_kid0 = alloca_0;
06490 alloca_kid0 =
06491 WN_Stid (Pointer_Mtype,
06492 0, alloca_st_0, ty_idx, alloca_kid0);
06493 WFE_Stmt_Append (alloca_kid0, Get_Srcpos());
06494 ST *alloca_st_1 =
06495 Gen_Temp_Symbol (ty_idx,
06496 "__builtin_apply_alloca1");
06497 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL,
06498 alloca_st_1);
06499 WN *alloca_1 = WN_CreateAlloca (kid2);
06500 WN *alloca_kid1 = alloca_1;
06501 alloca_kid1 = WN_Stid (Pointer_Mtype,
06502 0, alloca_st_1, ty_idx, alloca_kid1);
06503 WFE_Stmt_Append (alloca_kid1, Get_Srcpos());
06504
06505
06506 kid1 =
06507 WN_CreateIload (OPR_ILOAD, MTYPE_I4, MTYPE_I4, 0,
06508 MTYPE_To_TY(MTYPE_I4),
06509 Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8)),
06510 kid1, 0);
06511 load_wn =
06512 WN_CreateMload (0,
06513 Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8)),
06514 kid1, kid2);
06515 sp_addr = WN_LdidPreg(MTYPE_U4, 29);
06516 WFE_Stmt_Append(WN_CreateMstore (0,
06517 Make_Pointer_Type(MTYPE_To_TY(MTYPE_U8)),
06518 load_wn,
06519 sp_addr,
06520 kid2),
06521 Get_Srcpos());
06522
06523 WFE_Stmt_Append (call_wn, Get_Srcpos());
06524
06525 call_wn = WN_Create (OPR_ICALL, ret_mtype, MTYPE_V, 1);
06526 WN_kid(call_wn, 0) =
06527 WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06528 WN_set_ty (call_wn, TY_pointed(Get_TY(
06529 TREE_TYPE (TREE_VALUE(TREE_OPERAND (exp, 1))))));
06530 WFE_Stmt_Append (call_wn, Get_Srcpos());
06531
06532 TY_IDX tyi;
06533 TY& ty = New_TY(tyi);
06534 TY_Init(ty, 16, KIND_STRUCT, MTYPE_M,
06535 Save_Str("__apply"));
06536 Set_TY_align(tyi, 8);
06537 ST *tmpst = New_ST(CURRENT_SYMTAB);
06538 ST_Init(tmpst, TY_name_idx(ty),
06539 CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, tyi);
06540 Set_ST_is_temp_var(tmpst);
06541 WN *load, *store;
06542 load = WN_LdidPreg(MTYPE_I8, 2);
06543 store = WN_Stid(MTYPE_I8,
06544 (WN_OFFSET)0, tmpst, Spill_Int_Type, load);
06545 WFE_Stmt_Append (store, Get_Srcpos());
06546 load = WN_LdidPreg(MTYPE_F8, 32);
06547 store = WN_Stid(MTYPE_F8,
06548 (WN_OFFSET)8, tmpst, Spill_Int_Type, load);
06549 WFE_Stmt_Append (store, Get_Srcpos());
06550 wn = WN_Lda (Pointer_Mtype, 0, tmpst,
06551 Make_Pointer_Type (ST_type(tmpst), FALSE));
06552
06553
06554 WN *dealloca_wn = WN_CreateDealloca (2);
06555 WN_kid0 (dealloca_wn) =
06556 WN_Ldid (Pointer_Mtype,
06557 0, alloca_st_0, ST_type (alloca_st_0));
06558 WN_kid1 (dealloca_wn) =
06559 WN_Ldid (Pointer_Mtype,
06560 0, alloca_st_1, ST_type (alloca_st_1));
06561 WFE_Stmt_Append (dealloca_wn, Get_Srcpos());
06562
06563 whirl_generated = TRUE;
06564 break;
06565 }
06566 case BUILT_IN_RETURN:
06567 Set_PU_has_alloca(Get_Current_PU());
06568 iopc = INTRN_RETURN;
06569 break;
06570
06571
06572
06573
06574 case BUILT_IN_ISGREATER:
06575 iopc = INTRN_ISGREATER;
06576 intrinsic_op = TRUE;
06577 break;
06578 case BUILT_IN_ISGREATEREQUAL:
06579 iopc = INTRN_ISGREATEREQUAL;
06580 intrinsic_op = TRUE;
06581 break;
06582 case BUILT_IN_ISLESS:
06583 iopc = INTRN_ISLESS;
06584 intrinsic_op = TRUE;
06585 break;
06586 case BUILT_IN_ISLESSEQUAL:
06587 iopc = INTRN_ISLESSEQUAL;
06588 intrinsic_op = TRUE;
06589 break;
06590 case BUILT_IN_ISLESSGREATER:
06591 iopc = INTRN_ISLESSGREATER;
06592 intrinsic_op = TRUE;
06593 break;
06594 case BUILT_IN_ISUNORDERED:
06595 iopc = INTRN_ISUNORDERED;
06596 intrinsic_op = TRUE;
06597 break;
06598
06599 case BUILT_IN_EXPECT:
06600 #ifdef KEY
06601 iopc = INTRN_EXPECT;
06602 intrinsic_op = TRUE;
06603 if (ret_mtype == MTYPE_V) ret_mtype = MTYPE_I4;
06604 #else
06605 wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06606 whirl_generated = TRUE;
06607 #endif
06608 break;
06609
06610 case BUILT_IN_FFS:
06611 iopc = INTRN_I4FFS;
06612 intrinsic_op = TRUE;
06613 if (ret_mtype == MTYPE_V)
06614 ret_mtype = MTYPE_I4;
06615 break;
06616
06617 case BUILT_IN_EXTEND_POINTER:
06618 wn = WFE_Expand_Expr (TREE_VALUE (TREE_OPERAND (exp, 1)));
06619 whirl_generated = TRUE;
06620 break;
06621
06622 case BUILT_IN_POPCOUNT:
06623 case BUILT_IN_POPCOUNTL:
06624 case BUILT_IN_POPCOUNTLL:
06625 iopc = INTRN_POPCOUNT;
06626 intrinsic_op = TRUE;
06627 break;
06628
06629 case BUILT_IN_CTZ:
06630 case BUILT_IN_CTZL:
06631 case BUILT_IN_CTZLL:
06632 iopc = INTRN_CTZ;
06633 intrinsic_op = TRUE;
06634 break;
06635
06636 case BUILT_IN_TRAP:
06637 call_wn = WN_Create (OPR_CALL, MTYPE_V, MTYPE_V, 0);
06638 st = Get_ST (TREE_OPERAND (arg0, 0));
06639 Set_ST_name_idx (st, Save_Str ("abort"));
06640 WN_st_idx (call_wn) = ST_st_idx (st);
06641 WN_Set_Linenum (call_wn, Get_Srcpos());
06642 WN_Set_Call_Default_Flags (call_wn);
06643 WFE_Stmt_Append (call_wn, Get_Srcpos());
06644 whirl_generated = TRUE;
06645 break;
06646
06647 case BUILT_IN_PREFETCH:
06648 {
06649
06650 tree pf_arg = TREE_OPERAND (exp, 1);
06651 WN * pf_addr = WFE_Expand_Expr (TREE_VALUE (pf_arg));
06652
06653
06654 pf_arg = TREE_CHAIN (pf_arg);
06655 UINT32 pf_flag = 0;
06656 int access = 0;
06657 if (pf_arg && TREE_CODE (TREE_VALUE (pf_arg)) == INTEGER_CST)
06658 access = Get_Integer_Value (TREE_VALUE (pf_arg));
06659 if (access == 0)
06660 PF_SET_READ (pf_flag);
06661 else
06662 PF_SET_WRITE (pf_flag);
06663
06664
06665
06666 PF_SET_MANUAL (pf_flag);
06667 WFE_Stmt_Append (WN_CreatePrefetch (0, pf_flag, pf_addr),
06668 Get_Srcpos());
06669 whirl_generated = TRUE;
06670 }
06671 break;
06672 #endif
06673
06674 #ifdef TARG_X8664
06675 case BUILT_IN_COSF:
06676 case BUILT_IN_COSL:
06677 if (!Force_IEEE_Comparisons)
06678 {
06679 iopc = INTRN_COSL;
06680 intrinsic_op = TRUE;
06681 if (ret_mtype != MTYPE_FQ)
06682 {
06683
06684 cvt_to = ret_mtype;
06685 ret_mtype = MTYPE_FQ;
06686 }
06687 }
06688 break;
06689
06690 case BUILT_IN_SINF:
06691 case BUILT_IN_SINL:
06692 if (!Force_IEEE_Comparisons)
06693 {
06694 iopc = INTRN_SINL;
06695 intrinsic_op = TRUE;
06696 if (ret_mtype != MTYPE_FQ)
06697 {
06698
06699 cvt_to = ret_mtype;
06700 ret_mtype = MTYPE_FQ;
06701 }
06702 }
06703 break;
06704 #endif // TARG_X8664
06705
06706 #ifdef KEY
06707 #if !defined(TARG_SL)
06708 case BUILT_IN_TAN:
06709
06710 if (ret_mtype == MTYPE_F8)
06711 {
06712 iopc = INTRN_TAN;
06713 intrinsic_op = TRUE;
06714 }
06715 break;
06716 #endif
06717 #endif
06718 #if defined(TARG_SL)
06719 case BUILT_IN_PERIPHERAL_RW_BEGIN:
06720 iopc = INTRN_PERIPHERAL_RW_BEGIN;
06721 break;
06722 case BUILT_IN_PERIPHERAL_RW_END:
06723 iopc = INTRN_PERIPHERAL_RW_END;
06724 break;
06725 case BUILT_IN_VBUF_OFFSET:
06726 iopc = INTRN_VBUF_OFFSET;
06727 intrinsic_op = TRUE;
06728 break;
06729 case BUILT_IN_VBUF_ABSOLUTE:
06730 iopc = INTRN_VBUF_ABSOLUTE;
06731 intrinsic_op = TRUE;
06732 break;
06733 case BUILT_IN_SBUF_OFFSET:
06734 iopc = INTRN_SBUF_OFFSET;
06735 intrinsic_op = TRUE;
06736 break;
06737 case BUILT_IN_CVT64_HIGH:
06738 iopc = INTRN_CVT64_HIGH;
06739 intrinsic_op = TRUE;
06740 break;
06741 case BUILT_IN_CVT64_LOW:
06742 iopc = INTRN_CVT64_LOW;
06743 intrinsic_op = TRUE;
06744 break;
06745 case BUILT_IN_CVT32:
06746 iopc = INTRN_CVT32;
06747 intrinsic_op = TRUE;
06748 break;
06749 case BUILT_IN_LONGLONG_CVT64_HIGH:
06750 iopc = INTRN_LONGLONG_CVT64_HIGH;
06751 intrinsic_op = TRUE;
06752 break;
06753 case BUILT_IN_LONGLONG_CVT64_LOW:
06754 iopc = INTRN_LONGLONG_CVT64_LOW;
06755 intrinsic_op = TRUE;
06756 break;
06757 case BUILT_IN_C3_INIT_ACC:
06758 iopc = INTRN_C3_INIT_ACC;
06759 break;
06760 case BUILT_IN_C3_SAVE_ACC:
06761 iopc = INTRN_C3_SAVE_ACC;
06762 break;
06763 case BUILT_IN_C3_INIT_ADDR:
06764 iopc = INTRN_C3_INIT_ADDR;
06765 break;
06766 case BUILT_IN_C3_SAVE_ADDR:
06767 iopc = INTRN_C3_SAVE_ADDR;
06768 break;
06769 case BUILT_IN_C3_INIT_DACC:
06770 iopc = INTRN_C3_INIT_DACC;
06771 break;
06772 case BUILT_IN_C3_SAVE_DACC:
06773 iopc = INTRN_C3_SAVE_DACC;
06774 break;
06775 case BUILT_IN_C3_MVFS:
06776 iopc = INTRN_C3_MVFS;
06777 intrinsic_op = TRUE;
06778 break;
06779 case BUILT_IN_SET_ADDR:
06780 iopc = INTRN_C3_SET_ADDR;
06781 break;
06782 case BUILT_IN_SET_CIRCBUF:
06783 iopc = INTRN_C3_SET_CIRCBUF;
06784 break;
06785 case BUILT_IN_C3AADDA:
06786 iopc = INTRN_C3AADDA;
06787 intrinsic_op = TRUE;
06788 break;
06789 case BUILT_IN_C3BITR:
06790 iopc = INTRN_C3BITR;
06791 intrinsic_op = TRUE;
06792 break;
06793 case BUILT_IN_C3CS:
06794 iopc = INTRN_C3CS;
06795 intrinsic_op = TRUE;
06796 break;
06797 case BUILT_IN_C3DADD:
06798 iopc = INTRN_C3DADD;
06799 intrinsic_op = TRUE;
06800 break;
06801 case BUILT_IN_C3DMAC:
06802 iopc = INTRN_C3DMAC;
06803 intrinsic_op = TRUE;
06804 break;
06805 case BUILT_IN_C3DMACA:
06806 iopc = INTRN_C3DMAC_A;
06807 intrinsic_op = TRUE;
06808 break;
06809 case BUILT_IN_C3DMULA:
06810 iopc = INTRN_C3DMULA;
06811 intrinsic_op = TRUE;
06812 break;
06813 case BUILT_IN_C3DMULAA:
06814 iopc = INTRN_C3DMULA_A;
06815 intrinsic_op = TRUE;
06816 break;
06817 case BUILT_IN_C3DSHLLI:
06818 iopc = INTRN_C3DSHLL_I;
06819 intrinsic_op = TRUE;
06820 break;
06821 case BUILT_IN_C3FFE:
06822 iopc = INTRN_C3FFE;
06823 break;
06824 case BUILT_IN_C3LD:
06825 iopc = INTRN_C3LD;
06826 intrinsic_op = TRUE;
06827 break;
06828 case BUILT_IN_C3ST:
06829 iopc = INTRN_C3ST;
06830 break;
06831 case BUILT_IN_C3LEAD:
06832 iopc = INTRN_C3LEAD;
06833 intrinsic_op = TRUE;
06834 break;
06835 case BUILT_IN_C3MAC:
06836 iopc = INTRN_C3MAC;
06837 intrinsic_op = TRUE;
06838 break;
06839 case BUILT_IN_C3MACA:
06840 iopc = INTRN_C3MAC_A;
06841 intrinsic_op = TRUE;
06842 break;
06843 case BUILT_IN_C3MACAR:
06844 iopc = INTRN_C3MAC_AR;
06845 intrinsic_op = TRUE;
06846 break;
06847 case BUILT_IN_C3MACI:
06848 iopc = INTRN_C3MAC_I;
06849 intrinsic_op = TRUE;
06850 break;
06851 case BUILT_IN_C3MULA:
06852 iopc = INTRN_C3MULA;
06853 intrinsic_op = TRUE;
06854 break;
06855 case BUILT_IN_C3MULAA:
06856 iopc =