|
|
1.1 root 1: /* Utility routines for data type conversion for GNU C. 1.1.1.4 ! root 2: Copyright (C) 1987, 88, 91, 92, 94, 1995 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU C. 5: 6: GNU CC is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU CC is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU CC; see the file COPYING. If not, write to 1.1.1.4 ! root 18: the Free Software Foundation, 59 Temple Place - Suite 330, ! 19: Boston, MA 02111-1307, USA. */ 1.1 root 20: 21: 22: /* These routines are somewhat language-independent utility function 23: intended to be called by the language-specific convert () functions. */ 24: 25: #include "config.h" 26: #include "tree.h" 27: #include "flags.h" 28: #include "convert.h" 29: 1.1.1.4 ! root 30: /* Convert EXPR to some pointer or reference type TYPE. 1.1 root 31: 1.1.1.4 ! root 32: EXPR must be pointer, reference, integer, enumeral, or literal zero; 1.1 root 33: in other cases error is called. */ 34: 35: tree 36: convert_to_pointer (type, expr) 37: tree type, expr; 38: { 39: register tree intype = TREE_TYPE (expr); 40: register enum tree_code form = TREE_CODE (intype); 41: 42: if (integer_zerop (expr)) 43: { 44: expr = build_int_2 (0, 0); 45: TREE_TYPE (expr) = type; 46: return expr; 47: } 48: 1.1.1.4 ! root 49: if (form == POINTER_TYPE || form == REFERENCE_TYPE) 1.1 root 50: return build1 (NOP_EXPR, type, expr); 51: 52: 53: if (form == INTEGER_TYPE || form == ENUMERAL_TYPE) 54: { 55: if (type_precision (intype) == POINTER_SIZE) 56: return build1 (CONVERT_EXPR, type, expr); 57: expr = convert (type_for_size (POINTER_SIZE, 0), expr); 58: /* Modes may be different but sizes should be the same. */ 59: if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) 60: != GET_MODE_SIZE (TYPE_MODE (type))) 61: /* There is supposed to be some integral type 62: that is the same width as a pointer. */ 63: abort (); 64: return convert_to_pointer (type, expr); 65: } 66: 67: error ("cannot convert to a pointer type"); 68: 1.1.1.4 ! root 69: expr = build_int_2 (0, 0); ! 70: TREE_TYPE (expr) = type; ! 71: return expr; 1.1 root 72: } 73: 74: /* Convert EXPR to some floating-point type TYPE. 75: 76: EXPR must be float, integer, or enumeral; 77: in other cases error is called. */ 78: 79: tree 80: convert_to_real (type, expr) 81: tree type, expr; 82: { 83: register enum tree_code form = TREE_CODE (TREE_TYPE (expr)); 84: 85: if (form == REAL_TYPE) 86: return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR, 87: type, expr); 88: 1.1.1.3 root 89: if (INTEGRAL_TYPE_P (TREE_TYPE (expr))) 1.1 root 90: return build1 (FLOAT_EXPR, type, expr); 91: 92: if (form == COMPLEX_TYPE) 93: return convert (type, fold (build1 (REALPART_EXPR, 94: TREE_TYPE (TREE_TYPE (expr)), expr))); 95: 1.1.1.4 ! root 96: if (form == POINTER_TYPE || form == REFERENCE_TYPE) 1.1 root 97: error ("pointer value used where a floating point value was expected"); 98: else 99: error ("aggregate value used where a float was expected"); 100: 101: { 102: register tree tem = make_node (REAL_CST); 103: TREE_TYPE (tem) = type; 104: TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0", TYPE_MODE (type)); 105: return tem; 106: } 107: } 108: 109: /* Convert EXPR to some integer (or enum) type TYPE. 110: 111: EXPR must be pointer, integer, discrete (enum, char, or bool), or float; 112: in other cases error is called. 113: 114: The result of this is always supposed to be a newly created tree node 115: not in use in any existing structure. */ 116: 117: tree 118: convert_to_integer (type, expr) 119: tree type, expr; 120: { 121: register tree intype = TREE_TYPE (expr); 122: register enum tree_code form = TREE_CODE (intype); 123: 1.1.1.4 ! root 124: if (form == POINTER_TYPE || form == REFERENCE_TYPE) 1.1 root 125: { 126: if (integer_zerop (expr)) 127: expr = integer_zero_node; 128: else 129: expr = fold (build1 (CONVERT_EXPR, 130: type_for_size (POINTER_SIZE, 0), expr)); 131: intype = TREE_TYPE (expr); 132: form = TREE_CODE (intype); 133: if (intype == type) 134: return expr; 135: } 136: 137: if (form == INTEGER_TYPE || form == ENUMERAL_TYPE 138: || form == BOOLEAN_TYPE || form == CHAR_TYPE) 139: { 140: register unsigned outprec = TYPE_PRECISION (type); 141: register unsigned inprec = TYPE_PRECISION (intype); 142: register enum tree_code ex_form = TREE_CODE (expr); 143: 144: /* If we are widening the type, put in an explicit conversion. 145: Similarly if we are not changing the width. However, if this is 146: a logical operation that just returns 0 or 1, we can change the 1.1.1.3 root 147: type of the expression. For logical operations, we must 148: also change the types of the operands to maintain type 149: correctness. */ 1.1 root 150: 1.1.1.3 root 151: if (TREE_CODE_CLASS (ex_form) == '<') 152: { 153: TREE_TYPE (expr) = type; 154: return expr; 155: } 156: else if (ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR 157: || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR 158: || ex_form == TRUTH_XOR_EXPR) 159: { 160: TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0)); 161: TREE_OPERAND (expr, 1) = convert (type, TREE_OPERAND (expr, 1)); 162: TREE_TYPE (expr) = type; 163: return expr; 164: } 165: else if (ex_form == TRUTH_NOT_EXPR) 1.1 root 166: { 1.1.1.3 root 167: TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0)); 1.1 root 168: TREE_TYPE (expr) = type; 169: return expr; 170: } 171: else if (outprec >= inprec) 172: return build1 (NOP_EXPR, type, expr); 173: 1.1.1.4 ! root 174: /* If TYPE is an enumeral type or a type with a precision less ! 175: than the number of bits in its mode, do the conversion to the ! 176: type corresponding to its mode, then do a nop conversion ! 177: to TYPE. */ ! 178: else if (TREE_CODE (type) == ENUMERAL_TYPE ! 179: || outprec != GET_MODE_BITSIZE (TYPE_MODE (type))) ! 180: return build1 (NOP_EXPR, type, ! 181: convert (type_for_mode (TYPE_MODE (type), ! 182: TREE_UNSIGNED (type)), ! 183: expr)); ! 184: 1.1.1.3 root 185: /* Here detect when we can distribute the truncation down past some 186: arithmetic. For example, if adding two longs and converting to an 187: int, we can equally well convert both to ints and then add. 188: For the operations handled here, such truncation distribution 189: is always safe. 190: It is desirable in these cases: 191: 1) when truncating down to full-word from a larger size 192: 2) when truncating takes no work. 193: 3) when at least one operand of the arithmetic has been extended 194: (as by C's default conversions). In this case we need two conversions 195: if we do the arithmetic as already requested, so we might as well 196: truncate both and then combine. Perhaps that way we need only one. 197: 198: Note that in general we cannot do the arithmetic in a type 199: shorter than the desired result of conversion, even if the operands 200: are both extended from a shorter type, because they might overflow 201: if combined in that type. The exceptions to this--the times when 202: two narrow values can be combined in their narrow type even to 203: make a wider result--are handled by "shorten" in build_binary_op. */ 1.1 root 204: 205: switch (ex_form) 206: { 207: case RSHIFT_EXPR: 208: /* We can pass truncation down through right shifting 209: when the shift count is a nonpositive constant. */ 210: if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST 1.1.1.3 root 211: && tree_int_cst_lt (TREE_OPERAND (expr, 1), 212: convert (TREE_TYPE (TREE_OPERAND (expr, 1)), 213: integer_one_node))) 1.1 root 214: goto trunc1; 215: break; 216: 217: case LSHIFT_EXPR: 218: /* We can pass truncation down through left shifting 219: when the shift count is a nonnegative constant. */ 220: if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST 1.1.1.3 root 221: && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0 1.1 root 222: && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) 223: { 224: /* If shift count is less than the width of the truncated type, 225: really shift. */ 226: if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type))) 227: /* In this case, shifting is like multiplication. */ 228: goto trunc1; 229: else 230: { 231: /* If it is >= that width, result is zero. 232: Handling this with trunc1 would give the wrong result: 233: (int) ((long long) a << 32) is well defined (as 0) 234: but (int) a << 32 is undefined and would get a 235: warning. */ 236: 237: tree t = convert_to_integer (type, integer_zero_node); 238: 239: /* If the original expression had side-effects, we must 240: preserve it. */ 241: if (TREE_SIDE_EFFECTS (expr)) 242: return build (COMPOUND_EXPR, type, expr, t); 243: else 244: return t; 245: } 246: } 247: break; 248: 249: case MAX_EXPR: 250: case MIN_EXPR: 251: case MULT_EXPR: 252: { 253: tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); 254: tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); 255: 256: /* Don't distribute unless the output precision is at least as big 257: as the actual inputs. Otherwise, the comparison of the 258: truncated values will be wrong. */ 259: if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0)) 260: && outprec >= TYPE_PRECISION (TREE_TYPE (arg1)) 261: /* If signedness of arg0 and arg1 don't match, 262: we can't necessarily find a type to compare them in. */ 263: && (TREE_UNSIGNED (TREE_TYPE (arg0)) 264: == TREE_UNSIGNED (TREE_TYPE (arg1)))) 265: goto trunc1; 266: break; 267: } 268: 269: case PLUS_EXPR: 270: case MINUS_EXPR: 271: case BIT_AND_EXPR: 272: case BIT_IOR_EXPR: 273: case BIT_XOR_EXPR: 274: case BIT_ANDTC_EXPR: 275: trunc1: 276: { 277: tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); 278: tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); 279: 280: if (outprec >= BITS_PER_WORD 281: || TRULY_NOOP_TRUNCATION (outprec, inprec) 282: || inprec > TYPE_PRECISION (TREE_TYPE (arg0)) 283: || inprec > TYPE_PRECISION (TREE_TYPE (arg1))) 284: { 285: /* Do the arithmetic in type TYPEX, 286: then convert result to TYPE. */ 287: register tree typex = type; 288: 289: /* Can't do arithmetic in enumeral types 290: so use an integer type that will hold the values. */ 291: if (TREE_CODE (typex) == ENUMERAL_TYPE) 292: typex = type_for_size (TYPE_PRECISION (typex), 293: TREE_UNSIGNED (typex)); 294: 295: /* But now perhaps TYPEX is as wide as INPREC. 296: In that case, do nothing special here. 297: (Otherwise would recurse infinitely in convert. */ 298: if (TYPE_PRECISION (typex) != inprec) 299: { 300: /* Don't do unsigned arithmetic where signed was wanted, 301: or vice versa. 302: Exception: if either of the original operands were 303: unsigned then can safely do the work as unsigned. 304: And we may need to do it as unsigned 305: if we truncate to the original size. */ 306: typex = ((TREE_UNSIGNED (TREE_TYPE (expr)) 307: || TREE_UNSIGNED (TREE_TYPE (arg0)) 308: || TREE_UNSIGNED (TREE_TYPE (arg1))) 309: ? unsigned_type (typex) : signed_type (typex)); 310: return convert (type, 311: fold (build (ex_form, typex, 312: convert (typex, arg0), 313: convert (typex, arg1), 314: 0))); 315: } 316: } 317: } 318: break; 319: 320: case NEGATE_EXPR: 321: case BIT_NOT_EXPR: 1.1.1.2 root 322: /* This is not correct for ABS_EXPR, 323: since we must test the sign before truncation. */ 1.1 root 324: { 325: register tree typex = type; 326: 327: /* Can't do arithmetic in enumeral types 328: so use an integer type that will hold the values. */ 329: if (TREE_CODE (typex) == ENUMERAL_TYPE) 330: typex = type_for_size (TYPE_PRECISION (typex), 331: TREE_UNSIGNED (typex)); 332: 333: /* But now perhaps TYPEX is as wide as INPREC. 334: In that case, do nothing special here. 335: (Otherwise would recurse infinitely in convert. */ 336: if (TYPE_PRECISION (typex) != inprec) 337: { 338: /* Don't do unsigned arithmetic where signed was wanted, 339: or vice versa. */ 340: typex = (TREE_UNSIGNED (TREE_TYPE (expr)) 341: ? unsigned_type (typex) : signed_type (typex)); 342: return convert (type, 343: fold (build1 (ex_form, typex, 344: convert (typex, 345: TREE_OPERAND (expr, 0))))); 346: } 347: } 348: 349: case NOP_EXPR: 350: /* If truncating after truncating, might as well do all at once. 351: If truncating after extending, we may get rid of wasted work. */ 352: return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type)); 353: 354: case COND_EXPR: 355: /* Can treat the two alternative values like the operands 356: of an arithmetic expression. */ 357: { 358: tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); 359: tree arg2 = get_unwidened (TREE_OPERAND (expr, 2), type); 360: 361: if (outprec >= BITS_PER_WORD 362: || TRULY_NOOP_TRUNCATION (outprec, inprec) 363: || inprec > TYPE_PRECISION (TREE_TYPE (arg1)) 364: || inprec > TYPE_PRECISION (TREE_TYPE (arg2))) 365: { 366: /* Do the arithmetic in type TYPEX, 367: then convert result to TYPE. */ 368: register tree typex = type; 369: 370: /* Can't do arithmetic in enumeral types 371: so use an integer type that will hold the values. */ 372: if (TREE_CODE (typex) == ENUMERAL_TYPE) 373: typex = type_for_size (TYPE_PRECISION (typex), 374: TREE_UNSIGNED (typex)); 375: 376: /* But now perhaps TYPEX is as wide as INPREC. 377: In that case, do nothing special here. 378: (Otherwise would recurse infinitely in convert. */ 379: if (TYPE_PRECISION (typex) != inprec) 380: { 381: /* Don't do unsigned arithmetic where signed was wanted, 382: or vice versa. */ 383: typex = (TREE_UNSIGNED (TREE_TYPE (expr)) 384: ? unsigned_type (typex) : signed_type (typex)); 385: return convert (type, 386: fold (build (COND_EXPR, typex, 387: TREE_OPERAND (expr, 0), 388: convert (typex, arg1), 389: convert (typex, arg2)))); 390: } 391: else 392: /* It is sometimes worthwhile 393: to push the narrowing down through the conditional. */ 394: return fold (build (COND_EXPR, type, 395: TREE_OPERAND (expr, 0), 396: convert (type, TREE_OPERAND (expr, 1)), 397: convert (type, TREE_OPERAND (expr, 2)))); 398: } 399: } 400: 401: } 402: 403: return build1 (NOP_EXPR, type, expr); 404: } 405: 406: if (form == REAL_TYPE) 407: return build1 (FIX_TRUNC_EXPR, type, expr); 408: 409: if (form == COMPLEX_TYPE) 410: return convert (type, fold (build1 (REALPART_EXPR, 411: TREE_TYPE (TREE_TYPE (expr)), expr))); 412: 413: error ("aggregate value used where an integer was expected"); 414: 415: { 416: register tree tem = build_int_2 (0, 0); 417: TREE_TYPE (tem) = type; 418: return tem; 419: } 420: } 421: 422: /* Convert EXPR to the complex type TYPE in the usual ways. */ 423: 424: tree 425: convert_to_complex (type, expr) 426: tree type, expr; 427: { 428: register enum tree_code form = TREE_CODE (TREE_TYPE (expr)); 429: tree subtype = TREE_TYPE (type); 430: 431: if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE) 432: { 433: expr = convert (subtype, expr); 434: return build (COMPLEX_EXPR, type, expr, 435: convert (subtype, integer_zero_node)); 436: } 437: 438: if (form == COMPLEX_TYPE) 439: { 440: tree elt_type = TREE_TYPE (TREE_TYPE (expr)); 441: if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype)) 442: return expr; 443: else if (TREE_CODE (expr) == COMPLEX_EXPR) 444: return fold (build (COMPLEX_EXPR, 445: type, 446: convert (subtype, TREE_OPERAND (expr, 0)), 447: convert (subtype, TREE_OPERAND (expr, 1)))); 448: else 449: { 450: expr = save_expr (expr); 451: return fold (build (COMPLEX_EXPR, 452: type, 453: convert (subtype, 454: fold (build1 (REALPART_EXPR, 455: TREE_TYPE (TREE_TYPE (expr)), 456: expr))), 457: convert (subtype, 458: fold (build1 (IMAGPART_EXPR, 459: TREE_TYPE (TREE_TYPE (expr)), 460: expr))))); 461: } 462: } 463: 1.1.1.4 ! root 464: if (form == POINTER_TYPE || form == REFERENCE_TYPE) 1.1 root 465: error ("pointer value used where a complex was expected"); 466: else 467: error ("aggregate value used where a complex was expected"); 468: 469: return build (COMPLEX_EXPR, type, 470: convert (subtype, integer_zero_node), 471: convert (subtype, integer_zero_node)); 472: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.