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-Jun-91 - Integrated from Josie 00042 * 30-Apr-93 - Added constant table manipulation from stab.c 00043 * 00044 * Description: 00045 * 00046 * Routines for manipulating constants. 00047 * 00048 * ==================================================================== 00049 * ==================================================================== 00050 */ 00051 #ifdef USE_PCH 00052 #include "common_com_pch.h" 00053 #endif /* USE_PCH */ 00054 #pragma hdrstop 00055 00056 00057 #include "defs.h" 00058 #include "symtab.h" 00059 #include "wn.h" 00060 #include "config_targ.h" 00061 00062 #undef max 00063 #include "HashTable.h" 00064 using namespace stlCompatibility; 00065 00066 #include <math.h> 00067 00068 namespace { 00069 // unnamed namespace for function objects used for removing duplicated 00070 // constant STs 00071 00072 bool eqTCON (const TCON_IDX t1_idx, const TCON_IDX t2_idx) { 00073 if (t1_idx == t2_idx) 00074 return TRUE; 00075 const TCON& t1 = Tcon_Table[t1_idx]; 00076 const TCON& t2 = Tcon_Table[t2_idx]; 00077 00078 if (TCON_ty (t1) != TCON_ty (t2)) 00079 return FALSE; 00080 if (t1.flags != t2.flags) 00081 return FALSE; 00082 00083 switch (TCON_ty (t1)) { 00084 00085 case MTYPE_I1: 00086 case MTYPE_I2: 00087 case MTYPE_I4: 00088 case MTYPE_I8: 00089 case MTYPE_U1: 00090 case MTYPE_U2: 00091 case MTYPE_U4: 00092 case MTYPE_U8: 00093 return TCON_i0 (t1) == TCON_i0 (t2); 00094 00095 case MTYPE_F4: 00096 // Need to use integer inequality because need to match exact bit pattern 00097 return TCON_ival (t1) == TCON_ival (t2); 00098 00099 case MTYPE_F8: 00100 // Need to use integer inequality because need to match exact bit pattern 00101 return TCON_k0 (t1) == TCON_k0 (t2); 00102 00103 case MTYPE_STR: 00104 return (TCON_str_idx (t1) == TCON_str_idx (t2) && 00105 TCON_str_len (t1) == TCON_str_len (t2)); 00106 00107 default: 00108 return memcmp (&t1, &t2, sizeof(TCON)) == 0; 00109 } 00110 } // eqTCON 00111 00112 00113 size_t hashTCON(const TCON_IDX tcon_idx) { 00114 const TCON& tcon = Tcon_Table[tcon_idx]; 00115 size_t val = TCON_ty (tcon); 00116 val ^= TCON_ival (tcon); 00117 return val; 00118 } 00119 00120 struct EqTCON { 00121 bool operator() (const TCON_IDX t1Idx, const TCON_IDX t2Idx) const{ 00122 return eqTCON(t1Idx, t2Idx); 00123 } // operator 00124 }; 00125 00126 struct HashTCON { 00127 size_t operator() (const TCON_IDX idx) const { 00128 return hashTCON(idx); 00129 } 00130 }; 00131 00132 } // unnamed namespace 00133 00134 00135 typedef HashTable<TCON_IDX, ST *, HashTCON, EqTCON> TCON_MERGE; 00136 00137 00138 extern void dump_st (ST *st); 00139 ST * 00140 New_Const_Sym (TCON_IDX tcon, TY_IDX ty) 00141 { 00142 static TCON_MERGE merge; 00143 00144 TCON_MERGE::ValueBoolPair fv = merge.find(tcon); 00145 const TCON& t1 = Tcon_Table[ tcon ]; 00146 ST * st; 00147 00148 if (fv.second == true) { 00149 st = (ST *)fv.first; 00150 Is_True (ST_class (st) == CLASS_CONST && 00151 ST_sclass (st) == SCLASS_FSTATIC && 00152 ST_export (st) == EXPORT_LOCAL && 00153 ST_is_initialized (st), ("Mismatched const ST")); 00154 } else { 00155 // create new constant 00156 st = New_ST (GLOBAL_SYMTAB); 00157 ST_Init (st, 0, CLASS_CONST, SCLASS_FSTATIC, EXPORT_LOCAL, ty); 00158 Set_ST_tcon (st, tcon); 00159 Set_ST_is_initialized (st); 00160 TCON_MERGE::ValueBoolPair tmp1 = 00161 merge.insert(TCON_MERGE::KeyValuePair(tcon, st)); 00162 assert(tmp1.second == true); 00163 } 00164 return st; 00165 } // New_Const_Sym 00166 00167 00168 ST * 00169 Gen_String_Sym (TCON *val, TY_IDX ty, BOOL) 00170 { 00171 return New_Const_Sym (Enter_tcon (*val), ty); 00172 } 00173 00174 00175 /* ==================================================================== 00176 * 00177 * Const_Val 00178 * 00179 * Return the value of a constant node. 00180 * 00181 * WARNING: The node passed must be know to be one of those with a 00182 * ND_dec field pointing to a CLASS_CONST symbol. 00183 * 00184 * ==================================================================== 00185 */ 00186 00187 TCON 00188 Const_Val ( WN *n ) 00189 { 00190 return WN_val (n); 00191 } 00192 00193 00194 /* ==================================================================== 00195 * 00196 * Make_Const 00197 * 00198 * Make a constant node of the given value. 00199 * 00200 * ==================================================================== 00201 */ 00202 00203 WN * 00204 Make_Const ( TCON c ) 00205 { 00206 WN *n; 00207 OPCODE opc; 00208 ST *csym; 00209 00210 00211 #ifdef Is_True_On 00212 Check_TCON(&c); 00213 #endif /* Is_True_On */ 00214 00215 // eraxxon: The CONST opcode supports more rtypes than are listed 00216 // here: it would seem that this function could be converted to 00217 // creating the opcode with OPCODE_make_op(...). For the moment, I 00218 // add integer support taking the conservative route. 00219 switch(TCON_ty(c)) { 00220 00221 case MTYPE_I4: 00222 opc = OPC_I4CONST; 00223 break; 00224 case MTYPE_I8: 00225 opc = OPC_I8CONST; 00226 break; 00227 00228 case MTYPE_U4: 00229 opc = OPC_U4CONST; 00230 break; 00231 case MTYPE_U8: 00232 opc = OPC_U8CONST; 00233 break; 00234 00235 case MTYPE_F4: 00236 opc = OPC_F4CONST; 00237 break; 00238 case MTYPE_F8: 00239 opc = OPC_F8CONST; 00240 break; 00241 case MTYPE_FQ: 00242 opc = OPC_FQCONST; 00243 break; 00244 case MTYPE_C4: 00245 opc = OPC_C4CONST; 00246 break; 00247 case MTYPE_C8: 00248 opc = OPC_C8CONST; 00249 break; 00250 case MTYPE_CQ: 00251 opc = OPC_CQCONST; 00252 break; 00253 default: 00254 Is_True ( FALSE, ( "Make_Const can not handle %s", 00255 Mtype_Name(TCON_ty(c)) ) ); 00256 return NULL; 00257 } 00258 00259 csym = New_Const_Sym (Enter_tcon (c), Be_Type_Tbl(TCON_ty(c))); 00260 n = WN_CreateConst(opc, csym); 00261 return (n); 00262 00263 } 00264 00265 #ifndef MONGOOSE_BE 00266 /* ==================================================================== 00267 * 00268 * Make_Zerocon 00269 * 00270 * Make a zero node of the given type. 00271 * 00272 * ==================================================================== 00273 */ 00274 00275 WN * 00276 Make_Zerocon ( TYPE_ID ty ) 00277 { 00278 return Make_Const ( Targ_Conv ( ty, Host_To_Targ ( MTYPE_I4, 0 ) )); 00279 } 00280 00281 00282 /* ==================================================================== 00283 * 00284 * Make_Comparison_Result_Const 00285 * 00286 * Make a TRUE or FALSE node of the default comparison result type. 00287 * 00288 * ==================================================================== 00289 */ 00290 00291 WN * 00292 Make_Comparison_Result_Const ( INT16 val ) 00293 { 00294 return Make_Const ( Host_To_Targ ( Comparison_Result_Mtype, val ) ); 00295 } 00296 00297 00298 /* ==================================================================== 00299 * 00300 * Make_Integer_Const 00301 * 00302 * Make an integer constant node of the given type and value. 00303 * 00304 * ==================================================================== 00305 */ 00306 00307 WN * 00308 Make_Integer_Const ( INT16 mtype, TARG_INT val ) 00309 { 00310 /* Actually, in WHIRL there are no integer constants of the symbol table type */ 00311 /* 00312 * return Make_Const ( Host_To_Targ ( mtype, val ) ); 00313 */ 00314 00315 /* NOTE: TARG_INT should be INT64 for this to work! */ 00316 return (WN_CreateIntconst(OPCODE_make_op(OPR_INTCONST,mtype,MTYPE_V), val)); 00317 00318 } 00319 00320 #endif /* MONGOOSE_BE */ 00321 00322 /****************************************************************************** 00323 This routine makes a WHIRL node representing the reduction 00324 identity for a given WHIRL op. For example, the reduction identity 00325 for + is 0, for * is 1. The only tricky part is getting the value 00326 and constant types correct for each mtype (particularly partial-word 00327 integers. 00328 *******************************************************************************/ 00329 00330 WN * Make_Reduction_Identity ( INT32 opr, TYPE_ID mtype ) 00331 { 00332 WN * r; 00333 TYPE_ID ntype; 00334 00335 if ((mtype == MTYPE_I1) || (mtype == MTYPE_I2)) 00336 ntype = MTYPE_I4; 00337 else if ((mtype == MTYPE_U1) || (mtype == MTYPE_U2)) 00338 ntype = MTYPE_U4; 00339 else 00340 ntype = mtype; 00341 00342 switch (opr) { 00343 00344 case OPR_ADD: 00345 case OPR_SUB: 00346 switch (mtype) { 00347 case MTYPE_I1: 00348 case MTYPE_I2: 00349 case MTYPE_I4: 00350 case MTYPE_I8: 00351 case MTYPE_U1: 00352 case MTYPE_U2: 00353 case MTYPE_U4: 00354 case MTYPE_U8: 00355 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00356 MTYPE_V), 0 ); 00357 break; 00358 00359 case MTYPE_F4: 00360 case MTYPE_F8: 00361 case MTYPE_FQ: 00362 case MTYPE_C4: 00363 case MTYPE_C8: 00364 case MTYPE_CQ: 00365 r = Make_Const ( Host_To_Targ_Float ( ntype, 0.0 ) ); 00366 break; 00367 00368 default: 00369 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00370 opr, mtype); 00371 } 00372 break; 00373 00374 case OPR_MPY: 00375 case OPR_DIV: 00376 switch (mtype) { 00377 case MTYPE_I1: 00378 case MTYPE_I2: 00379 case MTYPE_I4: 00380 case MTYPE_I8: 00381 case MTYPE_U1: 00382 case MTYPE_U2: 00383 case MTYPE_U4: 00384 case MTYPE_U8: 00385 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00386 MTYPE_V), 1 ); 00387 break; 00388 00389 case MTYPE_F4: 00390 case MTYPE_F8: 00391 case MTYPE_FQ: 00392 case MTYPE_C4: 00393 case MTYPE_C8: 00394 case MTYPE_CQ: 00395 r = Make_Const ( Host_To_Targ_Float ( ntype, 1.0 ) ); 00396 break; 00397 00398 default: 00399 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00400 opr, mtype); 00401 } 00402 break; 00403 00404 case OPR_MAX: 00405 switch (mtype) { 00406 case MTYPE_I1: 00407 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00408 MTYPE_V), -128LL ); 00409 break; 00410 00411 case MTYPE_I2: 00412 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00413 MTYPE_V), -32768LL ); 00414 break; 00415 00416 case MTYPE_I4: 00417 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00418 MTYPE_V), -2147483648LL); 00419 break; 00420 00421 case MTYPE_I8: 00422 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00423 MTYPE_V), 00424 0x8000000000000000LL ); 00425 break; 00426 00427 case MTYPE_U1: 00428 case MTYPE_U2: 00429 case MTYPE_U4: 00430 case MTYPE_U8: 00431 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00432 MTYPE_V), 0 ); 00433 break; 00434 00435 case MTYPE_F4: 00436 case MTYPE_F8: 00437 case MTYPE_FQ: 00438 r = Make_Const ( Host_To_Targ_Float ( ntype, -HUGE_VAL ) ); 00439 break; 00440 00441 default: 00442 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00443 opr, mtype); 00444 } 00445 break; 00446 00447 case OPR_MIN: 00448 switch (mtype) { 00449 case MTYPE_I1: 00450 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00451 MTYPE_V), 0x7f ); 00452 break; 00453 00454 case MTYPE_I2: 00455 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00456 MTYPE_V), 0x7fff ); 00457 break; 00458 00459 case MTYPE_I4: 00460 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00461 MTYPE_V), 0x7fffffff ); 00462 break; 00463 00464 case MTYPE_I8: 00465 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00466 MTYPE_V), 00467 0x7fffffffffffffffLL ); 00468 break; 00469 00470 case MTYPE_U1: 00471 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00472 MTYPE_V), 0xff ); 00473 break; 00474 00475 case MTYPE_U2: 00476 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00477 MTYPE_V), 0xffff ); 00478 break; 00479 00480 case MTYPE_U4: 00481 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00482 MTYPE_V), 0xffffffff ); 00483 break; 00484 00485 case MTYPE_U8: 00486 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00487 MTYPE_V), 00488 0xffffffffffffffffLL ); 00489 break; 00490 00491 case MTYPE_F4: 00492 case MTYPE_F8: 00493 case MTYPE_FQ: 00494 r = Make_Const ( Host_To_Targ_Float ( ntype, HUGE_VAL ) ); 00495 break; 00496 00497 default: 00498 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00499 opr, mtype); 00500 } 00501 break; 00502 00503 case OPR_BIOR: 00504 case OPR_BXOR: 00505 switch (mtype) { 00506 case MTYPE_I1: 00507 case MTYPE_I2: 00508 case MTYPE_I4: 00509 case MTYPE_I8: 00510 case MTYPE_U1: 00511 case MTYPE_U2: 00512 case MTYPE_U4: 00513 case MTYPE_U8: 00514 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00515 MTYPE_V), 0 ); 00516 break; 00517 00518 default: 00519 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00520 opr, mtype); 00521 } 00522 break; 00523 00524 case OPR_BAND: 00525 switch (mtype) { 00526 case MTYPE_I1: 00527 case MTYPE_U1: 00528 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00529 MTYPE_V), 0xff ); 00530 break; 00531 00532 case MTYPE_I2: 00533 case MTYPE_U2: 00534 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00535 MTYPE_V), 0xffff ); 00536 break; 00537 00538 case MTYPE_I4: 00539 case MTYPE_U4: 00540 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00541 MTYPE_V), 0xffffffff ); 00542 break; 00543 00544 case MTYPE_I8: 00545 case MTYPE_U8: 00546 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00547 MTYPE_V), 00548 0xffffffffffffffffLL ); 00549 break; 00550 00551 default: 00552 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00553 opr, mtype); 00554 } 00555 break; 00556 00557 case OPR_LIOR: 00558 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, MTYPE_V ), 00559 0 ); 00560 break; 00561 00562 case OPR_LAND: 00563 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, MTYPE_V ), 00564 1 ); 00565 break; 00566 00567 case OPR_EQ: /* Fortran .EQV. operator on type LOGICAL */ 00568 case OPR_NE: /* Fortran .NEQV. operator on type LOGICAL */ 00569 case OPR_CAND: /* C/C++ short-circuit "&&" on integral or floating- 00570 point type */ 00571 case OPR_CIOR: /* C/C++ short-circuit "||" on int/float */ 00572 switch (mtype) { 00573 case MTYPE_I1: 00574 case MTYPE_I2: 00575 case MTYPE_I4: 00576 case MTYPE_I8: 00577 case MTYPE_U1: 00578 case MTYPE_U2: 00579 case MTYPE_U4: 00580 case MTYPE_U8: 00581 r = WN_CreateIntconst ( OPCODE_make_op ( OPR_INTCONST, ntype, 00582 MTYPE_V), 00583 (opr == OPR_EQ || opr == OPR_CAND) ? 1 00584 : 0 ); 00585 break; 00586 00587 case MTYPE_F4: 00588 case MTYPE_F8: 00589 case MTYPE_FQ: 00590 Is_True(opr == OPR_CAND || opr == OPR_CIOR, 00591 ("bad opr %d", (INT) opr)); 00592 r = Make_Const(Host_To_Targ_Float(ntype, 00593 (opr == OPR_CAND) ? 1.0 : 0.0)); 00594 break; 00595 00596 default: 00597 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", 00598 opr, mtype); 00599 } 00600 break; 00601 00602 default: 00603 Fail_FmtAssertion ( "No reduction identity for operator %d, type %d", opr, 00604 mtype); 00605 break; 00606 } 00607 return (r); 00608 }