Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
targ_const.h
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 #ifndef targ_const_INCLUDED
00037 #define targ_const_INCLUDED
00038 
00039 /* ====================================================================
00040  * ====================================================================
00041  *
00042  *
00043  * Revision history:
00044  *  12-Jun-91 - Integrated from Josie
00045  *  24-Jun-91 - Moved to tp/com/targ_const.h from Josie target.h
00046  *
00047  * Description:
00048  *
00049  * The purpose of this file is to isolate target constant handling
00050  * in one file.  The philosophy is that all constants intended to be
00051  * referenced on the target be handled here, from creation (from
00052  * strings in source code or by operation on other target constants)
00053  * to final creation of assembly strings or object code words for
00054  * those which actually end up in the generated code.
00055  *
00056  * Where possible, we implement the philosophy by keeping constant
00057  * values in the host format (i.e. when doing so will not compromise
00058  * the range or accuracy w.r.t. the target), as this approach maximizes
00059  * the efficiency of constant manipulation on the host.  However, this
00060  * will not always be possible, e.g. where the host formats are not
00061  * rich enough to represent a value.  We can expect this situation,
00062  * for example, when we attempt to cross-compile for a 64-bit target
00063  * from a 32-bit target.
00064  *
00065  * All target constants are represented by struct TCON.  The struct 
00066  * records the type of the constant as well as its value.  The fields 
00067  * of struct TCON must not be accessed anywhere other than in
00068  * targ_const.c.  All constant operations are done in targ_const.c.
00069  * Any difference between representation of numbers in host and target
00070  * is handled here, including floating point representation and
00071  * byte-order differences.
00072  *
00073  * See also common/com/const.[hc] for operations on constants which
00074  * are not target representation dependent.  Because the constants
00075  * record their types within themselves, many routines of const.c have
00076  * been integrated here.
00077  *
00078  * NOTE:  The semantics of all operations are to be interpreted as
00079  * though the given operations were being performed on the target
00080  * machine on the target representation of the constants.  The only
00081  * exception to this rule is that this package is allowed to cope with
00082  * precision and range in excess of the target's; only when a value is
00083  * converted to the target representation need it be restricted to the
00084  * target's format.
00085  *
00086  * ====================================================================
00087  * ====================================================================
00088  */
00089 
00090 #include <string.h> /* for memset() */
00091 
00092 #include "config_host.h"
00093 /* Include the target machine type IDs: */
00094 #include "mtypes.h"
00095 
00096 #ifdef __cplusplus
00097 extern "C" {
00098 #endif
00099 
00100 /* Incomplete types to keep ANSI happy: */
00101 struct ty;
00102 
00103 /* Define a quad-precision floating point type appropriate to host: */
00104 #if HOST_SUPPORTS_QUAD_FLOAT
00105 typedef QUADFP QUAD_TYPE;
00106 #else
00107 typedef struct { INT32 qval[4]; } QUAD_TYPE;
00108 #endif
00109 
00110 /* ====================================================================
00111  *
00112  * The target constant (TCON) structure.
00113  *
00114  * This structure contains the type of the constant (as an MTYPE value
00115  * from mtypes.h) and the value.  The only direct access to a TCON
00116  * allowed outside the targ_const package is a type query.  It should
00117  * be assumed that the constant values are in an unknown format --
00118  * direct references to the value fields are therefore dangerous.
00119  *
00120  * NOTE:  The MTYPE field 'ty' only needs to be 8 bits, but if it were,
00121  * there will be 3 bytes of padding between 'ty' and the union 'vals',
00122  * below.  Since we search for constants in the Const_Table by casting
00123  * a TCON as a pointer to a string and then doing string-search
00124  * assuming strings of length sizeof(TCON), padding is being avoided.
00125  * (This is to avoid potential problems due to uninitialized data in
00126  * the padding bytes screwing up the string search.)  -- Warren
00127  *
00128  * WARNING:  With respect to the above comment, note that the end of
00129  * the structure contains padding as well for values shorter than the
00130  * maximum (e.g. float).  Furthermore, since the union contains a
00131  * double, the padding is probably actually 7 bytes.  -- Jim
00132  * (TODO:  Perhaps we should worry about this.)
00133  *
00134  * ====================================================================
00135  */
00136 
00137 
00138 struct TCON { 
00139     mTYPE_ID ty;                        /* The type of this TCON: MTYPE_xx */
00140     UINT32 flags;                       /* flag bits */
00141 #ifdef _LP64
00142     INT64  pad;                         /* align at 64 bytes */
00143 #endif /* _LP64 */
00144 
00145     union {
00146         struct {
00147 #if HOST_IS_LITTLE_ENDIAN
00148             mINT32 v0, v1, v2, v3;      /* Individual signed words */
00149 #else
00150             mINT32 v1, v0, v3, v2;      /* Individual signed words */
00151 #endif
00152         } ival;
00153         struct {
00154 #if HOST_IS_LITTLE_ENDIAN
00155             mUINT32 u0, u1, u2, u3;     /* Individual unsigned words */
00156 #else
00157             mUINT32 u1, u0, u3, u2;     /* Individual unsigned words */
00158 #endif
00159         } uval;
00160         mINT32 word0;                   /* for getting the first integer word */
00161         mINT64 i0;                      /* Signed integer */
00162         mUINT64 k0;                     /* Unsigned integer */
00163         float fval;                     /* 32-bit floating point */
00164         double dval;                    /* 64-bit floating point */
00165         QUAD_TYPE qval;                 /* 128-bit floating point */
00166         struct {                        /* string literal */
00167             mUINT32 cp;                 /* STR_IDX to string table */
00168             mUINT32 len;
00169         } sval;
00170     } vals;
00171     union {
00172         struct {
00173 #if HOST_IS_LITTLE_ENDIAN
00174             mINT32 v0, v1, v2, v3;      /* Individual signed words */
00175 #else
00176             mINT32 v1, v0, v3, v2;      /* Individual signed words */
00177 #endif
00178         } ival;
00179         float fival;
00180         double dival;
00181         QUAD_TYPE qival;
00182     } cmplxval;
00183 };
00184 
00185 #ifdef __cplusplus
00186 inline TYPE_ID
00187 TCON_ty (const TCON& tcon)              { return tcon.ty; }
00188 inline void
00189 Set_TCON_ty (TCON& tcon, TYPE_ID mtype) { tcon.ty = mtype; }    
00190 inline INT32
00191 TCON_ival (const TCON& tcon)            { return tcon.vals.word0; }    
00192 inline UINT32
00193 TCON_uval (const TCON& tcon)            { return (UINT32) tcon.vals.word0; }    
00194 inline INT64
00195 TCON_i0 (const TCON& tcon)              { return tcon.vals.i0; }    
00196 inline UINT64
00197 TCON_k0 (const TCON& tcon)              { return tcon.vals.k0; }
00198 inline float
00199 TCON_fval (const TCON& tcon)            { return tcon.vals.fval; }
00200 inline double
00201 TCON_dval (const TCON& tcon)            { return tcon.vals.dval; }    
00202 inline QUAD_TYPE
00203 TCON_qval (const TCON& tcon)            { return tcon.vals.qval; }
00204 inline mUINT32
00205 TCON_str_idx (const TCON& tcon)         { return tcon.vals.sval.cp; }
00206 inline mUINT32
00207 TCON_str_len (const TCON& tcon)         { return tcon.vals.sval.len; }
00208 #else /* __cplusplus */
00209 typedef struct TCON TCON;
00210 #endif /* __cplusplus */
00211 
00212 /* The only field that is to be accessed outside of "targ_const.c" is
00213  * the type field.  Macros to reference the other fields of the TCON
00214  * structure are in "targ_const.c".
00215  *
00216  * Moreover, modification of TCON_ty is prohibited except in
00217  * targ_const.c, though accessing it is fine.  TCON_ty is being defined
00218  * below in a way that can not be used to modify it.  In targ_const.c
00219  * it is undefined and redefined.
00220  *
00221  */
00222 
00223 #define TCON_ADD_NULL           0x1
00224 #define TCON_add_null(c)        ((c).flags & TCON_ADD_NULL)
00225 #define Set_TCON_add_null(c)    ((c).flags |= TCON_ADD_NULL)
00226 
00227 #define TCON_clear(c)   memset (&c, '\0', sizeof(TCON))
00228 
00229 const char *
00230 TCONFlags_To_Str (UINT64 flags);
00231 
00232 UINT64
00233 Str_To_TCONFlags (const char* str);
00234 
00235 
00236 
00237 /* ====================================================================
00238  *
00239  * Procedural interface to the target constant (TCON) structure.
00240  *
00241  * ====================================================================
00242  */
00243 
00244 
00245 #ifdef opcode_INCLUDED
00246 /* Perform a target op on target constants: */
00247 extern TCON Targ_WhirlOp ( OPCODE op, TCON left_opnd, TCON right_opnd,
00248                      BOOL *folded /* Was operator folded? */ );
00249 #endif
00250 
00251 extern TCON Targ_IntrinsicOp ( UINT32 intrinsic, TCON c[],
00252                      BOOL *folded /* Was operator folded? */ );
00253 
00254 /* Perform target exponentiation: */
00255 extern TCON Targ_Pow ( TCON mantissa, TCON exponent );
00256 
00257 /* Convert between target constants: */
00258 extern TCON Targ_Conv ( TYPE_ID newtype, TCON cvalue );
00259 
00260 /* Typecast between target constants (must be of same sizes): */
00261 extern TCON Targ_Cast ( TYPE_ID newtype, TCON cvalue );
00262 
00263 /* Convert (char *) representation of host to target constant: */
00264 extern TCON Targ_Atoc ( TYPE_ID ctype, char *ascii );
00265 
00266 /* Convert (char *) representation of floating-point hexadecimal constant
00267  * to target constant:
00268  */
00269 extern TCON Targ_Hexfptoc ( const TYPE_ID ty, const char * const str );
00270 
00271 /* Convert to host integer.  The TCON must be of a type reasonably
00272  * convertible to an integer type, e.g. float types are not allowed:
00273  */
00274 extern INT64 Targ_To_Host ( TCON cvalue );
00275 
00276 /* Convert to host signed integer.  The TCON must be of a type reasonably
00277  * convertible to an integer type, e.g. float types are not allowed:
00278  */
00279 extern INT64 Targ_To_Signed_Host ( TCON cvalue );
00280 
00281 /* Convert host integer value to a TCON of given type: */
00282 extern TCON Host_To_Targ ( TYPE_ID ctype, INT64 ivalue );
00283 
00284 /* Convert host floating point value to a TCON of given type: */
00285 extern TCON Host_To_Targ_Float ( TYPE_ID ctype, double fvalue );
00286 extern TCON Host_To_Targ_Float_4 ( TYPE_ID ctype, float fvalue );
00287 extern TCON Host_To_Targ_Quad  ( QUAD_TYPE fvalue );
00288 
00289 /* Convert a TCON to a double or a quad: */
00290 extern double Targ_To_Host_Float ( TCON fvalue );
00291 extern QUAD_TYPE Targ_To_Host_Quad ( TCON fvalue );
00292 
00293 /* Convert host complex value to a TCON of given type: */
00294 extern TCON Host_To_Targ_Complex_4 ( TYPE_ID ctype, float real, float imag );
00295 extern TCON Host_To_Targ_Complex ( TYPE_ID ctype, double real, double imag );
00296 extern TCON Host_To_Targ_Complex_Quad ( QUAD_TYPE real, QUAD_TYPE imag );
00297 
00298 /* Make complex TCON from two TCONs representing real and imaginary parts. */
00299 extern TCON Make_Complex ( TYPE_ID ctype, TCON real, TCON imag );
00300 
00301 /* Create Tcon for unitialized variable */
00302 extern TCON Host_To_Targ_UV(TYPE_ID ctype);
00303 
00304 /* Extract complex real/imag TCON to a TCON: */
00305 extern TCON Extract_Complex_Real( TCON complex);
00306 extern TCON Extract_Complex_Imag( TCON complex);
00307 
00308 /* Extract hi/lo of quad TCON to a TCON: */
00309 extern TCON Extract_Quad_Hi( TCON q);
00310 extern TCON Extract_Quad_Lo( TCON q);
00311 
00312 /*
00313  * For C and C++ String TCONs should include the trailing NULL.
00314  * For Fortran they may not include the NULL (in fact it may be
00315  * wrong to include it if have array of these strings). 
00316  * So the user must be careful about whether the "len" that is
00317  * passed includes the NULL.
00318  * Targ_String_Length always returns the "len" that was initially passed in.
00319  */
00320 extern TCON Host_To_Targ_String ( TYPE_ID ctype, char *cp, UINT32 len );
00321 extern char *Targ_String_Address ( TCON cvalue );
00322 extern mUINT32 Targ_String_Length ( TCON cvalue );
00323 
00324 /* Print constant according to given printf format.  The return string
00325  * is a static string which gets recycled after 8 calls, so it must
00326  * be used immediately or copied:
00327  */
00328 extern char *Targ_Print ( const char *fmt, TCON cvalue );
00329 
00330 /* Format the given string as a printable string, by replacing special
00331  * characters by the C source codes, e.g. "\n" for newline, "\003" for
00332  * '^C', etc.
00333  */
00334 extern BOOL Targ_Format_String (
00335   char  *s,     /* String to format, */
00336   INT32 slen,   /* ... of this length, */
00337   char  *buf,   /* ... into this buffer, */
00338   INT32 blen,   /* ... with at most this many characters, */
00339   INT32 line,   /* ... with lines at most this long (0 = no limit), */
00340   char *divider /* ... divided by this string. */
00341 );
00342 
00343 /* Emit a constant string of exactly length len to the given file.
00344  * If str[len-1] is not a null byte, make it one.  loc is an offset
00345  * from the relevant symbol where output begins, used only for
00346  * a comment.
00347  */
00348 extern void Targ_Emit_String ( FILE *fl, char *str, INT32 len, INTSC loc );
00349 
00350 /* Emit a target constant to the assembly file, with repeat count rc,
00351  * beginning at offset loc (for comment only).
00352  * The add_null field only applies to string constants.
00353  */
00354 extern void Targ_Emit_Const ( FILE *fl, TCON tvalue, BOOL add_null, INTSC rc, INTSC loc );
00355 
00356 #if defined(BACK_END) || defined(QIKKI_BE)
00357 /* Emit a target constant to the object file into the given section */
00358 extern void Em_Targ_Emit_Const (void *scn, TCON tvalue, BOOL add_null, INTSC rc);
00359 #endif
00360 
00361 /* Emit uninitialized storage space of the given length to the assembly
00362  * file, beginning at offset loc (for comment only):
00363  */
00364 extern void Targ_Emit_Space ( FILE *fl, INT len, INT loc );
00365 
00366 /* Emit an assembly language comment to the assembly file: */
00367 extern void Targ_Emit_Cmt ( FILE *fl, char *cmt );
00368 
00369 /* Emit the length of the given dimension of the given type to the
00370  * assembly file, or '1' if it is not a compile-time constant:
00371  */
00372 extern void Targ_Emit_Dim ( FILE *fl, struct ty *ty, INT dim );
00373 
00374 /* Put the given constant into the given buffer in target (i.e. object
00375  * file) format, independent of the host format, and return a pointer
00376  * to it:
00377  */
00378 extern char *Tcon_To_Str ( char *buf, TCON cval );
00379 
00380 /* Given a constant in target format in the given buffer, of the given
00381  * type, convert it to a TCON:
00382  */
00383 extern TCON Str_To_Tcon ( TYPE_ID ctype, char *buf );
00384 extern TCON Bit_Str_To_Tcon ( TYPE_ID ctype, char *buf );
00385 
00386 /* A target constant with value zero: */
00387 extern TCON Zero_I4_Tcon;
00388 extern TCON Zero_I8_Tcon;
00389 extern TCON Quad_Zero_Tcon;
00390 
00391 /* Is the given constant a zero? */
00392 extern BOOL Targ_Is_Zero ( TCON t );
00393 
00394 /* Determine whether a TCON represents an integral value, and if so
00395  * return its value in *iv:
00396  */
00397 extern BOOL Targ_Is_Integral ( TCON t, INT64 *iv );
00398 
00399 /* Determine whether a TCON represents a power of two: */
00400 extern BOOL Targ_Is_Power_Of_Two ( TCON t );
00401 
00402 /* Determin whether a TCON contains only one bit set to 1
00403  * If onebit is not NULL then return the bit number which is on
00404  */
00405 extern BOOL Targ_Contains_One_Bit_On ( TCON t, INT32 *onebit);
00406 
00407 /* Determine the most significant bit that is on, with 0 being the
00408  * least-sig bit, and type's_size - 1 being the most-sig bit.
00409  * If no bits are on, return FALSE.
00410  */
00411 extern BOOL Targ_Determine_High_Bit ( TCON t, INT32 *highbit );
00412 
00413 /* Hash a TCON into a 32-bit integer modulo another integer: */
00414 extern UINT32 Hash_TCON ( TCON * t, UINT32 modulus );
00415 
00416 extern INT32 Targ_fp_class(TCON fvalue);
00417 
00418 #ifdef Is_True_On
00419 /* Check the TCON for validity. */
00420 extern void Check_TCON (TCON *tc);
00421 #endif /* Is_True_On */
00422 
00423 #ifdef __cplusplus
00424 }
00425 #endif
00426 #endif /* targ_const_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines