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