OpenADFortTk (basic)
src/whirl2xaif/wn2xaif_expr.cxx
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines