Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 12-Apr-95 - Original Version 00042 * 00043 * Description: 00044 * 00045 * Translate a WN load/store subtree to Fortran by means of an inorder 00046 * recursive descent traversal of the WHIRL IR. Note that the routines 00047 * handle statements and expressions are in separate source files. 00048 * Recursive translation of WN nodes should only use WN2F_Translate()! 00049 * 00050 * ==================================================================== 00051 * ==================================================================== 00052 */ 00053 00054 #ifdef _KEEP_RCS_ID 00055 /*REFERENCED*/ 00056 #endif 00057 00058 #include <climits> 00059 00060 #include "whirl2f_common.h" 00061 #include "PUinfo.h" /* In be/whirl2c directory */ 00062 #include "pf_cg.h" 00063 #include "wn2f.h" 00064 #include "st2f.h" 00065 #include "ty2f.h" 00066 #include "tcon2f.h" 00067 #include "wn2f_load_store.h" 00068 #include "ty_ftn.h" 00069 00070 #define DEB_Whirl2f_IR_TY_WN2F_Arrsection_Slots 0 00071 #define DEB_Whirl2f_IR_TY_WN2F_Arrsection_Slots_st1 0 00072 00073 extern BOOL W2F_Only_Mark_Loads; /* Defined in w2f_driver.c */ 00074 static void WN2F_Block(TOKEN_BUFFER tokens, ST * st, STAB_OFFSET off,WN2F_CONTEXT context) ; 00075 00076 static WN *WN2F_ZeroInt_Ptr = NULL; 00077 static WN *WN2F_OneInt_Ptr = NULL; 00078 TY_IDX fld_type_z = 0; 00079 00080 #define WN2F_INTCONST_ZERO\ 00081 (WN2F_ZeroInt_Ptr == NULL? WN2F_ZeroInt_Ptr = WN2F_Initiate_ZeroInt() \ 00082 : WN2F_ZeroInt_Ptr) 00083 #define WN2F_INTCONST_ONE\ 00084 (WN2F_OneInt_Ptr == NULL? WN2F_OneInt_Ptr = WN2F_Initiate_OneInt() \ 00085 : WN2F_OneInt_Ptr) 00086 00087 void WN2F_Arrsection_Slots(TOKEN_BUFFER tokens, WN *wn,TY_IDX array_ty,WN2F_CONTEXT context, 00088 BOOL parens); 00089 void WN2F_Array_Slots(TOKEN_BUFFER tokens, WN *wn,TY_IDX array_ty,WN2F_CONTEXT context,BOOL parens); 00090 00091 /*------------------------- Utility Functions ------------------------*/ 00092 /*--------------------------------------------------------------------*/ 00093 00094 static ST * 00095 WN2F_Get_Named_Param(const WN *pu, const char *param_name) 00096 { 00097 /* Find a parameter with a matching name, if possible, otherwise 00098 * return NULL. 00099 */ 00100 ST *param_st = NULL; 00101 INT param, num_formals; 00102 00103 if (WN_opcode(pu) == OPC_ALTENTRY) 00104 num_formals = WN_kid_count(pu); 00105 else 00106 num_formals = WN_num_formals(pu); 00107 00108 /* Search through the parameter ST entries 00109 */ 00110 for (param = 0; param_st == NULL && param < num_formals; param++) 00111 { 00112 if (ST_name(WN_st(WN_formal(pu, param))) != NULL && 00113 strcmp(ST_name(WN_st(WN_formal(pu, param))), param_name) == 0) 00114 param_st = WN_st(WN_formal(pu, param)); 00115 } 00116 return param_st; 00117 } /* WN2F_Get_Named_Param */ 00118 00119 static void 00120 WN2F_Translate_StringLEN(TOKEN_BUFFER tokens, ST *param_st) 00121 { 00122 INT dim; 00123 TY_IDX param_ty = (TY_Is_Pointer(ST_type(param_st))? 00124 TY_pointed(ST_type(param_st)) : ST_type(param_st)); 00125 00126 Append_Token_String(tokens, "LEN"); 00127 Append_Token_Special(tokens, '('); 00128 Append_Token_String(tokens, W2CF_Symtab_Nameof_St(param_st)); 00129 00130 if (TY_Is_Array(param_ty) && !TY_Is_Character_String(param_ty)) 00131 { 00132 /* Append index values (any arbitrary value will do for each dimension) 00133 */ 00134 Append_Token_Special(tokens, '('); 00135 00136 00137 ARB_HANDLE arb_base = TY_arb(param_ty); 00138 dim = ARB_dimension(arb_base) - 1; 00139 00140 while ( dim >= 0) 00141 { 00142 ARB_HANDLE arb = arb_base[dim]; 00143 00144 Append_Token_String(tokens, "1"); 00145 if (dim-- > 0) 00146 Append_Token_Special(tokens, ','); 00147 } 00148 Append_Token_Special(tokens, ')'); 00149 } 00150 else 00151 { 00152 ASSERT_WARN(TY_Is_Character_String(param_ty), 00153 (DIAG_W2F_EXPECTED_PTR_TO_CHARACTER, 00154 "WN2F_Translate_StringLEN")); 00155 } 00156 Append_Token_Special(tokens, ')'); 00157 } /* WN2F_Translate_StringLEN */ 00158 00159 static WN * 00160 WN2F_Initiate_ZeroInt(void) 00161 { 00162 static char ZeroInt [sizeof (WN)]; 00163 WN *wn = (WN*) &ZeroInt; 00164 OPCODE opcode = OPCODE_make_op(OPR_INTCONST, MTYPE_I4, MTYPE_V); 00165 00166 memset(wn, '\0', sizeof(WN)); 00167 WN_set_opcode(wn, opcode); 00168 WN_set_kid_count(wn, 0); 00169 WN_map_id(wn) = WN_MAP_UNDEFINED; 00170 WN_const_val(wn) = 0LL; 00171 return wn; 00172 } /* WN2F_Initiate_ZeroInt */ 00173 00174 static WN * 00175 WN2F_Initiate_OneInt(void) 00176 { 00177 static char OneInt [sizeof (WN)]; 00178 WN *wn = (WN*) &OneInt; 00179 OPCODE opcode = OPCODE_make_op(OPR_INTCONST, MTYPE_I4, MTYPE_V); 00180 00181 memset(wn, '\0', sizeof(WN)); 00182 WN_set_opcode(wn, opcode); 00183 WN_set_kid_count(wn, 0); 00184 WN_map_id(wn) = WN_MAP_UNDEFINED; 00185 WN_const_val(wn) = 1LL; 00186 return wn; 00187 } /* WN2F_Initiate_ZeroInt */ 00188 00189 00190 static BOOL 00191 WN2F_Expr_Plus_Literal(TOKEN_BUFFER tokens, 00192 WN *wn, 00193 INT64 literal, 00194 WN2F_CONTEXT context) 00195 { 00196 /* Returns TRUE if the resultant value is constant and different 00197 * from zero. 00198 */ 00199 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 00200 BOOL is_const = TRUE; 00201 INT64 value; 00202 00203 if (WN_opc_operator(wn) == OPR_INTCONST) 00204 value = WN_const_val(wn) + literal; 00205 else if (WN_opc_operator(wn) == OPR_CONST) 00206 value = Targ_To_Host(STC_val(WN_st(wn))) + literal; 00207 else 00208 is_const = FALSE; 00209 00210 if (is_const) 00211 { 00212 if (WN_opc_operator(wn) == OPR_INTCONST) { 00213 switch (TCON_ty(Host_To_Targ(WN_opc_rtype(wn), value))) 00214 { 00215 case MTYPE_I1: 00216 case MTYPE_I2: 00217 case MTYPE_I4: 00218 case MTYPE_I8: 00219 if (TCON_ival(Host_To_Targ(WN_opc_rtype(wn), value))<0) { 00220 Append_Token_Special(tokens, '('); 00221 TCON2F_translate(tokens, 00222 Host_To_Targ(WN_opc_rtype(wn), value), 00223 FALSE /*is_logical*/); 00224 Append_Token_Special(tokens, ')'); 00225 } 00226 else 00227 TCON2F_translate(tokens, 00228 Host_To_Targ(WN_opc_rtype(wn), value), 00229 FALSE/*is_logical*/); 00230 break; 00231 00232 default: 00233 TCON2F_translate(tokens, 00234 Host_To_Targ(WN_opc_rtype(wn), value), 00235 FALSE/*is_logical*/); 00236 00237 break; 00238 00239 } /*switch*/ 00240 00241 } else { //WN_opc_operator(wn) == OPR_CONST 00242 ; //Shouldn't be here 00243 00244 } 00245 00246 } 00247 else 00248 { 00249 if (parenthesize) 00250 { 00251 reset_WN2F_CONTEXT_no_parenthesis(context); 00252 Append_Token_Special(tokens, '('); 00253 } 00254 if (WN_opc_operator(wn) == OPR_IMPLICIT_BND) 00255 Append_Token_Special(tokens, '*'); 00256 else 00257 WN2F_translate(tokens, wn, context); 00258 00259 if (parenthesize) 00260 Append_Token_Special(tokens, ')'); 00261 } 00262 00263 return is_const && (value != 0LL); 00264 } /* WN2F_Expr_Plus_Literal */ 00265 00266 00267 00268 static WN2F_STATUS 00269 WN2F_OLD_Den_Arr_Idx(TOKEN_BUFFER tokens, 00270 WN *idx_expr, 00271 WN2F_CONTEXT context) 00272 { 00273 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 00274 TOKEN_BUFFER tmp_tokens; 00275 BOOL non_zero, cexpr_is_lhs; 00276 WN *nexpr, *cexpr; 00277 INT64 plus_value; 00278 00279 /* Given an index expression, translate it to Fortran and append 00280 * the tokens to the given token-buffer. If the value of the idx 00281 * expression is "v", then the appended tokens should represent 00282 * the value "v+1". This denormalization moves the base of the 00283 * array from index zero to index one. 00284 */ 00285 if (WN_opc_operator(idx_expr) == OPR_ADD && 00286 (WN_is_constant_expr(WN_kid1(idx_expr)) || 00287 WN_is_constant_expr(WN_kid0(idx_expr)))) 00288 { 00289 /* Do the "e+c" ==> "e+(c+1)" translation, using the property 00290 * that addition is commutative. 00291 */ 00292 if (WN_is_constant_expr(WN_kid1(idx_expr))) 00293 { 00294 cexpr = WN_kid1(idx_expr); 00295 nexpr = WN_kid0(idx_expr); 00296 } 00297 else /* if (WN_is_constant_expr(WN_kid0(idx_expr))) */ 00298 { 00299 cexpr = WN_kid0(idx_expr); 00300 nexpr = WN_kid1(idx_expr); 00301 } 00302 tmp_tokens = New_Token_Buffer(); 00303 non_zero = WN2F_Expr_Plus_Literal(tmp_tokens, cexpr, 1LL, context); 00304 if (non_zero) 00305 { 00306 if (parenthesize) 00307 { 00308 reset_WN2F_CONTEXT_no_parenthesis(context); 00309 Append_Token_Special(tokens, '('); 00310 } 00311 WN2F_translate(tokens, nexpr, context); 00312 Append_Token_Special(tokens, '+'); 00313 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00314 if (parenthesize) 00315 Append_Token_Special(tokens, ')'); 00316 } 00317 else 00318 { 00319 Reclaim_Token_Buffer(&tmp_tokens); 00320 WN2F_translate(tokens, nexpr, context); 00321 } 00322 } 00323 else if (WN_opc_operator(idx_expr) == OPR_SUB && 00324 (WN_is_constant_expr(WN_kid1(idx_expr)) || 00325 WN_is_constant_expr(WN_kid0(idx_expr)))) 00326 { 00327 /* Do the "e-c" ==> "e-(c-1)" or the "c-e" ==> "(c+1)-e" 00328 * translation. 00329 */ 00330 cexpr_is_lhs = WN_is_constant_expr(WN_kid0(idx_expr)); 00331 if (!cexpr_is_lhs) 00332 { 00333 cexpr = WN_kid1(idx_expr); 00334 nexpr = WN_kid0(idx_expr); 00335 plus_value = -1LL; 00336 } 00337 else 00338 { 00339 cexpr = WN_kid0(idx_expr); 00340 nexpr = WN_kid1(idx_expr); 00341 plus_value = 1LL; 00342 } 00343 00344 /* Do the "e-c" ==> "e-(c-1)" or the "c-e" ==> "(c+1)-e" 00345 * translation. 00346 */ 00347 tmp_tokens = New_Token_Buffer(); 00348 non_zero = 00349 WN2F_Expr_Plus_Literal(tmp_tokens, cexpr, plus_value, context); 00350 if (non_zero) 00351 { 00352 if (parenthesize) 00353 { 00354 reset_WN2F_CONTEXT_no_parenthesis(context); 00355 Append_Token_Special(tokens, '('); 00356 } 00357 if (!cexpr_is_lhs) 00358 { 00359 WN2F_translate(tokens, nexpr, context); 00360 Append_Token_Special(tokens, '-'); 00361 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00362 } 00363 else 00364 { 00365 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00366 Append_Token_Special(tokens, '-'); 00367 WN2F_translate(tokens, nexpr, context); 00368 } 00369 if (parenthesize) 00370 Append_Token_Special(tokens, ')'); 00371 } 00372 else 00373 { 00374 Reclaim_Token_Buffer(&tmp_tokens); 00375 if (cexpr_is_lhs) 00376 { 00377 if (parenthesize) 00378 { 00379 reset_WN2F_CONTEXT_no_parenthesis(context); 00380 Append_Token_Special(tokens, '('); 00381 } 00382 Append_Token_Special(tokens, '-'); 00383 WN2F_translate(tokens, nexpr, context); 00384 if (parenthesize) 00385 Append_Token_Special(tokens, ')'); 00386 } 00387 else 00388 { 00389 WN2F_translate(tokens, nexpr, context); 00390 } 00391 } 00392 } 00393 else 00394 { 00395 WN2F_Expr_Plus_Literal(tokens, idx_expr, 1LL, context); 00396 } 00397 return EMPTY_WN2F_STATUS; 00398 } /* WN2F_OLD_Den_Arr_Idx */ 00399 00400 00401 static WN2F_STATUS 00402 WN2F_Denormalize_Array_Idx(TOKEN_BUFFER tokens, 00403 WN *idx_expr, 00404 WN2F_CONTEXT context) 00405 { 00406 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 00407 TOKEN_BUFFER tmp_tokens; 00408 BOOL non_zero, cexpr_is_lhs; 00409 WN *nexpr, *cexpr; 00410 INT64 plus_value; 00411 00412 /* Given an index expression, translate it to Fortran and append 00413 * the tokens to the given token-buffer. If the value of the idx 00414 * expression is "v", then the appended tokens should represent 00415 * the value "v+1". This denormalization moves the base of the 00416 * array from index zero to index one. 00417 */ 00418 if (idx_expr==NULL) return EMPTY_WN2F_STATUS; 00419 00420 if (WN_opc_operator(idx_expr) == OPR_ADD && 00421 (WN_is_constant_expr(WN_kid1(idx_expr)) || 00422 WN_is_constant_expr(WN_kid0(idx_expr)))) 00423 { 00424 /* Do the "e+c" ==> "e+(c+1)" translation, using the property 00425 * that addition is commutative. 00426 */ 00427 if (WN_is_constant_expr(WN_kid1(idx_expr))) 00428 { 00429 cexpr = WN_kid1(idx_expr); 00430 nexpr = WN_kid0(idx_expr); 00431 } 00432 else /* if (WN_is_constant_expr(WN_kid0(idx_expr))) */ 00433 { 00434 cexpr = WN_kid0(idx_expr); 00435 nexpr = WN_kid1(idx_expr); 00436 } 00437 tmp_tokens = New_Token_Buffer(); 00438 non_zero = WN2F_Expr_Plus_Literal(tmp_tokens, cexpr, 0LL, context); 00439 if (non_zero) 00440 { 00441 if (parenthesize) 00442 { 00443 reset_WN2F_CONTEXT_no_parenthesis(context); 00444 Append_Token_Special(tokens, '('); 00445 } 00446 WN2F_translate(tokens, nexpr, context); 00447 Append_Token_Special(tokens, '+'); 00448 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00449 if (parenthesize) 00450 Append_Token_Special(tokens, ')'); 00451 } 00452 else 00453 { 00454 Reclaim_Token_Buffer(&tmp_tokens); 00455 WN2F_translate(tokens, nexpr, context); 00456 } 00457 } 00458 else if (WN_opc_operator(idx_expr) == OPR_SUB && 00459 (WN_is_constant_expr(WN_kid1(idx_expr)) || 00460 WN_is_constant_expr(WN_kid0(idx_expr)))) 00461 { 00462 /* Do the "e-c" ==> "e-(c-1)" or the "c-e" ==> "(c+1)-e" 00463 * translation. 00464 */ 00465 cexpr_is_lhs = WN_is_constant_expr(WN_kid0(idx_expr)); 00466 if (!cexpr_is_lhs) 00467 { 00468 cexpr = WN_kid1(idx_expr); 00469 nexpr = WN_kid0(idx_expr); 00470 plus_value = 0LL; 00471 } 00472 else 00473 { 00474 cexpr = WN_kid0(idx_expr); 00475 nexpr = WN_kid1(idx_expr); 00476 plus_value = 0LL; 00477 } 00478 00479 /* Do the "e-c" ==> "e-(c-1)" or the "c-e" ==> "(c+1)-e" 00480 * translation. 00481 */ 00482 tmp_tokens = New_Token_Buffer(); 00483 non_zero = 00484 WN2F_Expr_Plus_Literal(tmp_tokens, cexpr, plus_value, context); 00485 if (non_zero) 00486 { 00487 if (parenthesize) 00488 { 00489 reset_WN2F_CONTEXT_no_parenthesis(context); 00490 Append_Token_Special(tokens, '('); 00491 } 00492 if (!cexpr_is_lhs) 00493 { 00494 WN2F_translate(tokens, nexpr, context); 00495 Append_Token_Special(tokens, '-'); 00496 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00497 } 00498 else 00499 { 00500 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00501 Append_Token_Special(tokens, '-'); 00502 WN2F_translate(tokens, nexpr, context); 00503 } 00504 if (parenthesize) 00505 Append_Token_Special(tokens, ')'); 00506 } 00507 else 00508 { 00509 Reclaim_Token_Buffer(&tmp_tokens); 00510 if (cexpr_is_lhs) 00511 { 00512 if (parenthesize) 00513 { 00514 reset_WN2F_CONTEXT_no_parenthesis(context); 00515 Append_Token_Special(tokens, '('); 00516 } 00517 Append_Token_Special(tokens, '-'); 00518 WN2F_translate(tokens, nexpr, context); 00519 if (parenthesize) 00520 Append_Token_Special(tokens, ')'); 00521 } 00522 else 00523 { 00524 WN2F_translate(tokens, nexpr, context); 00525 } 00526 } 00527 } 00528 else 00529 { 00530 WN2F_Expr_Plus_Literal(tokens, idx_expr, 0LL, context); 00531 } 00532 return EMPTY_WN2F_STATUS; 00533 } /* WN2F_Denormalize_Array_Idx */ 00534 00535 00536 static void 00537 WN2F_Normalize_Idx_To_Onedim(TOKEN_BUFFER tokens, 00538 WN* wn, 00539 WN2F_CONTEXT context) 00540 { 00541 INT32 dim1, dim2; 00542 00543 /* Parenthesize the normalized index expressions */ 00544 reset_WN2F_CONTEXT_no_parenthesis(context); 00545 00546 for (dim1 = 0; dim1 < WN_num_dim(wn); dim1++) 00547 { 00548 if (dim1 > 0) 00549 Append_Token_Special(tokens, '+'); 00550 00551 /* Multiply the index expression with the product of the sizes 00552 * of subordinate dimensions, where a higher dimension-number 00553 * means a more subordinate dimension. Do not parenthesize the 00554 * least significant index expression. 00555 */ 00556 if (dim1+1 == WN_num_dim(wn)) 00557 set_WN2F_CONTEXT_no_parenthesis(context); 00558 WN2F_Denormalize_Array_Idx(tokens, WN_array_index(wn, dim1), context); 00559 for (dim2 = dim1+1; dim2 < WN_num_dim(wn); dim2++) 00560 { 00561 Append_Token_Special(tokens, '*'); 00562 (void)WN2F_translate(tokens, WN_array_dim(wn, dim2), context); 00563 } /*for*/ 00564 } /*for*/ 00565 } /* WN2F_Normalize_Idx_To_Onedim */ 00566 00567 00568 static void 00569 WN2F_Substring(TOKEN_BUFFER tokens, 00570 INT64 string_size, 00571 WN *lower_bnd, 00572 WN *substring_size, 00573 WN2F_CONTEXT context) 00574 { 00575 /* Given a substring offset from the base of a character string 00576 * (lower_bnd), the size of the whole string, and the size of the 00577 * substring, generate the notation necessary as a suffix to the 00578 * string reference to denote the substring. 00579 */ 00580 if (WN_opc_operator(lower_bnd) != OPR_INTCONST || 00581 WN_const_val(lower_bnd) != 0 || 00582 WN_opc_operator(substring_size) != OPR_INTCONST || 00583 WN_const_val(substring_size) != string_size) 00584 { 00585 /* Need to generate substring expression "(l+1:l+size)" */ 00586 Append_Token_Special(tokens, '('); 00587 set_WN2F_CONTEXT_no_parenthesis(context); 00588 /* WN2F_Denormalize_Array_Idx(tokens, lower_bnd, context);*/ 00589 00590 WN2F_OLD_Den_Arr_Idx(tokens, lower_bnd, context); 00591 00592 reset_WN2F_CONTEXT_no_parenthesis(context); 00593 Append_Token_Special(tokens, ':'); 00594 if (WN_opc_operator(lower_bnd) != OPR_INTCONST || 00595 WN_const_val(lower_bnd) != 0) 00596 { 00597 WN2F_translate(tokens, lower_bnd, context); 00598 Append_Token_Special(tokens, '+'); 00599 } 00600 WN2F_translate(tokens, substring_size, context); 00601 Append_Token_Special(tokens, ')'); 00602 } 00603 } /* WN2F_Substring */ 00604 00605 00606 static void 00607 WN2F_Get_Substring_Info(WN **base, /* Possibly OPR_ARRAY node (in/out) */ 00608 TY_IDX *string_ty, /* The string type (out) */ 00609 WN **lower_bnd, /* The lower bound index (out) */ 00610 WN **length ) 00611 { 00612 /* There are two possibilities concerning the array base expressions. 00613 * It can be a pointer to a complete character-string (array) or it 00614 * can be a pointer to a character within a character-string (single 00615 * character). In the first instance, the offset off the base of 00616 * string is zero. In the latter case, the offset is given by the 00617 * array indexing operation. 00618 */ 00619 TY_IDX ptr_ty = WN_Tree_Type(*base); 00620 00621 *string_ty = TY_pointed(ptr_ty); 00622 00623 if (TY_size(*string_ty) == 1 && 00624 !TY_Is_Array(*string_ty) && 00625 WN_opc_operator(*base) == OPR_ARRAY) 00626 { 00627 /* Let the base of the string be denoted as the base of the array 00628 * expression. 00629 */ 00630 *string_ty = TY_pointed(WN_Tree_Type(WN_kid0(*base))); 00631 *lower_bnd = WN_array_index(*base, 0); 00632 *length = WN_kid1(*base); 00633 *base = WN_kid0(*base); 00634 } 00635 else if (WN_opc_operator(*base) == OPR_ARRAY && 00636 TY_Is_Array(*string_ty) && 00637 TY_AR_ndims(*string_ty) == 1 && 00638 TY_Is_Character_String(*string_ty) && 00639 !TY_ptr_as_array(Ty_Table[ptr_ty])) 00640 { 00641 /* Presumably, the lower bound is given by the array operator 00642 */ 00643 *lower_bnd = WN_array_index(*base, 0); 00644 *length = WN_kid1(*base); 00645 *base = WN_kid0(*base); 00646 } 00647 else 00648 { 00649 *lower_bnd = WN2F_INTCONST_ZERO; 00650 *length = WN2F_INTCONST_ZERO; 00651 } 00652 } /* WN2F_Get_Substring_Info */ 00653 00654 static WN * 00655 WN2F_Find_Base(WN *addr) 00656 { 00657 /* utility to find base of address tree */ 00658 00659 WN *res = addr; 00660 00661 switch (WN_operator(addr)) 00662 { 00663 case OPR_ARRAY: 00664 case OPR_ILOAD: 00665 res=WN_kid0(addr); 00666 break; 00667 00668 case OPR_ADD: 00669 if (WN_operator(WN_kid0(addr)) == OPR_INTCONST) 00670 res = WN2F_Find_Base(WN_kid1(addr)); 00671 else 00672 res = WN2F_Find_Base(WN_kid0(addr)); 00673 break; 00674 00675 default: 00676 res = addr; 00677 break; 00678 } 00679 return res; 00680 } 00681 00682 extern BOOL 00683 WN2F_Is_Address_Preg(WN * ad ,TY_IDX ptr_ty) 00684 { 00685 /* Does this look like a preg or variable being used as an address ? */ 00686 /* These are propagated by opt/pfa */ 00687 00688 BOOL is_somewhat_address_like = TY_kind(ptr_ty) == KIND_POINTER; 00689 00690 if (TY_kind(ptr_ty) == KIND_SCALAR) 00691 { 00692 TYPE_ID tid = TY_mtype(ptr_ty); 00693 00694 is_somewhat_address_like |= (MTYPE_is_pointer(tid)) || (tid == MTYPE_I8) || (tid == MTYPE_I4) ; 00695 } 00696 00697 if (is_somewhat_address_like) 00698 { 00699 WN * wn = WN2F_Find_Base(ad); 00700 00701 if (WN_operator(wn) == OPR_LDID) 00702 { 00703 ST * st = WN_st(wn) ; 00704 if (ST_class(st) == CLASS_PREG) 00705 return TRUE ; 00706 00707 if (ST_class(st) == CLASS_VAR) 00708 { 00709 if (TY_kind(ptr_ty) == KIND_SCALAR) 00710 return TRUE; 00711 00712 if (TY_kind(WN_ty(wn)) == KIND_SCALAR) 00713 { 00714 TYPE_ID wtid = TY_mtype(WN_ty(wn)); 00715 00716 /* Looks like a Cray pointer (I4/I8) ? */ 00717 00718 if ((wtid == MTYPE_I8)|| (wtid == MTYPE_I4)) 00719 if (ad != wn) 00720 return TRUE ; 00721 00722 /* Looks like a VAR with a U4/U8? used */ 00723 /* only with offsets, or FORMALs would */ 00724 /* qualify, if intrinsic mtype */ 00725 00726 if (MTYPE_is_pointer(wtid)) 00727 if (TY_kind(ST_type(st)) != KIND_SCALAR) 00728 return TRUE; 00729 } 00730 } 00731 } 00732 } 00733 return FALSE; 00734 } 00735 00736 /*---------------------- Prefetching Comments ------------------------*/ 00737 /*--------------------------------------------------------------------*/ 00738 00739 static void 00740 WN2F_Append_Prefetch_Map(TOKEN_BUFFER tokens, WN *wn) 00741 { 00742 PF_POINTER* pfptr; 00743 const char *info_str; 00744 00745 pfptr = (PF_POINTER*)WN_MAP_Get(WN_MAP_PREFETCH, wn); 00746 info_str = "prefetch (ptr, lrnum): "; 00747 if (pfptr->wn_pref_1L) 00748 { 00749 info_str = 00750 Concat2_Strings( info_str, 00751 Concat2_Strings( "1st <", 00752 Concat2_Strings( Ptr_as_String(pfptr->wn_pref_1L), 00753 Concat2_Strings( ", ", 00754 Concat2_Strings(WHIRL2F_number_as_name(pfptr->lrnum_1L), 00755 ">"))))); 00756 } 00757 if (pfptr->wn_pref_2L) 00758 { 00759 info_str = 00760 Concat2_Strings( info_str, 00761 Concat2_Strings( "2nd <", 00762 Concat2_Strings( Ptr_as_String(pfptr->wn_pref_2L), 00763 Concat2_Strings( ", ", 00764 Concat2_Strings(WHIRL2F_number_as_name(pfptr->lrnum_2L), 00765 ">"))))); 00766 } 00767 Append_Token_String(tokens, info_str); 00768 } /* WN2F_Append_Prefetch_Map */ 00769 00770 00771 /*----------------------- Exported Functions ------------------------*/ 00772 /*--------------------------------------------------------------------*/ 00773 00774 void WN2F_Load_Store_initialize(void) 00775 { 00776 /* Nothing to do at the moment */ 00777 } /* WN2F_Load_Store_initialize */ 00778 00779 00780 void WN2F_Load_Store_finalize(void) 00781 { 00782 /* Nothing to do at the moment */ 00783 } /* WN2F_Load_Store_finalize */ 00784 00785 00786 extern WN2F_STATUS 00787 WN2F_pstore(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00788 { 00789 TOKEN_BUFFER lhs_tokens; 00790 TOKEN_BUFFER rhs_tokens; 00791 TY_IDX base_ty; 00792 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_PSTORE, 00793 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_pstore")); 00794 00795 /* Get the base address into which we are storing a value */ 00796 base_ty = WN_Tree_Type(WN_kid1(wn)); 00797 if (!TY_Is_Pointer(base_ty)) 00798 base_ty = WN_ty(wn); 00799 00800 /* Get the lhs of the assignment (dereference address) */ 00801 lhs_tokens = New_Token_Buffer(); 00802 00803 set_WN2F_CONTEXT_has_no_arr_elmt(context); 00804 00805 WN2F_Offset_Memref(lhs_tokens, 00806 WN_kid1(wn), /* base-symbol */ 00807 base_ty, /* base-type */ 00808 TY_pointed(WN_ty(wn)), /* object-type */ 00809 WN_store_offset(wn), /* object-ofst */ 00810 context); 00811 reset_WN2F_CONTEXT_has_no_arr_elmt(context); 00812 00813 /* The rhs */ 00814 rhs_tokens = New_Token_Buffer(); 00815 if (TY_is_logical(Ty_Table[TY_pointed(WN_ty(wn))])) 00816 { 00817 set_WN2F_CONTEXT_has_logical_arg(context); 00818 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 00819 reset_WN2F_CONTEXT_has_logical_arg(context); 00820 } 00821 else 00822 { 00823 00824 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 00825 } 00826 00827 /* See if we need to apply a "char" conversion to the rhs 00828 */ 00829 if (TY_Is_Character_String(W2F_TY_pointed(WN_ty(wn), "PSTORE lhs")) && 00830 TY_Is_Integral(WN_Tree_Type(WN_kid0(wn)))) 00831 { 00832 00833 Prepend_Token_Special(rhs_tokens, '('); 00834 Prepend_Token_String(rhs_tokens, "char"); 00835 Append_Token_Special(rhs_tokens, ')'); 00836 } 00837 00838 /* Assign the rhs to the lhs. 00839 */ 00840 if (Identical_Token_Lists(lhs_tokens, rhs_tokens)) 00841 { 00842 /* Ignore this redundant assignment statement! */ 00843 Reclaim_Token_Buffer(&lhs_tokens); 00844 Reclaim_Token_Buffer(&rhs_tokens); 00845 } 00846 else 00847 { 00848 /* See if there is any prefetch information with this store, 00849 * and if so insert information about it as a comment preceeding 00850 * the store. 00851 */ 00852 if (W2F_Emit_Prefetch && WN_MAP_Get(WN_MAP_PREFETCH, wn)) 00853 { 00854 Append_F77_Comment_Newline(tokens, 1, TRUE/*indent*/); 00855 WN2F_Append_Prefetch_Map(tokens, wn); 00856 } 00857 00858 /* The assignment statement on a new line */ 00859 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 00860 Append_And_Reclaim_Token_List(tokens, &lhs_tokens); 00861 Append_Token_String(tokens,"=>"); 00862 Append_And_Reclaim_Token_List(tokens, &rhs_tokens); 00863 } 00864 00865 return EMPTY_WN2F_STATUS; 00866 } /* WN2F_pstore */ 00867 00868 extern WN2F_STATUS 00869 WN2F_istore(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00870 { 00871 TOKEN_BUFFER lhs_tokens; 00872 TOKEN_BUFFER rhs_tokens; 00873 TY_IDX base_ty; 00874 TY_IDX object_ty; 00875 00876 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_ISTORE, 00877 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_istore")); 00878 00879 /* Get the base address into which we are storing a value */ 00880 base_ty = WN_Tree_Type(WN_kid1(wn)); 00881 object_ty = TY_pointed(WN_ty(wn)); 00882 00883 if (!TY_Is_Pointer(base_ty)) 00884 base_ty = WN_ty(wn); 00885 00886 //For pointer PP(:,...,:) 00887 if (TY_kind(TY_pointed(base_ty))==KIND_POINTER && 00888 TY_is_f90_deferred_shape(TY_pointed(base_ty))) 00889 base_ty = TY_pointed(base_ty); 00890 00891 if (TY_kind(object_ty)==KIND_POINTER && 00892 TY_is_f90_deferred_shape(object_ty)) 00893 object_ty = TY_pointed(object_ty); 00894 00895 /* Get the lhs of the assignment (dereference address) */ 00896 lhs_tokens = New_Token_Buffer(); 00897 if (WN_operator(WN_kid1(wn)) == OPR_LDA || 00898 WN_operator(WN_kid1(wn)) == OPR_LDID ) 00899 set_WN2F_CONTEXT_has_no_arr_elmt(context); 00900 #if 0 00901 WN2F_Offset_Memref(lhs_tokens, 00902 WN_kid1(wn), /* base-symbol */ 00903 base_ty, /* base-type */ 00904 object_ty, /* object-type */ 00905 WN_store_offset(wn), /* object-ofst */ 00906 context); 00907 #else 00908 WN2F_translate(lhs_tokens, WN_kid1(wn), context); 00909 #endif 00910 00911 reset_WN2F_CONTEXT_has_no_arr_elmt(context); 00912 00913 /* The rhs */ 00914 rhs_tokens = New_Token_Buffer(); 00915 00916 if (TY_is_logical(Ty_Table[TY_pointed(WN_ty(wn))])) 00917 { 00918 set_WN2F_CONTEXT_has_logical_arg(context); 00919 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 00920 reset_WN2F_CONTEXT_has_logical_arg(context); 00921 } 00922 else 00923 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 00924 00925 /* See if we need to apply a "char" conversion to the rhs 00926 */ 00927 #if 0 00928 if (TY_Is_Character_String(W2F_TY_pointed(WN_ty(wn), "ISTORE lhs")) && 00929 TY_Is_Integral(WN_Tree_Type(WN_kid0(wn)))) 00930 { 00931 Prepend_Token_Special(rhs_tokens, '('); 00932 Prepend_Token_String(rhs_tokens, "char"); 00933 Append_Token_Special(rhs_tokens, ')'); 00934 } 00935 #endif 00936 00937 /* Assign the rhs to the lhs. 00938 */ 00939 if (Identical_Token_Lists(lhs_tokens, rhs_tokens)) 00940 { 00941 /* Ignore this redundant assignment statement! */ 00942 Reclaim_Token_Buffer(&lhs_tokens); 00943 Reclaim_Token_Buffer(&rhs_tokens); 00944 } 00945 else 00946 { 00947 /* See if there is any prefetch information with this store, 00948 * and if so insert information about it as a comment preceeding 00949 * the store. 00950 */ 00951 if (W2F_Emit_Prefetch && WN_MAP_Get(WN_MAP_PREFETCH, wn)) 00952 { 00953 Append_F77_Comment_Newline(tokens, 1, TRUE/*indent*/); 00954 WN2F_Append_Prefetch_Map(tokens, wn); 00955 } 00956 00957 /* The assignment statement on a new line */ 00958 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 00959 Append_And_Reclaim_Token_List(tokens, &lhs_tokens); 00960 Append_Token_Special(tokens, '='); 00961 Append_And_Reclaim_Token_List(tokens, &rhs_tokens); 00962 } 00963 00964 fld_type_z = 0; 00965 00966 return EMPTY_WN2F_STATUS; 00967 } /* WN2F_istore */ 00968 00969 WN2F_STATUS 00970 WN2F_istorex(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00971 { 00972 ASSERT_DBG_WARN(FALSE, (DIAG_UNIMPLEMENTED, "WN2F_istorex")); 00973 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 00974 Append_Token_String(tokens, WN_opc_name(wn)); 00975 00976 return EMPTY_WN2F_STATUS; 00977 } /* WN2F_istorex */ 00978 00979 WN2F_STATUS 00980 WN2F_mstore(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00981 { 00982 TOKEN_BUFFER lhs_tokens; 00983 TOKEN_BUFFER rhs_tokens; 00984 TY_IDX base_ty; 00985 00986 /* Note that we make the assumption that this is just like an 00987 * ISTORE, and handle it as though it were. We do not handle 00988 * specially assignment-forms where the lhs is incompatible with 00989 * the rhs, since we assume this will never happen for Fortran 00990 * and we cannot easily get around this like we do in C (i.e. 00991 * with cast expressions. 00992 */ 00993 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_MSTORE, 00994 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_mstore")); 00995 #if 0 00996 ASSERT_DBG_WARN(WN_opc_operator(WN_kid0(wn)) == OPR_MLOAD, 00997 (DIAG_W2F_UNEXPECTED_OPC, "rhs of WN2F_mstore")); 00998 00999 //TODO: scalar expression allowed, but array/structure assignment assumed 01000 // with constant ie: should put out doloop?... call OFFSET_Memref? 01001 #endif 01002 01003 /* Get the base address into which we are storing a value */ 01004 base_ty = WN_Tree_Type(WN_kid1(wn)); 01005 if (!TY_Is_Pointer(base_ty)) 01006 base_ty = WN_ty(wn); 01007 01008 /* Get the lhs of the assignment (dereference address) */ 01009 lhs_tokens = New_Token_Buffer(); 01010 #if 0 01011 WN2F_Offset_Memref(lhs_tokens, 01012 WN_kid1(wn), /* base-symbol */ 01013 base_ty, /* base-type */ 01014 TY_pointed(WN_ty(wn)), /* object-type */ 01015 WN_store_offset(wn), /* object-ofst */ 01016 context); 01017 #else 01018 WN2F_translate(lhs_tokens, WN_kid1(wn), context); 01019 #endif 01020 01021 01022 /* The rhs */ 01023 rhs_tokens = New_Token_Buffer(); 01024 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 01025 01026 /* Assign the rhs to the lhs. 01027 */ 01028 if (Identical_Token_Lists(lhs_tokens, rhs_tokens)) 01029 { 01030 /* Ignore this redundant assignment statement! */ 01031 Reclaim_Token_Buffer(&lhs_tokens); 01032 Reclaim_Token_Buffer(&rhs_tokens); 01033 } 01034 else 01035 { 01036 /* The assignment statement on a new line */ 01037 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 01038 Append_And_Reclaim_Token_List(tokens, &lhs_tokens); 01039 Append_Token_Special(tokens, '='); 01040 Append_And_Reclaim_Token_List(tokens, &rhs_tokens); 01041 } 01042 01043 01044 return EMPTY_WN2F_STATUS; 01045 } /* WN2F_mstore */ 01046 01047 WN2F_STATUS 01048 WN2F_stid(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01049 { 01050 TOKEN_BUFFER lhs_tokens, rhs_tokens; 01051 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 01052 TY_IDX base_ty; 01053 TY_IDX object_ty; 01054 01055 01056 if (parenthesize) 01057 set_WN2F_CONTEXT_no_parenthesis(context); 01058 01059 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_STID, 01060 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_stid")); 01061 01062 if (W2F_OpenAD 01063 && 01064 ST_is_temp_var(WN_st(wn)) 01065 && 01066 ( 01067 strncmp("select_expr_",ST_name(WN_st(wn)),12)!=0 01068 && 01069 !ST_keep_in_openad(WN_st(wn)))) 01070 // emit assignments for symbols marked as to be kept and values of select expressions. 01071 // the hard coded name (see cwg_stmt.cxx:2271) 01072 // is awful but not particularly worse than the other 01073 // hacks done for select constructs 01074 return EMPTY_WN2F_STATUS; 01075 01076 /* Get the lhs of the assignment */ 01077 lhs_tokens = New_Token_Buffer(); 01078 if (ST_class(WN_st(wn)) == CLASS_PREG) 01079 { 01080 ST2F_Use_Preg(lhs_tokens, ST_type(WN_st(wn)), WN_store_offset(wn)); 01081 } 01082 else if (ST_sym_class(WN_st(wn))==CLASS_VAR && ST_is_not_used(WN_st(wn))) 01083 { 01084 /* This is a redundant assignment statement, so determined 01085 * by IPA, so just assign it to a temporary variable 01086 * instead. 01087 */ 01088 UINT tmp_idx = Stab_Lock_Tmpvar(WN_ty(wn), &ST2F_Declare_Tempvar); 01089 Append_Token_String(lhs_tokens, W2CF_Symtab_Nameof_Tempvar(tmp_idx)); 01090 Stab_Unlock_Tmpvar(tmp_idx); 01091 } 01092 else 01093 { 01094 base_ty = ST_type(WN_st(wn)); 01095 if (TY_kind(base_ty)==KIND_POINTER && 01096 TY_is_f90_pointer(base_ty)) 01097 ; 01098 else 01099 base_ty = Stab_Pointer_To(base_ty); 01100 01101 object_ty = WN_ty(wn); 01102 if ((TY_kind(object_ty)==KIND_POINTER) && 01103 ( TY_is_f90_pointer(object_ty))) 01104 object_ty = TY_pointed(object_ty); 01105 01106 WN2F_Offset_Symref(lhs_tokens, 01107 WN_st(wn), /* base-symbol */ 01108 base_ty, /* base_type */ 01109 object_ty, /* object-type */ 01110 WN_store_offset(wn), /* object-ofst */ 01111 context); 01112 } 01113 01114 /* The rhs */ 01115 rhs_tokens = New_Token_Buffer(); 01116 01117 // const BOOL p11arenthesize = !WN2F_CONTEXT_no_parenthesis(context); 01118 01119 if (TY_is_logical(Ty_Table[WN_ty(wn)])) 01120 { 01121 set_WN2F_CONTEXT_has_logical_arg(context); 01122 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 01123 reset_WN2F_CONTEXT_has_logical_arg(context); 01124 } 01125 else { 01126 01127 // set_WN2F_CONTEXT_no_parenthesis(context); 01128 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 01129 // reset_WN2F_CONTEXT_no_parenthesis(context); 01130 } 01131 01132 /* See if we need to apply a "char" conversion to the rhs 01133 */ 01134 01135 if (TY_Is_Character_String(WN_ty(wn)) && 01136 TY_Is_Integral(WN_Tree_Type(WN_kid0(wn)))) 01137 { 01138 Prepend_Token_Special(rhs_tokens, '('); 01139 Prepend_Token_String(rhs_tokens, "char"); 01140 Append_Token_Special(rhs_tokens, ')'); 01141 } 01142 01143 /* Assign the rhs to the lhs. 01144 */ 01145 01146 01147 if (!WN2F_CONTEXT_emit_stid(context) && 01148 Identical_Token_Lists(lhs_tokens, rhs_tokens)) 01149 { 01150 /* Ignore this redundant assignment statement! */ 01151 Reclaim_Token_Buffer(&lhs_tokens); 01152 Reclaim_Token_Buffer(&rhs_tokens); 01153 } 01154 else 01155 { 01156 /* The assignment statement on a new line */ 01157 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 01158 Append_And_Reclaim_Token_List(tokens, &lhs_tokens); 01159 Append_Token_Special(tokens, '='); 01160 Append_And_Reclaim_Token_List(tokens, &rhs_tokens); 01161 } 01162 01163 01164 return EMPTY_WN2F_STATUS; 01165 } /* WN2F_stid */ 01166 01167 01168 WN2F_STATUS 01169 WN2F_pstid(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01170 { 01171 TOKEN_BUFFER lhs_tokens, rhs_tokens; 01172 01173 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_PSTID, 01174 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_pstid")); 01175 01176 /* Get the lhs of the assignment */ 01177 lhs_tokens = New_Token_Buffer(); 01178 if (ST_class(WN_st(wn)) == CLASS_PREG) 01179 { 01180 ST2F_Use_Preg(lhs_tokens, ST_type(WN_st(wn)), WN_store_offset(wn)); 01181 } 01182 else if (ST_sym_class(WN_st(wn))==CLASS_VAR && ST_is_not_used(WN_st(wn))) 01183 { 01184 /* This is a redundant assignment statement, so determined 01185 * by IPA, so just assign it to a temporary variable 01186 * instead. 01187 */ 01188 UINT tmp_idx = Stab_Lock_Tmpvar(WN_ty(wn), &ST2F_Declare_Tempvar); 01189 Append_Token_String(lhs_tokens, W2CF_Symtab_Nameof_Tempvar(tmp_idx)); 01190 Stab_Unlock_Tmpvar(tmp_idx); 01191 } 01192 else 01193 { 01194 WN2F_Offset_Symref(lhs_tokens, 01195 WN_st(wn), /* base-symbol */ 01196 Stab_Pointer_To(ST_type(WN_st(wn))),/* base-type */ 01197 WN_ty(wn), /* object-type */ 01198 WN_store_offset(wn), /* object-ofst */ 01199 context); 01200 } 01201 01202 /* The rhs */ 01203 rhs_tokens = New_Token_Buffer(); 01204 if (TY_is_logical(Ty_Table[WN_ty(wn)])) 01205 { 01206 set_WN2F_CONTEXT_has_logical_arg(context); 01207 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 01208 reset_WN2F_CONTEXT_has_logical_arg(context); 01209 } 01210 else 01211 WN2F_translate(rhs_tokens, WN_kid0(wn), context); 01212 01213 /* See if we need to apply a "char" conversion to the rhs 01214 */ 01215 if (TY_Is_Character_String(WN_ty(wn)) && 01216 TY_Is_Integral(WN_Tree_Type(WN_kid0(wn)))) 01217 { 01218 Prepend_Token_Special(rhs_tokens, '('); 01219 Prepend_Token_String(rhs_tokens, "char"); 01220 Append_Token_Special(rhs_tokens, ')'); 01221 } 01222 01223 /* Assign the rhs to the lhs. 01224 */ 01225 if (!WN2F_CONTEXT_emit_stid(context) && 01226 Identical_Token_Lists(lhs_tokens, rhs_tokens)) 01227 { 01228 /* Ignore this redundant assignment statement! */ 01229 Reclaim_Token_Buffer(&lhs_tokens); 01230 Reclaim_Token_Buffer(&rhs_tokens); 01231 } 01232 else 01233 { 01234 /* The assignment statement on a new line */ 01235 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 01236 Append_And_Reclaim_Token_List(tokens, &lhs_tokens); 01237 Append_Token_String(tokens,"=>"); 01238 Append_And_Reclaim_Token_List(tokens, &rhs_tokens); 01239 } 01240 01241 return EMPTY_WN2F_STATUS; 01242 } /* WN2F_pstid */ 01243 01244 01245 WN2F_STATUS 01246 WN2F_iload(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01247 { 01248 TY_IDX base_ty; 01249 TY_IDX object_ty; 01250 01251 /* Note that we handle this just like we do the lhs of an ISTORE. 01252 */ 01253 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_ILOAD, 01254 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_iload")); 01255 01256 01257 if (WN_operator(WN_kid0(wn))==OPR_STRCTFLD){ //place-hold for pointer field 01258 WN2F_translate(tokens, WN_kid0(wn), context); 01259 return EMPTY_WN2F_STATUS; 01260 } 01261 01262 /* Special case for Purple (address values have no meaning, so emit 01263 * symbolic values for them). 01264 */ 01265 if (W2F_Only_Mark_Loads && !TY_Is_Pointer(WN_ty(wn))) 01266 { 01267 char buf[64]; 01268 sprintf(buf, "#<%p>#", wn); 01269 Append_Token_String(tokens, buf); 01270 return EMPTY_WN2F_STATUS; 01271 } 01272 01273 /* Get the type of the base from which we are loading */ 01274 base_ty = WN_Tree_Type(WN_kid0(wn)); 01275 object_ty = TY_pointed(WN_load_addr_ty(wn)); 01276 01277 if (!TY_Is_Pointer(base_ty)) 01278 base_ty = WN_load_addr_ty(wn); 01279 01280 /*For pointer PP(:,...,:) */ 01281 if (TY_kind(TY_pointed(base_ty))==KIND_POINTER && 01282 TY_is_f90_deferred_shape(TY_pointed(base_ty))) 01283 base_ty = TY_pointed(base_ty); 01284 01285 if (TY_kind(object_ty)==KIND_POINTER && 01286 TY_is_f90_deferred_shape(object_ty)) 01287 object_ty = TY_pointed(object_ty); 01288 01289 /* Get the object to be loaded (dereference address) */ 01290 if (WN_opc_operator(WN_kid0(wn)) == OPR_LDA || 01291 WN_opc_operator(WN_kid0(wn)) == OPR_LDID) 01292 set_WN2F_CONTEXT_has_no_arr_elmt(context); 01293 #if 0 01294 WN2F_Offset_Memref(tokens, 01295 WN_kid0(wn), /* base-symbol */ 01296 base_ty, /* base-type */ 01297 object_ty, /* object-type */ 01298 WN_load_offset(wn), /* object-ofst */ 01299 context); 01300 #else 01301 WN2F_translate(tokens, WN_kid0(wn), context); 01302 #endif 01303 reset_WN2F_CONTEXT_has_no_arr_elmt(context); 01304 01305 /* See if there is any prefetch information with this load, and 01306 * if so insert information about it as a comment on a separate 01307 * continuation line. 01308 */ 01309 if (W2F_Emit_Prefetch && WN_MAP_Get(WN_MAP_PREFETCH, wn)) 01310 { 01311 Set_Current_Indentation(Current_Indentation()+3); 01312 Append_F77_Indented_Continuation(tokens); 01313 Append_Token_Special(tokens, '!'); 01314 WN2F_Append_Prefetch_Map(tokens, wn); 01315 Set_Current_Indentation(Current_Indentation()-3); 01316 Append_F77_Indented_Continuation(tokens); 01317 } 01318 01319 return EMPTY_WN2F_STATUS; 01320 } /* WN2F_iload */ 01321 01322 WN2F_STATUS 01323 WN2F_iloadx(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01324 { 01325 ASSERT_DBG_WARN(FALSE, (DIAG_UNIMPLEMENTED, "WN2F_iloadx")); 01326 Append_Token_String(tokens, WN_opc_name(wn)); 01327 01328 return EMPTY_WN2F_STATUS; 01329 } /* WN2F_iloadx */ 01330 01331 01332 WN2F_STATUS 01333 WN2F_mload(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01334 { 01335 TY_IDX base_ty; 01336 01337 /* This should only appear the as the rhs of an ISTORE. Treat 01338 * it just like an ILOAD. 01339 */ 01340 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_MLOAD, 01341 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_mload")); 01342 01343 /* Special case for Purple (cannot be a pointer value) */ 01344 if (W2F_Only_Mark_Loads) 01345 { 01346 char buf[64]; 01347 sprintf(buf, "#<%p>#", wn); 01348 Append_Token_String(tokens, buf); 01349 return EMPTY_WN2F_STATUS; 01350 } 01351 01352 /* Get the type of the base from which we are loading */ 01353 base_ty = WN_Tree_Type(WN_kid0(wn)); 01354 if (!TY_Is_Pointer(base_ty)) 01355 base_ty = WN_ty(wn); 01356 01357 /* Get the object to be loaded */ 01358 WN2F_Offset_Memref(tokens, 01359 WN_kid0(wn), /* base-symbol */ 01360 base_ty, /* base-type */ 01361 TY_pointed(WN_ty(wn)), /* object-type */ 01362 WN_load_offset(wn), /* object-ofst */ 01363 context); 01364 return EMPTY_WN2F_STATUS; 01365 } /* WN2F_mload */ 01366 01367 01368 WN2F_STATUS 01369 WN2F_ldid(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01370 { 01371 const BOOL deref = WN2F_CONTEXT_deref_addr(context); 01372 TY_IDX base_ptr_ty; 01373 TY_IDX object_ty; 01374 01375 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_LDID, 01376 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_ldid")); 01377 01378 /* Special recognition of a LEN intrinsic call 01379 */ 01380 if (WN_load_offset(wn) == 0 && 01381 TY_Is_Integral(WN_ty(wn)) && 01382 ST_sclass(WN_st(wn))==SCLASS_FORMAL && 01383 ST_is_value_parm(WN_st(wn)) && 01384 strncmp(ST_name(WN_st(wn)), ".length.", strlen(".length.")) == 0) 01385 { 01386 /* Search the current PU parameters for a name that matches the 01387 * part of the ST_name that follows the ".length." prefix. 01388 */ 01389 ST *st_param = 01390 WN2F_Get_Named_Param(PUinfo_current_func, 01391 ST_name(WN_st(wn)) + strlen(".length.")); 01392 01393 if (st_param != NULL) 01394 { 01395 WN2F_Translate_StringLEN(tokens, st_param); 01396 return EMPTY_WN2F_STATUS; 01397 } 01398 } 01399 01400 /* Special case for Purple direct loads, except direct loads of 01401 * addresses (address values have no meaning in the purple output). 01402 */ 01403 if (W2F_Only_Mark_Loads && !TY_Is_Pointer(WN_ty(wn))) 01404 { 01405 char buf[64]; 01406 sprintf(buf, "#<%p>#", wn); 01407 Append_Token_String(tokens, buf); 01408 return EMPTY_WN2F_STATUS; 01409 } 01410 01411 if (ST_class(WN_st(wn)) == CLASS_PREG ) 01412 { 01413 char buffer[64]; 01414 STAB_OFFSET addr_offset = WN_load_offset(wn); 01415 object_ty = PUinfo_Preg_Type(ST_type(WN_st(wn)), addr_offset); 01416 01417 01418 if (addr_offset == -1 ) { 01419 switch (TY_mtype(Ty_Table[WN_ty(wn)])) { 01420 case MTYPE_I8: 01421 case MTYPE_U8: 01422 case MTYPE_I1: 01423 case MTYPE_I2: 01424 case MTYPE_I4: 01425 case MTYPE_U1: 01426 case MTYPE_U2: 01427 case MTYPE_U4: 01428 sprintf(buffer, "reg%d", First_Int_Preg_Return_Offset); 01429 Append_Token_String(tokens, buffer); 01430 break; 01431 case MTYPE_F4: 01432 case MTYPE_F8: 01433 case MTYPE_FQ: 01434 case MTYPE_C4: 01435 case MTYPE_C8: 01436 case MTYPE_CQ: 01437 sprintf(buffer, "reg%d", First_Float_Preg_Return_Offset); 01438 Append_Token_String(tokens, buffer); 01439 break; 01440 case MTYPE_M: 01441 Fail_FmtAssertion ("MLDID of Return_Val_Preg not allowed in middle" 01442 " of expression"); 01443 break; 01444 default: 01445 Fail_FmtAssertion ("Unexpected type in WN2C_ldid()"); 01446 break; 01447 } 01448 } 01449 else 01450 { 01451 ST2F_Use_Preg(tokens, ST_type(WN_st(wn)), WN_load_offset(wn)); 01452 } 01453 } 01454 else 01455 { 01456 /* Get the base and object type symbols. 01457 */ 01458 if (deref && TY_Is_Pointer(ST_type(WN_st(wn)))) 01459 { 01460 /* Expect the loaded type to be a pointer to the type of object 01461 * to be dereferenced. The only place (besides declaration sites) 01462 * where we expect to have to specially handle ptr_as_array 01463 * objects. 01464 */ 01465 if (TY_ptr_as_array(Ty_Table[WN_ty(wn)])) 01466 object_ty = Stab_Array_Of(TY_pointed(WN_ty(wn)), 0/*size*/); 01467 else 01468 object_ty = TY_pointed(WN_ty(wn)); 01469 01470 /* There are two possibilities for the base type: A regular 01471 * pointer or a pointer to be treated as a pointer to an array. 01472 * In either case, the "base_ptr_ty" is a pointer to the 01473 * derefenced base type. 01474 * 01475 * Note that this does not handle a pointer to a struct to be 01476 * treated as an array of structs, where the object type and 01477 * offset denote a member of the struct, since WN2F_Offset_Symref() 01478 * cannot access a struct member through an array access. 01479 */ 01480 if (TY_ptr_as_array(Ty_Table[ST_type(WN_st(wn))])) 01481 base_ptr_ty = 01482 Stab_Pointer_To(Stab_Array_Of(TY_pointed(ST_type(WN_st(wn))), 01483 0/*size*/)); 01484 else 01485 base_ptr_ty = ST_type(WN_st(wn)); 01486 } 01487 else 01488 { 01489 /* Either not a dereference, or possibly a dereference off a 01490 * record/map/common/equivalence field. The base symbol is 01491 * not a pointer, and any dereferencing on a field will occur 01492 * in WN2F_Offset_Symref(). 01493 */ 01494 object_ty = WN_ty(wn); 01495 if ((TY_kind(object_ty)==KIND_POINTER) && 01496 (TY_is_f90_pointer(object_ty))) 01497 object_ty = TY_pointed(object_ty); 01498 01499 base_ptr_ty = ST_type(WN_st(wn)); 01500 if ((TY_kind(base_ptr_ty)==KIND_POINTER) && 01501 (TY_is_f90_pointer(base_ptr_ty))) 01502 ; 01503 else 01504 base_ptr_ty = Stab_Pointer_To(base_ptr_ty); 01505 } 01506 01507 if (!deref && STAB_IS_POINTER_REF_PARAM(WN_st(wn))) 01508 { 01509 /* Since we do not wish to dereference a load of a reference 01510 * parameter, this must mean we are taking the address of the 01511 * parameter. 01512 */ 01513 01514 } 01515 set_WN2F_CONTEXT_has_no_arr_elmt(context); 01516 WN2F_Offset_Symref(tokens, 01517 WN_st(wn), /* base-symbol */ 01518 base_ptr_ty, /* base-type */ 01519 object_ty, /* object-type */ 01520 WN_load_offset(wn), /* object-ofst */ 01521 context); 01522 reset_WN2F_CONTEXT_has_no_arr_elmt(context); 01523 01524 if (!deref && STAB_IS_POINTER_REF_PARAM(WN_st(wn))) 01525 { 01526 } 01527 } 01528 return EMPTY_WN2F_STATUS; 01529 } /* WN2F_ldid */ 01530 01531 01532 WN2F_STATUS 01533 WN2F_lda(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01534 { 01535 const BOOL deref = WN2F_CONTEXT_deref_addr(context); 01536 01537 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_LDA, 01538 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_lda")); 01539 ASSERT_DBG_FATAL(ST_class(WN_st(wn)) != CLASS_PREG, 01540 (DIAG_W2F_CANNOT_LDA_PREG)); 01541 01542 TY_IDX object_ty; 01543 01544 if (!deref) 01545 { 01546 /* A true address-of operation */ 01547 set_WN2F_CONTEXT_no_parenthesis(context); 01548 } 01549 01550 /* Sometimes we need to deal with buggy WHIRL code, where the TY 01551 * associated with an LDA is not a pointer type. For such cases 01552 * we infer a type here. 01553 */ 01554 01555 if (TY_Is_Pointer(WN_ty(wn)) ) 01556 { 01557 object_ty = TY_pointed(WN_ty(wn)); 01558 } 01559 else 01560 { 01561 /* May be wrong, but the best we can do under these exceptional */ 01562 /* circumstances. */ 01563 01564 object_ty = ST_type(WN_st(wn)); 01565 } 01566 01567 01568 ST * st = WN_st(wn); 01569 TY_IDX ty ; 01570 TY_IDX ty_1; 01571 reset_WN2F_CONTEXT_deref_addr(context); 01572 01573 if (ST_sym_class(st) == CLASS_BLOCK) 01574 { 01575 WN2F_Block(tokens,st,WN_lda_offset(wn),context); 01576 } 01577 else 01578 { 01579 if (TY_is_f90_pointer(ST_type(st))) 01580 ty_1= TY_pointed(ST_type(st)); 01581 else 01582 ty_1= ST_type(st); 01583 ty = Stab_Pointer_To(ty_1); 01584 01585 set_WN2F_CONTEXT_has_no_arr_elmt(context); 01586 WN2F_Offset_Symref(tokens, 01587 WN_st(wn), /* base-symbol */ 01588 ty, /* base type */ 01589 object_ty, /* object-type */ 01590 WN_lda_offset(wn), /* object-ofst */ 01591 context); 01592 reset_WN2F_CONTEXT_has_no_arr_elmt(context); 01593 } 01594 01595 return EMPTY_WN2F_STATUS; 01596 } /* WN2F_lda */ 01597 01598 WN2F_STATUS 01599 WN2F_arrayexp(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01600 { 01601 WN * kid; 01602 kid = WN_kid0(wn); 01603 WN2F_translate(tokens, kid, context); 01604 01605 return EMPTY_WN2F_STATUS; 01606 } 01607 01608 /******************************************************************************\ 01609 |* *| 01610 |* for array section triplet node,kid0 is lower bound,it should plus 1LL for *| 01611 |* adjusted bound,upper bound=kid0+k1*k2 *| 01612 |* kid0 evaluates to the starting integer value of the progression. *| 01613 |* kid1 evaluates to an integer value that gives the stride in the progression*| 01614 |* kid2 evaluates to the number of values in the progression *| 01615 |* *| 01616 \******************************************************************************/ 01617 01618 WN2F_STATUS 01619 WN2F_triplet(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01620 { 01621 WN *kid0; 01622 WN *kid1; 01623 WN *kid2; 01624 kid0=WN_kid0(wn); 01625 kid1=WN_kid1(wn); 01626 kid2=WN_kid2(wn); 01627 (void)WN2F_Denormalize_Array_Idx(tokens,kid0,context); 01628 if ((WN_opc_operator(kid2) == OPR_INTCONST) && 01629 (WN_const_val(kid2)==INT_MIN) ) 01630 Append_Token_Special(tokens, ':'); 01631 else { 01632 Append_Token_Special(tokens, ':'); 01633 if (WN_opc_operator(kid0) == OPR_INTCONST && 01634 WN_opc_operator(kid1) == OPR_INTCONST && 01635 WN_opc_operator(kid2) == OPR_INTCONST) { 01636 if ((WN_const_val(kid0)+WN_const_val(kid2)*WN_const_val(kid1))>=INT_MAX) 01637 TCON2F_translate(tokens, 01638 Host_To_Targ(MTYPE_I8, 01639 WN_const_val(kid0)+ 01640 WN_const_val(kid2)* 01641 WN_const_val(kid1)), 01642 FALSE); 01643 else 01644 01645 TCON2F_translate(tokens, 01646 Host_To_Targ(MTYPE_I4, 01647 WN_const_val(kid0)+ 01648 WN_const_val(kid2)* 01649 WN_const_val(kid1)), 01650 FALSE); 01651 01652 } 01653 else 01654 if (WN_opc_operator(kid0) == OPR_INTCONST && 01655 WN_opc_operator(kid1) == OPR_INTCONST ) { 01656 if (WN_const_val(kid1)==1) { 01657 if (WN_const_val(kid0)== 0) { 01658 WN2F_translate(tokens, kid2, context); 01659 } 01660 else { 01661 WN2F_translate(tokens, kid1, context); 01662 Append_Token_Special(tokens, '+'); 01663 WN2F_translate(tokens, kid2, context); } 01664 } 01665 else { 01666 if (WN_const_val(kid0)== 0){ 01667 WN2F_translate(tokens, kid1, context); 01668 Append_Token_Special(tokens, '*'); 01669 WN2F_translate(tokens, kid2, context); } 01670 else { 01671 WN2F_translate(tokens, kid0, context); 01672 Append_Token_Special(tokens, '+'); 01673 WN2F_translate(tokens, kid1, context); 01674 Append_Token_Special(tokens, '*'); 01675 WN2F_translate(tokens, kid2, context); } 01676 } 01677 } 01678 else 01679 if (WN_opc_operator(kid1) == OPR_INTCONST && 01680 WN_opc_operator(kid2) == OPR_INTCONST) { 01681 WN2F_translate(tokens, kid0, context); 01682 Append_Token_Special(tokens, '+'); 01683 01684 if ((WN_const_val(kid1)*WN_const_val(kid2))>=INT_MAX) 01685 01686 TCON2F_translate(tokens, 01687 Host_To_Targ(MTYPE_I8, 01688 WN_const_val(kid1)* 01689 WN_const_val(kid2)), 01690 FALSE); 01691 else 01692 TCON2F_translate(tokens, 01693 Host_To_Targ(MTYPE_I4, 01694 WN_const_val(kid1)* 01695 WN_const_val(kid2)), 01696 FALSE); 01697 } 01698 else 01699 if (WN_opc_operator(kid0) == OPR_INTCONST && 01700 WN_opc_operator(kid2) == OPR_INTCONST) { 01701 if (WN_const_val(kid2)==1) { 01702 if (WN_const_val(kid0)== 0) { 01703 WN2F_translate(tokens, kid1, context); 01704 } 01705 else { 01706 WN2F_translate(tokens, kid0, context); 01707 Append_Token_Special(tokens, '+'); 01708 WN2F_translate(tokens, kid1, context); 01709 } 01710 } 01711 else { 01712 if (WN_const_val(kid0)== 0){ 01713 WN2F_translate(tokens, kid2, context); 01714 Append_Token_Special(tokens, '*'); 01715 WN2F_translate(tokens, kid1, context); } 01716 else { 01717 WN2F_translate(tokens, kid0, context); 01718 Append_Token_Special(tokens, '+'); 01719 WN2F_translate(tokens, kid1, context); 01720 Append_Token_Special(tokens, '*'); 01721 WN2F_translate(tokens, kid2, context); } 01722 } 01723 } 01724 else 01725 if (WN_opc_operator(kid0) == OPR_INTCONST){ 01726 if (WN_const_val(kid0)==0) { 01727 WN2F_translate(tokens, kid1, context); 01728 Append_Token_Special(tokens, '*'); 01729 WN2F_translate(tokens, kid2, context);} 01730 else { 01731 WN2F_translate(tokens, kid0, context); 01732 Append_Token_Special(tokens, '+'); 01733 WN2F_translate(tokens, kid1, context); 01734 Append_Token_Special(tokens, '*'); 01735 WN2F_translate(tokens, kid2, context); 01736 } 01737 } 01738 else 01739 if (WN_opc_operator(kid1) == OPR_INTCONST){ 01740 WN2F_translate(tokens, kid0, context); 01741 Append_Token_Special(tokens, '+'); 01742 if (WN_const_val(kid1)==1){ 01743 WN2F_translate(tokens, kid2, context);} 01744 else { 01745 WN2F_translate(tokens, kid1, context); 01746 Append_Token_Special(tokens, '*'); 01747 WN2F_translate(tokens, kid2, context); 01748 } 01749 } 01750 else 01751 if (WN_opc_operator(kid2) == OPR_INTCONST) { 01752 WN2F_translate(tokens, kid0, context); 01753 Append_Token_Special(tokens, '+'); 01754 if (WN_const_val(kid2)==1) 01755 WN2F_translate(tokens, kid1, context); 01756 else 01757 { 01758 WN2F_translate(tokens, kid2, context); 01759 Append_Token_Special(tokens, '*'); 01760 WN2F_translate(tokens, kid1, context); 01761 } 01762 } 01763 if ((WN_opc_operator(kid1) == OPR_INTCONST) && 01764 (WN_const_val(kid1)==1)) { 01765 } else { 01766 Append_Token_Special(tokens, ':'); 01767 WN2F_translate(tokens, kid1, context); 01768 } 01769 } 01770 return EMPTY_WN2F_STATUS; 01771 01772 } 01773 /******************************************************************************\ 01774 |* *| 01775 |* *| 01776 \******************************************************************************/ 01777 01778 WN2F_STATUS 01779 WN2F_src_triplet(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01780 { 01781 WN *kid0; 01782 WN *kid1; 01783 WN *kid2; 01784 kid0=WN_kid0(wn); 01785 kid1=WN_kid1(wn); 01786 kid2=WN_kid2(wn); 01787 WN2F_translate(tokens, kid0, context); 01788 Append_Token_Special(tokens, ':'); 01789 WN2F_translate(tokens, kid1, context); 01790 01791 if (WN_operator(kid2) == OPR_INTCONST && 01792 WN_const_val(kid2) == 1) 01793 ; 01794 else { 01795 Append_Token_Special(tokens, ':'); 01796 WN2F_translate(tokens, kid2, context); 01797 } 01798 01799 return EMPTY_WN2F_STATUS; 01800 01801 } 01802 01803 WN2F_STATUS 01804 WN2F_arrsection(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01805 { 01806 /* Note that array indices have been normalized to assume the 01807 * array is based at index zero. Since a base at index 1 is 01808 * the default for Fortran, we denormalize to base 1 here. 01809 */ 01810 BOOL deref = WN2F_CONTEXT_deref_addr(context); 01811 WN * kid; 01812 TY_IDX ptr_ty; 01813 TY_IDX array_ty; 01814 01815 01816 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_ARRAY, 01817 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_array")); 01818 01819 /* Only allow taking the address of an array element for F90! 01820 * 01821 */ 01822 #if 0 01823 else 01824 ASSERT_DBG_WARN(deref, 01825 (DIAG_UNIMPLEMENTED, 01826 "taking the address of an array element")); 01827 #endif 01828 01829 /* Get the array or, for ptr-as-array types, the element type */ 01830 01831 kid = WN_kid0(wn); 01832 if (WN_operator(kid) == OPR_ILOAD && 01833 WN_operator(WN_kid0(kid)) == OPR_STRCTFLD) 01834 kid = WN_kid0(kid) ; 01835 01836 ptr_ty = WN_Tree_Type(kid); 01837 01838 01839 01840 if (WN2F_Is_Address_Preg(kid,ptr_ty)) 01841 { 01842 /* a preg or sym has been used as an address, usually after optimization 01843 */ 01844 /* don't know base type, or anything else so use OPR_ARRAY to generate bounds 01845 */ 01846 01847 WN2F_translate(tokens, kid, context); 01848 WN2F_Arrsection_Slots(tokens,wn,ptr_ty,context,TRUE); 01849 } 01850 else 01851 { 01852 01853 if (WN_operator(kid)==OPR_STRCTFLD) 01854 array_ty = WN_ty(kid); 01855 else 01856 array_ty = W2F_TY_pointed(ptr_ty, "base of OPC_ARRAY"); 01857 01858 if (WN_opc_operator(kid) == OPR_LDID && 01859 ST_sclass(WN_st(kid)) == SCLASS_FORMAL && 01860 !ST_is_value_parm(WN_st(kid)) && 01861 WN_element_size(wn) == TY_size(array_ty) && 01862 WN_num_dim(wn) == 1 && 01863 WN_opc_operator(WN_array_index(wn, 0)) == OPR_INTCONST && 01864 WN_const_val(WN_array_index(wn, 0)) == 0 && 01865 !TY_ptr_as_array(Ty_Table[WN_ty(kid)]) && 01866 (!TY_Is_Array(array_ty) || 01867 TY_size(TY_AR_etype(array_ty)) < TY_size(array_ty))) 01868 { 01869 /* This array access is just a weird representation for an implicit 01870 * reference parameter dereference. Ignore the array indexing. 01871 */ 01872 01873 WN2F_translate(tokens, kid, context); 01874 } 01875 else if (!TY_ptr_as_array(Ty_Table[ptr_ty]) && TY_Is_Character_String(array_ty)) 01876 { 01877 /* We assume that substring accesses are treated in the handling 01878 * of intrinsic functions, except when the substrings are to be 01879 * handled as integral types and thus are encountered here. 01880 */ 01881 #if 0 01882 if (!WN2F_F90_pu) 01883 { 01884 Append_Token_String(tokens, "ichar"); 01885 Append_Token_Special(tokens, '('); 01886 } 01887 # endif 01888 01889 WN2F_String_Argument(tokens, wn, WN2F_INTCONST_ONE, context); 01890 # if 0 01891 01892 if (!WN2F_F90_pu) 01893 Append_Token_Special(tokens, ')'); 01894 # endif 01895 01896 } 01897 else /* A regular array access */ 01898 { 01899 /* Get the base of the object to be indexed into, still using 01900 * WN2F_CONTEXT_deref_addr(context). 01901 */ 01902 WN2F_translate(tokens, kid, context); 01903 reset_WN2F_CONTEXT_deref_addr(context); 01904 01905 if ( WN2F_CONTEXT_has_no_arr_elmt(context)) 01906 ; 01907 else 01908 WN2F_arrsection_bounds(tokens,wn,array_ty,context); 01909 } 01910 } 01911 return EMPTY_WN2F_STATUS; 01912 } /* WN2F_arrsection */ 01913 01914 01915 WN2F_STATUS 01916 WN2F_where(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01917 { 01918 WN *kid; 01919 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 01920 Append_Token_String(tokens,"WHERE"); 01921 Append_Token_Special(tokens, '('); 01922 kid =WN_kid0(wn); 01923 WN2F_translate(tokens, kid, context); 01924 Append_Token_Special(tokens, ')'); 01925 kid =WN_kid1(wn); 01926 WN2F_translate(tokens, kid, context); 01927 kid = WN_kid2(wn); 01928 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_Get_Linenum(wn), context); 01929 Append_Token_String(tokens,"END WHERE"); 01930 WN2F_translate(tokens, kid, context); 01931 return EMPTY_WN2F_STATUS; 01932 } 01933 01934 01935 WN2F_STATUS 01936 WN2F_array(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01937 { 01938 /* Note that array indices have been normalized to assume the 01939 * array is based at index zero. Since a base at index 1 is 01940 * the default for Fortran, we denormalize to base 1 here. 01941 */ 01942 BOOL deref = WN2F_CONTEXT_deref_addr(context); 01943 01944 WN * kid; 01945 TY_IDX ptr_ty; 01946 TY_IDX array_ty; 01947 01948 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_ARRAY, 01949 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_array")); 01950 01951 /* Only allow taking the address of an array element for F90! 01952 * 01953 */ 01954 #if 0 01955 else 01956 ASSERT_DBG_WARN(deref, 01957 (DIAG_UNIMPLEMENTED, 01958 "taking the address of an array element")); 01959 #endif 01960 01961 /* Get the array or, for ptr-as-array types, the element type */ 01962 01963 kid = WN_kid0(wn); 01964 01965 if (WN_operator(kid)==OPR_ILOAD && 01966 WN_operator(WN_kid0(kid))==OPR_STRCTFLD ) //F90 pointer 01967 kid = WN_kid0(kid); 01968 01969 ptr_ty = WN_Tree_Type(kid); 01970 01971 if (WN2F_Is_Address_Preg(kid,ptr_ty)) 01972 { 01973 /* a preg or sym has been used as an address, usually after optimization */ 01974 /* don't know base type, or anything else so use OPR_ARRAY to generate bounds */ 01975 WN2F_translate(tokens, kid, context); 01976 WN2F_Array_Slots(tokens,wn, ptr_ty, context,TRUE); 01977 /* need to take example to see if it's OK to use ptr_ty here*/ 01978 } 01979 else 01980 { 01981 array_ty = W2F_TY_pointed(ptr_ty, "base of OPC_ARRAY"); 01982 01983 if (WN_opc_operator(kid) == OPR_LDID && 01984 ST_sclass(WN_st(kid)) == SCLASS_FORMAL && 01985 !ST_is_value_parm(WN_st(kid)) && 01986 WN_element_size(wn) == TY_size(array_ty) && 01987 WN_num_dim(wn) == 1 && 01988 WN_opc_operator(WN_array_index(wn, 0)) == OPR_INTCONST && 01989 WN_const_val(WN_array_index(wn, 0)) == 0 && 01990 !TY_ptr_as_array(Ty_Table[WN_ty(kid)]) && 01991 (!TY_Is_Array(array_ty) || 01992 TY_size(TY_AR_etype(array_ty)) < TY_size(array_ty))) 01993 { 01994 /* This array access is just a weird representation for an implicit 01995 * reference parameter dereference. Ignore the array indexing. 01996 */ 01997 WN2F_translate(tokens, kid, context); 01998 } 01999 else if (!TY_ptr_as_array(Ty_Table[ptr_ty]) && 02000 TY_Is_Character_String(array_ty) ) 02001 { 02002 /* We assume that substring accesses are treated in the handling 02003 * of intrinsic functions, except when the substrings are to be 02004 * handled as integral types and thus are encountered here. 02005 */ 02006 # if 0 02007 if (!WN2F_F90_pu) 02008 { 02009 Append_Token_String(tokens, "ichar"); 02010 Append_Token_Special(tokens, '('); 02011 } 02012 # endif 02013 02014 WN2F_String_Argument(tokens, wn, WN2F_INTCONST_ONE, context); 02015 02016 # if 0 02017 if (!WN2F_F90_pu) 02018 Append_Token_Special(tokens, ')'); 02019 # endif 02020 02021 } 02022 else /* A regular array access */ 02023 { 02024 /* Get the base of the object to be indexed into, still using 02025 * WN2F_CONTEXT_deref_addr(context). 02026 */ 02027 // if (WN_operator(kid) == OPR_ADD || WN_operator(kid)==OPR_ARRAY) 02028 if (WN_operator(kid) == OPR_ADD) 02029 { 02030 02031 STAB_OFFSET offset =(WN_operator(kid) == OPR_ADD)?WN_const_val(WN_kid1(kid)):0; 02032 02033 WN2F_translate(tokens,WN_kid0(kid),context); 02034 02035 #if 0 02036 FLD_PATH_INFO *fld_path; 02037 if (!fld_type_z) 02038 fld_type_z = array_ty; 02039 fld_path = TY2F_Get_Fld_Path(fld_type_z,fld_type_z, offset); 02040 02041 if (fld_path){ 02042 TY2F_Fld_Separator(tokens); 02043 FLD_HANDLE f (fld_path->fld); 02044 fld_type_z = FLD_type(f); 02045 02046 while (TY_Is_Pointer(fld_type_z)) 02047 fld_type_z = TY_pointed(fld_type_z); 02048 02049 if (TY_kind(fld_type_z) == KIND_ARRAY) 02050 fld_type_z = TY_etype(fld_type_z); 02051 02052 Append_Token_String(tokens, 02053 TY2F_Fld_Name(f,FALSE,FALSE)); 02054 02055 } else 02056 Append_Token_String(tokens, 02057 Number_as_String(offset, 02058 "<field-at-offset=%lld>")); 02059 #endif 02060 02061 } 02062 else { 02063 WN2F_translate(tokens, kid, context); 02064 } 02065 02066 reset_WN2F_CONTEXT_deref_addr(context); 02067 WN2F_array_bounds(tokens,wn,array_ty,context); 02068 } 02069 } 02070 return EMPTY_WN2F_STATUS; 02071 } /* WN2F_array */ 02072 02073 02074 void 02075 WN2F_Arrsection_Slots(TOKEN_BUFFER tokens, WN *wn,TY_IDX array_ty,WN2F_CONTEXT context,BOOL parens) 02076 { 02077 INT32 dim; 02078 WN * kidz; 02079 INT32 co_dim; 02080 INT32 array_dim; 02081 TY_IDX ttyy; 02082 ARB_HANDLE arb_base; 02083 WN* kid; 02084 02085 02086 /* Gets bounds from the slots of an OPC_ARRSECTION node */ 02087 02088 /* Append the "denormalized" indexing expressions in reverse order 02089 * of the way they occur in the indexing expression, since Fortran 02090 * employs column-major array layout, meaning the leftmost indexing 02091 * expression represents array elements laid out in contiguous 02092 * memory locations. 02093 */ 02094 02095 ttyy = array_ty; 02096 02097 if (TY_Is_Pointer(ttyy)) 02098 ttyy=TY_pointed(ttyy); 02099 if (TY_is_f90_pointer(ttyy)) 02100 ttyy = TY_pointed(ttyy); 02101 02102 arb_base = TY_arb(ttyy); 02103 02104 dim = ARB_dimension(arb_base); 02105 co_dim = ARB_co_dimension(arb_base); 02106 02107 02108 if (dim > WN_num_dim(wn) ) { 02109 02110 array_dim = dim-co_dim; 02111 co_dim = 0; 02112 } 02113 else { 02114 dim = WN_num_dim(wn); 02115 array_dim = dim; 02116 } 02117 02118 02119 if (array_dim>0) { 02120 if (parens) 02121 { 02122 Append_Token_Special(tokens, '('); 02123 set_WN2F_CONTEXT_no_parenthesis(context); 02124 } 02125 # if 0 /* add co_array dimensions */ 02126 for (dim = WN_num_dim(wn)-1; dim >= 0; dim--) 02127 { 02128 if (WN_opc_operator(WN_array_index(wn, dim))==OPR_SRCTRIPLET) { 02129 WN2F_translate(tokens, WN_array_index(wn, dim), context); 02130 } 02131 else { 02132 (void)WN2F_Denormalize_Array_Idx(tokens, 02133 WN_array_index(wn, dim), 02134 context); 02135 } 02136 if (dim > 0) 02137 Append_Token_Special(tokens, ','); 02138 } 02139 # endif 02140 for (dim = WN_num_dim(wn)-1; dim >= co_dim; dim--) 02141 { 02142 if (WN_opc_operator(WN_array_index(wn, dim))==OPR_SRCTRIPLET) { 02143 WN2F_translate(tokens, WN_array_index(wn, dim), context); 02144 } 02145 else { 02146 (void)WN2F_Denormalize_Array_Idx(tokens, 02147 WN_array_index(wn, dim), 02148 context); 02149 } 02150 if (dim > co_dim) 02151 Append_Token_Special(tokens, ','); 02152 } 02153 if (parens) 02154 Append_Token_Special(tokens, ')'); 02155 } 02156 02157 if (co_dim > 0) { 02158 02159 if (parens) 02160 Append_Token_Special(tokens, '['); 02161 02162 for (dim = co_dim-1; dim >= 0; dim--) 02163 { 02164 if (WN_opc_operator(WN_array_index(wn, dim))==OPR_SRCTRIPLET) { 02165 WN2F_translate(tokens, WN_array_index(wn, dim), context); 02166 } 02167 else { 02168 (void)WN2F_Denormalize_Array_Idx(tokens, 02169 WN_array_index(wn, dim), 02170 context); 02171 } 02172 if (dim > 0) 02173 Append_Token_Special(tokens, ','); 02174 } 02175 02176 02177 if (parens) 02178 Append_Token_Special(tokens, ']'); 02179 } 02180 } 02181 02182 void 02183 WN2F_Array_Slots(TOKEN_BUFFER tokens, WN *wn,TY_IDX array_ty,WN2F_CONTEXT context,BOOL parens) 02184 { 02185 INT32 dim; 02186 WN * kid; 02187 INT32 co_dim; 02188 INT32 array_dim; 02189 ARB_HANDLE arb_base; 02190 TY_IDX ttyy; 02191 02192 02193 /* get array's rank and co_rank information from kid0 of wn 02194 * kid0 should be OPR_LDA 02195 *coarray reference is legal without co_rank 02196 *so we have to use dim plus kid_number to 02197 *see if there is co_rank or not 02198 */ 02199 02200 kid = WN_kid0(wn); 02201 02202 if (WN_operator(kid)==OPR_LDA) 02203 { 02204 ttyy = array_ty; 02205 02206 if (TY_Is_Pointer(ttyy)) 02207 ttyy =TY_pointed(ttyy); 02208 if (TY_is_f90_pointer(ttyy)) 02209 ttyy = TY_pointed(ttyy); 02210 02211 arb_base = TY_arb(ttyy); 02212 02213 dim = ARB_dimension(arb_base); 02214 co_dim = ARB_co_dimension(arb_base); 02215 } else { 02216 co_dim =0; 02217 dim = WN_num_dim(wn); 02218 } 02219 02220 02221 if (dim > WN_num_dim(wn) ) { 02222 array_dim = dim-co_dim; 02223 co_dim = 0; 02224 } 02225 else { 02226 dim = WN_num_dim(wn); 02227 array_dim = dim-co_dim; 02228 } 02229 02230 02231 02232 /* Gets bounds from the slots of an OPC_ARRAY node */ 02233 02234 /* Append the "denormalized" indexing expressions in reverse order 02235 * of the way they occur in the indexing expression, since Fortran 02236 * employs column-major array layout, meaning the leftmost indexing 02237 * expression represents array elements laid out in contiguous 02238 * memory locations. 02239 */ 02240 02241 if (array_dim > 0 ) { 02242 Append_Token_Special(tokens, '('); 02243 set_WN2F_CONTEXT_no_parenthesis(context); 02244 02245 02246 for (dim = WN_num_dim(wn)-1; dim >= co_dim; dim--) 02247 { 02248 (void)WN2F_Denormalize_Array_Idx(tokens, 02249 WN_array_index(wn, dim), 02250 context); 02251 02252 if (dim > co_dim) 02253 Append_Token_Special(tokens, ','); 02254 } 02255 02256 02257 Append_Token_Special(tokens, ')'); 02258 } 02259 02260 /* for co_rank */ 02261 02262 if (co_dim > 0) { 02263 Append_Token_Special(tokens, '['); 02264 for (dim = co_dim-1; dim >= 0; dim--) 02265 { 02266 (void)WN2F_Denormalize_Array_Idx(tokens, 02267 WN_array_index(wn, dim), 02268 context); 02269 02270 if (dim > 0) 02271 Append_Token_Special(tokens, ','); 02272 } 02273 02274 Append_Token_Special(tokens, ']'); 02275 02276 } 02277 } 02278 02279 void 02280 WN2F_arrsection_bounds(TOKEN_BUFFER tokens, WN *wn, TY_IDX array_ty,WN2F_CONTEXT context) 02281 { 02282 /* This prints the array subscript expression. It was part of 02283 * WN2F_array, but was split so it could be used for bounds 02284 * of structure components. 02285 */ 02286 02287 INT32 dim; 02288 02289 if (TY_is_f90_pointer(array_ty)) 02290 array_ty = TY_pointed(array_ty);//Sept 02291 02292 if (TY_Is_Array(array_ty) && TY_AR_ndims(array_ty) >= WN_num_dim(wn)) 02293 { 02294 /* Cannot currently handle differing element sizes at place of 02295 * array declaration versus place of array access (TODO?). 02296 */ 02297 02298 ASSERT_DBG_WARN((TY_size(TY_AR_etype(array_ty)) == WN_element_size(wn)) || 02299 WN_element_size(wn) < 0 || 02300 TY_size(TY_AR_etype(array_ty)) == 0, 02301 (DIAG_UNIMPLEMENTED, 02302 "access/declaration mismatch in array element size")); 02303 02304 WN2F_Arrsection_Slots(tokens,wn,array_ty,context,TRUE); 02305 02306 /* We handle the case when an array is declared to have more 02307 * dimensions than that given by this array addressing expression. 02308 */ 02309 # if 0 //could be co_array object 02310 02311 if (TY_AR_ndims(array_ty) > WN_num_dim(wn)) 02312 { 02313 /* Substitute in '1' for the missing dimensions */ 02314 for (dim = TY_AR_ndims(array_ty) - WN_num_dim(wn); dim > 0; dim--) 02315 { 02316 Append_Token_Special(tokens, ','); 02317 Append_Token_String(tokens, "1"); 02318 } 02319 } 02320 # endif 02321 } 02322 else /* Normalize array access to assume a single dimension */ 02323 { 02324 ASSERT_DBG_WARN(!TY_Is_Array(array_ty) || TY_AR_ndims(array_ty) == 1, 02325 (DIAG_UNIMPLEMENTED, 02326 "access/declaration mismatch in array dimensions")); 02327 02328 WN2F_Normalize_Idx_To_Onedim(tokens, wn, context); 02329 } 02330 02331 } 02332 02333 02334 void 02335 WN2F_array_bounds(TOKEN_BUFFER tokens, WN *wn, TY_IDX array_ty,WN2F_CONTEXT context) 02336 { 02337 /* This prints the array subscript expression. It was part of 02338 * WN2F_array, but was split so it could be used for bounds 02339 * of structure components. 02340 */ 02341 02342 INT32 dim; 02343 WN * kid; 02344 02345 // Append_Token_Special(tokens, '('); 02346 // set_WN2F_CONTEXT_no_parenthesis(context); 02347 02348 if (TY_is_f90_pointer(array_ty)) 02349 array_ty = TY_pointed(array_ty); 02350 02351 if (TY_Is_Array(array_ty) && TY_AR_ndims(array_ty) >= WN_num_dim(wn) || TRUE) 02352 { 02353 /* Cannot currently handle differing element sizes at place of 02354 * array declaration versus place of array access (TODO?). 02355 */ 02356 02357 ASSERT_DBG_WARN((TY_size(TY_AR_etype(array_ty)) == WN_element_size(wn)) || 02358 WN_element_size(wn) < 0 || 02359 TY_size(TY_AR_etype(array_ty)) == 0, 02360 (DIAG_UNIMPLEMENTED, 02361 "access/declaration mismatch in array element size")); 02362 02363 WN2F_Array_Slots(tokens,wn,array_ty,context,FALSE); 02364 02365 /* We handle the case when an array is declared to have more 02366 * dimensions than that given by this array addressing expression. 02367 * COMMENT ABOVE IS FROM ORIGINAL VERSION ,belowing added by zhao 02368 * this could be happend when co_rank doesn't appear,don't need add 02369 * 02370 */ 02371 #if 0 02372 if (TY_AR_ndims(array_ty) > WN_num_dim(wn)) 02373 { 02374 02375 /* Substitute in '1' for the missing dimensions */ 02376 for (dim = TY_AR_ndims(array_ty) - WN_num_dim(wn); dim > 0; dim--) 02377 { 02378 Append_Token_Special(tokens, ','); 02379 Append_Token_String(tokens, "1"); 02380 } 02381 } 02382 #endif 02383 02384 } 02385 else /* Normalize array access to assume a single dimension */ 02386 { 02387 ASSERT_DBG_WARN(!TY_Is_Array(array_ty) || TY_AR_ndims(array_ty) == 1, 02388 (DIAG_UNIMPLEMENTED, 02389 "access/declaration mismatch in array dimensions")); 02390 02391 WN2F_Normalize_Idx_To_Onedim(tokens, wn, context); 02392 } 02393 // Append_Token_Special(tokens, ')'); 02394 } 02395 02396 /*----------- Character String Manipulation Translation ---------------*/ 02397 /*---------------------------------------------------------------------*/ 02398 02399 void 02400 WN2F_String_Argument(TOKEN_BUFFER tokens, 02401 WN *base_parm, 02402 WN *length, 02403 WN2F_CONTEXT context) 02404 { 02405 /* Append the tokens denoting the substring expression represented 02406 * by the base-expression. 02407 * 02408 * There are two possibilities concerning the array base 02409 * expressions. It can be a pointer to a complete character- 02410 * string (array) or it can be a pointer to a character within 02411 * a character-string (single character). In the first instance, 02412 * the offset off the base of string is zero. In the latter 02413 * case, the offset is given by the array indexing operation. 02414 * 02415 * NOTE: In some cases (notably for IO_ITEMs), we may try to 02416 * derive a substring off an OPC_VINTRINSIC_CALL node or a 02417 * VCALL node. This should only happend when the returned value 02418 * is the first argument and the length is the second argument. 02419 */ 02420 WN *base = WN_Skip_Parm(base_parm); 02421 WN *lower_bnd; 02422 WN *length_new; 02423 WN *arg_expr; 02424 TY_IDX str_ty; 02425 INT64 str_length; 02426 02427 /* Skip any INTR_ADRTMP and INTR_VALTMP nodes */ 02428 if (WN_opc_operator(base) == OPR_INTRINSIC_OP && 02429 (INTR_is_adrtmp(WN_intrinsic(base)) || 02430 INTR_is_valtmp(WN_intrinsic(base)))) 02431 { 02432 base = WN_kid0(base); 02433 } 02434 02435 02436 if (WN_operator(base) == OPR_CVTL) 02437 { 02438 /* probably CHAR(INT) within IO stmt. convert via CHAR & process rest elsewhere */ 02439 02440 Append_Token_Special(tokens, '('); 02441 Append_Token_String(tokens, "char"); 02442 WN2F_translate(tokens,WN_kid0(base),context); 02443 Append_Token_Special(tokens, ')'); 02444 return; 02445 } 02446 02447 02448 /* Handle VCALLs specially, since the string information is given 02449 * by the first two arguments to the call. Note that we can 02450 * always assume a lower bound of zero for these, as we never 02451 * generate code for the return-address. This should only occur 02452 * within an IO stmt. Note that the type of VCALLs must be 02453 * accessed in the context of an ADRTMP or VALTMP. 02454 */ 02455 if (WN_opcode(base) == OPC_VCALL || 02456 WN_opcode(base) == OPC_VINTRINSIC_CALL) 02457 { 02458 arg_expr = WN_Skip_Parm(WN_kid1(base)); 02459 lower_bnd = WN2F_INTCONST_ZERO; 02460 02461 /* fixed size string? */ 02462 02463 if (WN_opc_operator(arg_expr) == OPR_INTCONST) 02464 str_length = WN_const_val(arg_expr); 02465 else 02466 str_length = -1 ; 02467 02468 set_WN2F_CONTEXT_deref_addr(context); 02469 WN2F_translate(tokens, base, context); 02470 reset_WN2F_CONTEXT_deref_addr(context); 02471 02472 } 02473 else 02474 { 02475 /* A regular address expression as base */ 02476 #if 0 02477 WN2F_Get_Substring_Info(&base, &str_ty, &lower_bnd,&length_new); 02478 02479 /* Was this a character component of an array of derived type? */ 02480 /* eg: vvv(2)%ccc(:)(1:5) - offset to ccc is added above base, */ 02481 /* ADD(8,ARRAY(2,LDA VVV)) with array section for CCC on top */ 02482 /* of the ADD, and the substring above the array section. Take */ 02483 /* the substring off the top, and process the rest */ 02484 02485 if (TY_kind(str_ty) == KIND_STRUCT) 02486 { 02487 FLD_PATH_INFO *fld_path ; 02488 FLD_HANDLE fld; 02489 TY_IDX ty_idx ; 02490 02491 TY & ty = New_TY(ty_idx); 02492 02493 TY_Init (ty, 1, KIND_SCALAR, MTYPE_U1, Save_Str(".w2fch.")); 02494 Set_TY_is_character(ty); 02495 02496 fld_path = TY2F_Get_Fld_Path(str_ty, 02497 ty_idx, 02498 WN2F_Sum_Offsets(base)); 02499 02500 fld = TY2F_Last_Fld(fld_path); 02501 TY2F_Free_Fld_Path(fld_path); 02502 02503 /* call memref for FLD offset, otherwise the ADD is */ 02504 /* just another binary op */ 02505 WN2F_Offset_Memref(tokens, 02506 WN_kid0(base), 02507 WN_Tree_Type(base), 02508 FLD_type(fld), 02509 0, 02510 context); 02511 } 02512 else 02513 { 02514 str_length = TY_size(str_ty); 02515 02516 /* with optimization, may not have useful address TY 02517 * when TreeType will return array of U1 from SubstringInfo */ 02518 02519 ASSERT_DBG_WARN(TY_Is_Character_String(str_ty) || TY_Is_Array_Of_UChars(str_ty), 02520 (DIAG_W2F_EXPECTED_PTR_TO_CHARACTER, 02521 "WN2F_String_Argument")); 02522 02523 /* Get the string base and substring notation for the argument. */ 02524 set_WN2F_CONTEXT_deref_addr(context); 02525 WN2F_translate(tokens, base, context); 02526 reset_WN2F_CONTEXT_deref_addr(context); 02527 } 02528 02529 if (length_new != WN2F_INTCONST_ZERO && !WN2F_CONTEXT_has_no_arr_elmt(context)) 02530 WN2F_Substring(tokens, 02531 str_length, 02532 lower_bnd, 02533 // WN_Skip_Parm(length), 02534 length_new, 02535 context); 02536 #else 02537 02538 { 02539 WN * base1; 02540 if (WN_operator(base)==OPR_ARRAY) 02541 base1 = WN_kid0(base); 02542 else 02543 if (WN_operator(base)==OPR_ARRAYEXP && 02544 WN_operator(WN_kid0(base))==OPR_ARRAY) 02545 base1 = WN_kid0(WN_kid0(base)); 02546 else 02547 base1 = base; 02548 02549 WN2F_translate(tokens, base1, context); 02550 } 02551 02552 WN2F_Get_Substring_Info(&base, &str_ty, &lower_bnd,&length_new); 02553 str_length = TY_size(str_ty); 02554 02555 if (length_new != WN2F_INTCONST_ZERO && !WN2F_CONTEXT_has_no_arr_elmt(context)) 02556 WN2F_Substring(tokens, 02557 str_length, 02558 lower_bnd, 02559 length_new, 02560 context); 02561 else 02562 reset_WN2F_CONTEXT_has_no_arr_elmt(context); 02563 #endif 02564 return ; 02565 } 02566 } /* WN2F_String_Argument */ 02567 02568 02569 /*----------- Miscellaneous routines ---------------------------------*/ 02570 /*---------------------------------------------------------------------*/ 02571 02572 static void 02573 WN2F_Block(TOKEN_BUFFER tokens, ST * st, STAB_OFFSET offset,WN2F_CONTEXT context) 02574 { 02575 /* An ST of CLASS_BLOCK may appear in f90 IO, at -O2 */ 02576 /* put out something for the whirl browser */ 02577 02578 ST2F_use_translate(tokens,st); 02579 02580 if (offset != 0) 02581 { 02582 Append_Token_Special(tokens, '+'); 02583 Append_Token_String(tokens, Number_as_String(offset, "%lld")); 02584 } 02585 } 02586 02587 02588 WN2F_STATUS 02589 WN2F_strctfld(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 02590 { 02591 TY_IDX ty1,ty2; 02592 char * fld_name; 02593 FLD_HANDLE fld; 02594 UINT field_id ; 02595 02596 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_STRCTFLD, 02597 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_strctfld")); 02598 02599 if (!WN_kid0(wn)) 02600 Append_Token_String(tokens,"Null kid here"); 02601 else 02602 WN2F_translate(tokens,WN_kid0(wn),context); 02603 02604 ty2 = WN_load_addr_ty(wn); 02605 Is_True (TY_kind(ty2) == KIND_STRUCT, ("expecting KIND_STRUCT")); 02606 field_id = WN_field_id(wn); 02607 fld = TY_fld(ty2); 02608 field_id--; 02609 while (field_id && !FLD_last_field(fld)) { 02610 --field_id ; 02611 fld = FLD_next(fld); 02612 } 02613 02614 //TODO: add assertion about field_id ? Must be resonable value based 02615 // on the structure and field type 02616 fld_name = FLD_name(fld); 02617 Append_Token_Special(tokens,'%'); 02618 Append_Token_String(tokens,fld_name); 02619 02620 return EMPTY_WN2F_STATUS; 02621 } 02622 02623 02624 WN2F_STATUS 02625 WN2F_comma(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 02626 { 02627 WN2F_translate(tokens,WN_kid1(wn),context); 02628 return EMPTY_WN2F_STATUS; 02629 }