|
OpenADFortTk (basic)
|
00001 // ########################################################## 00002 // # This file is part of OpenADFortTk. # 00003 // # The full COPYRIGHT notice can be found in the top # 00004 // # level directory of the OpenADFortTk source tree. # 00005 // # For more information visit # 00006 // # http://www.mcs.anl.gov/openad # 00007 // ########################################################## 00008 00009 #include "Open64IRInterface/Open64BasicTypes.h" 00010 #include "Open64IRInterface/IntrinsicInfo.h" 00011 00012 #include "wn2xaif.h" 00013 #include "wn2xaif_expr.h" 00014 #include "wn2xaif_mem.h" 00015 #include "ty2xaif.h" 00016 #include "st2xaif.h" 00017 00018 using namespace whirl2xaif; 00019 using namespace xml; // for xml::ostream, etc 00020 00021 static void 00022 xlate_UnaryOpUsingIntrinsicTable(xml::ostream& xos, OPCODE opcode, 00023 TY_IDX result_ty, 00024 WN* wn, PUXlationContext& ctxt); 00025 00026 static void 00027 xlate_BinaryOpUsingIntrinsicTable(xml::ostream& xos, OPCODE opcode, 00028 TY_IDX result_ty, 00029 WN *wn0, WN *wn1, PUXlationContext& ctxt); 00030 00031 static void 00032 xlate_Operand(xml::ostream& xos, WN *opnd, TY_IDX assumed_ty, BOOL callByValue, 00033 PUXlationContext& ctxt); 00034 00035 //*************************************************************************** 00036 00037 /*------------------------- Value Conversions -------------------------*/ 00038 /*---------------------------------------------------------------------*/ 00039 00040 /* Create a mapping from a pair of MTYPEs to the Fortran intrinsic 00041 * or builtin operation that carries out the conversion. NULL means 00042 * that either the conversion is redundant and can be ignored or there 00043 * is no way we can do it. 00044 */ 00045 static const char *Conv_Op[MTYPE_LAST+1][MTYPE_LAST+1]; 00046 static bool Conv_OpInitialized = false; 00047 00048 typedef struct Conv_Op 00049 { 00050 MTYPE from, to; 00051 const char *name; 00052 } CONV_OP; 00053 00054 #define NUMBER_OF_CONV_OPS sizeof(Conv_Op_Map)/sizeof(CONV_OP) 00055 00056 static const CONV_OP Conv_Op_Map[] = 00057 { 00058 /* from | to | op-name */ 00059 00060 /* Only consider conversion to ptr sized unsigned numbers 00061 * valid in Fortran. 00062 */ 00063 {MTYPE_I1, MTYPE_U4, "C_JZEXT"}, 00064 {MTYPE_I2, MTYPE_U4, "C_JZEXT"}, 00065 {MTYPE_I4, MTYPE_U4, "C_JZEXT"}, 00066 {MTYPE_I8, MTYPE_U4, "C_JZEXT"}, 00067 /*{MTYPE_U1, MTYPE_U4, ""},*/ 00068 /*{MTYPE_U2, MTYPE_U4, ""},*/ 00069 /*{MTYPE_U4, MTYPE_U4, ""},*/ 00070 {MTYPE_U8, MTYPE_U4, "C_JZEXT"}, 00071 00072 {MTYPE_I1, MTYPE_U8, "C_KZEXT"}, 00073 {MTYPE_I2, MTYPE_U8, "C_KZEXT"}, 00074 {MTYPE_I4, MTYPE_U8, "C_KZEXT"}, 00075 {MTYPE_I8, MTYPE_U8, "C_KZEXT"}, 00076 /*{MTYPE_U1, MTYPE_U8, ""},*/ 00077 /*{MTYPE_U2, MTYPE_U8, ""},*/ 00078 /*{MTYPE_U4, MTYPE_U8, ""},*/ 00079 /*{MTYPE_U8, MTYPE_U8, ""},*/ 00080 00081 /*{MTYPE_I1, MTYPE_I1, ""},*/ 00082 {MTYPE_I2, MTYPE_I1, "C_INT1"}, 00083 {MTYPE_I4, MTYPE_I1, "C_INT1"}, 00084 {MTYPE_I8, MTYPE_I1, "C_INT1"}, 00085 /*{MTYPE_U1, MTYPE_I1, ""},*/ 00086 {MTYPE_U2, MTYPE_I1, "C_INT1"}, 00087 {MTYPE_U4, MTYPE_I1, "C_INT1"}, 00088 {MTYPE_U8, MTYPE_I1, "C_INT1"}, 00089 {MTYPE_F4, MTYPE_I1, "C_INT1"}, 00090 {MTYPE_F8, MTYPE_I1, "C_INT1"}, 00091 {MTYPE_FQ, MTYPE_I1, "C_INT1"}, 00092 00093 {MTYPE_I1, MTYPE_I2, "C_INT2"}, 00094 /*{MTYPE_I2, MTYPE_I2, ""},*/ 00095 {MTYPE_I4, MTYPE_I2, "C_INT2"}, 00096 {MTYPE_I8, MTYPE_I2, "C_INT2"}, 00097 {MTYPE_U1, MTYPE_I2, "C_INT2"}, 00098 /*{MTYPE_U2, MTYPE_I2, ""},*/ 00099 {MTYPE_U4, MTYPE_I2, "C_INT2"}, 00100 {MTYPE_U8, MTYPE_I2, "C_INT2"}, 00101 {MTYPE_F4, MTYPE_I2, "C_INT2"}, 00102 {MTYPE_F8, MTYPE_I2, "C_INT2"}, 00103 {MTYPE_FQ, MTYPE_I2, "C_INT2"}, 00104 00105 {MTYPE_I1, MTYPE_I4, "C_INT"}, 00106 {MTYPE_I2, MTYPE_I4, "C_INT"}, 00107 /*{MTYPE_I4, MTYPE_I4, ""},*/ 00108 {MTYPE_I8, MTYPE_I4, "C_INT"}, 00109 {MTYPE_U1, MTYPE_I4, "C_INT"}, 00110 {MTYPE_U2, MTYPE_I4, "C_INT"}, 00111 /*{MTYPE_U4, MTYPE_I4, ""},*/ 00112 {MTYPE_U8, MTYPE_I4, "C_INT"}, 00113 {MTYPE_F4, MTYPE_I4, "C_INT"}, 00114 {MTYPE_F8, MTYPE_I4, "C_INT"}, 00115 {MTYPE_FQ, MTYPE_I4, "C_INT"}, 00116 00117 00118 {MTYPE_I1, MTYPE_I8, "C_INT"}, 00119 {MTYPE_I2, MTYPE_I8, "C_INT"}, 00120 {MTYPE_I4, MTYPE_I8, "C_INT"}, 00121 /*{MTYPE_I8, MTYPE_I8, ""},*/ 00122 {MTYPE_U1, MTYPE_I8, "C_INT"}, 00123 {MTYPE_U2, MTYPE_I8, "C_INT"}, 00124 {MTYPE_U4, MTYPE_I8, "C_INT"}, 00125 /*{MTYPE_U8, MTYPE_I8, ""},*/ 00126 {MTYPE_F4, MTYPE_I8, "C_INT"}, 00127 {MTYPE_F8, MTYPE_I8, "C_INT"}, 00128 {MTYPE_FQ, MTYPE_I8, "C_INT"}, 00129 00130 {MTYPE_I1, MTYPE_F4, "C_REAL"}, 00131 {MTYPE_I2, MTYPE_F4, "C_REAL"}, 00132 {MTYPE_I4, MTYPE_F4, "C_REAL"}, 00133 {MTYPE_I8, MTYPE_F4, "C_REAL"}, 00134 {MTYPE_U1, MTYPE_F4, "C_REAL"}, 00135 {MTYPE_U2, MTYPE_F4, "C_REAL"}, 00136 {MTYPE_U4, MTYPE_F4, "C_REAL"}, 00137 {MTYPE_U8, MTYPE_F4, "C_REAL"}, 00138 /*{MTYPE_F4, MTYPE_F4, ""},*/ 00139 {MTYPE_F8, MTYPE_F4, "C_REAL"}, 00140 {MTYPE_FQ, MTYPE_F4, "C_REAL"}, 00141 00142 {MTYPE_I1, MTYPE_F8, "C_DBLE"}, 00143 {MTYPE_I2, MTYPE_F8, "C_DBLE"}, 00144 {MTYPE_I4, MTYPE_F8, "C_DBLE"}, 00145 {MTYPE_I8, MTYPE_F8, "C_DBLE"}, 00146 {MTYPE_U1, MTYPE_F8, "C_DBLE"}, 00147 {MTYPE_U2, MTYPE_F8, "C_DBLE"}, 00148 {MTYPE_U4, MTYPE_F8, "C_DBLE"}, 00149 {MTYPE_U8, MTYPE_F8, "C_DBLE"}, 00150 {MTYPE_F4, MTYPE_F8, "C_DBLE"}, 00151 /*{MTYPE_F8, MTYPE_F8, ""},*/ 00152 {MTYPE_FQ, MTYPE_F8, "C_DBLE"}, 00153 00154 {MTYPE_I1, MTYPE_FQ, "C_QREAL"}, 00155 {MTYPE_I2, MTYPE_FQ, "C_QREAL"}, 00156 {MTYPE_I4, MTYPE_FQ, "C_QREAL"}, 00157 {MTYPE_I8, MTYPE_FQ, "C_QREAL"}, 00158 {MTYPE_U1, MTYPE_FQ, "C_QREAL"}, 00159 {MTYPE_U2, MTYPE_FQ, "C_QREAL"}, 00160 {MTYPE_U4, MTYPE_FQ, "C_QREAL"}, 00161 {MTYPE_U8, MTYPE_FQ, "C_QREAL"}, 00162 {MTYPE_F4, MTYPE_FQ, "C_QREAL"}, 00163 {MTYPE_F8, MTYPE_FQ, "C_QREAL"} 00164 /*{MTYPE_FQ, MTYPE_FQ, ""}*/ 00165 }; /* Conv_Op_Map */ 00166 00167 static void 00168 WN2F_Expr_initialize(void) 00169 { 00170 /* Initialize the Conv_Op array (default value is NULL) */ 00171 for (UINT i = 0; i < NUMBER_OF_CONV_OPS; i++) { 00172 Conv_Op[Conv_Op_Map[i].from][Conv_Op_Map[i].to] = 00173 Conv_Op_Map[i].name; 00174 } 00175 } 00176 00177 static void 00178 WN2F_Convert(xml::ostream& xos, MTYPE from_mtype, MTYPE to_mtype) 00179 { 00180 /* We emit a warning message for conversions not covered (TODO: put 00181 * this warning under a command-line option). Converts the expression 00182 * in the given token-buffer to the given mtype. 00183 */ 00184 xos << "("; // FIXMEprepend 00185 if (Conv_Op[from_mtype][to_mtype] == NULL) { 00186 FORTTK_ASSERT_WARN(Conv_Op[from_mtype][to_mtype] != NULL, 00187 "unexpected conversion from " << MTYPE_name(from_mtype) << "to" 00188 << MTYPE_name(to_mtype)); 00189 xos << "WN2F_Convert"; // FIXMEprepend 00190 } else { 00191 /* Note all these are intrinsics in the mongoose compiler and 00192 * need not be declared. 00193 */ 00194 Append_Token_String(xos, Conv_Op[from_mtype][to_mtype]); // FIXMEprepend 00195 } 00196 xos << ")"; 00197 } /* WN2F_Convert */ 00198 00199 00200 //*************************************************************************** 00201 // Type Conversion 00202 //*************************************************************************** 00203 00204 static void 00205 InitConvOpMap() // FIXME 00206 { 00207 if (!Conv_OpInitialized) { 00208 WN2F_Expr_initialize(); 00209 Conv_OpInitialized = true; 00210 } 00211 } 00212 00213 void 00214 whirl2xaif::WN2F_cvt(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00215 { 00216 FORTTK_ASSERT(WN_operator(wn) == OPR_CVT, fortTkSupport::Diagnostics::UnexpectedInput); 00217 00218 InitConvOpMap(); 00219 TranslateWN(xos, WN_kid0(wn), ctxt); 00220 00221 /* Maybe we shouldn't or needn't explicitly output these kinds of 00222 convert in .w2f.f file----fzhao 00223 */ 00224 // WN2F_Convert(xos, WN_desc(wn), WN_rtype(wn)); 00225 00226 00227 } 00228 00229 void 00230 whirl2xaif::WN2F_cvtl(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00231 { 00232 FORTTK_ASSERT(WN_operator(wn) == OPR_CVTL, fortTkSupport::Diagnostics::UnexpectedInput); 00233 00234 TY_IDX rtype, dtype; 00235 InitConvOpMap(); 00236 00237 dtype = WN_Tree_Type(WN_kid0(wn)); 00238 rtype = WN_Tree_Type(wn); 00239 00240 /* Only convert if it is necessary */ 00241 if (Conv_Op[TY_mtype(dtype)][TY_mtype(rtype)] != NULL ) { 00242 TranslateWN(xos, WN_kid0(wn), ctxt); 00243 WN2F_Convert(xos, TY_mtype(dtype), TY_mtype(rtype)); 00244 } else { 00245 TranslateWN(xos, WN_kid0(wn), ctxt); 00246 } 00247 00248 } 00249 00250 void 00251 whirl2xaif::WN2F_tas(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00252 { 00253 FORTTK_ASSERT(WN_operator(wn) == OPR_TAS, fortTkSupport::Diagnostics::UnexpectedInput); 00254 00255 // Just ignore TAS operators for now. TODO: make sure this 00256 // is always ok. 00257 return TranslateWN(xos, WN_kid0(wn), ctxt); 00258 } 00259 00260 00261 //*************************************************************************** 00262 // Leaf (Other) 00263 //*************************************************************************** 00264 00265 // xlate_INTCONST: Translate a WHIRL integer constant into an XAIF 00266 // constant. 00267 void 00268 whirl2xaif::xlate_INTCONST(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00269 { 00270 FORTTK_ASSERT(WN_operator(wn) == OPR_INTCONST, fortTkSupport::Diagnostics::UnexpectedInput); 00271 00272 // FIXME: use xlate_CONST 00273 TCON tval = Host_To_Targ(WN_rtype(wn), WN_const_val(wn)); 00274 bool logical = ctxt.currentXlationContext().isFlag(XlationContext::IS_LOGICAL_ARG); 00275 std::string val = TCON2F_translate(tval, logical); 00276 const char* ty_str = (logical) ? "bool" : "integer"; 00277 00278 xos << BegElem("xaif:Constant") 00279 << Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId()) 00280 << Attr("type", ty_str) 00281 << Attr("feType",Mtype_Name(OPCODE_rtype(WN_opcode(wn)))) 00282 << Attr("value", val) 00283 << EndElem; 00284 } 00285 00286 // xlate_CONST: Translate a WHIRL constant (string, floating point, 00287 // etc.) into an XAIF constant. 00288 void 00289 whirl2xaif::xlate_CONST(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00290 { 00291 FORTTK_ASSERT(WN_operator(wn) == OPR_CONST, fortTkSupport::Diagnostics::UnexpectedInput); 00292 00293 TY_IDX ty_idx = ST_type(WN_st(wn)); 00294 00295 BOOL logical = (TY_is_logical(ty_idx) || ctxt.currentXlationContext().isFlag(XlationContext::IS_LOGICAL_ARG)); 00296 std::string val = TCON2F_translate(STC_val(WN_st(wn)), logical); 00297 00298 const char* ty_str = TranslateTYToSymType(ty_idx); // FIXME: logical 00299 if (!ty_str) { ty_str = "***"; } 00300 00301 xos << BegElem("xaif:Constant") 00302 << Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId()) 00303 << Attr("type", ty_str) 00304 << Attr("feType",Mtype_Name(TY_mtype(ty_idx))) 00305 << Attr("value", val) 00306 << EndElem; 00307 } 00308 00309 00310 //*************************************************************************** 00311 // Expression Operators: Unary Operations 00312 //*************************************************************************** 00313 00314 void 00315 whirl2xaif::xlate_UnaryOp(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00316 { 00317 OPERATOR opr = WN_operator(wn); 00318 OPCODE opc = WN_opcode(wn); 00319 FORTTK_ASSERT(WN_kid_count(wn) == 1, 00320 fortTkSupport::Diagnostics::UnexpectedInput << OPERATOR_name(opr)); 00321 xlate_UnaryOpUsingIntrinsicTable(xos, 00322 opc, 00323 WN_Tree_Type(wn), 00324 WN_kid0(wn), 00325 ctxt); 00326 } 00327 00328 00329 void 00330 whirl2xaif::WN2F_rsqrt(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00331 { 00332 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00333 00334 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00335 00336 xos << "(1.0/SQRT("; 00337 xlate_Operand(xos, WN_kid(wn,0), result_ty, 00338 !TY_Is_Character_Reference(result_ty), ctxt); 00339 xos << "))"; 00340 00341 00342 } /* WN2F_rsqrt */ 00343 00344 00345 void 00346 whirl2xaif::WN2F_realpart(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00347 { 00348 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00349 00350 switch (WN_rtype(wn)) { 00351 case MTYPE_F4: 00352 xos << "REAL"; 00353 break; 00354 case MTYPE_F8: 00355 xos << "DBLE"; 00356 break; 00357 case MTYPE_FQ: 00358 xos << "QREAL"; 00359 00360 break; 00361 default: 00362 FORTTK_DIE("Unexpected type: " << MTYPE_name(WN_rtype(wn))); 00363 break; 00364 } 00365 xos << "("; 00366 TranslateWN(xos, WN_kid0(wn), ctxt); 00367 xos << ")"; 00368 00369 00370 } /* WN2F_realpart */ 00371 00372 00373 void 00374 whirl2xaif::WN2F_imagpart(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00375 { 00376 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00377 00378 switch (WN_rtype(wn)) { 00379 case MTYPE_F4: 00380 xos << "AIMAG"; 00381 break; 00382 case MTYPE_F8: 00383 xos << "DIMAG"; 00384 break; 00385 case MTYPE_FQ: 00386 xos << "QIMAG"; 00387 break; 00388 default: 00389 FORTTK_DIE("Unexpected type: " << MTYPE_name(WN_rtype(wn))); 00390 break; 00391 } 00392 xos << "(imagpart"; 00393 TranslateWN(xos, WN_kid0(wn), ctxt); 00394 xos << "imagpart)"; 00395 00396 00397 } /* WN2F_imagpart */ 00398 00399 00400 void 00401 whirl2xaif::xlate_PAREN(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00402 { 00403 FORTTK_ASSERT(WN_operator(wn) == OPR_PAREN, fortTkSupport::Diagnostics::UnexpectedInput); 00404 00405 return TranslateWN(xos, WN_kid0(wn), ctxt); 00406 } 00407 00408 00409 void 00410 whirl2xaif::xlate_RECIP(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00411 { 00412 FORTTK_ASSERT(WN_operator(wn) == OPR_RECIP, fortTkSupport::Diagnostics::UnexpectedInput); 00413 00414 const TY_IDX result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00415 00416 // Translate using a temporary DIV expression [1 / kid0(wn)] 00417 TYPE_ID rty = TY_mtype(result_ty); 00418 OPCODE opc = OPCODE_make_op(OPR_DIV, rty, MTYPE_V); 00419 00420 TCON tcon; 00421 if (MTYPE_is_integral(rty)) { 00422 tcon = Host_To_Targ(rty, 1); 00423 } 00424 else if (MTYPE_is_float(rty)) { 00425 tcon = Host_To_Targ_Float(rty, 1.0); 00426 } 00427 else if (MTYPE_is_complex(rty)) { 00428 tcon = Host_To_Targ_Complex(rty, 1, 0); 00429 } 00430 else { 00431 FORTTK_DIE("Cannot take reciprical of this TCON"); 00432 } 00433 WN* wn_one = Make_Const(tcon); 00434 00435 xlate_BinaryOpUsingIntrinsicTable(xos, opc, result_ty, wn_one, 00436 WN_kid0(wn), ctxt); 00437 00438 WN_DELETE_Tree(wn_one); 00439 00440 00441 } 00442 00443 00444 void 00445 whirl2xaif::WN2F_parm(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00446 { 00447 /* TODO: handle opcode parms properly, i.e. take some advantage 00448 * of the information provided in this packaging of argument 00449 * expressions. For now, just skip these nodes. 00450 */ 00451 FORTTK_ASSERT(WN_operator(wn) == OPR_PARM, fortTkSupport::Diagnostics::UnexpectedInput); 00452 if (TY_is_logical(Ty_Table[WN_ty(wn)]) || 00453 ctxt.currentXlationContext().isFlag(XlationContext::IS_LOGICAL_ARG)) { //fzhao Jan 00454 ctxt.currentXlationContext().setFlag(XlationContext::HAS_LOGICAL_ARG); 00455 TranslateWN(xos, WN_kid0(wn), ctxt); 00456 ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_LOGICAL_ARG); 00457 } 00458 else { 00459 TranslateWN(xos, WN_kid0(wn), ctxt); 00460 } 00461 00462 00463 } /* WN2F_parm */ 00464 00465 00466 void 00467 whirl2xaif::WN2F_alloca(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00468 { 00469 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00470 00471 xos << "OPR_ALLOCA("; 00472 TranslateWN(xos,WN_kid0(wn),ctxt); 00473 xos << ")"; 00474 00475 00476 } /* WN2F_alloca */ 00477 00478 00479 //*************************************************************************** 00480 // Expression Operators: Binary Operations 00481 //*************************************************************************** 00482 00483 void 00484 whirl2xaif::xlate_BinaryOp(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00485 { 00486 OPERATOR opr = WN_operator(wn); 00487 OPCODE opc = WN_opcode(wn); 00488 FORTTK_ASSERT(WN_kid_count(wn) == 2, 00489 fortTkSupport::Diagnostics::UnexpectedInput << OPERATOR_name(opr)); 00490 xlate_BinaryOpUsingIntrinsicTable(xos, 00491 opc, 00492 WN_GetExprType(wn), 00493 WN_kid0(wn), 00494 WN_kid1(wn), 00495 ctxt); 00496 ctxt.currentXlationContext().unsetFlag(XlationContext::IS_LOGICAL_OPERATION); 00497 } 00498 00499 void 00500 whirl2xaif::WN2F_bnor(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00501 { 00502 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00503 00504 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00505 00506 xos << "NOT(IOR("; 00507 xlate_Operand(xos, WN_kid(wn,0), result_ty, 00508 !TY_Is_Character_Reference(result_ty), ctxt); 00509 xos << ","; 00510 xlate_Operand(xos, WN_kid(wn,1), result_ty, 00511 !TY_Is_Character_Reference(result_ty), ctxt); 00512 xos << "))"; 00513 00514 00515 } /* WN2F_bnor */ 00516 00517 00518 void 00519 whirl2xaif::WN2F_lshr(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00520 { 00521 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00522 00523 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00524 00525 xos << "ISHIFT("; 00526 xlate_Operand(xos, WN_kid(wn,0), result_ty, 00527 !TY_Is_Character_Reference(result_ty), ctxt); 00528 xos << ",-("; 00529 xlate_Operand(xos, WN_kid(wn,1), result_ty, 00530 !TY_Is_Character_Reference(result_ty), ctxt); 00531 xos << "))"; 00532 00533 00534 } /* WN2F_lshr */ 00535 00536 00537 //*************************************************************************** 00538 // Expression Operators: Ternary Operations; N-ary Operations 00539 //*************************************************************************** 00540 00541 void 00542 whirl2xaif::WN2F_select(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00543 { 00544 /* SELECT is almost the same as the F90 MERGE intrinsic, 00545 so I will output it that way for now */ 00546 FORTTK_DIE(fortTkSupport::Diagnostics::Unimplemented); 00547 00548 xos << "MERGE("; 00549 TranslateWN(xos, WN_kid1(wn), ctxt); 00550 xos << ","; 00551 TranslateWN(xos, WN_kid2(wn), ctxt); 00552 xos << ","; 00553 TranslateWN(xos, WN_kid0(wn), ctxt); 00554 xos << ")"; 00555 00556 00557 } /* WN2F_select */ 00558 00559 00560 void 00561 whirl2xaif::WN2F_madd(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00562 { 00563 FORTTK_ASSERT(WN_operator(wn) == OPR_MADD, fortTkSupport::Diagnostics::UnexpectedInput); 00564 00565 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00566 00567 xos << "("; 00568 xlate_Operand(xos, WN_kid(wn,1), result_ty, 00569 !TY_Is_Character_Reference(result_ty), ctxt); 00570 xos << "*"; 00571 xlate_Operand(xos, WN_kid(wn,2), result_ty, 00572 !TY_Is_Character_Reference(result_ty),ctxt); 00573 xos << "+"; 00574 xlate_Operand(xos, WN_kid(wn,0), result_ty, 00575 !TY_Is_Character_Reference(result_ty), ctxt); 00576 xos << ")"; 00577 00578 00579 } /* WN2F_madd */ 00580 00581 00582 void 00583 whirl2xaif::WN2F_msub(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00584 { 00585 FORTTK_ASSERT(WN_operator(wn) == OPR_MSUB, fortTkSupport::Diagnostics::UnexpectedInput); 00586 00587 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00588 00589 xos << "("; 00590 xlate_Operand(xos, WN_kid(wn,1), result_ty, 00591 !TY_Is_Character_Reference(result_ty), ctxt); 00592 xos << "*"; 00593 xlate_Operand(xos, WN_kid(wn,2), result_ty, 00594 !TY_Is_Character_Reference(result_ty), ctxt); 00595 xos << "-"; 00596 xlate_Operand(xos, WN_kid(wn, 0), result_ty, 00597 !TY_Is_Character_Reference(result_ty), ctxt); 00598 xos << ")"; 00599 00600 00601 } /* WN2F_msub */ 00602 00603 00604 void 00605 whirl2xaif::WN2F_nmadd(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00606 { 00607 FORTTK_ASSERT(WN_operator(wn) == OPR_NMADD, fortTkSupport::Diagnostics::UnexpectedInput); 00608 00609 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00610 00611 xos << "-("; 00612 xlate_Operand(xos, WN_kid(wn,1), result_ty, 00613 !TY_Is_Character_Reference(result_ty), ctxt); 00614 xos << "*"; 00615 xlate_Operand(xos, WN_kid(wn,2), result_ty, 00616 !TY_Is_Character_Reference(result_ty), ctxt); 00617 xos << "+"; 00618 xlate_Operand(xos, WN_kid(wn, 0), result_ty, 00619 !TY_Is_Character_Reference(result_ty), ctxt); 00620 xos << ")"; 00621 00622 00623 } /* WN2F_nmadd */ 00624 00625 00626 void 00627 whirl2xaif::WN2F_nmsub(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00628 { 00629 FORTTK_ASSERT(WN_operator(wn) == OPR_NMSUB, fortTkSupport::Diagnostics::UnexpectedInput); 00630 00631 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_rtype(wn)); 00632 00633 xos << "-("; 00634 xlate_Operand(xos, WN_kid(wn,1), result_ty, 00635 !TY_Is_Character_Reference(result_ty), ctxt); 00636 xos << "*"; 00637 xlate_Operand(xos, WN_kid(wn,2), result_ty, 00638 !TY_Is_Character_Reference(result_ty), ctxt); 00639 xos << "-"; 00640 xlate_Operand(xos, WN_kid(wn, 0), result_ty, 00641 !TY_Is_Character_Reference(result_ty), ctxt); 00642 xos << ")"; 00643 00644 00645 } /* WN2F_nmsub */ 00646 00647 00648 //*************************************************************************** 00649 // Expression Operators: N-ary Operations 00650 //*************************************************************************** 00651 00652 static void 00653 WN2F_Intr_Funcall(xml::ostream& xos, WN* wn, fortTkSupport::IntrinsicXlationTable::XAIFInfoPair& infoPair, 00654 INT begArgIdx, INT endArgIdx, BOOL callByValue, 00655 PUXlationContext& ctxt); 00656 00657 void 00658 whirl2xaif::xlate_INTRINSIC_OP(xml::ostream& xos, WN *wn, PUXlationContext& ctxt) 00659 { 00660 // An intrinsic operator expression (function call). This call is 00661 // not related to the call-info generated by PUinfo. Note that 00662 // either all or none of the arguments are call-by-value. 00663 OPERATOR opr = WN_operator(wn); 00664 FORTTK_ASSERT(opr == OPR_INTRINSIC_OP, fortTkSupport::Diagnostics::UnexpectedInput); 00665 00666 INTRINSIC intrn = WN_intrinsic(wn); 00667 BOOL by_value = INTRN_by_value(intrn); 00668 INT begArgIdx = 0; // Assume we never return to first argument 00669 INT endArgIdx = WN_kid_count(wn) - 1; 00670 00671 const char* inm = IntrinsicInfo::intrinsicBaseName(intrn); 00672 fortTkSupport::IntrinsicXlationTable::XAIFInfoPair infoPair(Whirl2Xaif::getIntrinsicXlationTable().findXAIFInfo(opr, inm)); 00673 if ((strcmp(inm, "ADRTMP") == 0) || (strcmp(inm, "VALTMP") == 0)) { 00674 // Special cases: 00675 // ADRTMP: Call-by-reference. Emit the dereferenced parameter. 00676 // VALTMP: Call-by-value. Assume 'ctxt' determines when it 00677 // is necessary to put a %val qualifier around the argument. 00678 TranslateWN(xos, WN_kid0(wn), ctxt); 00679 } else { 00680 // General case 00681 WN2F_Intr_Funcall(xos, wn, infoPair, 00682 begArgIdx, endArgIdx, by_value, ctxt); 00683 } 00684 00685 00686 } /* xlate_INTRINSIC_OP */ 00687 00688 00689 static void 00690 WN2F_Intr_Funcall(xml::ostream& xos, WN* wn, fortTkSupport::IntrinsicXlationTable::XAIFInfoPair& infoPair, 00691 INT begArgIdx, INT endArgIdx, BOOL callByValue, 00692 PUXlationContext& ctxt) 00693 { 00694 /* An intrinsic operator expression to be emitted with function 00695 * call syntax. All arguments are passed by value or by reference, 00696 * i.e. we never have some arguments passed by value and some by 00697 * reference, unless we have explicit INTR_OPC_ADRTMP or 00698 * INTR_OPC_VALTMP argument expressions. Note that we also 00699 * handle substring arguments here. 00700 */ 00701 00702 /* Determine the number of implicit arguments appended to the end 00703 * of the argument list (i.e. string lengths). 00704 */ 00705 if (WN_intrinsic(wn) == INTRN_COUNT) { 00706 endArgIdx--; 00707 } 00708 00709 INT argIdx = begArgIdx, total_implicit_args = 0; 00710 TY_IDX opnd_type; 00711 for ( ; argIdx <= endArgIdx - total_implicit_args; argIdx++) { 00712 opnd_type = WN_Tree_Type(WN_kid(wn, argIdx)); 00713 if (TY_Is_Character_Reference(opnd_type) || 00714 TY_Is_Chararray_Reference(opnd_type)) { 00715 total_implicit_args++; 00716 } 00717 } 00718 00719 // Emit Intrinsic name 00720 UINT targid = ctxt.currentXlationContext().getNewVertexId(); 00721 xos << BegElem("xaif:Intrinsic") 00722 << Attr("vertex_id", targid) << Attr("name", infoPair.second.name) 00723 << Attr("type", "***"); 00724 if (infoPair.second.key) { xos << IntrinsicKeyAnnot(infoPair.second.key); } 00725 TY_IDX result_ty=WN_GetExprType(wn); 00726 bool isPointer = TY_Is_Pointer(result_ty) || TY_is_f90_pointer(result_ty); 00727 bool isFnPointer = isPointer && (TY_kind(TY_pointed(result_ty)) == KIND_FUNCTION); 00728 const char* ty_str = 00729 (isPointer && (!isFnPointer)) ? TranslateTYToSymType(TY_pointed(result_ty)) 00730 : TranslateTYToSymType(result_ty); 00731 if (!ty_str) { ty_str = "***"; } 00732 const char* shape_str = 00733 (isPointer && (!isFnPointer)) ? TranslateTYToSymShape(TY_pointed(result_ty)) 00734 : TranslateTYToSymShape(result_ty); 00735 if (strcmp(ty_str,"real")) 00736 xos << xml::Attr("rType", ty_str); 00737 if (strcmp(shape_str,"scalar")) 00738 xos << xml::Attr("rShape", shape_str); 00739 xos << EndElem; 00740 00741 // Emit Intrinsic argument list, skipping implicit 00742 // character-string-length arguments assumed to be the last ones in 00743 // the list (see also ST2F_func_header()). 00744 UINT srcid = 0; 00745 UINT position = 0; 00746 switch (WN_intrinsic(wn)) { 00747 case INTRN_F90INDEX: // FIXME 00748 case INTRN_SCAN: 00749 case INTRN_VERIFY: { 00750 for (argIdx = begArgIdx; argIdx < endArgIdx; argIdx = argIdx + 2) { 00751 opnd_type = WN_Tree_Type(WN_kid(wn, argIdx)); 00752 00753 position++; 00754 srcid = ctxt.currentXlationContext().peekVertexId(); 00755 if (TY_Is_Character_Reference(opnd_type) || 00756 TY_Is_Chararray_Reference(opnd_type)) { 00757 WN2F_String_Argument(xos, WN_kid(wn, argIdx) /* string base */, 00758 WN_kid(wn, endArgIdx) /* string len */, ctxt); 00759 } else { 00760 xlate_Operand(xos, WN_kid(wn, argIdx), opnd_type, callByValue, ctxt); 00761 } 00762 DumpExprGraphEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid, position); 00763 } 00764 00765 ctxt.currentXlationContext().setFlag(XlationContext::HAS_LOGICAL_ARG); 00766 position++; 00767 srcid = ctxt.currentXlationContext().peekVertexId(); 00768 xlate_Operand(xos, WN_kid(wn, endArgIdx), opnd_type, callByValue, ctxt); 00769 ctxt.currentXlationContext().unsetFlag(XlationContext::HAS_LOGICAL_ARG); 00770 DumpExprGraphEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid, position); 00771 break; 00772 } 00773 default: { 00774 00775 INT implicit_args = 0; 00776 for (argIdx = begArgIdx; argIdx <= endArgIdx - implicit_args; argIdx++) { 00777 opnd_type = WN_Tree_Type(WN_kid(wn, argIdx)); 00778 00779 position++; 00780 srcid = ctxt.currentXlationContext().peekVertexId(); 00781 if (TY_Is_Character_Reference(opnd_type) || 00782 TY_Is_Chararray_Reference(opnd_type)) { 00783 implicit_args++; 00784 INT strlIdx = (endArgIdx - (total_implicit_args - implicit_args)); 00785 WN2F_String_Argument(xos, WN_kid(wn, argIdx) /* string base */, 00786 WN_kid(wn, strlIdx) /* string len */, ctxt); 00787 } else { 00788 xlate_Operand(xos, WN_kid(wn, argIdx), opnd_type, callByValue, ctxt); 00789 } 00790 DumpExprGraphEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid, targid, position); 00791 00792 } 00793 break; 00794 } 00795 } /* switch */ 00796 00797 00798 } /* WN2F_Intr_Funcall */ 00799 00800 00801 //*************************************************************************** 00802 // Helpers 00803 //*************************************************************************** 00804 00805 static void 00806 xlate_UnaryOpUsingIntrinsicTable(xml::ostream& xos, 00807 OPCODE opcode, 00808 TY_IDX result_ty, 00809 WN* wn, 00810 PUXlationContext& ctxt) 00811 { 00812 xlate_BinaryOpUsingIntrinsicTable(xos, opcode, result_ty, wn, NULL, ctxt); 00813 00814 } 00815 00816 00817 // xlate_BinaryOpUsingIntrinsicTable: 00818 static void 00819 xlate_BinaryOpUsingIntrinsicTable(xml::ostream& xos, 00820 OPCODE opcode, 00821 TY_IDX result_ty, 00822 WN* wn0, 00823 WN* wn1, 00824 PUXlationContext& ctxt) { 00825 BOOL is_binary_op = (wn1 != NULL); 00826 // Get the expected types for the two operands, dependent on whether 00827 // or not we have a descriptor type. 00828 TY_IDX wn0_ty, wn1_ty; 00829 if (OPCODE_desc(opcode) == MTYPE_V) { 00830 wn0_ty = wn1_ty = result_ty; 00831 } else { 00832 wn0_ty = wn1_ty = Stab_Mtype_To_Ty(OPCODE_desc(opcode)); 00833 } 00834 00835 OPERATOR opr = OPCODE_operator(opcode); 00836 fortTkSupport::IntrinsicXlationTable::XAIFInfoPair infoPair(Whirl2Xaif::getIntrinsicXlationTable().findXAIFInfo(opr, NULL)); 00837 UINT targid, srcid0, srcid1; 00838 bool noParent=false; 00839 if (opr==OPR_TRUNC && WN_operator(wn0)==OPR_CALL && strcmp(ST_name(WN_st(wn0)),"TRANSFER")==0) { // skip the TRUNC node 00840 if (ctxt.currentXlationContext().peekVertexId()==1) { // nothing there yet 00841 noParent=true; 00842 } 00843 else 00844 targid=ctxt.currentXlationContext().getVertexId(); 00845 } 00846 else { 00847 // Get XAIF operator type 00848 const char* opStr = NULL; 00849 const char* typeStr = NULL; 00850 switch (infoPair.second.opr) { 00851 case fortTkSupport::IntrinsicXlationTable::XAIFIntrin: { 00852 opStr = "xaif:Intrinsic"; 00853 typeStr = "***"; 00854 break; 00855 } 00856 case fortTkSupport::IntrinsicXlationTable::XAIFBoolOp: { 00857 opStr = "xaif:BooleanOperation"; 00858 break; 00859 } 00860 default: 00861 FORTTK_DIE("xlate_BinaryOpUsingIntrinsicTable: no logic to handle: " 00862 << fortTkSupport::IntrinsicXlationTable::toString(infoPair.second.opr).c_str()); 00863 } 00864 00865 // Operation 00866 targid = ctxt.currentXlationContext().getNewVertexId(); 00867 xos << BegElem(opStr) << Attr("vertex_id", targid) 00868 << Attr("name", infoPair.second.name); 00869 if (typeStr) { 00870 xos << Attr("type", typeStr); 00871 } 00872 bool isPointer = TY_Is_Pointer(result_ty) || TY_is_f90_pointer(result_ty); 00873 bool isFnPointer = isPointer && (TY_kind(TY_pointed(result_ty)) == KIND_FUNCTION); 00874 const char* ty_str = 00875 (isPointer && (!isFnPointer)) ? TranslateTYToSymType(TY_pointed(result_ty)) 00876 : TranslateTYToSymType(result_ty); 00877 if (!ty_str) { ty_str = "***"; } 00878 const char* shape_str = 00879 (isPointer && (!isFnPointer)) ? TranslateTYToSymShape(TY_pointed(result_ty)) 00880 : TranslateTYToSymShape(result_ty); 00881 if (infoPair.second.opr!=fortTkSupport::IntrinsicXlationTable::XAIFBoolOp && strcmp(ty_str,"real")) 00882 xos << xml::Attr("rType", ty_str); 00883 if (infoPair.second.opr!=fortTkSupport::IntrinsicXlationTable::XAIFBoolOp && strcmp(shape_str,"scalar")) 00884 xos << xml::Attr("rShape", shape_str); 00885 xos << EndElem; 00886 } 00887 // First operand 00888 srcid0 = ctxt.currentXlationContext().peekVertexId(); 00889 xlate_Operand(xos, wn0, wn0_ty, TRUE/*call-by-value*/, ctxt); 00890 00891 // Second operand (only for binary op) 00892 if (is_binary_op) { 00893 srcid1 = ctxt.currentXlationContext().peekVertexId(); 00894 xlate_Operand(xos, wn1, wn1_ty, TRUE/*call-by-value*/, ctxt); 00895 } 00896 if (!noParent) { 00897 // Edges 00898 DumpExprGraphEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid0, targid, 1); 00899 if (is_binary_op) { 00900 DumpExprGraphEdge(xos, ctxt.currentXlationContext().getNewEdgeId(), srcid1, targid, 2); 00901 } 00902 } 00903 } 00904 00905 00906 // xlate_Operand: Translate a WHIRL operand (from an operator) to XAIF. 00907 static void 00908 xlate_Operand(xml::ostream& xos, WN *opnd, TY_IDX assumed_ty, 00909 BOOL callByValue, PUXlationContext& ctxt) 00910 { 00911 // Translate an operand to a function or built-in operator invocation, 00912 // based on whether the ctxt indicates that we have call-by-value 00913 // or call-by-reference. Also, the ctxt indicates what type of 00914 // argument we expect. FIXME 00915 00916 // We do not handle substring expressions here, and assume any 00917 // such expression will be dispatched to another. 00918 FORTTK_ASSERT(!TY_Is_Character_Reference(assumed_ty) && 00919 !TY_Is_Chararray_Reference(assumed_ty), 00920 fortTkSupport::Diagnostics::UnexpectedInput << "substring reference"); 00921 00922 if (!callByValue && !TY_Is_Character_String(assumed_ty)) { 00923 xlate_MemRef(xos, opnd, /* address expression */ 00924 assumed_ty, /* address type */ 00925 TY_pointed(assumed_ty), /* object type */ 00926 0, /* offset from address */ 00927 ctxt); 00928 } 00929 else { 00930 TranslateWN(xos, opnd, ctxt); 00931 } 00932 00933 00934 } 00935