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 #ifdef _KEEP_RCS_ID
00064
00065 #endif
00066
00067 #include <alloca.h>
00068 #include <set>
00069
00070 #include "x_string.h"
00071 #include "whirl2f_common.h"
00072 #include "PUinfo.h"
00073 #include "wn2f.h"
00074 #include "wn2f_stmt.h"
00075 #include "wn2f_pragma.h"
00076 #include "wn2f_expr.h"
00077 #include "wn2f_load_store.h"
00078 #include "wn2f_io.h"
00079 #include "st2f.h"
00080 #include "ty2f.h"
00081 #include "tcon2f.h"
00082 #include "unparse_target.h"
00083 #include "ty_ftn.h"
00084
00085 extern WN_MAP *W2F_Construct_Map;
00086 extern BOOL W2F_Prompf_Emission;
00087 char * sgi_comment_str = "CSGI$ " ;
00088
00089
00090 static BOOL PU_Need_End_Contains = FALSE;
00091 static BOOL PU_Dangling_Contains = FALSE;
00092 static INT32 PU_Host_Func_Id = 0 ;
00093
00094 WN* PU_Body=NULL;
00095
00096 static void WN2F_End_Routine_Strings(TOKEN_BUFFER tokens, INT32 func_id);
00097
00098
00099
00100
00101
00102
00103
00104 TOKEN_BUFFER Data_Stmt_Tokens = NULL;
00105
00106
00107
00108
00109
00110
00111
00112 typedef WN2F_STATUS (*WN2F_HANDLER_FUNC)(TOKEN_BUFFER, WN*, WN2F_CONTEXT);
00113
00114
00115
00116
00117
00118
00119 static WN2F_STATUS
00120 WN2F_ignore(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context);
00121 static WN2F_STATUS
00122 WN2F_unsupported(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context);
00123 static WN2F_STATUS
00124 WN2F_func_entry(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context);
00125 static WN2F_STATUS
00126 WN2F_altentry(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context);
00127 static WN2F_STATUS
00128 WN2F_comment(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context);
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 #define NUMBER_OF_OPERATORS (OPERATOR_LAST + 1)
00141 static WN2F_HANDLER_FUNC WN2F_Handler[NUMBER_OF_OPERATORS];
00142
00143 typedef struct WN2F_Opr_Handler
00144 {
00145 OPERATOR opr;
00146 WN2F_HANDLER_FUNC handler;
00147 } WN2F_OPR_HANDLER;
00148
00149 #define NUMBER_OF_OPR_HANDLERS \
00150 (sizeof(WN2F_Opr_Handler_List) / sizeof(WN2F_OPR_HANDLER))
00151
00152 static const WN2F_OPR_HANDLER WN2F_Opr_Handler_List[] =
00153 {
00154 {OPR_FUNC_ENTRY, &WN2F_func_entry},
00155 {OPR_BLOCK, &WN2F_block},
00156 {OPR_REGION_EXIT, &WN2F_goto},
00157
00158 {OPR_COMPGOTO, &WN2F_compgoto},
00159 {OPR_DO_LOOP, &WN2F_do_loop},
00160 {OPR_DO_WHILE, &WN2F_do_while},
00161 {OPR_WHILE_DO, &WN2F_while_do},
00162 {OPR_IF, &WN2F_if},
00163 {OPR_GOTO, &WN2F_goto},
00164 {OPR_AGOTO, &WN2F_agoto},
00165 {OPR_ALTENTRY, &WN2F_altentry},
00166 {OPR_FALSEBR, &WN2F_condbr},
00167 {OPR_TRUEBR, &WN2F_condbr},
00168 {OPR_RETURN, &WN2F_return},
00169 {OPR_RETURN_VAL, &WN2F_return_val},
00170 {OPR_LABEL, &WN2F_label},
00171 {OPR_ISTORE, &WN2F_istore},
00172 {OPR_PSTORE, &WN2F_pstore},
00173 {OPR_ISTOREX, &WN2F_istorex},
00174 {OPR_MSTORE, &WN2F_mstore},
00175 {OPR_STID, &WN2F_stid},
00176 {OPR_PSTID, &WN2F_pstid},
00177 {OPR_CALL, &WN2F_call},
00178 {OPR_INTRINSIC_CALL, &WN2F_intrinsic_call},
00179 {OPR_ICALL, &WN2F_call},
00180 {OPR_PICCALL, &WN2F_call},
00181 {OPR_EVAL, &WN2F_eval},
00182 {OPR_PREFETCH, &WN2F_prefetch},
00183 {OPR_PREFETCHX, &WN2F_prefetch},
00184 {OPR_PRAGMA, &WN2F_pragma},
00185 {OPR_XPRAGMA, &WN2F_pragma},
00186 {OPR_IO, &WN2F_io},
00187 {OPR_COMMENT, &WN2F_comment},
00188 {OPR_ILOAD, &WN2F_iload},
00189 {OPR_ILOADX, &WN2F_iloadx},
00190 {OPR_MLOAD, &WN2F_mload},
00191 {OPR_ARRAY, &WN2F_array},
00192
00193 {OPR_ARRAYEXP,&WN2F_arrayexp},
00194 {OPR_ARRSECTION,&WN2F_arrsection},
00195 {OPR_TRIPLET,&WN2F_triplet},
00196 {OPR_SRCTRIPLET,&WN2F_src_triplet},
00197 {OPR_WHERE,&WN2F_where},
00198 {OPR_INTRINSIC_OP, &WN2F_intrinsic_op},
00199 {OPR_TAS, &WN2F_tas},
00200 {OPR_SELECT, &WN2F_select},
00201 {OPR_CVT, &WN2F_cvt},
00202 {OPR_CVTL, &WN2F_cvtl},
00203 {OPR_NEG, &WN2F_unaryop},
00204 {OPR_ABS, &WN2F_unaryop},
00205 {OPR_SQRT, &WN2F_unaryop},
00206 {OPR_REALPART, &WN2F_realpart},
00207 {OPR_IMAGPART, &WN2F_imagpart},
00208 {OPR_PAREN, &WN2F_paren},
00209 {OPR_RND, &WN2F_unaryop},
00210 {OPR_TRUNC, &WN2F_unaryop},
00211 {OPR_CEIL, &WN2F_ceil},
00212 {OPR_FLOOR, &WN2F_floor},
00213 {OPR_BNOT, &WN2F_unaryop},
00214 {OPR_LNOT, &WN2F_unaryop},
00215 {OPR_ADD, &WN2F_binaryop},
00216 {OPR_SUB, &WN2F_binaryop},
00217 {OPR_MPY, &WN2F_binaryop},
00218 {OPR_DIV, &WN2F_binaryop},
00219 {OPR_MOD, &WN2F_binaryop},
00220 {OPR_REM, &WN2F_binaryop},
00221 {OPR_MAX, &WN2F_binaryop},
00222 {OPR_MIN, &WN2F_binaryop},
00223 {OPR_BAND, &WN2F_binaryop},
00224 {OPR_BIOR, &WN2F_binaryop},
00225 {OPR_BNOR, &WN2F_bnor},
00226 {OPR_BXOR, &WN2F_binaryop},
00227 {OPR_LAND, &WN2F_binaryop},
00228 {OPR_LIOR, &WN2F_binaryop},
00229 {OPR_CAND, &WN2F_binaryop},
00230 {OPR_CIOR, &WN2F_binaryop},
00231 {OPR_SHL, &WN2F_binaryop},
00232 {OPR_ASHR, &WN2F_ashr},
00233 {OPR_LSHR, &WN2F_lshr},
00234 {OPR_COMPLEX, &WN2F_complex},
00235 {OPR_RECIP, &WN2F_recip},
00236 {OPR_RSQRT, &WN2F_rsqrt},
00237 {OPR_MADD, &WN2F_madd},
00238 {OPR_MSUB, &WN2F_msub},
00239 {OPR_NMADD, &WN2F_nmadd},
00240 {OPR_NMSUB, &WN2F_nmsub},
00241 {OPR_EQ, &WN2F_eq},
00242 {OPR_NE, &WN2F_ne},
00243 {OPR_GT, &WN2F_binaryop},
00244 {OPR_GE, &WN2F_binaryop},
00245 {OPR_LT, &WN2F_binaryop},
00246 {OPR_LE, &WN2F_binaryop},
00247 {OPR_LDID, &WN2F_ldid},
00248 {OPR_LDA, &WN2F_lda},
00249 {OPR_CONST, &WN2F_const},
00250 {OPR_INTCONST, &WN2F_intconst},
00251 {OPR_PARM, &WN2F_parm},
00252 {OPR_TRAP, &WN2F_ignore},
00253 {OPR_ASSERT, &WN2F_ignore},
00254 {OPR_FORWARD_BARRIER, &WN2F_ignore},
00255 {OPR_BACKWARD_BARRIER, &WN2F_ignore},
00256 {OPR_ALLOCA, &WN2F_alloca},
00257 {OPR_DEALLOCA, &WN2F_dealloca},
00258 {OPR_USE, &WN2F_use_stmt},
00259 {OPR_IMPLICIT_BND, &WN2F_implicit_bnd},
00260 {OPR_NAMELIST, &WN2F_namelist_stmt},
00261 {OPR_INTERFACE, &WN2F_interface_blk},
00262 {OPR_SWITCH,&WN2F_switch},
00263 {OPR_CASEGOTO,&WN2F_casegoto},
00264 {OPR_NULLIFY,&WN2F_nullify_stmt},
00265 {OPR_ARRAY_CONSTRUCT,&WN2F_ar_construct},
00266 {OPR_IMPLIED_DO,&WN2F_noio_implied_do},
00267 {OPR_IDNAME, &WN2F_idname},
00268 {OPR_STRCTFLD, &WN2F_strctfld},
00269 {OPR_COMMA, &WN2F_comma}
00270
00271 };
00272
00273
00274
00275
00276
00277 void
00278 WN2F_Stmt_Newline(TOKEN_BUFFER tokens,
00279 const char *label,
00280 SRCPOS srcpos,
00281 WN2F_CONTEXT context)
00282 {
00283 if (WN2F_CONTEXT_no_newline(context))
00284 {
00285 if (W2F_File[W2F_LOC_FILE] != NULL)
00286 Append_Srcpos_Map(tokens, srcpos);
00287 }
00288 else
00289 {
00290 if (W2F_Emit_Linedirs)
00291 Append_Srcpos_Directive(tokens, srcpos);
00292 Append_F77_Indented_Newline(tokens, 1, label);
00293 if (W2F_File[W2F_LOC_FILE] != NULL)
00294 Append_Srcpos_Map(tokens, srcpos);
00295 }
00296 }
00297
00298
00299
00300
00301
00302
00303 static void
00304 WN2F_Begin_Prompf_Transformed_Func(TOKEN_BUFFER tokens, INT32 func_id)
00305 {
00306 Append_F77_Directive_Newline(tokens, sgi_comment_str) ;
00307 Append_Token_String(tokens, "start");
00308 Append_Token_String(tokens, Number_as_String(func_id, "%llu"));
00309 }
00310
00311 static void
00312 WN2F_End_Prompf_Transformed_Func(TOKEN_BUFFER tokens, INT32 func_id)
00313 {
00314 Append_F77_Directive_Newline(tokens, sgi_comment_str) ;
00315 Append_Token_String(tokens, "end");
00316 Append_Token_String(tokens, Number_as_String(func_id, "%llu"));
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326 class LOC_INFO{
00327
00328 private:
00329 FLD_PATH_INFO * _flds_left;
00330 STAB_OFFSET _off;
00331 BOOL _base_is_array;
00332
00333 public:
00334 WN * _nested_addr;
00335
00336 LOC_INFO(FLD_PATH_INFO * path) {
00337 _flds_left = path;
00338
00339 _off = 0;
00340 _nested_addr = NULL;
00341 _base_is_array = FALSE ;
00342 }
00343
00344 void WN2F_Find_And_Mark_Nested_Address(WN * addr);
00345 #ifdef FMZDBG
00346 void debugpathinfo(void);
00347 #endif
00348 };
00349
00350 #ifdef FMZDBG
00351 void LOC_INFO::
00352 debugpathinfo(void)
00353 {
00354 FLD_PATH_INFO *fld_path_test;
00355 fld_path_test = _flds_left;
00356 printf("****In the file LOC_INFO::debugpathinf******\n");
00357 while (fld_path_test)
00358 {
00359 printf("\t***Field name in the path is :: %s\n",
00360 FLD_name(fld_path_test->fld));
00361 if (fld_path_test->arr_wn)
00362 printf("\t***WN opr is %d \n",
00363 WN_operator(fld_path_test->arr_wn));
00364 else
00365 printf("\t***no WN find in the path\n");
00366
00367 fld_path_test = fld_path_test->next;
00368
00369 }
00370
00371 printf("****Out of the file LOC_INFO::debugpathinf******\n");
00372 }
00373 #endif
00374
00375 void LOC_INFO::
00376 WN2F_Find_And_Mark_Nested_Address(WN * addr)
00377 {
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 switch (WN_operator(addr))
00392 {
00393 case OPR_ARRAY:
00394 case OPR_ARRSECTION:
00395 {
00396 WN * kid;
00397 #if 0
00398 if (WN_operator(addr)==OPR_ARRAYEXP)
00399 addr = WN_kid0(addr);
00400 #endif
00401 kid = WN_kid0(addr);
00402 WN2F_Find_And_Mark_Nested_Address(kid);
00403 if ((_flds_left && _flds_left->arr_elt) &&
00404 (!(_base_is_array)))
00405 {
00406 _flds_left-> arr_wn = addr;
00407 _flds_left = TY2F_Point_At_Path(_flds_left,_off);
00408 }
00409 else
00410 _nested_addr = addr;
00411
00412 _base_is_array = FALSE;
00413 }
00414 break;
00415
00416
00417 case OPR_ARRAYEXP:
00418 WN * kid;
00419 kid = WN_kid0(addr);
00420 WN2F_Find_And_Mark_Nested_Address(kid);
00421 _base_is_array = FALSE;
00422 break;
00423
00424 case OPR_ADD:
00425 {
00426 WN * cnst = WN_kid0(addr);
00427 WN * othr = WN_kid1(addr);
00428
00429 if (WN_operator(cnst) != OPR_INTCONST)
00430 {
00431 cnst = WN_kid1(addr);
00432 othr = WN_kid0(addr);
00433 }
00434 WN2F_Find_And_Mark_Nested_Address(othr);
00435 _off = WN_const_val(cnst);
00436 _base_is_array = FALSE;
00437 }
00438 break;
00439
00440 case OPR_LDID:
00441 _off = 0;
00442 _nested_addr = addr;
00443 _flds_left = TY2F_Point_At_Path(_flds_left,_off);
00444 _base_is_array = ((TY_kind(WN_ty(addr)) == KIND_POINTER) &&
00445 (TY_kind(TY_pointed(WN_ty(addr))) == KIND_ARRAY));
00446 break;
00447
00448 case OPR_LDA:
00449 _off = WN_lda_offset(addr);
00450 _nested_addr = addr;
00451 _base_is_array = ((TY_kind(WN_ty(addr)) == KIND_POINTER) &&
00452 (TY_kind(TY_pointed(WN_ty(addr))) == KIND_ARRAY ||
00453 TY_is_f90_deferred_shape(TY_pointed(WN_ty(addr)))));
00454 break;
00455
00456 case OPR_ILOAD:
00457 _off = 0;
00458 _nested_addr = addr;
00459 _flds_left = TY2F_Point_At_Path(_flds_left,0);
00460 _base_is_array = ((TY_kind(WN_ty(addr)) == KIND_POINTER) &&
00461 (TY_kind(TY_pointed(WN_ty(addr))) == KIND_ARRAY));
00462 break;
00463
00464 default:
00465
00466 ASSERT_WARN((0),
00467 (DIAG_W2F_UNEXPECTED_OPC,"WN2F_Find_And_Mark_Nested_Address"));
00468
00469 break;
00470 }
00471 return;
00472 }
00473
00474
00475 extern WN_OFFSET
00476 WN2F_Sum_Offsets(WN *addr)
00477 {
00478
00479
00480
00481 BOOL sum = 0;
00482
00483 switch (WN_operator(addr))
00484 {
00485 case OPR_ARRAY:
00486 case OPR_ARRAYEXP:
00487 case OPR_ARRSECTION:
00488 sum += WN2F_Sum_Offsets(WN_kid0(addr));
00489 break;
00490
00491 case OPR_ADD:
00492 sum += WN2F_Sum_Offsets(WN_kid0(addr));
00493 sum += WN2F_Sum_Offsets(WN_kid1(addr));
00494 break;
00495
00496 case OPR_INTCONST:
00497 sum = WN_const_val(addr);
00498 break;
00499 }
00500 return sum;
00501 }
00502
00503
00504 void
00505 WN2F_Address_Of(TOKEN_BUFFER tokens)
00506 {
00507 Prepend_Token_Special(tokens, '(');
00508 Prepend_Token_String(tokens, "loc%");
00509 Append_Token_Special(tokens, '(');
00510 }
00511
00512 WN2F_STATUS
00513 WN2F_Offset_Symref(TOKEN_BUFFER tokens,
00514 ST *st,
00515 TY_IDX addr_ty,
00516 TY_IDX object_ty,
00517 STAB_OFFSET offset,
00518 WN2F_CONTEXT context)
00519 {
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 TY_IDX base_ty = TY_pointed(addr_ty);
00540 const BOOL deref_val = WN2F_CONTEXT_deref_addr(context);
00541 BOOL deref_fld;
00542 void (*translate_var_ref)(TOKEN_BUFFER, ST *);
00543
00544
00545 #ifdef __USE_COMMON_BLOCK_NAME__
00546
00547
00548 if (Stab_Is_Based_At_Common_Or_Equivalence(st))
00549 {
00550 offset += ST_ofst(st);
00551 st = ST_base(st);
00552
00553 base_ty = ST_type(st);
00554 addr_ty = Stab_Pointer_To(base_ty);
00555 Set_BE_ST_w2fc_referenced(st);
00556 }
00557
00558
00559 if (ST_is_split_common(st))
00560 {
00561 #if 0
00562 offset += Stab_Full_Split_Offset(st);
00563 #endif
00564 Clear_BE_ST_w2fc_referenced(st);
00565 st = ST_full(st);
00566 Set_BE_ST_w2fc_referenced(st);
00567 base_ty = ST_type(st);
00568
00569 if (TY_is_Pointer(base_ty))
00570 base_ty = TY_pointed(base_ty);
00571
00572 if (TY_is_f90_pointer(base_ty))
00573 base_ty = TY_pointed(base_ty);
00574
00575 addr_ty = Stab_Pointer_To(base_ty);
00576 }
00577 #endif
00578
00579
00580
00581 if (deref_val &&
00582 ST_sclass(st) != SCLASS_FORMAL &&
00583 TY_Is_Pointer(ST_type(st)) && !TY_is_f90_pointer(ST_type(st)))
00584 {
00585
00586 translate_var_ref = &ST2F_deref_translate;
00587 }
00588 else
00589 {
00590
00591 translate_var_ref = &ST2F_use_translate;
00592 }
00593
00594 if (WN2F_Can_Assign_Types(base_ty, object_ty) ||
00595 (TY_kind(base_ty) == KIND_FUNCTION &&
00596 TY_kind(base_ty) == TY_kind(object_ty) &&
00597 TY_kind(object_ty) != KIND_STRUCT ))
00598 {
00599
00600
00601
00602
00603
00604 ASSERT_WARN(offset==0, (DIAG_W2F_UNEXPEXTED_OFFSET,
00605 offset, "WN2F_Offset_Symref"));
00606
00607 translate_var_ref(tokens, st);
00608 }
00609 else if (TY_Is_Array(base_ty))
00610 {
00611 ASSERT_DBG_WARN(WN2F_Can_Assign_Types(TY_AR_etype(base_ty), object_ty),
00612 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_Offset_Symref"));
00613
00614 if (TY_Is_Character_String(base_ty))
00615 {
00616 # if 0
00617 Append_Token_String(tokens, "ichar");
00618 Append_Token_Special(tokens, '(');
00619 # endif
00620 translate_var_ref(tokens, st);
00621 TY2F_Translate_ArrayElt(tokens, base_ty, offset);
00622 #if 0
00623 Append_Token_Special(tokens, ')');
00624 #endif
00625
00626 }
00627 else
00628 {
00629 translate_var_ref(tokens, st);
00630 if (!WN2F_CONTEXT_has_no_arr_elmt(context)) {
00631 TY2F_Translate_ArrayElt(tokens, base_ty, offset);
00632 reset_WN2F_CONTEXT_has_no_arr_elmt(context);
00633 }
00634 }
00635 }
00636 else
00637 {
00638
00639 #if 0 //we use OPR_STRCTFLD to get the fld_path--FMZ August 2005
00640
00641 FLD_PATH_INFO *fld_path;
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 deref_fld = (deref_val && !TY_Is_Pointer(ST_type(st)))? TRUE : FALSE;
00664 if (deref_fld)
00665 object_ty = Stab_Pointer_To(object_ty);
00666
00667 fld_path = TY2F_Get_Fld_Path(base_ty, object_ty, offset);
00668
00669 if (fld_path == NULL)
00670 {
00671
00672
00673
00674
00675 if (ST_is_return_var(st))
00676 (void)translate_var_ref(tokens, st);
00677 else
00678 {
00679 ASSERT_DBG_WARN(FALSE,
00680 (DIAG_W2F_NONEXISTENT_FLD_PATH,
00681 "WN2F_Offset_Symref"));
00682 Append_Token_String(tokens, "SOMEWHERE_IN");
00683 Append_Token_Special(tokens, '(');
00684 (void)translate_var_ref(tokens, st);
00685 Append_Token_Special(tokens, ')');
00686 }
00687 }
00688 else
00689 {
00690
00691 {
00692
00693
00694
00695
00696 (void)translate_var_ref(tokens, st);
00697 TY2F_Fld_Separator(tokens);
00698 }
00699 # if 0
00700 if (Stab_Is_Equivalence_Block(st) &&
00701 (ST_is_return_var(st) ||
00702 (PUinfo_current_func != NULL &&
00703 (PUINFO_RETURN_TO_PARAM && st == PUINFO_RETURN_PARAM))))
00704 TY2F_Translate_Fld_Path(tokens, fld_path,
00705 deref_fld,FALSE, TRUE,context);
00706 else
00707 # endif
00708
00709 TY2F_Translate_Fld_Path(tokens, fld_path,
00710 deref_fld,
00711
00712
00713 FALSE ,
00714 FALSE,
00715 context);
00716
00717 TY2F_Free_Fld_Path(fld_path);
00718 }
00719 #else
00720 (void)translate_var_ref(tokens, st);
00721 #endif
00722
00723 }
00724
00725 return EMPTY_WN2F_STATUS;
00726 }
00727
00728
00729 WN2F_STATUS
00730 WN2F_Offset_Memref(TOKEN_BUFFER tokens,
00731 WN *addr,
00732 TY_IDX addr_ty,
00733 TY_IDX object_ty,
00734 STAB_OFFSET offset,
00735 WN2F_CONTEXT context)
00736 {
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 const BOOL deref_fld = WN2F_CONTEXT_deref_addr(context);
00760
00761
00762 set_WN2F_CONTEXT_deref_addr(context);
00763
00764 if (WN2F_Is_Address_Preg(addr,addr_ty))
00765 {
00766
00767
00768
00769
00770 (void)WN2F_translate(tokens, addr, context);
00771
00772 if (offset != 0)
00773 {
00774 Append_Token_Special(tokens, '+');
00775 Append_Token_String(tokens, Number_as_String(offset, "%lld"));
00776 }
00777 }
00778 else
00779 {
00780
00781 TY_IDX base_ty = TY_pointed(addr_ty);
00782
00783
00784
00785
00786 if (TY_Is_Array(base_ty) &&
00787 TY_is_f90_deferred_shape(base_ty) &&
00788 !TY_Is_Array(object_ty) )
00789 base_ty = TY_AR_etype(base_ty);
00790
00791 if (WN2F_Can_Assign_Types(base_ty, object_ty))
00792 {
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 ASSERT_WARN(offset==0, (DIAG_W2F_UNEXPEXTED_OFFSET,
00809 offset, "WN2F_Offset_Memref"));
00810
00811 (void)WN2F_translate(tokens, addr, context);
00812 }
00813 else
00814 {
00815 if (TY_Is_Array(base_ty))
00816 {
00817 ASSERT_DBG_WARN(WN2F_Can_Assign_Types(TY_AR_etype(base_ty),
00818 object_ty),
00819 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_Offset_Memref"));
00820
00821 if (TY_Is_Character_String(base_ty))
00822 {
00823 # if 0
00824 Append_Token_String(tokens, "ichar");
00825 Append_Token_Special(tokens, '(');
00826 # endif
00827 (void)WN2F_translate(tokens, addr, context);
00828 # if 0
00829 Append_Token_Special(tokens, ')');
00830 # endif
00831
00832 }
00833 else
00834 {
00835 (void)WN2F_translate(tokens, addr, context);
00836 }
00837 }
00838
00839 else if ((WN_opc_operator(addr) == OPR_LDA ||
00840 WN_opc_operator(addr) == OPR_LDID) &&
00841 (TY_kind(base_ty) != KIND_STRUCT) &&
00842 (Stab_Is_Common_Block(WN_st(addr)) ||
00843 Stab_Is_Equivalence_Block(WN_st(addr))))
00844 {
00845
00846
00847
00848
00849 ASSERT_WARN(WN2F_Can_Assign_Types(ST_type(WN_st(addr)), base_ty) ,
00850 (DIAG_W2F_INCOMPATIBLE_TYS, "WN2F_Offset_Symref"));
00851
00852 if (WN_opc_operator(addr) == OPR_LDA)
00853 reset_WN2F_CONTEXT_deref_addr(context);
00854 (void)WN2F_Offset_Symref(tokens,
00855 WN_st(addr),
00856 addr_ty,
00857 object_ty,
00858 offset + WN_lda_offset(addr),
00859 context);
00860 }
00861
00862 else
00863 {
00864
00865
00866
00867
00868 FLD_PATH_INFO *fld_path;
00869
00870
00871
00872
00873
00874
00875
00876 WN_OFFSET tmp = WN2F_Sum_Offsets(addr);
00877
00878 if (tmp < TY_size(TY_pointed(addr_ty)))
00879 offset += tmp;
00880 else
00881 offset = tmp;
00882
00883 if (WN_operator(addr)==OPR_ARRAYEXP)
00884 addr = WN_kid0(addr);
00885
00886 fld_path = TY2F_Get_Fld_Path(base_ty, object_ty, offset);
00887
00888 #ifdef FMZDBG
00889 {
00890 FLD_PATH_INFO *fld_path_test;
00891 fld_path_test = fld_path;
00892 while (fld_path_test)
00893 {
00894 printf("\t***Field name in the path is :: %s\n",
00895 FLD_name(fld_path_test->fld));
00896 if (fld_path_test->arr_wn)
00897 printf("\t***WN opr is %d \n",
00898 WN_operator(fld_path_test->arr_wn));
00899 else
00900 printf("\t***no WN found in the path\n");
00901
00902 fld_path_test = fld_path_test->next;
00903
00904 }
00905 }
00906 #endif
00907
00908 ASSERT_DBG_WARN(fld_path != NULL,
00909 (DIAG_W2F_NONEXISTENT_FLD_PATH,
00910 "WN2F_Offset_Memref"));
00911
00912
00913
00914
00915
00916
00917
00918 LOC_INFO det(fld_path);
00919 #ifdef FMZDBG
00920 det.debugpathinfo();
00921 #endif
00922 det.WN2F_Find_And_Mark_Nested_Address(addr);
00923 #ifdef FMZDBG
00924 det.debugpathinfo();
00925 #endif
00926 addr = det._nested_addr;
00927
00928
00929 (void)WN2F_translate(tokens, addr, context);
00930
00931
00932 #if 0
00933 if (fld_type_z && offset_add) {
00934 fld_path = TY2F_Get_Fld_Path(fld_type_z, fld_type_z, offset_add);
00935 }
00936 #endif
00937
00938 #ifdef FMZDBG
00939 {
00940 FLD_PATH_INFO *fld_path_test;
00941 fld_path_test = fld_path;
00942 while (fld_path_test)
00943 {
00944 printf("\t***Field name in the path is :: %s\n",
00945 FLD_name(fld_path_test->fld));
00946 if (fld_path_test->arr_wn)
00947 printf("\t***WN opr is %d \n",
00948 WN_operator(fld_path_test->arr_wn));
00949 else
00950 printf("\t***no WN find in the path\n");
00951
00952 fld_path_test = fld_path_test->next;
00953 }
00954 }
00955 #endif
00956
00957 if (fld_path != NULL)
00958 {
00959 TY2F_Fld_Separator(tokens);
00960 TY2F_Translate_Fld_Path(tokens,
00961 fld_path,
00962 deref_fld,
00963 FALSE,
00964 FALSE,
00965 context);
00966 #if 0
00967 }
00968 }
00969 fld_type_z = FLD_type(fld_path->fld);
00970 #endif
00971 TY2F_Free_Fld_Path(fld_path);
00972 }
00973 else
00974 {
00975 Append_Token_String(tokens,
00976 Number_as_String(offset,
00977 "<field-at-offset=%lld>"));
00978 }
00979
00980 }
00981
00982 }
00983 }
00984
00985 return EMPTY_WN2F_STATUS;
00986 }
00987
00988
00989
00990
00991 void
00992 WN2F_Entry_Point(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
00993 {
00994
00995
00996
00997
00998
00999 ST **param_st;
01000 INT param, num_formals;
01001
01002 ASSERT_DBG_FATAL(WN_opcode(wn) == OPC_ALTENTRY ||
01003 WN_opcode(wn) == OPC_FUNC_ENTRY,
01004 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_Entry_Point"));
01005
01006 if (WN_opcode(wn) == OPC_ALTENTRY)
01007 num_formals = WN_kid_count(wn);
01008 else
01009 num_formals = WN_num_formals(wn);
01010
01011
01012 param_st = (ST **)alloca((num_formals + 1) * sizeof(ST *));
01013 for (param = 0; param < num_formals; param++)
01014 {
01015 param_st[param] = WN_st(WN_formal(wn, param));
01016 }
01017
01018 param_st[num_formals] = NULL;
01019
01020
01021
01022
01023
01024 ST2F_func_header(tokens,
01025 &St_Table[WN_entry_name(wn)],
01026 param_st,
01027 num_formals,
01028 WN_opcode(wn) == OPC_ALTENTRY);
01029
01030 }
01031
01032
01033
01034
01035
01036
01037 static WN2F_STATUS
01038 WN2F_ignore(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01039 {
01040 return EMPTY_WN2F_STATUS;
01041 }
01042
01043
01044 static WN2F_STATUS
01045 WN2F_unsupported(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01046 {
01047
01048
01049 ASSERT_WARN(FALSE,
01050 (DIAG_W2F_CANNOT_HANDLE_OPC, WN_opc_name(wn), WN_opcode(wn)));
01051
01052 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(wn), context);
01053 Append_Token_String(tokens, Concat3_Strings("<", WN_opc_name(wn), ">"));
01054
01055 return EMPTY_WN2F_STATUS;
01056 }
01057
01058
01059 static WN2F_STATUS
01060 WN2F_func_entry(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01061 {
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 INT32 func_id = 0;
01073
01074 ASSERT_DBG_FATAL(WN_opcode(wn) == OPC_FUNC_ENTRY,
01075 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_func_entry"));
01076
01077
01078
01079 if (W2F_Prompf_Emission) {
01080 func_id = WN_MAP32_Get(*W2F_Construct_Map, wn);
01081 WN2F_Begin_Prompf_Transformed_Func(tokens, func_id);
01082 }
01083
01084
01085
01086
01087 PUinfo_local_decls_indent = Current_Indentation();
01088
01089 PU_Body=WN_func_body(wn);
01090
01091
01092 WN2F_Entry_Point(tokens, wn, context);
01093
01094
01095 if (!W2F_No_Pragmas)
01096 WN2F_pragma_list_begin(PUinfo_pragmas,
01097 WN_first(WN_func_pragmas(wn)),
01098 context);
01099
01100 set_WN2F_CONTEXT_new_pu(context);
01101 (void)WN2F_translate(tokens, WN_func_body(wn), context);
01102
01103
01104
01105
01106 if (!W2F_No_Pragmas)
01107 WN2F_pragma_list_end(tokens,
01108 WN_first(WN_func_pragmas(wn)),
01109 context);
01110
01111 WN2F_Stmt_Newline(tokens,NULL, WN_Get_Linenum(wn), context);
01112
01113 WN2F_End_Routine_Strings(tokens,func_id);
01114
01115 return EMPTY_WN2F_STATUS;
01116 }
01117
01118 WN2F_STATUS
01119 WN2F_altentry(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01120 {
01121
01122
01123
01124 ASSERT_DBG_FATAL(WN_opcode(wn) == OPC_ALTENTRY,
01125 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_altentry"));
01126
01127
01128 WN2F_Entry_Point(tokens, wn, context);
01129
01130 return EMPTY_WN2F_STATUS;
01131 }
01132
01133
01134 WN2F_STATUS
01135 WN2F_comment(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01136 {
01137 ASSERT_DBG_FATAL(WN_opcode(wn) == OPC_COMMENT,
01138 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_comment"));
01139
01140
01141
01142
01143 static char* avoid[] = {
01144 "ENDLOOP",
01145
01146
01147 "read", "write", "print"
01148 };
01149 static int avoidSZ = sizeof(avoid) / sizeof(char*);
01150
01151 const char* com = Index_To_Str(WN_GetComment(wn));
01152
01153 for (int i = 0; i < avoidSZ; ++i) {
01154 const char* str = avoid[i];
01155 if (ux_strncasecmp(com, str, strlen(str)) == 0) {
01156 return EMPTY_WN2F_STATUS;
01157 }
01158 }
01159
01160 WHIRL2F_Append_Comment(tokens, com, 0, 0);
01161
01162 return EMPTY_WN2F_STATUS;
01163 }
01164
01165
01166
01167
01168
01169
01170 void
01171 WN2F_initialize(void)
01172 {
01173 INT opr;
01174 INT map;
01175
01176
01177 for (opr = 0; opr < NUMBER_OF_OPERATORS; opr++)
01178 WN2F_Handler[opr] = &WN2F_unsupported;
01179
01180
01181 for (map = 0; map < NUMBER_OF_OPR_HANDLERS; map++)
01182 WN2F_Handler[WN2F_Opr_Handler_List[map].opr] =
01183 WN2F_Opr_Handler_List[map].handler;
01184
01185 WN2F_Stmt_initialize();
01186 WN2F_Expr_initialize();
01187 WN2F_Load_Store_initialize();
01188 WN2F_Io_initialize();
01189
01190 }
01191
01192
01193 void
01194 WN2F_finalize(void)
01195 {
01196
01197
01198
01199 WN2F_Stmt_finalize();
01200 WN2F_Expr_finalize();
01201 WN2F_Load_Store_finalize();
01202 WN2F_Io_finalize();
01203 Stab_Free_Tmpvars();
01204 }
01205
01206
01207
01208 void
01209 WN2F_dump_context( WN2F_CONTEXT c)
01210 {
01211 printf ("(");
01212
01213 if (WN2F_CONTEXT_new_pu(c)) printf (" new_pu") ;
01214 if (WN2F_CONTEXT_insert_induction(c)) printf (" induct_tmp_reqd") ;
01215 if (WN2F_CONTEXT_deref_addr(c)) printf (" deref") ;
01216 if (WN2F_CONTEXT_no_newline(c)) printf (" no_newline") ;
01217 if (WN2F_CONTEXT_has_logical_arg(c)) printf (" logical_arg") ;
01218 if (WN2F_CONTEXT_no_parenthesis(c)) printf (" no_paren") ;
01219 if (WN2F_CONTEXT_keyword_ioctrl(c)) printf (" ioctrl") ;
01220 if (WN2F_CONTEXT_io_stmt(c)) printf (" in_io") ;
01221 if (WN2F_CONTEXT_deref_io_item(c)) printf (" deref_io") ;
01222 if (WN2F_CONTEXT_origfmt_ioctrl(c)) printf (" varfmt") ;
01223 if (WN2F_CONTEXT_emit_stid(c)) printf (" emit_stid") ;
01224 if (WN2F_CONTEXT_explicit_region(c)) printf (" region_pragma") ;
01225 if (WN2F_CONTEXT_fmt_io(c)) printf (" formatted io") ;
01226 if (WN2F_CONTEXT_cray_io(c)) printf (" craylib") ;
01227 printf (")\n");
01228 }
01229
01230
01231 WN2F_STATUS
01232 WN2F_translate(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context)
01233 {
01234 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context);
01235
01236
01237
01238
01239
01240
01241 if (OPCODE_is_boolean(WN_opcode(wn)) &&
01242 WN2F_expr_has_boolean_arg(WN_opcode(wn)))
01243 {
01244
01245
01246
01247 set_WN2F_CONTEXT_has_logical_arg(context);
01248 }
01249 else if (WN2F_CONTEXT_has_logical_arg(context))
01250 {
01251
01252
01253
01254
01255
01256 reset_WN2F_CONTEXT_has_logical_arg(context);
01257 set_WN2F_CONTEXT_is_logical_arg(context);
01258 }
01259 else
01260 {
01261 reset_WN2F_CONTEXT_has_logical_arg(context);
01262 reset_WN2F_CONTEXT_is_logical_arg(context);
01263 }
01264
01265
01266
01267 OPERATOR op = WN_opc_operator(wn);
01268 WN2F_STATUS ret = WN2F_Handler[WN_opc_operator(wn)](tokens, wn, context);
01269
01270
01271 reset_WN2F_CONTEXT_has_logical_arg(context);
01272
01273 return ret;
01274 }
01275
01276 WN2F_STATUS
01277 WN2F_translate_purple_main(TOKEN_BUFFER tokens,
01278 WN *pu,
01279 const char *region_name,
01280 WN2F_CONTEXT context)
01281 {
01282 static const char prp_return_var_name[] = "prp___return";
01283 extern BOOL Use_Purple_Array_Bnds_Placeholder;
01284
01285 TY_IDX return_ty;
01286 ST *param_st;
01287 INT first_param, param, implicit_parms = 0;
01288
01289 ASSERT_DBG_FATAL(WN_opcode(pu) == OPC_FUNC_ENTRY,
01290 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_translate_purple_main"));
01291
01292
01293
01294 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01295 Append_Token_String(tokens, "PROGRAM MAIN");
01296
01297 # if 0
01298 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01299 Append_Token_String(tokens, "IMPLICIT NONE");
01300 # endif
01301
01302
01303
01304 Use_Purple_Array_Bnds_Placeholder = TRUE;
01305 first_param = ST2F_FIRST_PARAM_IDX(ST_type(WN_entry_name(pu)));
01306 for (param = first_param;
01307 (param+implicit_parms) < WN_num_formals(pu);
01308 param++)
01309 {
01310 param_st = WN_st(WN_formal(pu, param));
01311 if (STAB_PARAM_HAS_IMPLICIT_LENGTH(param_st))
01312 implicit_parms++;
01313
01314 Append_F77_Indented_Newline(tokens, 1, NULL);
01315
01316 ST2F_decl_translate(tokens, param_st);
01317 Append_F77_Indented_Newline(tokens, 1, NULL);
01318 Append_Token_String(tokens, "SAVE");
01319 Append_Token_String(tokens, W2CF_Symtab_Nameof_St(param_st));
01320
01321 }
01322 Use_Purple_Array_Bnds_Placeholder = FALSE;
01323
01324
01325
01326
01327
01328
01329 return_ty = W2X_Unparse_Target->Func_Return_Type(ST_type(WN_entry_name(pu)));
01330 if (return_ty != (TY_IDX) 0 && TY_kind(return_ty) != KIND_VOID)
01331 {
01332 TOKEN_BUFFER return_tokens = New_Token_Buffer();
01333
01334
01335
01336 Append_Token_String(return_tokens, region_name);
01337 if (TY_Is_Pointer(return_ty))
01338 TY2F_translate(return_tokens,
01339 Stab_Mtype_To_Ty(TY_mtype(return_ty)));
01340 else
01341 TY2F_translate(return_tokens, return_ty);
01342
01343 Append_F77_Indented_Newline(tokens, 1, NULL);
01344 Append_Token_String(tokens, "EXTERNAL");
01345 Append_Token_String(tokens, region_name);
01346 Append_F77_Indented_Newline(tokens, 1, NULL);
01347 Append_And_Reclaim_Token_List(tokens, &return_tokens);
01348
01349
01350
01351 return_tokens = New_Token_Buffer();
01352 Append_Token_String(return_tokens, prp_return_var_name);
01353 if (TY_Is_Pointer(return_ty))
01354 TY2F_translate(return_tokens,
01355 Stab_Mtype_To_Ty(TY_mtype(return_ty)));
01356 else
01357 TY2F_translate(return_tokens, return_ty);
01358
01359 Append_F77_Indented_Newline(tokens, 1, NULL);
01360 Append_And_Reclaim_Token_List(tokens, &return_tokens);
01361 }
01362
01363
01364
01365 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01366 Append_Token_String(tokens, "<#PRP_XSYM:INIT_PARAM");
01367 WN2F_Append_Purple_Funcinfo(tokens);
01368 Append_Token_String(tokens, "#>");
01369
01370
01371
01372 WHIRL2F_Append_Comment(tokens,
01373 "**** Call to extracted purple region ****",
01374 1, 1);
01375 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01376 if (return_ty != (TY_IDX) 0 && TY_kind(return_ty) != KIND_VOID)
01377 {
01378 Append_Token_String(tokens, prp_return_var_name);
01379 Append_Token_Special(tokens, '=');
01380 }
01381 else
01382 Append_Token_String(tokens, "CALL");
01383 Append_Token_String(tokens, region_name);
01384 Append_Token_Special(tokens, '(');
01385 for (param = first_param;
01386 (param+implicit_parms) < WN_num_formals(pu);
01387 param++)
01388 {
01389 if (param > first_param)
01390 Append_Token_Special(tokens, ',');
01391
01392 param_st = WN_st(WN_formal(pu, param));
01393 Append_Token_String(tokens, W2CF_Symtab_Nameof_St(param_st));
01394 }
01395 Append_Token_Special(tokens, ')');
01396
01397
01398
01399 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01400 Append_Token_String(tokens, "<#PRP_XSYM:TEST_PARAM");
01401 WN2F_Append_Purple_Funcinfo(tokens);
01402 Append_Token_String(tokens, "#>");
01403
01404 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01405 Append_Token_String(tokens, "END");
01406 Append_Token_String(tokens, "!");
01407 Append_Token_String(tokens, "MAIN");
01408 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01409 WN2F_Stmt_Newline(tokens, NULL, WN_Get_Linenum(pu), context);
01410
01411 return EMPTY_WN2F_STATUS;
01412 }
01413
01414
01415
01416
01417
01418 extern void
01419 WN2F_Emit_End_Stmt(TOKEN_BUFFER tokens, BOOL start)
01420 {
01421
01422
01423
01424
01425
01426 if (PU_Need_End_Contains)
01427 {
01428 if (start)
01429 {
01430 if(PU_Dangling_Contains)
01431 {
01432 PU_Dangling_Contains = FALSE;
01433 Append_Token_String(tokens,"CONTAINS");
01434 if (W2F_Prompf_Emission)
01435 WN2F_End_Prompf_Transformed_Func(tokens, PU_Host_Func_Id);
01436 Append_Token_Special(tokens, '\n');
01437 }
01438 }
01439 else
01440 {
01441 PU_Need_End_Contains = FALSE;
01442 if (Is_Empty_Token_Buffer(tokens))
01443 Append_F77_Indented_Newline(tokens,0,NULL);
01444 Append_Token_String(tokens,"END");
01445
01446
01447
01448
01449 if (W2F_Prompf_Emission && PU_Dangling_Contains)
01450 WN2F_End_Prompf_Transformed_Func(tokens, PU_Host_Func_Id);
01451 Append_Token_Special(tokens,'\n');
01452 }
01453 }
01454 }
01455
01456 static void
01457 WN2F_End_Routine_Strings(TOKEN_BUFFER tokens, INT32 func_id)
01458 {
01459
01460
01461
01462
01463
01464
01465 PU & pu = Pu_Table[ST_pu(PUINFO_FUNC_ST)];
01466
01467 if (WN2F_F90_pu) {
01468 if (PU_has_nested(pu) )
01469 {
01470 PU_Need_End_Contains = TRUE;
01471 PU_Dangling_Contains = TRUE;
01472 PU_Host_Func_Id = func_id;
01473 }
01474 else {
01475
01476 char * p ;
01477
01478 if (PU_is_mainpu(pu))
01479 p = "END PROGRAM";
01480
01481 else {
01482 TY_IDX rt = PUINFO_RETURN_TY;
01483
01484 if (TY_kind(rt) == KIND_VOID) {
01485 if (ST_is_in_module(PUINFO_FUNC_ST) && !PU_is_nested_func(pu))
01486 p = "END MODULE";
01487 else
01488 if (ST_is_block_data(PUINFO_FUNC_ST))
01489 p = "END BLOCK DATA";
01490 else
01491 p = "END SUBROUTINE";
01492 }
01493 else
01494 p = "END FUNCTION";
01495 }
01496 Append_Token_String(tokens,p);
01497
01498 if (W2F_Prompf_Emission)
01499 WN2F_End_Prompf_Transformed_Func(tokens,func_id);
01500
01501 Append_Token_Special(tokens, '\n');
01502 }
01503
01504 } else {
01505
01506 Append_Token_String(tokens, "END");
01507 Append_Token_String(tokens, "!");
01508 Append_Token_String(tokens, PUINFO_FUNC_NAME) ;
01509
01510 if (W2F_Prompf_Emission)
01511 WN2F_End_Prompf_Transformed_Func(tokens,func_id);
01512
01513 Append_Token_Special(tokens, '\n');
01514 Append_Token_Special(tokens, '\n');
01515 }
01516 }
01517