Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
util.c
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 static char *source_file = __FILE__;
00038 #include <unistd.h>
00039 #include <errno.h>
00040 #include "defs.h"
00041 #include "erglob.h"
00042 #include "tracing.h"
00043 #include "util.h"
00044 
00045 #include <sys/wait.h>
00046 /*extern pid_t wait(INT *statptr); */   /* Currently not defined with
00047                                          *  prototype in sys/wait.h
00048                                          */
00049 
00050 #ifndef MONGOOSE_BE
00051 /* ====================================================================
00052  *
00053  * Execute
00054  *
00055  * Execute an external command via fork/execvp.
00056  * Returns 0 on success, an error code on failure.
00057  * An error code < 0400 is a Unix error code from errno.h.
00058  * An error code > 0400 is 0400 plus the signal which killed child.
00059  *
00060  * ====================================================================
00061  */
00062 
00063 INT Execute (
00064   char *cmd,            /* The command to execute */
00065   char **argv,          /* Argument list */
00066   char *stdoutfile,     /* stdout for new process to use or NULL */
00067   BOOL echo             /* Echo the command line? */
00068 )
00069 {
00070   INT child, t, status;
00071 
00072   /* Echo the command line if requested: */
00073   if ( echo ) {
00074     char **arg = argv+1;
00075 
00076     fprintf ( stderr, " %s", cmd);
00077     while ( *arg ) fprintf ( stderr, " %s", *arg++);
00078     if ( stdoutfile != NULL ) fprintf ( stderr, " >%s", stdoutfile );
00079     fprintf ( stderr, "\n" );
00080   }
00081 
00082   /* Fork and check for failure: */
00083   child = fork();
00084   if (child == -1) return (EAGAIN);
00085 
00086   /* Execute the requested command in the child: */
00087   if (child == 0) {
00088     /* If a new stdout is given, open it: */
00089     if (stdoutfile != NULL) {
00090       if( freopen(stdoutfile, "w", stdout) == NULL) _exit(errno);
00091     }
00092 
00093     /* Execute the command: */
00094     execvp( cmd, argv );
00095 
00096     /* If the exec failed, return the system error code: */
00097     _exit(errno);
00098   }
00099 
00100   /* Wait for the child in the parent and then check for errors: */
00101   while (child != wait(&status)) {};
00102   if ( (t=(status&0377)) != 0 ) return ( 0400 + t );
00103   return ((status>>8) & 0377);
00104 
00105 }
00106 
00107 /* ====================================================================
00108  *
00109  * Get_Environment_Value
00110  *
00111  * Get the value of an environment variable.
00112  *
00113  * ====================================================================
00114  */
00115 
00116 char *
00117 Get_Environment_Value (
00118   char *name,   /* The name of the environment variable */
00119   char **envp,  /* Array of environment variables + NULL */
00120   char *def     /* Default to return if not found */
00121 )
00122 {
00123   INT len = strlen(name);
00124   char **env = envp;
00125 
00126   /* Search for a match: */
00127   while ( *env ) {
00128     if ( strncmp (name, *env, len) == 0 && *(len + *env) == '=' )
00129         return (*env) + len + 1;
00130     env++;
00131   }
00132 
00133   /* Not found: */
00134   return def;
00135 }
00136 #endif /* MONGOOSE_BE */
00137 
00138 /* ====================================================================
00139  *
00140  * Check_Range
00141  *
00142  * Check an integer value against bounds.  Return the value if in
00143  * range, and a default if out of range.
00144  *
00145  * ====================================================================
00146  */
00147 
00148 INT
00149 Check_Range (
00150   INT val,      /* Check this value */
00151   INT lbound,   /* ... against this lower bound */
00152   INT ubound,   /* ... and this upper bound, */
00153   INT def       /* ... with this default. */
00154 )
00155 {
00156   if ( val >= lbound && val <= ubound ) return val;
00157   return def;
00158 }
00159 
00160 #ifndef MONGOOSE_BE
00161 /* ====================================================================
00162  *
00163  * Indent
00164  *
00165  * Print tabs and spaces to indent given number of characters.
00166  *
00167  * ====================================================================
00168  */
00169 
00170 void
00171 Indent (
00172   FILE *f,
00173   INT16 indent
00174 )
00175 {
00176   while ( indent >= 8 ) {
00177     fprintf ( f, "\t" );
00178     indent -= 8;
00179   }
00180   while ( indent-- > 0 ) fprintf ( f, " " );
00181 }
00182 #endif /* MONGOOSE_BE */
00183 
00184 /* ====================================================================
00185  *
00186  *  Mod
00187  *
00188  *  Mathematically correct integer modulus function.  Unlike C's
00189  *  builtin remainder function, this correctly handles the case where
00190  *  one of the two arguments is negative.
00191  *
00192  *  Notice the use if INT as the argument and return type.  Should
00193  *  this have been INT64?
00194  *
00195  * ====================================================================
00196  */
00197 
00198 INT Mod(
00199   INT i,
00200   INT j
00201 )
00202 {
00203   INT rem;
00204 
00205   if ( j == 0 )
00206     return i;
00207 
00208   rem = i % j;
00209 
00210   if ( rem == 0 )
00211     return 0;
00212 
00213   if ( (i < 0) != (j < 0) )
00214     return j + rem;
00215   else
00216     return rem;
00217 }
00218 
00219 /* ====================================================================
00220  *
00221  *  Pop_Count
00222  *
00223  *  Return the count of set bits in 'x'.  This could be a lot faster,
00224  *  but does it matter?
00225  *
00226  *  TODO: Better algorithm.
00227  *
00228  * ====================================================================
00229  */
00230 
00231 /* Count of bits in all the one byte numbers.
00232  */
00233 const mUINT8 UINT8_pop_count[256] = {
00234   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 
00235   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
00236   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
00237   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
00238   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
00239   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
00240   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
00241   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
00242   1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 
00243   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
00244   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
00245   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
00246   2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 
00247   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
00248   3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 
00249   4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8  
00250 };
00251 
00252 TARG_INT
00253 TARG_INT_Pop_Count(
00254   TARG_INT x
00255 )
00256 {
00257   INT i, result=0;
00258 
00259   /* Find the least significant byte in x that's not zero and look it
00260    * up in the above table.
00261    */
00262   for (i = sizeof(x) - 1; i >= 0; --i ) {
00263     unsigned char y = ((TARG_UINT) x) >> (((UINT) i) * 8);
00264 
00265     result += UINT8_pop_count[y];
00266   }
00267   return result;
00268 }
00269 
00270 /* ====================================================================
00271  *
00272  *  TARG_INT Most_Sig_One
00273  *
00274  *  Return the index of the most signicant bit in x, or -1 if x is 0.
00275  *  Bits are labeled [63 .. 0]
00276  *
00277  * ====================================================================
00278  */
00279 
00280 /* Mapping from unsigned 8 bit integers to the index of their most
00281  * significant one.  Notice -1 for out of range 0.
00282  */
00283 static const mUINT8 UINT8_most_sig_one [256] = {
00284   (mUINT8)-1, 
00285       0,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  
00286   4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  
00287   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  
00288   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  
00289   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
00290   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
00291   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
00292   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  
00293   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00294   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00295   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00296   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00297   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00298   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00299   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00300   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  
00301 };
00302 
00303 
00304 TARG_INT
00305 TARG_INT_Most_Sig_One(
00306   TARG_INT x
00307 )
00308 {
00309   INT i;
00310 
00311   /* Find the least significant byte in x that's not zero and look it
00312    * up in the above table.
00313    */
00314   for (i = sizeof(x) - 1; i >= 0; --i ) {
00315     unsigned char y = ((TARG_UINT) x) >> (((UINT) i) * 8);
00316 
00317     if (y != 0 )
00318       return i*8 + UINT8_most_sig_one[y];
00319   }
00320 
00321   return (TARG_INT) -1;
00322 }
00323 
00324 
00325 /* ====================================================================
00326  *
00327  *  TARG_INT_Least_Sig_One
00328  *
00329  *  Return the index of the least signicant bit in x, or -1 if x is 0.
00330  *  Bits are labeled [63 .. 0]
00331  *
00332  * ====================================================================
00333  */
00334 
00335 /* Mapping from 8 bit unsigned integers to the index of the first one
00336  * bit:
00337  */
00338 const mUINT8 UINT8_least_sig_one [256] = {
00339   (mUINT8)-1, 
00340       0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00341   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00342   5,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00343   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00344   6,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00345   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00346   5,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00347   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00348   7,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00349   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00350   5,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00351   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00352   6,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00353   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00354   5,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00355   4,  0,  1,  0,  2,  0,  1,  0,  3,  0,  1,  0,  2,  0,  1,  0,  
00356 };
00357 
00358 
00359 TARG_INT
00360 TARG_INT_Least_Sig_One(
00361   TARG_INT x
00362 )
00363 {
00364   INT  i;
00365 
00366   /* Find the least significant byte in x that's not zero and look it
00367    * up in the above table.
00368    */
00369   for (i = 0; i < sizeof(x); ++i) {
00370     unsigned char y = ((TARG_UINT) x) >> (((UINT) i) * 8);
00371 
00372     if (y != 0)
00373       return i*8 + UINT8_least_sig_one[y];
00374   }
00375 
00376   return (TARG_INT) -1;
00377 }
00378 
00379 
00380 /* ====================================================================
00381  *
00382  * INT32 nearest_power_of two(INT32 n)
00383  *
00384  * find the next nearest power of 2
00385  * ex.
00386  *      nearest_power_of two(7) = 8
00387  *      nearest_power_of two(4) = 4
00388  *
00389  * ==================================================================== */
00390 #define IS_POW2(n)              (((n) & ((n)-1))==0)
00391 
00392 INT32 nearest_power_of_two(INT32 n)
00393 {
00394   INT32 i;
00395 
00396   Is_True((n>0), ("nearest_power_of two() not defined for <=0"));
00397 
00398   if (IS_POW2(n))
00399   {
00400     return n;
00401   }
00402   for(i=0; (1<<i)<n; i++)
00403         ;
00404   return 1<<i;
00405 }
00406 
00407 
00408 
00409 /* ====================================================================
00410  *
00411  * BOOL Immediate_Has_All_Ones(INT64 imm, INT32 ub, INT32 lb)
00412  *
00413  * return TRUE if imm has all ones from lb to ub
00414  *
00415  * ==================================================================== */
00416 BOOL Immediate_Has_All_Ones(INT64 imm, INT32 ub, INT32 lb)
00417 {
00418   TARG_UINT     field= (TARG_UINT)~0;
00419   INT32         fieldsize= ub - lb + 1;
00420 
00421   Is_True((fieldsize>0), ("nonsensical ub,lb for immediate"));
00422 
00423  /* create mask of ones
00424   * cannonicalize immediate to start at bits zero
00425   */
00426   field >>=     (sizeof(TARG_INT)*8) - fieldsize;
00427   imm   =       (imm >> lb) & field;
00428   
00429   if (imm ^ field)
00430     return FALSE;
00431 
00432   return TRUE; 
00433 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines