Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
const.cxx
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines