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 expression subtree to Fortran by means of an inorder 00046 * recursive descent traversal of the WHIRL IR. Note that the routines 00047 * to handle statements and loads/stores 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 "whirl2f_common.h" 00059 #include "PUinfo.h" /* In be/whirl2c directory */ 00060 #include "tcon2f.h" 00061 #include "wn2f.h" 00062 #include "ty2f.h" 00063 #include "st2f.h" 00064 #include "wn2f_load_store.h" 00065 #include "intrn_info.h" /* INTR macros */ 00066 #include "ty_ftn.h" 00067 00068 extern BOOL W2F_OpenAD; /* w2f_driver.h */ 00069 00070 /*---- Fortran names for binary and unary arithmetic operations -------*/ 00071 /*---------------------------------------------------------------------*/ 00072 00073 00074 /* The builtin Fortran operations will begin with a special character 00075 * or an alphabetic character, where those beginning with an alphabetic 00076 * character will be applied like functions and all others will be 00077 * applied in usual infix format. When a name begins with '_', it is 00078 * a whirl2f special symbol to be applied like a function. It will 00079 * be implemented in a library made available to be linked in with 00080 * compiled whirl2f code. 00081 */ 00082 #define WN2F_IS_ALPHABETIC(opc) \ 00083 ((Opc_Fname[opc][0]>='a' && Opc_Fname[opc][0]<='z') || \ 00084 (Opc_Fname[opc][0]>='A' && Opc_Fname[opc][0]<='Z') || \ 00085 (Opc_Fname[opc][0]=='_')) 00086 00087 #define WN2F_IS_INFIX_OP(opc) \ 00088 (Opc_Fname[opc]!=NULL && !WN2F_IS_ALPHABETIC(opc)) 00089 00090 #define WN2F_IS_FUNCALL_OP(opc) \ 00091 (Opc_Fname[opc]!=NULL && WN2F_IS_ALPHABETIC(opc)) 00092 00093 /* Mapping from opcodes to Fortran names for arithmetic/logical 00094 * operations. An empty (NULL) name will occur for non- 00095 * arithmetic/logical opcodes, which must be handled by special 00096 * handler-functions. This mapping is dynamically initialized, 00097 * based on Fname_Map[], in WN2F_Expr_Initialize(). 00098 */ 00099 #define NUMBER_OF_OPCODES (OPCODE_LAST+1) 00100 static const char *Opc_Fname[NUMBER_OF_OPCODES]; 00101 00102 00103 typedef struct Fname_PartialMap 00104 { 00105 OPCODE opc; 00106 const char *fname; 00107 } FNAME_PARTIALMAP; 00108 00109 #define NUMBER_OF_FNAME_PARTIALMAPS \ 00110 sizeof(Fname_Map) / sizeof(FNAME_PARTIALMAP) 00111 00112 static const FNAME_PARTIALMAP Fname_Map[] = 00113 { 00114 {OPC_U8NEG, "-"}, 00115 {OPC_FQNEG, "-"}, 00116 {OPC_I8NEG, "-"}, 00117 {OPC_U4NEG, "-"}, 00118 {OPC_CQNEG, "-"}, 00119 {OPC_F8NEG, "-"}, 00120 {OPC_C8NEG, "-"}, 00121 {OPC_I4NEG, "-"}, 00122 {OPC_F4NEG, "-"}, 00123 {OPC_C4NEG, "-"}, 00124 {OPC_I4ABS, "ABS"}, 00125 {OPC_F4ABS, "ABS"}, 00126 {OPC_FQABS, "ABS"}, 00127 {OPC_I8ABS, "ABS"}, 00128 {OPC_F8ABS, "ABS"}, 00129 {OPC_F4SQRT, "SQRT"}, 00130 {OPC_C4SQRT, "SQRT"}, 00131 {OPC_FQSQRT, "SQRT"}, 00132 {OPC_CQSQRT, "SQRT"}, 00133 {OPC_F8SQRT, "SQRT"}, 00134 {OPC_C8SQRT, "SQRT"}, 00135 {OPC_I4F4RND, "JNINT"}, 00136 {OPC_I4FQRND, "JIQNNT"}, 00137 {OPC_I4F8RND, "JIDNNT"}, 00138 {OPC_U4F4RND, "JNINT"}, 00139 {OPC_U4FQRND, "JIQNNT"}, 00140 {OPC_U4F8RND, "JIDNNT"}, 00141 {OPC_I8F4RND, "KNINT"}, 00142 {OPC_I8FQRND, "KIQNNT"}, 00143 {OPC_I8F8RND, "KIDNNT"}, 00144 {OPC_U8F4RND, "KNINT"}, 00145 {OPC_U8FQRND, "KIQNNT"}, 00146 {OPC_U8F8RND, "KIDNNT"}, 00147 {OPC_I4I4TRUNC, "INT"}, 00148 {OPC_I4F4TRUNC, "INT"}, 00149 {OPC_I4FQTRUNC, "INT"}, 00150 {OPC_I4F8TRUNC, "INT"}, 00151 {OPC_U4F4TRUNC, "INT"}, 00152 {OPC_U4FQTRUNC, "INT"}, 00153 {OPC_U4F8TRUNC, "INT"}, 00154 {OPC_I8F4TRUNC, "INT"}, 00155 {OPC_I8FQTRUNC, "INT"}, 00156 {OPC_I8F8TRUNC, "INT"}, 00157 {OPC_U8F4TRUNC, "INT"}, 00158 {OPC_U8FQTRUNC, "INT"}, 00159 {OPC_U8F8TRUNC, "INT"}, 00160 {OPC_I4F4CEIL, "CEILING"}, 00161 {OPC_I4FQCEIL, "CEILING"}, 00162 {OPC_I4F8CEIL, "CEILING"}, 00163 {OPC_I8F4CEIL, "CEILING"}, 00164 {OPC_I8FQCEIL, "CEILING"}, 00165 {OPC_I8F8CEIL, "CEILING"}, 00166 {OPC_I4F4FLOOR, "FLOOR"}, 00167 {OPC_I4FQFLOOR, "FLOOR"}, 00168 {OPC_I4F8FLOOR, "FLOOR"}, 00169 {OPC_I8F4FLOOR, "FLOOR"}, 00170 {OPC_I8FQFLOOR, "FLOOR"}, 00171 {OPC_I8F8FLOOR, "FLOOR"}, 00172 {OPC_I4BNOT, "NOT"}, 00173 {OPC_U8BNOT, "NOT"}, 00174 {OPC_I8BNOT, "NOT"}, 00175 {OPC_U4BNOT, "NOT"}, 00176 // >> WHIRL 0.30: replace OPC_LNOT by OPC_B and OPC_I4 variant 00177 // TODO WHIRL 0.30: get rid of OPC_I4 variant 00178 {OPC_BLNOT, ".NOT."}, 00179 {OPC_I4LNOT, ".NOT."}, 00180 // << WHIRL 0.30: replace OPC_LNOT by OPC_B and OPC_I4 variant 00181 {OPC_U8ADD, "+"}, 00182 {OPC_FQADD, "+"}, 00183 {OPC_I8ADD, "+"}, 00184 {OPC_U4ADD, "+"}, 00185 {OPC_CQADD, "+"}, 00186 {OPC_F8ADD, "+"}, 00187 {OPC_C8ADD, "+"}, 00188 {OPC_I4ADD, "+"}, 00189 {OPC_F4ADD, "+"}, 00190 {OPC_C4ADD, "+"}, 00191 {OPC_U8SUB, "-"}, 00192 {OPC_FQSUB, "-"}, 00193 {OPC_I8SUB, "-"}, 00194 {OPC_U4SUB, "-"}, 00195 {OPC_CQSUB, "-"}, 00196 {OPC_F8SUB, "-"}, 00197 {OPC_C8SUB, "-"}, 00198 {OPC_I4SUB, "-"}, 00199 {OPC_F4SUB, "-"}, 00200 {OPC_C4SUB, "-"}, 00201 {OPC_U8MPY, "*"}, 00202 {OPC_FQMPY, "*"}, 00203 {OPC_I8MPY, "*"}, 00204 {OPC_U4MPY, "*"}, 00205 {OPC_CQMPY, "*"}, 00206 {OPC_F8MPY, "*"}, 00207 {OPC_C8MPY, "*"}, 00208 {OPC_I4MPY, "*"}, 00209 {OPC_F4MPY, "*"}, 00210 {OPC_C4MPY, "*"}, 00211 {OPC_U8DIV, "/"}, 00212 {OPC_FQDIV, "/"}, 00213 {OPC_I8DIV, "/"}, 00214 {OPC_U4DIV, "/"}, 00215 {OPC_CQDIV, "/"}, 00216 {OPC_F8DIV, "/"}, 00217 {OPC_C8DIV, "/"}, 00218 {OPC_I4DIV, "/"}, 00219 {OPC_F4DIV, "/"}, 00220 {OPC_C4DIV, "/"}, 00221 {OPC_I4MOD, "MOD"}, 00222 {OPC_U8MOD, "MOD"}, 00223 {OPC_I8MOD, "MOD"}, 00224 {OPC_U8MOD, "MOD"}, 00225 {OPC_U4MOD, "MOD"}, 00226 {OPC_I4REM, "MOD"}, 00227 {OPC_U8REM, "MOD"}, 00228 {OPC_I8REM, "MOD"}, 00229 {OPC_U4REM, "MOD"}, 00230 {OPC_I4MAX, "MAX"}, 00231 {OPC_U8MAX, "MAX"}, 00232 {OPC_F4MAX, "MAX"}, 00233 {OPC_FQMAX, "MAX"}, 00234 {OPC_I8MAX, "MAX"}, 00235 {OPC_U4MAX, "MAX"}, 00236 {OPC_F8MAX, "MAX"}, 00237 {OPC_I4MIN, "MIN"}, 00238 {OPC_U8MIN, "MIN"}, 00239 {OPC_F4MIN, "MIN"}, 00240 {OPC_FQMIN, "MIN"}, 00241 {OPC_I8MIN, "MIN"}, 00242 {OPC_U4MIN, "MIN"}, 00243 {OPC_F8MIN, "MIN"}, 00244 {OPC_I4BAND, "IAND"}, 00245 {OPC_U8BAND, "IAND"}, 00246 {OPC_I8BAND, "IAND"}, 00247 {OPC_U4BAND, "IAND"}, 00248 {OPC_I4BIOR, "IOR"}, 00249 {OPC_U8BIOR, "IOR"}, 00250 {OPC_I8BIOR, "IOR"}, 00251 {OPC_U4BIOR, "IOR"}, 00252 {OPC_I4BXOR, "IEOR"}, 00253 {OPC_U8BXOR, "IEOR"}, 00254 {OPC_I8BXOR, "IEOR"}, 00255 {OPC_U4BXOR, "IEOR"}, 00256 // >> WHIRL 0.30: replaced OPC_{LAND,LIOR,CAND,CIOR} by OPC_B and OPC_I4 variants 00257 // TODO WHIRL 0.30: get rid of OPC_I4 variants 00258 {OPC_BLAND, ".AND."}, 00259 {OPC_I4LAND, ".AND."}, 00260 {OPC_BLIOR, ".OR."}, 00261 {OPC_I4LIOR, ".OR."}, 00262 {OPC_BCAND, ".AND."}, 00263 {OPC_I4CAND, ".AND."}, 00264 {OPC_BCIOR, ".OR."}, 00265 {OPC_I4CIOR, ".OR."}, 00266 // << WHIRL 0.30: replaced OPC_{LAND,LIOR,CAND,CIOR} by OPC_B and OPC_I4 variants 00267 {OPC_I4SHL, "ISHIFT"}, 00268 {OPC_U8SHL, "ISHIFT"}, 00269 {OPC_I8SHL, "ISHIFT"}, 00270 {OPC_U4SHL, "ISHIFT"}, 00271 {OPC_I4ASHR, "IASHR"}, 00272 {OPC_U8ASHR, "IASHR"}, 00273 {OPC_I8ASHR, "IASHR"}, 00274 {OPC_U4ASHR, "IASHR"}, 00275 // >> WHIRL 0.30: replaced OPC_T1{EQ,NE,GT,GE,LT,LE} by OPC_B and OPC_I4 variants 00276 // TODO WHIRL 0.30: get rid of OPC_I4 variants 00277 {OPC_BU8EQ, ".EQ."}, 00278 {OPC_BFQEQ, ".EQ."}, 00279 {OPC_BI8EQ, ".EQ."}, 00280 {OPC_BU4EQ, ".EQ."}, 00281 {OPC_BCQEQ, ".EQ."}, 00282 {OPC_BF8EQ, ".EQ."}, 00283 {OPC_BC8EQ, ".EQ."}, 00284 {OPC_BI4EQ, ".EQ."}, 00285 {OPC_BF4EQ, ".EQ."}, 00286 {OPC_BC4EQ, ".EQ."}, 00287 {OPC_BU8NE, ".NE."}, 00288 {OPC_BFQNE, ".NE."}, 00289 {OPC_BI8NE, ".NE."}, 00290 {OPC_BU4NE, ".NE."}, 00291 {OPC_BCQNE, ".NE."}, 00292 {OPC_BF8NE, ".NE."}, 00293 {OPC_BC8NE, ".NE."}, 00294 {OPC_BI4NE, ".NE."}, 00295 {OPC_BF4NE, ".NE."}, 00296 {OPC_BC4NE, ".NE."}, 00297 {OPC_BI4GT, ".GT."}, 00298 {OPC_BU8GT, ".GT."}, 00299 {OPC_BF4GT, ".GT."}, 00300 {OPC_BFQGT, ".GT."}, 00301 {OPC_BI8GT, ".GT."}, 00302 {OPC_BU4GT, ".GT."}, 00303 {OPC_BF8GT, ".GT."}, 00304 {OPC_BI4GE, ".GE."}, 00305 {OPC_BU8GE, ".GE."}, 00306 {OPC_BF4GE, ".GE."}, 00307 {OPC_BFQGE, ".GE."}, 00308 {OPC_BI8GE, ".GE."}, 00309 {OPC_BU4GE, ".GE."}, 00310 {OPC_BF8GE, ".GE."}, 00311 {OPC_BI4LT, ".LT."}, 00312 {OPC_BU8LT, ".LT."}, 00313 {OPC_BF4LT, ".LT."}, 00314 {OPC_BFQLT, ".LT."}, 00315 {OPC_BI8LT, ".LT."}, 00316 {OPC_BU4LT, ".LT."}, 00317 {OPC_BF8LT, ".LT."}, 00318 {OPC_BI4LE, ".LE."}, 00319 {OPC_BU8LE, ".LE."}, 00320 {OPC_BF4LE, ".LE."}, 00321 {OPC_BFQLE, ".LE."}, 00322 {OPC_BI8LE, ".LE."}, 00323 {OPC_BU4LE, ".LE."}, 00324 {OPC_BF8LE, ".LE."}, 00325 {OPC_I4U8EQ, ".EQ."}, 00326 {OPC_I4FQEQ, ".EQ."}, 00327 {OPC_I4I8EQ, ".EQ."}, 00328 {OPC_I4U4EQ, ".EQ."}, 00329 {OPC_I4CQEQ, ".EQ."}, 00330 {OPC_I4F8EQ, ".EQ."}, 00331 {OPC_I4C8EQ, ".EQ."}, 00332 {OPC_I4I4EQ, ".EQ."}, 00333 {OPC_I4F4EQ, ".EQ."}, 00334 {OPC_I4C4EQ, ".EQ."}, 00335 {OPC_I4U8NE, ".NE."}, 00336 {OPC_I4FQNE, ".NE."}, 00337 {OPC_I4I8NE, ".NE."}, 00338 {OPC_I4U4NE, ".NE."}, 00339 {OPC_I4CQNE, ".NE."}, 00340 {OPC_I4F8NE, ".NE."}, 00341 {OPC_I4C8NE, ".NE."}, 00342 {OPC_I4I4NE, ".NE."}, 00343 {OPC_I4F4NE, ".NE."}, 00344 {OPC_I4C4NE, ".NE."}, 00345 {OPC_I4I4GT, ".GT."}, 00346 {OPC_I4U8GT, ".GT."}, 00347 {OPC_I4F4GT, ".GT."}, 00348 {OPC_I4FQGT, ".GT."}, 00349 {OPC_I4I8GT, ".GT."}, 00350 {OPC_I4U4GT, ".GT."}, 00351 {OPC_I4F8GT, ".GT."}, 00352 {OPC_I4I4GE, ".GE."}, 00353 {OPC_I4U8GE, ".GE."}, 00354 {OPC_I4F4GE, ".GE."}, 00355 {OPC_I4FQGE, ".GE."}, 00356 {OPC_I4I8GE, ".GE."}, 00357 {OPC_I4U4GE, ".GE."}, 00358 {OPC_I4F8GE, ".GE."}, 00359 {OPC_I4I4LT, ".LT."}, 00360 {OPC_I4U8LT, ".LT."}, 00361 {OPC_I4F4LT, ".LT."}, 00362 {OPC_I4FQLT, ".LT."}, 00363 {OPC_I4I8LT, ".LT."}, 00364 {OPC_I4U4LT, ".LT."}, 00365 {OPC_I4F8LT, ".LT."}, 00366 {OPC_I4I4LE, ".LE."}, 00367 {OPC_I4U8LE, ".LE."}, 00368 {OPC_I4F4LE, ".LE."}, 00369 {OPC_I4FQLE, ".LE."}, 00370 {OPC_I4I8LE, ".LE."}, 00371 {OPC_I4U4LE, ".LE."}, 00372 {OPC_I4F8LE, ".LE."} 00373 // << WHIRL 0.30: replaced OPC_T1{EQ,NE,GT,GE,LT,LE} by OPC_B and OPC_I4 variants 00374 }; /* Fname_Map */ 00375 00376 00377 /*------------------------- Value Conversions -------------------------*/ 00378 /*---------------------------------------------------------------------*/ 00379 00380 /* Create a mapping from a pair of MTYPEs to the Fortran intrinsic 00381 * or builtin operation that carries out the conversion. NULL means 00382 * that either the conversion is redundant and can be ignored or there 00383 * is no way we can do it. 00384 */ 00385 static const char *Conv_Op[MTYPE_LAST+1][MTYPE_LAST+1]; 00386 00387 typedef struct Conv_Op 00388 { 00389 MTYPE from, to; 00390 const char *name; 00391 } CONV_OP; 00392 00393 #define NUMBER_OF_CONV_OPS sizeof(Conv_Op_Map)/sizeof(CONV_OP) 00394 00395 static const CONV_OP Conv_Op_Map[] = 00396 { 00397 /* from | to | op-name */ 00398 00399 /* Only consider conversion to ptr sized unsigned numbers 00400 * valid in Fortran. 00401 */ 00402 {MTYPE_I1, MTYPE_U4, ""}, // eraxxon: was JZEXT 00403 {MTYPE_I2, MTYPE_U4, ""}, 00404 {MTYPE_I4, MTYPE_U4, ""}, 00405 {MTYPE_I8, MTYPE_U4, ""}, 00406 /*{MTYPE_U1, MTYPE_U4, ""},*/ 00407 /*{MTYPE_U2, MTYPE_U4, ""},*/ 00408 /*{MTYPE_U4, MTYPE_U4, ""},*/ 00409 {MTYPE_U8, MTYPE_U4, ""}, 00410 00411 {MTYPE_I1, MTYPE_U8, ""}, // eraxxon: was KZEXT 00412 {MTYPE_I2, MTYPE_U8, ""}, 00413 {MTYPE_I4, MTYPE_U8, ""}, 00414 {MTYPE_I8, MTYPE_U8, ""}, 00415 /*{MTYPE_U1, MTYPE_U8, ""},*/ 00416 /*{MTYPE_U2, MTYPE_U8, ""},*/ 00417 /*{MTYPE_U4, MTYPE_U8, ""},*/ 00418 /*{MTYPE_U8, MTYPE_U8, ""},*/ 00419 00420 /*{MTYPE_I1, MTYPE_I1, ""},*/ 00421 {MTYPE_I2, MTYPE_I1, "INT1"}, 00422 {MTYPE_I4, MTYPE_I1, "INT1"}, 00423 {MTYPE_I8, MTYPE_I1, "INT1"}, 00424 /*{MTYPE_U1, MTYPE_I1, ""},*/ 00425 {MTYPE_U2, MTYPE_I1, "INT1"}, 00426 {MTYPE_U4, MTYPE_I1, "INT1"}, 00427 {MTYPE_U8, MTYPE_I1, "INT1"}, 00428 {MTYPE_F4, MTYPE_I1, "INT1"}, 00429 {MTYPE_F8, MTYPE_I1, "INT1"}, 00430 {MTYPE_FQ, MTYPE_I1, "INT1"}, 00431 00432 {MTYPE_I1, MTYPE_I2, "INT2"}, 00433 /*{MTYPE_I2, MTYPE_I2, ""},*/ 00434 {MTYPE_I4, MTYPE_I2, "INT2"}, 00435 {MTYPE_I8, MTYPE_I2, "INT2"}, 00436 {MTYPE_U1, MTYPE_I2, "INT2"}, 00437 /*{MTYPE_U2, MTYPE_I2, ""},*/ 00438 {MTYPE_U4, MTYPE_I2, "INT2"}, 00439 {MTYPE_U8, MTYPE_I2, "INT2"}, 00440 {MTYPE_F4, MTYPE_I2, "INT2"}, 00441 {MTYPE_F8, MTYPE_I2, "INT2"}, 00442 {MTYPE_FQ, MTYPE_I2, "INT2"}, 00443 00444 {MTYPE_I1, MTYPE_I4, "INT"}, 00445 {MTYPE_I2, MTYPE_I4, "INT"}, 00446 /*{MTYPE_I4, MTYPE_I4, ""},*/ 00447 {MTYPE_I8, MTYPE_I4, "INT"}, 00448 {MTYPE_U1, MTYPE_I4, "INT"}, 00449 {MTYPE_U2, MTYPE_I4, "INT"}, 00450 /*{MTYPE_U4, MTYPE_I4, ""},*/ 00451 {MTYPE_U8, MTYPE_I4, "INT"}, 00452 {MTYPE_F4, MTYPE_I4, "INT"}, 00453 {MTYPE_F8, MTYPE_I4, "INT"}, 00454 {MTYPE_FQ, MTYPE_I4, "INT"}, 00455 00456 00457 {MTYPE_I1, MTYPE_I8, "INT"}, 00458 {MTYPE_I2, MTYPE_I8, "INT"}, 00459 {MTYPE_I4, MTYPE_I8, "INT"}, 00460 /*{MTYPE_I8, MTYPE_I8, ""},*/ 00461 {MTYPE_U1, MTYPE_I8, "INT"}, 00462 {MTYPE_U2, MTYPE_I8, "INT"}, 00463 {MTYPE_U4, MTYPE_I8, "INT"}, 00464 /*{MTYPE_U8, MTYPE_I8, ""},*/ 00465 {MTYPE_F4, MTYPE_I8, "INT"}, 00466 {MTYPE_F8, MTYPE_I8, "INT"}, 00467 {MTYPE_FQ, MTYPE_I8, "INT"}, 00468 00469 {MTYPE_I1, MTYPE_F4, "REAL"}, 00470 {MTYPE_I2, MTYPE_F4, "REAL"}, 00471 {MTYPE_I4, MTYPE_F4, "REAL"}, 00472 {MTYPE_I8, MTYPE_F4, "REAL"}, 00473 {MTYPE_U1, MTYPE_F4, "REAL"}, 00474 {MTYPE_U2, MTYPE_F4, "REAL"}, 00475 {MTYPE_U4, MTYPE_F4, "REAL"}, 00476 {MTYPE_U8, MTYPE_F4, "REAL"}, 00477 /*{MTYPE_F4, MTYPE_F4, ""},*/ 00478 {MTYPE_F8, MTYPE_F4, "REAL"}, 00479 {MTYPE_FQ, MTYPE_F4, "REAL"}, 00480 00481 {MTYPE_I1, MTYPE_F8, "DBLE"}, 00482 {MTYPE_I2, MTYPE_F8, "DBLE"}, 00483 {MTYPE_I4, MTYPE_F8, "DBLE"}, 00484 {MTYPE_I8, MTYPE_F8, "DBLE"}, 00485 {MTYPE_U1, MTYPE_F8, "DBLE"}, 00486 {MTYPE_U2, MTYPE_F8, "DBLE"}, 00487 {MTYPE_U4, MTYPE_F8, "DBLE"}, 00488 {MTYPE_U8, MTYPE_F8, "DBLE"}, 00489 {MTYPE_F4, MTYPE_F8, "DBLE"}, 00490 /*{MTYPE_F8, MTYPE_F8, ""},*/ 00491 {MTYPE_FQ, MTYPE_F8, "DBLE"}, 00492 00493 {MTYPE_I1, MTYPE_FQ, "QREAL"}, 00494 {MTYPE_I2, MTYPE_FQ, "QREAL"}, 00495 {MTYPE_I4, MTYPE_FQ, "QREAL"}, 00496 {MTYPE_I8, MTYPE_FQ, "QREAL"}, 00497 {MTYPE_U1, MTYPE_FQ, "QREAL"}, 00498 {MTYPE_U2, MTYPE_FQ, "QREAL"}, 00499 {MTYPE_U4, MTYPE_FQ, "QREAL"}, 00500 {MTYPE_U8, MTYPE_FQ, "QREAL"}, 00501 {MTYPE_F4, MTYPE_FQ, "QREAL"}, 00502 {MTYPE_F8, MTYPE_FQ, "QREAL"} 00503 /*{MTYPE_FQ, MTYPE_FQ, ""}*/ 00504 }; /* Conv_Op_Map */ 00505 00506 00507 static void 00508 WN2F_Convert(TOKEN_BUFFER tokens, 00509 MTYPE from_mtype, 00510 MTYPE to_mtype) 00511 { 00512 /* We emit a warning message for conversions not covered (TODO: put 00513 * this warning under a command-line option). Converts the expression 00514 * in the given token-buffer to the given mtype. 00515 */ 00516 Prepend_Token_Special(tokens, '('); 00517 00518 if (Conv_Op[from_mtype][to_mtype] == NULL) 00519 { 00520 ASSERT_WARN(Conv_Op[from_mtype][to_mtype] != NULL, 00521 (DIAG_W2F_UNEXPECTED_CVT, 00522 MTYPE_name(from_mtype), MTYPE_name(to_mtype), 00523 "WN2F_Convert")); 00524 Prepend_Token_String(tokens, "WN2F_Convert"); 00525 } 00526 else 00527 { 00528 /* Note all these are intrinsics in the mongoose compiler and 00529 * need not be declared. 00530 */ 00531 Prepend_Token_String(tokens, Conv_Op[from_mtype][to_mtype]); 00532 } 00533 Append_Token_Special(tokens, ')'); 00534 } /* WN2F_Convert */ 00535 00536 00537 /*------------------------- Utility Functions -------------------------*/ 00538 /*---------------------------------------------------------------------*/ 00539 00540 static WN2F_STATUS 00541 WN2F_Translate_Arithmetic_Operand(TOKEN_BUFFER tokens, 00542 WN *opnd, 00543 TY_IDX assumed_ty, 00544 BOOL call_by_value, 00545 WN2F_CONTEXT context) 00546 { 00547 /* Translate an operand to a function or built-in operator invocation, 00548 * based on whether the context indicates that we have call-by-value 00549 * or call-by-reference. Also, the context indicates what type of 00550 * argument we expect. 00551 */ 00552 00553 /* TODO(?): Type promotion 00554 * 00555 * TY *opnd_ty = WN_Tree_Type(opnd); 00556 * if (!WN2F_arithmetic_compatible_types(assumed_ty, opnd_ty)) 00557 * { 00558 * WN2F_prepend_cast(opnd, assumed_ty, context); 00559 * } 00560 */ 00561 00562 /* We do not handle substring expressions here, and assume any 00563 * such expression will be dispatched to a specialty routine 00564 * such as WN2F_Intr_Infix_SubstrExpr(). 00565 */ 00566 ASSERT_DBG_WARN(!TY_Is_Character_Reference(assumed_ty) && 00567 !TY_Is_Chararray_Reference(assumed_ty), 00568 (DIAG_W2F_UNEXPECTED_SUBSTRING_REF, 00569 "WN2F_Translate_Arithmetic_Operand()")); 00570 00571 if (!call_by_value) 00572 { 00573 WN2F_Offset_Memref(tokens, 00574 opnd, /* address expression */ 00575 assumed_ty, /* address type */ 00576 TY_pointed(assumed_ty), /* object type */ 00577 0, /* offset from address */ 00578 context); 00579 } 00580 else 00581 { 00582 WN2F_translate(tokens, opnd, context); 00583 } 00584 00585 return EMPTY_WN2F_STATUS; 00586 } /* WN2F_Translate_Arithmetic_Operand */ 00587 00588 00589 static WN2F_STATUS 00590 WN2F_Infix_Op(TOKEN_BUFFER tokens, 00591 OPCODE opcode, 00592 TY_IDX result_ty, 00593 WN *wn0, 00594 WN *wn1, 00595 WN2F_CONTEXT context) 00596 { 00597 /* Infix Fortran operator. Only string argument are passed by 00598 * reference; all other argument types are passed by value. 00599 */ 00600 const BOOL parenthesize = !(WN2F_CONTEXT_no_parenthesis(context) || 00601 WN2F_CONTEXT_subexp_no_parenthesis(context)); 00602 00603 const BOOL binary_op = (wn0 != NULL); 00604 00605 TY_IDX wn0_ty; /* Expected type of wn0 */ 00606 TY_IDX wn1_ty; /* Expected type of wn1 */ 00607 TY_IDX kid0_ty; 00608 TY_IDX kid1_ty; 00609 INT priori_p = 0; 00610 INT priori_k0 = 0; 00611 INT priori_k1 = 0; 00612 00613 /* Ensure that subexpressions are parenthesized */ 00614 reset_WN2F_CONTEXT_no_parenthesis(context); 00615 00616 /* Get the expected types for the two operands, dependent on whether 00617 * or not we have a descriptor type. 00618 */ 00619 if (OPCODE_desc(opcode) == MTYPE_V) 00620 wn0_ty = wn1_ty = OPCODE_rtype(opcode); 00621 else 00622 wn0_ty = wn1_ty = Stab_Mtype_To_Ty(OPCODE_desc(opcode)); 00623 00624 if (parenthesize) 00625 Append_Token_Special(tokens, '('); 00626 00627 if (OPCODE_operator(opcode) == OPR_ADD) 00628 priori_p = 1; 00629 else if (OPCODE_operator(opcode) == OPR_SUB) 00630 priori_p = 2; 00631 else if (OPCODE_operator(opcode) == OPR_MPY) 00632 priori_p = 3; 00633 00634 if (binary_op) { 00635 if (WN_operator(wn0) == OPR_ADD || 00636 WN_operator(wn0) == OPR_SUB) 00637 priori_k0 = 2; 00638 else if (WN_operator(wn0) == OPR_MPY) 00639 priori_k0 = 3; 00640 } 00641 00642 if (WN_operator(wn1) == OPR_ADD || 00643 WN_operator(wn1) == OPR_SUB) 00644 priori_k1 = 1; 00645 else if (WN_operator(wn1) == OPR_MPY) 00646 priori_k1 = 3; 00647 00648 if (priori_p && priori_k0 && 00649 priori_p <= priori_k0) 00650 set_WN2F_CONTEXT_subexp_no_parenthesis(context); 00651 else 00652 reset_WN2F_CONTEXT_subexp_no_parenthesis(context); 00653 00654 /* First operand */ 00655 if (binary_op) { 00656 WN2F_Translate_Arithmetic_Operand(tokens, wn0, wn0_ty, 00657 TRUE/*call-by-value*/, 00658 context); 00659 } 00660 00661 reset_WN2F_CONTEXT_subexp_no_parenthesis(context); 00662 00663 /* Operation */ 00664 OPERATOR opr = OPCODE_operator(opcode); 00665 if (opr == OPR_EQ || opr == OPR_NE) { 00666 const char *oprstr = NULL, *logoprstr = NULL; 00667 switch (opr) { 00668 case OPR_EQ: 00669 oprstr = ".eq."; 00670 logoprstr = ".eqv."; 00671 break; 00672 case OPR_NE: 00673 oprstr = ".ne."; 00674 logoprstr = ".neqv."; 00675 break; 00676 }; 00677 00678 kid0_ty = kid1_ty = 0; 00679 if (WN_rtype(wn0) == MTYPE_I4 && WN_rtype(wn1) == MTYPE_I4) { 00680 if (WN_operator(wn0) == OPR_CALL) { 00681 kid0_ty = TY_ret_type(ST_pu_type(WN_st(wn0))); 00682 } 00683 else if (OPERATOR_has_1ty(WN_operator(wn0)) || OPERATOR_is_boolean(WN_operator(wn0))) { 00684 kid0_ty = WN_ty(wn0); 00685 } 00686 if (WN_operator(wn1) == OPR_CALL) { 00687 kid1_ty = TY_ret_type(ST_pu_type(WN_st(wn1))); 00688 } else if (OPERATOR_has_1ty(WN_operator(wn1)) || OPERATOR_is_boolean(WN_operator(wn1))) { 00689 kid1_ty = WN_ty(wn1); 00690 } 00691 } 00692 00693 if ( (wn0 && (kid0_ty && 00694 (TY_is_logical(kid0_ty) || TY_is_logical(wn0_ty)))) || 00695 (wn1 && (kid1_ty && 00696 (TY_is_logical(kid1_ty) || TY_is_logical(wn1_ty)))) ) { 00697 set_WN2F_CONTEXT_has_logical_arg(context); 00698 Append_Token_String(tokens, logoprstr); 00699 } 00700 else { 00701 Append_Token_String(tokens, oprstr); 00702 } 00703 } 00704 else { 00705 Append_Token_String(tokens, Opc_Fname[opcode]); 00706 reset_WN2F_CONTEXT_is_logical_operation(context); 00707 } 00708 00709 /* Second operand, or only operand for unary operation */ 00710 if (priori_p && priori_k1 && 00711 priori_p <= priori_k1) 00712 set_WN2F_CONTEXT_subexp_no_parenthesis(context); 00713 else 00714 reset_WN2F_CONTEXT_subexp_no_parenthesis(context); 00715 00716 WN2F_Translate_Arithmetic_Operand(tokens, wn1, wn1_ty, 00717 TRUE/*call-by-value*/, 00718 context); 00719 00720 reset_WN2F_CONTEXT_has_logical_arg(context); 00721 reset_WN2F_CONTEXT_subexp_no_parenthesis(context); 00722 00723 if (parenthesize) 00724 Append_Token_Special(tokens, ')'); 00725 00726 return EMPTY_WN2F_STATUS; 00727 } /* WN2F_Infix_Op */ 00728 00729 static WN2F_STATUS 00730 WN2F_Funcall_Op(TOKEN_BUFFER tokens, 00731 OPCODE opcode, 00732 WN *wn0, 00733 WN *wn1, 00734 WN2F_CONTEXT context) 00735 { 00736 /* Prefix Fortran operator. Only string argument are passed by 00737 * reference; all other argument types are passed by value. 00738 */ 00739 const BOOL binary_op = (wn0 != NULL); 00740 00741 TY_IDX const rty = Stab_Mtype_To_Ty(OPCODE_rtype(opcode)); 00742 TY_IDX dty = Stab_Mtype_To_Ty(OPCODE_desc(opcode)); 00743 00744 /* If there is no descriptor type, assume the operands should be 00745 * of the same type as the result. The assumed type of the argument 00746 * will be the dty. 00747 */ 00748 if (TY_kind(dty) == KIND_VOID) 00749 dty = rty; 00750 00751 00752 switch (OPCODE_operator(opcode)) { 00753 case OPR_EQ: 00754 if ((wn0 !=NULL) && TY_is_logical(WN_ty(wn0)) || 00755 (( wn1 !=NULL) && TY_is_logical(WN_ty(wn1)))) 00756 00757 Append_Token_String(tokens,".eqv."); 00758 else 00759 Append_Token_String(tokens,".eq."); 00760 00761 break; 00762 case OPR_NE: 00763 if ((wn0 !=NULL) && TY_is_logical(WN_ty(wn0)) || 00764 (( wn1 !=NULL) && TY_is_logical(WN_ty(wn1)))) 00765 Append_Token_String(tokens,".neq."); 00766 else 00767 Append_Token_String(tokens,".ne."); 00768 00769 break; 00770 00771 default: 00772 Append_Token_String(tokens, Opc_Fname[opcode]); 00773 reset_WN2F_CONTEXT_is_logical_operation(context); 00774 00775 break; 00776 } /*switch */ 00777 00778 00779 Append_Token_Special(tokens, '('); 00780 00781 /* No need to parenthesize subexpressions */ 00782 set_WN2F_CONTEXT_no_parenthesis(context); 00783 00784 /* First operand */ 00785 if (binary_op) 00786 { 00787 WN2F_Translate_Arithmetic_Operand(tokens, wn0, dty, 00788 TRUE/*call-by-value*/, 00789 context); 00790 Append_Token_Special(tokens, ','); 00791 } 00792 00793 /* Second operand, or only operand for unary operation */ 00794 WN2F_Translate_Arithmetic_Operand(tokens, wn1, dty, 00795 TRUE/*call-by-value*/, 00796 context); 00797 00798 Append_Token_Special(tokens, ')'); 00799 return EMPTY_WN2F_STATUS; 00800 } /* WN2F_Funcall_Op */ 00801 00802 00803 static WN2F_STATUS 00804 WN2F_Intr_Funcall(TOKEN_BUFFER tokens, 00805 WN *wn, 00806 const char *func_name, 00807 INT first_arg_idx, 00808 INT last_arg_idx, 00809 BOOL call_by_value, 00810 WN2F_CONTEXT context) 00811 { 00812 /* An intrinsic operator expression to be emitted with function 00813 * call syntax. All arguments are passed by value or by reference, 00814 * i.e. we never have some arguments passed by value and some by 00815 * reference, unless we have explicit INTR_OPC_ADRTMP or 00816 * INTR_OPC_VALTMP argument expressions. Note that we also 00817 * handle substring arguments here. 00818 */ 00819 INT arg_idx, implicit_args, total_implicit_args; 00820 TY_IDX opnd_type; 00821 00822 /* Determine the number of implicit arguments appended to the end 00823 * of the argument list (i.e. string lengths). 00824 */ 00825 if (WN_intrinsic(wn)==INTRN_COUNT) 00826 last_arg_idx--; 00827 00828 for (arg_idx = first_arg_idx, total_implicit_args = 0; 00829 arg_idx <= last_arg_idx - total_implicit_args; 00830 arg_idx++) 00831 { 00832 opnd_type = WN_Tree_Type(WN_kid(wn, arg_idx)); 00833 if (TY_Is_Character_Reference(opnd_type) || 00834 TY_Is_Chararray_Reference(opnd_type)) 00835 { 00836 total_implicit_args++; 00837 } 00838 } 00839 00840 /* Append the function-name */ 00841 if (WN_intrinsic(wn)==INTRN_LENTRIM) 00842 Append_Token_String(tokens,"LEN_TRIM"); 00843 else 00844 if (WN_intrinsic(wn)==INTRN_F90INDEX) 00845 Append_Token_String(tokens,"INDEX"); 00846 else 00847 Append_Token_String(tokens, func_name); 00848 00849 /* Append the argument list to the function reference, skipping 00850 * implicit character-string-length arguments assumed to be the 00851 * last ones in the list (see also ST2F_func_header()). 00852 */ 00853 Append_Token_Special(tokens, '('); 00854 set_WN2F_CONTEXT_no_parenthesis(context); 00855 00856 switch (WN_intrinsic(wn)) 00857 { 00858 case INTRN_F90INDEX: 00859 case INTRN_SCAN: 00860 case INTRN_VERIFY: 00861 for (arg_idx = first_arg_idx; 00862 arg_idx < last_arg_idx ; 00863 arg_idx=arg_idx+2) 00864 { 00865 opnd_type = WN_Tree_Type(WN_kid(wn, arg_idx)); 00866 00867 if (TY_Is_Character_Reference(opnd_type) || 00868 TY_Is_Chararray_Reference(opnd_type)) 00869 { 00870 WN2F_String_Argument(tokens, 00871 WN_kid(wn, arg_idx), /* string base */ 00872 WN_kid(wn, 00873 last_arg_idx 00874 ), /* string length */ 00875 context); 00876 } 00877 else { 00878 00879 WN2F_Translate_Arithmetic_Operand(tokens, 00880 WN_kid(wn, arg_idx), 00881 opnd_type, 00882 call_by_value, 00883 context); 00884 00885 } 00886 00887 if ((arg_idx) < WN_kid_count(wn) - 1) 00888 Append_Token_Special(tokens, ','); 00889 00890 } 00891 00892 set_WN2F_CONTEXT_has_logical_arg(context); 00893 00894 WN2F_Translate_Arithmetic_Operand(tokens, 00895 WN_kid(wn, last_arg_idx), 00896 opnd_type, 00897 call_by_value, 00898 context); 00899 00900 reset_WN2F_CONTEXT_has_logical_arg(context); 00901 00902 00903 break; 00904 00905 default: 00906 00907 for (arg_idx = first_arg_idx, implicit_args = 0; 00908 arg_idx <= last_arg_idx - implicit_args; 00909 arg_idx++) 00910 { 00911 opnd_type = WN_Tree_Type(WN_kid(wn, arg_idx)); 00912 00913 if (TY_Is_Character_Reference(opnd_type) || 00914 TY_Is_Chararray_Reference(opnd_type)) 00915 { 00916 implicit_args++; 00917 WN2F_String_Argument(tokens, 00918 WN_kid(wn, arg_idx), /* string base */ 00919 WN_kid(wn, 00920 last_arg_idx - 00921 (total_implicit_args - 00922 implicit_args)), /* string length */ 00923 context); 00924 if ((arg_idx+implicit_args) < WN_kid_count(wn) - 1) 00925 Append_Token_Special(tokens, ','); 00926 } 00927 else 00928 00929 if ((WN_intrinsic(wn)==INTRN_SUM|| 00930 INTRN_MAXVAL|| 00931 INTRN_PRODUCT) && 00932 (WN_opc_operator(WN_kid0(WN_kid(wn,arg_idx)))== OPR_INTCONST) && 00933 (WN_const_val(WN_kid0(WN_kid(wn,arg_idx)))==0)) { 00934 00935 } else { 00936 00937 WN2F_Translate_Arithmetic_Operand(tokens, 00938 WN_kid(wn, arg_idx), 00939 opnd_type, 00940 call_by_value, 00941 context); 00942 00943 // if ((arg_idx+implicit_args) < WN_kid_count(wn) - 1) 00944 if ((arg_idx+implicit_args) < last_arg_idx) 00945 if ((WN_intrinsic(wn)==INTRN_SUM || 00946 INTRN_MAXVAL|| 00947 INTRN_PRODUCT) && 00948 (WN_opc_operator(WN_kid0(WN_kid(wn,arg_idx+1)))== OPR_INTCONST) && 00949 (WN_const_val(WN_kid0(WN_kid(wn,arg_idx+1)))==0)) { 00950 00951 } else 00952 Append_Token_Special(tokens, ',');} 00953 } 00954 break; 00955 } 00956 Append_Token_Special(tokens, ')'); 00957 00958 /* TODO: See if we need to cast the resultant value */ 00959 00960 return EMPTY_WN2F_STATUS; 00961 } /* WN2F_Intr_Funcall */ 00962 00963 00964 static WN2F_STATUS 00965 WN2F_Intr_Infix(TOKEN_BUFFER tokens, 00966 const char *op_name, 00967 WN *opnd0, /* NULL for unary operation */ 00968 WN *opnd1, 00969 BOOL call_by_value, 00970 WN2F_CONTEXT context) 00971 { 00972 /* An intrinsic operator expression to be emitted with infix operator 00973 * syntax. Note that we have already determined what the two arguments 00974 * are, and any implicit argument have already been ignored. 00975 */ 00976 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 00977 const BOOL binary_op = (opnd0 != NULL); 00978 00979 /* Ensure that subexpressions are parenthesized */ 00980 reset_WN2F_CONTEXT_no_parenthesis(context); 00981 00982 if (parenthesize) 00983 Append_Token_Special(tokens, '('); 00984 00985 if (binary_op) 00986 WN2F_Translate_Arithmetic_Operand(tokens, 00987 opnd0, 00988 WN_Tree_Type(opnd0), 00989 call_by_value, 00990 context); 00991 Append_Token_String(tokens, op_name); 00992 WN2F_Translate_Arithmetic_Operand(tokens, 00993 opnd1, 00994 WN_Tree_Type(opnd1), 00995 call_by_value, 00996 context); 00997 if (parenthesize) 00998 Append_Token_Special(tokens, ')'); 00999 01000 return EMPTY_WN2F_STATUS; 01001 } /* WN2F_Intr_Infix */ 01002 01003 01004 static WN2F_STATUS 01005 WN2F_Binary_Substr_Op(TOKEN_BUFFER tokens, 01006 WN *op_wn, /* Top-level expression */ 01007 const char *op_name, /* The builtin operator */ 01008 WN2F_CONTEXT context) 01009 { 01010 /* Similar to WN2F_Infix_Op, but we expect the arguments to be 01011 * string expressions. 01012 */ 01013 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 01014 01015 /* Ensure that subexpressions are parenthesized */ 01016 reset_WN2F_CONTEXT_no_parenthesis(context); 01017 01018 if (parenthesize) 01019 Append_Token_Special(tokens, '('); 01020 01021 WN2F_String_Argument(tokens, 01022 WN_kid(op_wn, 0), /* string base */ 01023 WN_kid(op_wn, 2), /* string length */ 01024 context); 01025 Append_Token_String(tokens, op_name); 01026 WN2F_String_Argument(tokens, 01027 WN_kid(op_wn, 1), /* string base */ 01028 WN_kid(op_wn, 3), /* string length */ 01029 context); 01030 if (parenthesize) 01031 Append_Token_Special(tokens, ')'); 01032 01033 return EMPTY_WN2F_STATUS; 01034 } /* WN2F_Binary_Substr_Op */ 01035 01036 01037 /*------------------------- Exported Functions ------------------------*/ 01038 /*---------------------------------------------------------------------*/ 01039 01040 01041 void WN2F_Expr_initialize(void) 01042 { 01043 INT map; 01044 01045 /* Reset the Opc_Fname array. This has already been 01046 * implicitly done by declaring it as static: 01047 * 01048 * OPCODE opc; 01049 * for (opc = 0; opc < NUMBER_OF_OPCODES; opc++) 01050 * Opc_Fname[opc] = NULL; 01051 * 01052 * Initialize the Opc_Fname array: 01053 */ 01054 for (map = 0; map < NUMBER_OF_FNAME_PARTIALMAPS; map++) 01055 Opc_Fname[Fname_Map[map].opc] = Fname_Map[map].fname; 01056 01057 /* Initialize the Conv_Op array (default value is NULL) */ 01058 for (map = 0; map < NUMBER_OF_CONV_OPS; map++) 01059 Conv_Op[Conv_Op_Map[map].from][Conv_Op_Map[map].to] = 01060 Conv_Op_Map[map].name; 01061 01062 } /* WN2F_Expr_initialize */ 01063 01064 01065 void WN2F_Expr_finalize(void) 01066 { 01067 /* Nothing to do for now */ 01068 } /* WN2F_Expr_finalize */ 01069 01070 01071 WN2F_STATUS 01072 WN2F_binaryop(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01073 { 01074 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 01075 01076 ASSERT_DBG_FATAL(WN_kid_count(wn) == 2, 01077 (DIAG_W2F_UNEXPECTED_NUM_KIDS, 01078 WN_kid_count(wn), 2, WN_opc_name(wn))); 01079 01080 if (WN2F_IS_INFIX_OP(WN_opcode(wn))) 01081 WN2F_Infix_Op(tokens, 01082 WN_opcode(wn), 01083 WN_Tree_Type(wn), 01084 WN_kid0(wn), 01085 WN_kid1(wn), 01086 context); 01087 else if (WN2F_IS_FUNCALL_OP(WN_opcode(wn))) 01088 WN2F_Funcall_Op(tokens, 01089 WN_opcode(wn), 01090 WN_kid0(wn), 01091 WN_kid1(wn), 01092 context); 01093 else 01094 ASSERT_DBG_FATAL(FALSE, (DIAG_W2F_UNEXPECTED_OPC, "WN2F_binaryop")); 01095 01096 reset_WN2F_CONTEXT_is_logical_operation(context); 01097 01098 return EMPTY_WN2F_STATUS; 01099 } /* WN2F_binaryop */ 01100 01101 01102 WN2F_STATUS 01103 WN2F_unaryop(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01104 { 01105 ASSERT_DBG_FATAL(WN_kid_count(wn) == 1, 01106 (DIAG_W2F_UNEXPECTED_NUM_KIDS, 01107 WN_kid_count(wn), 1, WN_opc_name(wn))); 01108 01109 if (WN2F_IS_INFIX_OP(WN_opcode(wn))) 01110 WN2F_Infix_Op(tokens, 01111 WN_opcode(wn), 01112 WN_Tree_Type(wn), 01113 NULL, /* No first operand */ 01114 WN_kid0(wn), 01115 context); 01116 else if (WN2F_IS_FUNCALL_OP(WN_opcode(wn))) 01117 WN2F_Funcall_Op(tokens, 01118 WN_opcode(wn), 01119 NULL, /* No first operand */ 01120 WN_kid0(wn), 01121 context); 01122 else 01123 ASSERT_DBG_FATAL(FALSE, (DIAG_W2F_UNEXPECTED_OPC, "WN2F_binaryop")); 01124 01125 return EMPTY_WN2F_STATUS; 01126 } /* WN2F_unaryop */ 01127 01128 01129 WN2F_STATUS 01130 WN2F_intrinsic_op(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01131 { 01132 /* An intrinsic operator expression. Generate the call as is, 01133 * regardless how the return value is returned, since we know 01134 * the consumer of the value is the surrounding expression. This 01135 * call is not related to the call-info generated by PUinfo. 01136 * Note that either all or none of the arguments are call-by-value. 01137 */ 01138 INT first_arg_idx, last_arg_idx; 01139 BOOL by_value; 01140 01141 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_INTRINSIC_OP, 01142 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_intrinsic_op")); 01143 01144 by_value = INTRN_by_value(WN_intrinsic(wn)); 01145 last_arg_idx = WN_kid_count(wn) - 1; 01146 first_arg_idx = 0; /* Assume we never return to first argument */ 01147 01148 /* Switch on WN_intrinsic(wn) to handle builtin fortran opcodes. 01149 */ 01150 switch (WN_intrinsic(wn)) 01151 { 01152 case INTRN_I4EXPEXPR: 01153 case INTRN_I8EXPEXPR: 01154 case INTRN_F4EXPEXPR: 01155 case INTRN_F8EXPEXPR: 01156 case INTRN_FQEXPEXPR: 01157 case INTRN_C4EXPEXPR: 01158 case INTRN_C8EXPEXPR: 01159 case INTRN_CQEXPEXPR: 01160 case INTRN_F4I4EXPEXPR: 01161 case INTRN_F4I8EXPEXPR: 01162 case INTRN_F8I4EXPEXPR: 01163 case INTRN_F8I8EXPEXPR: 01164 case INTRN_FQI4EXPEXPR: 01165 case INTRN_FQI8EXPEXPR: 01166 case INTRN_C4I4EXPEXPR: 01167 case INTRN_C4I8EXPEXPR: 01168 case INTRN_C8I4EXPEXPR: 01169 case INTRN_C8I8EXPEXPR: 01170 case INTRN_CQI4EXPEXPR: 01171 case INTRN_CQI8EXPEXPR: 01172 WN2F_Intr_Infix(tokens, 01173 "**", WN_kid0(wn), WN_kid1(wn), by_value, context); 01174 break; 01175 01176 case INTRN_CEQEXPR: 01177 WN2F_Binary_Substr_Op(tokens, wn, ".EQ.", context); 01178 break; 01179 case INTRN_CNEEXPR: 01180 WN2F_Binary_Substr_Op(tokens, wn, ".NE.", context); 01181 break; 01182 case INTRN_CGEEXPR: 01183 WN2F_Binary_Substr_Op(tokens, wn, ".GE.", context); 01184 break; 01185 case INTRN_CGTEXPR: 01186 WN2F_Binary_Substr_Op(tokens, wn, ".GT.", context); 01187 break; 01188 case INTRN_CLEEXPR: 01189 WN2F_Binary_Substr_Op(tokens, wn, ".LE.", context); 01190 break; 01191 case INTRN_CLTEXPR: 01192 WN2F_Binary_Substr_Op(tokens, wn, ".LT.", context); 01193 break; 01194 01195 case INTRN_U4I1ADRTMP: 01196 case INTRN_U4I2ADRTMP: 01197 case INTRN_U4I4ADRTMP: 01198 case INTRN_U4I8ADRTMP: 01199 case INTRN_U4F4ADRTMP: 01200 case INTRN_U4F8ADRTMP: 01201 case INTRN_U4FQADRTMP: 01202 case INTRN_U4C4ADRTMP: 01203 case INTRN_U4C8ADRTMP: 01204 case INTRN_U4CQADRTMP: 01205 case INTRN_U4VADRTMP : 01206 case INTRN_U8I1ADRTMP: 01207 case INTRN_U8I2ADRTMP: 01208 case INTRN_U8I4ADRTMP: 01209 case INTRN_U8I8ADRTMP: 01210 case INTRN_U8F4ADRTMP: 01211 case INTRN_U8F8ADRTMP: 01212 case INTRN_U8FQADRTMP: 01213 case INTRN_U8C4ADRTMP: 01214 case INTRN_U8C8ADRTMP: 01215 case INTRN_U8CQADRTMP: 01216 case INTRN_U8VADRTMP: 01217 /* Implicit call by reference. Emit the dereferenced parameter. 01218 */ 01219 WN2F_translate(tokens, WN_kid0(wn), context); 01220 break; 01221 01222 case INTRN_I4VALTMP: 01223 case INTRN_I8VALTMP: 01224 case INTRN_F4VALTMP: 01225 case INTRN_F8VALTMP: 01226 case INTRN_FQVALTMP: 01227 case INTRN_C4VALTMP: 01228 case INTRN_C8VALTMP: 01229 case INTRN_CQVALTMP: 01230 /* Call-by-value. Assume the context determines when it is 01231 * necessary to put a %val qualifier around the argument. 01232 */ 01233 WN2F_translate(tokens, WN_kid0(wn), context); 01234 break; 01235 01236 default: 01237 WN2F_Intr_Funcall(tokens, 01238 wn, 01239 WN_intrinsic_name((INTRINSIC) WN_intrinsic(wn)), 01240 first_arg_idx, 01241 last_arg_idx, 01242 by_value, 01243 context); 01244 break; 01245 } /*switch*/ 01246 01247 /* TODO: See if we need to cast the resultant value. 01248 * TY * return_ty = 01249 * WN_intrinsic_return_ty(WN_opcode(wn), WN_intrinsic(wn)); 01250 */ 01251 01252 return EMPTY_WN2F_STATUS; 01253 } /* WN2F_intrinsic_op */ 01254 01255 01256 WN2F_STATUS 01257 WN2F_tas(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01258 { 01259 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_TAS, 01260 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_tas")); 01261 01262 /* Just ignore TAS operators for now. TODO: make sure this 01263 * is always ok. 01264 */ 01265 return WN2F_translate(tokens, WN_kid0(wn), context); 01266 } /* WN2F_tas */ 01267 01268 01269 WN2F_STATUS 01270 WN2F_select(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01271 { 01272 /* SELECT is almost the same as the F90 MERGE intrinsic, 01273 so I will output it that way for now */ 01274 01275 Append_Token_String(tokens, "MERGE"); 01276 Append_Token_Special(tokens, '('); 01277 WN2F_translate(tokens, WN_kid1(wn), context); 01278 Append_Token_Special(tokens, ','); 01279 01280 WN2F_translate(tokens, WN_kid2(wn), context); 01281 Append_Token_Special(tokens, ','); 01282 01283 WN2F_translate(tokens, WN_kid0(wn), context); 01284 01285 Append_Token_Special(tokens, ')'); 01286 #if 0 01287 ASSERT_DBG_WARN(FALSE, (DIAG_UNIMPLEMENTED, "WN2F_select")); 01288 #endif 01289 01290 return EMPTY_WN2F_STATUS; 01291 } /* WN2F_select */ 01292 01293 01294 WN2F_STATUS 01295 WN2F_cvt(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01296 { 01297 TOKEN_BUFFER expr_tokens = New_Token_Buffer(); 01298 01299 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_CVT, 01300 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_cvt")); 01301 01302 WN2F_translate(expr_tokens, WN_kid0(wn), context); 01303 01304 /* Maybe we shouldn't or needn't explicitly output these kinds of 01305 convert in .w2f.f file----fzhao 01306 */ 01307 if (W2F_OpenAD) { 01308 WN2F_Convert(expr_tokens, WN_opc_dtype(wn), WN_opc_rtype(wn)); 01309 } 01310 Append_And_Reclaim_Token_List(tokens, &expr_tokens); 01311 01312 return EMPTY_WN2F_STATUS; 01313 } /* WN2F_cvt */ 01314 01315 01316 WN2F_STATUS 01317 WN2F_cvtl(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01318 { 01319 TY_IDX rtype, dtype; 01320 TOKEN_BUFFER expr_tokens; 01321 01322 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_CVTL, 01323 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_cvtl")); 01324 01325 dtype = WN_Tree_Type(WN_kid0(wn)); 01326 rtype = WN_Tree_Type(wn); 01327 01328 /* Only convert if it is necessary */ 01329 01330 if (Conv_Op[TY_mtype(dtype)][TY_mtype(rtype)] != NULL ) 01331 01332 { 01333 expr_tokens = New_Token_Buffer(); 01334 WN2F_translate(expr_tokens, WN_kid0(wn), context); 01335 WN2F_Convert(expr_tokens, TY_mtype(dtype), TY_mtype(rtype)); 01336 Append_And_Reclaim_Token_List(tokens, &expr_tokens); 01337 } 01338 else 01339 { 01340 WN2F_translate(tokens, WN_kid0(wn), context); 01341 } 01342 return EMPTY_WN2F_STATUS; 01343 } /* WN2F_cvtl */ 01344 01345 01346 WN2F_STATUS 01347 WN2F_realpart(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01348 { 01349 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_REALPART, 01350 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_realpart")); 01351 01352 switch (WN_opc_rtype(wn)) 01353 { 01354 case MTYPE_F4: 01355 Append_Token_String(tokens, "REAL"); 01356 break; 01357 case MTYPE_F8: 01358 Append_Token_String(tokens, "DBLE"); 01359 break; 01360 case MTYPE_FQ: 01361 Append_Token_String(tokens, "QREAL"); 01362 01363 break; 01364 default: 01365 ASSERT_DBG_FATAL(FALSE, 01366 (DIAG_W2F_UNEXPECTED_BTYPE, 01367 MTYPE_name(WN_opc_rtype(wn)), 01368 "WN2F_realpart")); 01369 Append_Token_String(tokens, "WN2F_realpart"); 01370 break; 01371 } 01372 Append_Token_Special(tokens, '('); 01373 WN2F_translate(tokens, WN_kid0(wn), context); 01374 Append_Token_Special(tokens, ')'); 01375 01376 return EMPTY_WN2F_STATUS; 01377 } /* WN2F_realpart */ 01378 01379 01380 WN2F_STATUS 01381 WN2F_imagpart(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01382 { 01383 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_IMAGPART, 01384 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_imagpart")); 01385 01386 switch (WN_opc_rtype(wn)) 01387 { 01388 case MTYPE_F4: 01389 Append_Token_String(tokens, "AIMAG"); 01390 break; 01391 case MTYPE_F8: 01392 Append_Token_String(tokens, "DIMAG"); 01393 break; 01394 case MTYPE_FQ: 01395 Append_Token_String(tokens, "QIMAG"); 01396 break; 01397 default: 01398 ASSERT_DBG_FATAL(FALSE, 01399 (DIAG_W2F_UNEXPECTED_BTYPE, 01400 MTYPE_name(WN_opc_rtype(wn)), 01401 "WN2F_imagpart")); 01402 Append_Token_String(tokens, "WN2F_imagpart"); 01403 break; 01404 } 01405 Append_Token_Special(tokens, '('); 01406 WN2F_translate(tokens, WN_kid0(wn), context); 01407 Append_Token_Special(tokens, ')'); 01408 01409 return EMPTY_WN2F_STATUS; 01410 } /* WN2F_imagpart */ 01411 01412 01413 WN2F_STATUS 01414 WN2F_paren(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01415 { 01416 WN2F_STATUS status; 01417 01418 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_PAREN, 01419 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_paren")); 01420 01421 Append_Token_Special(tokens, '('); 01422 set_WN2F_CONTEXT_subexp_no_parenthesis(context); 01423 status = WN2F_translate(tokens, WN_kid0(wn), context); 01424 reset_WN2F_CONTEXT_subexp_no_parenthesis(context); 01425 Append_Token_Special(tokens, ')'); 01426 01427 return status; 01428 } /* WN2F_paren */ 01429 01430 01431 WN2F_STATUS 01432 WN2F_complex(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01433 { 01434 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_COMPLEX, 01435 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_complex")); 01436 01437 switch (WN_opc_rtype(wn)) 01438 { 01439 case MTYPE_C4: 01440 Append_Token_String(tokens, "CMPLX"); 01441 break; 01442 case MTYPE_C8: 01443 Append_Token_String(tokens, "DCMPLX"); 01444 break; 01445 case MTYPE_CQ: 01446 Append_Token_String(tokens, "QCMPLX"); 01447 break; 01448 default: 01449 ASSERT_DBG_FATAL(FALSE, 01450 (DIAG_W2F_UNEXPECTED_BTYPE, 01451 MTYPE_name(WN_opc_rtype(wn)), 01452 "WN2F_complex")); 01453 Append_Token_String(tokens, "WN2F_complex"); 01454 break; 01455 } 01456 /* No need to parenthesize subexpressions */ 01457 set_WN2F_CONTEXT_no_parenthesis(context); 01458 01459 Append_Token_Special(tokens, '('); /* getting real part */ 01460 (void)WN2F_translate(tokens, WN_kid0(wn), context); 01461 Append_Token_Special(tokens, ','); /* getting imaginary part */ 01462 (void)WN2F_translate(tokens, WN_kid1(wn), context); 01463 Append_Token_Special(tokens, ')'); 01464 01465 return EMPTY_WN2F_STATUS; 01466 } /* WN2F_complex */ 01467 01468 01469 WN2F_STATUS 01470 WN2F_ceil(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01471 { 01472 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_CEIL, 01473 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_ceil")); 01474 ASSERT_DBG_FATAL(WN_kid_count(wn) == 1, 01475 (DIAG_W2F_UNEXPECTED_NUM_KIDS, 01476 WN_kid_count(wn), 1, WN_opc_name(wn))); 01477 01478 /* Special handling for opcodes that do not have an intrinsic 01479 * counterpart in compiler versions < v7.00. TODO: define this one. 01480 */ 01481 ASSERT_DBG_WARN(!W2F_Ansi_Format, 01482 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_ceil")); 01483 01484 WN2F_Funcall_Op(tokens, 01485 WN_opcode(wn), 01486 NULL, 01487 WN_kid0(wn), 01488 context); 01489 01490 return EMPTY_WN2F_STATUS; 01491 } /* WN2F_ceil */ 01492 01493 01494 WN2F_STATUS 01495 WN2F_floor(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01496 { 01497 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_FLOOR, 01498 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_floor")); 01499 ASSERT_DBG_FATAL(WN_kid_count(wn) == 1, 01500 (DIAG_W2F_UNEXPECTED_NUM_KIDS, 01501 WN_kid_count(wn), 1, WN_opc_name(wn))); 01502 01503 /* Special handling for opcodes that do not have an intrinsic 01504 * counterpart in compiler versions < v7.00. TODO: define this one. 01505 */ 01506 ASSERT_DBG_WARN(!W2F_Ansi_Format, 01507 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_floor")); 01508 01509 WN2F_Funcall_Op(tokens, 01510 WN_opcode(wn), 01511 NULL, 01512 WN_kid0(wn), 01513 context); 01514 01515 return EMPTY_WN2F_STATUS; 01516 } /* WN2F_floor */ 01517 01518 01519 WN2F_STATUS 01520 WN2F_ashr(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01521 { 01522 TY_IDX const rty = Stab_Mtype_To_Ty(WN_rtype(wn)); 01523 01524 ASSERT_DBG_FATAL(WN_kid_count(wn) == 2, 01525 (DIAG_W2F_UNEXPECTED_NUM_KIDS, 01526 WN_kid_count(wn), 2, WN_opc_name(wn))); 01527 01528 if (W2F_Ansi_Format) 01529 { 01530 /* Special handling for opcodes that do not have an intrinsic 01531 * counterpart in compiler versions < v7.00. 01532 */ 01533 switch (WN_opcode(wn)) 01534 { 01535 case OPC_I4ASHR: 01536 Append_Token_String(tokens, "I4ASHR"); 01537 break; 01538 case OPC_U8ASHR: 01539 Append_Token_String(tokens, "U8ASHR"); 01540 break; 01541 case OPC_I8ASHR: 01542 Append_Token_String(tokens, "I8ASHR"); 01543 break; 01544 case OPC_U4ASHR: 01545 Append_Token_String(tokens, "I4ASHR"); 01546 break; 01547 default: 01548 ASSERT_DBG_FATAL(FALSE, 01549 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_ashr")); 01550 break; 01551 } 01552 01553 /* No need to parenthesize subexpressions */ 01554 set_WN2F_CONTEXT_no_parenthesis(context); 01555 01556 Append_Token_Special(tokens, '('); 01557 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid0(wn), rty, 01558 TRUE, /* call-by-value */ 01559 context); 01560 Append_Token_Special(tokens, ','); 01561 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid1(wn), rty, 01562 TRUE, /* call-by-value */ 01563 context); 01564 01565 Append_Token_Special(tokens, ')'); 01566 } 01567 else 01568 { 01569 /* Has an intrinsic counterpart in compiler versions >= v7.00. 01570 */ 01571 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_ASHR, 01572 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_ashr")); 01573 WN2F_Funcall_Op(tokens, 01574 WN_opcode(wn), 01575 WN_kid0(wn), 01576 WN_kid1(wn), 01577 context); 01578 } 01579 01580 return EMPTY_WN2F_STATUS; 01581 } /* WN2F_ashr */ 01582 01583 01584 WN2F_STATUS 01585 WN2F_lshr(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01586 { 01587 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01588 01589 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_LSHR, 01590 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_lshr")); 01591 01592 /* No need to parenthesize subexpressions */ 01593 set_WN2F_CONTEXT_no_parenthesis(context); 01594 01595 Append_Token_String(tokens, "ISHIFT"); 01596 Append_Token_Special(tokens, '('); 01597 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,0), result_ty, 01598 !TY_Is_Character_Reference(result_ty), 01599 context); 01600 Append_Token_Special(tokens, ','); 01601 Append_Token_Special(tokens, '-'); 01602 Append_Token_Special(tokens, '('); 01603 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,1), result_ty, 01604 !TY_Is_Character_Reference(result_ty), 01605 context); 01606 Append_Token_Special(tokens, ')'); 01607 Append_Token_Special(tokens, ')'); 01608 01609 return EMPTY_WN2F_STATUS; 01610 } /* WN2F_lshr */ 01611 01612 01613 WN2F_STATUS 01614 WN2F_bnor(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01615 { 01616 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01617 01618 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_BNOR, 01619 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_bnor")); 01620 01621 /* No need to parenthesize subexpressions */ 01622 set_WN2F_CONTEXT_no_parenthesis(context); 01623 01624 Append_Token_String(tokens, "NOT"); 01625 Append_Token_Special(tokens, '('); 01626 Append_Token_String(tokens, "IOR"); 01627 Append_Token_Special(tokens, '('); 01628 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,0), result_ty, 01629 !TY_Is_Character_Reference(result_ty), 01630 context); 01631 Append_Token_Special(tokens, ','); 01632 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,1), result_ty, 01633 !TY_Is_Character_Reference(result_ty), 01634 context); 01635 Append_Token_Special(tokens, ')'); 01636 Append_Token_Special(tokens, ')'); 01637 01638 return EMPTY_WN2F_STATUS; 01639 } /* WN2F_bnor */ 01640 01641 01642 WN2F_STATUS 01643 WN2F_recip(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01644 { 01645 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01646 BOOL no_parenthesis = (WN_operator(WN_kid0(wn)) == OPR_PAREN || 01647 WN_operator(WN_kid0(wn)) == OPR_LDID || 01648 WN_operator(WN_kid0(wn)) == OPR_LDA); 01649 01650 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_RECIP, 01651 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_recip")); 01652 01653 if (TY_mtype(result_ty) == MTYPE_FQ || TY_mtype(result_ty) == MTYPE_CQ) 01654 Append_Token_String(tokens, "1Q00"); 01655 else if (TY_mtype(result_ty) == MTYPE_F8 || TY_mtype(result_ty) == MTYPE_C8) 01656 Append_Token_String(tokens, "1D00"); 01657 else 01658 Append_Token_String(tokens, "1E00"); 01659 01660 Append_Token_Special(tokens, '/'); 01661 if (!no_parenthesis) 01662 Append_Token_Special(tokens, '('); 01663 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,0), result_ty, 01664 !TY_Is_Character_Reference(result_ty), 01665 context); 01666 if (!no_parenthesis) 01667 Append_Token_Special(tokens, ')'); 01668 01669 return EMPTY_WN2F_STATUS; 01670 } /* WN2F_recip */ 01671 01672 WN2F_STATUS 01673 WN2F_rsqrt(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01674 { 01675 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01676 01677 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_RSQRT, 01678 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_rsqrt")); 01679 01680 Append_Token_Special(tokens, '('); 01681 Append_Token_String(tokens, "1.0"); 01682 Append_Token_Special(tokens, '/'); 01683 Append_Token_String(tokens, "SQRT"); 01684 Append_Token_Special(tokens, '('); 01685 set_WN2F_CONTEXT_no_parenthesis(context); 01686 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,0), result_ty, 01687 !TY_Is_Character_Reference(result_ty), 01688 context); 01689 Append_Token_Special(tokens, ')'); 01690 Append_Token_Special(tokens, ')'); 01691 01692 return EMPTY_WN2F_STATUS; 01693 } /* WN2F_rsqrt */ 01694 01695 01696 WN2F_STATUS 01697 WN2F_madd(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01698 { 01699 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01700 01701 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_MADD, 01702 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_madd")); 01703 01704 Append_Token_Special(tokens, '('); 01705 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,1), result_ty, 01706 !TY_Is_Character_Reference(result_ty), 01707 context); 01708 Append_Token_Special(tokens, '*'); 01709 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,2), result_ty, 01710 !TY_Is_Character_Reference(result_ty), 01711 context); 01712 Append_Token_Special(tokens, '+'); 01713 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn, 0), result_ty, 01714 !TY_Is_Character_Reference(result_ty), 01715 context); 01716 Append_Token_Special(tokens, ')'); 01717 01718 return EMPTY_WN2F_STATUS; 01719 } /* WN2F_madd */ 01720 01721 01722 WN2F_STATUS 01723 WN2F_msub(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01724 { 01725 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01726 01727 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_MSUB, 01728 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_msub")); 01729 01730 Append_Token_Special(tokens, '('); 01731 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,1), result_ty, 01732 !TY_Is_Character_Reference(result_ty), 01733 context); 01734 Append_Token_Special(tokens, '*'); 01735 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,2), result_ty, 01736 !TY_Is_Character_Reference(result_ty), 01737 context); 01738 Append_Token_Special(tokens, '-'); 01739 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn, 0), result_ty, 01740 !TY_Is_Character_Reference(result_ty), 01741 context); 01742 Append_Token_Special(tokens, ')'); 01743 01744 return EMPTY_WN2F_STATUS; 01745 } /* WN2F_msub */ 01746 01747 01748 WN2F_STATUS 01749 WN2F_nmadd(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01750 { 01751 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01752 01753 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_NMADD, 01754 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_nmadd")); 01755 01756 Append_Token_Special(tokens, '-'); 01757 Append_Token_Special(tokens, '('); 01758 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,1), result_ty, 01759 !TY_Is_Character_Reference(result_ty), 01760 context); 01761 Append_Token_Special(tokens, '*'); 01762 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,2), result_ty, 01763 !TY_Is_Character_Reference(result_ty), 01764 context); 01765 Append_Token_Special(tokens, '+'); 01766 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn, 0), result_ty, 01767 !TY_Is_Character_Reference(result_ty), 01768 context); 01769 Append_Token_Special(tokens, ')'); 01770 01771 return EMPTY_WN2F_STATUS; 01772 } /* WN2F_nmadd */ 01773 01774 01775 WN2F_STATUS 01776 WN2F_nmsub(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01777 { 01778 TY_IDX const result_ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn)); 01779 01780 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_NMSUB, 01781 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_nmsub")); 01782 01783 Append_Token_Special(tokens, '-'); 01784 Append_Token_Special(tokens, '('); 01785 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,1), result_ty, 01786 !TY_Is_Character_Reference(result_ty), 01787 context); 01788 Append_Token_Special(tokens, '*'); 01789 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn,2), result_ty, 01790 !TY_Is_Character_Reference(result_ty), 01791 context); 01792 Append_Token_Special(tokens, '-'); 01793 WN2F_Translate_Arithmetic_Operand(tokens, WN_kid(wn, 0), result_ty, 01794 !TY_Is_Character_Reference(result_ty), 01795 context); 01796 Append_Token_Special(tokens, ')'); 01797 01798 return EMPTY_WN2F_STATUS; 01799 } /* WN2F_nmsub */ 01800 01801 01802 WN2F_STATUS 01803 WN2F_const(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01804 { 01805 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 01806 BOOL add_paren = false; 01807 01808 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_CONST, 01809 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_const")); 01810 01811 /* eraxxon: always parenthesize negative constants to prevent generation of 01812 code like "x + -73" */ 01813 TCON& tcon = STC_val(WN_st(wn)); 01814 if (parenthesize && !WN2F_CONTEXT_is_logical_arg(context)) { 01815 BOOL neg_num = 0; 01816 switch (TCON_ty(tcon)) 01817 { 01818 case MTYPE_F4: 01819 neg_num = (TCON_fval(tcon) < 0); 01820 break; 01821 case MTYPE_F8: 01822 neg_num = (TCON_dval(tcon) < 0); 01823 break; 01824 case MTYPE_FQ: 01825 neg_num = (TCON_qval(tcon) < 0); 01826 break; 01827 case MTYPE_I1: 01828 case MTYPE_I2: 01829 case MTYPE_I4: 01830 case MTYPE_I8: 01831 neg_num = (TCON_ival(tcon) < 0); 01832 break; 01833 } 01834 add_paren = (neg_num); 01835 } 01836 01837 if (add_paren) { 01838 Append_Token_Special(tokens, '('); 01839 } 01840 TCON2F_translate(tokens, tcon, (TY_is_logical(ST_type(WN_st(wn))) || 01841 WN2F_CONTEXT_is_logical_arg(context))); 01842 if (add_paren) { 01843 Append_Token_Special(tokens, ')'); 01844 } 01845 01846 if (parenthesize) 01847 reset_WN2F_CONTEXT_no_parenthesis(context); 01848 01849 return EMPTY_WN2F_STATUS; 01850 } /* WN2F_const */ 01851 01852 01853 WN2F_STATUS 01854 WN2F_intconst(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01855 { 01856 const BOOL parenthesize = !WN2F_CONTEXT_no_parenthesis(context); 01857 01858 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_INTCONST, 01859 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_intconst")); 01860 01861 if (parenthesize && !WN2F_CONTEXT_is_logical_arg(context)) 01862 { 01863 switch (TCON_ty(Host_To_Targ(WN_opc_rtype(wn), WN_const_val(wn)))) 01864 { 01865 case MTYPE_I1: 01866 case MTYPE_I2: 01867 case MTYPE_I4: 01868 case MTYPE_I8: 01869 if (TCON_ival(Host_To_Targ(WN_opc_rtype(wn), WN_const_val(wn)))<0) { 01870 Append_Token_Special(tokens, '('); 01871 TCON2F_translate(tokens, 01872 Host_To_Targ(WN_opc_rtype(wn), WN_const_val(wn)), 01873 WN2F_CONTEXT_is_logical_arg(context)); 01874 01875 Append_Token_Special(tokens, ')'); 01876 } 01877 else 01878 TCON2F_translate(tokens, 01879 Host_To_Targ(WN_opc_rtype(wn), WN_const_val(wn)), 01880 WN2F_CONTEXT_is_logical_arg(context)); 01881 break; 01882 01883 default: 01884 TCON2F_translate(tokens, 01885 Host_To_Targ(WN_opc_rtype(wn), WN_const_val(wn)), 01886 WN2F_CONTEXT_is_logical_arg(context)); 01887 01888 break; 01889 01890 } /*switch*/ 01891 } 01892 else 01893 01894 TCON2F_translate(tokens, 01895 Host_To_Targ(WN_opc_rtype(wn), WN_const_val(wn)), 01896 WN2F_CONTEXT_is_logical_arg(context)); 01897 if (parenthesize) 01898 reset_WN2F_CONTEXT_no_parenthesis(context); 01899 01900 return EMPTY_WN2F_STATUS; 01901 } /* WN2F_intconst */ 01902 01903 01904 WN2F_STATUS 01905 WN2F_eq(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01906 { 01907 /* Try to reduce "bool .EQ. 0" to simply ".NOT. (bool)", whenever possible. 01908 */ 01909 01910 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_EQ, 01911 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_eq")); 01912 01913 if (WN_opc_operator(WN_kid0(wn)) == OPR_INTCONST && 01914 WN_const_val(WN_kid0(wn)) == 0LL && 01915 (OPCODE_is_boolean(WN_opcode(WN_kid1(wn))) || 01916 TY_is_logical(WN_Tree_Type(WN_kid1(wn))))) 01917 { 01918 Append_Token_String(tokens, ".NOT."); 01919 Append_Token_Special(tokens, '('); 01920 set_WN2F_CONTEXT_no_parenthesis(context); 01921 WN2F_translate(tokens, WN_kid1(wn), context); 01922 Append_Token_Special(tokens, ')'); 01923 } 01924 else if (WN_opc_operator(WN_kid1(wn)) == OPR_INTCONST && 01925 WN_const_val(WN_kid1(wn)) == 0LL && 01926 (OPCODE_is_boolean(WN_opcode(WN_kid0(wn))) || 01927 TY_is_logical(WN_Tree_Type(WN_kid0(wn))))) 01928 { 01929 Append_Token_String(tokens, ".NOT."); 01930 Append_Token_Special(tokens, '('); 01931 set_WN2F_CONTEXT_no_parenthesis(context); 01932 WN2F_translate(tokens, WN_kid0(wn), context); 01933 Append_Token_Special(tokens, ')'); 01934 } 01935 else 01936 { 01937 WN2F_binaryop(tokens, wn, context); 01938 } 01939 01940 return EMPTY_WN2F_STATUS; 01941 } /* WN2F_eq */ 01942 01943 01944 WN2F_STATUS 01945 WN2F_ne(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01946 { 01947 /* Try to reduce "bool .NE. 0" to simply "bool", whenever possible. 01948 */ 01949 01950 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_NE, 01951 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_ne")); 01952 01953 if (WN_opc_operator(WN_kid0(wn)) == OPR_INTCONST && 01954 WN_const_val(WN_kid0(wn)) == 0LL && 01955 (OPCODE_is_boolean(WN_opcode(WN_kid1(wn))) || 01956 TY_is_logical(WN_Tree_Type(WN_kid1(wn))))) 01957 { 01958 WN2F_translate(tokens, WN_kid1(wn), context); 01959 } 01960 else if (WN_opc_operator(WN_kid1(wn)) == OPR_INTCONST && 01961 WN_const_val(WN_kid1(wn)) == 0LL && 01962 (OPCODE_is_boolean(WN_opcode(WN_kid0(wn))) || 01963 TY_is_logical(WN_Tree_Type(WN_kid0(wn))))) 01964 { 01965 WN2F_translate(tokens, WN_kid0(wn), context); 01966 } 01967 else 01968 { 01969 WN2F_binaryop(tokens, wn, context); 01970 } 01971 01972 return EMPTY_WN2F_STATUS; 01973 } /* WN2F_ne */ 01974 01975 01976 01977 WN2F_STATUS 01978 WN2F_parm(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01979 { 01980 /* TODO: handle opcode parms properly, i.e. take some advantage 01981 * of the information provided in this packaging of argument 01982 * expressions. For now, just skip these nodes. 01983 */ 01984 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_PARM, 01985 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_parm")); 01986 01987 if ( wn->u3.ty_fields.ty){ //ST_IDX point to key word FMZ August 2005 01988 ST2F_output_keyword(tokens,&St_Table[wn->u3.ty_fields.ty]); 01989 Append_Token_Special(tokens,'='); 01990 } 01991 01992 01993 if (WN_Parm_Copy_In(wn) && 01994 WN_kid0(wn) && 01995 WN_operator(WN_kid0(wn)) !=OPR_PAREN) 01996 Append_Token_Special(tokens,'('); 01997 01998 01999 if ( TY_is_logical(Ty_Table[WN_ty(wn)]) || 02000 WN2F_CONTEXT_is_logical_arg(context)) //fzhao Jan 02001 { 02002 set_WN2F_CONTEXT_has_logical_arg(context); 02003 WN2F_translate(tokens, WN_kid0(wn), context); 02004 reset_WN2F_CONTEXT_has_logical_arg(context); 02005 } 02006 else 02007 WN2F_translate(tokens, WN_kid0(wn), context); 02008 02009 if (WN_Parm_Copy_In(wn) && 02010 WN_kid0(wn) && 02011 WN_operator(WN_kid0(wn)) !=OPR_PAREN) 02012 Append_Token_Special(tokens,')'); 02013 02014 return EMPTY_WN2F_STATUS; 02015 02016 } /* WN2F_parm */ 02017 02018 02019 /*---------------- Memory allocation ops -------------------*/ 02020 02021 WN2F_STATUS 02022 WN2F_alloca(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 02023 { 02024 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_ALLOCA, 02025 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_alloca")); 02026 02027 02028 Append_Token_String(tokens,"OPR_ALLOCA"); 02029 Append_Token_Special(tokens,'('); 02030 WN2F_translate(tokens,WN_kid0(wn),context); 02031 Append_Token_Special(tokens,')'); 02032 02033 return EMPTY_WN2F_STATUS; 02034 } /* WN2F_alloca */ 02035 02036 02037 WN2F_STATUS 02038 WN2F_dealloca(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 02039 { 02040 INT16 n,i; 02041 02042 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_DEALLOCA, 02043 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_dealloca")); 02044 02045 n = WN_kid_count(wn); 02046 02047 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 02048 Append_Token_String(tokens,"CALL OPR_DEALLOCA"); 02049 Append_Token_Special(tokens,'('); 02050 02051 i = 0 ; 02052 while (i < n) 02053 { 02054 WN2F_translate(tokens,WN_kid(wn,i),context); 02055 if (++i < n) 02056 Append_Token_Special(tokens,','); 02057 } 02058 02059 Append_Token_Special(tokens,')'); 02060 return EMPTY_WN2F_STATUS; 02061 } /* WN2F_dealloca */ 02062