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