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
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #ifdef _KEEP_RCS_ID
00070
00071 static char *rcs_id = "$Source: /depot/CVSROOT/javi/src/sw/cmplr/be/whirl2f/wn2f_stmt.cxx,v $ $Revision: 1.1 $";
00072 #endif
00073
00074 #include "whirl2f_common.h"
00075 #include "const.h"
00076 #include "pf_cg.h"
00077 #include "region_util.h"
00078 #include "w2cf_parentize.h"
00079 #include "PUinfo.h"
00080 #include "wn2f.h"
00081 #include "st2f.h"
00082 #include "ty2f.h"
00083 #include "tcon2f.h"
00084 #include "wn2f_stmt.h"
00085 #include "wn2f_load_store.h"
00086 #include "wn2f_io.h"
00087 #include "wn2f_pragma.h"
00088 #include "init2f.h"
00089 #include "be_symtab.h"
00090 #include "intrn_info.h"
00091
00092
00093 extern WN_MAP W2F_Frequency_Map;
00094 extern WN_MAP *W2F_Construct_Map;
00095 extern BOOL W2F_Prompf_Emission;
00096 extern BOOL W2F_Emit_Cgtag;
00097
00098
00099 static const char WN2F_Purple_Region_Name[] = "prp___region";
00100
00101 #define WN_pragma_nest(wn) WN_pragma_arg1(wn)
00102
00103
00104
00105
00106
00107
00108
00109
00110 static RETURNSITE *WN2F_Next_ReturnSite = NULL;
00111 static CALLSITE *WN2F_Prev_CallSite = NULL;
00112
00113
00114 static void
00115 WN2F_Load_Return_Reg(TOKEN_BUFFER tokens,
00116 TY_IDX return_ty,
00117 const char * var_name,
00118 STAB_OFFSET var_offset,
00119 MTYPE preg_mtype,
00120 PREG_IDX preg_offset,
00121 WN2F_CONTEXT context)
00122 {
00123
00124
00125
00126 const TY_IDX preg_ty = Stab_Mtype_To_Ty(preg_mtype);
00127 TOKEN_BUFFER tmp_tokens = New_Token_Buffer();
00128 FLD_PATH_INFO *path ;
00129
00130
00131
00132
00133 Append_Token_String(tmp_tokens, var_name);
00134 Append_Token_Special(tmp_tokens, WN2F_F90_pu ? '%' : '.');
00135 path = TY2F_Get_Fld_Path(return_ty,preg_ty,var_offset);
00136 TY2F_Translate_Fld_Path(tmp_tokens,path,FALSE,FALSE,FALSE,context);
00137 (void)TY2F_Free_Fld_Path(path);
00138
00139
00140 ST2F_Use_Preg(tokens, preg_ty, preg_offset);
00141 Append_Token_Special(tokens, '=');
00142 Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00143
00144 }
00145
00146 static void
00147 WN2F_Callsite_Directives(TOKEN_BUFFER tokens,
00148 WN *call_wn,
00149 ST *func_st)
00150 {
00151 if (WN_Call_Inline(call_wn))
00152 {
00153 Append_F77_Directive_Newline(tokens, "C*$*");
00154 Append_Token_String(tokens, "inline");
00155 Append_Token_Special(tokens, '(');
00156 ST2F_use_translate(tokens, func_st);
00157 Append_Token_Special(tokens, ')');
00158 }
00159 else if (WN_Call_Dont_Inline(call_wn))
00160 {
00161 Append_F77_Directive_Newline(tokens, "C*$*");
00162 Append_Token_String(tokens, "noinline");
00163 Append_Token_Special(tokens, '(');
00164 ST2F_use_translate(tokens, func_st);
00165 Append_Token_Special(tokens, ')');
00166 }
00167 }
00168
00169
00170 static void
00171 WN2F_Function_Call_Lhs(TOKEN_BUFFER rhs_tokens,
00172 TY_IDX return_ty,
00173 WN2F_CONTEXT context)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182
00183 TOKEN_BUFFER lhs_tokens = New_Token_Buffer();
00184 BOOL return_value_is_used = TRUE;
00185 UINT tmpvar_idx;
00186
00187
00188
00189
00190 const RETURN_PREG return_info = PUinfo_Get_ReturnPreg(return_ty);
00191 const MTYPE preg_mtype = RETURN_PREG_mtype(&return_info, 0);
00192 TY_IDX const preg_ty = Stab_Mtype_To_Ty(preg_mtype);
00193 const PREG_IDX preg_num = RETURN_PREG_offset(&return_info, 0);
00194 const INT num_pregs = RETURN_PREG_num_pregs(&return_info);
00195
00196
00197
00198
00199
00200 ST *result_var = (ST *)CALLSITE_return_var(WN2F_Prev_CallSite);
00201 const WN *result_store = CALLSITE_store1(WN2F_Prev_CallSite);
00202 STAB_OFFSET var_offset = CALLSITE_var_offset(WN2F_Prev_CallSite);
00203 BOOL need_result_in_regs = CALLSITE_in_regs(WN2F_Prev_CallSite);
00204
00205 if (preg_mtype == MTYPE_V)
00206 {
00207
00208 return_value_is_used = FALSE;
00209 }
00210 else if (result_var != NULL)
00211 {
00212
00213 ASSERT_WARN(!need_result_in_regs,
00214 (DIAG_W2F_UNEXPEXTED_RETURNREG_USE,
00215 "WN2F_Function_Call_Lhs"));
00216
00217
00218
00219
00220 if (ST_class(result_var) == CLASS_PREG)
00221 ST2F_Use_Preg(lhs_tokens, ST_type(result_var), var_offset);
00222
00223 else if (TY_kind(ST_type(result_var)) == KIND_STRUCT)
00224 ST2F_use_translate(lhs_tokens,result_var);
00225
00226 else
00227 WN2F_Offset_Symref(lhs_tokens,
00228 result_var,
00229 Stab_Pointer_To(ST_type(result_var)),
00230 return_ty,
00231 var_offset,
00232 context);
00233 }
00234 else if (result_store != NULL)
00235 {
00236
00237
00238
00239
00240
00241
00242 ASSERT_DBG_FATAL(WN_operator(result_store) == OPR_ISTORE &&
00243 WN_operator(WN_kid0(result_store)) == OPR_LDID,
00244 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_Function_Call_Lhs()"));
00245
00246
00247 ASSERT_WARN(!need_result_in_regs,
00248 (DIAG_W2F_UNEXPEXTED_RETURNREG_USE,
00249 "WN2F_Function_Call_Lhs"));
00250
00251
00252
00253
00254 ASSERT_WARN(WN2F_Can_Assign_Types(TY_pointed(WN_ty(result_store)),
00255 return_ty),
00256 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_Function_Call_Lhs"));
00257
00258 WN2F_Offset_Memref(lhs_tokens,
00259 WN_kid1(result_store),
00260 WN_Tree_Type(WN_kid1(result_store)),
00261 TY_pointed(WN_ty(result_store)),
00262 WN_store_offset(result_store),
00263 context);
00264 }
00265 else if (!need_result_in_regs)
00266 {
00267
00268
00269
00270 return_value_is_used = FALSE;
00271 }
00272 else if (num_pregs == 1 && TY_Is_Preg_Type(return_ty))
00273 {
00274
00275
00276
00277
00278
00279 ASSERT_WARN(WN2F_Can_Assign_Types(preg_ty, return_ty),
00280 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_Function_Call_Lhs"));
00281 ST2F_Use_Preg(lhs_tokens, preg_ty, preg_num);
00282 }
00283 else
00284 {
00285
00286
00287
00288
00289 const UINT tmp_idx = Stab_Lock_Tmpvar(return_ty,
00290 ST2F_Declare_Tempvar);
00291 const char *tmpvar_name = W2CF_Symtab_Nameof_Tempvar(tmp_idx);
00292
00293
00294 Append_Token_String(lhs_tokens, tmpvar_name);
00295
00296
00297
00298 WN2F_Stmt_Newline(rhs_tokens, (char*) NULL, (SRCPOS) NULL , context);
00299 WN2F_Load_Return_Reg(rhs_tokens,
00300 return_ty,
00301 tmpvar_name,
00302 0,
00303 preg_mtype,
00304 preg_num,
00305 context);
00306
00307 if (num_pregs > 1)
00308 {
00309
00310
00311
00312 STAB_OFFSET value_offset = TY_size(Stab_Mtype_To_Ty(preg_mtype));
00313
00314
00315 WN2F_Stmt_Newline(rhs_tokens, (char*) NULL, (SRCPOS) NULL , context);
00316 const PREG_IDX preg_num2 = RETURN_PREG_offset(&return_info, 1);
00317 const MTYPE preg_mtype2 = RETURN_PREG_mtype(&return_info, 1);
00318
00319 WN2F_Load_Return_Reg(rhs_tokens,
00320 return_ty,
00321 tmpvar_name,
00322 value_offset,
00323 preg_mtype2,
00324 preg_num2,
00325 context);
00326 }
00327
00328 Stab_Unlock_Tmpvar(tmp_idx);
00329
00330 }
00331
00332
00333
00334
00335 if (!return_value_is_used)
00336 {
00337 tmpvar_idx = Stab_Lock_Tmpvar(return_ty, &ST2F_Declare_Tempvar);
00338 Append_Token_String(lhs_tokens, W2CF_Symtab_Nameof_Tempvar(tmpvar_idx));
00339 Stab_Unlock_Tmpvar(tmpvar_idx);
00340 }
00341
00342 Prepend_Token_Special(rhs_tokens, '=');
00343 Prepend_And_Reclaim_Token_List(rhs_tokens, &lhs_tokens);
00344
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354 #define MAX_TEST_OPERATIONS 16
00355
00356
00357 typedef struct Partial_Op
00358 {
00359 OPERATOR opr;
00360 INTRINSIC intr;
00361 WN *opnd1;
00362 BOOL switch_opnds;
00363 } PARTIAL_OP;
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 typedef struct Do_Loop_Bound
00381 {
00382 OPERATOR comparison_opr;
00383 WN *opnd0;
00384 INT const0;
00385 UINT num_ops;
00386 PARTIAL_OP *op;
00387 } DO_LOOP_BOUND;
00388
00389
00390
00391
00392
00393
00394 #define WN2F_Reverse_Bounds_Comparison(comparison_opr) \
00395 (comparison_opr == OPR_GE? OPR_LE : \
00396 comparison_opr == OPR_LE? OPR_GE : \
00397 comparison_opr == OPR_GT? OPR_LT : \
00398 OPR_GT)
00399
00400
00401 static INTRINSIC
00402 WN2F_Get_Divfloor_Intr(MTYPE mtype)
00403 {
00404 INTRINSIC intr;
00405 switch (mtype)
00406 {
00407 case MTYPE_I4:
00408 intr = INTRN_I4DIVFLOOR;
00409 break;
00410 case MTYPE_U4:
00411 intr = INTRN_U4DIVFLOOR;
00412 break;
00413 case MTYPE_I8:
00414 intr = INTRN_I8DIVFLOOR;
00415 break;
00416 case MTYPE_U8:
00417 intr = INTRN_U8DIVFLOOR;
00418 break;
00419 default:
00420 intr = INTRINSIC_NONE;
00421 break;
00422 }
00423 return intr;
00424 }
00425
00426
00427 static INTRINSIC
00428 WN2F_Get_Divceil_Intr(MTYPE mtype)
00429 {
00430 INTRINSIC intr;
00431 switch (mtype)
00432 {
00433 case MTYPE_I4:
00434 intr = INTRN_I4DIVCEIL;
00435 break;
00436 case MTYPE_U4:
00437 intr = INTRN_U4DIVCEIL;
00438 break;
00439 case MTYPE_I8:
00440 intr = INTRN_I8DIVCEIL;
00441 break;
00442 case MTYPE_U8:
00443 intr = INTRN_U8DIVCEIL;
00444 break;
00445 default:
00446 intr = INTRINSIC_NONE;
00447 break;
00448 }
00449 return intr;
00450 }
00451
00452
00453 static WN *
00454 WN2F_Get_DoLoop_StepSize(WN *step, ST *idx_var, STAB_OFFSET idx_ofst)
00455 {
00456
00457
00458
00459
00460
00461
00462 WN *add;
00463 WN *step_size = NULL;
00464
00465 ASSERT_DBG_FATAL(WN_operator(step) == OPR_STID &&
00466 WN_st(step) == idx_var && WN_offset(step) == idx_ofst,
00467 (DIAG_W2F_UNEXPECTED_OPC, "WN_Get_DoLoop_StepSize"));
00468
00469 if (WN_operator(WN_kid0(step)) == OPR_ADD)
00470 {
00471 add = WN_kid0(step);
00472 if (WN_operator(WN_kid0(add)) == OPR_LDID &&
00473 WN_st(WN_kid0(add)) == idx_var)
00474 {
00475 step_size = WN_kid1(add);
00476 }
00477 else if (WN_operator(WN_kid1(add)) == OPR_LDID &&
00478 WN_st(WN_kid1(add)) == idx_var)
00479 {
00480 step_size = WN_kid0(add);
00481 }
00482 else
00483 ASSERT_DBG_WARN(FALSE,
00484 (DIAG_W2F_UNEXPECTED_OPC, "WN_Get_DoLoop_StepSize"));
00485 }
00486 else
00487 ASSERT_DBG_WARN(FALSE,
00488 (DIAG_W2F_UNEXPECTED_OPC, "WN_Get_DoLoop_StepSize"));
00489
00490 return step_size;
00491 }
00492
00493
00494 static UINT
00495 WN2F_LoopBound_VarRef(WN *wn,
00496 ST *st,
00497 STAB_OFFSET st_ofst,
00498 INT *ldid_in_kid,
00499 UINT level)
00500 {
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 UINT counter;
00527
00528 if (level >= MAX_TEST_OPERATIONS)
00529 {
00530
00531
00532
00533 counter = 0xfffffff0;
00534 }
00535 else
00536 {
00537 *ldid_in_kid = -1;
00538
00539 if (WN_operator(wn) == OPR_LDID &&
00540 WN_st(wn) == st && WN_offset(wn) == st_ofst)
00541 {
00542
00543
00544
00545 counter = 1;
00546 }
00547 else switch (WN_operator(wn))
00548 {
00549 case OPR_NEG:
00550 counter = WN2F_LoopBound_VarRef(WN_kid0(wn),
00551 st,
00552 st_ofst,
00553 ldid_in_kid+1,
00554 level++);
00555 if (counter == 1)
00556 *ldid_in_kid = 0;
00557 break;
00558
00559 case OPR_ADD:
00560 case OPR_SUB:
00561 case OPR_MPY:
00562 case OPR_DIV:
00563 counter = WN2F_LoopBound_VarRef(WN_kid0(wn),
00564 st,
00565 st_ofst,
00566 ldid_in_kid+1,
00567 level++);
00568 if (counter == 1)
00569 {
00570 counter += WN_num_var_refs(WN_kid1(wn), st, st_ofst);
00571 if (counter == 1)
00572 *ldid_in_kid = 0;
00573 }
00574 else if (counter == 0)
00575 {
00576 counter = WN2F_LoopBound_VarRef(WN_kid1(wn),
00577 st,
00578 st_ofst,
00579 ldid_in_kid+1,
00580 level++);
00581 if (counter == 1)
00582 *ldid_in_kid = 1;
00583 }
00584 else
00585 {
00586 counter += WN_num_var_refs(WN_kid1(wn), st, st_ofst);
00587 }
00588 break;
00589
00590 default:
00591
00592 counter = WN_num_var_refs(wn, st, st_ofst);
00593 break;
00594 }
00595 }
00596
00597 return counter;
00598 }
00599
00600
00601 static void
00602 WN2F_Get_Next_LoopBoundOp(PARTIAL_OP *op,
00603 OPERATOR *comp_opr,
00604 BOOL *ok,
00605 WN *wn,
00606 INT idx_kid)
00607 {
00608
00609
00610
00611
00612
00613
00614
00615 ASSERT_DBG_WARN(*comp_opr == OPR_LE || *comp_opr == OPR_GE,
00616 (DIAG_W2F_UNEXPECTED_OPC, "WN_Get_DoLoop_Bound"));
00617
00618 if (idx_kid < 0)
00619 {
00620
00621 *ok = FALSE;
00622 }
00623 else
00624 {
00625 *ok = TRUE;
00626 switch (WN_operator(wn))
00627 {
00628 case OPR_NEG:
00629
00630
00631 op->intr = INTRINSIC_NONE;
00632 op->opr = OPR_NEG;
00633 op->opnd1 = NULL;
00634 op->switch_opnds = FALSE;
00635 *comp_opr = WN2F_Reverse_Bounds_Comparison(*comp_opr);
00636 break;
00637
00638 case OPR_ADD:
00639
00640 op->intr = INTRINSIC_NONE;
00641 op->opr = OPR_SUB;
00642 op->opnd1 = WN_kid(wn, (idx_kid == 0)? 1 : 0);
00643 op->switch_opnds = FALSE;
00644 break;
00645
00646 case OPR_SUB:
00647 op->intr = INTRINSIC_NONE;
00648 if (idx_kid == 0)
00649 {
00650
00651 op->opr = OPR_ADD;
00652 op->opnd1 = WN_kid1(wn);
00653 op->switch_opnds = FALSE;
00654 }
00655 else
00656 {
00657
00658 op->opr = OPR_SUB;
00659 op->opnd1 = WN_kid0(wn);
00660 op->switch_opnds = TRUE;
00661 *comp_opr = WN2F_Reverse_Bounds_Comparison(*comp_opr);
00662 }
00663 break;
00664
00665 case OPR_MPY:
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 op->opnd1 = WN_kid(wn, (idx_kid == 0)? 1 : 0);
00683 op->switch_opnds = FALSE;
00684 if (WN_operator(op->opnd1) != OPR_INTCONST ||
00685 WN_const_val(op->opnd1) == 0)
00686 {
00687 *ok = FALSE;
00688 }
00689 else
00690 {
00691
00692
00693
00694 if (WN_const_val(op->opnd1) < 0)
00695 *comp_opr = WN2F_Reverse_Bounds_Comparison(*comp_opr);
00696
00697
00698
00699 op->opr = OPR_INTRINSIC_OP;
00700 op->intr = INTRINSIC_NONE;
00701 if (*comp_opr == OPR_LE)
00702 op->intr = WN2F_Get_Divfloor_Intr(WN_opc_rtype(wn));
00703 else
00704 op->intr = WN2F_Get_Divceil_Intr(WN_opc_rtype(wn));
00705 }
00706 break;
00707
00708 case OPR_DIV:
00709 if (idx_kid == 0)
00710 {
00711
00712 op->opr = OPR_MPY;
00713 op->opnd1 = WN_kid1(wn);
00714 op->switch_opnds = FALSE;
00715 }
00716 else
00717 {
00718
00719 op->opr = OPR_DIV;
00720 op->opnd1 = WN_kid0(wn);
00721 op->switch_opnds = TRUE;
00722 }
00723 if (WN_operator(op->opnd1) != OPR_INTCONST ||
00724 WN_const_val(op->opnd1) == 0)
00725 {
00726 *ok = FALSE;
00727 }
00728 else if (WN_const_val(op->opnd1) < 0)
00729 {
00730
00731 *comp_opr = WN2F_Reverse_Bounds_Comparison(*comp_opr);
00732 }
00733 break;
00734
00735 default:
00736 *ok = FALSE;
00737 break;
00738 }
00739 }
00740 }
00741
00742
00743 static DO_LOOP_BOUND *
00744 WN2F_Get_DoLoop_Bound(WN *end_test,
00745 ST *idx_var,
00746 STAB_OFFSET idx_ofst,
00747 WN *step_size)
00748 {
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 static PARTIAL_OP partial_op[MAX_TEST_OPERATIONS];
00760
00761 static DO_LOOP_BOUND bound = {(OPERATOR) 0,
00762 NULL,
00763 0,
00764 0,
00765 partial_op};
00766
00767 DO_LOOP_BOUND *boundp = NULL;
00768 OPERATOR comparison_opr = WN_operator(end_test);
00769 INT path_to_idx0[MAX_TEST_OPERATIONS];
00770 INT path_to_idx1[MAX_TEST_OPERATIONS];
00771 INT *path_to_idx;
00772 INT path_level;
00773 INT idx_refs0;
00774 INT idx_refs1;
00775 WN *idx_expr;
00776 BOOL bound_ok;
00777
00778 if (step_size == NULL)
00779 {
00780
00781 }
00782 else if (comparison_opr == OPR_LE ||
00783 comparison_opr == OPR_GE ||
00784 comparison_opr == OPR_LT ||
00785 comparison_opr == OPR_GT)
00786 {
00787
00788
00789
00790
00791
00792 idx_refs0 = WN2F_LoopBound_VarRef(WN_kid0(end_test),
00793 idx_var,
00794 idx_ofst,
00795 path_to_idx0,
00796 1);
00797 if (idx_refs0 <= 1)
00798 {
00799 idx_refs1 = WN2F_LoopBound_VarRef(WN_kid1(end_test),
00800 idx_var,
00801 idx_ofst,
00802 path_to_idx1,
00803 1);
00804
00805 if ((idx_refs0 + idx_refs1) == 1)
00806 {
00807
00808
00809
00810
00811
00812
00813 if (idx_refs0 == 1)
00814 {
00815
00816 bound.opnd0 = WN_kid1(end_test);
00817 idx_expr = WN_kid0(end_test);
00818 path_to_idx = path_to_idx0;
00819 }
00820 else
00821 {
00822
00823 bound.opnd0 = WN_kid0(end_test);
00824 idx_expr = WN_kid1(end_test);
00825 path_to_idx = path_to_idx1;
00826 comparison_opr = WN2F_Reverse_Bounds_Comparison(comparison_opr);
00827 }
00828
00829
00830
00831
00832
00833
00834 if (comparison_opr == OPR_LT)
00835 {
00836
00837 bound.const0 = -1;
00838 comparison_opr = OPR_LE;
00839 }
00840 else if (comparison_opr == OPR_GT)
00841 {
00842
00843 bound.const0 = 1;
00844 comparison_opr = OPR_GE;
00845 }
00846 else
00847 bound.const0 = 0;
00848
00849
00850
00851
00852 for (bound_ok = TRUE, path_level = 0;
00853 bound_ok && path_to_idx[path_level] >= 0;
00854 path_level++)
00855 {
00856 WN2F_Get_Next_LoopBoundOp(&bound.op[path_level],
00857 &comparison_opr,
00858 &bound_ok,
00859 idx_expr,
00860 path_to_idx[path_level]);
00861 idx_expr = WN_kid(idx_expr, path_to_idx[path_level]);
00862 }
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 if (bound_ok &&
00880 WN_operator(idx_expr) == OPR_LDID &&
00881 WN_st(idx_expr) == idx_var &&
00882 WN_offset(idx_expr) == idx_ofst &&
00883 (WN_operator(step_size) != OPR_INTCONST ||
00884 (WN_const_val(step_size) <= 0 && comparison_opr == OPR_GE) ||
00885 (WN_const_val(step_size) >= 0 && comparison_opr == OPR_LE)))
00886 {
00887
00888 boundp = &bound;
00889 bound.comparison_opr = comparison_opr;
00890 bound.num_ops = path_level;
00891 }
00892 }
00893 }
00894 }
00895 else
00896 ASSERT_DBG_WARN(FALSE, (DIAG_W2F_UNEXPECTED_OPC, "WN_Get_DoLoop_Bound"));
00897
00898 return boundp;
00899 }
00900
00901
00902 static WN2F_STATUS
00903 WN2F_Translate_DoLoop_Bound(TOKEN_BUFFER tokens,
00904 DO_LOOP_BOUND *bound,
00905 WN2F_CONTEXT context)
00906 {
00907
00908 TOKEN_BUFFER bound_expr = New_Token_Buffer();
00909 TOKEN_BUFFER opnd1_expr;
00910 UINT op_idx;
00911 BOOL is_intrinsic;
00912 const char *intrname;
00913 char opname;
00914
00915 WN2F_translate(bound_expr, bound->opnd0, context);
00916 if (bound->const0 != 0)
00917 {
00918 Append_Token_Special(bound_expr, '+');
00919 Append_Token_String(bound_expr, Number_as_String(bound->const0, "%lld"));
00920 }
00921 for (op_idx = 0; op_idx < bound->num_ops; op_idx++)
00922 {
00923 is_intrinsic = FALSE;
00924
00925
00926 switch (bound->op[op_idx].opr)
00927 {
00928 case OPR_NEG:
00929 opname = '-';
00930 break;
00931 case OPR_ADD:
00932 opname = '+';
00933 break;
00934 case OPR_SUB:
00935 opname = '-';
00936 break;
00937 case OPR_MPY:
00938 opname = '*';
00939 break;
00940 case OPR_DIV:
00941 opname = '/';
00942 break;
00943 case OPR_INTRINSIC_OP:
00944 is_intrinsic = TRUE;
00945 switch (bound->op[op_idx].intr)
00946 {
00947 case INTRN_I4DIVFLOOR:
00948 intrname = "INTRN_I4DIVFLOOR";
00949 break;
00950 case INTRN_I8DIVFLOOR:
00951 intrname = "INTRN_I8DIVFLOOR";
00952 break;
00953 case INTRN_U4DIVFLOOR:
00954 intrname = "INTRN_U4DIVFLOOR";
00955 break;
00956 case INTRN_U8DIVFLOOR:
00957 intrname = "INTRN_U8DIVFLOOR";
00958 break;
00959 case INTRN_I4DIVCEIL:
00960 intrname = "INTRN_I4DIVCEIL";
00961 break;
00962 case INTRN_I8DIVCEIL:
00963 intrname = "INTRN_I8DIVCEIL";
00964 break;
00965 case INTRN_U4DIVCEIL:
00966 intrname = "INTRN_U4DIVCEIL";
00967 break;
00968 case INTRN_U8DIVCEIL:
00969 intrname = "INTRN_U8DIVCEIL";
00970 break;
00971 default:
00972 ASSERT_FATAL(FALSE, (DIAG_W2F_UNEXPECTED_DOLOOP_BOUNDOP,
00973 "WN2F_Translate_DoLoop_Bound",
00974 OPERATOR_name(bound->op[op_idx].opr)));
00975 }
00976 break;
00977 default:
00978 ASSERT_FATAL(FALSE, (DIAG_W2F_UNEXPECTED_DOLOOP_BOUNDOP,
00979 "WN2F_Translate_DoLoop_Bound",
00980 OPERATOR_name(bound->op[op_idx].opr)));
00981 break;
00982 }
00983
00984 if (!is_intrinsic && bound->op[op_idx].opnd1 == NULL)
00985 {
00986 WHIRL2F_Parenthesize(bound_expr);
00987 Prepend_Token_Special(bound_expr, opname);
00988 }
00989 else
00990 {
00991
00992 opnd1_expr = New_Token_Buffer();
00993 (void)WN2F_translate(opnd1_expr, bound->op[op_idx].opnd1, context);
00994
00995
00996 if (is_intrinsic)
00997 {
00998 if (bound->op[op_idx].switch_opnds)
00999 {
01000 Prepend_Token_Special(bound_expr, ',');
01001 Prepend_And_Reclaim_Token_List(bound_expr, &opnd1_expr);
01002 }
01003 else
01004 {
01005 Append_Token_Special(bound_expr, ',');
01006 Append_And_Reclaim_Token_List(bound_expr, &opnd1_expr);
01007 }
01008 Prepend_Token_Special(bound_expr, '(');
01009 Append_Token_Special(bound_expr, ')');
01010 Prepend_Token_String(bound_expr, intrname);
01011 }
01012 else
01013 {
01014 WHIRL2F_Parenthesize(bound_expr);
01015 WHIRL2F_Parenthesize(opnd1_expr);
01016 if (bound->op[op_idx].switch_opnds)
01017 {
01018 Prepend_Token_Special(bound_expr, opname);
01019 Prepend_And_Reclaim_Token_List(bound_expr, &opnd1_expr);
01020 }
01021 else
01022 {
01023 Append_Token_Special(bound_expr, opname);
01024 Append_And_Reclaim_Token_List(bound_expr, &opnd1_expr);
01025 }
01026 }
01027 }
01028 }
01029
01030 Append_And_Reclaim_Token_List(tokens, &bound_expr);
01031 return EMPTY_WN2F_STATUS;
01032 }
01033
01034
01035
01036
01037
01038 static BOOL
01039 WN2F_Is_Loop_Region(const WN *region, WN2F_CONTEXT context)
01040 {
01041
01042
01043
01044 BOOL predicate = (WN_operator(region) == OPR_REGION);
01045
01046 if (predicate)
01047 {
01048 WN *pragma = WN_first(WN_region_pragmas(region));
01049
01050 predicate = (pragma != NULL &&
01051 (WN_pragma(pragma) == WN_PRAGMA_DOACROSS ||
01052 WN_pragma(pragma) == WN_PRAGMA_PARALLEL_DO ||
01053 WN_pragma(pragma) == WN_PRAGMA_PDO_BEGIN) &&
01054 WN_pragma_nest(pragma) <= 0 &&
01055 !Ignore_Synchronized_Construct(pragma, context));
01056 }
01057 return predicate;
01058 }
01059
01060
01061
01062
01063
01064
01065
01066 static BOOL
01067 WN2F_Is_Parallel_Region(WN *region, WN2F_CONTEXT context)
01068 {
01069 BOOL predicate = (region != NULL && WN_operator(region) == OPR_REGION);
01070
01071 if (predicate)
01072 {
01073 WN *pragma = WN_first(WN_region_pragmas(region));
01074
01075 predicate = (pragma != NULL) &&
01076 (WN_pragma(pragma) == WN_PRAGMA_PARALLEL_BEGIN ||
01077 WN_pragma(pragma) == WN_PRAGMA_MASTER_BEGIN ||
01078 WN_pragma(pragma) == WN_PRAGMA_SINGLE_PROCESS_BEGIN ||
01079 WN_pragma(pragma) == WN_PRAGMA_PSECTION_BEGIN ||
01080 WN_pragma(pragma) == WN_PRAGMA_PARALLEL_SECTIONS) &&
01081 !Ignore_Synchronized_Construct(pragma, context);
01082 }
01083 return predicate;
01084
01085 }
01086
01087
01088 static void
01089 WN2F_Prompf_Construct_Start(TOKEN_BUFFER tokens, WN *construct)
01090 {
01091 INT32 construct_id = WN_MAP32_Get(*W2F_Construct_Map, construct);
01092
01093 if (construct_id != 0)
01094 {
01095 Append_F77_Directive_Newline(tokens,sgi_comment_str);
01096 Append_Token_String(tokens, "start");
01097 Append_Token_String(tokens, Number_as_String(construct_id, "%llu"));
01098 }
01099 }
01100
01101
01102 static void
01103 WN2F_Prompf_Construct_End(TOKEN_BUFFER tokens, WN *construct)
01104 {
01105 INT32 construct_id = WN_MAP32_Get(*W2F_Construct_Map, construct);
01106
01107 if (construct_id != 0)
01108 {
01109 Append_F77_Directive_Newline(tokens, sgi_comment_str);
01110 Append_Token_String(tokens, "end");
01111 Append_Token_String(tokens, Number_as_String(construct_id, "%llu"));
01112 }
01113 }
01114
01115
01116 static void
01117 WN2F_Start_Prompf_Transformed_Loop(TOKEN_BUFFER tokens,
01118 WN *loop,
01119 WN2F_CONTEXT context)
01120 {
01121
01122
01123
01124
01125 if (!WN2F_Is_Loop_Region(W2CF_Get_Parent(W2CF_Get_Parent(loop)), context))
01126 WN2F_Prompf_Construct_Start(tokens, loop);
01127 }
01128
01129
01130 static void
01131 WN2F_End_Prompf_Transformed_Loop(TOKEN_BUFFER tokens,
01132 WN *loop,
01133 WN2F_CONTEXT context)
01134 {
01135
01136
01137
01138
01139 if (!WN2F_Is_Loop_Region(W2CF_Get_Parent(W2CF_Get_Parent(loop)), context))
01140 WN2F_Prompf_Construct_End(tokens, loop);
01141 }
01142
01143
01144 static void
01145 WN2F_Start_Prompf_Transformed_Region(TOKEN_BUFFER tokens,
01146 WN *region,
01147 WN2F_CONTEXT context)
01148 {
01149
01150
01151
01152
01153
01154 if (WN2F_Is_Loop_Region(region, context) ||
01155 WN2F_Is_Parallel_Region(region, context))
01156 WN2F_Prompf_Construct_Start(tokens, region);
01157
01158 }
01159
01160
01161 static void
01162 WN2F_End_Prompf_Transformed_Region(TOKEN_BUFFER tokens,
01163 WN *region,
01164 WN2F_CONTEXT context)
01165 {
01166
01167
01168
01169
01170
01171 if (WN2F_Is_Loop_Region(region, context) ||
01172 WN2F_Is_Parallel_Region(region, context))
01173 WN2F_Prompf_Construct_End(tokens, region);
01174
01175 }
01176
01177
01178
01179
01180
01181
01182 static void
01183 WN2F_Append_Symtab_Consts(TOKEN_BUFFER tokens,
01184 SYMTAB_IDX symtab,
01185 UINT lines_between_decls)
01186 {
01187
01188
01189
01190 #if 0
01191
01192 FOR_ALL_CONSTANTS(st, const_idx)
01193 {
01194
01195
01196 if (tokens != NULL)
01197 {
01198 Append_F77_Indented_Newline(tokens,
01199 lines_between_decls, NULL);
01200 ST2F_decl_translate(tokens, st);
01201 }
01202 else
01203 {
01204 tmp_tokens = New_Token_Buffer();
01205 Append_F77_Indented_Newline(tmp_tokens,
01206 lines_between_decls, NULL);
01207 ST2F_decl_translate(tmp_tokens, st);
01208 Write_And_Reclaim_Tokens(W2F_File[W2F_FTN_FILE],
01209 W2F_File[W2F_LOC_FILE],
01210 &tmp_tokens);
01211 }
01212 }
01213 }
01214 #endif
01215
01216 }
01217
01218
01219 struct write_st {
01220 private:
01221 TOKEN_BUFFER tokens;
01222 UINT lines_between_decls;
01223 public:
01224 write_st(TOKEN_BUFFER tb,UINT lbd) : tokens(tb), lines_between_decls(lbd) {}
01225
01226
01227
01228
01229
01230
01231
01232
01233 void operator() (UINT32 idx , ST* st) const
01234 {
01235 if (!BE_ST_w2fc_referenced(st) && !ST_has_nested_ref(st))
01236 return ;
01237
01238 BOOL dop ;
01239
01240 dop = ST_sclass(st) != SCLASS_FORMAL &&
01241 ST_sclass(st) != SCLASS_FORMAL_REF ;
01242
01243 dop &= ((ST_sym_class(st) == CLASS_VAR && !ST_is_namelist(st)) ||
01244 (ST_sym_class(st) == CLASS_FUNC)) ;
01245
01246
01247
01248
01249
01250 if (dop)
01251 {
01252 if (tokens != NULL)
01253 {
01254 Append_F77_Indented_Newline(tokens,
01255 lines_between_decls, NULL);
01256 ST2F_decl_translate(tokens, st);
01257 }
01258 else
01259 {
01260 TOKEN_BUFFER tmp_tokens;
01261
01262 tmp_tokens = New_Token_Buffer();
01263 Append_F77_Indented_Newline(tmp_tokens,
01264 lines_between_decls, NULL);
01265 ST2F_decl_translate(tmp_tokens, st);
01266 Write_And_Reclaim_Tokens(W2F_File[W2F_FTN_FILE],
01267 W2F_File[W2F_LOC_FILE],
01268 &tmp_tokens);
01269 }
01270 }
01271 }
01272 } ;
01273
01274 static void
01275 WN2F_Append_Symtab_Vars(TOKEN_BUFFER tokens,
01276 SYMTAB_IDX symtab,
01277 UINT lines_between_decls)
01278 {
01279
01280
01281
01282
01283
01284 For_all(St_Table,symtab,write_st(tokens,lines_between_decls));
01285
01286
01287 }
01288
01289 static void
01290 WN2F_Enter_PU_Block(void)
01291 {
01292 WN2F_Next_ReturnSite = PUinfo_Get_ReturnSites();
01293 WN2F_Prev_CallSite = NULL;
01294
01295 Data_Stmt_Tokens = New_Token_Buffer();
01296
01297 }
01298
01299
01300
01301
01302
01303
01304 static void
01305 WN2F_Exit_PU_Block(TOKEN_BUFFER tokens, TOKEN_BUFFER *stmts)
01306 {
01307 SYMTAB_IDX symtab;
01308 TOKEN_BUFFER decl_tokens;
01309 PU & pu = Get_Current_PU();
01310
01311
01312
01313 decl_tokens = New_Token_Buffer();
01314 WN2F_Append_Symtab_Consts(decl_tokens, CURRENT_SYMTAB, 1);
01315 if (!W2F_Purple_Emission && !Is_Empty_Token_Buffer(decl_tokens))
01316 WHIRL2F_Append_Comment(tokens, "**** Constants ****", 1, 1);
01317 Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01318
01319
01320
01321 decl_tokens = New_Token_Buffer();
01322 symtab = PU_lexical_level(pu);
01323
01324 WN2F_Append_Symtab_Vars(decl_tokens, symtab, 1);
01325 Stab_Reset_Referenced_Flag(symtab);
01326
01327 WN2F_Append_Symtab_Vars(decl_tokens, GLOBAL_SYMTAB, 1);
01328
01329 if (!W2F_Purple_Emission && !Is_Empty_Token_Buffer(decl_tokens))
01330 WHIRL2F_Append_Comment(tokens,
01331 "**** Variables and functions ****", 1, 1);
01332 Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01333
01334 Stab_Reset_Referenced_Flag(GLOBAL_SYMTAB);
01335
01336
01337
01338
01339
01340
01341
01342 if (!W2F_Purple_Emission && !Is_Empty_Token_Buffer(PUinfo_local_decls))
01343 WHIRL2F_Append_Comment(tokens, "**** Temporary variables ****",1,1);
01344 Append_And_Reclaim_Token_List(tokens, &PUinfo_local_decls);
01345
01346
01347
01348
01349 if (!W2F_Purple_Emission && !Is_Empty_Token_Buffer(Data_Stmt_Tokens))
01350 WHIRL2F_Append_Comment(tokens,
01351 "**** Initializers ****", 1, 1);
01352 Append_And_Reclaim_Token_List(tokens, &Data_Stmt_Tokens);
01353
01354 if (!W2F_Purple_Emission && !Is_Empty_Token_Buffer(PUinfo_pragmas))
01355 WHIRL2F_Append_Comment(tokens,
01356 "**** top level pragmas ****", 1, 1);
01357 Append_And_Reclaim_Token_List(tokens, &PUinfo_pragmas);
01358
01359
01360
01361
01362
01363
01364 if (W2F_Purple_Emission)
01365 {
01366
01367
01368 Append_F77_Indented_Newline(tokens, 1, NULL);
01369 Append_Token_String(tokens, "<#PRP_XSYM:INIT_DECL");
01370 WN2F_Append_Purple_Funcinfo(tokens);
01371 Append_Token_String(tokens, "#>");
01372 }
01373
01374
01375
01376 if (!W2F_Purple_Emission)
01377 WHIRL2F_Append_Comment(tokens, "**** statements ****", 1, 1);
01378 Append_And_Reclaim_Token_List(tokens, stmts);
01379
01380 if (W2F_Purple_Emission &&
01381 strcmp(W2F_Object_Name(PUINFO_FUNC_ST), WN2F_Purple_Region_Name) == 0)
01382 {
01383
01384
01385 Append_F77_Indented_Newline(tokens, 1, NULL);
01386 Append_Token_String(tokens, "<#PRP_XSYM:TEST");
01387 WN2F_Append_Purple_Funcinfo(tokens);
01388 Append_Token_String(tokens, "#>");
01389 }
01390
01391 WN2F_Next_ReturnSite = NULL;
01392 WN2F_Prev_CallSite = NULL;
01393 }
01394
01395
01396
01397
01398 void
01399 WN2F_Stmt_initialize(void)
01400 {
01401
01402 }
01403
01404
01405 void
01406 WN2F_Stmt_finalize(void)
01407 {
01408
01409 }
01410
01411
01412 BOOL
01413 WN2F_Skip_Stmt(WN *stmt)
01414 {
01415 return ((W2F_No_Pragmas && \
01416 (WN_operator(stmt) == OPR_PRAGMA ||
01417 WN_operator(stmt) == OPR_XPRAGMA) &&
01418 WN_pragma(stmt) != WN_PRAGMA_PREAMBLE_END) || \
01419
01420 WN2F_Skip_Pragma_Stmt(stmt) ||
01421
01422 (!W2F_Emit_Prefetch &&
01423 (WN_operator(stmt) == OPR_PREFETCH ||
01424 WN_operator(stmt) == OPR_PREFETCHX)) ||
01425
01426 (WN2F_Next_ReturnSite != NULL &&
01427 (stmt == RETURNSITE_store1(WN2F_Next_ReturnSite) ||
01428 stmt == RETURNSITE_store2(WN2F_Next_ReturnSite))) ||
01429
01430 (WN2F_Prev_CallSite != NULL &&
01431 (stmt == CALLSITE_store1(WN2F_Prev_CallSite) ||
01432 stmt == CALLSITE_store2(WN2F_Prev_CallSite)))
01433 );
01434 }
01435
01436
01437
01438
01439
01440 struct WN2F_emit_commons{
01441 private:
01442 TOKEN_BUFFER tokens;
01443
01444 public:
01445 WN2F_emit_commons(TOKEN_BUFFER tb) : tokens(tb) {}
01446
01447 void operator() (UINT32, ST* st) const {
01448 if (ST_sclass(st) == SCLASS_DGLOBAL)
01449 if(ST_is_initialized(st)) {
01450 if (!Has_Base_Block(st) ||
01451 ST_class(ST_base_idx(st)) == CLASS_BLOCK) {
01452 ST2F_decl_translate(tokens,st);
01453 }
01454 }
01455 }
01456 };
01457
01458
01459
01460
01461
01462
01463 void
01464 WN2F_Append_Block_Data(TOKEN_BUFFER tokens)
01465 {
01466 TOKEN_BUFFER Decl_Stmt_Tokens ;
01467
01468 Decl_Stmt_Tokens = New_Token_Buffer() ;
01469 Data_Stmt_Tokens = New_Token_Buffer() ;
01470 PUinfo_local_decls = New_Token_Buffer() ;
01471
01472 For_all(St_Table,GLOBAL_SYMTAB,WN2F_emit_commons(Decl_Stmt_Tokens)) ;
01473
01474 if (!Is_Empty_Token_Buffer(Decl_Stmt_Tokens))
01475 {
01476 Append_F77_Indented_Newline(tokens, 1, NULL);
01477 Append_Token_String(tokens, "BLOCK DATA");
01478
01479 Append_F77_Indented_Newline(tokens, 1, NULL);
01480 Append_Token_String(tokens, "IMPLICIT NONE");
01481
01482 WHIRL2F_Append_Comment(tokens, "**** Variables ****", 1, 1);
01483 Append_F77_Indented_Newline(tokens, 1, NULL);
01484 Append_And_Reclaim_Token_List(tokens, &Decl_Stmt_Tokens);
01485
01486 Append_And_Reclaim_Token_List(tokens,&PUinfo_local_decls);
01487
01488 if (!Is_Empty_Token_Buffer(Data_Stmt_Tokens))
01489 {
01490
01491 WHIRL2F_Append_Comment(tokens, "**** statements ****", 1, 1);
01492 Append_And_Reclaim_Token_List(tokens, &Data_Stmt_Tokens);
01493 }
01494
01495 Append_F77_Indented_Newline(tokens, 1, NULL) ;
01496 Append_Token_String(tokens, "END") ;
01497 Append_Token_Special(tokens, '\n');
01498 }
01499
01500 }
01501
01502 void
01503 WN2F_Append_Purple_Funcinfo(TOKEN_BUFFER tokens)
01504 {
01505 const char *name = W2F_Object_Name(PUINFO_FUNC_ST);
01506 mUINT32 id = ST_st_idx(PUINFO_FUNC_ST);
01507 ST_SCLASS sclass = ST_sclass(PUINFO_FUNC_ST);
01508 ST_EXPORT export_class = (ST_EXPORT) ST_export(PUINFO_FUNC_ST);
01509
01510 Append_Token_String(tokens, name);
01511 Append_Token_Special(tokens, ',');
01512 if (strcmp(name, WN2F_Purple_Region_Name) == 0)
01513 {
01514
01515
01516
01517 id = 0xffffffff;
01518 sclass = SCLASS_TEXT;
01519 export_class = EXPORT_INTERNAL;
01520 }
01521 Append_Token_String(tokens, Number_as_String(id, "%llu"));
01522 Append_Token_Special(tokens, ',');
01523 Append_Token_String(tokens, Number_as_String(sclass, "%lld"));
01524 Append_Token_Special(tokens, ',');
01525 Append_Token_String(tokens, Number_as_String(export_class, "%lld"));
01526 Append_Token_Special(tokens, ',');
01527 Append_Token_String(tokens, "0");
01528 }
01529
01530
01531 WN2F_STATUS
01532 WN2F_block(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01533 {
01534 WN *stmt;
01535 WN *induction_step = NULL;
01536 TOKEN_BUFFER stmt_tokens;
01537 const BOOL is_pu_block = WN2F_CONTEXT_new_pu(context);
01538 const BOOL add_induction_step = WN2F_CONTEXT_insert_induction(context);
01539
01540 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_BLOCK,
01541 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_block"));
01542
01543 if (add_induction_step)
01544 {
01545 induction_step = WN2F_CONTEXT_induction_stmt(context);
01546 reset_WN2F_CONTEXT_induction_step(context);
01547 }
01548
01549 if (is_pu_block)
01550 {
01551 WN2F_Enter_PU_Block();
01552 reset_WN2F_CONTEXT_new_pu(context);
01553 }
01554
01555
01556 stmt_tokens = New_Token_Buffer();
01557 for (stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))
01558 {
01559 if (!WN2F_Skip_Stmt(stmt))
01560 {
01561 if (induction_step != NULL &&
01562 WN_next(stmt) == NULL &&
01563 WN_operator(stmt) == OPR_LABEL)
01564 {
01565
01566 (void)WN2F_translate(stmt_tokens, induction_step, context);
01567 induction_step = NULL;
01568 }
01569 (void)WN2F_translate(stmt_tokens, stmt, context);
01570
01571
01572
01573 if (W2F_Emit_Frequency &&
01574 W2F_Frequency_Map != WN_MAP_UNDEFINED &&
01575 WN_MAP32_Get(W2F_Frequency_Map, stmt) >= 0 &&
01576 WN_operator(stmt) != OPR_REGION &&
01577 WN_operator(stmt) != OPR_PRAGMA &&
01578 WN_operator(stmt) != OPR_XPRAGMA &&
01579 WN_operator(stmt) != OPR_TRAP &&
01580 WN_operator(stmt) != OPR_ASSERT &&
01581 WN_operator(stmt) != OPR_FORWARD_BARRIER &&
01582 WN_operator(stmt) != OPR_BACKWARD_BARRIER)
01583 {
01584 INT32 freq = WN_MAP32_Get(W2F_Frequency_Map, stmt);
01585 Append_Token_String(tokens, " !FREQ=");
01586 Append_Token_String(tokens, WHIRL2F_number_as_name(freq));
01587 }
01588 }
01589 }
01590
01591
01592 if (induction_step != NULL)
01593 (void)WN2F_translate(stmt_tokens, induction_step, context);
01594
01595 if (is_pu_block)
01596 WN2F_Exit_PU_Block(tokens, &stmt_tokens);
01597 else
01598 {
01599 Append_And_Reclaim_Token_List(tokens, &stmt_tokens);
01600 }
01601 return EMPTY_WN2F_STATUS;
01602 }
01603
01604
01605 WN2F_STATUS
01606 WN2F_region(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01607 {
01608
01609
01610
01611 WN *stmt;
01612 RID *rid;
01613 BOOL good_rid;
01614
01615 Is_True(WN_operator(wn) == OPR_REGION,
01616 ("Invalid operator for WN2F_region()"));
01617
01618 Is_True(WN_operator(WN_region_body(wn)) == OPR_BLOCK,
01619 ("Expected OPR_BLOCK as body of OPR_REGION in WN2F_region()"));
01620
01621 if (W2F_Prompf_Emission)
01622 WN2F_Start_Prompf_Transformed_Region(tokens, wn, context);
01623
01624 good_rid = RID_map >= 0;
01625 if (good_rid)
01626 rid = (RID *)WN_MAP_Get(RID_map, wn);
01627 if (W2F_Emit_All_Regions ||
01628 (!W2F_No_Pragmas && good_rid &&
01629 (rid == NULL ||
01630 RID_type(rid) == RID_TYPE_pragma)))
01631 {
01632 Append_F77_Directive_Newline(tokens, "C*$*");
01633 Append_Token_String(tokens, "REGION BEGIN");
01634
01635 set_WN2F_CONTEXT_explicit_region(context);
01636
01637 if (!W2F_No_Pragmas)
01638 WN2F_pragma_list_begin(tokens,
01639 WN_first(WN_region_pragmas(wn)),
01640 context);
01641
01642 for (stmt = WN_first(WN_region_body(wn));
01643 stmt != NULL;
01644 stmt = WN_next(stmt))
01645 {
01646 if (!WN2F_Skip_Stmt(stmt))
01647 (void)WN2F_translate(tokens, stmt, context);
01648 }
01649
01650 if (!W2F_No_Pragmas)
01651 WN2F_pragma_list_end(tokens,
01652 WN_first(WN_region_pragmas(wn)),
01653 context);
01654
01655 Append_F77_Directive_Newline(tokens, "C*$*");
01656 Append_Token_String(tokens, "REGION END");
01657 }
01658 else
01659 {
01660 reset_WN2F_CONTEXT_explicit_region(context);
01661
01662
01663
01664
01665 if (!W2F_No_Pragmas)
01666 WN2F_pragma_list_begin(tokens,
01667 WN_first(WN_region_pragmas(wn)),
01668 context);
01669
01670
01671
01672
01673 for (stmt = WN_first(WN_region_body(wn));
01674 stmt != NULL;
01675 stmt = WN_next(stmt))
01676 {
01677 if (!WN2F_Skip_Stmt(stmt))
01678 (void)WN2F_translate(tokens, stmt, context);
01679 }
01680
01681
01682
01683
01684 if (!W2F_No_Pragmas)
01685 WN2F_pragma_list_end(tokens,
01686 WN_first(WN_region_pragmas(wn)),
01687 context);
01688 }
01689
01690 if (W2F_Prompf_Emission)
01691 WN2F_End_Prompf_Transformed_Region(tokens, wn, context);
01692
01693 return EMPTY_WN2F_STATUS;
01694 }
01695
01696
01697 WN2F_STATUS
01698 WN2F_compgoto(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01699 {
01700 WN *goto_stmt;
01701 INT32 goto_entry;
01702 const char *label_num;
01703
01704 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_COMPGOTO,
01705 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_compgoto"));
01706 ASSERT_DBG_FATAL(WN_operator(WN_compgoto_table(wn)) == OPR_BLOCK,
01707 (DIAG_W2F_UNEXPECTED_OPC, "WN_compgoto_table"));
01708
01709
01710 if (WN_compgoto_num_cases(wn) > 0)
01711 {
01712 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01713 Append_Token_String(tokens, "GO TO");
01714 Append_Token_Special(tokens, '(');
01715 goto_stmt = WN_first(WN_compgoto_table(wn));
01716 for (goto_entry = 0;
01717 goto_entry < WN_compgoto_num_cases(wn);
01718 goto_entry++)
01719 {
01720 ASSERT_DBG_FATAL(WN_operator(goto_stmt) == OPR_GOTO,
01721 (DIAG_W2F_UNEXPECTED_OPC, "COMPGOTO entry"));
01722 label_num = WHIRL2F_number_as_name(WN_label_number(goto_stmt));
01723 Append_Token_String(tokens, label_num);
01724 if (goto_entry+1 < WN_compgoto_num_cases(wn))
01725 Append_Token_Special(tokens, ',');
01726 goto_stmt = WN_next(goto_stmt);
01727 }
01728 Append_Token_Special(tokens, ')');
01729 Append_Token_Special(tokens, ',');
01730
01731
01732
01733
01734 (void)WN2F_translate(tokens, WN_compgoto_idx(wn), context);
01735 Append_Token_Special(tokens, '+');
01736 Append_Token_String(tokens, "1");
01737 }
01738
01739
01740 if (WN_compgoto_has_default_case(wn))
01741 WN2F_goto(tokens, WN_kid(wn,2), context);
01742
01743 return EMPTY_WN2F_STATUS;
01744 }
01745
01746
01747 WN2F_STATUS
01748 WN2F_do_loop(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01749 {
01750
01751
01752
01753
01754
01755
01756
01757 STAB_OFFSET idx_ofst;
01758 ST *idx_var;
01759 WN *step_size;
01760 DO_LOOP_BOUND *bound;
01761 WN *loop_info;
01762
01763 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_DO_LOOP,
01764 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_do_loop"));
01765 ASSERT_DBG_FATAL(WN_operator(WN_start(wn)) == OPR_STID,
01766 (DIAG_W2F_UNEXPECTED_OPC, "WN_start"));
01767 ASSERT_DBG_FATAL(WN_operator(WN_do_body(wn)) == OPR_BLOCK,
01768 (DIAG_W2F_UNEXPECTED_OPC, "WN_do_body"));
01769
01770 if (W2F_Prompf_Emission)
01771 WN2F_Start_Prompf_Transformed_Loop(tokens, wn, context);
01772
01773 loop_info = WN_do_loop_info(wn);
01774 if (W2F_Emit_Cgtag && loop_info != NULL)
01775 WHIRL2F_Append_Comment(
01776 tokens,
01777 Concat2_Strings("LOOPINFO #",
01778 WHIRL2F_number_as_name((UINTPS)loop_info)),
01779 1,
01780 1);
01781
01782
01783
01784
01785
01786 idx_var = WN_st(WN_index(wn));
01787 idx_ofst = WN_idname_offset(WN_index(wn));
01788 step_size = WN2F_Get_DoLoop_StepSize(WN_step(wn), idx_var, idx_ofst);
01789 bound = WN2F_Get_DoLoop_Bound(WN_end(wn), idx_var, idx_ofst, step_size);
01790
01791 if (bound != NULL)
01792 {
01793
01794 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01795 Append_Token_String(tokens, "DO");
01796 set_WN2F_CONTEXT_emit_stid(context);
01797 if (!WN2F_CONTEXT_no_newline(context))
01798 {
01799 set_WN2F_CONTEXT_no_newline(context);
01800 (void)WN2F_translate(tokens, WN_start(wn), context);
01801 reset_WN2F_CONTEXT_no_newline(context);
01802 }
01803 else
01804 {
01805 (void)WN2F_translate(tokens, WN_start(wn), context);
01806 }
01807 reset_WN2F_CONTEXT_emit_stid(context);
01808 Append_Token_Special(tokens, ',');
01809
01810 (void)WN2F_Translate_DoLoop_Bound(tokens, bound, context);
01811 Append_Token_Special(tokens, ',');
01812
01813 (void)WN2F_translate(tokens, step_size, context);
01814
01815 Increment_Indentation();
01816 (void)WN2F_translate(tokens, WN_do_body(wn), context);
01817 Decrement_Indentation();
01818
01819 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01820 Append_Token_String(tokens, "END DO");
01821 }
01822 else
01823 {
01824 (void)WN2F_translate(tokens, WN_start(wn), context);
01825 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01826 Append_Token_String(tokens, "DO WHILE");
01827 Append_Token_Special(tokens, '(');
01828 set_WN2F_CONTEXT_has_logical_arg(context);
01829 set_WN2F_CONTEXT_no_parenthesis(context);
01830 (void)WN2F_translate(tokens, WN_end(wn), context);
01831 reset_WN2F_CONTEXT_no_parenthesis(context);
01832 reset_WN2F_CONTEXT_has_logical_arg(context);
01833 Append_Token_Special(tokens, ')');
01834 Increment_Indentation();
01835 set_WN2F_CONTEXT_induction_step(context, WN_step(wn));
01836 (void)WN2F_translate(tokens, WN_do_body(wn), context);
01837 Decrement_Indentation();
01838 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01839 Append_Token_String(tokens, "END DO");
01840 }
01841
01842 if (W2F_Prompf_Emission)
01843 WN2F_End_Prompf_Transformed_Loop(tokens, wn, context);
01844
01845 return EMPTY_WN2F_STATUS;
01846 }
01847
01848
01849 WN2F_STATUS
01850 WN2F_implied_do(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01851 {
01852
01853
01854
01855
01856
01857
01858
01859
01860 INT kid;
01861 BOOL emitted;
01862 ST *idx_name;
01863
01864 ASSERT_DBG_FATAL(WN2F_CONTEXT_io_stmt(context) &&
01865 WN2F_CONTEXT_no_newline(context),
01866 (DIAG_W2F_UNEXPECTED_CONTEXT, "WN2F_implied_do"));
01867
01868
01869 Append_Token_Special(tokens, '(');
01870
01871
01872 for (kid = 4; kid < WN_kid_count(wn); kid++)
01873 {
01874 emitted = WN2F_io_item(tokens, WN_kid(wn, kid), context);
01875 if (emitted)
01876 Append_Token_Special(tokens, ',');
01877 }
01878
01879
01880 idx_name = WN_st(WN_index(wn));
01881 WN2F_Offset_Symref(tokens,
01882 idx_name,
01883 Stab_Pointer_To(ST_type(idx_name)),
01884 ST_type(idx_name),
01885 0,
01886 context);
01887 Append_Token_Special(tokens, '=');
01888 (void)WN2F_translate(tokens, WN_start(wn), context);
01889 Append_Token_Special(tokens, ',');
01890 (void)WN2F_translate(tokens, WN_end(wn), context);
01891 Append_Token_Special(tokens, ',');
01892 (void)WN2F_translate(tokens, WN_step(wn), context);
01893
01894
01895 Append_Token_Special(tokens, ')');
01896
01897 return EMPTY_WN2F_STATUS;
01898 }
01899
01900
01901 WN2F_STATUS
01902 WN2F_do_while(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01903 {
01904 const char *tmpvar_name;
01905 UINT tmpvar_idx;
01906 TY_IDX logical_ty;
01907
01908 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_DO_WHILE,
01909 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_do_while"));
01910
01911
01912
01913
01914
01915
01916 logical_ty = WN_Tree_Type(WN_while_test(wn));
01917
01918 if (W2F_Prompf_Emission)
01919 WN2F_Start_Prompf_Transformed_Loop(tokens, wn, context);
01920
01921 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01922 WHIRL2F_Append_Comment(tokens,
01923 "whirl2f:: DO loop with termination test after first iteration", 1, 1);
01924
01925
01926 tmpvar_idx = Stab_Lock_Tmpvar(logical_ty, &ST2F_Declare_Tempvar);
01927 tmpvar_name = W2CF_Symtab_Nameof_Tempvar(tmpvar_idx);
01928 Append_Token_String(tokens, tmpvar_name);
01929 Append_Token_Special(tokens, '=');
01930 Append_Token_String(tokens, ".TRUE.");
01931
01932
01933 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01934 Append_Token_String(tokens, "DO WHILE");
01935 Append_Token_Special(tokens, '(');
01936 Append_Token_String(tokens, tmpvar_name);
01937 Append_Token_Special(tokens, ')');
01938
01939
01940 Increment_Indentation();
01941 (void)WN2F_translate(tokens, WN_while_body(wn), context);
01942 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01943 Append_Token_String(tokens, tmpvar_name);
01944 Append_Token_Special(tokens, '=');
01945 set_WN2F_CONTEXT_has_logical_arg(context);
01946 (void)WN2F_translate(tokens, WN_while_test(wn), context);
01947 reset_WN2F_CONTEXT_has_logical_arg(context);
01948 Decrement_Indentation();
01949
01950
01951
01952
01953 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01954 Append_Token_String(tokens, "END DO");
01955 Stab_Unlock_Tmpvar(tmpvar_idx);
01956
01957 if (W2F_Prompf_Emission)
01958 WN2F_End_Prompf_Transformed_Loop(tokens, wn, context);
01959
01960 return EMPTY_WN2F_STATUS;
01961 }
01962
01963
01964 WN2F_STATUS
01965 WN2F_while_do(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01966 {
01967 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_WHILE_DO,
01968 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_while_do"));
01969
01970 if (W2F_Prompf_Emission)
01971 WN2F_Start_Prompf_Transformed_Loop(tokens, wn, context);
01972
01973
01974 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01975 Append_Token_String(tokens, "DO WHILE");
01976 Append_Token_Special(tokens, '(');
01977 set_WN2F_CONTEXT_has_logical_arg(context);
01978 set_WN2F_CONTEXT_no_parenthesis(context);
01979 (void)WN2F_translate(tokens, WN_while_test(wn), context);
01980 reset_WN2F_CONTEXT_no_parenthesis(context);
01981 reset_WN2F_CONTEXT_has_logical_arg(context);
01982 Append_Token_Special(tokens, ')');
01983
01984
01985 Increment_Indentation();
01986 (void)WN2F_translate(tokens, WN_while_body(wn), context);
01987 Decrement_Indentation();
01988
01989
01990 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01991 Append_Token_String(tokens, "END DO");
01992
01993 if (W2F_Prompf_Emission)
01994 WN2F_End_Prompf_Transformed_Loop(tokens, wn, context);
01995
01996 return EMPTY_WN2F_STATUS;
01997 }
01998
01999
02000 WN2F_STATUS
02001 WN2F_if(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02002 {
02003 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_IF,
02004 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_if"));
02005
02006
02007
02008
02009 if (WN_Is_If_Guard(wn))
02010 {
02011
02012 if (WN_operator(WN_then(wn)) != OPR_BLOCK ||
02013 WN_first(WN_then(wn)) != NULL)
02014 {
02015 WN2F_translate(tokens, WN_then(wn), context);
02016 }
02017 }
02018 else
02019 {
02020
02021 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02022 Append_Token_String(tokens, "IF");
02023 Append_Token_Special(tokens, '(');
02024 set_WN2F_CONTEXT_has_logical_arg(context);
02025 set_WN2F_CONTEXT_no_parenthesis(context);
02026 (void)WN2F_translate(tokens, WN_if_test(wn), context);
02027 reset_WN2F_CONTEXT_no_parenthesis(context);
02028 reset_WN2F_CONTEXT_has_logical_arg(context);
02029 Append_Token_Special(tokens, ')');
02030 Append_Token_String(tokens, "THEN");
02031
02032
02033 Increment_Indentation();
02034 (void)WN2F_translate(tokens, WN_then(wn), context);
02035 Decrement_Indentation();
02036
02037
02038 if (!WN_else_is_empty(wn))
02039 {
02040 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02041 Append_Token_String(tokens, "ELSE");
02042 Increment_Indentation();
02043 (void)WN2F_translate(tokens, WN_else(wn), context);
02044 Decrement_Indentation();
02045 }
02046
02047
02048 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02049 Append_Token_String(tokens, "ENDIF");
02050 }
02051
02052 return EMPTY_WN2F_STATUS;
02053 }
02054
02055
02056 WN2F_STATUS
02057 WN2F_goto(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02058 {
02059 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_GOTO ||
02060 WN_operator(wn) == OPR_REGION_EXIT,
02061 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_goto"));
02062
02063 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02064 Append_Token_String(tokens, "GO TO");
02065 Append_Token_String(tokens, WHIRL2F_number_as_name(WN_label_number(wn)));
02066
02067 return EMPTY_WN2F_STATUS;
02068 }
02069
02070
02071 WN2F_STATUS
02072 WN2F_agoto(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02073 {
02074 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_AGOTO,
02075 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_agoto"));
02076
02077 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02078 Append_Token_String(tokens, "GO TO");
02079 (void)WN2F_translate(tokens, WN_kid0(wn), context);
02080
02081 return EMPTY_WN2F_STATUS;
02082 }
02083
02084
02085 WN2F_STATUS
02086 WN2F_condbr(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02087 {
02088 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_TRUEBR ||
02089 WN_operator(wn) == OPR_FALSEBR,
02090 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_condbr"));
02091
02092 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02093 Append_Token_String(tokens, "IF");
02094 Append_Token_Special(tokens, '(');
02095 set_WN2F_CONTEXT_has_logical_arg(context);
02096 set_WN2F_CONTEXT_no_parenthesis(context);
02097 if (WN_operator(wn) == OPR_FALSEBR)
02098 {
02099 Append_Token_String(tokens, ".NOT.");
02100 Append_Token_Special(tokens, '(');
02101 (void)WN2F_translate(tokens, WN_condbr_cond(wn), context);
02102 Append_Token_Special(tokens, ')');
02103 }
02104 else
02105 {
02106 (void)WN2F_translate(tokens, WN_condbr_cond(wn), context);
02107 }
02108 reset_WN2F_CONTEXT_no_parenthesis(context);
02109 reset_WN2F_CONTEXT_has_logical_arg(context);
02110 Append_Token_Special(tokens, ')');
02111 Append_Token_String(tokens, "GO TO");
02112 Append_Token_String(tokens, WHIRL2F_number_as_name(WN_label_number(wn)));
02113
02114 return EMPTY_WN2F_STATUS;
02115 }
02116
02117 WN2F_STATUS
02118 WN2F_return(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02119 {
02120
02121
02122
02123
02124 ST *result_var =
02125 (ST *)RETURNSITE_return_var(WN2F_Next_ReturnSite);
02126 const WN *result_store = RETURNSITE_store1(WN2F_Next_ReturnSite);
02127 const STAB_OFFSET var_offset = RETURNSITE_var_offset(WN2F_Next_ReturnSite);
02128
02129 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_RETURN,
02130 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_return"));
02131
02132 ASSERT_DBG_FATAL(RETURNSITE_return(WN2F_Next_ReturnSite) == wn,
02133 (DIAG_W2F_UNEXPECTED_RETURNSITE, "WN2F_return()"));
02134
02135
02136
02137 if (PU_is_mainpu(Get_Current_PU()) ||
02138 strcmp(ST_name(WN_entry_name(PUinfo_current_func)), "MAIN__") == 0)
02139 {
02140 WN2F_Next_ReturnSite = RETURNSITE_next(WN2F_Next_ReturnSite);
02141 return EMPTY_WN2F_STATUS;
02142
02143 }
02144
02145
02146
02147 if (!PUINFO_RETURN_TO_PARAM &&
02148 PUINFO_RETURN_TY != (TY_IDX) 0 &&
02149 TY_kind(PUINFO_RETURN_TY) != KIND_VOID &&
02150 RETURN_PREG_mtype(PUinfo_return_preg, 0) != MTYPE_V)
02151 {
02152
02153
02154
02155
02156
02157 if (result_var != NULL)
02158 {
02159 if (ST_class(result_var) == CLASS_PREG ||
02160 !ST_is_return_var(result_var))
02161 {
02162
02163
02164
02165
02166 TY_IDX rv_ty = ST_type(result_var);
02167
02168 if (TY_kind(rv_ty) != KIND_STRUCT)
02169 {
02170 ASSERT_WARN(WN2F_Can_Assign_Types(rv_ty,
02171 PUINFO_RETURN_TY),
02172 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_return"));
02173 }
02174
02175
02176 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02177 ST2F_use_translate(tokens, PUINFO_FUNC_ST);
02178 Append_Token_Special(tokens, '=');
02179 if (ST_class(result_var) == CLASS_PREG)
02180 ST2F_Use_Preg(tokens, ST_type(result_var),var_offset);
02181 else
02182 WN2F_Offset_Symref(tokens,
02183 result_var,
02184 Stab_Pointer_To(ST_type(result_var)),
02185
02186 PUINFO_RETURN_TY,
02187
02188 var_offset,
02189 context);
02190 }
02191 }
02192 else if (result_store != NULL)
02193 {
02194
02195
02196
02197 ASSERT_DBG_FATAL(WN_operator(result_store) == OPR_STID,
02198 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_return"));
02199 ASSERT_WARN(WN2F_Can_Assign_Types(WN_Tree_Type(WN_kid0(result_store)),
02200 PUINFO_RETURN_TY),
02201 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_return"));
02202
02203
02204 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02205 ST2F_use_translate(tokens, PUINFO_FUNC_ST);
02206 Append_Token_Special(tokens, '=');
02207 (void)WN2F_translate(tokens, WN_kid0(result_store), context);
02208 }
02209 else if (RETURN_PREG_num_pregs(PUinfo_return_preg) == 1 &&
02210 TY_Is_Preg_Type(PUINFO_RETURN_TY))
02211 {
02212
02213
02214
02215 const MTYPE preg_mtype = RETURN_PREG_mtype(PUinfo_return_preg, 0);
02216 TY_IDX const preg_ty = Stab_Mtype_To_Ty(preg_mtype);
02217 const PREG_IDX preg_num = RETURN_PREG_offset(PUinfo_return_preg, 0);
02218
02219 ASSERT_WARN(WN2F_Can_Assign_Types(preg_ty, PUINFO_RETURN_TY),
02220 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_return"));
02221
02222 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02223 ST2F_use_translate(tokens, PUINFO_FUNC_ST);
02224 Append_Token_Special(tokens, '=');
02225 ST2F_Use_Preg(tokens, preg_ty, preg_num);
02226 }
02227 else
02228 {
02229
02230
02231
02232
02233
02234
02235
02236
02237 ASSERT_WARN(FALSE,
02238 (DIAG_UNIMPLEMENTED, "WN2F_return from two registers"));
02239 }
02240 }
02241
02242
02243 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02244 Append_Token_String(tokens, "RETURN");
02245
02246 WN2F_Next_ReturnSite = RETURNSITE_next(WN2F_Next_ReturnSite);
02247 return EMPTY_WN2F_STATUS;
02248 }
02249
02250 WN2F_STATUS
02251 WN2F_return_val(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02252 {
02253 char buf[64];
02254 Is_True(WN_operator(wn) == OPR_RETURN_VAL,
02255 ("Invalid operator for WN2F_return_val()"));
02256 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02257 ST2F_use_translate(tokens, PUINFO_FUNC_ST);
02258 Append_Token_Special(tokens, '=');
02259 (void) WN2F_translate(tokens, WN_kid0(wn), context);
02260 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02261 Append_Token_String(tokens, "RETURN");
02262 return EMPTY_WN2F_STATUS;
02263 }
02264
02265 WN2F_STATUS
02266 WN2F_label(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02267 {
02268 const char *label_num;
02269
02270 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_LABEL,
02271 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_label"));
02272
02273 label_num = WHIRL2F_number_as_name(WN_label_number(wn));
02274 WN2F_Stmt_Newline(tokens, label_num, WN_Get_Linenum(wn), context);
02275 Append_Token_String(tokens, "CONTINUE");
02276 return EMPTY_WN2F_STATUS;
02277 }
02278
02279
02280 WN2F_STATUS
02281 WN2F_intrinsic_call(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02282 {
02283 WN *arg_expr;
02284 TY_IDX arg_ty;
02285 INT str_kid, length_kid, first_length_kid;
02286 BOOL regular_call = FALSE;
02287
02288 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_INTRINSIC_CALL,
02289 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_intrinsic_call"));
02290
02291 switch (WN_intrinsic(wn))
02292 {
02293 case INTRN_CONCATEXPR:
02294 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02295
02296
02297
02298
02299 if (!WN2F_CONTEXT_io_stmt(context))
02300 {
02301 WN2F_String_Argument(tokens,
02302 WN_kid(wn,0),
02303 WN_kid(wn,1),
02304 context);
02305 Append_Token_Special(tokens, '=');
02306 }
02307
02308
02309
02310
02311 str_kid = 2;
02312 length_kid = first_length_kid = (WN_kid_count(wn) + 2)/2;
02313
02314
02315 WN2F_String_Argument(tokens,
02316 WN_kid(wn, str_kid),
02317 WN_kid(wn, length_kid),
02318 context);
02319 while ((++str_kid) < first_length_kid)
02320 {
02321 length_kid++;
02322 Append_Token_String(tokens, "//");
02323 WN2F_String_Argument(tokens,
02324 WN_kid(wn, str_kid),
02325 WN_kid(wn, length_kid),
02326 context);
02327 }
02328 break;
02329
02330 case INTRN_CASSIGNSTMT:
02331 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02332 WN2F_String_Argument(tokens,
02333 WN_kid(wn,0),
02334 WN_kid(wn,2),
02335 context);
02336 Append_Token_Special(tokens, '=');
02337 WN2F_String_Argument(tokens,
02338 WN_kid(wn,1),
02339 WN_kid(wn,3),
02340 context);
02341 break;
02342
02343 case INTRN_STOP:
02344 case INTRN_STOP_F90:
02345 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02346
02347
02348 Append_Token_String(tokens, "STOP");
02349
02350
02351
02352
02353 arg_ty = WN_Tree_Type(WN_kid0(wn));
02354 arg_expr = WN_Skip_Parm(WN_kid1(wn));
02355 ASSERT_DBG_WARN(WN_operator(arg_expr) == OPR_INTCONST ,
02356 (DIAG_W2F_UNEXPECTED_OPC,
02357 "for INTRN_STOP in WN2F_intrinsic_call"));
02358
02359
02360 if (WN_const_val(arg_expr) > 0LL)
02361 {
02362 WN2F_Offset_Memref(tokens,
02363 WN_kid0(wn),
02364 arg_ty,
02365 TY_pointed(arg_ty),
02366 0,
02367 context);
02368 }
02369 break;
02370
02371 default:
02372 regular_call = TRUE;
02373 WN2F_call(tokens, wn, context);
02374 break;
02375 }
02376
02377 if (!regular_call && !WN2F_CONTEXT_io_stmt(context))
02378 {
02379
02380 if (WN2F_Prev_CallSite == NULL)
02381 WN2F_Prev_CallSite = PUinfo_Get_CallSites();
02382 else
02383 WN2F_Prev_CallSite = CALLSITE_next(WN2F_Prev_CallSite);
02384
02385 ASSERT_DBG_FATAL(CALLSITE_call(WN2F_Prev_CallSite) == wn,
02386 (DIAG_W2F_UNEXPECTED_CALLSITE,
02387 "WN2F_intrinsic_call()"));
02388 }
02389
02390 return EMPTY_WN2F_STATUS;
02391 }
02392
02393
02394 WN2F_STATUS
02395 WN2F_call(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02396 {
02397
02398
02399
02400
02401
02402
02403
02404 INT arg_idx, implicit_args, first_arg_idx, last_arg_idx;
02405 INT total_implicit_args;
02406 TOKEN_BUFFER call_tokens = New_Token_Buffer();
02407 TY_IDX return_ty = 0 ;
02408 TY_IDX arg_ty;
02409 BOOL return_to_param;
02410 BOOL is_user_call = FALSE;
02411
02412
02413
02414 if (WN_operator(wn) == OPR_CALL || WN_operator(wn) == OPR_PICCALL)
02415 {
02416 is_user_call = TRUE;
02417 if (WN2F_CONTEXT_io_stmt(context))
02418
02419 WN2F_Callsite_Directives(WN2F_io_prefix_tokens(), wn, WN_st(wn));
02420 else
02421
02422 WN2F_Callsite_Directives(tokens, wn, WN_st(wn));
02423 }
02424
02425
02426
02427
02428 if (!WN2F_CONTEXT_io_stmt(context))
02429 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
02430
02431
02432
02433
02434 if (WN_operator(wn) == OPR_INTRINSIC_CALL)
02435 {
02436
02437
02438
02439
02440
02441 switch (WN_intrinsic(wn))
02442 {
02443 case INTRN_F4VACOS:
02444 case INTRN_F8VACOS:
02445 case INTRN_F4VASIN:
02446 case INTRN_F8VASIN:
02447 case INTRN_F4VATAN:
02448 case INTRN_F8VATAN:
02449 case INTRN_F4VCOS:
02450 case INTRN_F8VCOS:
02451 case INTRN_F4VEXP:
02452 case INTRN_F8VEXP:
02453 case INTRN_F4VLOG:
02454 case INTRN_F8VLOG:
02455 case INTRN_F4VLOG10:
02456 case INTRN_F8VLOG10:
02457 case INTRN_F4VSIN:
02458 case INTRN_F8VSIN:
02459 case INTRN_F4VSQRT:
02460 case INTRN_F8VSQRT:
02461 case INTRN_F4VTAN:
02462 case INTRN_F8VTAN:
02463
02464
02465 Append_Token_String(call_tokens,
02466 Concat2_Strings(INTRN_rt_name(WN_intrinsic(wn)),
02467 "$"));
02468 break;
02469
02470 default:
02471 Append_Token_String(call_tokens, WN_intrinsic_name((INTRINSIC)WN_intrinsic(wn)));
02472 break;
02473 }
02474 return_ty = WN_intrinsic_return_ty(WN_opcode(wn), (INTRINSIC) WN_intrinsic(wn), wn);
02475 return_to_param = WN_intrinsic_return_to_param(return_ty);
02476 first_arg_idx = (return_to_param? 1 : 0);
02477 last_arg_idx = WN_kid_count(wn) - 1;
02478 }
02479 else
02480 {
02481
02482
02483
02484 TY_IDX func_ty;
02485
02486 if (WN_operator(wn) == OPR_CALL)
02487 {
02488 ST2F_use_translate(call_tokens, WN_st(wn));
02489 func_ty = ST_pu_type(WN_st(wn));
02490 last_arg_idx = WN_kid_count(wn) - 1;
02491 }
02492 else if (WN_operator(wn) == OPR_ICALL)
02493 {
02494 (void)WN2F_translate(call_tokens,
02495 WN_kid(wn, WN_kid_count(wn) - 1),
02496 context);
02497 func_ty = WN_ty(wn);
02498 last_arg_idx = WN_kid_count(wn) - 2;
02499 }
02500 else
02501 {
02502 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_PICCALL,
02503 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_call"));
02504 ST2F_use_translate(call_tokens, WN_st(wn));
02505 func_ty = ST_type(WN_st(wn));
02506 last_arg_idx = WN_kid_count(wn) - 2;
02507 }
02508
02509 return_ty = Func_Return_Type(func_ty);
02510 return_to_param = Func_Return_To_Param(func_ty);
02511 first_arg_idx = ST2F_FIRST_PARAM_IDX(func_ty);
02512 }
02513
02514
02515
02516
02517 for (arg_idx = first_arg_idx, total_implicit_args = 0;
02518 arg_idx <= last_arg_idx - total_implicit_args;
02519 arg_idx++)
02520 {
02521 arg_ty = WN_Tree_Type(WN_kid(wn, arg_idx));
02522 if (TY_Is_Character_Reference(arg_ty) ||
02523 TY_Is_Chararray_Reference(arg_ty))
02524 {
02525 total_implicit_args++;
02526 }
02527 }
02528
02529
02530
02531
02532
02533
02534
02535
02536 Append_Token_Special(call_tokens, '(');
02537 set_WN2F_CONTEXT_no_parenthesis(context);
02538 for (arg_idx = first_arg_idx, implicit_args = 0;
02539 arg_idx <= last_arg_idx - implicit_args;
02540 arg_idx++)
02541 {
02542 arg_ty = WN_Tree_Type(WN_kid(wn, arg_idx));
02543
02544 if (WN_operator(wn) == OPR_INTRINSIC_CALL &&
02545 INTRN_by_value(WN_intrinsic(wn)))
02546 {
02547
02548
02549
02550 WN2F_translate(call_tokens, WN_kid(wn, arg_idx), context);
02551 }
02552 else if (TY_Is_Character_Reference(arg_ty))
02553 {
02554
02555
02556
02557
02558
02559
02560 INT len_idx ;
02561 INT cur_idx = arg_idx ;
02562
02563 implicit_args++;
02564
02565 if ((is_user_call) &&
02566 (cur_idx == first_arg_idx) &&
02567 (cur_idx == first_arg_idx) && (WN_kid_count(wn) >= cur_idx + 2) &&
02568 (WN_Parm_By_Value(WN_kid(wn,cur_idx + 1))) &&
02569 ((return_ty != 0) && (TY_kind(return_ty) == KIND_VOID)))
02570 {
02571 len_idx = cur_idx + 1 ;
02572 arg_idx ++ ;
02573 }
02574 else
02575 len_idx = last_arg_idx - (total_implicit_args - implicit_args);
02576
02577
02578 WN2F_String_Argument(call_tokens,
02579 WN_kid(wn, cur_idx),
02580 WN_kid(wn, len_idx),
02581 context);
02582 }
02583 else if (!TY_Is_Pointer(arg_ty) ||
02584 (WN_operator(WN_kid(wn, arg_idx)) == OPR_INTRINSIC_OP &&
02585 INTR_is_valtmp(WN_intrinsic(WN_kid(wn, arg_idx)))))
02586 {
02587
02588
02589 Append_Token_String(call_tokens, "%val");
02590 Append_Token_Special(call_tokens, '(');
02591 WN2F_translate(call_tokens, WN_kid(wn, arg_idx), context);
02592 Append_Token_Special(call_tokens, ')');
02593 }
02594 else
02595 {
02596
02597
02598
02599 if (TY_Is_Chararray_Reference(arg_ty))
02600 implicit_args++;
02601
02602
02603 WN2F_Offset_Memref(call_tokens,
02604 WN_kid(wn, arg_idx),
02605 arg_ty,
02606 TY_pointed(arg_ty),
02607 0,
02608 context);
02609 }
02610 if ((arg_idx+implicit_args) < last_arg_idx)
02611 Append_Token_Special(call_tokens, ',');
02612 }
02613 reset_WN2F_CONTEXT_no_parenthesis(context);
02614 Append_Token_Special(call_tokens, ')');
02615
02616
02617
02618
02619
02620
02621 if (!WN2F_CONTEXT_io_stmt(context))
02622 {
02623
02624 if (WN2F_Prev_CallSite == NULL)
02625 WN2F_Prev_CallSite = PUinfo_Get_CallSites();
02626 else
02627 WN2F_Prev_CallSite = CALLSITE_next(WN2F_Prev_CallSite);
02628
02629 ASSERT_DBG_FATAL(CALLSITE_call(WN2F_Prev_CallSite) == wn,
02630 (DIAG_W2F_UNEXPECTED_CALLSITE, "WN2F_call()"));
02631
02632
02633
02634
02635 if (return_ty != (TY_IDX) 0 && TY_kind(return_ty) != KIND_VOID)
02636 {
02637
02638
02639
02640
02641 ASSERT_DBG_WARN(return_to_param || first_arg_idx == 0,
02642 (DIAG_A_STRING,
02643 "WN2F_call expects first argument as kid0 "
02644 "when not returning through first argument"));
02645
02646 if (return_to_param)
02647 {
02648
02649
02650
02651 (void)WN2F_Offset_Memref(tokens,
02652 WN_kid0(wn),
02653 WN_Tree_Type(WN_kid0(wn)),
02654 return_ty,
02655 0,
02656 context);
02657 Append_Token_Special(tokens, '=');
02658 }
02659 else
02660 WN2F_Function_Call_Lhs(call_tokens,
02661 return_ty,
02662 context);
02663 }
02664 else
02665 {
02666 Prepend_Token_String(call_tokens, "CALL");
02667 }
02668 }
02669 Append_And_Reclaim_Token_List(tokens, &call_tokens);
02670
02671 return EMPTY_WN2F_STATUS;
02672 }
02673
02674
02675 WN2F_STATUS
02676 WN2F_prefetch(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02677 {
02678
02679 INT pflag;
02680
02681 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_PREFETCH ||
02682 WN_operator(wn) == OPR_PREFETCHX,
02683 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_prefetch"));
02684
02685
02686 set_WN2F_CONTEXT_deref_addr(context);
02687 Append_F77_Comment_Newline(tokens, 1, TRUE);
02688
02689
02690 if (WN_operator(wn) == OPR_PREFETCH)
02691 {
02692 Append_Token_String(tokens,
02693 Concat3_Strings("PREFETCH(", Ptr_as_String(wn), ")"));
02694
02695 (void)WN2F_translate(tokens, WN_kid0(wn), context);
02696
02697 Append_Token_String(tokens,
02698 Concat2_Strings("OFFS=", WHIRL2F_number_as_name(WN_offset(wn))));
02699 }
02700 else
02701 {
02702 Append_Token_String(tokens,
02703 Concat3_Strings("PREFETCH(", Ptr_as_String(wn),")"));
02704
02705 (void)WN2F_translate(tokens, WN_kid0(wn), context);
02706 Append_Token_Special(tokens, '+');
02707 (void)WN2F_translate(tokens, WN_kid1(wn), context);
02708 }
02709
02710
02711 pflag = WN_prefetch_flag(wn);
02712 Set_Current_Indentation(Current_Indentation()+3);
02713 Append_F77_Comment_Newline(tokens, 1, TRUE);
02714 Append_Token_String(tokens,
02715 Concat2_Strings( PF_GET_READ(pflag)? "read" : "write",
02716 Concat2_Strings( " strid1=",
02717 Concat2_Strings( WHIRL2F_number_as_name(PF_GET_STRIDE_1L(pflag)),
02718 Concat2_Strings( " strid2=",
02719 Concat2_Strings( WHIRL2F_number_as_name(PF_GET_STRIDE_2L(pflag)),
02720 Concat2_Strings(" conf=",
02721 WHIRL2F_number_as_name(PF_GET_CONFIDENCE(pflag))
02722 )))))));
02723 Set_Current_Indentation(Current_Indentation()-3);
02724
02725 return EMPTY_WN2F_STATUS;
02726 }
02727
02728
02729 WN2F_STATUS
02730 WN2F_eval(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
02731 {
02732
02733
02734
02735
02736 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_EVAL,
02737 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_eval"));
02738
02739 Append_F77_Comment_Newline(tokens, 1, TRUE);
02740 Append_Token_String(tokens, "CALL");
02741 Append_Token_String(tokens, "_EVAL");
02742 Append_Token_Special(tokens, '(');
02743 set_WN2F_CONTEXT_has_logical_arg(context);
02744 set_WN2F_CONTEXT_no_parenthesis(context);
02745 (void)WN2F_translate(tokens, WN_kid0(wn), context);
02746 Append_Token_Special(tokens, ')');
02747
02748 return EMPTY_WN2F_STATUS;
02749 }