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
00053
00054
00055
00056
00057
00058 #include <alloca.h>
00059 #include <ctype.h>
00060 #include <vector>
00061
00062 #include <stdint.h>
00063 #include "defs.h"
00064 #include "cg_flags.h"
00065 #include "mempool.h"
00066 #include "wn.h"
00067 #include "symtab.h"
00068 #include "const.h"
00069 #include "erbe.h"
00070 #include "erglob.h"
00071 #include "tracing.h"
00072 #include "config.h"
00073 #include "config_targ_opt.h"
00074 #include "topcode.h"
00075 #include "targ_isa_lits.h"
00076 #include "intrn_info.h"
00077 #include "opcode.h"
00078 #include "w2op.h"
00079 #include "wn_util.h"
00080 #include "ir_reader.h"
00081 #include "region_util.h"
00082 #include "cg_region.h"
00083 #include "bb.h"
00084 #include "op.h"
00085 #include "tn.h"
00086 #include "register.h"
00087 #include "calls.h"
00088 #include "cgexp.h"
00089 #include "stblock.h"
00090 #include "targ_sim.h"
00091 #include "irbdata.h"
00092 #include "ttype.h"
00093 #include "op_map.h"
00094 #include "pf_cg.h"
00095 #include "wn_map.h"
00096 #include "whirl2ops.h"
00097 #include "gtn_universe.h"
00098 #include "cg.h"
00099 #include "cg_internal.h"
00100 #include "variants.h"
00101 #include "targ_sim.h"
00102 #include "eh_region.h"
00103 #include "fb_whirl.h"
00104 #include "xstats.h"
00105 #include "data_layout.h"
00106 #include "cgtarget.h"
00107 #include "cg_spill.h"
00108 #include "label_util.h"
00109 #include "comment.h"
00110 #include "be_symtab.h"
00111 #include "be_util.h"
00112 #include "config_asm.h"
00113
00114 #if defined(TARG_X8664) || defined(TARG_NVISA) || defined(TARG_SL)
00115 #include "cgexp_internals.h"
00116 #else
00117 #define OP_NEED_PAIR(t) (0)
00118 #define Create_TN_Pair(x,y)
00119 #endif
00120 #ifdef KEY
00121 #include "cxx_template.h"
00122 #endif
00123
00124 #ifdef EMULATE_LONGLONG
00125 extern void Add_TN_Pair (TN*, TN*);
00126 extern TN *If_Get_TN_Pair(TN*);
00127 extern TN *Gen_Literal_TN_Pair(UINT64);
00128 #endif
00129
00130 BOOL Compiling_Proper_REGION;
00131 static BOOL Trace_WhirlToOp = FALSE;
00132
00133
00134 static BOOL dedicated_seen;
00135
00136 static BOOL In_Glue_Region = FALSE;
00137
00138
00139 #if !defined(TARG_SL)
00140 static TN * Expand_Expr (WN *expr, WN *parent, TN *result);
00141 #endif
00142 static void initialize_region_stack(WN *);
00143 static RID *region_stack_pop(void);
00144 static void region_stack_push(RID *value);
00145 static void region_stack_eh_set_has_call(void);
00146 static VARIANT WHIRL_Compare_To_OP_variant (OPCODE opcode, BOOL invert);
00147
00148 #ifdef KEY
00149
00150 #define WHIRL2OPS_STATIC
00151 #else
00152 #define WHIRL2OPS_STATIC static
00153 #endif
00154
00155
00156
00157
00158 WHIRL2OPS_STATIC OPS New_OPs;
00159
00160 WHIRL2OPS_STATIC OP *Last_Processed_OP;
00161 WHIRL2OPS_STATIC SRCPOS current_srcpos;
00162 WHIRL2OPS_STATIC INT total_bb_insts;
00163
00164
00165 WHIRL2OPS_STATIC BB *Cur_BB;
00166
00167 static RID **region_stack_base;
00168 static RID **region_stack_ptr;
00169 static INT region_stack_size;
00170 #define current_region (*(region_stack_ptr - 1))
00171 #define region_depth (region_stack_ptr - region_stack_base)
00172 static BB_NUM min_bb_id;
00173
00174 static WN *last_loop_pragma;
00175
00176 #define return_max 3
00177
00178
00179
00180
00181
00182
00183 static OP *Last_Mem_OP;
00184 OP_MAP OP_to_WN_map;
00185 static OP_MAP predicate_map = NULL;
00186 static WN_MAP WN_to_OP_map;
00187
00188 OP_MAP OP_Ld_GOT_2_Sym_Map;
00189
00190 OP_MAP OP_Asm_Map;
00191
00192 #ifdef TARG_IA64
00193 inline BOOL
00194 WN_Is_Bool_Operator(WN* expr)
00195 {
00196 OPERATOR opr;
00197 opr = WN_operator(expr);
00198 if(opr == OPR_EQ ||
00199 opr == OPR_NE ||
00200 opr == OPR_LE ||
00201 opr == OPR_LT ||
00202 opr == OPR_GE ||
00203 opr == OPR_GT )
00204 {
00205 return TRUE;
00206 }else{
00207 return FALSE;
00208 }
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218 inline BOOL
00219 WN_Is_Convert_Bool(WN* expr)
00220 {
00221 if(WN_operator_is(expr,OPR_CVT) &&
00222 WN_desc(expr) == MTYPE_B &&
00223 WN_operator_is(WN_kid0(expr),OPR_LDID) &&
00224 WN_rtype(WN_kid0(expr)) == MTYPE_B &&
00225 WN_class(WN_kid0(expr)) == CLASS_PREG){
00226 return TRUE;
00227 }else{
00228 return FALSE;
00229 }
00230 }
00231
00232
00233 inline BOOL
00234 Is_Old_Boolean_Expression(WN* expr)
00235 {
00236 if(WN_opcode(expr) == OPC_I8BAND ||
00237 WN_opcode(expr) == OPC_I8BIOR )
00238 {
00239 WN* kid0 = WN_kid0(expr);
00240 WN* kid1 = WN_kid1(expr);
00241 if((WN_Is_Bool_Operator(kid0) || WN_Is_Convert_Bool(kid0)) &&
00242 (WN_Is_Bool_Operator(kid1) || WN_Is_Convert_Bool(kid1))){
00243 return TRUE;
00244 }
00245 }
00246 return FALSE;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 static TN*
00335 Handle_Bool_As_Predicate(WN*condition, WN*parent, BOOL invert)
00336 {
00337 WN* kid0 = NULL;
00338 WN* kid1 = NULL;
00339 OP* last_op = NULL;
00340 OP* kid0_last_op = NULL;
00341 OP* kid1_last_op = NULL;
00342 TN* kid0_result = NULL;
00343 TN* kid1_result = NULL;
00344 TN* predicate_result0 = NULL;
00345 TN* predicate_result1 = NULL;
00346 TN* guarder = NULL;
00347 OP* first_guardee = NULL;
00348 OP *preset_op = NULL;
00349 OPERATOR condition_opr = WN_operator(condition);
00350
00351 if (Trace_WhirlToOp)
00352 fprintf(TFile, "Use Predicate register to replace band/bior operation in boolean expression!\n");
00353
00354 kid0 = WN_kid0(condition);
00355 kid1 = WN_kid1(condition);
00356 kid0_result = Build_TN_Of_Mtype(MTYPE_B);
00357 kid1_result = Build_TN_Of_Mtype(MTYPE_B);
00358
00359 last_op = OPS_last(&New_OPs);
00360
00361 if(WN_Is_Bool_Operator(kid0)){
00362 Expand_Expr(kid0, condition, kid0_result);
00363 }else if(WN_Is_Convert_Bool(kid0)){
00364 kid0_result = Expand_Expr(WN_kid0(kid0), kid0, NULL);
00365 Is_True(OPS_last(&New_OPs) == last_op,("kid0: kid of CVT can not generate new OPs!"));
00366 }else{
00367 Is_True(FALSE,("Can not handle operators other than bool and convert!"));
00368 }
00369 kid0_last_op = OPS_last(&New_OPs);
00370
00371 if(WN_Is_Bool_Operator(kid1)){
00372 Expand_Expr(kid1, condition, kid1_result);
00373 }else if(WN_Is_Convert_Bool(kid1)){
00374 kid1_result = Expand_Expr(WN_kid0(kid1), kid0, NULL);
00375 Is_True(OPS_last(&New_OPs) == kid0_last_op,("kid1: kid of CVT can not generate new OPs!"));
00376 }else{
00377 Is_True(FALSE,("Can not handle operators other than bool and convert!"));
00378 }
00379 kid1_last_op = OPS_last(&New_OPs);
00380
00381 if(WN_Is_Convert_Bool(kid0) && WN_Is_Convert_Bool(kid1)){
00382
00383
00384 Is_True(kid0_last_op == last_op,("CVT-LDID can not generate OPs!"));
00385 Is_True(kid1_last_op == last_op,("CVT-LDID can not generate OPs!"));
00386
00387 predicate_result0 = Build_TN_Of_Mtype(MTYPE_B);
00388 predicate_result1 = Build_TN_Of_Mtype(MTYPE_B);
00389
00390 TN* kid0_guard = condition_opr == OPR_BIOR ? kid0_result : Get_Complement_TN(kid0_result);
00391 TN* kid1_guard = condition_opr == OPR_BIOR ? kid1_result : Get_Complement_TN(kid1_result);
00392
00393 OP* op1;
00394 OP* op2;
00395 if(condition_opr == OPR_BIOR){
00396 op1 = Mk_OP(TOP_cmp_eq_or_andcm, predicate_result0, predicate_result1, kid0_guard, Zero_TN, Zero_TN);
00397 op2 = Mk_OP(TOP_cmp_eq_or_andcm, predicate_result0, predicate_result1, kid1_guard, Zero_TN, Zero_TN);
00398 preset_op = Mk_OP(TOP_cmp_eq, predicate_result1, predicate_result0, True_TN, Zero_TN, Zero_TN);
00399 }else if(condition_opr == OPR_BAND){
00400 op1 = Mk_OP(TOP_cmp_eq_or_andcm, predicate_result1, predicate_result0, kid0_guard, Zero_TN, Zero_TN);
00401 op2 = Mk_OP(TOP_cmp_eq_or_andcm, predicate_result1, predicate_result0, kid1_guard, Zero_TN, Zero_TN);
00402 preset_op = Mk_OP(TOP_cmp_eq, predicate_result0, predicate_result1, True_TN, Zero_TN, Zero_TN);
00403 }else{
00404 Is_True(FALSE,("Can not get to here!"));
00405 }
00406 OPS_Append_Op(&New_OPs,preset_op);
00407 OPS_Append_Op(&New_OPs,op1);
00408 OPS_Append_Op(&New_OPs,op2);
00409
00410 }else{
00411
00412 if(WN_Is_Convert_Bool(kid0) || WN_Is_Convert_Bool(kid1)){
00413
00414
00415 TN* tmp_pred;
00416 if(WN_Is_Convert_Bool(kid0)){
00417 tmp_pred = kid0_result;
00418 }else{
00419 tmp_pred = kid1_result;
00420 }
00421 guarder = condition_opr == OPR_BAND ? tmp_pred : Get_Complement_TN(tmp_pred);
00422 first_guardee = last_op == NULL ? OPS_first(&New_OPs) : OP_next(last_op);
00423 FmtAssert(first_guardee != NULL, ("boolean expression doesn't generate OPs"));
00424
00425 }else{
00426
00427
00428 Is_True(WN_Is_Bool_Operator(kid0) && WN_Is_Bool_Operator(kid1),("kid0 and kid1 should be boolean expression!"));
00429 guarder = OP_result(kid0_last_op, condition_opr == OPR_BAND ? 0:1);
00430 first_guardee = OP_next(kid0_last_op);
00431 FmtAssert(first_guardee != NULL, ("boolean expression doesn't generate OPs"));
00432 }
00433
00434 BOOL all_true = TRUE;
00435 for(OP* op = first_guardee; op; op = OP_next(op)){
00436 if(OP_opnd(op,0) != True_TN)
00437 all_true = FALSE;
00438 }
00439
00440 if(all_true){
00441 for(OP* op = first_guardee; op; op = OP_next(op)){
00442 Set_OP_opnd(op, 0, guarder);
00443 }
00444 }else{
00445 Set_OP_opnd(kid1_last_op, 0, guarder);
00446 }
00447
00448 predicate_result0 = OP_result(kid1_last_op, 0);
00449 predicate_result1 = OP_result(kid1_last_op, 1);
00450
00451
00452
00453
00454 if(condition_opr == OPR_BAND) {
00455 preset_op = Mk_OP(TOP_cmp_eq_unc, predicate_result1, predicate_result0, True_TN, Zero_TN, Zero_TN);
00456 OPS_Insert_Op_Before(&New_OPs, first_guardee, preset_op);
00457 }else if(condition_opr == OPR_BIOR) {
00458 preset_op = Mk_OP(TOP_cmp_eq_unc, predicate_result0, predicate_result1, True_TN, Zero_TN, Zero_TN);
00459 OPS_Insert_Op_Before(&New_OPs, first_guardee, preset_op);
00460 }else{
00461 FmtAssert(FALSE, ("Condition error. This should never happen.\n"));
00462 }
00463 }
00464
00465 if (Trace_WhirlToOp) {
00466 fprintf(TFile, "After if-conv has been done: \n");
00467 OP* op = last_op == NULL ? OPS_first(&New_OPs) : OP_next(last_op);
00468 for(; op; op = OP_next(op)){
00469 Print_OP(op);
00470 }
00471 }
00472
00473
00474 WN_set_rtype(condition, MTYPE_B);
00475 return (invert) ? predicate_result1 : predicate_result0;
00476 }
00477 #endif
00478
00479 TN *
00480 Get_Complement_TN(TN *tn)
00481 {
00482 TN *c_tn;
00483 PREG_NUM preg = TN_To_PREG(tn);
00484 if (preg != 0) {
00485 PREG_NUM c_preg = preg + 1;
00486 c_tn = PREG_To_TN_Array[c_preg];
00487 } else {
00488 c_tn = Build_TN_Like(tn);
00489 }
00490 return c_tn;
00491 }
00492
00493
00494 void Copy_WN_For_Memory_OP(OP *dest, OP *src)
00495 {
00496 WN *wn = Get_WN_From_Memory_OP(src);
00497 UINT64 predicate = predicate_map ? OP_MAP64_Get(predicate_map, src) : 0;
00498 if (wn)
00499 OP_MAP_Set(OP_to_WN_map, dest, wn);
00500 if (predicate)
00501 OP_MAP64_Set(predicate_map, dest, predicate);
00502 #ifdef TARG_X8664
00503 if( Is_Target_32bit() &&
00504 OP_memory_hi( src ) ){
00505 Set_OP_memory_hi( dest );
00506 }
00507 #endif
00508 }
00509
00510
00511 OP *Get_OP_From_WN(WN *wn )
00512 {
00513 return (OP*) WN_MAP_Get(WN_to_OP_map, wn);
00514 }
00515
00516
00517 void Set_Memory_OP_Predicate_Info(OP *memop, TN *pred_tn, UINT8 omega,
00518 BOOL inverted)
00519 {
00520 UINT64 predicate = pred_tn ?
00521 (TN_number(pred_tn) | (UINT64)omega << 32 | (UINT64)inverted << 40) : 0;
00522 if (predicate_map == NULL && predicate) predicate_map = OP_MAP64_Create();
00523 if (predicate || predicate_map && OP_MAP64_Get(predicate_map, memop))
00524 OP_MAP64_Set(predicate_map, memop, predicate);
00525 }
00526
00527 void Get_Memory_OP_Predicate_Info(OP *memop, TN **pred_tn, UINT8 *omega,
00528 BOOL *inverted)
00529 {
00530 UINT64 predicate = predicate_map ? OP_MAP64_Get(predicate_map, memop) : 0;
00531 *pred_tn = predicate ? TNvec(predicate & 0xffffffff) : NULL;
00532 *omega = (predicate >> 32) & 0xff;
00533 *inverted = (predicate >> 40) & 1;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 static void initialize_region_stack(WN *wn)
00547 {
00548 RID *rid = REGION_get_rid(wn);
00549 Is_True(rid != NULL, ("initialize_region_stack, NULL RID"));
00550
00551 region_stack_size = 8;
00552 region_stack_base = TYPE_MEM_POOL_ALLOC_N( RID *, &MEM_local_pool,
00553 region_stack_size );
00554 region_stack_ptr = region_stack_base;
00555
00556 region_stack_push( rid );
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 static RID *region_stack_pop(void)
00568 {
00569 if ( region_stack_ptr == region_stack_base )
00570 return NULL;
00571 else
00572 return *(--region_stack_ptr);
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 static void region_stack_push(RID *value)
00584 {
00585 *(region_stack_ptr++) = value;
00586 if ( ( region_stack_ptr - region_stack_base ) == region_stack_size ) {
00587 region_stack_base = TYPE_MEM_POOL_REALLOC_N( RID *, &MEM_local_pool,
00588 region_stack_base, region_stack_size,
00589 2 * region_stack_size );
00590 region_stack_ptr = region_stack_base + region_stack_size;
00591 region_stack_size = 2 * region_stack_size;
00592 }
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 static void region_stack_eh_set_has_call(void)
00605 {
00606 RID ** p;
00607 for (p = region_stack_ptr - 1; p >= region_stack_base; --p)
00608 #ifdef KEY
00609 if (RID_TYPE_eh(*p) && RID_eh_range_ptr(*p))
00610 #else
00611 if (RID_TYPE_eh(*p))
00612 #endif
00613 EH_Set_Has_Call(RID_eh_range_ptr(*p));
00614 }
00615
00616
00617
00618 #ifndef TARG_IA64
00619 static BOOL WN_pragma_preamble_end_seen = FALSE;
00620
00621 BOOL W2OPS_Pragma_Preamble_End_Seen ()
00622 {
00623 return WN_pragma_preamble_end_seen;
00624 }
00625 #endif
00626
00627
00628
00629
00630
00631 #ifndef KEY
00632 static
00633 #endif
00634 void
00635 Process_New_OPs (void)
00636 {
00637 OP *op;
00638 INT i;
00639
00640 op = Last_Processed_OP ? OP_next(Last_Processed_OP) : OPS_first(&New_OPs);
00641
00642 for (; op != NULL; op = OP_next(op)) {
00643 for (i = OP_opnds(op)-1; i >= 0; i--) {
00644 if (OP_opnd(op,i) == GP_TN) PU_References_GP = TRUE;
00645 }
00646 OP_srcpos(op) = current_srcpos;
00647 total_bb_insts++;
00648 #ifndef TARG_IA64
00649 if (WN_pragma_preamble_end_seen) {
00650 Set_OP_first_after_preamble_end(op);
00651 WN_pragma_preamble_end_seen = FALSE;
00652 }
00653 #endif
00654 }
00655 Last_Processed_OP = OPS_last(&New_OPs);
00656 }
00657
00658 #ifdef EMULATE_LONGLONG
00659
00660
00661
00662
00663
00664
00665
00666
00667 static void
00668 Update_BB_Properties (BB *orig_bb, BB *new_bb) {
00669
00670 BB_rid(new_bb) = BB_rid(orig_bb);
00671
00672 ANNOTATION *ant = BB_annotations(orig_bb);
00673
00674 while (ant) {
00675 switch (ANNOT_kind(ant)) {
00676 case ANNOT_LABEL:
00677
00678 break;
00679 case ANNOT_PRAGMA:
00680 #pragma mips_frequency_hint NEVER
00681 FmtAssert (FALSE,
00682 ("Update_BB_Properties: foxed by pragma annotation\n"));
00683
00684
00685 case ANNOT_ENTRYINFO:
00686
00687 Reset_BB_entry(new_bb);
00688 break;
00689 case ANNOT_EXITINFO:
00690 case ANNOT_CALLINFO:
00691 case ANNOT_ASMINFO:
00692
00693 BB_annotations(orig_bb) = ANNOT_Unlink(BB_annotations(orig_bb),
00694 ant);
00695 ANNOT_next(ant) = BB_annotations(new_bb);
00696 BB_annotations(new_bb) = ant;
00697
00698 if (ANNOT_kind(ant) == ANNOT_CALLINFO) {
00699 Reset_BB_call(orig_bb);
00700 Set_BB_call(new_bb);
00701 } else if (ANNOT_kind(ant) == ANNOT_ASMINFO) {
00702 Reset_BB_asm(orig_bb);
00703 Set_BB_asm(new_bb);
00704 } else {
00705 Reset_BB_exit(orig_bb);
00706 Set_BB_exit(new_bb);
00707 }
00708 break;
00709 case ANNOT_NOTE:
00710 break;
00711 case ANNOT_LOOPINFO:
00712 case ANNOT_SWITCH:
00713 case ANNOT_ROTATING_KERNEL:
00714 default:
00715 #pragma mips_frequency_hint NEVER
00716 FmtAssert (FALSE,
00717 ("Update_BB_Properties: Unknown annotation %d\n", ANNOT_kind(ant)));
00718
00719 }
00720 ant = ANNOT_next(ant);
00721 }
00722
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 static BB *
00736 Split_Jumpy_BB (BB *bb) {
00737
00738 BOOL need_to_split = FALSE;
00739 OP *op;
00740 for (op = BB_first_op(bb); op; op = OP_next(op)) {
00741 if (OP_xfer(op) && op != BB_last_op(bb)) {
00742 need_to_split = TRUE;
00743 break;
00744 }
00745 if (OP_code(op) == TOP_label) {
00746 need_to_split = TRUE;
00747 break;
00748 }
00749 if (op == BB_last_op(bb)) break;
00750 }
00751
00752 if (!need_to_split) return bb;
00753
00754
00755 for (op = BB_first_op(bb); op; ) {
00756
00757
00758 if (OP_xfer(op) && op != BB_last_op(bb)) {
00759 BB *new_bb = Gen_And_Append_BB (bb);
00760 op = OP_next(op);
00761
00762 while (op) {
00763 OP *tmp_op = OP_next(op);
00764 BB_Move_Op_To_End (new_bb, bb, op);
00765 op = tmp_op;
00766 }
00767
00768 Update_BB_Properties (bb, new_bb);
00769 bb = new_bb;
00770 op = BB_first_op(new_bb);
00771 continue;
00772 }
00773
00774
00775 if (OP_code(op) == TOP_label) {
00776 BB *new_bb = Gen_And_Append_BB (bb);
00777 while (op) {
00778 OP *tmp_op = OP_next(op);
00779 BB_Move_Op_To_End (new_bb, bb, op);
00780 op = tmp_op;
00781 }
00782
00783
00784
00785 Update_BB_Properties (bb, new_bb);
00786 bb = new_bb;
00787 op = BB_first_op(new_bb);
00788 Is_True (OP_code(op) == TOP_label,
00789 ("Split_Jumpy_BB: where did the dummy label go?"));
00790 TN *label_tn = OP_opnd(op,0);
00791 LABEL_IDX label = TN_label(label_tn);
00792 BB_Add_Annotation(bb, ANNOT_LABEL, (void*) label);
00793 FmtAssert (Get_Label_BB(label) == NULL,
00794 ("Split_Jumpy_BB: Label %s defined more than once",
00795 LABEL_name(label)));
00796 Set_Label_BB (label,bb);
00797 Set_BB_has_label(bb);
00798 BB_Remove_Op (bb, op);
00799 op = BB_first_op(bb);
00800 continue;
00801 }
00802
00803 if (op == BB_last_op(bb)) break;
00804
00805 op = OP_next(op);
00806 }
00807
00808 return bb;
00809 }
00810 #endif
00811
00812
00813
00814
00815
00816 static BB *
00817 Start_New_Basic_Block (void)
00818 {
00819 BB *bb = Cur_BB;
00820
00821 if (bb == NULL) {
00822
00823
00824 bb = Gen_And_Append_BB (bb);
00825 REGION_First_BB = bb;
00826 }
00827
00828 FmtAssert (BB_first_op(bb) == NULL, ("Start_New_Basic_Block: error"));
00829
00830 if (OPS_first(&New_OPs) != NULL) {
00831 Process_New_OPs ();
00832 BB_Append_Ops(bb, &New_OPs);
00833 OPS_Init(&New_OPs);
00834 #ifdef EMULATE_LONGLONG
00835 bb = Split_Jumpy_BB (bb);
00836 #endif
00837 if ( dedicated_seen )
00838 Set_BB_has_globals( bb );
00839 else
00840 Reset_BB_has_globals( bb );
00841 bb = Gen_And_Append_BB (bb);
00842 } else if (BB_entry(bb) || BB_exit(bb)) {
00843
00844
00845
00846 bb = Gen_And_Append_BB (bb);
00847 }
00848
00849 if (PU_has_region(Get_Current_PU()))
00850 BB_rid(bb) = Non_Transparent_RID(current_region);
00851 else
00852 BB_rid(bb) = NULL;
00853
00854 #ifdef TARG_SL //minor_reg_alloc
00855
00856
00857
00858
00859
00860 if(RID_TYPE_minor(current_region)) {
00861 if(RID_parent(current_region) && RID_TYPE_minor(RID_parent(current_region))) {
00862 BB_rid(bb) = current_region;
00863 }
00864 else {
00865
00866 BB_rid(bb) = NULL;
00867 }
00868 }
00869 else {
00870
00871
00872
00873
00874 if(BB_rid(bb) && !RID_TYPE_major(BB_rid(bb)))
00875 BB_rid(bb) = NULL;
00876 }
00877 #endif
00878
00879
00880
00881 total_bb_insts = 0;
00882 Last_Processed_OP = NULL;
00883 Last_Mem_OP = NULL;
00884 Cur_BB = bb;
00885 dedicated_seen = FALSE;
00886
00887 return bb;
00888 }
00889
00890
00891
00892
00893
00894 static void
00895 Process_OPs_For_Stmt (void)
00896 {
00897 Process_New_OPs ();
00898
00899 #if 0 // now done later in Split_BBs()
00900 if (Enable_BB_Splitting && (total_bb_insts > Split_BB_Length)) {
00901
00902
00903
00904 FmtAssert (total_bb_insts < 32768,
00905 ("Convert_WHIRL_To_OPs: Too many instructions for 1 statment (%d)\n",
00906 total_bb_insts));
00907 if (Trace_WhirlToOp) {
00908 fprintf (TFile, "Convert_WHIRL_To_OPs: splitting a large BB (%d)\n",
00909 total_bb_insts);
00910 }
00911 Start_New_Basic_Block ();
00912 }
00913 #endif
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 static TN *
00925 Allocate_Result_TN (WN *wn, TN **opnd_tn)
00926 {
00927 #ifdef TARG_SL
00928
00929 #ifdef EMULATE_LONGLONG
00930 TYPE_ID mtype = WN_rtype(wn);
00931 if (MTYPE_is_longlong(mtype)) {
00932 TYPE_ID new_mtype = (mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
00933 TN *tn = Build_TN_Of_Mtype (new_mtype);
00934 TN *tn2 = Build_TN_Of_Mtype (new_mtype);
00935 Add_TN_Pair (tn, tn2);
00936 return tn;
00937 }
00938 #endif
00939
00940 #ifdef EMULATE_FLOAT_POINT
00941 if (mtype == MTYPE_F8) {
00942 TN *tn = Build_TN_Of_Mtype(MTYPE_U4);
00943 TN *pair = Build_TN_Of_Mtype(MTYPE_U4);
00944 Add_TN_Pair (tn, pair);
00945 return tn;
00946 } else if (mtype = MTYPE_F4) {
00947 return Build_TN_Of_Mtype(MTYPE_U4);
00948 }
00949 #endif
00950
00951 return Build_TN_Of_Mtype (mtype);
00952
00953 #else // !defined(TARG_SL)
00954
00955 #ifdef EMULATE_LONGLONG
00956
00957 TYPE_ID mtype = WN_rtype(wn);
00958 if (mtype == MTYPE_I8 || mtype == MTYPE_U8) {
00959 TYPE_ID new_mtype = (mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
00960 TN *tn = Build_TN_Of_Mtype (new_mtype);
00961 TN *tn2 = Build_TN_Of_Mtype (new_mtype);
00962 Add_TN_Pair (tn, tn2);
00963 return tn;
00964 }
00965 else return Build_TN_Of_Mtype (WN_rtype(wn));
00966
00967 #else
00968 #ifdef TARG_X8664
00969 if (Is_Target_64bit() && WN_operator(wn) == OPR_INTRINSIC_OP &&
00970 ((INTRINSIC) WN_intrinsic(wn)) == INTRN_CTZ)
00971
00972 return Build_TN_Of_Mtype (WN_rtype(WN_kid0(wn)));
00973 else
00974 #endif
00975 return Build_TN_Of_Mtype (WN_rtype(wn));
00976
00977 #endif // defined(TARG_SL)
00978 #endif
00979 }
00980
00981
00982
00983
00984 #if !defined(TARG_SL)
00985 static
00986 #endif
00987 void
00988 Set_OP_To_WN_Map(WN *wn)
00989 {
00990 OP *op;
00991
00992
00993 if (CG_opt_level < 2) return;
00994
00995 op = Last_Mem_OP ? OP_next(Last_Mem_OP) : OPS_first(&New_OPs);
00996 for ( ; op != NULL; op = OP_next(op)) {
00997 if ( (!OP_memory(op)
00998 #ifndef KEY
00999
01000
01001 || OP_no_alias(op)
01002 #endif
01003 ) && !OP_call(op)
01004 && !CGTARG_Is_OP_Barrier(op) && OP_code(op) != TOP_spadjust)
01005 continue;
01006 if (OP_memory(op) && WN_Is_Volatile_Mem(wn)) Set_OP_volatile(op);
01007 if (OP_prefetch(op)) {
01008
01009
01010
01011
01012
01013
01014
01015 if (OP_to_WN_map == NULL) {
01016 OP_to_WN_map = OP_MAP_Create();
01017 Is_True(WN_to_OP_map == WN_MAP_UNDEFINED,
01018 ("WN_to_OP_map has already been created"));
01019 WN_to_OP_map = WN_MAP_Create(&MEM_phase_pool);
01020 }
01021 OP_MAP_Set(OP_to_WN_map, op, wn);
01022 WN_MAP_Set(WN_to_OP_map, wn, op);
01023 } else if (Alias_Manager) {
01024 OP_MAP_Set(OP_to_WN_map, op, wn);
01025 }
01026 }
01027
01028 Last_Mem_OP = OPS_last(&New_OPs);
01029 }
01030
01031
01032 static BOOL Disallowed_Homeable(ST *sym)
01033 {
01034 if (Is_Structure_Type(ST_type(sym))) {
01035 return TRUE;
01036 } else if (TY_kind(ST_type(sym)) == KIND_ARRAY &&
01037 (TY_kind(TY_AR_etype(ST_type(sym))) == KIND_STRUCT ||
01038 TY_kind(TY_AR_etype(ST_type(sym))) == KIND_ARRAY)) {
01039 return TRUE;
01040 }
01041 return FALSE;
01042 }
01043
01044
01045
01046
01047
01048 extern WN*
01049 Preg_Is_Rematerializable(PREG_NUM preg, BOOL *gra_homeable)
01050 {
01051 WN *home= Preg_Home(preg);
01052 OPCODE opc;
01053
01054 if (home == NULL)
01055 return NULL;
01056 opc = WN_opcode(home);
01057
01058 #ifdef TARG_X8664
01059
01060
01061
01062
01063
01064
01065 if( OP_NEED_PAIR( OPCODE_rtype(opc) ) ){
01066 return NULL;
01067 }
01068
01069 if( mcmodel >= MEDIUM ){
01070 return NULL;
01071 }
01072 #endif
01073
01074
01075 if (WN_operator(home) == OPR_LDID) {
01076 ST *sym = WN_st(home);
01077 ST *basesym = Base_Symbol(sym);
01078 TYPE_ID rtype = OPCODE_rtype(opc);
01079
01080 #ifdef KEY
01081 if (ST_sclass(sym) == SCLASS_FORMAL_REF)
01082 return NULL;
01083 if (ST_is_uplevelTemp(sym))
01084 return NULL;
01085 #endif
01086
01087
01088
01089
01090
01091 if (MTYPE_is_quad(rtype)) {
01092 return NULL;
01093 }
01094 if (MTYPE_is_complex(rtype)) {
01095 return NULL;
01096 }
01097
01098
01099
01100
01101
01102 if ( !Alias_Manager ) {
01103 return NULL;
01104 }
01105
01106
01107
01108
01109 if (GRA_home == TRUE && !Disallowed_Homeable(sym) &&
01110 ST_class(sym) == CLASS_VAR) {
01111 #if !defined(TARG_X8664) && !defined(TARG_IA32) && !defined(TARG_NVISA) // skip test of GPREL for CISC's
01112 if (ST_gprel(basesym) ||
01113 (ST_is_split_common(basesym) && ST_gprel(ST_full(basesym)))
01114 || ST_on_stack(sym))
01115 #endif
01116 {
01117 #ifdef KEY
01118 if( gra_homeable != NULL )
01119 #endif
01120 *gra_homeable = TRUE;
01121 return home;
01122 }
01123 }
01124 return NULL;
01125 }
01126 if (MTYPE_is_complex(OPCODE_rtype(opc)))
01127 return NULL;
01128 if (MTYPE_is_quad(OPCODE_rtype(opc)))
01129 return NULL;
01130 if (OPCODE_has_sym(opc) && ST_is_uplevelTemp(WN_st(home)))
01131 return NULL;
01132
01133 return home;
01134 }
01135
01136
01137 TN **PREG_To_TN_Array;
01138 TYPE_ID *PREG_To_TN_Mtype;
01139 static PREG_NUM max_preg_to_tn_index = 0;
01140
01141
01142 static void Realloc_Preg_To_TN_Arrays (PREG_NUM preg_num)
01143 {
01144 if (preg_num < max_preg_to_tn_index) return;
01145
01146 max_preg_to_tn_index = Get_Preg_Num (PREG_Table_Size(CURRENT_SYMTAB));
01147 PREG_To_TN_Array = TYPE_MEM_POOL_REALLOC_N( TN *, &MEM_pu_pool,
01148 PREG_To_TN_Array, max_preg_to_tn_index, max_preg_to_tn_index + 10);
01149 PREG_To_TN_Mtype = TYPE_MEM_POOL_REALLOC_N( TYPE_ID, &MEM_pu_pool,
01150 PREG_To_TN_Mtype, max_preg_to_tn_index, max_preg_to_tn_index + 10);
01151 max_preg_to_tn_index += 10;
01152 }
01153
01154
01155
01156
01157
01158
01159 TN *
01160 PREG_To_TN (TY_IDX preg_ty, PREG_NUM preg_num)
01161 {
01162 TN *tn;
01163 TYPE_ID mtype = TY_mtype(preg_ty);
01164
01165 #ifdef TARG_NVISA
01166
01167
01168 ISA_REGISTER_CLASS rclass;
01169 REGISTER reg;
01170 if (CURRENT_SYMTAB == GLOBAL_SYMTAB
01171 && preg_num <= Last_Dedicated_Preg_Offset
01172 && CGTARG_Preg_Register_And_Class(preg_num, &rclass, ®))
01173 {
01174 return Build_Dedicated_TN(rclass, reg, TY_size(preg_ty));
01175 }
01176 #endif
01177 Is_True((preg_num <= Get_Preg_Num(PREG_Table_Size(CURRENT_SYMTAB))),
01178 ("PREG_To_TN(): preg %d > SYMTAB_last_preg(%d)",
01179 preg_num, Get_Preg_Num(PREG_Table_Size(CURRENT_SYMTAB))));
01180
01181 tn = PREG_To_TN_Array[preg_num];
01182 #ifdef KEY
01183 Is_True(preg_num > 0, ("PREG_To_TN: non-positive preg_num"));
01184 #endif
01185 if (tn == NULL)
01186 {
01187 ISA_REGISTER_CLASS rclass;
01188 REGISTER reg;
01189
01190 if (CGTARG_Preg_Register_And_Class(preg_num, &rclass, ®))
01191 {
01192 Is_True(!Is_Predicate_REGISTER_CLASS(rclass),
01193 ("don't support dedicate predicate pregs"));
01194 #ifdef HAS_STACKED_REGISTERS
01195 if (ABI_PROPERTY_Is_stacked(
01196 rclass,
01197 REGISTER_machine_id(rclass, reg) ))
01198 {
01199 reg = REGISTER_Allocate_Stacked_Register(
01200 (Is_Int_Output_Preg(preg_num) ? ABI_PROPERTY_caller
01201 : ABI_PROPERTY_callee),
01202 rclass, reg);
01203
01204 if (PU_has_syscall_linkage(Get_Current_PU())
01205 && ! Is_Int_Output_Preg(preg_num))
01206 {
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217 REGISTER_Unallocate_Stacked_Register (rclass, reg);
01218 }
01219 }
01220 #endif
01221 tn = Build_Dedicated_TN(rclass, reg, TY_size(preg_ty));
01222 #if defined(TARG_SL) && defined(EMULATE_LONGLONG)
01223 if (mtype == MTYPE_I8 || mtype == MTYPE_U8) {
01224 TN* pair = Build_Dedicated_TN(rclass, reg+1, TY_size(preg_ty));
01225 Add_TN_Pair(tn, pair);
01226 }
01227 #endif
01228 #if defined(TARG_SL) && defined(EMULATE_FLOAT_POINT)
01229 if (mtype == MTYPE_F8) {
01230 TN* pair = Build_Dedicated_TN(rclass, reg+1, TY_size(preg_ty));
01231 Add_TN_Pair(tn, pair);
01232 }
01233 #endif
01234
01235 #ifdef TARG_X8664
01236 if( reg == First_Int_Preg_Return_Offset &&
01237 Is_Target_32bit() ){
01238 if( !CGTARG_Preg_Register_And_Class(Last_Int_Preg_Return_Offset,
01239 &rclass, ®) ){
01240 FmtAssert( FALSE, ("NYI") );
01241 }
01242 TN* pair = Build_Dedicated_TN( rclass, reg, TY_size(preg_ty) );
01243 Create_TN_Pair( tn, pair );
01244 }
01245 #endif
01246
01247 #if defined(EMULATE_LONGLONG) && !defined(TARG_SL)
01248
01249 if (reg == First_Int_Preg_Return_Offset) {
01250
01251
01252
01253
01254 if (CGTARG_Preg_Register_And_Class(Last_Int_Preg_Return_Offset,
01255 &rclass, ®)) {
01256 TN *pair = Build_Dedicated_TN(rclass, reg,
01257 TY_size(preg_ty));
01258
01259 Add_TN_Pair (tn, pair);
01260 } else {
01261 #pragma mips_frequency_hint NEVER
01262 FmtAssert (FALSE,
01263 ("Could not find reg for Last_Int_Preg_Return_Offset"));
01264
01265 }
01266 }
01267 #endif
01268 }
01269 else
01270 {
01271
01272 TYPE_ID mtype = TY_mtype(preg_ty);
01273 #ifdef TARG_X8664
01274
01275
01276
01277 if( mtype == MTYPE_C4 ){
01278 mtype = MTYPE_F8;
01279 }
01280 #endif
01281
01282 #if defined(EMULATE_LONGLONG) && !defined (TARG_SL)
01283 if (mtype == MTYPE_I8 || mtype == MTYPE_U8) {
01284 mtype = (mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
01285 tn = Build_TN_Of_Mtype(mtype);
01286 Add_TN_Pair (tn, Build_TN_Of_Mtype(mtype));
01287 } else {
01288 tn = Build_TN_Of_Mtype (mtype);
01289 }
01290 #elif defined(TARG_SL)
01291
01292 #ifdef EMULATE_LONGLONG
01293 if (mtype == MTYPE_I8 || mtype == MTYPE_U8) {
01294 mtype = (mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
01295 tn = Build_TN_Of_Mtype(mtype);
01296 Add_TN_Pair(tn, Build_TN_Of_Mtype(mtype));
01297 } else
01298 #endif
01299
01300 #ifdef EMULATE_FLOAT_POINT
01301 if (mtype == MTYPE_F8) {
01302 TN* pair = Build_TN_Of_Mtype(MTYPE_U4);
01303 tn = Build_TN_Of_Mtype(MTYPE_U4);
01304 Add_TN_Pair(tn, pair);
01305 } else if (mtype == MTYPE_F4) {
01306 tn = Build_TN_Of_Mtype(MTYPE_U4);
01307 } else
01308 #endif
01309 tn = Build_TN_Of_Mtype (mtype);
01310
01311 #else
01312 #ifdef TARG_X8664
01313 if( OP_NEED_PAIR(mtype) ){
01314 mtype = (mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
01315 tn = Build_TN_Of_Mtype(mtype);
01316 Create_TN_Pair( tn, mtype );
01317
01318 } else
01319 #endif // TARG_X8664
01320 tn = Build_TN_Of_Mtype (mtype);
01321 #endif
01322
01323 if (CGSPILL_Rematerialize_Constants)
01324 {
01325 BOOL gra_homeable = FALSE;
01326 WN *home= Preg_Is_Rematerializable(preg_num, &gra_homeable);
01327
01328 if (home)
01329 {
01330 if (gra_homeable) {
01331 if (TN_number(tn) < GRA_non_home_lo ||
01332 TN_number(tn) > GRA_non_home_hi) {
01333 Set_TN_is_gra_homeable(tn);
01334 Set_TN_home (tn, home);
01335 }
01336 } else {
01337 Set_TN_is_rematerializable(tn);
01338 Set_TN_home (tn, home);
01339 }
01340 }
01341 }
01342
01343 TN_MAP_Set( TN_To_PREG_Map, tn, (void *)(INTPTR)preg_num );
01344
01345 if (Is_Predicate_REGISTER_CLASS(TN_register_class(tn))) {
01346
01347
01348
01349
01350 Is_True(!TN_is_gra_homeable(tn) && !TN_is_rematerializable(tn),
01351 ("don't support homeable or rematerializable predicate preg"));
01352 PREG_NUM preg2_num = preg_num + 1;
01353 TN *tn2 = Build_TN_Of_Mtype (mtype);
01354 TN_MAP_Set( TN_To_PREG_Map, tn2, (void *)(INTPTR)preg2_num );
01355 PREG_To_TN_Array[preg2_num] = tn2;
01356 PREG_To_TN_Mtype[preg2_num] = mtype;
01357 }
01358 }
01359 if (Get_Trace (TP_CGEXP, 16)) {
01360 fprintf(TFile, "preg %d maps to tn %d", preg_num, TN_number(tn));
01361 if (TN_is_gra_homeable(tn)) {
01362 fprintf(TFile, "(gra_homeable)\n");
01363 } else if (TN_is_rematerializable(tn)) {
01364 fprintf(TFile, "(rematerializable)\n");
01365 } else {
01366 fprintf(TFile, "\n");
01367 }
01368 }
01369 PREG_To_TN_Array[preg_num] = tn;
01370 PREG_To_TN_Mtype[preg_num] = TY_mtype(preg_ty);
01371 }
01372 if ( TN_is_dedicated( tn ) ) {
01373 dedicated_seen = TRUE;
01374
01375
01376
01377 if (TN_is_float(tn) && TN_size(tn) != TY_size(preg_ty)) {
01378 tn = Build_Dedicated_TN (TN_register_class(tn),
01379 TN_register(tn),
01380 TY_size(preg_ty));
01381
01382 #if defined(TARG_SL) && defined(EMULATE_FLOAT_POINT)
01383 if ((mtype == MTYPE_F8) && (!Get_TN_Pair(tn))) {
01384 TN* pair = Build_Dedicated_TN(TN_register_class(tn),
01385 TN_register(tn) + 1, TY_size(preg_ty));
01386 Add_TN_Pair(tn, pair);
01387 }
01388 #endif
01389 }
01390 #ifdef KEY
01391
01392
01393 if (!TN_is_float(tn) &&
01394 TN_size(tn) != TY_size(preg_ty)
01395 #ifdef TARG_X8664
01396 && Is_Target_64bit()
01397 #endif
01398 ) {
01399 #if defined(TARG_SL) && (defined(EMULATE_LONGLONG) || defined(EMULATE_FLOAT_POINT))
01400 if (mtype != MTYPE_I8 && mtype != MTYPE_U8 && mtype != MTYPE_F8)
01401 #endif
01402 tn = Build_Dedicated_TN (TN_register_class(tn),
01403 TN_register(tn),
01404 TY_size(preg_ty));
01405 }
01406 #endif
01407 #if defined(TARG_SL) && (defined(EMULATE_LONGLONG) || defined(EMULATE_FLOAT_POINT))
01408
01409 if (mtype == MTYPE_I8 || mtype == MTYPE_U8 || mtype == MTYPE_F8) {
01410 if (!Get_TN_Pair(tn)) {
01411 TN* pair = Build_Dedicated_TN (TN_register_class(tn),
01412 TN_register(tn) + 1, TY_size(preg_ty));
01413 Add_TN_Pair(tn, pair);
01414 }
01415 }
01416 #endif
01417 }
01418
01419 return tn;
01420 }
01421
01422 TN *
01423 PREG_To_TN (ST *preg_st, PREG_NUM preg_num)
01424 {
01425 return PREG_To_TN (ST_type(preg_st), preg_num);
01426 }
01427
01428
01429 PREG_NUM
01430 TN_To_Assigned_PREG (TN *tn)
01431 {
01432 PREG_NUM i;
01433
01434 FmtAssert (TN_register(tn) != REGISTER_UNDEFINED,
01435 ("TN_To_Assigned_PREG: no assigned register for TN%d", TN_number(tn)));
01436
01437 i = REGISTER_machine_id(TN_register_class(tn), TN_register(tn));
01438 if (TN_is_float(tn)) {
01439 i += Float_Preg_Min_Offset;
01440 }
01441 #if defined(TARG_IA32) || defined(TARG_X8664)
01442
01443 else {
01444 i += Int_Preg_Min_Offset;
01445 }
01446 #endif
01447 return i;
01448 }
01449
01450
01451
01452
01453
01454
01455 PREG_NUM
01456 TN_To_PREG (TN *tn)
01457 {
01458 PREG_NUM i;
01459
01460 if (TN_is_dedicated(tn)) {
01461 return TN_To_Assigned_PREG (tn);
01462 }
01463
01464 for (i = Last_Dedicated_Preg_Offset;
01465 i < Get_Preg_Num(PREG_Table_Size(CURRENT_SYMTAB));
01466 i++)
01467 {
01468 if (PREG_To_TN_Array[i] == tn) return i;
01469 }
01470 return 0;
01471 }
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483 void
01484 PREG_To_TN_Clear (void)
01485 {
01486 PREG_NUM i;
01487
01488 for (i = Last_Dedicated_Preg_Offset + 1;
01489 i <= Get_Preg_Num(PREG_Table_Size(CURRENT_SYMTAB));
01490 i++)
01491 {
01492 PREG_To_TN_Array[i] = NULL;
01493 PREG_To_TN_Mtype[i] = (TYPE_ID)0;
01494 }
01495 max_preg_to_tn_index = 0;
01496 }
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506 static TN_LIST *
01507 TN_LIST_From_PREG_LIST( PREG_LIST *prl0, MEM_POOL *pool )
01508 {
01509 PREG_LIST *prl;
01510 PREG_NUM pr;
01511 TN_LIST *tnl = NULL;
01512 TN *tn;
01513
01514 for ( prl = prl0; prl; prl = PREG_LIST_rest( prl ) ) {
01515 pr = PREG_LIST_first( prl );
01516 if (pr > Last_Dedicated_Preg_Offset) {
01517 tn = PREG_To_TN_Array[pr];
01518 Is_True(tn != NULL,
01519 ("TN_LIST_From_PREG_LIST, NULL TN in PREG to TN map, PREG%d",pr));
01520 tnl = TN_LIST_Push( tn, tnl, pool );
01521 }
01522 }
01523
01524 return tnl;
01525 }
01526
01527
01528
01529 static void
01530 Add_PregTNs_To_BB (PREG_LIST *prl0, BB *bb, BOOL prepend)
01531 {
01532 PREG_LIST *prl;
01533 PREG_NUM pr;
01534 TN *tn;
01535 TOP topcode = (prepend ? TOP_begin_pregtn : TOP_end_pregtn);
01536 OPS ops;
01537 OPS_Init(&ops);
01538
01539 #ifdef TARG_NVISA
01540 FmtAssert(FALSE, ("NYI"));
01541 return;
01542 #endif
01543 for ( prl = prl0; prl; prl = PREG_LIST_rest( prl ) ) {
01544 pr = PREG_LIST_first( prl );
01545 if (pr > Last_Dedicated_Preg_Offset) {
01546 tn = PREG_To_TN_Array[pr];
01547 if (tn == NULL) {
01548
01549 if (Trace_REGION_Interface)
01550 fprintf(TFile, "<region> remove preg %d from rid list\n", pr);
01551 REGION_remove_preg(BB_rid(bb), pr, !prepend );
01552 } else {
01553 Build_OP (topcode, tn, Gen_Literal_TN(pr, 4), &ops);
01554 Set_OP_glue(OPS_last(&ops));
01555 }
01556 }
01557 }
01558 if ( Trace_REGION_Interface ) {
01559 fprintf( TFile, "<region> add pregtns to bb %d:\n", BB_id(bb) );
01560 Print_OPS(&ops);
01561 }
01562 if (prepend)
01563 CGSPILL_Prepend_Ops (bb, &ops);
01564 else
01565 CGSPILL_Append_Ops (bb, &ops);
01566 }
01567
01568
01569
01570
01571 static BOOL
01572 Has_Immediate_Operand (WN *parent, WN *expr)
01573 {
01574 Is_True( WN_operator_is(expr, OPR_INTCONST),
01575 ("Has_Immediate_Operand: Not a constant") );
01576
01577
01578
01579
01580 if (parent == NULL) return FALSE;
01581
01582
01583 if (Target_Has_Immediate_Operand (parent, expr)) {
01584 return TRUE;
01585 }
01586
01587
01588
01589
01590 if (WN_kid_count(parent) < 2 || WN_kid1(parent) != expr) return FALSE;
01591
01592
01593
01594
01595
01596 if (OPCODE_is_store(WN_opcode(parent))) return FALSE;
01597
01598
01599
01600
01601
01602
01603
01604 if (MTYPE_is_float(WN_rtype(parent)))
01605 return FALSE;
01606
01607 switch (WN_operator(parent)) {
01608 case OPR_ADD:
01609 case OPR_SUB:
01610 case OPR_MPY:
01611 case OPR_DIV:
01612 case OPR_REM:
01613 case OPR_DIVREM:
01614 case OPR_SHL:
01615 case OPR_LSHR:
01616 case OPR_ASHR:
01617 case OPR_RROTATE:
01618 case OPR_BAND:
01619 case OPR_BIOR:
01620 case OPR_BXOR:
01621 case OPR_EQ:
01622 case OPR_NE:
01623 case OPR_LE:
01624 case OPR_LT:
01625 case OPR_GE:
01626 case OPR_GT:
01627 return TRUE;
01628 }
01629 return FALSE;
01630 }
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 static void
01642 Handle_Call_Site (WN *call, OPERATOR call_opr)
01643 {
01644 TN *tgt_tn;
01645 ST *call_st = (call_opr != OPR_ICALL) ? WN_st(call) : NULL;
01646 CALLINFO *call_info;
01647
01648
01649
01650
01651
01652
01653 PU_Has_Calls = TRUE;
01654
01655 #ifdef TARG_X8664
01656 if( Is_Target_32bit() &&
01657 Gen_PIC_Shared &&
01658 call_st != NULL &&
01659 !ST_is_export_local(call_st) ){
01660 PU_References_GOT = TRUE;
01661 }
01662 #endif
01663
01664
01665 if (call_opr == OPR_CALL) {
01666 tgt_tn = Gen_Symbol_TN (call_st, 0, 0);
01667 }
01668 else {
01669
01670 tgt_tn = Gen_PIC_Calls ? Ep_TN : NULL;
01671 tgt_tn = Expand_Expr (WN_kid(call,WN_kid_count(call)-1), call, tgt_tn);
01672
01673
01674
01675
01676 if (Gen_PIC_Call_Shared &&
01677 call_st != NULL &&
01678 !ST_is_preemptible(call_st) )
01679 {
01680 tgt_tn = Gen_Symbol_TN (call_st, 0, 0);
01681 call_opr = OPR_CALL;
01682 }
01683 }
01684 Last_Mem_OP = OPS_last(&New_OPs);
01685 Exp_Call (call_opr, RA_TN, tgt_tn, &New_OPs);
01686 Set_OP_To_WN_Map(call);
01687
01688 call_info = TYPE_PU_ALLOC (CALLINFO);
01689 CALLINFO_call_st(call_info) = call_st;
01690 CALLINFO_call_wn(call_info) = call;
01691 BB_Add_Annotation (Cur_BB, ANNOT_CALLINFO, call_info);
01692
01693 region_stack_eh_set_has_call();
01694
01695
01696
01697
01698
01699 Start_New_Basic_Block ();
01700
01701
01702
01703 #ifdef TARG_IA64
01704 if (Is_Caller_Save_GP && !Constant_GP &&
01705
01706
01707
01708 (call_st == NULL || ST_export(call_st) == EXPORT_PREEMPTIBLE || ST_is_weak_symbol(call_st)) )
01709
01710 #else
01711 if (Is_Caller_Save_GP && !Constant_GP
01712 && (call_st == NULL || ST_export(call_st) == EXPORT_PREEMPTIBLE))
01713 #endif
01714 {
01715
01716
01717 TN *caller_gp_tn = PREG_To_TN_Array[ Caller_GP_Preg ];
01718 if (caller_gp_tn == NULL) {
01719 caller_gp_tn = Gen_Register_TN ( ISA_REGISTER_CLASS_integer,
01720 Pointer_Size);
01721 TN_MAP_Set( TN_To_PREG_Map, caller_gp_tn,
01722 (void *)(INTPTR)Caller_GP_Preg );
01723 PREG_To_TN_Array[ Caller_GP_Preg ] = caller_gp_tn;
01724 PREG_To_TN_Mtype[ Caller_GP_Preg ] = TY_mtype(Spill_Int_Type);
01725 }
01726 Exp_COPY (GP_TN, caller_gp_tn, &New_OPs);
01727 }
01728 }
01729
01730
01731
01732
01733
01734 static VARIANT Memop_Variant(WN *memop)
01735 {
01736 VARIANT variant = V_NONE;
01737 INT required_alignment = MTYPE_RegisterSize(WN_desc(memop));
01738
01739 #ifndef KEY
01740
01741
01742 if(WN_Is_Volatile_Mem(memop))
01743 Set_V_volatile(variant);
01744 #endif
01745
01746
01747
01748
01749 Is_True ((required_alignment != 0), ("bad value 0 for required_alignment"));
01750
01751 if (required_alignment > 1) {
01752 WN_OFFSET offset;
01753 INT ty_align;
01754 INT align;
01755
01756 switch (WN_operator(memop)) {
01757 case OPR_LDID:
01758 case OPR_LDBITS:
01759 case OPR_STID:
01760 case OPR_STBITS:
01761
01762
01763 offset = WN_load_offset(memop);
01764 ty_align = ST_alignment(WN_st(memop));
01765 #if defined(TARG_X8664) || defined(TARG_SL) // bug 8198: in absence of pointed-to type's alignment, need this
01766 if (offset) {
01767 INT offset_align = offset % required_alignment;
01768 if (offset_align) ty_align = MIN(ty_align, offset_align);
01769 }
01770 #endif
01771 break;
01772 case OPR_ILOAD:
01773 case OPR_ILDBITS:
01774 {
01775 TY_IDX ty = WN_load_addr_ty(memop);
01776 if (TY_kind(ty) == KIND_POINTER) ty = TY_pointed(ty);
01777 ty_align = TY_align(ty);
01778 offset = WN_load_offset(memop);
01779 }
01780 break;
01781 case OPR_ISTORE:
01782 case OPR_ISTBITS:
01783 {
01784 TY_IDX ty = WN_ty(memop);
01785 if (TY_kind(ty) == KIND_POINTER) ty = TY_pointed(ty);
01786 ty_align = TY_align(ty);
01787 offset = WN_store_offset(memop);
01788 }
01789 break;
01790 default:
01791 FmtAssert(FALSE, ("unhandled memop in Memop_Variant"));
01792
01793 }
01794
01795 align = ty_align;
01796 #ifdef TARG_IA64
01797 if (offset) {
01798 int ofs_mod = offset % required_alignment;
01799 if (ofs_mod) {
01800 int ofs_align = ffs(ofs_mod) - 1;
01801 align = MIN(ty_align, 1U << ofs_align);
01802 }
01803 }
01804 #endif
01805
01806 #ifndef KEY // bug 8640: for enabling generation of 128-bit-aligned accesses from SIMD
01807 if (offset) {
01808 INT offset_align = offset % required_alignment;
01809 if (offset_align) align = MIN(ty_align, offset_align);
01810 }
01811 #endif
01812
01813 if (align < required_alignment) {
01814 #ifdef TARG_IA64
01815 Set_V_alignment(variant, ffs(align) - 1);
01816 #else
01817 Set_V_alignment(variant, align);
01818 #endif
01819
01820
01821
01822
01823
01824 Set_V_align_offset_unknown(variant);
01825
01826
01827
01828
01829
01830
01831 if (V_volatile(variant)) {
01832 ErrMsgLine(EC_Ill_Align,
01833 SRCPOS_linenum(current_srcpos),
01834 ty_align,
01835 "reference to unaligned volatile: volatile atomicity is ignored");
01836 }
01837 }
01838 }
01839
01840
01841
01842 WN *pf_wn = NULL;
01843 PF_POINTER *pf_ptr = (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH, memop);
01844 if (pf_ptr) {
01845 pf_wn = PF_PTR_wn_pref_2L(pf_ptr);
01846 if (pf_wn == NULL) pf_wn = PF_PTR_wn_pref_1L(pf_ptr);
01847 }
01848 if (pf_wn) Set_V_pf_flags(variant, WN_prefetch_flag(pf_wn));
01849
01850 #ifdef KEY
01851
01852
01853 #ifndef TARG_NVISA // want to know volatile even if no other variant
01854 if (variant)
01855 #endif
01856 if (WN_Is_Volatile_Mem(memop)) Set_V_volatile(variant);
01857 #endif
01858 return variant;
01859 }
01860
01861 static TN *
01862 Handle_LDA (WN *lda, WN *parent, TN *result, OPCODE opcode)
01863 {
01864 OPERATOR call_op = OPERATOR_UNKNOWN;
01865
01866 if (parent != NULL) call_op = WN_operator(parent);
01867
01868 if (result == NULL) {
01869 result = Allocate_Result_TN (lda, NULL);
01870 if (CGSPILL_Rematerialize_Constants) {
01871 Set_TN_is_rematerializable(result);
01872 Set_TN_home (result, lda);
01873 }
01874 }
01875
01876 Last_Mem_OP = OPS_last(&New_OPs);
01877 #if defined(TARG_SL)
01878 Exp_Lda (
01879 OPCODE_rtype(opcode),
01880 result,
01881 WN_st(lda),
01882 WN_lda_offset(lda),
01883 call_op,
01884 &New_OPs,
01885 WN_is_internal_mem_ofst(lda));
01886 #else
01887 Exp_Lda (
01888 OPCODE_rtype(opcode),
01889 result,
01890 WN_st(lda),
01891 WN_lda_offset(lda),
01892 call_op,
01893 &New_OPs);
01894 #endif
01895 Set_OP_To_WN_Map(lda);
01896
01897 return result;
01898 }
01899
01900
01901
01902 struct find_dreg_preg {
01903 ST_IDX st;
01904 find_dreg_preg (const ST *s) : st (ST_st_idx (s)) {}
01905
01906 BOOL operator () (UINT, const ST_ATTR *st_attr) const {
01907 return (ST_ATTR_kind (*st_attr) == ST_ATTR_DEDICATED_REGISTER &&
01908 ST_ATTR_st_idx (*st_attr) == st);
01909 }
01910 };
01911 PREG_NUM
01912 Find_PREG_For_Symbol (const ST *st)
01913 {
01914 ST_IDX idx = ST_st_idx (st);
01915 ST_ATTR_IDX d;
01916
01917 d = For_all_until (St_Attr_Table, ST_IDX_level (idx),
01918 find_dreg_preg(st));
01919 return ST_ATTR_reg_id(St_Attr_Table(ST_IDX_level (idx), d));
01920 }
01921
01922 #ifdef TARG_SL
01923 extern void Expand_Copy_Extension (TN *result, TN *src, TYPE_ID mtype, BOOL signed_extension, OPS *ops);
01924 #endif
01925
01926 static TN *
01927 Handle_LDID (WN *ldid, TN *result, OPCODE opcode)
01928 {
01929 if (ST_assigned_to_dedicated_preg(WN_st(ldid))) {
01930
01931 WN_offset(ldid) = Find_PREG_For_Symbol(WN_st(ldid));
01932 WN_st_idx(ldid) = ST_st_idx(MTYPE_To_PREG(ST_mtype(WN_st(ldid))));
01933 }
01934
01935
01936
01937 if (WN_class(ldid) == CLASS_PREG)
01938 {
01939 #ifdef TARG_SL
01940 TYPE_ID mtype = ST_mtype(WN_st(ldid));
01941 TN *ldid_result = PREG_To_TN (WN_st(ldid), WN_load_offset(ldid));
01942
01943 #ifdef EMULATE_LONGLONG
01944 if (MTYPE_is_longlong(mtype)) {
01945 FmtAssert(Get_TN_Pair(ldid_result), ("Handle_LDID: TN pair should be setup"));
01946 }
01947 #endif
01948 #ifdef EMULATE_FLOAT_POINT
01949 if (mtype == MTYPE_F8) {
01950 FmtAssert(Get_TN_Pair(ldid_result), ("Handle_LDID: TN pair should be setup"));
01951 }
01952 #endif
01953
01954 #elif defined(TARG_NVISA)
01955 TN *ldid_result;
01956 if (Is_Simple_Type(WN_ty(ldid))) {
01957
01958
01959 ldid_result = PREG_To_TN (WN_ty(ldid), WN_load_offset(ldid));
01960 } else {
01961 ldid_result = PREG_To_TN (WN_st(ldid), WN_load_offset(ldid));
01962 }
01963 TYPE_ID rtype = OPCODE_rtype(opcode);
01964 if (result)
01965 Is_True(TN_size(result) >= MTYPE_byte_size(rtype),
01966 ("ldid result is too small for rtype"));
01967 if (rtype != OPCODE_desc(opcode)
01968 && MTYPE_size_reg(Mtype_Of_TN(ldid_result)) != MTYPE_size_reg(rtype) )
01969 {
01970
01971 if (result == NULL)
01972 result = Build_TN_Of_Mtype(rtype);
01973 Expand_Convert (result, rtype, ldid_result, OPCODE_desc(opcode), &New_OPs);
01974 return result;
01975 }
01976 #else
01977 TN *ldid_result = PREG_To_TN (WN_st(ldid), WN_load_offset(ldid));
01978 #endif
01979 if (result == NULL) {
01980 result = ldid_result;
01981 }
01982 else {
01983 #if defined(TARG_SL) && (defined(EMULATE_LONGLONG) || defined(EMULATE_FLOAT_POINT))
01984 if (Get_TN_Pair(result)) {
01985 Expand_Copy_Extension(result, ldid_result, WN_rtype(ldid), MTYPE_signed(WN_desc(ldid)), &New_OPs);
01986 }
01987 else {
01988 Exp_COPY(result, ldid_result, &New_OPs);
01989 }
01990 #elif defined(EMULATE_LONGLONG)
01991 {
01992 extern void Expand_Copy (TN *result, TN *src, TYPE_ID mtype, OPS *ops);
01993 TYPE_ID mtype = ST_mtype(WN_st(ldid));
01994 if (mtype == MTYPE_I8 || mtype == MTYPE_U8) {
01995 Expand_Copy (result, ldid_result, mtype, &New_OPs);
01996 } else {
01997 Exp_COPY (result, ldid_result, &New_OPs);
01998 }
01999 }
02000 #else
02001 #ifdef TARG_X8664
02002 if( OP_NEED_PAIR( ST_mtype(WN_st(ldid) ) ) ){
02003 Expand_Copy( result, ldid_result, ST_mtype(WN_st(ldid)), &New_OPs );
02004
02005 } else
02006 #endif // TARG_X8664
02007 Exp_COPY (result, ldid_result, &New_OPs);
02008
02009 #endif // EMULATE_LONGLONG
02010 }
02011 }
02012 else
02013 {
02014 VARIANT variant;
02015
02016 if (opcode == OPC_U4U8LDID)
02017 {
02018 opcode = OPC_U4U4LDID;
02019 WN_set_opcode(ldid, opcode);
02020 if (Target_Byte_Sex == BIG_ENDIAN) {
02021 WN_offset(ldid) += 4;
02022 }
02023 }
02024 else if (opcode == OPC_I4I8LDID)
02025 {
02026 opcode = OPC_I4I4LDID;
02027 WN_set_opcode(ldid, opcode);
02028 if (Target_Byte_Sex == BIG_ENDIAN) {
02029 WN_offset(ldid) += 4;
02030 }
02031 }
02032 variant = Memop_Variant(ldid);
02033
02034 if (result == NULL) result = Allocate_Result_TN (ldid, NULL);
02035 Last_Mem_OP = OPS_last(&New_OPs);
02036 Exp_Load (OPCODE_rtype(opcode), OPCODE_desc(opcode),
02037 result,
02038 WN_st(ldid),
02039 WN_load_offset(ldid),
02040 &New_OPs,
02041 variant);
02042 Set_OP_To_WN_Map(ldid);
02043 }
02044 return result;
02045 }
02046
02047 static TN *
02048 Handle_LDBITS (WN *ldbits, TN *result, OPCODE opcode)
02049 {
02050 TN *src_tn;
02051
02052 if (result == NULL) result = Allocate_Result_TN (ldbits, NULL);
02053
02054 if (WN_class(ldbits) == CLASS_PREG)
02055 {
02056 src_tn = PREG_To_TN (WN_st(ldbits), WN_load_offset(ldbits));
02057 }
02058 else
02059 {
02060 VARIANT variant = Memop_Variant(ldbits);
02061
02062 src_tn = Allocate_Result_TN (ldbits, NULL);
02063 Last_Mem_OP = OPS_last(&New_OPs);
02064 Exp_Load (OPCODE_rtype(opcode), OPCODE_desc(opcode),
02065 src_tn,
02066 WN_st(ldbits),
02067 WN_load_offset(ldbits),
02068 &New_OPs,
02069 variant);
02070 Set_OP_To_WN_Map(ldbits);
02071 }
02072 Exp_Extract_Bits(WN_rtype(ldbits), WN_desc(ldbits), WN_bit_offset(ldbits),
02073 WN_bit_size(ldbits), result, src_tn, &New_OPs);
02074 return result;
02075 }
02076
02077 static TN *
02078 Handle_EXTRACT_BITS (WN *extrbits, TN *result, OPCODE opcode)
02079 {
02080 TN *kid0_tn = Expand_Expr (WN_kid0(extrbits), extrbits, NULL);
02081 if (result == NULL) result = Allocate_Result_TN (extrbits, NULL);
02082
02083 Exp_Extract_Bits(OPCODE_rtype(opcode), OPCODE_rtype(opcode),
02084 WN_bit_offset(extrbits), WN_bit_size(extrbits),
02085 result, kid0_tn, &New_OPs);
02086 return result;
02087 }
02088
02089 typedef struct TN_CORRESPOND
02090 {
02091 TN *result;
02092 TN *result2;
02093 struct TN_CORRESPOND *next;
02094 } TN_CORRESPOND, *TN_CORRESPONDp;
02095
02096 static TN_CORRESPONDp tn_correspond_list= NULL;
02097
02098
02099 TN *TN_CORRESPOND_Lookup(TN *result)
02100 {
02101 TN_CORRESPONDp p;
02102
02103 for(p= tn_correspond_list; p; p= p->next)
02104 {
02105 if (p->result == result)
02106 {
02107 return p->result2;
02108 }
02109 }
02110 return NULL;
02111 }
02112
02113 void TN_CORRESPOND_Free(void)
02114 {
02115 TN_CORRESPONDp next;
02116 TN_CORRESPONDp p = tn_correspond_list;
02117
02118 while(p)
02119 {
02120 next = p->next;
02121 MEM_POOL_FREE(Malloc_Mem_Pool, p);
02122 p = next;
02123 }
02124 tn_correspond_list= NULL;
02125 }
02126
02127 static TN *
02128 TN_CORRESPOND_Set(TN *result, WN *expr)
02129 {
02130 TN_CORRESPONDp p;
02131
02132 Is_True((TN_CORRESPOND_Lookup(result)==NULL),("TN_CORRESPOND_Set(): expected null"));
02133
02134 p = TYPE_MEM_POOL_ALLOC(TN_CORRESPOND, Malloc_Mem_Pool);
02135 p->result = result;
02136 p->result2= Allocate_Result_TN(expr, NULL);
02137 p->next = tn_correspond_list;
02138
02139 tn_correspond_list= p;
02140
02141 return p->result2;
02142 }
02143
02144 TN *TN_CORRESPOND_Get(TN *result, WN *expr)
02145 {
02146 TN *tn = TN_CORRESPOND_Lookup(result);
02147
02148 if (tn)
02149 return tn;
02150
02151 return TN_CORRESPOND_Set(result, expr);
02152 }
02153
02154
02155 static TN *
02156 Handle_DIVREM(WN *expr, WN *parent, TN *result, OPCODE opcode)
02157 {
02158 TN *result2, *kid0_tn, *kid1_tn;
02159
02160 Is_True ((parent && WN_class(parent) == CLASS_PREG),
02161 ("DIVREM: expected store of preg"));
02162 Is_True ((result == PREG_To_TN(WN_st(parent), WN_store_offset(parent))),
02163 ("DIVREM: bad result tn"));
02164
02165 kid0_tn = Expand_Expr (WN_kid0(expr), expr, NULL);
02166 kid1_tn = Expand_Expr (WN_kid1(expr), expr, NULL);
02167
02168 result2 = TN_CORRESPOND_Get(result, expr);
02169
02170 Exp_OP(opcode, result, result2, kid0_tn, kid1_tn, V_NONE, &New_OPs);
02171
02172 return result;
02173 }
02174
02175 static TN *
02176 Handle_DIVPART(WN *expr, WN *parent, TN *result)
02177 {
02178 TN *pregTN;
02179 WN *kid = WN_kid0(expr);
02180
02181 Is_True ((WN_class(kid) == CLASS_PREG), ("DIVPART: expected preg"));
02182
02183 pregTN = PREG_To_TN(WN_st(kid), WN_store_offset(kid));
02184
02185 if (result==NULL)
02186 {
02187 return pregTN;
02188 }
02189
02190 #ifdef TARG_X8664
02191 Exp_COPY (result, pregTN, &New_OPs, TRUE);
02192 #else
02193 Exp_COPY (result, pregTN, &New_OPs);
02194 #endif
02195
02196 return result;
02197 }
02198
02199 static TN *
02200 Handle_REMPART(WN *expr, WN *parent, TN *result)
02201 {
02202 TN *pregTN;
02203 WN *kid = WN_kid0(expr);
02204
02205 Is_True ((WN_class(kid) == CLASS_PREG), ("REMPART: expected preg"));
02206
02207 pregTN = PREG_To_TN(WN_st(kid), WN_store_offset(kid));
02208 pregTN = TN_CORRESPOND_Get(pregTN, expr);
02209
02210 Is_True ((pregTN),("expected tn correspondence"));
02211
02212 if (result==NULL)
02213 {
02214 return pregTN;
02215 }
02216
02217 #ifdef TARG_X8664
02218 Exp_COPY (result, pregTN, &New_OPs, TRUE);
02219 #else
02220 Exp_COPY (result, pregTN, &New_OPs);
02221 #endif
02222
02223 return result;
02224 }
02225
02226 static TN *
02227 Handle_MINMAX(WN *expr, WN *parent, TN *result, OPCODE opcode)
02228 {
02229 TN *result2, *kid0_tn, *kid1_tn;
02230
02231 Is_True ((parent && WN_class(parent) == CLASS_PREG),
02232 ("MINMAX: expected store of preg"));
02233 Is_True ((result == PREG_To_TN(WN_st(parent), WN_store_offset(parent))),
02234 ("MINMAX: bad result tn"));
02235
02236 kid0_tn = Expand_Expr (WN_kid0(expr), expr, NULL);
02237 kid1_tn = Expand_Expr (WN_kid1(expr), expr, NULL);
02238
02239 result2 = TN_CORRESPOND_Get(result, expr);
02240
02241 Exp_OP(opcode, result, result2, kid0_tn, kid1_tn, V_NONE, &New_OPs);
02242
02243 return result;
02244 }
02245
02246 static TN *
02247 Handle_MINPART(WN *expr, WN *parent, TN *result)
02248 {
02249 TN *pregTN;
02250 WN *kid = WN_kid0(expr);
02251
02252 Is_True ((WN_class(kid) == CLASS_PREG), ("MINPART: expected preg"));
02253
02254 pregTN = PREG_To_TN(WN_st(kid), WN_store_offset(kid));
02255
02256 if (result==NULL)
02257 {
02258 return pregTN;
02259 }
02260
02261 #ifdef TARG_X8664
02262 if( OP_NEED_PAIR( ST_mtype(WN_st(kid) ) ) ){
02263 Expand_Copy( result, pregTN, ST_mtype(WN_st(kid)), &New_OPs );
02264
02265 } else
02266 #endif // TARG_X8664
02267 Exp_COPY (result, pregTN, &New_OPs);
02268 return result;
02269 }
02270
02271 static TN *
02272 Handle_MAXPART(WN *expr, WN *parent, TN *result)
02273 {
02274 TN *pregTN;
02275 WN *kid = WN_kid0(expr);
02276
02277 Is_True ((WN_class(kid) == CLASS_PREG), ("MAXPART: expected preg"));
02278
02279 pregTN = PREG_To_TN(WN_st(kid), WN_store_offset(kid));
02280 pregTN = TN_CORRESPOND_Get(pregTN, expr);
02281
02282 Is_True ((pregTN),("expected tn correspondende"));
02283
02284 if (result==NULL)
02285 {
02286 return pregTN;
02287 }
02288
02289 #ifdef TARG_X8664
02290 if( OP_NEED_PAIR( ST_mtype(WN_st(kid) ) ) ){
02291 Expand_Copy( result, pregTN, ST_mtype(WN_st(kid)), &New_OPs );
02292
02293 } else
02294 #endif // TARG_X8664
02295 Exp_COPY (result, pregTN, &New_OPs);
02296 return result;
02297 }
02298
02299
02300
02301 static TN *
02302 Handle_ILOAD (WN *iload, TN *result, OPCODE opcode)
02303 {
02304 VARIANT variant;
02305 WN *kid0 = WN_kid0(iload);
02306 ST *st;
02307
02308 if (opcode == OPC_U4U8ILOAD)
02309 {
02310 opcode = OPC_U4U4ILOAD;
02311 WN_set_opcode(iload, opcode);
02312 if (Target_Byte_Sex == BIG_ENDIAN) {
02313 WN_offset(iload) += 4;
02314 }
02315 }
02316 else if (opcode == OPC_I4I8ILOAD)
02317 {
02318 opcode = OPC_I4I4ILOAD;
02319 WN_set_opcode(iload, opcode);
02320 if (Target_Byte_Sex == BIG_ENDIAN) {
02321 WN_offset(iload) += 4;
02322 }
02323 }
02324 variant = Memop_Variant(iload);
02325 if (result == NULL) result = Allocate_Result_TN (iload, NULL);
02326
02327
02328 if (WN_operator_is(kid0, OPR_LDA)) {
02329 Last_Mem_OP = OPS_last(&New_OPs);
02330 st = WN_st(kid0);
02331
02332 Allocate_Object (st);
02333
02334 Exp_Load (OPCODE_rtype(opcode), OPCODE_desc(opcode),
02335 result,
02336 st,
02337 WN_offset(iload) + WN_lda_offset(kid0),
02338 &New_OPs,
02339 variant);
02340 }
02341 else {
02342 TN *kid0_tn = Expand_Expr (kid0, iload, NULL);
02343 #if defined(TARG_SL)
02344
02345 if (CG_sl2 && CG_SL2_enable_v1buf_expansion && WN_is_internal_mem_ofst(iload))
02346 Set_TN_is_v1buf_addr(kid0_tn);
02347 #endif
02348 TN *offset_tn = Gen_Literal_TN (WN_offset(iload), 4);
02349 #ifdef TARG_NVISA
02350 TY_IDX addr_ty = WN_load_addr_ty(iload);
02351
02352 WN *addr_wn = WN_kid0(iload);
02353 WN *lda = Find_Lda (addr_wn);
02354 if (lda) {
02355 if (WN_operator(lda) == OPR_LDID
02356 && ST_sclass(WN_st(lda)) == SCLASS_FORMAL)
02357 {
02358
02359
02360 Set_V_global_mem(variant);
02361 }
02362 else if (WN_operator(lda) == OPR_LDID
02363 && ST_sclass(WN_st(lda)) == SCLASS_FSTATIC
02364 && ST_in_constant_mem(WN_st(lda)) )
02365 {
02366
02367
02368 Set_V_global_mem(variant);
02369 }
02370 else {
02371
02372 if (ST_in_global_mem(WN_st(lda)))
02373 Set_V_global_mem(variant);
02374 else if (ST_sclass(WN_st(lda)) == SCLASS_FORMAL)
02375 Set_V_param_mem(variant);
02376 else if (ST_in_shared_mem(WN_st(lda)))
02377 Set_V_shared_mem(variant);
02378 else if (ST_in_constant_mem(WN_st(lda)))
02379 Set_V_const_mem(variant);
02380 else if (ST_in_local_mem(WN_st(lda)))
02381 Set_V_local_mem(variant);
02382 else if (TN_in_param_mem(kid0_tn))
02383 Set_V_param_mem(variant);
02384 else {
02385 DevWarn("unknown lda for iload");
02386 ErrMsgLine (EC_Ptr_Assumed_Global, SRCPOS_linenum(current_srcpos));
02387 Set_V_global_mem(variant);
02388 }
02389 }
02390 } else {
02391 DevWarn("no lda for iload");
02392 ErrMsgLine (EC_Ptr_Assumed_Global, SRCPOS_linenum(current_srcpos));
02393 Set_V_global_mem(variant);
02394 }
02395 #endif
02396 Last_Mem_OP = OPS_last(&New_OPs);
02397 Exp_OP2v (opcode, result, kid0_tn, offset_tn, variant, &New_OPs);
02398 }
02399 Set_OP_To_WN_Map(iload);
02400 return result;
02401 }
02402
02403
02404 static TN *
02405 Handle_ILDBITS (WN *ildbits, TN *result, OPCODE opcode)
02406 {
02407 VARIANT variant = Memop_Variant(ildbits);
02408 WN *kid0 = WN_kid0(ildbits);
02409 ST *st;
02410 TN *src_tn = Allocate_Result_TN (ildbits, NULL);
02411 if (result == NULL) result = Allocate_Result_TN (ildbits, NULL);
02412
02413
02414 if (WN_operator_is(kid0, OPR_LDA)) {
02415 Last_Mem_OP = OPS_last(&New_OPs);
02416 st = WN_st(kid0);
02417
02418 Allocate_Object (st);
02419
02420 Exp_Load (OPCODE_rtype(opcode), OPCODE_desc(opcode),
02421 src_tn,
02422 st,
02423 WN_offset(ildbits) + WN_lda_offset(kid0),
02424 &New_OPs,
02425 variant);
02426 }
02427 else {
02428 TN *kid0_tn = Expand_Expr (kid0, ildbits, NULL);
02429 TN *offset_tn = Gen_Literal_TN (WN_offset(ildbits), 4);
02430 Last_Mem_OP = OPS_last(&New_OPs);
02431 Exp_OP2v (OPCODE_make_op(OPR_ILOAD, OPCODE_rtype(opcode), OPCODE_desc(opcode)),
02432 src_tn, kid0_tn, offset_tn, variant, &New_OPs);
02433 }
02434 Set_OP_To_WN_Map(ildbits);
02435
02436 Exp_Extract_Bits(WN_rtype(ildbits), WN_desc(ildbits), WN_bit_offset(ildbits),
02437 WN_bit_size(ildbits), result, src_tn, &New_OPs);
02438 return result;
02439 }
02440
02441 static BOOL Operator_Is_Bool (OPERATOR opr) {
02442
02443 if (opr == OPR_LNOT ||
02444 opr == OPR_EQ ||
02445 opr == OPR_NE ||
02446 opr == OPR_GE ||
02447 opr == OPR_GT ||
02448 opr == OPR_LE ||
02449 opr == OPR_LT ||
02450 opr == OPR_LAND ||
02451 opr == OPR_LIOR) {
02452 return TRUE;
02453 } else {
02454 return FALSE;
02455 }
02456 }
02457
02458 static void
02459 Handle_STID (WN *stid, OPCODE opcode)
02460 {
02461 TN *result;
02462
02463 #ifdef EMULATE_LONGLONG
02464 {
02465
02466
02467 TYPE_ID rtype = OPCODE_rtype(opcode);
02468 TYPE_ID dtype = WN_rtype(WN_kid0(stid));
02469 if ((rtype == MTYPE_I8 || rtype == MTYPE_U8) && dtype == MTYPE_I4) {
02470 FmtAssert (Operator_Is_Bool (WN_operator(WN_kid0(stid))),
02471 ("Handle_STID: LHS is I/U8, RHS is I4 and not BOOL"));
02472 }
02473 }
02474 #endif
02475
02476 if (ST_assigned_to_dedicated_preg(WN_st(stid))) {
02477
02478 WN_offset(stid) = Find_PREG_For_Symbol(WN_st(stid));
02479 WN_st_idx(stid) = ST_st_idx(MTYPE_To_PREG(ST_mtype(WN_st(stid))));
02480 }
02481
02482
02483
02484 if (WN_class(stid) == CLASS_PREG) {
02485 WN *kid = WN_kid0(stid);
02486
02487 #ifdef TARG_NVISA
02488 TN *final_result = NULL;
02489 if (Is_Simple_Type(WN_ty(stid))) {
02490
02491
02492 result = PREG_To_TN (WN_ty(stid), WN_store_offset(stid));
02493 } else {
02494 result = PREG_To_TN (WN_st(stid), WN_store_offset(stid));
02495 }
02496 if (TN_size(result) < MTYPE_byte_size(WN_rtype(kid))) {
02497
02498
02499 final_result = result;
02500 result = Build_TN_Of_Mtype(WN_rtype(kid));
02501
02502 }
02503
02504
02505
02506 if (OPERATOR_is_boolean(WN_operator(kid))) {
02507 Set_TN_is_boolean(result);
02508 }
02509 #elif defined(TARG_SL)
02510 if (Is_Simple_Type(WN_ty(stid))) {
02511
02512
02513 result = PREG_To_TN (WN_ty(stid), WN_store_offset(stid));
02514 } else {
02515 result = PREG_To_TN (WN_st(stid), WN_store_offset(stid));
02516 }
02517 #else
02518 result = PREG_To_TN (WN_st(stid), WN_store_offset(stid));
02519 #endif
02520
02521 #if defined(TARG_SL)
02522 extern void Set_IntrnOP_Result (WN *stid);
02523 Set_IntrnOP_Result(stid);
02524 if (WN_operator(kid) == OPR_LDID) {
02525 extern void Copy_Preg_MapInfo(WN *stid);
02526 Copy_Preg_MapInfo(stid);
02527 }
02528 #endif
02529
02530 #ifdef KEY
02531
02532
02533
02534
02535
02536 TN *old_result = NULL;
02537 TYPE_ID dtype = WN_rtype(kid);
02538 if (MTYPE_is_float(dtype) &&
02539 MTYPE_byte_size(dtype) < TN_size(result)) {
02540 old_result = result;
02541 result = Gen_Register_TN(TN_register_class(result),
02542 MTYPE_byte_size(dtype));
02543 }
02544 #endif
02545
02546 #if defined(TARG_IA32)
02547 if (TN_is_dedicated(result)) {
02548
02549 TN *tmp = Build_TN_Like(result);
02550 TN *tmp1 = NULL;
02551 TN *tmp2 = NULL;
02552
02553 if (tmp1 = If_Get_TN_Pair(result)) {
02554 Add_TN_Pair(tmp, tmp2 = Build_TN_Like(tmp1));
02555 }
02556
02557 Expand_Expr (kid, stid, tmp);
02558 Exp_COPY (result, tmp, &New_OPs);
02559 if (tmp1)
02560 Exp_COPY (tmp1, tmp2, &New_OPs);
02561 }
02562 else {
02563 Expand_Expr (kid, stid, result);
02564 }
02565 #else
02566
02567 #if defined(TARG_SL) && defined(EMULATE_LONGLONG)
02568 if(MTYPE_is_longlong(OPCODE_desc(opcode)) && !Get_TN_Pair(result)) {
02569 FmtAssert(FALSE, ("Handle_STID: Get_TN_Pair Failed"));
02570 }
02571
02572 TYPE_ID stid_type = OPCODE_desc(opcode);
02573 TYPE_ID kid0_type = WN_rtype(WN_kid0(stid));
02574
02575 if (MTYPE_is_longlong(kid0_type)
02576 && (MTYPE_byte_size(kid0_type) > MTYPE_byte_size(stid_type))) {
02577 TN * rett = Expand_Expr(kid, stid, NULL);
02578 if (result)
02579 Expand_Copy(result, rett, stid_type, &New_OPs);
02580 else
02581 result = rett;
02582 }
02583 else if (MTYPE_is_longlong(stid_type) && Get_TN_Pair(result)
02584 && (MTYPE_byte_size(kid0_type) < MTYPE_byte_size(stid_type))) {
02585 TN* tn = Expand_Expr(kid, stid, NULL);
02586 Expand_Copy_Extension(result, tn, stid_type, MTYPE_signed(kid0_type), &New_OPs);
02587 }
02588 else {
02589 Expand_Expr(kid, stid, result);
02590 }
02591
02592 #else // TARG_SL && EMULATE_LONGLONG
02593
02594 #ifdef TARG_X8664 // bug 11088
02595 if(OPCODE_is_compare(WN_opcode(kid)) &&
02596 MTYPE_is_vector(WN_desc(kid))){
02597
02598 TN *op1 = Expand_Expr (WN_kid0(kid), kid, NULL);
02599 TN *op2 = Expand_Expr (WN_kid1(kid), kid, NULL);
02600 Exp_Stid_And_VComp(opcode, result, op1, op2, WN_opcode(kid), &New_OPs);
02601 return;
02602 }else
02603 #endif
02604
02605 Expand_Expr (kid, stid, result);
02606
02607 #ifdef TARG_NVISA
02608 if (final_result != NULL) {
02609
02610
02611 Expand_Convert (final_result, OPCODE_desc(opcode), result, WN_rtype(kid), &New_OPs);
02612 result = final_result;
02613 }
02614 #endif
02615
02616 #ifdef KEY
02617 if (old_result != NULL) {
02618 Exp_COPY(old_result, result, &New_OPs);
02619 }
02620 #endif
02621 #endif // TARG_SL && EMULATE_LONGLONG
02622
02623 #ifdef TARG_X8664
02624 const TYPE_ID stid_type = OPCODE_desc(opcode);
02625 const TYPE_ID kid0_type = WN_rtype(WN_kid0(stid));
02626
02627 if( OP_NEED_PAIR(stid_type) &&
02628 Get_TN_Pair(result) != NULL &&
02629 MTYPE_byte_size(kid0_type) < MTYPE_byte_size(stid_type) ){
02630
02631
02632 FmtAssert(old_result == NULL, ("Handle_STID: old_result not NULL"));
02633
02634 if( MTYPE_is_signed(kid0_type) ){
02635 DevWarn( "the higher 32-bit of PREG %d is set to 0",
02636 WN_store_offset(stid) );
02637 }
02638
02639 TN* result_hi = Get_TN_Pair( result );
02640 Expand_Immediate( result_hi, Gen_Literal_TN(0,4), FALSE, &New_OPs );
02641 }
02642 #endif // TARG_X8664
02643
02644 #endif // IA_32
02645 if (In_Glue_Region) {
02646 if ( Trace_REGION_Interface ) {
02647 fprintf(TFile,"set op_glue on preg store in bb %d\n", BB_id(Cur_BB));
02648 }
02649 Set_OP_glue(OPS_last(&New_OPs));
02650 }
02651
02652
02653
02654
02655
02656 if (WN_operator_is(kid, OPR_LDID) && WN_class(kid) == CLASS_PREG) {
02657 TN *ldidTN = PREG_To_TN (WN_st(kid), WN_load_offset(kid));
02658
02659 TN *ldidTN2 = TN_CORRESPOND_Lookup(ldidTN);
02660 if (ldidTN2 != NULL) {
02661 TN *stidTN = TN_CORRESPOND_Get(result, kid);
02662 Exp_COPY(stidTN, ldidTN2, &New_OPs);
02663 } else if (Is_Predicate_REGISTER_CLASS(TN_register_class(ldidTN))) {
02664 Is_True(Is_Predicate_REGISTER_CLASS(TN_register_class(result)),
02665 ("result should be predicate register class"));
02666 PREG_NUM cpreg_num = WN_load_offset(kid) + 1;
02667 TN *ctn = PREG_To_TN_Array[cpreg_num];
02668 PREG_NUM cresult_num = WN_store_offset(stid) + 1;
02669 TN *cresult = PREG_To_TN_Array[cresult_num];
02670 Exp_COPY (cresult, ctn, &New_OPs);
02671 }
02672 }
02673 }
02674 else {
02675 #if defined(TARG_SL)
02676 extern void Set_IntrnOP_Result (WN *stid);
02677 Set_IntrnOP_Result(stid);
02678 extern void Copy_Preg_MapInfo(WN *stid);
02679 Copy_Preg_MapInfo(stid);
02680 #endif
02681 VARIANT variant = Memop_Variant(stid);
02682 Last_Mem_OP = OPS_last(&New_OPs);
02683 Exp_Store (
02684 OPCODE_desc(opcode),
02685 Expand_Expr (WN_kid0(stid), stid, NULL),
02686 WN_st(stid),
02687 WN_store_offset(stid),
02688 &New_OPs,
02689 variant);
02690 Set_OP_To_WN_Map(stid);
02691
02692 }
02693 }
02694
02695
02696 static void
02697 Handle_STBITS (WN *stbits)
02698 {
02699 VARIANT variant;
02700 WN *kid = WN_kid0(stbits);
02701 TN *result;
02702 TN *field_tn;
02703 TN *bits_tn = Allocate_Result_TN (kid, NULL);
02704 const TYPE_ID desc = Mtype_TransferSign(MTYPE_U4, WN_desc(stbits));
02705 TYPE_ID rtype = Mtype_TransferSize(WN_rtype(kid), desc);
02706 #ifdef KEY // bug 7418
02707 if (MTYPE_bit_size(rtype) < MTYPE_bit_size(desc))
02708 rtype = desc;
02709 #endif
02710
02711 Expand_Expr (kid, stbits, bits_tn);
02712
02713
02714
02715 if (WN_class(stbits) == CLASS_PREG) {
02716 field_tn = PREG_To_TN (WN_st(stbits), WN_store_offset(stbits));
02717 result = field_tn;
02718 } else {
02719 variant = Memop_Variant(stbits);
02720 field_tn = Allocate_Result_TN (kid, NULL);
02721 Last_Mem_OP = OPS_last(&New_OPs);
02722 Exp_Load(rtype, desc, field_tn, WN_st(stbits), WN_load_offset(stbits),
02723 &New_OPs, variant);
02724 Set_OP_To_WN_Map(stbits);
02725 result = Allocate_Result_TN (kid, NULL);
02726 }
02727
02728
02729 Exp_Deposit_Bits(rtype, desc, WN_bit_offset(stbits),
02730 WN_bit_size(stbits), result, field_tn, bits_tn, &New_OPs);
02731
02732 if (WN_class(stbits) != CLASS_PREG)
02733 {
02734 Last_Mem_OP = OPS_last(&New_OPs);
02735 Exp_Store(desc, result, WN_st(stbits), WN_store_offset(stbits), &New_OPs,
02736 variant);
02737 Set_OP_To_WN_Map(stbits);
02738 }
02739 }
02740
02741
02742 static TN *
02743 Handle_COMPOSE_BITS (WN *compbits, TN *result, OPCODE opcode)
02744 {
02745 TN *kid0_tn = Expand_Expr (WN_kid0(compbits), compbits, NULL);
02746 TN *kid1_tn = Expand_Expr (WN_kid1(compbits), compbits, NULL);
02747 if (result == NULL) result = Allocate_Result_TN (compbits, NULL);
02748
02749 #ifdef TARG_X8664
02750 extern UINT64 Bitmask_Of_Size(INT bsize);
02751 if (WN_operator(WN_kid1(compbits)) == OPR_INTCONST &&
02752 WN_const_val(WN_kid1(compbits)) == Bitmask_Of_Size(WN_bit_size(compbits)))
02753 Exp_Set_Bits(OPCODE_rtype(opcode), WN_bit_offset(compbits),
02754 WN_bit_offset(compbits), WN_bit_size(compbits),
02755 result, kid0_tn, &New_OPs);
02756 else
02757 #endif
02758 #ifdef TARG_SL
02759 Exp_Deposit_Bits(OPCODE_rtype(opcode), WN_rtype(WN_kid1(compbits)),
02760 WN_bit_offset(compbits), WN_bit_size(compbits),
02761 result, kid0_tn, kid1_tn, &New_OPs);
02762 #else
02763 Exp_Deposit_Bits(OPCODE_rtype(opcode), OPCODE_rtype(opcode),
02764 WN_bit_offset(compbits), WN_bit_size(compbits),
02765 result, kid0_tn, kid1_tn, &New_OPs);
02766
02767 #endif //TARG_SL
02768 return result;
02769 }
02770
02771
02772 static void
02773 Handle_ISTORE (WN *istore, OPCODE opcode)
02774 {
02775 VARIANT variant = Memop_Variant(istore);
02776 WN *kid1 = WN_kid1(istore);
02777 TN *kid0_tn = Expand_Expr (WN_kid0(istore), istore, NULL);
02778 ST *st;
02779
02780 #if defined(EMULATE_LONGLONG) && !defined(TARG_SL)
02781 {
02782
02783
02784 TYPE_ID rtype = WN_rtype(WN_kid0(istore));
02785 TYPE_ID dtype = OPCODE_desc(opcode);
02786 if ((dtype == MTYPE_I8 || dtype == MTYPE_U8) && rtype == MTYPE_I4) {
02787 FmtAssert (Operator_Is_Bool (WN_operator(WN_kid0(istore))),
02788 ("Handle_ISTORE: LHS is I/U8, RHS is I4 and not BOOL"));
02789 }
02790 }
02791 #endif
02792
02793
02794 if (WN_operator_is(kid1, OPR_LDA)) {
02795 Last_Mem_OP = OPS_last(&New_OPs);
02796 st = WN_st(kid1);
02797
02798 Allocate_Object (st);
02799
02800 Exp_Store (
02801 OPCODE_desc(opcode),
02802 kid0_tn,
02803 st,
02804 WN_offset(istore) + WN_lda_offset(kid1),
02805 &New_OPs,
02806 variant);
02807 }
02808 else {
02809 TN *kid1_tn = Expand_Expr (WN_kid1(istore), istore, NULL);
02810 TN *offset_tn = Gen_Literal_TN (WN_offset(istore), 4);
02811 #ifdef TARG_NVISA
02812 TY_IDX addr_ty = WN_ty(istore);
02813
02814 WN *addr_wn = WN_kid1(istore);
02815 WN *lda = Find_Lda (addr_wn);
02816 if (lda) {
02817 if (WN_operator(lda) == OPR_LDID
02818 && ST_sclass(WN_st(lda)) == SCLASS_FORMAL)
02819 {
02820
02821
02822 Set_V_global_mem(variant);
02823 }
02824 else if (WN_operator(lda) == OPR_LDID
02825 && ST_sclass(WN_st(lda)) == SCLASS_FSTATIC
02826 && ST_in_constant_mem(WN_st(lda)) )
02827 {
02828
02829
02830 Set_V_global_mem(variant);
02831 }
02832 else {
02833 if (ST_in_global_mem(WN_st(lda)))
02834 Set_V_global_mem(variant);
02835 else if (ST_sclass(WN_st(lda)) == SCLASS_FORMAL)
02836 Set_V_param_mem(variant);
02837 else if (ST_in_shared_mem(WN_st(lda)))
02838 Set_V_shared_mem(variant);
02839 else if (ST_in_constant_mem(WN_st(lda)))
02840 Set_V_const_mem(variant);
02841 else if (ST_in_local_mem(WN_st(lda)))
02842 Set_V_local_mem(variant);
02843 else if (TN_in_param_mem(kid1_tn))
02844 Set_V_param_mem(variant);
02845 else {
02846 DevWarn("unknown lda for istore");
02847 ErrMsgLine (EC_Ptr_Assumed_Global, SRCPOS_linenum(current_srcpos));
02848 Set_V_global_mem(variant);
02849 }
02850 }
02851 } else {
02852 DevWarn("no lda for istore");
02853 ErrMsgLine (EC_Ptr_Assumed_Global, SRCPOS_linenum(current_srcpos));
02854 Set_V_global_mem(variant);
02855 }
02856 #endif
02857 Last_Mem_OP = OPS_last(&New_OPs);
02858 #if defined(TARG_SL)
02859
02860 if(CG_sl2 && CG_SL2_enable_v1buf_expansion && WN_is_internal_mem_ofst(istore))
02861 Set_TN_is_v1buf_addr(kid1_tn);
02862 #endif
02863 Exp_OP3v (
02864 opcode,
02865 NULL,
02866 kid0_tn,
02867 kid1_tn,
02868 offset_tn,
02869 variant,
02870 &New_OPs);
02871 }
02872 Set_OP_To_WN_Map(istore);
02873 }
02874
02875
02876 static void
02877 Handle_ISTBITS (WN *istbits)
02878 {
02879 VARIANT variant = Memop_Variant(istbits);
02880 WN *kid0 = WN_kid0(istbits);
02881 WN *kid1 = WN_kid1(istbits);
02882 TN *bits_tn = Expand_Expr (kid0, istbits, NULL);
02883 TN *field_tn = Allocate_Result_TN (kid0, NULL);
02884 TN *result = Allocate_Result_TN (kid0, NULL);
02885 TYPE_ID desc = Mtype_TransferSign(MTYPE_U4, WN_desc(istbits));
02886 TYPE_ID rtype = desc;
02887
02888
02889 if (MTYPE_byte_size(rtype) < 4)
02890 rtype = Mtype_TransferSize(MTYPE_U4, rtype);
02891 if (MTYPE_byte_size(WN_rtype(kid0)) > MTYPE_byte_size(rtype))
02892 rtype = Mtype_TransferSize(WN_rtype(kid0), rtype);
02893
02894
02895 if (WN_operator_is(kid1, OPR_LDA)) {
02896 Last_Mem_OP = OPS_last(&New_OPs);
02897 ST *st = WN_st(kid1);
02898
02899 Allocate_Object (st);
02900
02901 Last_Mem_OP = OPS_last(&New_OPs);
02902 Exp_Load(rtype, desc, field_tn, st,
02903 WN_store_offset(istbits) + WN_lda_offset(kid1), &New_OPs,
02904 variant);
02905 Set_OP_To_WN_Map(istbits);
02906
02907
02908 Exp_Deposit_Bits(rtype, desc, WN_bit_offset(istbits),
02909 WN_bit_size(istbits), result, field_tn, bits_tn, &New_OPs);
02910
02911 Last_Mem_OP = OPS_last(&New_OPs);
02912 Exp_Store(desc, result, st, WN_store_offset(istbits) + WN_lda_offset(kid1),
02913 &New_OPs, variant);
02914 Set_OP_To_WN_Map(istbits);
02915 }
02916 else {
02917 TN *kid1_tn = Expand_Expr (WN_kid1(istbits), istbits, NULL);
02918 TN *offset_tn = Gen_Literal_TN (WN_store_offset(istbits), 4);
02919
02920 Last_Mem_OP = OPS_last(&New_OPs);
02921 Exp_OP2v(OPCODE_make_op(OPR_ILOAD, rtype, desc),
02922 field_tn, kid1_tn, offset_tn, variant, &New_OPs);
02923 Set_OP_To_WN_Map(istbits);
02924
02925
02926 Exp_Deposit_Bits(rtype, desc, WN_bit_offset(istbits),
02927 WN_bit_size(istbits), result, field_tn, bits_tn, &New_OPs);
02928
02929 Last_Mem_OP = OPS_last(&New_OPs);
02930 Exp_OP3v(OPCODE_make_op(OPR_ISTORE, MTYPE_V, desc),
02931 NULL, result, kid1_tn, offset_tn, variant, &New_OPs);
02932 Set_OP_To_WN_Map(istbits);
02933 }
02934 }
02935
02936 static TN *
02937 Handle_SELECT(WN *select, TN *result, OPCODE opcode)
02938 {
02939 TN *trueop, *falseop, *cond;
02940 TN *op1, *op2;
02941 WN *compare;
02942 VARIANT variant;
02943
02944
02945
02946
02947
02948
02949
02950 trueop = Expand_Expr (WN_kid1(select), select, NULL);
02951 falseop = Expand_Expr (WN_kid2(select), select, NULL);
02952 compare = WN_kid0(select);
02953
02954 if (result == NULL) result = Allocate_Result_TN (select, NULL);
02955
02956
02957
02958 #if defined(TARG_SL)
02959
02960
02961 if(CG_opt_level > 1 && CG_sl2 && CG_SL2_enable_combine_condmv)
02962 {
02963 if(trueop != Zero_TN && falseop != Zero_TN) {
02964 cond = Expand_Expr(compare, select, NULL);
02965 Build_OP(TOP_c2_cmov,
02966 result,
02967 trueop,
02968 falseop,
02969 cond,
02970 &New_OPs);
02971 return result;
02972 }
02973 }
02974 #endif
02975
02976
02977
02978 variant = WHIRL_Compare_To_OP_variant (WN_opcode(compare), FALSE);
02979 #ifndef KEY
02980 if (Check_Select_Expansion (WN_opcode(compare)) || (variant == V_BR_NONE)) {
02981 #else
02982 if (Check_Select_Expansion (WN_opcode(compare)) ||
02983 (variant == V_BR_NONE && !MTYPE_is_vector(WN_desc(compare)))) {
02984 #endif
02985 Is_True( WN_desc(select) != MTYPE_B
02986 || ( WN_operator_is(compare, OPR_LDID)
02987 && WN_class(compare) == CLASS_PREG),
02988 ("MTYPE_B SELECT condition must be preg or relop"));
02989 cond = Expand_Expr (compare, select, NULL);
02990 Exp_OP3 (opcode, result, cond, trueop, falseop, &New_OPs);
02991 }
02992 #ifdef TARG_X8664 //bug 11088
02993 else if (WN_operator_is(compare, OPR_LDID) &&
02994 WN_class(compare) == CLASS_PREG){
02995 Is_True(variant == V_BR_NONE && MTYPE_is_vector(WN_desc(compare)),
02996 ("Hanle_Select: ldid as condition must be a vector here!"));
02997
02998 cond = Expand_Expr (compare, select, NULL);
02999 Exp_Select_And_VLdid(opcode, result, trueop, falseop, WN_opcode(compare),
03000 cond,&New_OPs);
03001 }
03002 #endif
03003 else {
03004 op1 = Expand_Expr (WN_kid0(compare), compare, NULL);
03005 op2 = Expand_Expr (WN_kid1(compare), compare, NULL);
03006 #if defined(TARG_SL)
03007 if (!(CG_enable_opt_condmv && Exp_Opt_Select_And_Condition(select, result, trueop, falseop, op1, op2, &New_OPs)))
03008 Exp_Select_And_Condition (select, opcode, result, trueop, falseop,
03009 WN_opcode(compare), op1, op2, variant, &New_OPs);
03010 #else
03011 Exp_Select_And_Condition (opcode, result, trueop, falseop,
03012 WN_opcode(compare), op1, op2, variant,
03013 &New_OPs);
03014 #endif
03015 }
03016
03017 return result;
03018 }
03019
03020 #ifdef TARG_X8664
03021
03022
03023
03024
03025 static TN *
03026 Handle_SHUFFLE (WN *shuffle, TN *result)
03027 {
03028 TN *op1;
03029 VARIANT variant;
03030
03031 op1 = Expand_Expr (WN_kid0(shuffle), shuffle, NULL);
03032
03033 if (result == NULL) result = Allocate_Result_TN (shuffle, NULL);
03034
03035 variant = WN_offset(shuffle);
03036 Expand_Shuffle(WN_opcode(shuffle), result, op1, variant, &New_OPs);
03037
03038 return result;
03039 }
03040
03041
03042
03043 static TN *
03044 Handle_RROTATE (WN *rotate, TN *result)
03045 {
03046 if (result == NULL) result = Allocate_Result_TN (rotate, NULL);
03047
03048 WN * obj = WN_kid0 (rotate);
03049 WN * rotate_amount = WN_kid1 (rotate);
03050
03051
03052 if (WN_operator (rotate_amount) == OPR_SUB)
03053 {
03054 WN * kid0 = WN_kid0 (rotate_amount);
03055 WN * kid1 = WN_kid1 (rotate_amount);
03056
03057
03058 if (WN_operator (kid0) == OPR_INTCONST &&
03059 WN_const_val (kid0) == MTYPE_bit_size (WN_rtype (obj)))
03060 {
03061 TN * op1 = Expand_Expr (obj, rotate, NULL);
03062 TN * op2 = Expand_Expr (kid1, rotate_amount, NULL);
03063 Expand_Left_Rotate (result, op1, op2, WN_rtype (rotate),
03064 WN_desc (rotate), &New_OPs);
03065
03066 return result;
03067 }
03068 }
03069
03070 TN * op1 = Expand_Expr (WN_kid0(rotate), rotate, NULL);
03071 TN * op2 = Expand_Expr (WN_kid1(rotate), rotate, NULL);
03072
03073 Exp_OP2 (WN_opcode (rotate), result, op1, op2, &New_OPs);
03074
03075 return result;
03076 }
03077 #endif
03078
03079
03080
03081
03082
03083
03084 static TN*
03085 Handle_LAND_LIOR(WN *expr, WN *parent, TN *result)
03086 {
03087 VARIANT variant;
03088 OPCODE opcode = WN_opcode(expr);
03089 TN *op1 = Expand_Expr(WN_kid0(expr), expr, NULL);
03090 TN *op2 = Expand_Expr(WN_kid1(expr), expr, NULL);
03091
03092 variant = V_NONE;
03093 if (OPCODE_is_boolean(WN_opcode(WN_kid0(expr)))
03094 #ifdef TARG_NVISA
03095 || TN_is_boolean(op1)
03096 #endif
03097 )
03098 Set_V_normalized_op1(variant);
03099 if (OPCODE_is_boolean(WN_opcode(WN_kid1(expr)))
03100 #ifdef TARG_NVISA
03101 || TN_is_boolean(op2)
03102 #endif
03103 )
03104 Set_V_normalized_op2(variant);
03105
03106 if (result == NULL) result = Allocate_Result_TN (expr, NULL);
03107
03108 Exp_OP2v(opcode, result, op1, op2, variant, &New_OPs);
03109
03110 return result;
03111 }
03112
03113 static TN*
03114 Handle_LNOT(WN *expr, WN *parent, TN *result)
03115 {
03116 VARIANT variant;
03117 OPCODE opcode = WN_opcode(expr);
03118 WN *kid0 = WN_kid0(expr);
03119 TN *op1 = Expand_Expr(kid0, expr, NULL);
03120
03121 variant = V_NONE;
03122 if (OPCODE_is_boolean(WN_opcode(kid0))
03123 #ifdef TARG_NVISA
03124 || TN_is_boolean(op1)
03125 #endif
03126 )
03127 Set_V_normalized_op1(variant);
03128
03129 if (result == NULL) result = Allocate_Result_TN (expr, NULL);
03130
03131 if ( WN_rtype(kid0) == MTYPE_B
03132 && WN_operator_is(kid0, OPR_LDID)
03133 && WN_class(kid0) == CLASS_PREG)
03134 {
03135 PREG_NUM cpreg_num = WN_load_offset(kid0) + 1;
03136 TN *ctn = PREG_To_TN_Array[cpreg_num];
03137 PREG_NUM result_num = TN_To_PREG(result);
03138 if (result_num) {
03139 PREG_NUM cresult_num = result_num + 1;
03140 TN *cresult = PREG_To_TN_Array[cresult_num];
03141 Exp_COPY (cresult, op1, &New_OPs);
03142 }
03143 Exp_COPY (result, ctn, &New_OPs);
03144 } else {
03145 Exp_OP1v(opcode, result, op1, variant, &New_OPs);
03146 }
03147
03148 return result;
03149 }
03150
03151 static BOOL U4ExprHasUpperBitZero(WN *wn)
03152 {
03153 switch(WN_opcode(wn))
03154 {
03155 case OPC_U4LSHR:
03156
03157
03158
03159 if (WN_operator_is(WN_kid1(wn), OPR_INTCONST))
03160 {
03161 if (0 < WN_const_val(WN_kid1(wn)))
03162 return TRUE;
03163 }
03164 break;
03165
03166 case OPC_U4BAND:
03167
03168
03169
03170 if (WN_operator_is(WN_kid1(wn), OPR_INTCONST))
03171 {
03172 if ((WN_const_val(WN_kid1(wn)) & 0x80000000) == 0)
03173 return TRUE;
03174 }
03175 break;
03176 }
03177 return FALSE;
03178 }
03179
03180 static BOOL
03181 Is_CVT_Noop(WN *cvt, WN *parent)
03182 {
03183 if (WN_opcode(cvt) == OPC_I4U4CVT || WN_opcode(cvt) == OPC_U4I4CVT ||
03184 WN_opcode(cvt) == OPC_I8U8CVT || WN_opcode(cvt) == OPC_U8I8CVT) {
03185
03186 return TRUE;
03187 }
03188
03189 #ifdef TARG_X8664
03190 {
03191
03192
03193 TYPE_ID desc = WN_desc (cvt);
03194 TYPE_ID rtype = WN_rtype (cvt);
03195 if (MTYPE_is_mmx_vector (desc) && MTYPE_is_integral (desc) &&
03196 MTYPE_is_mmx_vector (rtype) && MTYPE_is_integral (rtype))
03197 return TRUE;
03198 }
03199 #endif
03200
03201 if (Enable_CVT_Opt)
03202 {
03203 switch(WN_opcode(cvt))
03204 {
03205 #ifdef TARG_IA64
03206 case OPC_F8F4CVT:
03207 case OPC_F4F8CVT:
03208 if (WN_operator(parent) == OPR_TAS) {
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218 return FALSE;
03219
03220 }
03221 break;
03222 #endif
03223 case OPC_U8I4CVT:
03224 case OPC_I8I4CVT:
03225
03226
03227
03228
03229 #ifdef TARG_SL
03230 return FALSE;
03231 #endif
03232
03233 if ( ! Split_64_Bit_Int_Ops && ! Only_Unsigned_64_Bit_Ops)
03234 {
03235 #ifdef TARG_X8664
03236 return FALSE;
03237 #else
03238 return TRUE;
03239 #endif
03240 }
03241 break;
03242
03243 case OPC_U8U4CVT:
03244 case OPC_I8U4CVT:
03245 #ifndef EMULATE_LONGLONG
03246
03247
03248
03249 if (U4ExprHasUpperBitZero(WN_kid0(cvt))
03250 #ifdef TARG_X8664
03251 && !Is_Target_32bit()
03252 #endif
03253 )
03254 {
03255 return TRUE;
03256 }
03257 #endif
03258 break;
03259
03260 case OPC_U4U8CVT:
03261 #ifdef TARG_X8664
03262
03263
03264
03265
03266 if (Is_Target_64bit() &&
03267 parent != NULL &&
03268 MTYPE_byte_size(WN_rtype(parent)) == 4 &&
03269
03270
03271 WN_operator(parent) != OPR_MPY &&
03272 WN_operator(parent) != OPR_DIV &&
03273 WN_operator(parent) != OPR_REM &&
03274 WN_operator(parent) != OPR_DIVREM) {
03275 return TRUE;
03276 }
03277 #endif
03278
03279 case OPC_I4U8CVT:
03280 case OPC_I4I8CVT:
03281 case OPC_U4I8CVT:
03282
03283
03284
03285
03286 if (parent)
03287 {
03288 switch(WN_opcode(parent))
03289 {
03290 case OPC_I4STID:
03291 case OPC_U4STID:
03292 if (WN_class(parent) != CLASS_PREG)
03293 {
03294 return TRUE;
03295 }
03296 break;
03297
03298 case OPC_I4ISTORE:
03299 case OPC_U4ISTORE:
03300 return TRUE;
03301 }
03302 }
03303 break;
03304 case OPC_I4CVTL:
03305 case OPC_U4CVTL:
03306 case OPC_I8CVTL:
03307 case OPC_U8CVTL:
03308
03309
03310
03311
03312 if (parent)
03313 {
03314 switch(WN_operator(parent))
03315 {
03316 case OPR_STID:
03317 if (MTYPE_size_reg(WN_desc(parent)) == WN_cvtl_bits(cvt)
03318 && WN_class(parent) != CLASS_PREG)
03319 {
03320 return TRUE;
03321 }
03322 break;
03323
03324 case OPR_ISTORE:
03325 if (MTYPE_size_reg(WN_desc(parent)) == WN_cvtl_bits(cvt))
03326 {
03327 return TRUE;
03328 }
03329 }
03330 }
03331 break;
03332 }
03333 }
03334 return FALSE;
03335 }
03336
03337
03338
03339 static BOOL
03340 Is_CVTL_Opcode (OPCODE opc)
03341 {
03342 switch (opc) {
03343 case OPC_U8I4CVT:
03344 case OPC_U8U4CVT:
03345 case OPC_I8I4CVT:
03346 case OPC_I8U4CVT:
03347 case OPC_I4I8CVT:
03348 case OPC_I4U8CVT:
03349 case OPC_U4U8CVT:
03350 case OPC_U4I8CVT:
03351 case OPC_I8CVTL:
03352 case OPC_I4CVTL:
03353 case OPC_U8CVTL:
03354 case OPC_U4CVTL:
03355 return TRUE;
03356 default:
03357 return FALSE;
03358 }
03359 }
03360
03361 static TN*
03362 Handle_ALLOCA (WN *tree, TN *result)
03363 {
03364 #ifdef TARG_IA64
03365 TN *tsize = Expand_Expr (WN_kid0(tree), tree, NULL);
03366
03367 if (TN_has_value(tsize)) {
03368 INT64 size;
03369 size = TN_value(tsize);
03370 size += Stack_Alignment() - 1;
03371 size &= -Stack_Alignment();
03372 tsize = Gen_Literal_TN (size, Pointer_Size);
03373 }
03374 else if ( ! TN_is_zero_reg (tsize)) {
03375 #else
03376 BOOL is_const = WN_operator(WN_kid0(tree)) == OPR_INTCONST;
03377 BOOL is_zero = is_const && WN_const_val(WN_kid0(tree)) == 0;
03378 TN *tsize = NULL;
03379 if (!is_zero) {
03380 if (is_const) {
03381
03382 INT64 size = WN_const_val(WN_kid0(tree));
03383 size += Stack_Alignment() - 1;
03384 size &= -Stack_Alignment();
03385 tsize = Gen_Literal_TN (size, Pointer_Size);
03386 }
03387 else {
03388 tsize = Expand_Expr (WN_kid0(tree), tree, NULL);
03389 #endif
03390 TN *tmp1 = Build_TN_Like ( tsize );
03391 TN *tmp2 = Build_TN_Like ( tsize );
03392 Exp_ADD (Pointer_Mtype, tmp1, tsize,
03393 Gen_Literal_TN (Stack_Alignment()-1, Pointer_Size),
03394 &New_OPs);
03395 Exp_OP2 ((MTYPE_is_size_double(WN_rtype(tree)) ? OPC_I8BAND : OPC_I4BAND),
03396 tmp2, tmp1,
03397 Gen_Literal_TN (-Stack_Alignment(), Pointer_Size),
03398 &New_OPs);
03399 tsize = tmp2;
03400 #ifndef TARG_IA64
03401 }
03402 #endif
03403 }
03404
03405 INT64 offset;
03406 INT stack_adjustment = Stack_Offset_Adjustment_For_PU();
03407 #ifdef TARG_IA64
03408 if ( ! TN_is_zero(tsize)) {
03409 #else
03410 if (!is_zero) {
03411 #endif
03412 Exp_Spadjust (SP_TN, tsize, V_SPADJUST_MINUS, &New_OPs);
03413
03414 #ifdef TARG_X8664
03415
03416
03417
03418 if( Is_Target_32bit() ){
03419 Exp_BAND( Pointer_Mtype,
03420 SP_TN, SP_TN, Gen_Literal_TN( -15, Pointer_Size ), &New_OPs);
03421 }
03422 #endif
03423
03424 offset = Current_PU_Actual_Size + stack_adjustment;
03425 }
03426 else {
03427
03428 offset = stack_adjustment;
03429 }
03430
03431 if (offset == 0) {
03432 if (result == NULL)
03433 result = SP_TN;
03434 else
03435 Exp_COPY(result, SP_TN, &New_OPs);
03436 }
03437 else {
03438 if (result == NULL)
03439 result = Build_TN_Of_Mtype (Pointer_Mtype);
03440 Exp_ADD (Pointer_Mtype, result, SP_TN,
03441 Gen_Literal_TN (offset, Pointer_Size),
03442 &New_OPs);
03443 }
03444
03445 return result;
03446 }
03447
03448 static void
03449 Handle_DEALLOCA (WN *tree)
03450 {
03451 INT stack_adjustment = Stack_Offset_Adjustment_For_PU();
03452 TN *val = Expand_Expr (WN_kid0(tree), tree, NULL);
03453 Last_Mem_OP = OPS_last(&New_OPs);
03454 if (stack_adjustment != 0) {
03455 Exp_ADD (Pointer_Mtype, val, val,
03456 Gen_Literal_TN (-stack_adjustment, Pointer_Size),
03457 &New_OPs);
03458 }
03459 Exp_Spadjust (SP_TN, val, V_SPADJUST_PLUS, &New_OPs);
03460 Set_OP_To_WN_Map (tree);
03461 }
03462
03463 #ifdef TARG_X8664
03464
03465
03466 static TN*
03467 Handle_Imm_Op (WN * expr, INT * kidno )
03468 {
03469 Is_True (WN_operator (expr) == OPR_INTRINSIC_OP,
03470 ("Handle_Imm_Op: Expected INTRINSIC_OP"));
03471
03472 INTRINSIC id = (INTRINSIC) WN_intrinsic (expr);
03473
03474 switch (id)
03475 {
03476 case INTRN_SHUFPS:
03477 case INTRN_SHUFPD:
03478 #ifdef Is_True_On
03479 {
03480 const char * intrn_name = INTRN_c_name (id);
03481 Is_True (WN_kid_count (expr) == 3,
03482 ("Handle_Imm_Op: Invalid # of kids of %s intrn", intrn_name));
03483 Is_True (WN_operator (WN_kid0 (WN_kid2 (expr))) == OPR_INTCONST,
03484 ("Handle_Imm_Op: Arg 3 of %s intrn must be immediate constant",
03485 intrn_name));
03486 }
03487 #endif
03488 *kidno = 2;
03489 return Gen_Literal_TN (WN_const_val (WN_kid0 (WN_kid2 (expr))), 4);
03490
03491 case INTRN_PSLLDQ:
03492 case INTRN_PSRLDQ:
03493 case INTRN_PSHUFD:
03494 case INTRN_PSHUFW:
03495 case INTRN_PSHUFLW:
03496 case INTRN_PSHUFHW:
03497 #ifdef Is_True_On
03498 {
03499 const char * intrn_name = INTRN_c_name (id);
03500 Is_True (WN_kid_count (expr) == 2,
03501 ("Handle_Imm_Op: Invalid # of kids of %s intrn", intrn_name));
03502 Is_True (WN_operator (WN_kid0 (WN_kid1 (expr))) == OPR_INTCONST,
03503 ("Handle_Imm_Op: Arg 2 of %s intrn must be immediate constant",
03504 intrn_name));
03505 }
03506 #endif
03507 *kidno = 1;
03508 return Gen_Literal_TN (WN_const_val (WN_kid0 (WN_kid1 (expr))), 4);
03509
03510 default:
03511 return NULL;
03512 }
03513 }
03514 #endif
03515
03516 static TN*
03517 Handle_INTRINSIC_OP (WN *expr, TN *result)
03518 {
03519 INTRINSIC id = (INTRINSIC) WN_intrinsic (expr);
03520 INTRN_RETKIND rkind = INTRN_return_kind(id);
03521 INT numkids = WN_kid_count(expr);
03522 #if defined(TARG_SL)
03523 if((id >= INTRN_C3_INTRINSIC_BEGIN) && (id <= INTRN_C3_INTRINSIC_END)) {
03524 Exp_SL_Intrinsic_Call(id, expr, &New_OPs, NULL, NULL, result);
03525 return result;
03526 }
03527 #endif
03528
03529 TN *kid0 = Expand_Expr(WN_kid0(expr), expr, NULL);
03530 TN * kid1 = NULL, * kid2 = NULL;
03531 #ifdef TARG_X8664
03532 INT imm_kidno = 0;
03533
03534 TN * imm_kid = Handle_Imm_Op (expr, &imm_kidno);
03535
03536
03537 if (imm_kid)
03538 {
03539 Is_True (imm_kidno == 1 || imm_kidno == 2,
03540 ("Immediate kid0 of intrinsic not supported"));
03541 if (imm_kidno == 1)
03542 {
03543 kid1 = imm_kid;
03544 if (numkids == 3)
03545 kid2 = Expand_Expr(WN_kid2(expr), expr, NULL);
03546 }
03547 else
03548 {
03549 Is_True (numkids == 3, ("Invalid # of kids for intrinsic"));
03550 kid1 = Expand_Expr(WN_kid1(expr), expr, NULL);
03551 kid2 = imm_kid;
03552 }
03553 }
03554 else
03555 {
03556 kid1 = (numkids >= 2) ? Expand_Expr(WN_kid1(expr), expr, NULL) : NULL;
03557
03558 if (numkids == 3) {
03559 kid2 = Expand_Expr(WN_kid2(expr), expr, NULL);
03560 }
03561 }
03562
03563 FmtAssert(numkids <= 3, ("unexpected number of kids in intrinsic_op"));
03564 #elif defined(TARG_NVISA)
03565 kid1 = (numkids >= 2) ? Expand_Expr(WN_kid1(expr), expr, NULL) : NULL;
03566 if (numkids == 3) {
03567 kid2 = Expand_Expr(WN_kid2(expr), expr, NULL);
03568 }
03569 FmtAssert(numkids <= 3, ("unexpected number of kids in intrinsic_op"));
03570 #else
03571 kid1 = (numkids == 2) ? Expand_Expr(WN_kid1(expr), expr, NULL) : NULL;
03572 FmtAssert(numkids <= 2, ("unexpected number of kids in intrinsic_op"));
03573 #endif
03574
03575 if (rkind != IRETURN_UNKNOWN && result == NULL) {
03576 result = Allocate_Result_TN(expr, NULL);
03577 }
03578
03579 #ifdef TARG_IA64
03580 Exp_Intrinsic_Op (id, result, kid0, kid1, &New_OPs);
03581 #elif defined(TARG_X8664) || defined(TARG_NVISA)
03582 const TYPE_ID mtype = WN_rtype( WN_kid0(expr) );
03583 Exp_Intrinsic_Op (id, result, kid0, kid1, kid2, mtype, &New_OPs);
03584 #else
03585 const TYPE_ID mtype = WN_rtype( WN_kid0(expr) );
03586 Exp_Intrinsic_Op (id, result, kid0, kid1, mtype, &New_OPs);
03587 #endif
03588
03589 return result;
03590 }
03591
03592 #if defined(TARG_SL)
03593 static WN*
03594 Handle_SL_Intrinsic_Op_Parm(WN* call, WN* parm, TY_IDX ty) {
03595 PLOC ploc = Get_Output_Parameter_Location(ty);
03596 WN* wn = WN_StidIntoPreg(ty, PLOC_reg(ploc), Int_Preg, parm);
03597 Expand_Expr(wn, call, NULL);
03598 return wn;
03599 }
03600
03601 TN*
03602 Preproc_Divmodsi3_To_udivremsi4_Unsigned(WN* expr) {
03603 TN *tmp, *tn_a, *tn_b;
03604 WN *parm_a, *parm_b;
03605
03606 parm_a = WN_kid(expr, 0);
03607 parm_b = WN_kid(expr, 1);
03608
03609 TN *a0 = PREG_To_TN(MTYPE_To_PREG(MTYPE_U4), 4 );
03610 TN *a1 = PREG_To_TN(MTYPE_To_PREG(MTYPE_U4), 5 );
03611
03612 tn_a = Expand_Expr(parm_a, expr, NULL);
03613 tn_b = Expand_Expr(parm_b, expr, NULL);
03614
03615 tmp = Build_TN_Of_Mtype(MTYPE_U4);
03616
03617 Build_OP(TOP_addiu, tmp, Zero_TN, Gen_Literal_TN(1, 4), &New_OPs);
03618
03619 if(TN_is_constant(tn_a)) {
03620 TN* tmp_a = Build_TN_Of_Mtype(MTYPE_U4);
03621 if (ISA_LC_Value_In_Class (TN_value(tn_a), LC_simm16)) {
03622 Build_OP(TOP_addiu, tmp_a, Zero_TN, Gen_Literal_TN(TN_value(tn_a), 4), &New_OPs);
03623 } else if ( TN_value(tn_a) >= INT32_MIN && TN_value(tn_a) <= INT32_MAX ) {
03624 Build_OP(TOP_lui, tmp_a, Gen_Literal_TN((TN_value(tn_a) >> 16) & 0xffff, 4),
03625 &New_OPs );
03626 Build_OP(TOP_ori, tmp_a, tmp_a, Gen_Literal_TN(TN_value(tn_a) & 0xffff, 4),
03627 &New_OPs );
03628 Build_OP(TOP_addu, tmp_a, Zero_TN, tmp_a, &New_OPs);
03629 }
03630 Build_OP(TOP_addu, a0, tmp_a, Zero_TN, &New_OPs);
03631 }
03632 else {
03633 Build_OP(TOP_addu, a0, tn_a, Zero_TN, &New_OPs);
03634 }
03635
03636 if(TN_is_constant(tn_b)) {
03637 TN* tmp_b = Build_TN_Of_Mtype(MTYPE_U4);
03638 if (ISA_LC_Value_In_Class (TN_value(tn_b), LC_simm16)) {
03639 Build_OP(TOP_addiu, tmp_b, Zero_TN, Gen_Literal_TN(TN_value(tn_b), 4), &New_OPs);
03640 } else if ( TN_value(tn_b) >= INT32_MIN && TN_value(tn_b) <= INT32_MAX ) {
03641 Build_OP(TOP_lui, tmp_b, Gen_Literal_TN((TN_value(tn_b) >> 16) & 0xffff, 4),
03642 &New_OPs );
03643 Build_OP(TOP_ori, tmp_b, tmp_b, Gen_Literal_TN(TN_value(tn_b) & 0xffff, 4),
03644 &New_OPs );
03645 Build_OP(TOP_addu, tmp_b, Zero_TN, tmp_b, &New_OPs);
03646 }
03647 Build_OP(TOP_addu, a1, tmp_b, Zero_TN, &New_OPs);
03648 }
03649 else {
03650 Build_OP(TOP_addu, a1, tn_b, Zero_TN, &New_OPs);
03651 }
03652 return NULL;
03653 }
03654
03655
03656
03657
03658 TN*
03659 Preproc_Divmodsi3_To_udivremsi4(WN* expr) {
03660 TN *tmp, *tn_a, *tn_b, *neg = NULL;
03661 WN *parm_a, *parm_b;
03662
03663 parm_a = WN_kid(expr, 0);
03664 parm_b = WN_kid(expr, 1);
03665
03666 TN *a0 = PREG_To_TN(MTYPE_To_PREG(MTYPE_I4), 4 );
03667 TN *a1 = PREG_To_TN(MTYPE_To_PREG(MTYPE_I4), 5 );
03668
03669 tn_a = Expand_Expr(parm_a, expr, NULL);
03670 tn_b = Expand_Expr(parm_b, expr, NULL);
03671
03672
03673 neg = Build_TN_Of_Mtype(MTYPE_I4);
03674 tmp = Build_TN_Of_Mtype(MTYPE_I4);
03675
03676 Build_OP(TOP_addiu, tmp, Zero_TN, Gen_Literal_TN(1, 4), &New_OPs);
03677
03678
03679 if(TN_is_constant(tn_a)) {
03680 TN* tmp_a = Build_TN_Of_Mtype(MTYPE_I4);
03681 if (ISA_LC_Value_In_Class (TN_value(tn_a), LC_simm16)) {
03682 Build_OP(TOP_addiu, tmp_a, Zero_TN, Gen_Literal_TN(TN_value(tn_a), 4), &New_OPs);
03683 } else if ( TN_value(tn_a) >= INT32_MIN && TN_value(tn_a) <= INT32_MAX ) {
03684 Build_OP(TOP_lui, tmp_a, Gen_Literal_TN((TN_value(tn_a) >> 16) & 0xffff, 4),
03685 &New_OPs );
03686 Build_OP(TOP_ori, tmp_a, tmp_a, Gen_Literal_TN(TN_value(tn_a) & 0xffff, 4),
03687 &New_OPs );
03688 Build_OP(TOP_addu, tmp_a, Zero_TN, tmp_a, &New_OPs);
03689 }
03690 Build_OP(TOP_mc_zc_lt, neg, tmp_a, tmp, Gen_Literal_TN(0, 4), &New_OPs);
03691 }
03692 else {
03693 Build_OP(TOP_mc_zc_lt, neg, tn_a, tmp, Gen_Literal_TN(0, 4), &New_OPs);
03694 }
03695
03696
03697 if(TN_is_constant(tn_a)) {
03698 TN* tmp_a = Build_TN_Of_Mtype(MTYPE_I4);
03699 if (ISA_LC_Value_In_Class (TN_value(tn_a), LC_simm16)) {
03700 Build_OP(TOP_addiu, tmp_a, Zero_TN, Gen_Literal_TN(TN_value(tn_a), 4), &New_OPs);
03701 } else if ( TN_value(tn_a) >= INT32_MIN && TN_value(tn_a) <= INT32_MAX ) {
03702 Build_OP(TOP_lui, tmp_a, Gen_Literal_TN((TN_value(tn_a) >> 16) & 0xffff, 4),
03703 &New_OPs );
03704 Build_OP(TOP_ori, tmp_a, tmp_a, Gen_Literal_TN(TN_value(tn_a) & 0xffff, 4),
03705 &New_OPs );
03706 Build_OP(TOP_addu, tmp_a, Zero_TN, tmp_a, &New_OPs);
03707 }
03708 Build_OP(TOP_mc_abs, tmp_a, tmp_a, &New_OPs);
03709 Build_OP(TOP_addu, a0, tmp_a, Zero_TN, &New_OPs);
03710 }
03711 else {
03712 Build_OP(TOP_mc_abs, tn_a, tn_a, &New_OPs);
03713 Build_OP(TOP_addu, a0, tn_a, Zero_TN, &New_OPs);
03714 }
03715
03716
03717 if(TN_is_constant(tn_b)) {
03718 TN* tmp_b = Build_TN_Of_Mtype(MTYPE_I4);
03719 if (ISA_LC_Value_In_Class (TN_value(tn_b), LC_simm16)) {
03720 Build_OP(TOP_addiu, tmp_b, Zero_TN, Gen_Literal_TN(TN_value(tn_b), 4), &New_OPs);
03721 } else if ( TN_value(tn_b) >= INT32_MIN && TN_value(tn_b) <= INT32_MAX ) {
03722 Build_OP(TOP_lui, tmp_b, Gen_Literal_TN((TN_value(tn_b) >> 16) & 0xffff, 4),
03723 &New_OPs );
03724 Build_OP(TOP_ori, tmp_b, tmp_b, Gen_Literal_TN(TN_value(tn_b) & 0xffff, 4),
03725 &New_OPs );
03726 Build_OP(TOP_addu, tmp_b, Zero_TN, tmp_b, &New_OPs);
03727 }
03728 Build_OP(TOP_mc_abs, tmp_b, tmp_b, &New_OPs);
03729 Build_OP(TOP_addu, a1, tmp_b, Zero_TN, &New_OPs);
03730 }
03731 else {
03732 Build_OP(TOP_mc_abs, tn_b, tn_b, &New_OPs);
03733 Build_OP(TOP_addu, a1, tn_b, Zero_TN, &New_OPs);
03734 }
03735 return neg;
03736 }
03737
03738 void
03739 Save_Restore_Div_In_Parm( WN* expr, TN* actual, UINT32 nth, BOOL sel ) {
03740
03741 if(WN_div_in_actual(expr) > 1) {
03742 TN* prev_actual = PREG_To_TN(MTYPE_To_PREG(MTYPE_I4), (nth+4) );
03743 if(!sel) {
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754 TN* tmp;
03755 OP* tmp_op = OPS_last(&New_OPs);
03756 tmp = OP_result(tmp_op, 0);
03757 while(tmp != prev_actual) {
03758 tmp_op = OP_prev(tmp_op);
03759 tmp = OP_result(tmp_op, 0);
03760 }
03761 if(OP_copy(tmp_op)) {
03762 Build_OP(TOP_addu, actual, OP_opnd(tmp_op, 0), \
03763 Zero_TN, &New_OPs);
03764 }
03765 else {
03766 Build_OP(TOP_addiu, actual, OP_opnd(tmp_op, 0), \
03767 OP_opnd(tmp_op, 1), &New_OPs);
03768 }
03769 }
03770 else {
03771 if(TN_is_constant(actual)) {
03772 Build_OP(TOP_addiu, prev_actual, Zero_TN, Gen_Literal_TN(TN_value(actual), 4), &New_OPs);
03773 }
03774 else
03775 Build_OP(TOP_addu, prev_actual, Zero_TN, actual, &New_OPs);
03776 }
03777 }
03778 }
03779
03780
03781
03782 TN*
03783 Expand_SL_DivRem_Op( WN* expr, const char* func_name, OPCODE opcode, PREG_NUM preg_num = 2, TN* result = NULL ){
03784 WN* wn_call;
03785 TN* result2, *ret_val, *ret_val2, *neg;
03786
03787 TN* tmp_actuals[WN_div_in_actual(expr)];
03788
03789
03790
03791
03792 if(WN_div_in_actual(expr)) {
03793 for( INT i = 0; i < (WN_div_in_actual(expr)-1); i++ ) {
03794 tmp_actuals[i] = Build_TN_Of_Mtype(MTYPE_I4);
03795 Save_Restore_Div_In_Parm( expr, tmp_actuals[i], i, 0);
03796 }
03797 }
03798
03799
03800 TYPE_ID rtype = WN_rtype(expr);
03801 TY_IDX ty = Make_Function_Type(MTYPE_To_TY(rtype));
03802 ST* ST = Gen_Intrinsic_Function(ty, func_name);
03803 PLOC ploc = Setup_Output_Parameter_Locations(MTYPE_To_TY(rtype));
03804 BOOL expand_parm_done = false;
03805 if(!strcmp(func_name, "udivmodsi4"))
03806 {
03807 if(opcode == OPC_I4DIV || opcode == OPC_I4REM
03808 || (opcode == OPC_I4DIVREM)) {
03809 neg = Preproc_Divmodsi3_To_udivremsi4(expr);
03810 expand_parm_done = true;
03811 }
03812 else if((opcode == OPC_U4REM) || (opcode == OPC_U4DIV) )
03813 {
03814 Preproc_Divmodsi3_To_udivremsi4_Unsigned(expr);
03815 expand_parm_done = true;
03816 }
03817 }
03818
03819
03820 extern WN* Gen_Call(const char *name, WN *arg1, WN *arg2, TYPE_ID rtype = MTYPE_V);
03821 wn_call = Gen_Call(func_name, WN_kid(expr, 0), WN_kid(expr, 1), rtype);
03822
03823 if(!expand_parm_done) {
03824 WN_actual(wn_call, 0) = Handle_SL_Intrinsic_Op_Parm( \
03825 wn_call, \
03826 WN_actual(wn_call,0), \
03827 MTYPE_To_TY(rtype));
03828 WN_actual(wn_call, 1) = Handle_SL_Intrinsic_Op_Parm( \
03829 wn_call, \
03830 WN_actual(wn_call,1), \
03831 MTYPE_To_TY(rtype));
03832 }
03833
03834 if ( !strcmp(func_name, "udivmodsi4") ) {
03835 WN* select_wn;
03836 TN *sel_tn;
03837 if( (opcode == OPC_I4REM) || ( opcode==OPC_U4REM ) ||
03838 (preg_num == 3)) {
03839 select_wn = WN_Intconst(MTYPE_I4, 1);
03840 sel_tn = Gen_Literal_TN(1, 4);
03841 }
03842 else {
03843 select_wn = WN_Intconst(MTYPE_I4, 0);
03844 sel_tn = Gen_Literal_TN(0, 4);
03845 }
03846 WN* select_parm = WN_CreateParm(MTYPE_I4, select_wn, \
03847 MTYPE_To_TY(MTYPE_I4), \
03848 WN_PARM_BY_VALUE);
03849 if(!expand_parm_done) {
03850 WN_actual(wn_call, 2) = Handle_SL_Intrinsic_Op_Parm( \
03851 wn_call, \
03852 select_parm, \
03853 MTYPE_To_TY(rtype));
03854 }
03855 else {
03856 TN *a2 = PREG_To_TN(MTYPE_To_PREG(MTYPE_I4), 6 );
03857 Build_OP(TOP_addiu, a2, Zero_TN, sel_tn, &New_OPs);
03858 }
03859 }
03860 Handle_Call_Site(wn_call, OPR_CALL);
03861 if(result == NULL) {
03862 result = Allocate_Result_TN (expr, NULL);
03863 }
03864
03865
03866 if(preg_num > 2) {
03867 result2 = TN_CORRESPOND_Get(result, expr);
03868 ret_val2 = PREG_To_TN(Return_Val_Preg, 2 );
03869 Exp_COPY(result2, ret_val2, &New_OPs);
03870 }
03871 else {
03872 ret_val = PREG_To_TN(Return_Val_Preg, preg_num);
03873 Exp_COPY(result, ret_val, &New_OPs);
03874 }
03875 if ( !strcmp(func_name, "udivmodsi4") ) {
03876 if((opcode == OPC_I4REM) || (opcode == OPC_I4DIV) || (opcode == OPC_I4DIVREM)) {
03877
03878 TN* res = (preg_num == 3) ? result2 : result;
03879
03880 WN* parm_a = WN_kid(expr, 0);
03881 WN* parm_b = WN_kid(expr, 1);
03882 TN* tn_a = Expand_Expr(parm_a, expr, NULL);
03883 TN* tn_b = Expand_Expr(parm_b, expr, NULL);
03884
03885
03886 TN* tmp = Build_TN_Of_Mtype(MTYPE_I4);
03887
03888 Build_OP(TOP_addiu, tmp, Zero_TN, Gen_Literal_TN(1, 4), &New_OPs);
03889
03890 if(opcode == OPC_I4DIV || (opcode==OPC_I4DIVREM && preg_num == 2)) {
03891 if(TN_is_constant(tn_b)) {
03892 TN* tmp_b = Build_TN_Of_Mtype(MTYPE_I4);
03893 if (ISA_LC_Value_In_Class (TN_value(tn_b), LC_simm16)) {
03894 Build_OP(TOP_addiu, tmp_b, Zero_TN, Gen_Literal_TN(TN_value(tn_b), 4), &New_OPs);
03895 } else if ( TN_value(tn_b) >= INT32_MIN && TN_value(tn_b) <= INT32_MAX ) {
03896 Build_OP(TOP_lui, tmp_b, Gen_Literal_TN((TN_value(tn_b) >> 16) & 0xffff, 4),
03897 &New_OPs );
03898 Build_OP(TOP_ori, tmp_b, tmp_b, Gen_Literal_TN(TN_value(tn_b) & 0xffff, 4),
03899 &New_OPs );
03900 Build_OP(TOP_addu, tmp_b, Zero_TN, tmp_b, &New_OPs);
03901 }
03902
03903 TN* neg_a1 = Build_TN_Of_Mtype(MTYPE_I4);
03904 Build_OP(TOP_mc_zc_lt, neg_a1, tmp_b, tmp, Gen_Literal_TN(0, 4), &New_OPs);
03905 Build_OP(TOP_xor, neg, neg, neg_a1, &New_OPs);
03906 }
03907 else {
03908 TN* neg_a1 = Build_TN_Of_Mtype(MTYPE_I4);
03909 Build_OP(TOP_mc_zc_lt, neg_a1, tn_b, tmp, Gen_Literal_TN(0, 4), &New_OPs);
03910 Build_OP(TOP_xor, neg, neg, neg_a1, &New_OPs);
03911 }
03912 }
03913 Build_OP(TOP_mc_zn_eq, res, neg, res, Gen_Literal_TN(0, 4), &New_OPs);
03914
03915 if(!TN_is_constant(tn_a)) {
03916 Build_OP(TOP_mc_zn_eq, tn_a, neg, tn_a, Gen_Literal_TN(0, 4), &New_OPs);
03917 }
03918 if(!TN_is_constant(tn_b)) {
03919 Build_OP(TOP_mc_zn_eq, tn_b, neg, tn_b, Gen_Literal_TN(0, 4), &New_OPs);
03920 }
03921
03922 if(WN_div_in_actual(expr)) {
03923 for( INT i = 0; i < (WN_div_in_actual(expr)-1); i++ ) {
03924 Save_Restore_Div_In_Parm( expr, tmp_actuals[i], i, 1);
03925 }
03926 }
03927 return res;
03928 }
03929 }
03930
03931
03932 if(WN_div_in_actual(expr)) {
03933 for( INT i = 0; i < (WN_div_in_actual(expr)-1); i++ ) {
03934 Save_Restore_Div_In_Parm( expr, tmp_actuals[i], i, 1);
03935 }
03936 }
03937 return (((preg_num > 2) ? result2 : result));
03938 }
03939
03940 BOOL
03941 Is_Power_2_Div( WN* div) {
03942 WN* divisor = WN_kid(div, 1);
03943 extern BOOL Is_Power_Of_2(INT64 val, TYPE_ID mtype);
03944 if(WN_operator(divisor) == OPR_INTCONST) {
03945 INT64 val = WN_const_val(divisor);
03946 return Is_Power_Of_2(val, WN_rtype(divisor));
03947 }
03948 return FALSE;
03949 }
03950 #endif // TARG_SL
03951
03952
03953
03954
03955
03956 static STR_IDX
03957 Get_Non_Local_Label_Name (SYMTAB_IDX level, LABEL_IDX index)
03958 {
03959
03960 char *name = (char *) alloca (11 + 1 + 8 + 1 + 8 + 1);
03961 sprintf(name, ".Lnonlocal%s%d%s%d", Label_Name_Separator,
03962 level, Label_Name_Separator, index);
03963 return Save_Str(name);
03964 }
03965
03966
03967
03968
03969
03970 #ifndef KEY
03971 static
03972 #endif
03973 LABEL_IDX
03974 Get_WN_Label (WN *wn, BOOL *is_non_local_label = NULL)
03975 {
03976 LABEL_IDX label = WN_label_number(wn);
03977 char *name;
03978 const char *label_prefix = NULL;
03979
03980 FmtAssert (OPCODE_has_label(WN_opcode(wn)),
03981 ("Get_WN_Label: invalid opcode %d ", WN_opcode(wn)));
03982 FmtAssert (LABEL_IDX_index(label) > 0 &&
03983 LABEL_IDX_index(label) <= LABEL_Table_Size(LABEL_IDX_level(label)),
03984 ("Get_WN_Label: label %d greater than last label %d",
03985 label, LABEL_Table_Size(LABEL_IDX_level(label))));
03986 #ifdef KEY
03987 if (is_non_local_label != NULL)
03988 *is_non_local_label = FALSE;
03989 #endif
03990
03991 if (LABEL_name_idx(label) == 0) {
03992 if (LABEL_target_of_goto_outer_block(label)) {
03993 Set_LABEL_name_idx (Label_Table[label],
03994 Get_Non_Local_Label_Name (CURRENT_SYMTAB, label) );
03995 #ifdef KEY
03996 if (is_non_local_label != NULL)
03997 *is_non_local_label = TRUE;
03998 #endif
03999 }
04000 else {
04001 label_prefix = LABEL_PREFIX "t";
04002 }
04003 }
04004 else if (isdigit(LABEL_name(label)[0])) {
04005
04006 label_prefix = LABEL_PREFIX;
04007 }
04008 if (label_prefix != NULL) {
04009
04010
04011 const char *oldname = (LABEL_name_idx(label) == 0
04012 ? "" : LABEL_name(label));
04013 name = (char *) alloca (strlen(label_prefix) + strlen(oldname)
04014 + 1 + 8 + 1 + 8 + 1);
04015 sprintf(name, "%s%s%s%d%s%d", label_prefix, oldname,
04016 Label_Name_Separator, Current_PU_Count(),
04017 Label_Name_Separator, label);
04018 Set_LABEL_name_idx (Label_Table[label], Save_Str(name));
04019 }
04020 return label;
04021 }
04022
04023 #if defined(TARG_SL)
04024
04025 #define IS_POWER_OF_2(x) (((x)!=0) && ((x) & ((x)-1))==0)
04026
04027 BOOL
04028 Is_Shft_Operation(WN* expr)
04029 {
04030 switch(WN_operator(expr))
04031 {
04032 case OPR_SHL:
04033 case OPR_ASHR:
04034 case OPR_LSHR:
04035 return TRUE;
04036 default:
04037 return FALSE;
04038 }
04039 }
04040
04041 void
04042 Replace_Multiply_With_Shift(WN* expr)
04043 {
04044 Is_True(WN_operator_is(expr, OPR_MPY),
04045 ("incorrect operator in replace multiply with shift"));
04046 WN* kid0 = WN_kid0(expr);
04047 WN* kid1 = WN_kid1(expr);
04048
04049 if(Get_Trace(TP_CGEXP, 4096)){
04050 fprintf(TFile,
04051 "======before replace multiply with shift======\n");
04052 fdump_tree(TFile, expr);
04053 }
04054
04055 if(WN_operator_is(kid0, OPR_INTCONST) &&
04056 IS_POWER_OF_2(WN_const_val(kid0))) {
04057 WN_set_operator(expr, OPR_SHL);
04058 WN_kid1(expr) = kid0;
04059 INT const_val = WN_const_val(kid0);
04060 INT shft_amnt = 0;
04061 INT tmp = const_val;
04062 while(1)
04063 {
04064 if(tmp == 0 || tmp & 0x1)
04065 break;
04066 else {
04067 shft_amnt++;
04068 tmp = const_val >> shft_amnt;
04069 }
04070 }
04071 WN_kid0(expr) = WN_CreateIntconst(OPC_I4INTCONST, shft_amnt);
04072 }
04073 else {
04074 WN_set_operator(expr, OPR_SHL);
04075 INT const_val = WN_const_val(kid1);
04076 INT shft_amnt = 0;
04077 INT tmp = const_val;
04078 while(1)
04079 {
04080 if(tmp == 0 || tmp & 0x1)
04081 break;
04082 else {
04083 shft_amnt++;
04084 tmp = const_val >> shft_amnt;
04085 }
04086 }
04087 WN_kid1(expr) = WN_CreateIntconst(OPC_I4INTCONST, shft_amnt);
04088 }
04089
04090 if(Get_Trace(TP_CGEXP, 4096)){
04091 fprintf(TFile,
04092 "======after replace multiply with shift======\n");
04093 fdump_tree(TFile, expr);
04094 }
04095 return;
04096 }
04097
04098 BOOL
04099 Has_Shift_Operation(WN* expr)
04100 {
04101 WN* kid0 = WN_kid0(expr);
04102 WN* kid1 = WN_kid1(expr);
04103
04104 BOOL kid0_has_shft = Is_Shft_Operation(kid0);
04105
04106 BOOL kid1_has_shft = Is_Shft_Operation(kid1);
04107
04108
04109 if(WN_operator_is(expr, OPR_BIOR)) {
04110 if(kid0_has_shft && !WN_operator_is(WN_kid1(kid0), OPR_INTCONST))
04111 return FALSE;
04112 else if(kid1_has_shft && !WN_operator_is(WN_kid1(kid1), OPR_INTCONST))
04113 return FALSE;
04114 }
04115
04116
04117
04118
04119
04120
04121
04122
04123 if(kid0_has_shft &&
04124 WN_operator(WN_kid0(kid0))!= OPR_INTCONST &&
04125 WN_operator(kid1) !=OPR_INTCONST)
04126 return TRUE;
04127
04128
04129
04130 else if(kid1_has_shft &&
04131 !WN_operator_is(WN_kid0(kid1), OPR_INTCONST) &&
04132 !WN_operator_is(expr, OPR_SUB) &&
04133 WN_operator(kid0) != OPR_INTCONST)
04134 return TRUE;
04135
04136
04137
04138 if(WN_operator_is(kid0, OPR_MPY) && !WN_operator_is(kid1, OPR_INTCONST)){
04139 if(WN_operator_is(WN_kid0(kid0), OPR_INTCONST) &&
04140 IS_POWER_OF_2(WN_const_val(WN_kid0(kid0)))) {
04141
04142 Replace_Multiply_With_Shift(kid0);
04143 return TRUE;
04144 }
04145 else if(WN_operator_is(WN_kid1(kid0), OPR_INTCONST) &&
04146 IS_POWER_OF_2(WN_const_val(WN_kid1(kid0)))) {
04147
04148 Replace_Multiply_With_Shift(kid0);
04149 return TRUE;
04150 }
04151 }
04152 else if(WN_operator_is(kid1, OPR_MPY) &&
04153 !WN_operator_is(kid0, OPR_INTCONST) &&
04154 !WN_operator_is(expr, OPR_SUB)){
04155
04156 if(WN_operator_is(WN_kid0(kid1), OPR_INTCONST) &&
04157 IS_POWER_OF_2(WN_const_val(WN_kid0(kid1)))){
04158
04159 Replace_Multiply_With_Shift(kid1);
04160 return TRUE;
04161 }
04162 else if(WN_operator_is(WN_kid1(kid1), OPR_INTCONST) &&
04163 IS_POWER_OF_2(WN_const_val(WN_kid1(kid1)))){
04164
04165 Replace_Multiply_With_Shift(kid1);
04166 return TRUE;
04167 }
04168 }
04169 if((kid0_has_shft || kid1_has_shft) &&
04170 Get_Trace(TP_CGEXP, 2048)){
04171 fprintf(TFile,
04172 "expr can't be converted to c2.sh\n");
04173 fdump_tree(TFile, expr);
04174 }
04175
04176 return FALSE;
04177 }
04178
04179 static TN*
04180 Handle_Shift_Operation(WN* expr, TN* result)
04181 {
04182
04183 WN* kid0 = WN_kid0(expr);
04184 WN* kid1 = WN_kid1(expr);
04185 TN* shft_value;
04186 TN* opnd0;
04187 TN* opnd1;
04188
04189 if(!Is_Shft_Operation(kid0) && Is_Shft_Operation(kid1)) {
04190 WN_kid1(expr) = kid0;
04191 WN_kid0(expr) = kid1;
04192 kid0 = kid1;
04193 kid1 = WN_kid1(expr);
04194 }
04195
04196 opnd0 = Expand_Expr(WN_kid0(kid0), kid0, NULL);
04197 opnd1 = Expand_Expr(kid1, expr, NULL);
04198 shft_value = Expand_Expr(WN_kid1(kid0), kid0, NULL);
04199
04200 if(result == NULL)
04201 result = Allocate_Result_TN(expr, NULL);
04202
04203 BOOL shft_left = (WN_operator(kid0) == OPR_SHL) ? TRUE : FALSE;
04204 BOOL shft_arith = (WN_operator(kid0) == OPR_ASHR) ? TRUE : FALSE;
04205 BOOL shft_imm = (WN_operator(WN_kid1(kid0)) == OPR_INTCONST) ? TRUE : FALSE;
04206 TOP opcode;
04207 switch(WN_operator(expr))
04208 {
04209 case OPR_ADD:
04210 if(shft_imm)
04211 opcode = shft_left ? TOP_c2_shadd_l_i :
04212 (shft_arith ? TOP_c2_shadd_ra_i : TOP_c2_shadd_rl_i);
04213 else
04214 opcode = shft_left ? TOP_c2_shadd_l :
04215 (shft_arith ? TOP_c2_shadd_ra : TOP_c2_shadd_rl);
04216 break;
04217 case OPR_SUB:
04218 if(shft_imm)
04219 opcode = shft_left ? TOP_c2_shsub_l_i :
04220 (shft_arith ? TOP_c2_shsub_ra_i : TOP_c2_shsub_rl_i);
04221 else
04222 opcode = shft_left ? TOP_c2_shsub_l :
04223 (shft_arith ? TOP_c2_shsub_ra : TOP_c2_shsub_rl);
04224 break;
04225 case OPR_BIOR:
04226 if(shft_imm)
04227 opcode = shft_left ? TOP_c2_shor_l_i :
04228 (shft_arith ? TOP_c2_shor_ra_i : TOP_c2_shor_rl_i);
04229 else
04230 opcode = shft_left ? TOP_c2_shor_l :
04231 (shft_arith ? TOP_c2_shor_ra : TOP_c2_shor_rl);
04232 break;
04233 default:
04234 Fail_FmtAssertion("unexpected operator in shift+alu combination");
04235 }
04236
04237 Build_OP(opcode, result, opnd0, shft_value, opnd1, &New_OPs);
04238
04239 return result;
04240 }
04241 #endif
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259 #if defined(TARG_SL)
04260 TN *
04261 Expand_Expr (WN *expr, WN *parent, TN *result, INTRINSIC intrn_id)
04262 #else
04263 static TN *
04264 Expand_Expr (WN *expr, WN *parent, TN *result)
04265 #endif
04266 {
04267 OPCODE opcode;
04268 OPERATOR opr;
04269 INT num_opnds;
04270 INT i;
04271 TN *opnd_tn[OP_MAX_FIXED_OPNDS];
04272 TN *const_tn;
04273 TOP top;
04274 INT const_operands = 0;
04275
04276 opcode = WN_opcode (expr);
04277 opr = WN_operator(expr);
04278
04279 PU_WN_Cnt++;
04280 #if Is_True_On
04281 if (WN_rtype(expr) == MTYPE_C4 ||
04282 WN_rtype(expr) == MTYPE_C8 ||
04283 #ifdef TARG_IA64
04284 WN_rtype(expr) == MTYPE_C10 ||
04285 #endif
04286 WN_rtype(expr) == MTYPE_CQ)
04287 {
04288 ErrMsg (EC_Unimplemented, "Expand_Expr: COMPLEX");
04289 }
04290 if (opcode == OPC_MLOAD || opcode == OPC_MSTORE) {
04291 ErrMsg (EC_Unimplemented, "Expand_Expr: MLOAD/MSTORE");
04292 }
04293 #endif
04294
04295 top = WHIRL_To_TOP (expr);
04296 if (TOP_is_noop(top)
04297 #ifdef TARG_IA64
04298 && (opr == OPR_PAREN || opr == OPR_TAS || opr == OPR_PARM))
04299 #else
04300 && (opr == OPR_PAREN ||
04301 #ifndef TARG_X8664
04302 opr == OPR_TAS ||
04303 #else
04304 opr == OPR_TAS && top == TOP_nop ||
04305 #endif
04306 opr == OPR_PARM))
04307 #endif
04308 {
04309
04310
04311
04312 return Expand_Expr (WN_kid0(expr), parent, result
04313 #if defined(TARG_SL)
04314 , intrn_id
04315 #endif
04316 );
04317 }
04318
04319
04320 if (top != TOP_UNDEFINED) {
04321 num_opnds = ISA_OPERAND_INFO_Operands(ISA_OPERAND_Info(top))
04322 - (TOP_is_predicated(top) != 0);
04323 } else {
04324 num_opnds = OPCODE_nkids(opcode);
04325 }
04326 FmtAssert(num_opnds <= OP_MAX_FIXED_OPNDS, ("too many operands (%d)", num_opnds));
04327
04328 if (OPCODE_has_sym(opcode) && WN_st(expr) != NULL) {
04329
04330 Allocate_Object (WN_st(expr));
04331 }
04332
04333 #ifdef TARG_IA64
04334
04335
04336
04337 if (Is_Old_Boolean_Expression(expr)) {
04338
04339
04340
04341 if (parent && WN_operator(parent)==OPR_SELECT) {
04342 if (Trace_WhirlToOp) {
04343 fprintf(TFile, "Replace select operator\n");
04344 }
04345 return Handle_Bool_As_Predicate(expr, parent, 0);
04346 }
04347 else
04348 FmtAssert(true, ("!!!Operator may handle boolean result improperly, pls check."));
04349 }
04350 #endif
04351
04352 switch (opr) {
04353
04354 case OPR_LDID:
04355 return Handle_LDID (expr, result, opcode);
04356
04357 case OPR_LDBITS:
04358 return Handle_LDBITS (expr, result, opcode);
04359
04360 case OPR_STID:
04361 Handle_STID (expr, opcode);
04362 return NULL;
04363
04364 case OPR_STBITS:
04365 Handle_STBITS (expr);
04366 return NULL;
04367
04368 case OPR_LDA:
04369 return Handle_LDA (expr, parent, result, opcode);
04370
04371 case OPR_LDA_LABEL:
04372
04373
04374 {
04375 ST *st = New_ST (CURRENT_SYMTAB);
04376 ST_Init (st, Save_Str (LABEL_name(Get_WN_Label(expr))),
04377 CLASS_NAME, SCLASS_UNKNOWN, EXPORT_LOCAL, WN_ty(expr));
04378 opnd_tn[0] = Gen_Symbol_TN (st, 0, 0);
04379 }
04380 num_opnds = 1;
04381 break;
04382
04383 #ifndef KEY
04384 case OPR_GOTO_OUTER_BLOCK:
04385
04386
04387 {
04388 ST *st = New_ST (CURRENT_SYMTAB);
04389 ST_Init (st, Get_Non_Local_Label_Name (
04390 WN_label_level(expr), WN_label_number(expr) ),
04391 CLASS_NAME, SCLASS_UNKNOWN, EXPORT_LOCAL, WN_ty(expr));
04392 opnd_tn[0] = Gen_Symbol_TN (st, 0, 0);
04393 }
04394 num_opnds = 1;
04395 break;
04396 #endif
04397
04398 case OPR_ILOAD:
04399 return Handle_ILOAD (expr, result, opcode);
04400
04401 case OPR_ILDBITS:
04402 return Handle_ILDBITS (expr, result, opcode);
04403
04404 case OPR_EXTRACT_BITS:
04405 return Handle_EXTRACT_BITS (expr, result, opcode);
04406
04407 case OPR_ISTORE:
04408 Handle_ISTORE (expr, opcode);
04409 return NULL;
04410
04411 case OPR_ISTBITS:
04412 Handle_ISTBITS (expr);
04413 return NULL;
04414
04415 case OPR_COMPOSE_BITS:
04416 return Handle_COMPOSE_BITS (expr, result, opcode);
04417
04418 case OPR_SELECT:
04419 return Handle_SELECT(expr, result, opcode);
04420
04421 #ifdef TARG_X8664
04422 case OPR_SHUFFLE:
04423 return Handle_SHUFFLE(expr, result);
04424
04425 case OPR_RROTATE:
04426 return Handle_RROTATE(expr, result);
04427 #endif
04428
04429 case OPR_CALL:
04430 case OPR_ICALL:
04431 case OPR_PICCALL:
04432 Handle_Call_Site (expr, opr);
04433 return NULL;
04434
04435 case OPR_CONST:
04436 if (result == NULL) {
04437 result = Allocate_Result_TN (expr, NULL);
04438 if (CGSPILL_Rematerialize_Constants) {
04439 Set_TN_is_rematerializable(result);
04440 Set_TN_home (result, expr);
04441 }
04442 }
04443 #ifdef TARG_X8664
04444 if (WN_rtype(expr) == MTYPE_V16F4 ||
04445 WN_rtype(expr) == MTYPE_V16F8 ||
04446 WN_rtype(expr) == MTYPE_V16C4 ||
04447 WN_rtype(expr) == MTYPE_V16I1 ||
04448 WN_rtype(expr) == MTYPE_V16I2 ||
04449 WN_rtype(expr) == MTYPE_V16I4 ||
04450 WN_rtype(expr) == MTYPE_V16I8) {
04451 TCON then = ST_tcon_val(WN_st(expr));
04452 TCON now = Create_Simd_Const (WN_rtype(expr), then);
04453 ST *sym = New_Const_Sym (Enter_tcon (now), Be_Type_Tbl(WN_rtype(expr)));
04454 Allocate_Object(sym);
04455 opnd_tn[0] = Gen_Symbol_TN (sym, 0, 0);
04456 } else
04457 #endif
04458 opnd_tn[0] = Gen_Symbol_TN (WN_st(expr), 0, 0);
04459 num_opnds = 1;
04460 break;
04461
04462 case OPR_INTCONST:
04463
04464
04465
04466 switch (opcode) {
04467 case OPC_I8INTCONST:
04468 case OPC_U8INTCONST:
04469 #if defined(EMULATE_LONGLONG) && !defined(TARG_SL)
04470 const_tn = Gen_Literal_TN_Pair((UINT64) WN_const_val(expr));
04471 #else
04472 const_tn = Gen_Literal_TN (WN_const_val(expr), 8);
04473 #endif
04474 break;
04475 #ifndef TARG_X8664
04476 case OPC_I4INTCONST:
04477 case OPC_U4INTCONST:
04478
04479
04480 const_tn = Gen_Literal_TN ((INT32) WN_const_val(expr), 4);
04481 break;
04482 #else
04483 case OPC_I4INTCONST:
04484
04485
04486 const_tn = Gen_Literal_TN ((INT32) WN_const_val(expr), 4);
04487 break;
04488 case OPC_U4INTCONST:
04489 const_tn = Gen_Literal_TN ((UINT32) WN_const_val(expr), 4);
04490 break;
04491 #endif
04492 case OPC_BINTCONST:
04493 if (result == NULL) result = Allocate_Result_TN (expr, NULL);
04494 Exp_Pred_Set(result, Get_Complement_TN(result), WN_const_val(expr), &New_OPs);
04495 return result;
04496
04497
04498 default:
04499 #pragma mips_frequency_hint NEVER
04500 FmtAssert(FALSE, ("Expand_Expr: %s unhandled", OPCODE_name(opcode)));
04501
04502 }
04503
04504
04505
04506
04507
04508 if (Has_Immediate_Operand (parent, expr)) {
04509 if (Get_Trace (TP_CGEXP, 8)) {
04510 #pragma mips_frequency_hint NEVER
04511 fprintf(TFile, "has_immed: %s\n", OPCODE_name(WN_opcode(parent)));
04512 }
04513 return const_tn;
04514 }
04515
04516
04517
04518
04519 if (result == NULL) {
04520 if (opcode == OPC_BINTCONST) {
04521
04522
04523
04524 if (True_TN && WN_const_val(expr) == 1) return True_TN;
04525 } else {
04526
04527
04528
04529 #if !(defined(TARG_SL) && defined(EMULATE_LONGLONG))
04530 if (Zero_TN && WN_const_val(expr) == 0) return Zero_TN;
04531 #endif
04532 }
04533 }
04534
04535 if (CGSPILL_Rematerialize_Constants && result == NULL) {
04536 result = Allocate_Result_TN (expr, NULL);
04537 #ifdef TARG_X8664
04538
04539 if( !OP_NEED_PAIR( WN_rtype(expr) ) )
04540 #endif // TARG_X8664
04541 {
04542 Set_TN_is_rematerializable(result);
04543 Set_TN_home (result, expr);
04544 }
04545 }
04546
04547 opnd_tn[0] = const_tn;
04548 num_opnds = 1;
04549 break;
04550
04551 case OPR_CVTL:
04552 if (Is_CVT_Noop(expr, parent))
04553 {
04554 return Expand_Expr(WN_kid0(expr), parent, result);
04555 }
04556 else {
04557 opnd_tn[0] = Expand_Expr (WN_kid0(expr), expr, NULL);
04558 opnd_tn[1] = Gen_Literal_TN (WN_cvtl_bits(expr), 4);
04559 num_opnds = 2;
04560 }
04561 break;
04562
04563 case OPR_CVT:
04564 if (Is_CVT_Noop(expr, parent))
04565 {
04566 return Expand_Expr(WN_kid0(expr), parent, result);
04567 }
04568 else if (Is_CVTL_Opcode(opcode))
04569 {
04570 opnd_tn[0] = Expand_Expr (WN_kid0(expr), expr, NULL);
04571 opnd_tn[1] = Gen_Literal_TN (32, 4);
04572 num_opnds = 2;
04573 }
04574 else
04575 {
04576 Is_True(WN_desc(expr) != MTYPE_B || WN_rtype(WN_kid0(expr)) == MTYPE_B,
04577 ("rtype of xxBCVT kid is not MTYPE_B"));
04578 #ifdef TARG_NVISA
04579 if (WN_desc(expr) == MTYPE_B && WN_operator_is(WN_kid0(expr), OPR_LNOT)) {
04580
04581
04582
04583
04584 DevWarn("special-case handling of CVT of LNOT");
04585 opnd_tn[0] = Expand_Expr(WN_kid0(WN_kid0(expr)), expr, NULL);
04586 if (result == NULL) {
04587 result = Allocate_Result_TN (expr, opnd_tn);
04588 }
04589
04590
04591
04592
04593 if (TN_register_class(opnd_tn[0]) != ISA_REGISTER_CLASS_predicate
04594 && TN_register_class(result) != ISA_REGISTER_CLASS_predicate)
04595 {
04596 VARIANT variant = V_NONE;
04597 if (OPCODE_is_boolean(WN_opcode(WN_kid0(WN_kid0(expr))))
04598 || TN_is_boolean(opnd_tn[0]))
04599 {
04600 Set_V_normalized_op1(variant);
04601 Set_TN_is_boolean(result);
04602 }
04603 Exp_OP1v (OPCODE_make_op(OPR_LNOT,
04604 OPCODE_rtype(opcode), WN_desc(WN_kid0(WN_kid0(expr)))),
04605 result, opnd_tn[0], variant, &New_OPs);
04606 }
04607 else {
04608
04609 Exp_OP1v (opcode, result, opnd_tn[0], V_BR_FALSE, &New_OPs);
04610 }
04611 return result;
04612 }
04613 #endif
04614 opnd_tn[0] = Expand_Expr (WN_kid0(expr), expr, NULL);
04615 num_opnds = 1;
04616 }
04617 break;
04618
04619 case OPR_PREFETCH:
04620 case OPR_PREFETCHX:
04621 if (Prefetch_Kind_Enabled(expr)) {
04622 VARIANT variant = V_NONE;
04623 Set_V_pf_flags(variant, WN_prefetch_flag(expr));
04624 Last_Mem_OP = OPS_last(&New_OPs);
04625 Exp_Prefetch (top,
04626 Expand_Expr (WN_kid(expr,0), expr, NULL),
04627 (opr == OPR_PREFETCH) ?
04628 Gen_Literal_TN (WN_offset(expr), 4) :
04629 Expand_Expr (WN_kid(expr,1), expr, NULL),
04630 variant,
04631 &New_OPs);
04632 Set_OP_To_WN_Map(expr);
04633 }
04634 return NULL;
04635
04636 case OPR_DIVREM:
04637 #if defined(TARG_SL)
04638 {
04639
04640 TN *ra_sv_tn = Build_TN_Like(RA_TN);
04641 Exp_COPY (ra_sv_tn, RA_TN, &New_OPs);
04642
04643
04644 const char * func_name;
04645 if(Opt_Level >= 2 || (opcode == OPC_U4DIVREM)) {
04646 func_name = "udivmodsi4";
04647 }
04648 else {
04649 func_name = "__divsi3";
04650 }
04651 TN* tmp_result = result;
04652
04653
04654 tmp_result = Expand_SL_DivRem_Op(expr, func_name, opcode, 2, tmp_result);
04655
04656 if(Opt_Level >= 2 || (opcode == OPC_U4DIVREM)) {
04657 func_name = "udivmodsi4";
04658 }
04659 else {
04660 func_name = "__modsi3";
04661 }
04662
04663
04664
04665
04666 tmp_result = Expand_SL_DivRem_Op(expr, func_name, opcode, 3, tmp_result);
04667
04668
04669 Exp_COPY (RA_TN, ra_sv_tn, &New_OPs);
04670 Set_OP_no_move_before_gra(OPS_last(&New_OPs));
04671
04672 return result;
04673 }
04674 #else
04675 return Handle_DIVREM(expr, parent, result, opcode);
04676 #endif // TARG_SL
04677
04678 case OPR_DIVPART:
04679 return Handle_DIVPART(expr, parent, result);
04680
04681 case OPR_REMPART:
04682 return Handle_REMPART(expr, parent, result);
04683
04684 case OPR_MINMAX:
04685 return Handle_MINMAX(expr, parent, result, opcode);
04686
04687 case OPR_MINPART:
04688 return Handle_MINPART(expr, parent, result);
04689
04690 case OPR_MAXPART:
04691 return Handle_MAXPART(expr, parent, result);
04692
04693 case OPR_LNOT:
04694 return Handle_LNOT(expr, parent, result);
04695
04696 case OPR_LIOR:
04697 case OPR_LAND:
04698 return Handle_LAND_LIOR(expr, parent, result);
04699
04700 case OPR_ALLOCA:
04701 return Handle_ALLOCA (expr, result);
04702
04703 case OPR_DEALLOCA:
04704 Handle_DEALLOCA (expr);
04705 return NULL;
04706
04707 case OPR_INTRINSIC_OP:
04708 #if defined(TARG_SL)
04709 if (result == NULL)
04710 result = Allocate_Result_TN (expr, NULL);
04711 #endif
04712 if (WN_intrinsic(expr)==INTRN_EXPECT)
04713 return Expand_Expr(WN_kid0(WN_kid0(expr)), WN_kid0(expr), result);
04714 return Handle_INTRINSIC_OP (expr, result);
04715
04716 #if defined(TARG_SL) // expand div/rem
04717 case OPR_DIV:
04718 case OPR_REM:
04719 {
04720 const char * func_name;
04721 TN* ret_val;
04722 BOOL expand_div = TRUE;
04723 if(!(((opr == OPR_DIV)||(opr == OPR_REM)) && (Is_Power_2_Div(expr))))
04724 {
04725 switch(opcode) {
04726 case OPC_I4DIV:
04727 func_name = (Opt_Level >=2) ? ("udivmodsi4") : ("__divsi3");
04728 break;
04729 case OPC_U4DIV:
04730 func_name = "udivmodsi4";
04731 break;
04732 case OPC_F4DIV:
04733 func_name = "__divsf3";
04734 break;
04735 case OPC_I4REM:
04736 func_name = (Opt_Level >=2) ? ("udivmodsi4") : ("__modsi3");
04737 break;
04738 case OPC_U4REM:
04739 func_name = (Opt_Level >= 2) ? ("udivmodsi4") : ("__umodsi3");
04740 break;
04741 default:
04742 DevWarn(("Don't support %s div/rem function call operation\n", OPCODE_name(opcode)));
04743 expand_div = FALSE;
04744
04745 }
04746 if(expand_div) {
04747
04748
04749 TN *ra_sv_tn = Build_TN_Like(RA_TN);
04750 Exp_COPY (ra_sv_tn, RA_TN, &New_OPs);
04751
04752 TN* divide_result = Expand_SL_DivRem_Op(expr, func_name, opcode, 2, result);
04753
04754
04755 Exp_COPY (RA_TN, ra_sv_tn, &New_OPs);
04756 Set_OP_no_move_before_gra(OPS_last(&New_OPs));
04757
04758 return divide_result;
04759 }
04760
04761
04762 }
04763 else {
04764
04765 DevWarn("power of 2 div/rem");
04766 }
04767 }
04768 #endif // TARG_SL
04769
04770 #if defined(TARG_SL)
04771 case OPR_ADD:
04772 case OPR_SUB:
04773 case OPR_BIOR:
04774 if(CG_sl2 && CG_opt_level > 1 &&
04775 CG_SL2_enable_peephole &&
04776 Has_Shift_Operation(expr)) {
04777 return Handle_Shift_Operation(expr, result);
04778 }
04779 #endif
04780
04781 default:
04782 for (i = 0; i < num_opnds; i++) {
04783 opnd_tn[i] = Expand_Expr (WN_kid(expr, i), expr, NULL
04784 #if defined(TARG_SL)
04785 , intrn_id
04786 #endif
04787 );
04788
04789 if (TN_has_value(opnd_tn[i])) {
04790 #if TODO_MONGOOSE
04791
04792 Is_True (const_operands == 0,
04793 ("Expand_Expr: cannot have more than 1 constant operand"));
04794 #else
04795 if (const_operands != 0) {
04796 TN *ldimm_tn = Build_TN_Like (opnd_tn[i]);
04797 Last_Mem_OP = OPS_last(&New_OPs);
04798 Exp_OP1 (OPC_I4INTCONST, ldimm_tn, opnd_tn[i], &New_OPs);
04799 Set_OP_To_WN_Map(expr);
04800 opnd_tn[i] = ldimm_tn;
04801 printf ("Expand_Expr: cannot have more than 1 constant operand\n");
04802 }
04803 #endif
04804 const_operands++;
04805 }
04806 }
04807 break;
04808 }
04809
04810
04811 if (OPCODE_is_expression(opcode) && (result == NULL)) {
04812 result = Allocate_Result_TN (expr, opnd_tn);
04813 }
04814
04815
04816
04817
04818 Last_Mem_OP = OPS_last(&New_OPs);
04819 if (num_opnds > 3) {
04820 ErrMsg (EC_Unimplemented, "Expand_Expr: cannot handle more than 3 opnds");
04821 }
04822 if (top != TOP_UNDEFINED) {
04823
04824
04825 if (TOP_is_predicated(top)) {
04826 Build_OP (top, result, True_TN, opnd_tn[0], opnd_tn[1], opnd_tn[2],
04827 &New_OPs);
04828 } else {
04829 Build_OP (top, result, opnd_tn[0], opnd_tn[1], opnd_tn[2], &New_OPs);
04830 }
04831 } else {
04832 switch (num_opnds) {
04833 case 0:
04834 Exp_OP0 (opcode, result, &New_OPs);
04835 break;
04836 case 1:
04837 Exp_OP1 (opcode, result, opnd_tn[0], &New_OPs);
04838 break;
04839 case 2:
04840 Exp_OP2 (opcode, result, opnd_tn[0], opnd_tn[1], &New_OPs);
04841 break;
04842 case 3:
04843 Exp_OP3 (opcode, result, opnd_tn[0], opnd_tn[1], opnd_tn[2], &New_OPs);
04844 break;
04845 }
04846 }
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856 if (opr == OPR_TAS) Reset_TN_is_fpu_int(result);
04857
04858 Set_OP_To_WN_Map(expr);
04859 return result;
04860 }
04861
04862
04863
04864
04865
04866 BB *
04867 Add_Label (LABEL_IDX label)
04868 {
04869 BB *bb = Start_New_Basic_Block ();
04870 BB_Add_Annotation (bb, ANNOT_LABEL, (void *)(INTPTR)label);
04871 FmtAssert (Get_Label_BB(label) == NULL,
04872 ("Add_Label: Label %s defined more than once", LABEL_name(label)));
04873 Set_Label_BB (label,bb);
04874 return bb;
04875 }
04876
04877 static void
04878 Link_BBs (BB *bb, LABEL_IDX label)
04879 {
04880 BB *dst_bb = Get_Label_BB(label);
04881
04882 FmtAssert(dst_bb != (LABEL_IDX) 0,
04883 ("Build_CFG: Label %s not defined", ST_name(label)));
04884
04885 Link_Pred_Succ(bb, dst_bb);
04886 }
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899 static
04900 BOOL label_is_external ( INT *num, WN *wn, BB *bb )
04901 {
04902 INT32 label_number;
04903 LABEL_IDX label;
04904 BB *target_bb;
04905 RID *rid = BB_rid( bb );
04906 INT j;
04907 WN *goto_wn;
04908 BOOL match;
04909
04910 label_number = WN_label_number( wn );
04911 label = label_number;
04912 target_bb = Get_Label_BB ( label );
04913
04914 if ( ( target_bb == NULL ) || ( BB_id( target_bb ) < min_bb_id ) )
04915 {
04916 FmtAssert (rid, ("RID == NULL, label %d doesn't have a matching target",
04917 label_number));
04918 if ( RID_num_exits( rid ) == 1 ) {
04919 *num = 0;
04920 return TRUE;
04921 }
04922 FmtAssert( RID_num_exits( rid ) > 1,
04923 ("found branch to external label when num_exits <= 0") );
04924
04925 goto_wn = WN_first( WN_region_exits ( RID_rwn( rid ) ) );
04926 match = FALSE;
04927 for ( j = 0; j < RID_num_exits( rid ); j++ ) {
04928 if ( label_number == WN_label_number( goto_wn ) ) {
04929 *num = j;
04930 match = TRUE;
04931 break;
04932 }
04933 goto_wn = WN_next( goto_wn );
04934 }
04935 FmtAssert( match, ("no matching label found in REGION exits for "
04936 "external label L%d, RGN %d, BB%d",
04937 label_number, RID_id(rid), BB_id(bb)));
04938 return TRUE;
04939 }
04940
04941 return FALSE;
04942 }
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953 BOOL Prefetch_Kind_Enabled( WN *wn )
04954 {
04955 BOOL is_read, is_write;
04956 BOOL is_L1, is_L2;
04957 BOOL z_conf;
04958 BOOL confidence_match;
04959 INT32 nz_conf;
04960
04961 is_read = WN_pf_read( wn );
04962 is_write = WN_pf_write( wn );
04963 is_L1 = ( WN_pf_stride_1L( wn ) != 0 );
04964 is_L2 = ( WN_pf_stride_2L( wn ) != 0 );
04965
04966 z_conf = ( WN_pf_confidence( wn ) == 0 );
04967 nz_conf = WN_pf_confidence( wn );
04968 confidence_match = ( ( z_conf && CG_enable_z_conf_prefetch )
04969 || ( (nz_conf > 1) && CG_enable_nz_conf_prefetch ) );
04970
04971 if ( confidence_match ) {
04972
04973 if ( is_read && is_L1 )
04974 return CG_enable_pf_L1_ld;
04975
04976 if ( is_write && is_L1 )
04977 return CG_enable_pf_L1_st;
04978
04979 if ( is_read && is_L2 )
04980 return CG_enable_pf_L2_ld;
04981
04982 if ( is_write && is_L2 )
04983 return CG_enable_pf_L2_st;
04984 }
04985
04986 return FALSE;
04987 }
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998 BOOL Has_External_Branch_Target( BB *bb )
04999 {
05000 WN *branch_wn = BB_branch_wn( bb );
05001 WN *wn;
05002 INT i,j;
05003
05004 if ( branch_wn == NULL )
05005 return FALSE;
05006
05007 switch ( WN_opcode( branch_wn ) ) {
05008 case OPC_TRUEBR:
05009 case OPC_FALSEBR:
05010 case OPC_GOTO:
05011 return label_is_external( &j, branch_wn, bb );
05012 #ifdef KEY
05013 case OPC_GOTO_OUTER_BLOCK:
05014 #endif
05015 case OPC_REGION_EXIT:
05016 return TRUE;
05017 case OPC_COMPGOTO:
05018 wn = WN_first( WN_kid1( branch_wn ) );
05019 for ( i = 0; i < WN_num_entries( branch_wn ); i++ ) {
05020 if ( label_is_external( &j, wn, bb ) )
05021 return TRUE;
05022 wn = WN_next( wn );
05023 }
05024 if ( WN_kid_count( branch_wn ) == 3 ) {
05025 if ( label_is_external( &j, WN_kid( branch_wn, 2 ), bb ) )
05026 return TRUE;
05027 }
05028 return FALSE;
05029 default:
05030 #pragma mips_frequency_hint NEVER
05031 FmtAssert( FALSE, ("unexpected opcode in Has_External_Branch_Target") );
05032
05033 }
05034 }
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044
05045 BOOL Has_External_Fallthru( BB *bb )
05046 {
05047 WN *branch_wn = BB_branch_wn( bb );
05048
05049 if ( BB_exit( bb ) )
05050 return FALSE;
05051
05052 if ( ( branch_wn == NULL )
05053 || ( WN_opcode( branch_wn ) == OPC_TRUEBR ||
05054 WN_opcode( branch_wn ) == OPC_FALSEBR ) ) {
05055 return ( BB_next( bb ) == NULL );
05056 }
05057
05058 switch ( WN_opcode( branch_wn ) ) {
05059 case OPC_GOTO:
05060 case OPC_COMPGOTO:
05061 #ifdef KEY
05062 case OPC_GOTO_OUTER_BLOCK:
05063 #endif
05064 return FALSE;
05065 case OPC_REGION_EXIT:
05066 return TRUE;
05067 default:
05068 #pragma mips_frequency_hint NEVER
05069 FmtAssert( FALSE, ("unexpected opcode in Has_External_Fallthru") );
05070
05071 }
05072 }
05073
05074 #ifdef KEY
05075
05076
05077
05078 static float get_branch_confidence (BB * bb)
05079 {
05080 WN * branch_wn = BB_branch_wn(bb);
05081 if (!branch_wn || (WN_operator(branch_wn) != OPR_TRUEBR &&
05082 WN_operator(branch_wn) != OPR_FALSEBR))
05083 return -1.0;
05084
05085 WN * cond = WN_kid0(branch_wn);
05086 if (!cond ||
05087 (WN_operator(cond) != OPR_EQ && WN_operator(cond) != OPR_NE))
05088 return -1.0;
05089
05090 WN * intrn_op = WN_kid0(cond);
05091
05092 if (WN_operator(intrn_op) != OPR_INTRINSIC_OP ||
05093 WN_intrinsic(intrn_op) != INTRN_EXPECT)
05094 return -1.0;
05095
05096 WN * constval = WN_kid1(cond);
05097
05098 if (WN_operator(constval) != OPR_INTCONST)
05099 return -1.0;
05100
05101
05102 WN * expected_value = WN_kid0(WN_kid1(intrn_op));
05103 Is_True (WN_operator(expected_value) == OPR_INTCONST,
05104 ("get_branch_confidence: 2nd operand of __builtin_expect must "
05105 "be constant -- front-end should ensure this"));
05106
05107 INT confidence = WN_const_val(expected_value) == WN_const_val(constval);
05108 if (WN_operator(cond) == OPR_NE)
05109 confidence = !confidence;
05110 if (WN_operator(branch_wn) == OPR_FALSEBR)
05111 confidence = !confidence;
05112
05113
05114 if (confidence) return 0.90;
05115 else return 0.10;
05116 }
05117
05118 #endif
05119
05120
05121 static void Build_CFG(void)
05122 {
05123 BB *bb;
05124 WN *branch_wn, *wn;
05125 INT i, num;
05126 RID *rid;
05127 OP *br_op;
05128 TN *target_tn;
05129 LABEL_IDX label;
05130
05131
05132
05133 while (Exit_BB_Head) {
05134 Exit_BB_Head = BB_LIST_Delete(BB_LIST_first(Exit_BB_Head), Exit_BB_Head);
05135 }
05136
05137 for (bb = REGION_First_BB; bb != NULL; bb = BB_next(bb)) {
05138
05139 if (BB_exit(bb)) {
05140 Exit_BB_Head = BB_LIST_Push (bb, Exit_BB_Head, &MEM_pu_pool);
05141 }
05142
05143 rid = BB_rid(bb);
05144 if ( rid && RID_level(rid) >= RL_CGSCHED ) {
05145
05146
05147
05148 if ( BB_REGION_Exit( bb, rid ) != NO_REGION_EXIT && !BB_exit( bb ) ) {
05149 br_op = BB_branch_op( bb );
05150 if ( br_op == NULL ) {
05151 if ( BB_next( bb ) && !BB_exit( bb ) )
05152
05153
05154 Link_Pred_Succ ( bb, BB_next( bb ) );
05155 } else {
05156 if ( OP_cond( br_op ) ) {
05157 if ( BB_next( bb ) )
05158 Link_Pred_Succ ( bb, BB_next( bb ) );
05159 }
05160
05161
05162 target_tn = OP_opnd(br_op, OP_find_opnd_use(br_op, OU_target));
05163 FmtAssert( TN_is_label( target_tn ),
05164 ("target of branch is not a label") );
05165 label = TN_label( target_tn );
05166 if ( Get_Label_BB ( label ) != NULL )
05167 Link_BBs( bb, label );
05168 }
05169 }
05170 continue;
05171 }
05172
05173 if (BB_exit(bb)) {
05174
05175 continue;
05176 }
05177
05178 float confidence=-1.0;
05179 branch_wn = BB_branch_wn(bb);
05180 if (branch_wn != NULL) {
05181 switch (WN_opcode(branch_wn)) {
05182 case OPC_FALSEBR:
05183 case OPC_TRUEBR:
05184
05185
05186
05187
05188 {
05189 OP *br_op = BB_branch_op( bb );
05190 if ( br_op == NULL || OP_cond( br_op ) ) {
05191 if ( ! Has_External_Fallthru( bb ) ) {
05192 if ((confidence = get_branch_confidence( bb )) != -1.0) {
05193 if (BB_next(bb) != Get_Label_BB(Get_WN_Label(branch_wn)))
05194 confidence = 1 - confidence;
05195 Link_Pred_Succ_with_Prob(bb, BB_next(bb), confidence,
05196 FALSE, TRUE, TRUE);
05197 } else
05198 Link_Pred_Succ(bb, BB_next(bb));
05199 #ifdef TARG_X8664
05200
05201
05202 if( WN_kid0(branch_wn) == NULL ){
05203 BB_branch_wn(bb) = NULL;
05204 }
05205 #endif
05206 }
05207 #ifdef KEY
05208
05209
05210
05211
05212
05213 else if ( rid && CGRIN_exits ( RID_cginfo( rid ) ) )
05214 #else
05215 else if ( rid )
05216 #endif
05217 {
05218 label_is_external( &num, branch_wn, bb );
05219 CGRIN_exit_i( RID_cginfo( rid ), num) = bb;
05220 CGRIN_exit_label_i( RID_cginfo( rid ), num) = 0;
05221 }
05222
05223 if ( br_op == NULL ) break;
05224 }
05225 #ifdef TARG_SL2 //fork_joint
05226 else if( OP_fork(br_op) ) {
05227 if(BB_next(bb))
05228 Link_Pred_Succ ( bb, BB_next( bb ) );
05229 }
05230 #endif
05231
05232 }
05233
05234 case OPC_GOTO:
05235 case OPC_REGION_EXIT:
05236 if ( ! label_is_external( &num, branch_wn, bb ) ) {
05237 #ifdef KEY
05238 if ((WN_opcode(branch_wn) == OPC_TRUEBR ||
05239 WN_opcode(branch_wn) == OPC_FALSEBR) &&
05240 confidence != -1.0) {
05241 Link_Pred_Succ_with_Prob(bb,
05242 Get_Label_BB(Get_WN_Label(branch_wn)),
05243 1 - confidence, FALSE, TRUE, TRUE);
05244 } else
05245 #endif
05246 Link_BBs(bb, Get_WN_Label(branch_wn));
05247 } else if ( rid ) {
05248 WN *new_exit;
05249 LABEL_IDX new_label;
05250 CGRIN *cgrin = RID_Find_Cginfo(bb);
05251 Is_True(cgrin != NULL,("Build_CFG, null cginfo"));
05252 CGRIN_exit_i( cgrin, num ) = bb;
05253 label = Get_WN_Label( branch_wn );
05254 CGRIN_exit_label_i( cgrin, num ) = label;
05255 new_label = REGION_Exit_Whirl_Labels(
05256 CGRIN_exit_glue_i(cgrin, num), bb, label, rid);
05257
05258
05259 Is_True(new_label != (LABEL_IDX) 0,
05260 ("Build_CFG, new region exit label is NULL"));
05261 new_exit = WN_CreateRegionExit(new_label);
05262 WN_INSERT_BlockLast(CGRIN_nested_exit(cgrin),new_exit);
05263 }
05264 break;
05265 #ifdef TARG_SL //fork_joint
05266 case OPC_SL2_FORK_MAJOR:
05267 case OPC_SL2_FORK_MINOR:
05268 if(BB_next(bb))
05269 Link_Pred_Succ ( bb, BB_next( bb ) );
05270 if ( ! label_is_external( &num, branch_wn, bb ) ) {
05271 Link_BBs(bb, Get_WN_Label(branch_wn));
05272 } else if ( rid ) {
05273 WN *new_exit;
05274 LABEL_IDX new_label;
05275 CGRIN *cgrin = RID_Find_Cginfo(bb);
05276 Is_True(cgrin != NULL,("Build_CFG, null cginfo"));
05277 CGRIN_exit_i( cgrin, num ) = bb;
05278 label = Get_WN_Label( branch_wn );
05279 CGRIN_exit_label_i( cgrin, num ) = label;
05280 new_label = REGION_Exit_Whirl_Labels(
05281 CGRIN_exit_glue_i(cgrin, num), bb, label, rid);
05282
05283
05284 Is_True(new_label != (LABEL_IDX) 0,
05285 ("Build_CFG, new region exit label is NULL"));
05286 new_exit = WN_CreateRegionExit(new_label);
05287 WN_INSERT_BlockLast(CGRIN_nested_exit(cgrin),new_exit);
05288 }
05289 break;
05290 #endif
05291 case OPC_COMPGOTO:
05292 if (WN_kid_count(branch_wn) == 3) {
05293 Link_BBs (bb, Get_WN_Label(WN_kid(branch_wn,2)));
05294 }
05295 case OPC_XGOTO:
05296 wn = WN_first(WN_kid1(branch_wn));
05297 for (i = 0; i < WN_num_entries(branch_wn); i++) {
05298 if ( ! label_is_external( &num, wn, bb ) ) {
05299 Link_BBs (bb, Get_WN_Label(wn));
05300 } else if ( rid ) {
05301 CGRIN_exit_i( RID_cginfo( rid ), num ) = bb;
05302 label = Get_WN_Label( wn );
05303 CGRIN_exit_label_i( RID_cginfo( rid ), num ) = label;
05304 REGION_Exit_Whirl_Labels(
05305 CGRIN_exit_glue_i(RID_cginfo(rid), num), bb, label, rid);
05306 }
05307 wn = WN_next(wn);
05308 }
05309 if (WN_kid_count(branch_wn) == 3) {
05310 if ( ! label_is_external( &num, WN_kid( branch_wn, 2 ), bb ) )
05311
05312 Link_BBs (bb, Get_WN_Label(WN_kid(branch_wn,2)));
05313 else if ( rid ) {
05314 CGRIN_exit_i( RID_cginfo( rid ), num ) = bb;
05315 label = Get_WN_Label( WN_kid( branch_wn, 2 ) );
05316 CGRIN_exit_label_i( RID_cginfo( rid ), num ) = label;
05317 REGION_Exit_Whirl_Labels(
05318 CGRIN_exit_glue_i(RID_cginfo(rid), num), bb, label, rid);
05319 }
05320 }
05321 break;
05322 case OPC_AGOTO:
05323 {
05324 BB *targ;
05325 for (targ = REGION_First_BB; targ != NULL; targ = BB_next(targ)) {
05326 if (BB_Has_Addr_Taken_Label(targ)) Link_Pred_Succ(bb, targ);
05327 }
05328 }
05329 }
05330 }
05331 else if (BB_next(bb) != NULL) {
05332 if (BB_rid(BB_next(bb)) != BB_rid(bb)
05333 && BB_rid(BB_next(bb)) != NULL
05334 && CGRIN_entry(RID_cginfo(BB_rid(BB_next(bb)))) != BB_next(bb)) {
05335 BB *region_entry = CGRIN_entry(RID_cginfo(BB_rid(BB_next(bb))));
05336 ANNOTATION *ant = ANNOT_Get (BB_annotations(region_entry), ANNOT_LABEL);
05337 OPS ops;
05338 OPS_Init(&ops);
05339 DevWarn("first bb in region %d is not the entry bb",
05340 RID_id(BB_rid(BB_next(bb))));
05341 if (ant != NULL) {
05342 label = ANNOT_label(ant);
05343 } else {
05344 label = Gen_Temp_Label();
05345 BB_Add_Annotation (region_entry, ANNOT_LABEL, (void *)label);
05346 Set_Label_BB (label,region_entry);
05347 }
05348 target_tn = Gen_Label_TN (label, 0);
05349 Exp_OP1 (OPC_GOTO, NULL, target_tn, &ops);
05350 BB_Append_Ops(bb, &ops);
05351 Link_Pred_Succ (bb, region_entry);
05352 }
05353 else if (BB_call(bb)
05354 && WN_Call_Never_Return( CALLINFO_call_wn(ANNOT_callinfo(
05355 ANNOT_Get (BB_annotations(bb), ANNOT_CALLINFO) ))) )
05356 {
05357 continue;
05358 }
05359 else {
05360 Link_Pred_Succ (bb, BB_next(bb));
05361 }
05362 }
05363 }
05364 }
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374 static VARIANT
05375 WHIRL_Compare_To_OP_variant (OPCODE opcode, BOOL invert)
05376 {
05377 VARIANT variant = V_BR_NONE;
05378 switch (opcode) {
05379
05380
05381 case OPC_U4I8EQ:
05382 case OPC_BI8EQ: case OPC_I4I8EQ: variant = V_BR_I8EQ; break;
05383 #ifdef KEY
05384 case OPC_I8I4EQ: case OPC_U8I4EQ:
05385 case OPC_U4I4EQ:
05386 #endif
05387 case OPC_BI4EQ: case OPC_I4I4EQ: variant = V_BR_I4EQ; break;
05388 #ifdef KEY
05389 case OPC_U8U8EQ:
05390 case OPC_U4U8EQ:
05391 #endif
05392 case OPC_BU8EQ: case OPC_I4U8EQ: variant = V_BR_U8EQ; break;
05393 case OPC_U4U4EQ:
05394 case OPC_BU4EQ: case OPC_I4U4EQ: variant = V_BR_U4EQ; break;
05395 case OPC_U4FQEQ:
05396 case OPC_BFQEQ: case OPC_I4FQEQ: variant = V_BR_QEQ; break;
05397 #ifdef TARG_IA64
05398 case OPC_BF10EQ: case OPC_I4F10EQ: variant = V_BR_XEQ; break;
05399 #endif
05400 case OPC_U4F8EQ:
05401 case OPC_BF8EQ: case OPC_I4F8EQ: variant = V_BR_DEQ; break;
05402 case OPC_U4F4EQ:
05403 case OPC_BF4EQ: case OPC_I4F4EQ: variant = V_BR_FEQ; break;
05404
05405 case OPC_U4I8NE:
05406 case OPC_BI8NE: case OPC_I4I8NE: variant = V_BR_I8NE; break;
05407 #ifdef KEY
05408 case OPC_I8I4NE: case OPC_U8I4NE:
05409 case OPC_U4I4NE:
05410 #endif
05411 case OPC_BI4NE: case OPC_I4I4NE: variant = V_BR_I4NE; break;
05412 #ifdef KEY
05413 case OPC_U8U8NE:
05414 case OPC_U4U8NE:
05415 #endif
05416 case OPC_BU8NE: case OPC_I4U8NE: variant = V_BR_U8NE; break;
05417 #ifdef KEY
05418 case OPC_U8U4NE:
05419 case OPC_U4U4NE:
05420 #endif
05421 case OPC_BU4NE: case OPC_I4U4NE: variant = V_BR_U4NE; break;
05422 case OPC_U4FQNE:
05423 case OPC_BFQNE: case OPC_I4FQNE: variant = V_BR_QNE; break;
05424 #ifdef TARG_IA64
05425 case OPC_BF10NE: case OPC_I4F10NE: variant = V_BR_XNE; break;
05426 #endif
05427 case OPC_U4F8NE:
05428 case OPC_BF8NE: case OPC_I4F8NE: variant = V_BR_DNE; break;
05429 case OPC_U4F4NE:
05430 case OPC_BF4NE: case OPC_I4F4NE: variant = V_BR_FNE; break;
05431
05432 case OPC_U4I8GT:
05433 case OPC_BI8GT: case OPC_I4I8GT: variant = V_BR_I8GT; break;
05434 #ifdef KEY
05435 case OPC_I8I4GT: case OPC_U8I4GT:
05436 case OPC_U4I4GT:
05437 #endif
05438 case OPC_BI4GT: case OPC_I4I4GT: variant = V_BR_I4GT; break;
05439 #ifdef KEY
05440 case OPC_U8U8GT:
05441 case OPC_U4U8GT:
05442 #endif
05443 case OPC_BU8GT: case OPC_I4U8GT: variant = V_BR_U8GT; break;
05444 #ifdef KEY
05445 case OPC_U8U4GT:
05446 case OPC_U4U4GT:
05447 #endif
05448 case OPC_BU4GT: case OPC_I4U4GT: variant = V_BR_U4GT; break;
05449 case OPC_U4FQGT:
05450 case OPC_BFQGT: case OPC_I4FQGT: variant = V_BR_QGT; break;
05451 #ifdef TARG_IA64
05452 case OPC_BF10GT: case OPC_I4F10GT: variant = V_BR_XGT; break;
05453 #endif
05454 case OPC_U4F8GT:
05455 case OPC_BF8GT: case OPC_I4F8GT: variant = V_BR_DGT; break;
05456 case OPC_U4F4GT:
05457 case OPC_BF4GT: case OPC_I4F4GT: variant = V_BR_FGT; break;
05458
05459
05460 case OPC_U4I8GE:
05461 case OPC_BI8GE: case OPC_I4I8GE: variant = V_BR_I8GE; break;
05462 #ifdef KEY
05463 case OPC_I8I4GE: case OPC_U8I4GE:
05464 case OPC_U4I4GE:
05465 #endif
05466 case OPC_BI4GE: case OPC_I4I4GE: variant = V_BR_I4GE; break;
05467 #ifdef KEY
05468 case OPC_U8U8GE:
05469 case OPC_U4U8GE:
05470 #endif
05471 case OPC_BU8GE: case OPC_I4U8GE: variant = V_BR_U8GE; break;
05472 #ifdef KEY
05473 case OPC_U8U4GE:
05474 case OPC_U4U4GE:
05475 #endif
05476 case OPC_BU4GE: case OPC_I4U4GE: variant = V_BR_U4GE; break;
05477 case OPC_U4FQGE:
05478 case OPC_BFQGE: case OPC_I4FQGE: variant = V_BR_QGE; break;
05479 #ifdef TARG_IA64
05480 case OPC_BF10GE: case OPC_I4F10GE: variant = V_BR_XGE; break;
05481 #endif
05482 case OPC_U4F8GE:
05483 case OPC_BF8GE: case OPC_I4F8GE: variant = V_BR_DGE; break;
05484 case OPC_U4F4GE:
05485 case OPC_BF4GE: case OPC_I4F4GE: variant = V_BR_FGE; break;
05486
05487
05488 case OPC_U4I8LT:
05489 case OPC_BI8LT: case OPC_I4I8LT: variant = V_BR_I8LT; break;
05490 #ifdef KEY
05491 case OPC_I8I4LT: case OPC_U8I4LT:
05492 case OPC_U4I4LT:
05493 #endif
05494 case OPC_BI4LT: case OPC_I4I4LT: variant = V_BR_I4LT; break;
05495 #ifdef KEY
05496 case OPC_U8U8LT:
05497 case OPC_U4U8LT:
05498 #endif
05499 case OPC_BU8LT: case OPC_I4U8LT: variant = V_BR_U8LT; break;
05500 #ifdef KEY
05501 case OPC_U8U4LT:
05502 case OPC_U4U4LT:
05503 #endif
05504 case OPC_BU4LT: case OPC_I4U4LT: variant = V_BR_U4LT; break;
05505 case OPC_U4FQLT:
05506 case OPC_BFQLT: case OPC_I4FQLT: variant = V_BR_QLT; break;
05507 case OPC_U4F8LT:
05508 #ifdef TARG_IA64
05509 case OPC_BF10LT: case OPC_I4F10LT: variant = V_BR_XLT; break;
05510 #endif
05511 case OPC_BF8LT: case OPC_I4F8LT: variant = V_BR_DLT; break;
05512 case OPC_U4F4LT:
05513 case OPC_BF4LT: case OPC_I4F4LT: variant = V_BR_FLT; break;
05514
05515
05516 case OPC_U4I8LE:
05517 case OPC_BI8LE: case OPC_I4I8LE: variant = V_BR_I8LE; break;
05518 #ifdef KEY
05519 case OPC_I8I4LE: case OPC_U8I4LE:
05520 case OPC_U4I4LE:
05521 #endif
05522 case OPC_BI4LE: case OPC_I4I4LE: variant = V_BR_I4LE; break;
05523 #ifdef KEY
05524 case OPC_U8U8LE:
05525 case OPC_U4U8LE:
05526 #endif
05527 case OPC_BU8LE: case OPC_I4U8LE: variant = V_BR_U8LE; break;
05528 #ifdef KEY
05529 case OPC_U8U4LE:
05530 case OPC_U4U4LE:
05531 #endif
05532 case OPC_BU4LE: case OPC_I4U4LE: variant = V_BR_U4LE; break;
05533 case OPC_U4FQLE:
05534 case OPC_BFQLE: case OPC_I4FQLE: variant = V_BR_QLE; break;
05535 #ifdef TARG_IA64
05536 case OPC_BF10LE: case OPC_I4F10LE: variant = V_BR_XLE; break;
05537 #endif
05538 case OPC_U4F8LE:
05539 case OPC_BF8LE: case OPC_I4F8LE: variant = V_BR_DLE; break;
05540 case OPC_U4F4LE:
05541 case OPC_BF4LE: case OPC_I4F4LE: variant = V_BR_FLE; break;
05542
05543 case OPC_BBNE: variant = V_BR_PNE; break;
05544 case OPC_BBEQ: variant = V_BR_PEQ; break;
05545
05546 }
05547 if (invert) variant = Negate_BR_Variant(variant);
05548 #ifdef Is_True_On
05549 if (variant == V_BR_NONE && OPERATOR_is_compare(OPCODE_operator(opcode)))
05550 DevWarn ("KEY: Unknown branch variant found for %s!", OPCODE_name(opcode));
05551 #endif
05552 return variant;
05553 }
05554
05555
05556 static void
05557 Handle_CONDBR (WN *branch)
05558 {
05559 WN *condition;
05560 VARIANT variant;
05561 TN *operand0, *operand1;
05562 TN *target_tn;
05563 BOOL invert;
05564
05565 condition = WN_kid0 (branch);
05566 invert = (WN_opcode(branch) == OPC_FALSEBR);
05567 #ifdef TARG_NVISA
05568 if (WN_rtype(condition) == MTYPE_B
05569 && WN_operator_is(condition, OPR_LNOT))
05570 {
05571
05572 invert = !invert;
05573 condition = WN_kid0(condition);
05574 }
05575 #endif
05576 variant = WHIRL_Compare_To_OP_variant (WN_opcode(condition), invert);
05577 if (variant != V_BR_NONE) {
05578 operand0 = Expand_Expr (WN_kid0(condition), condition, NULL);
05579 operand1 = Expand_Expr (WN_kid1(condition), condition, NULL);
05580 }
05581 else if (WN_operator_is(condition, OPR_INTCONST)) {
05582 BOOL cond_is_true = WN_const_val(condition) != 0;
05583 variant = (cond_is_true ^ invert) ? V_BR_ALWAYS : V_BR_NEVER;
05584 operand0 = NULL;
05585 operand1 = NULL;
05586 }
05587 else {
05588
05589 #ifdef TARG_IA64
05590
05591
05592
05593
05594
05595
05596 operand0 = NULL;
05597 if (Is_Old_Boolean_Expression(condition)) {
05598 operand0 = Handle_Bool_As_Predicate(condition, branch, invert);
05599 operand1 = NULL;
05600 variant = V_BR_P_TRUE;
05601 }
05602
05603 if (operand0==NULL) {
05604 operand0 = Expand_Expr (condition, branch, NULL);
05605 if (WN_rtype(condition) == MTYPE_B) {
05606 Is_True( WN_operator_is(condition, OPR_LDID)
05607 && WN_class(condition) == CLASS_PREG,
05608 ("MTYPE_B TRUEBR/FALSEBR condition must be preg or relop"));
05609 operand1 = NULL;
05610 variant = V_BR_P_TRUE;
05611 if (invert) {
05612 PREG_NUM preg2_num = WN_load_offset(condition) + 1;
05613 operand0 = PREG_To_TN_Array[preg2_num];
05614 }
05615 } else {
05616 operand1 = Zero_TN;
05617 variant = (invert) ? V_BR_I8EQ : V_BR_I8NE;
05618 }
05619 }
05620 }
05621 #else // TARG_IA64
05622 operand0 = Expand_Expr (condition, branch, NULL);
05623 if (WN_rtype(condition) == MTYPE_B) {
05624 Is_True( WN_operator_is(condition, OPR_LDID)
05625 && WN_class(condition) == CLASS_PREG,
05626 ("MTYPE_B TRUEBR/FALSEBR condition must be preg or relop"));
05627 operand1 = NULL;
05628 variant = V_BR_P_TRUE;
05629 if (invert) {
05630 #ifdef TARG_NVISA
05631
05632 Set_V_false_br(variant);
05633 #else
05634 PREG_NUM preg2_num = WN_load_offset(condition) + 1;
05635 operand0 = PREG_To_TN_Array[preg2_num];
05636 #endif
05637 }
05638 } else {
05639 #if !defined(TARG_IA32) && !defined(TARG_X8664) && !defined(TARG_NVISA)
05640 operand1 = Zero_TN;
05641 variant = (invert) ? V_BR_I8EQ : V_BR_I8NE;
05642 #else
05643 if (TN_size(operand0) == 8
05644 #ifdef TARG_NVISA
05645 || MTYPE_is_size_double(WN_rtype(condition)))
05646 #else
05647
05648 || OP_NEED_PAIR(OPCODE_rtype(WN_opcode(condition))))
05649 #endif
05650 {
05651 operand1 = Gen_Literal_TN (0, 8);
05652 variant = (invert) ? V_BR_I8EQ : V_BR_I8NE;
05653 } else if (TN_size(operand0) == 1 ||
05654 TN_size(operand0) == 4) {
05655 operand1 = Gen_Literal_TN (0, 4);
05656 variant = (invert) ? V_BR_I4EQ : V_BR_I4NE;
05657 } else {
05658 Is_True(FALSE, ("Handle_CONDBR: unexpected size"));
05659 }
05660 #endif
05661 }
05662 }
05663 #endif // TARG_IA64
05664 target_tn = Gen_Label_TN (Get_WN_Label (branch), 0);
05665 Exp_OP3v (WN_opcode(branch), NULL, target_tn, operand0, operand1,
05666 variant, &New_OPs);
05667 }
05668
05669
05670 static void
05671 Handle_XGOTO (WN *branch)
05672 {
05673 TN *target_tn;
05674 WN *wn;
05675 INT i;
05676 ST *st;
05677 INITO_IDX ino;
05678 INITV_IDX inv, prev_inv;
05679
05680 target_tn = Expand_Expr (WN_kid0(branch), NULL, NULL);
05681 Exp_Indirect_Branch (target_tn, &New_OPs);
05682
05683
05684
05685 st = WN_st(branch);
05686 BB_Add_Annotation (Cur_BB, ANNOT_SWITCH, st);
05687
05688 Allocate_Object(st);
05689 ino = New_INITO(st);
05690 prev_inv = INITV_IDX_ZERO;
05691
05692 wn = WN_first(WN_kid1(branch));
05693 for (i = 0; i < WN_num_entries(branch); i++) {
05694 FmtAssert ((wn && WN_opcode(wn) == OPC_GOTO),
05695 ("XGOTO block doesn't have goto's? (%d)", WN_opcode(wn)));
05696 LABEL_IDX lab = WN_label_number(wn);
05697 inv = New_INITV();
05698 INITV_Init_Label (inv, lab);
05699 prev_inv = Append_INITV (inv, ino, prev_inv);
05700 wn = WN_next(wn);
05701 }
05702 }
05703
05704
05705
05706
05707
05708 static void
05709 Convert_Branch (WN *branch)
05710 {
05711 OPCODE opcode;
05712 TN *target_tn;
05713
05714 opcode = WN_opcode (branch);
05715 switch (opcode) {
05716 case OPC_GOTO:
05717 case OPC_REGION_EXIT:
05718 #ifdef KEY
05719 case OPC_GOTO_OUTER_BLOCK:
05720 #endif
05721 target_tn = Gen_Label_TN (Get_WN_Label (branch), 0);
05722 Exp_OP1 (OPC_GOTO, NULL, target_tn, &New_OPs);
05723 break;
05724
05725 #ifdef TARG_SL //fork_joint
05726 case OPC_SL2_FORK_MAJOR:
05727 case OPC_SL2_FORK_MINOR:
05728 target_tn = Gen_Label_TN (Get_WN_Label (branch), 0);
05729 Exp_OP1 (opcode, NULL, target_tn, &New_OPs);
05730 break;
05731 #endif
05732
05733 case OPC_FALSEBR:
05734 case OPC_TRUEBR:
05735 Handle_CONDBR (branch);
05736 break;
05737 case OPC_XGOTO:
05738 #ifdef TARG_SL //fork_joint
05739 if(WN_is_compgoto_para(branch) || WN_is_compgoto_for_minor(branch)) {
05740 opcode = WN_is_compgoto_para(branch) ? OPC_SL2_FORK_MAJOR : OPC_SL2_FORK_MINOR;
05741
05742 WN* fork_branch = WN_CreateFork(WN_label_number(WN_last(WN_kid1(branch))), WN_is_compgoto_para(branch));
05743
05744 WN_CopyMap(fork_branch, WN_MAP_FEEDBACK, branch);
05745 branch=fork_branch;
05746
05747 target_tn = Gen_Label_TN (Get_WN_Label (branch), 0);
05748 Exp_OP1 ( opcode, NULL, target_tn, &New_OPs);
05749
05750 }
05751 else
05752 #endif
05753 Handle_XGOTO (branch);
05754 break;
05755 case OPC_AGOTO:
05756 target_tn = Expand_Expr (WN_kid0(branch), NULL, NULL);
05757 Exp_Indirect_Branch (target_tn, &New_OPs);
05758 break;
05759 default:
05760 #pragma mips_frequency_hint NEVER
05761 FmtAssert (FALSE,
05762 ("Convert_Branch: unexpected opcode %s", OPCODE_name(opcode)));
05763
05764 }
05765 BB_branch_wn(Cur_BB) = branch;
05766
05767 Start_New_Basic_Block ();
05768 }
05769
05770
05771
05772 static void Handle_Entry (WN *entry)
05773 {
05774 ST *entry_st;
05775 BB *entry_bb;
05776 ENTRYINFO *ent;
05777
05778 if (WN_Label_Is_Handler_Begin(entry)) {
05779
05780
05781 TY_IDX ty = Make_Function_Type( MTYPE_To_TY(MTYPE_V));
05782 PU_IDX pu_idx;
05783 PU& pu = New_PU (pu_idx);
05784 PU_Init (pu, ty, CURRENT_SYMTAB);
05785 entry_st = New_ST (GLOBAL_SYMTAB);
05786 #ifdef KEY
05787 char *name = (char *) alloca (strlen("Handler")+1+8+1);
05788 sprintf (name, "Handler.%d", Current_PU_Count());
05789 ST_Init (entry_st, Save_Str2i (name, ".", Get_WN_Label(entry)),
05790 CLASS_FUNC, SCLASS_TEXT, EXPORT_LOCAL, (TY_IDX) pu_idx);
05791 #ifndef TARG_IA64
05792 PU_Has_Exc_Handler = TRUE;
05793 #endif
05794 #else
05795 ST_Init (entry_st, Save_Str2i ("Handler", ".", Get_WN_Label(entry)),
05796 CLASS_FUNC, SCLASS_TEXT, EXPORT_LOCAL, (TY_IDX) pu_idx);
05797 #endif // KEY
05798 Allocate_Object(entry_st);
05799 }
05800 else {
05801 entry_st = WN_st(entry);
05802 if (Read_Global_Data && ST_sclass(entry_st) == SCLASS_EXTERN) {
05803
05804
05805 Set_ST_sclass(entry_st, SCLASS_TEXT);
05806 Allocate_Object(entry_st);
05807 }
05808 }
05809
05810
05811 entry_bb = Start_New_Basic_Block ();
05812 Set_BB_entry (entry_bb);
05813 ent = TYPE_PU_ALLOC (ENTRYINFO);
05814 ENTRYINFO_name(ent) = entry_st;
05815 ENTRYINFO_entry_wn(ent) = entry;
05816 ENTRYINFO_srcpos(ent) = WN_Get_Linenum(entry);
05817 current_srcpos = ENTRYINFO_srcpos(ent);
05818 BB_Add_Annotation (entry_bb, ANNOT_ENTRYINFO, ent);
05819 Entry_BB_Head = BB_LIST_Push (entry_bb, Entry_BB_Head, &MEM_pu_pool);
05820 }
05821
05822 static void Handle_Return (void)
05823 {
05824 EXITINFO *exit_info;
05825 BB *exit_bb;
05826
05827 exit_bb = Cur_BB;
05828 Set_BB_exit(exit_bb);
05829 exit_info = TYPE_PU_ALLOC (EXITINFO);
05830 EXITINFO_srcpos(exit_info) = current_srcpos;
05831 BB_Add_Annotation (exit_bb, ANNOT_EXITINFO, exit_info);
05832
05833 Start_New_Basic_Block ();
05834 }
05835
05836
05837
05838 static void Handle_Trap(WN *trap)
05839 {
05840 Exp_OP1(OPC_TRAP, NULL, Gen_Literal_TN(WN_offset(trap), 4), &New_OPs);
05841 }
05842
05843
05844
05845
05846
05847
05848 static WN*
05849 Find_Asm_Out_Parameter_Load (const WN* stmt, PREG_NUM preg_num, ST** ded_st)
05850 {
05851 WN* ret_load = NULL;
05852 for(; stmt != NULL; stmt = WN_next(stmt)) {
05853 #ifdef KEY // bug 5733: need to stop searching at the next ASM statement
05854 if (WN_operator(stmt) == OPR_ASM_STMT)
05855 return NULL;
05856 #endif
05857 if (OPERATOR_is_store(WN_operator(stmt))) {
05858 WN* load = WN_kid0(stmt);
05859 OPERATOR opr = WN_operator(load);
05860 if (opr == OPR_CVT || opr == OPR_CVTL) {
05861 load = WN_kid0(load);
05862 opr = WN_operator(load);
05863 }
05864 if (OPERATOR_is_load(opr) || opr == OPR_LDA) {
05865 if (WN_has_sym(load) &&
05866 WN_class(load) == CLASS_PREG &&
05867 WN_offset(load) == preg_num) {
05868 ret_load = load;
05869 break;
05870 }
05871 }
05872 }
05873 }
05874 if (ret_load) {
05875 if (OPERATOR_has_sym(WN_operator(stmt)) &&
05876 ST_assigned_to_dedicated_preg(WN_st(stmt))) {
05877 *ded_st = WN_st(stmt);
05878 }
05879 }
05880 else {
05881 DevWarn("didn't find out store for asm preg %d", preg_num);
05882 }
05883 return ret_load;
05884 }
05885
05886 #ifdef KEY
05887 TYPE_ID
05888 Find_Preg_Type ( ST_IDX st_idx )
05889 {
05890 char *str = &Str_Table[ ST_name_idx (St_Table[st_idx]) ];
05891 if (strcmp(str, ".preg_U1") == 0 || strcmp(str, ".preg_I1") == 0)
05892 return MTYPE_I1;
05893 if (strcmp(str, ".preg_U2") == 0 || strcmp(str, ".preg_I2") == 0)
05894 return MTYPE_I2;
05895 if (strcmp(str, ".preg_U4") == 0 || strcmp(str, ".preg_I4") == 0)
05896 return MTYPE_I4;
05897 if (strcmp(str, ".preg_U8") == 0 || strcmp(str, ".preg_I8") == 0)
05898 return MTYPE_I8;
05899 return MTYPE_I4;
05900 }
05901 #endif
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914 static void
05915 Handle_ASM (const WN* asm_wn)
05916 {
05917
05918
05919 enum { MAX_OPNDS = ASM_OP_size, MAX_RESULTS = ASM_OP_size };
05920
05921
05922 TN* result[MAX_RESULTS];
05923 TN* opnd[MAX_OPNDS];
05924 INT num_results = 0;
05925 INT num_opnds = 0;
05926
05927 ISA_REGISTER_SUBCLASS opnd_sc[OP_MAX_FIXED_OPNDS];
05928 BZERO(opnd_sc, sizeof(opnd_sc));
05929
05930 CGTARG_Init_Asm_Constraints();
05931
05932 ASM_OP_ANNOT* asm_info = TYPE_PU_ALLOC(ASM_OP_ANNOT);
05933 BZERO(asm_info, sizeof(ASM_OP_ANNOT));
05934
05935 ASM_OP_wn(asm_info) = asm_wn;
05936
05937 #ifdef TARG_IA32
05938 #if 0
05939
05940
05941
05942
05943
05944
05945 if (WN_Asm_Clobbers_Cc(asm_wn)) {
05946 ASM_OP_clobber_set(asm_info)[ISA_REGISTER_CLASS_eflags] =
05947 REGISTER_SET_Union1(REGISTER_SET_EMPTY_SET, REGISTER_MIN);
05948 }
05949 #endif
05950 #endif
05951
05952
05953 for (const WN* clobber_pragma = WN_first(WN_asm_clobbers(asm_wn));
05954 clobber_pragma != NULL;
05955 clobber_pragma = WN_next(clobber_pragma)) {
05956 Is_True(WN_pragma(clobber_pragma) == WN_PRAGMA_ASM_CLOBBER,
05957 ("Wrong pragma type for ASM clobber"));
05958 if (WN_operator(clobber_pragma) == OPR_XPRAGMA) {
05959 WN* idname = WN_kid0(clobber_pragma);
05960 Is_True(WN_operator(idname) == OPR_IDNAME,
05961 ("Wrong kid operator for ASM clobber PREG"));
05962 #if !defined(TARG_NVISA)
05963
05964
05965 {
05966 PREG_NUM preg = WN_offset (idname);
05967 ISA_REGISTER_CLASS rclass;
05968 REGISTER reg;
05969 CGTARG_Preg_Register_And_Class(preg, &rclass, ®);
05970 if (ABI_PROPERTY_Is_callee(rclass, preg-REGISTER_MIN))
05971 {
05972 SAVE_REG_LOC sr;
05973 extern STACK<SAVE_REG_LOC> Saved_Callee_Saved_Regs;
05974 sr.ded_tn = Build_Dedicated_TN(rclass, reg, 0);
05975 DevAssert(sr.ded_tn,
05976 ("Missing dedicated TN for callee-saved register %s",
05977 REGISTER_name(rclass, reg)));
05978 if (Is_Unique_Callee_Saved_Reg (sr.ded_tn))
05979 {
05980 #ifdef TARG_X8664
05981 if (CG_push_pop_int_saved_regs && ! Gen_Frame_Pointer &&
05982 rclass == ISA_REGISTER_CLASS_integer)
05983 sr.temp = NULL;
05984 else
05985 #endif
05986 sr.temp = CGSPILL_Get_TN_Spill_Location (sr.ded_tn, CGSPILL_LCL);
05987 sr.user_allocated = TRUE;
05988 Saved_Callee_Saved_Regs.Push(sr);
05989 }
05990 }
05991 }
05992 #endif // KEY
05993 TN* tn = PREG_To_TN(WN_st(idname), WN_offset(idname));
05994 FmtAssert(tn && TN_is_register(tn) && TN_is_dedicated(tn),
05995 ("Wrong TN for PREG from ASM clobber list"));
05996 ISA_REGISTER_CLASS rc = TN_register_class(tn);
05997 ASM_OP_clobber_set(asm_info)[rc] =
05998 REGISTER_SET_Union1(ASM_OP_clobber_set(asm_info)[rc], TN_register(tn));
05999 }
06000 }
06001
06002
06003
06004
06005 WN* asm_output_constraints = WN_asm_constraints(asm_wn);
06006 FmtAssert(WN_operator(asm_output_constraints) == OPR_BLOCK,
06007 ("asm output constraints not a block?"));
06008
06009 for (WN* out_pragma = WN_first(asm_output_constraints);
06010 out_pragma != NULL;
06011 out_pragma = WN_next(out_pragma)) {
06012
06013 FmtAssert(num_results < MAX_RESULTS,
06014 ("too many asm results in Handle_ASM"));
06015
06016 FmtAssert(WN_pragma(out_pragma) == WN_PRAGMA_ASM_CONSTRAINT,
06017 ("not an asm_constraint pragma"));
06018
06019 const char* constraint = WN_pragma_asm_constraint(out_pragma);
06020 PREG_NUM preg = WN_pragma_asm_copyout_preg(out_pragma);
06021 ST* pref_st = NULL;
06022 WN* load = Find_Asm_Out_Parameter_Load(WN_next(asm_wn), preg, &pref_st);
06023 #ifdef KEY
06024 TYPE_ID default_type = Find_Preg_Type(WN_st_idx(out_pragma));
06025 #endif
06026 TN* pref_tn = NULL;
06027 if (pref_st) {
06028 pref_tn = PREG_To_TN(MTYPE_To_PREG(ST_mtype(pref_st)),
06029 Find_PREG_For_Symbol(pref_st));
06030 }
06031 ISA_REGISTER_SUBCLASS subclass = ISA_REGISTER_SUBCLASS_UNDEFINED;
06032
06033 #if defined(TARG_IA64)
06034 TN* tn = CGTARG_TN_For_Asm_Operand(constraint, load, pref_tn, &subclass);
06035 #else
06036 TN* tn = CGTARG_TN_For_Asm_Operand(constraint, load, pref_tn, &subclass,
06037 default_type);
06038 #endif
06039
06040 ASM_OP_result_constraint(asm_info)[num_results] = constraint;
06041 ASM_OP_result_subclass(asm_info)[num_results] = subclass;
06042 ASM_OP_result_position(asm_info)[num_results] =
06043 WN_pragma_asm_opnd_num(out_pragma);
06044 ASM_OP_result_clobber(asm_info)[num_results] =
06045 (strchr(constraint, '&') != NULL);
06046 ASM_OP_result_memory(asm_info)[num_results] =
06047 #ifdef TARG_X8664
06048 (strchr(constraint, 'm') != NULL || strchr(constraint, 'g') != NULL);
06049 #elif defined(TARG_MIPS)
06050 (strchr(constraint, 'm') != NULL || strchr(constraint, 'R') != NULL);
06051 #else
06052 (strchr(constraint, 'm') != NULL);
06053 #endif
06054
06055 result[num_results] = tn;
06056 num_results++;
06057
06058
06059
06060
06061 if (load) {
06062 PREG_NUM new_preg = TN_To_PREG(tn);
06063 if (new_preg == 0) {
06064 char preg_name[16];
06065 sprintf(preg_name,"_asm_result_%d",WN_pragma_asm_opnd_num(out_pragma));
06066 new_preg = Create_Preg (TY_mtype(ST_type(WN_st(load))), preg_name);
06067 Realloc_Preg_To_TN_Arrays (new_preg);
06068 TN_MAP_Set(TN_To_PREG_Map, tn, (void*)new_preg);
06069 PREG_To_TN_Array[new_preg] = tn;
06070 PREG_To_TN_Mtype[new_preg] = TY_mtype(ST_type(WN_st(load)));
06071 }
06072 WN_offset(load) = new_preg;
06073 }
06074
06075 }
06076
06077
06078 for (INT kid = 2; kid < WN_kid_count(asm_wn); ++kid) {
06079 FmtAssert(num_opnds < MAX_OPNDS,
06080 ("too may asm operands in Handle_ASM"));
06081
06082 WN* asm_input = WN_kid(asm_wn, kid);
06083 FmtAssert(WN_operator(asm_input) == OPR_ASM_INPUT,
06084 ("asm kid not an asm_input?"));
06085
06086 const char* constraint = WN_asm_input_constraint(asm_input);
06087 WN* load = WN_kid0(asm_input);
06088 TN* pref_tn = NULL;
06089 if (OPERATOR_has_sym(WN_operator(load))) {
06090 ST* pref_st = WN_st(load);
06091 if (ST_assigned_to_dedicated_preg(pref_st)) {
06092 pref_tn = PREG_To_TN(MTYPE_To_PREG(ST_mtype(pref_st)),
06093 Find_PREG_For_Symbol(pref_st));
06094 }
06095 }
06096 ISA_REGISTER_SUBCLASS subclass = ISA_REGISTER_SUBCLASS_UNDEFINED;
06097
06098 #if defined(TARG_IA64)
06099 TN* tn = CGTARG_TN_For_Asm_Operand(constraint, load, pref_tn, &subclass);
06100 #else
06101 TN* tn = CGTARG_TN_For_Asm_Operand(constraint, load, pref_tn, &subclass,
06102 MTYPE_I4);
06103 #endif
06104
06105 ASM_OP_opnd_constraint(asm_info)[num_opnds] = constraint;
06106 ASM_OP_opnd_subclass(asm_info)[num_opnds] = subclass;
06107 ASM_OP_opnd_position(asm_info)[num_opnds] = WN_asm_opnd_num(asm_input);
06108 ASM_OP_opnd_memory(asm_info)[num_opnds] =
06109 #ifdef TARG_X8664
06110 (strchr(constraint, 'm') != NULL || strchr(constraint, 'g') != NULL);
06111 #elif defined(TARG_MIPS)
06112 (strchr(constraint, 'm') != NULL || strchr(constraint, 'R') != NULL);
06113 #else
06114 (strchr(constraint, 'm') != NULL);
06115 #endif
06116
06117
06118
06119 if (TN_is_register(tn)) {
06120 #ifdef TARG_X8664
06121 if( ( TN_register_class(tn) == ISA_REGISTER_CLASS_x87 ) &&
06122 ( WN_rtype(load) != MTYPE_FQ ) ){
06123 const TYPE_ID rtype = WN_rtype(load);
06124 extern void Expand_Float_To_Float( TN*, TN*, TYPE_ID, TYPE_ID, OPS* );
06125 FmtAssert( MTYPE_is_float(rtype), ("NYI") );
06126 TN* tmp_tn = Gen_Typed_Register_TN( rtype, MTYPE_byte_size(rtype) );
06127
06128 Expand_Expr( load, NULL, tmp_tn );
06129 Expand_Float_To_Float( tn, tmp_tn, MTYPE_FQ, rtype, &New_OPs );
06130 } else
06131 #endif // TARG_X8664
06132 Expand_Expr (load, NULL, tn);
06133 }
06134
06135 #ifdef TARG_X8664
06136
06137
06138
06139
06140
06141
06142
06143 if (ASM_OP_opnd_memory(asm_info)[num_opnds] &&
06144 (!Gen_PIC_Shared ||
06145
06146
06147 (WN_operator(load) == OPR_LDA &&
06148 ST_is_export_local(WN_st(load))))) {
06149 TN* new_opnd_tn =
06150 CGTARG_Process_Asm_m_constraint( load,
06151 &ASM_OP_opnd_offset(asm_info)[num_opnds],
06152 &New_OPs );
06153 if( new_opnd_tn != NULL )
06154 tn = new_opnd_tn;
06155 }
06156 #endif // TARG_X8664
06157
06158 opnd[num_opnds] = tn;
06159 num_opnds++;
06160 }
06161
06162
06163 OP* asm_op = Mk_VarOP(TOP_asm, num_results, num_opnds, result, opnd);
06164 if (WN_Asm_Volatile(asm_wn)) {
06165 Set_OP_volatile(asm_op);
06166 }
06167 OPS_Append_Op(&New_OPs, asm_op);
06168 OP_MAP_Set(OP_Asm_Map, asm_op, asm_info);
06169
06170 #ifdef KEY
06171
06172 {
06173 int i;
06174 ISA_REGISTER_CLASS rc;
06175
06176 ASMINFO *asm_bb_info = TYPE_PU_ALLOC(ASMINFO);
06177 bzero(asm_bb_info, sizeof(ASMINFO));
06178
06179 FOR_ALL_ISA_REGISTER_CLASS(rc) {
06180 ASMINFO_livein(asm_bb_info)[rc] = REGISTER_SET_EMPTY_SET;
06181 ASMINFO_liveout(asm_bb_info)[rc] = REGISTER_SET_EMPTY_SET;
06182
06183 ASMINFO_kill(asm_bb_info)[rc] = ASM_OP_clobber_set(asm_info)[rc];
06184 }
06185
06186 for (i = 0; i < OP_opnds(asm_op); i++) {
06187 TN *tn = OP_opnd(asm_op, i);
06188 if (TN_is_register(tn)) {
06189 REGISTER reg = TN_register(tn);
06190 if (reg != REGISTER_UNDEFINED) {
06191 rc = TN_register_class(tn);
06192 ASMINFO_livein(asm_bb_info)[rc] =
06193 REGISTER_SET_Union1(ASMINFO_livein(asm_bb_info)[rc], reg);
06194 }
06195 }
06196 }
06197
06198 for (i = 0; i < OP_results(asm_op); i++) {
06199 TN *tn = OP_result(asm_op, i);
06200 REGISTER reg = TN_register(tn);
06201 if (reg != REGISTER_UNDEFINED) {
06202 rc = TN_register_class(tn);
06203 ASMINFO_liveout(asm_bb_info)[rc] =
06204 REGISTER_SET_Union1(ASMINFO_liveout(asm_bb_info)[rc], reg);
06205 ASMINFO_kill(asm_bb_info)[rc] =
06206 REGISTER_SET_Union1(ASMINFO_kill(asm_bb_info)[rc], reg);
06207 }
06208 }
06209
06210 BB_Add_Annotation(Cur_BB, ANNOT_ASMINFO, asm_bb_info);
06211 }
06212
06213
06214 Start_New_Basic_Block ();
06215 #endif
06216 }
06217
06218
06219
06220 static void
06221 Replace_Substring (char *s, char *match, char *newstr)
06222 {
06223
06224 char *buf = (char*) alloca(strlen(s)+16);
06225
06226 while (TRUE) {
06227 char *p = strstr (s, match);
06228 if (p == NULL) {
06229 return;
06230 }
06231 char *match_end = p + strlen(match);
06232 *p = '\0';
06233 sprintf(buf, "%s%s%s", s, newstr, match_end);
06234 strcpy(s,buf);
06235 }
06236 }
06237
06238 static void
06239 Modify_Asm_String (char *asm_string, INT pattern_index, TN *tn, char *tn_name)
06240 {
06241 char pattern[4];
06242 sprintf(pattern, "%%%c", '0'+pattern_index);
06243 Replace_Substring (asm_string, pattern, tn_name);
06244
06245 if (tn && TN_is_register(tn)) {
06246 for (INT i = 0; i < CGTARG_Num_Asm_Opnd_Modifiers; i++) {
06247 char modifier = CGTARG_Asm_Opnd_Modifiers[i];
06248 sprintf(pattern, "%%%c%c", modifier, '0'+pattern_index);
06249 char* mod_name = (char*) CGTARG_Modified_Asm_Opnd_Name(modifier, tn, tn_name);
06250 Replace_Substring (asm_string, pattern, mod_name);
06251 }
06252 }
06253 }
06254
06255
06256
06257
06258
06259
06260 static SRCPOS get_loop_srcpos(WN *body_label)
06261 {
06262 if (current_srcpos) {
06263 return current_srcpos;
06264 } else if (WN_linenum(body_label)) {
06265 return WN_linenum(body_label);
06266 } else {
06267 WN *wn = WN_next(body_label);
06268 while (wn && WN_linenum(wn) == 0 && WN_opcode(wn) != OPC_LABEL)
06269 wn = WN_next(wn);
06270 return wn ? WN_linenum(wn) : 0;
06271 }
06272 }
06273
06274
06275 #if defined(TARG_SL)
06276
06277
06278
06279
06280
06281
06282 BOOL SL_Intrinsic_Has_ReturnP(TOP opcode) {
06283 switch (opcode) {
06284 case TOP_c2_mvgr_r2g_h_u:
06285 case TOP_c2_mvgr_r2g_h:
06286 case TOP_c2_mvgr_r2g_w:
06287 case TOP_c2_mvgr_r2g_h_u_i:
06288 case TOP_c2_mvgr_r2g_h_i:
06289 case TOP_c2_mvgr_r2g_w_i:
06290 case TOP_c2_mvgc_c2g:
06291 case TOP_c2_ld_s_h_u_p:
06292 case TOP_c2_ld_s_h_u:
06293 case TOP_c2_ld_s_h_p:
06294 case TOP_c2_ld_s_h:
06295 case TOP_c2_ld_s_w_p:
06296 case TOP_c2_ld_s_w:
06297 case TOP_c2_ld_v2g_b_u:
06298 case TOP_c2_ld_v2g_b:
06299 case TOP_c2_ld_v2g_h_u:
06300 case TOP_c2_ld_v2g_h:
06301 case TOP_c2_ld_v2g_w:
06302 case TOP_c2_ldi_v2g_b_u:
06303 case TOP_c2_ldi_v2g_b:
06304 case TOP_c2_ldi_v2g_h_u:
06305 case TOP_c2_ldi_v2g_h:
06306 case TOP_c2_ldi_v2g_w:
06307 case TOP_c2_ldi_s_h_u:
06308 case TOP_c2_ldi_s_h:
06309 case TOP_c2_ldi_s_w:
06310 case TOP_c2_sad:
06311 case TOP_c2_satd:
06312 case TOP_c2_mvsel_mode0:
06313 case TOP_c2_mvsel_mode1:
06314 case TOP_c2_mvsel_mode2:
06315 case TOP_c2_mvsel_mode345:
06316 case TOP_c2_bcst_q:
06317 case TOP_c2_bcst_i:
06318 case TOP_c2_vlcs_wb:
06319 case TOP_c2_add_shl_g_i:
06320 case TOP_c2_add_shr_g_i:
06321 case TOP_c2_add_shl_g:
06322 case TOP_c2_add_shr_g:
06323 case TOP_c2_sub_g_abs_i:
06324 case TOP_c2_subs_g_i:
06325 case TOP_c2_sub_g_abs:
06326 case TOP_c2_subs_g:
06327 case TOP_c2_mads:
06328 case TOP_c2_smads:
06329 case TOP_c2_min:
06330 case TOP_c2_max:
06331 case TOP_c2_cmov:
06332 case TOP_c2_mov_g:
06333 case TOP_c2_clp:
06334 case TOP_c2_clp_i:
06335 case TOP_c2_chkrng:
06336 case TOP_c2_scond_r_h_wb_eq:
06337 case TOP_c2_scond_r_h_wb_lt:
06338 case TOP_c2_scond_r_h_wb_le:
06339 case TOP_c2_scond_r_h_wb_gt:
06340 case TOP_c2_scond_r_h_wb_ge:
06341 case TOP_c2_scond_r_wb_eq_i:
06342 case TOP_c2_scond_r_wb_lt_i:
06343 case TOP_c2_scond_r_wb_le_i:
06344 case TOP_c2_scond_r_wb_gt_i:
06345 case TOP_c2_scond_r_wb_ge_i:
06346 case TOP_c2_scond_r_w_wb_eq:
06347 case TOP_c2_scond_r_w_wb_lt:
06348 case TOP_c2_scond_r_w_wb_le:
06349 case TOP_c2_scond_r_w_wb_gt:
06350 case TOP_c2_scond_r_w_wb_ge:
06351 case TOP_c2_scond_r_w_wb_eq_i:
06352 case TOP_c2_scond_r_w_wb_lt_i:
06353 case TOP_c2_scond_r_w_wb_le_i:
06354 case TOP_c2_scond_r_w_wb_gt_i:
06355 case TOP_c2_scond_r_w_wb_ge_i:
06356 case TOP_c2_scond_eq:
06357 case TOP_c2_scond_lt:
06358 case TOP_c2_scond_le:
06359 case TOP_c2_scond_gt:
06360 case TOP_c2_scond_ge:
06361 case TOP_c2_scond_eq_i:
06362 case TOP_c2_scond_lt_i:
06363 case TOP_c2_scond_le_i:
06364 case TOP_c2_scond_gt_i:
06365 case TOP_c2_scond_ge_i:
06366 case TOP_c2_bop_ls:
06367 case TOP_c2_bop_rs:
06368 case TOP_c2_bop_and:
06369 case TOP_c2_bop_or:
06370 case TOP_c2_bop_xor:
06371 case TOP_c2_bop_ls_i:
06372 case TOP_c2_bop_rs_i:
06373 case TOP_c2_bop_and_i:
06374 case TOP_c2_bop_or_i:
06375 case TOP_c2_bop_xor_i:
06376 case TOP_c2_bdep_l:
06377 case TOP_c2_bdep_m:
06378 case TOP_c2_bxtr_u_l:
06379 case TOP_c2_bxtr_s_l:
06380 case TOP_c2_bxtr_u_m:
06381 case TOP_c2_bxtr_s_m:
06382 case TOP_c2_sum4_g:
06383 case TOP_c2_sum4_sw:
06384 case TOP_c2_sum4_saddr:
06385 case TOP_c2_med:
06386 case TOP_c2_gsums:
06387 case TOP_c3_mvtacc:
06388 case TOP_c3_mvtaddr:
06389 case TOP_c3_mvfacc:
06390 case TOP_c3_mvfaddr:
06391 return TRUE;
06392 default:
06393 return FALSE;
06394 }
06395 }
06396 #endif
06397
06398
06399
06400
06401
06402 static void Expand_Statement (WN *stmt)
06403 {
06404 BB *bb;
06405 WN *loop_info;
06406 LOOPINFO *info = NULL;
06407 TN *trip_tn;
06408 OPCODE opc = WN_opcode(stmt);
06409 PU_WN_Cnt++;
06410
06411 switch (opc) {
06412
06413
06414
06415
06416
06417
06418
06419
06420
06421
06422
06423
06424
06425
06426 case OPC_TRUEBR:
06427 case OPC_FALSEBR:
06428 case OPC_GOTO:
06429 case OPC_AGOTO:
06430 case OPC_COMPGOTO:
06431 case OPC_XGOTO:
06432 case OPC_REGION_EXIT:
06433 #ifdef KEY
06434 case OPC_GOTO_OUTER_BLOCK:
06435 #endif
06436 #ifdef TARG_SL2 //fork_joint
06437 case OPC_SL2_FORK_MAJOR:
06438 case OPC_SL2_FORK_MINOR:
06439 #endif
06440 Convert_Branch (stmt);
06441 break;
06442 case OPC_RETURN:
06443
06444
06445
06446
06447
06448
06449 Handle_Return ();
06450 break;
06451 case OPC_LABEL:
06452 loop_info = WN_label_loop_info(stmt);
06453 if (loop_info && CG_opt_level > 1) {
06454 WN *trip_wn = WN_loop_trip(loop_info);
06455 SRCPOS srcpos = get_loop_srcpos(stmt);
06456 if (trip_wn && WN_operator_is(trip_wn, OPR_INTCONST) &&
06457 WN_const_val(trip_wn) < 1) {
06458
06459
06460
06461
06462
06463
06464
06465
06466 DevWarn("removing loop trip count (line %d) "
06467 "(< 1, either useless or invalid)",
06468 Srcpos_To_Line(srcpos));
06469 WN_set_loop_trip(loop_info, NULL);
06470 trip_wn = NULL;
06471 }
06472 if (trip_wn == NULL) {
06473 trip_tn = NULL;
06474 } else {
06475 if (WN_operator_is(trip_wn, OPR_INTCONST)) {
06476 INT64 trip_val = WN_const_val(trip_wn);
06477 UINT16 sz = MTYPE_RegisterSize(WN_rtype(trip_wn));
06478
06479 WN_loop_trip_est(loop_info) = MIN(trip_val, UINT16_MAX);
06480 trip_tn = Gen_Literal_TN(WN_const_val(trip_wn), sz);
06481 } else {
06482
06483
06484
06485
06486
06487
06488
06489
06490 if (OPS_first(&New_OPs)) {
06491 Start_New_Basic_Block();
06492 }
06493 trip_tn = Expand_Expr(trip_wn, NULL, NULL);
06494 if (OPS_first(&New_OPs) == NULL) {
06495
06496 TN *tmp = Dup_TN_Even_If_Dedicated(trip_tn);
06497 Exp_COPY(tmp, trip_tn, &New_OPs);
06498 trip_tn = tmp;
06499 }
06500 }
06501 }
06502 info = TYPE_P_ALLOC(LOOPINFO);
06503 LOOPINFO_wn(info) = loop_info;
06504 LOOPINFO_srcpos(info) = srcpos;
06505 LOOPINFO_trip_count_tn(info) = trip_tn;
06506 #ifndef TARG_NVISA
06507 if (!CG_PU_Has_Feedback && WN_loop_trip_est(loop_info) == 0)
06508 WN_loop_trip_est(loop_info) = 100;
06509 #endif
06510 }
06511 if (WN_Label_Is_Handler_Begin(stmt)) {
06512 LABEL_IDX label = Get_WN_Label(stmt);
06513 Handle_Entry(stmt);
06514 bb = BB_LIST_first(Entry_BB_Head);
06515 Set_BB_handler(bb);
06516 BB_Add_Annotation (bb, ANNOT_LABEL, (void *)(INTPTR)label);
06517 FmtAssert (Get_Label_BB(label) == NULL,
06518 ("Label %s defined more than once", LABEL_name(label)));
06519 Set_Label_BB (label,bb);
06520 } else {
06521
06522 #ifdef KEY
06523 BOOL is_non_local_label;
06524 bb = Add_Label(Get_WN_Label (stmt, &is_non_local_label));
06525 if (is_non_local_label)
06526 Set_BB_has_non_local_label(bb);
06527 #else
06528 bb = Add_Label(Get_WN_Label (stmt));
06529 #endif
06530 }
06531 if (info) {
06532 BB_Add_Annotation(bb, ANNOT_LOOPINFO, info);
06533 if (last_loop_pragma) {
06534 BB_Add_Annotation(bb, ANNOT_PRAGMA, last_loop_pragma);
06535 last_loop_pragma = NULL;
06536 }
06537 }
06538 break;
06539 case OPC_ALTENTRY:
06540 Handle_Entry (stmt);
06541 break;
06542 case OPC_PRAGMA:
06543 case OPC_XPRAGMA:
06544 if (WN_pragmas[WN_pragma(stmt)].users == PUSER_CG) {
06545 if (WN_pragma(stmt) == WN_PRAGMA_UNROLL)
06546
06547
06548
06549
06550
06551 last_loop_pragma = stmt;
06552 else
06553 BB_Add_Annotation(Cur_BB, ANNOT_PRAGMA, stmt);
06554 }
06555 #ifdef TARG_X8664
06556 if (WN_pragma(stmt) == WN_PRAGMA_PREAMBLE_END)
06557 WN_pragma_preamble_end_seen = TRUE;
06558 #endif
06559 break;
06560 case OPC_COMMENT:
06561 COMMENT_Add(Cur_BB, WN_GetComment(stmt));
06562 break;
06563 case OPC_EVAL:
06564
06565 #if defined(TARG_IA32) || defined(TARG_X8664)
06566 if (WN_has_side_effects(WN_kid0(stmt)))
06567 #endif
06568 Expand_Expr (WN_kid0(stmt), NULL, NULL);
06569 break;
06570 case OPC_TRAP:
06571 Handle_Trap(stmt);
06572 break;
06573 case OPC_ASM_STMT:
06574 Handle_ASM (stmt);
06575 break;
06576 default:
06577 PU_WN_Cnt--;
06578 Expand_Expr (stmt, NULL, NULL);
06579 break;
06580 }
06581 }
06582
06583
06584 static WN *
06585 Handle_INTRINSIC_CALL (WN *intrncall)
06586 {
06587 enum {max_intrinsic_opnds = 4};
06588 TN *result;
06589 TN *opnd_tn[max_intrinsic_opnds];
06590 INT i;
06591 LABEL_IDX label = LABEL_IDX_ZERO;
06592 OPS loop_ops;
06593
06594 #ifdef KEY
06595 OP *last_op_from_intrn_call = NULL;
06596 #endif
06597
06598 #if !defined(TARG_SL)
06599 FmtAssert(WN_num_actuals(intrncall) <= max_intrinsic_opnds,
06600 ("too many intrinsic call operands (%d)", WN_num_actuals(intrncall)));
06601 #endif
06602
06603 WN *next_stmt = WN_next(intrncall);
06604 INTRINSIC id = (INTRINSIC) WN_intrinsic (intrncall);
06605
06606 #ifdef TARG_X8664
06607 switch( id ){
06608 case INTRN_SAVE_XMMS:
06609 {
06610 Exp_Savexmms_Intrinsic(intrncall,
06611 Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06612 &label, &New_OPs);
06613 BB *bb = Start_New_Basic_Block();
06614 BB_Add_Annotation (bb, ANNOT_LABEL, (void *)label);
06615 Set_Label_BB (label,bb);
06616 return next_stmt;
06617 }
06618 break;
06619
06620 #if 0 // removed from PSC 3.2
06621 case INTRN_FETCH_AND_ADD_I4:
06622 case INTRN_FETCH_AND_ADD_I8:
06623 {
06624 Exp_Fetch_and_Add( Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06625 Expand_Expr(WN_kid1(intrncall), intrncall, NULL),
06626 WN_rtype(intrncall),
06627 &New_OPs );
06628
06629 return next_stmt;
06630 }
06631 break;
06632 #endif
06633
06634 case INTRN_FETCH_AND_AND_I4:
06635 case INTRN_FETCH_AND_AND_I8:
06636 {
06637 Exp_Fetch_and_And( Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06638 Expand_Expr(WN_kid1(intrncall), intrncall, NULL),
06639 WN_rtype(intrncall),
06640 &New_OPs );
06641 return next_stmt;
06642 }
06643 break;
06644 case INTRN_FETCH_AND_OR_I4:
06645 case INTRN_FETCH_AND_OR_I8:
06646 {
06647 Exp_Fetch_and_Or( Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06648 Expand_Expr(WN_kid1(intrncall), intrncall, NULL),
06649 WN_rtype(intrncall),
06650 &New_OPs );
06651 return next_stmt;
06652 }
06653 break;
06654 case INTRN_FETCH_AND_XOR_I4:
06655 case INTRN_FETCH_AND_XOR_I8:
06656 {
06657 Exp_Fetch_and_Xor( Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06658 Expand_Expr(WN_kid1(intrncall), intrncall, NULL),
06659 WN_rtype(intrncall),
06660 &New_OPs );
06661 return next_stmt;
06662 }
06663 break;
06664
06665 #if 0 // removed from PSC 3.2
06666 case INTRN_FETCH_AND_SUB_I4:
06667 case INTRN_FETCH_AND_SUB_I8:
06668 {
06669 Exp_Fetch_and_Sub( Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06670 Expand_Expr(WN_kid1(intrncall), intrncall, NULL),
06671 WN_rtype(intrncall),
06672 &New_OPs );
06673 #if defined(TARG_IA64)
06674
06675 goto cont;
06676 #else
06677 return next_stmt;
06678 #endif
06679 }
06680 break;
06681 #endif
06682
06683 case INTRN_COMPARE_AND_SWAP_I4:
06684 case INTRN_COMPARE_AND_SWAP_I8:
06685 {
06686 result = Exp_Compare_and_Swap( Expand_Expr(WN_kid0(intrncall), intrncall, NULL),
06687 Expand_Expr(WN_kid1(intrncall), intrncall, NULL),
06688 Expand_Expr(WN_kid2(intrncall), intrncall, NULL),
06689 WN_rtype(WN_kid1(intrncall)),
06690 &New_OPs );
06691
06692
06693 goto cont;
06694 }
06695 break;
06696 case INTRN_STMXCSR: {
06697 WN *lda = WN_kid0(WN_kid0(intrncall));
06698 TN *ofst_tn = Gen_Symbol_TN(WN_st(lda), WN_lda_offset(lda), 0);
06699 Build_OP(TOP_stmxcsr, SP_TN, ofst_tn, &New_OPs);
06700 return next_stmt;
06701 }
06702 case INTRN_LDMXCSR: {
06703 TN *val_tn = Expand_Expr(WN_kid0(WN_kid0(intrncall)), WN_kid0(intrncall),
06704 NULL);
06705 ST *tmp_st = Gen_Temp_Symbol(MTYPE_To_TY(MTYPE_I4), "__ldmxcsr");
06706 Allocate_Temp_To_Memory(tmp_st);
06707 TN *ofst_tn = Gen_Symbol_TN(tmp_st, ST_ofst(tmp_st), 0);
06708 Build_OP(TOP_store32, val_tn, SP_TN, ofst_tn, &New_OPs);
06709 Build_OP(TOP_ldmxcsr, SP_TN, ofst_tn, &New_OPs);
06710 return next_stmt;
06711 }
06712 }
06713 #endif
06714
06715 #ifdef KEY
06716 opnd_tn[0] = opnd_tn[1] = opnd_tn[2] = NULL;
06717 #endif
06718
06719 #if defined(TARG_SL)
06720 if ((id >= INTRN_SL_INTRN_BGN) && (id <= INTRN_SL_INTRN_END) ||
06721 (id >= INTRN_C3_INTRINSIC_BEGIN && id <= INTRN_C3_INTRINSIC_END)) {
06722 result = Exp_SL_Intrinsic_Call (id, intrncall,
06723 &New_OPs, &label, &loop_ops);
06724 } else {
06725 #endif
06726
06727 for (i = 0; i < WN_num_actuals(intrncall); i++) {
06728
06729
06730 opnd_tn[i] = Expand_Expr (WN_kid(intrncall, i), intrncall, NULL);
06731 }
06732
06733
06734
06735
06736
06737
06738 OPS_Init(&loop_ops);
06739 current_srcpos = WN_Get_Linenum (intrncall);
06740 result = Exp_Intrinsic_Call (id,
06741 opnd_tn[0], opnd_tn[1], opnd_tn[2], &New_OPs, &label, &loop_ops);
06742
06743 #ifdef KEY
06744 last_op_from_intrn_call = OPS_last(&New_OPs);
06745 #endif
06746
06747 if (OPS_first(&loop_ops) != NULL && label != LABEL_IDX_ZERO) {
06748 BB *bb = Start_New_Basic_Block ();
06749 BB_Add_Annotation (bb, ANNOT_LABEL, (void *)(INTPTR)label);
06750 Set_Label_BB (label,bb);
06751 BB_branch_wn(bb) = WN_Create(OPC_FALSEBR,1);
06752 WN_label_number(BB_branch_wn(bb)) = label;
06753 New_OPs = loop_ops;
06754 Start_New_Basic_Block ();
06755 }
06756
06757 #if defined(TARG_SL)
06758 }
06759 #endif
06760
06761 #ifdef KEY
06762 cont:
06763 #endif
06764
06765
06766
06767
06768 if (next_stmt != NULL &&
06769 result != NULL &&
06770 !WN_operator_is (next_stmt, OPR_INTRINSIC_CALL))
06771 {
06772 OP *op;
06773 if (Trace_WhirlToOp) {
06774 fprintf (TFile, "---------------------------------\n");
06775 fdump_tree_with_freq (TFile, next_stmt, WN_MAP_UNDEFINED);
06776 }
06777 Expand_Statement (next_stmt);
06778 next_stmt = WN_next(next_stmt);
06779 FOR_ALL_OPS_OPs_REV (&New_OPs, op) {
06780 #ifdef KEY
06781 if (op == last_op_from_intrn_call)
06782 break;
06783 #else
06784 if (OP_code(op) == TOP_intrncall) break;
06785 #endif
06786
06787 #if defined(TARG_SL)
06788 if (SL_Intrinsic_Has_ReturnP(OP_code(op)))
06789 break;
06790 #endif
06791 for (i = 0; i < OP_opnds(op); i++) {
06792 TN *otn = OP_opnd(op,i);
06793
06794 if ( TN_is_dedicated(otn)
06795 && (TN_register_and_class(otn) == CLASS_AND_REG_v0
06796 #if defined(TARG_X8664)
06797 ||
06798 TN_register_and_class(otn) == CLASS_AND_REG_f0
06799 #endif
06800 )
06801 ) {
06802 Set_OP_opnd (op, i, result);
06803 }
06804 }
06805 }
06806 }
06807 return next_stmt;
06808 }
06809
06810
06811 static BOOL
06812 Only_Has_Exc_Label(BB *bb)
06813 {
06814 if (BB_has_label(bb)) {
06815 ANNOTATION *ant;
06816
06817 for (ant = ANNOT_First(BB_annotations(bb), ANNOT_LABEL);
06818 ant != NULL;
06819 ant = ANNOT_Next(ant, ANNOT_LABEL)
06820 ) {
06821 LABEL_IDX lab = ANNOT_label(ant);
06822 if (!LABEL_begin_eh_range(lab) && !LABEL_end_eh_range(lab))
06823 return FALSE;
06824 }
06825 return TRUE;
06826 }
06827 return FALSE;
06828 }
06829
06830
06831
06832
06833
06834 static void
06835 convert_stmt_list_to_OPs(WN *stmt)
06836 {
06837 RID *rid;
06838 WN *first;
06839 BB *prev, *last;
06840 WN *next_stmt;
06841
06842 for( ; stmt; stmt = next_stmt )
06843 {
06844 next_stmt = WN_next(stmt);
06845
06846 switch( WN_opcode( stmt ) ) {
06847 case OPC_REGION:
06848 rid = REGION_get_rid(stmt);
06849 Is_True(rid != NULL, ("convert_stmt_list_to_OPs NULL RID"));
06850 if ( RID_level( rid ) < RL_CG ) {
06851 region_stack_push( rid );
06852
06853 #ifdef TARG_SL //fork_joint
06854
06855
06856
06857
06858 if(RID_TYPE_minor(rid) && RID_cginfo(rid) == NULL) {
06859 INT num_exits = RID_num_exits( rid );
06860 CGRIN * cgrin = CGRIN_Create( num_exits );
06861 RID_cginfo( rid ) = cgrin;
06862 RID_level( rid ) = RL_CG-1;
06863 CGRIN_entry( cgrin ) = Cur_BB;
06864 BB_rid( Cur_BB ) = NULL;
06865 }
06866 #endif
06867
06868
06869 #ifdef TARG_IA64
06870
06871 if (RID_TYPE_eh(rid) &&
06872 RID_eh_range_ptr(rid) &&
06873 !PU_Need_Not_Create_LSDA ()) {
06874 #else // TARG_IA64
06875 if (RID_TYPE_eh(rid) && RID_eh_range_ptr(rid)) {
06876 #endif
06877 EH_Set_Start_Label(RID_eh_range_ptr(rid));
06878 }
06879
06880 first = WN_first( WN_region_body( stmt ) );
06881 Start_New_Basic_Block();
06882 if (RID_is_glue_code(rid)) {
06883 In_Glue_Region = TRUE;
06884 }
06885 convert_stmt_list_to_OPs( first );
06886 if (RID_is_glue_code(rid)) {
06887 In_Glue_Region = FALSE;
06888 }
06889 #ifdef KEY
06890 if (RID_TYPE_eh(rid) && RID_eh_range_ptr(rid)) {
06891 #else
06892 if (RID_TYPE_eh(rid)) {
06893 #endif
06894 EH_Set_End_Label(RID_eh_range_ptr(rid));
06895 #ifdef KEY
06896
06897
06898
06899
06900 {
06901 BB* old_bb = Cur_BB;
06902 Start_New_Basic_Block();
06903 if( Cur_BB == old_bb ){
06904 Cur_BB = Gen_And_Append_BB( Cur_BB );
06905 BB_rid(Cur_BB) = Non_Transparent_RID(current_region);
06906 }
06907 }
06908 #endif
06909 }
06910 rid = region_stack_pop();
06911 } else {
06912 BB *old_bb = Cur_BB;
06913 Start_New_Basic_Block();
06914 if (old_bb == Cur_BB) {
06915
06916
06917
06918
06919
06920
06921
06922 Set_BB_gra_spill(Cur_BB);
06923 Cur_BB = Gen_And_Append_BB(Cur_BB);
06924 BB_rid(Cur_BB) = Non_Transparent_RID(current_region);
06925 }
06926
06927 prev = BB_prev( Cur_BB );
06928 last = Append_Region_BBs( prev, rid );
06929 BB_prev( Cur_BB ) = last;
06930 BB_next( last ) = Cur_BB;
06931
06932 CGRIN *cginfo = RID_cginfo(rid);
06933 Is_True(cginfo != NULL, ("convert_stmt_list_to_OPs, null cginfo"));
06934 if ( CGRIN_min_bb_id( cginfo ) < min_bb_id )
06935 min_bb_id = CGRIN_min_bb_id( cginfo );
06936 if ( CGRIN_first_regular_tn( cginfo ) < First_REGION_TN )
06937 First_REGION_TN = CGRIN_first_regular_tn( cginfo );
06938 if ( CGRIN_first_gtn( cginfo ) < First_REGION_GTN )
06939 First_REGION_GTN = CGRIN_first_gtn( cginfo );
06940 }
06941 break;
06942 default:
06943 Is_True((OPCODE_is_stmt(WN_opcode(stmt))),
06944 ("convert_stmt_list_to_OPs: %d not a stmt", WN_opcode(stmt)));
06945
06946 if (Trace_WhirlToOp) {
06947 fprintf (TFile,
06948 "----- convert_stmt_list_to_OPs, BB%d -------------------\n",
06949 BB_id(Cur_BB));
06950 fdump_tree_with_freq (TFile, stmt, WN_MAP_UNDEFINED);
06951 }
06952 if (WN_Get_Linenum(stmt))
06953 current_srcpos = WN_Get_Linenum(stmt);
06954 if (WN_operator_is (stmt, OPR_INTRINSIC_CALL)) {
06955 next_stmt = Handle_INTRINSIC_CALL (stmt);
06956 #if defined(TARG_SL)
06957 if(WN_intrinsic(stmt)==INTRN_C2_JOINT) {
06958 Set_BB_freq_unbalanced(Cur_BB);
06959 }
06960 #endif
06961 } else {
06962 Expand_Statement( stmt );
06963 }
06964 Process_OPs_For_Stmt();
06965 }
06966 }
06967 }
06968
06969
06970
06971
06972
06973 void
06974 Convert_WHIRL_To_OPs (WN *tree)
06975 {
06976 WN *stmt;
06977 CGRIN *cgrin;
06978 BB *last_bb;
06979 INT num_exits, i;
06980 RID *rid = REGION_get_rid(tree);
06981 Is_True(rid != NULL, ("Convert_WHIRL_To_OPs, NULL RID"));
06982 BOOL Trace_BBs = Get_Trace (TP_CGEXP, 512);
06983 Trace_WhirlToOp = Get_Trace (TP_CGEXP, 2);
06984
06985
06986
06987 if (Trace_WhirlToOp) {
06988 fprintf(TFile, "%sWHIRL tree input to Convert_WHIRL_To_OPs:\n%s",
06989 DBar, DBar);
06990 fdump_tree_with_freq(TFile, tree, WN_MAP_UNDEFINED);
06991 }
06992
06993 initialize_region_stack(tree);
06994 Cur_BB = NULL;
06995 current_srcpos = 0;
06996
06997 switch ( WN_opcode( tree ) ) {
06998 case OPC_FUNC_ENTRY:
06999 Compiling_Proper_REGION = FALSE;
07000 if (RID_cginfo(rid) == NULL) {
07001 RID_cginfo(rid) = CGRIN_Create(RID_num_exits(rid));
07002 }
07003 Handle_Entry( tree );
07004 stmt = WN_entry_first( tree );
07005 break;
07006 case OPC_REGION:
07007 Compiling_Proper_REGION = TRUE;
07008 if ( RID_level( rid ) < RL_CG ) {
07009 num_exits = RID_num_exits( rid );
07010 cgrin = CGRIN_Create( num_exits );
07011 RID_cginfo( rid ) = cgrin;
07012 RID_level( rid ) = RL_CG;
07013 region_stack_push( rid );
07014 Start_New_Basic_Block();
07015 CGRIN_entry( cgrin ) = Cur_BB;
07016 min_bb_id = BB_id( Cur_BB );
07017 CGRIN_min_bb_id( cgrin ) = min_bb_id;
07018 BB_rid( Cur_BB ) = rid;
07019 stmt = WN_first( WN_region_body( tree ) );
07020 }
07021 else {
07022 Cur_BB = Append_Region_BBs( Cur_BB, rid );
07023 if ( CGRIN_first_regular_tn( RID_cginfo( rid ) ) < First_REGION_TN )
07024 First_REGION_TN = CGRIN_first_regular_tn( RID_cginfo( rid ) );
07025 if ( CGRIN_first_gtn( RID_cginfo( rid ) ) < First_REGION_GTN )
07026 First_REGION_GTN = CGRIN_first_gtn( RID_cginfo( rid ) );
07027 CGRIN_entry( cgrin ) = REGION_First_BB;
07028 stmt = NULL;
07029 }
07030 break;
07031 default:
07032 Is_True( FALSE, ("unexpected opcode in Convert_WHIRL_To_OPs") );
07033 break;
07034 }
07035
07036 #ifndef TARG_IA64
07037
07038 WN_pragma_preamble_end_seen = FALSE;
07039 #endif
07040 if ( stmt )
07041 convert_stmt_list_to_OPs( stmt );
07042
07043
07044
07045
07046 if (OPS_first(&New_OPs) != NULL) Start_New_Basic_Block ();
07047
07048
07049
07050
07051
07052
07053
07054
07055 if ( ! Compiling_Proper_REGION ) {
07056 BB *final_bb = Cur_BB;
07057 if ( BB_length( final_bb ) == 0
07058 && ! BB_exit( final_bb )
07059 && ! BB_entry( final_bb )
07060
07061 && (! BB_has_label( final_bb ) || Only_Has_Exc_Label (final_bb) )
07062 ) {
07063 final_bb = BB_prev ( final_bb );
07064 }
07065
07066 if ( ! BB_exit( final_bb ) ) {
07067 OP *op = BB_last_op( final_bb );
07068 if ( op == NULL || OP_cond( op ) ) {
07069 Handle_Return ();
07070 }
07071 }
07072 }
07073
07074
07075
07076
07077
07078
07079 last_bb = Cur_BB;
07080 if ( ( BB_length( Cur_BB ) == 0 )
07081 && ( ! BB_has_label( Cur_BB ) )
07082 && ( ! BB_exit( Cur_BB ) )
07083 ) {
07084 last_bb = BB_prev( Cur_BB );
07085 Remove_BB( Cur_BB );
07086 if ( BB_id( Cur_BB ) == PU_BB_Count )
07087 --PU_BB_Count;
07088 }
07089 Is_True(last_bb != NULL,("Convert_WHIRL_To_OPs, last_bb is NULL"));
07090
07091
07092 Build_CFG();
07093
07094 switch ( WN_opcode( tree ) ) {
07095 case OPC_FUNC_ENTRY:
07096 break;
07097 case OPC_REGION:
07098 region_stack_pop();
07099 rid = REGION_get_rid(tree);
07100 CGRIN_first_bb( cgrin ) = REGION_First_BB;
07101 BB_rid( last_bb ) = rid;
07102 CGRIN_last_bb( cgrin ) = last_bb;
07103 CGRIN_min_bb_id( cgrin ) = min_bb_id;
07104 CGRIN_first_regular_tn( RID_cginfo( rid ) ) = First_REGION_TN;
07105 CGRIN_first_gtn( RID_cginfo( rid ) ) = First_REGION_GTN;
07106 CGRIN_preg_to_tn_mapping( cgrin ) = NULL;
07107 CGRIN_tns_in( cgrin ) = NULL;
07108 if ( RID_pregs_in( rid ) ) {
07109 Add_PregTNs_To_BB (RID_pregs_in(rid), CGRIN_entry(cgrin),
07110 TRUE );
07111 }
07112 num_exits = RID_num_exits(rid);
07113 if (num_exits > 0) {
07114 TN_LIST **tno;
07115 tno = TYPE_MEM_POOL_ALLOC_N( TN_LIST *, ®ION_mem_pool, num_exits );
07116 CGRIN_tns_out( cgrin ) = tno;
07117 } else {
07118 CGRIN_tns_out( cgrin ) = NULL;
07119 }
07120 for ( i = 0; i < num_exits; i++ ) {
07121 FmtAssert(cgrin != NULL && CGRIN_exit_i(cgrin,i),
07122 ("missing exit bb for RGN %d, exit %d, cgrin=0x%x",
07123 RID_id(rid), i, cgrin));
07124 Add_PregTNs_To_BB (RID_pregs_out_i(rid,i), CGRIN_exit_i(cgrin,i),
07125 FALSE );
07126 }
07127 break;
07128 default:
07129 #pragma mips_frequency_hint NEVER
07130 FmtAssert( FALSE, ("unexpected opcode in Convert_WHIRL_To_OPs") );
07131
07132 }
07133
07134 if (Trace_BBs)
07135 Print_All_BBs ();
07136 }
07137
07138 void Whirl2ops_Initialize(struct ALIAS_MANAGER *alias_mgr)
07139 {
07140 Alias_Manager = alias_mgr;
07141
07142 if ( Alias_Manager) {
07143 OP_to_WN_map = OP_MAP_Create();
07144 WN_to_OP_map = WN_MAP_Create(&MEM_phase_pool);
07145 }
07146 else {
07147 OP_to_WN_map = NULL;
07148 WN_to_OP_map = WN_MAP_UNDEFINED;
07149 }
07150 last_loop_pragma = NULL;
07151 OP_Asm_Map = OP_MAP_Create();
07152 #if defined(TARG_IA64)
07153 OP_Ld_GOT_2_Sym_Map = OP_MAP_Create();
07154 #endif
07155 }
07156
07157 void Whirl2ops_Finalize(void)
07158 {
07159
07160 if (predicate_map) {
07161 OP_MAP_Delete(predicate_map);
07162 predicate_map = NULL;
07163 }
07164 if (OP_to_WN_map) {
07165 OP_MAP_Delete(OP_to_WN_map);
07166 OP_to_WN_map = NULL;
07167 }
07168 if (WN_to_OP_map != WN_MAP_UNDEFINED) {
07169 WN_MAP_Delete(WN_to_OP_map);
07170 WN_to_OP_map = WN_MAP_UNDEFINED;
07171 }
07172 if (last_loop_pragma &&
07173 !WN_pragma_compiler_generated(last_loop_pragma) &&
07174 CG_opt_level > 1) {
07175 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(last_loop_pragma),
07176 WN_pragmas[WN_pragma(last_loop_pragma)].name,
07177 "not followed by a loop, ignored");
07178 }
07179 OP_MAP_Delete(OP_Asm_Map);
07180 #if defined(TARG_IA64)
07181 OP_MAP_Delete(OP_Ld_GOT_2_Sym_Map);
07182 #endif
07183 }
07184
07185
07186
07187
07188
07189
07190
07191
07192
07193
07194 void
07195 Expand_New_Call_To_OPs (WN *call, OPERATOR call_opr, OPS *ops)
07196 {
07197 TN *tgt_tn;
07198 ST *call_st = (call_opr != OPR_ICALL) ? WN_st(call) : NULL;
07199 CALLINFO *call_info;
07200
07201 FmtAssert (ops != NULL && ops != &New_OPs,
07202 ("Wrong parameter ops, can not be NULL or &New_Ops."));
07203
07204
07205
07206
07207
07208
07209 PU_Has_Calls = TRUE;
07210
07211 #ifdef TARG_X8664
07212 if( Is_Target_32bit() &&
07213 Gen_PIC_Shared &&
07214 call_st != NULL &&
07215 !ST_is_export_local(call_st) ){
07216 PU_References_GOT = TRUE;
07217 }
07218 #endif
07219
07220
07221 if (call_opr == OPR_CALL) {
07222 tgt_tn = Gen_Symbol_TN (call_st, 0, 0);
07223 }
07224 else {
07225
07226 tgt_tn = Gen_PIC_Calls ? Ep_TN : NULL;
07227 tgt_tn = Expand_Expr (WN_kid(call,WN_kid_count(call)-1), call, tgt_tn);
07228
07229
07230
07231
07232 if (Gen_PIC_Call_Shared &&
07233 call_st != NULL &&
07234 !ST_is_preemptible(call_st) )
07235 {
07236 tgt_tn = Gen_Symbol_TN (call_st, 0, 0);
07237 call_opr = OPR_CALL;
07238 }
07239 }
07240 Last_Mem_OP = OPS_last(ops);
07241 Exp_Call (call_opr, RA_TN, tgt_tn, ops);
07242 Set_OP_To_WN_Map(call);
07243
07244 call_info = TYPE_PU_ALLOC (CALLINFO);
07245 CALLINFO_call_st(call_info) = call_st;
07246 CALLINFO_call_wn(call_info) = call;
07247 BB_Add_Annotation (Cur_BB, ANNOT_CALLINFO, call_info);
07248
07249 region_stack_eh_set_has_call();
07250
07251
07252
07253
07254
07255
07256
07257
07258
07259 OPS_Append_Ops(&New_OPs, ops);
07260 Start_New_Basic_Block ();
07261 OPS_Init(ops);
07262
07263
07264
07265 #ifdef TARG_IA64
07266 if (Is_Caller_Save_GP && !Constant_GP &&
07267
07268
07269
07270 (call_st == NULL || ST_export(call_st) == EXPORT_PREEMPTIBLE || ST_is_weak_symbol(call_st)) )
07271
07272 #else
07273 if (Is_Caller_Save_GP && !Constant_GP
07274 && (call_st == NULL || ST_export(call_st) == EXPORT_PREEMPTIBLE))
07275 #endif
07276 {
07277
07278
07279 TN *caller_gp_tn = PREG_To_TN_Array[ Caller_GP_Preg ];
07280 if (caller_gp_tn == NULL) {
07281 caller_gp_tn = Gen_Register_TN ( ISA_REGISTER_CLASS_integer,
07282 Pointer_Size);
07283 TN_MAP_Set( TN_To_PREG_Map, caller_gp_tn,
07284 (void *)(INTPTR)Caller_GP_Preg );
07285 PREG_To_TN_Array[ Caller_GP_Preg ] = caller_gp_tn;
07286 PREG_To_TN_Mtype[ Caller_GP_Preg ] = TY_mtype(Spill_Int_Type);
07287 }
07288 Exp_COPY (GP_TN, caller_gp_tn, ops);
07289 }
07290 }