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 #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 */