1132718Skan/* Utility routines for data type conversion for GCC. 2132718Skan Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 3169689Skan 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 2118334Speter 2218334Speter 2318334Speter/* These routines are somewhat language-independent utility function 2450397Sobrien intended to be called by the language-specific convert () functions. */ 2518334Speter 2618334Speter#include "config.h" 2790075Sobrien#include "system.h" 28132718Skan#include "coretypes.h" 29132718Skan#include "tm.h" 3018334Speter#include "tree.h" 3118334Speter#include "flags.h" 3218334Speter#include "convert.h" 3350397Sobrien#include "toplev.h" 34117395Skan#include "langhooks.h" 35132718Skan#include "real.h" 36169689Skan 3718334Speter/* Convert EXPR to some pointer or reference type TYPE. 3818334Speter EXPR must be pointer, reference, integer, enumeral, or literal zero; 3950397Sobrien in other cases error is called. */ 4018334Speter 4118334Spetertree 42132718Skanconvert_to_pointer (tree type, tree expr) 4318334Speter{ 44169689Skan if (TREE_TYPE (expr) == type) 45169689Skan return expr; 46169689Skan 4718334Speter if (integer_zerop (expr)) 4818334Speter { 49169689Skan tree t = build_int_cst (type, 0); 50169689Skan if (TREE_OVERFLOW (expr) || TREE_CONSTANT_OVERFLOW (expr)) 51169689Skan t = force_fit_type (t, 0, TREE_OVERFLOW (expr), 52169689Skan TREE_CONSTANT_OVERFLOW (expr)); 53169689Skan return t; 5418334Speter } 5518334Speter 5650397Sobrien switch (TREE_CODE (TREE_TYPE (expr))) 5750397Sobrien { 5850397Sobrien case POINTER_TYPE: 5950397Sobrien case REFERENCE_TYPE: 60169689Skan return fold_build1 (NOP_EXPR, type, expr); 6118334Speter 6250397Sobrien case INTEGER_TYPE: 6350397Sobrien case ENUMERAL_TYPE: 6450397Sobrien case BOOLEAN_TYPE: 65169689Skan if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE) 66169689Skan expr = fold_build1 (NOP_EXPR, 67261188Spfg lang_hooks.types.type_for_size (POINTER_SIZE, 0), 68169689Skan expr); 69169689Skan return fold_build1 (CONVERT_EXPR, type, expr); 7018334Speter 71261188Spfg /* APPLE LOCAL begin blocks (C++ ck) */ 72261188Spfg case BLOCK_POINTER_TYPE: 73261188Spfg /* APPLE LOCAL begin radar 5809099 */ 74261188Spfg if (objc_is_id (type) 75261188Spfg || (TREE_CODE (type) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type)))) 76261188Spfg /* APPLE LOCAL end radar 5809099 */ 77261188Spfg return fold_build1 (NOP_EXPR, type, expr); 78261188Spfg /* APPLE LOCAL end blocks (C++ ck) */ 79261188Spfg default: 80261188Spfg error ("cannot convert to a pointer type"); 81261188Spfg return convert_to_pointer (type, integer_zero_node); 82261188Spfg } 83261188Spfg} 8418334Speter 85261188Spfg/* APPLE LOCAL begin blocks (C++ ck) */ 86261188Spfgtree 87261188Spfgconvert_to_block_pointer (tree type, tree expr) 88261188Spfg{ 89261188Spfg if (TREE_TYPE (expr) == type) 90261188Spfg return expr; 91261188Spfg 92261188Spfg if (integer_zerop (expr)) 93261188Spfg { 94261188Spfg tree t = build_int_cst (type, 0); 95261188Spfg if (TREE_OVERFLOW (expr) || TREE_CONSTANT_OVERFLOW (expr)) 96261188Spfg t = force_fit_type (t, 0, TREE_OVERFLOW (expr), 97261188Spfg TREE_CONSTANT_OVERFLOW (expr)); 98261188Spfg return t; 9950397Sobrien } 100261188Spfg 101261188Spfg switch (TREE_CODE (TREE_TYPE (expr))) 102261188Spfg { 103261188Spfg case BLOCK_POINTER_TYPE: 104261188Spfg return fold_build1 (NOP_EXPR, type, expr); 105261188Spfg 106261188Spfg case INTEGER_TYPE: 107261188Spfg if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE) 108261188Spfg expr = fold_build1 (NOP_EXPR, 109261188Spfg lang_hooks.types.type_for_size (POINTER_SIZE, 0), 110261188Spfg expr); 111261188Spfg return fold_build1 (CONVERT_EXPR, type, expr); 112261188Spfg 113261188Spfg case POINTER_TYPE: 114261188Spfg /* APPLE LOCAL radar 5809099 */ 115261188Spfg if (objc_is_id (TREE_TYPE (expr)) || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (expr)))) 116261188Spfg return build1 (NOP_EXPR, type, expr); 117261188Spfg /* fall thru */ 118261188Spfg 119261188Spfg default: 120261188Spfg error ("cannot convert to a block pointer type"); 121261188Spfg return convert_to_block_pointer (type, integer_zero_node); 122261188Spfg } 12318334Speter} 12418334Speter 125261188Spfg/* APPLE LOCAL end blocks (C++ ck) */ 126261188Spfg 127132718Skan/* Avoid any floating point extensions from EXP. */ 128132718Skantree 129132718Skanstrip_float_extensions (tree exp) 130132718Skan{ 131132718Skan tree sub, expt, subt; 132132718Skan 133132718Skan /* For floating point constant look up the narrowest type that can hold 134132718Skan it properly and handle it like (type)(narrowest_type)constant. 135132718Skan This way we can optimize for instance a=a*2.0 where "a" is float 136132718Skan but 2.0 is double constant. */ 137132718Skan if (TREE_CODE (exp) == REAL_CST) 138132718Skan { 139132718Skan REAL_VALUE_TYPE orig; 140132718Skan tree type = NULL; 141132718Skan 142132718Skan orig = TREE_REAL_CST (exp); 143132718Skan if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node) 144132718Skan && exact_real_truncate (TYPE_MODE (float_type_node), &orig)) 145132718Skan type = float_type_node; 146132718Skan else if (TYPE_PRECISION (TREE_TYPE (exp)) 147132718Skan > TYPE_PRECISION (double_type_node) 148132718Skan && exact_real_truncate (TYPE_MODE (double_type_node), &orig)) 149132718Skan type = double_type_node; 150132718Skan if (type) 151132718Skan return build_real (type, real_value_truncate (TYPE_MODE (type), orig)); 152132718Skan } 153132718Skan 154169689Skan if (TREE_CODE (exp) != NOP_EXPR 155169689Skan && TREE_CODE (exp) != CONVERT_EXPR) 156132718Skan return exp; 157132718Skan 158132718Skan sub = TREE_OPERAND (exp, 0); 159132718Skan subt = TREE_TYPE (sub); 160132718Skan expt = TREE_TYPE (exp); 161132718Skan 162132718Skan if (!FLOAT_TYPE_P (subt)) 163132718Skan return exp; 164132718Skan 165132718Skan if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt)) 166132718Skan return exp; 167132718Skan 168132718Skan return strip_float_extensions (sub); 169132718Skan} 170132718Skan 171132718Skan 17218334Speter/* Convert EXPR to some floating-point type TYPE. 17318334Speter 17418334Speter EXPR must be float, integer, or enumeral; 17550397Sobrien in other cases error is called. */ 17618334Speter 17718334Spetertree 178132718Skanconvert_to_real (tree type, tree expr) 17918334Speter{ 180132718Skan enum built_in_function fcode = builtin_mathfn_code (expr); 181132718Skan tree itype = TREE_TYPE (expr); 182132718Skan 183132718Skan /* Disable until we figure out how to decide whether the functions are 184132718Skan present in runtime. */ 185132718Skan /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */ 186132718Skan if (optimize 187132718Skan && (TYPE_MODE (type) == TYPE_MODE (double_type_node) 188132718Skan || TYPE_MODE (type) == TYPE_MODE (float_type_node))) 189132718Skan { 190169689Skan switch (fcode) 191169689Skan { 192169689Skan#define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L: 193169689Skan CASE_MATHFN (ACOS) 194169689Skan CASE_MATHFN (ACOSH) 195169689Skan CASE_MATHFN (ASIN) 196169689Skan CASE_MATHFN (ASINH) 197169689Skan CASE_MATHFN (ATAN) 198169689Skan CASE_MATHFN (ATANH) 199169689Skan CASE_MATHFN (CBRT) 200169689Skan CASE_MATHFN (COS) 201169689Skan CASE_MATHFN (COSH) 202169689Skan CASE_MATHFN (ERF) 203169689Skan CASE_MATHFN (ERFC) 204169689Skan CASE_MATHFN (EXP) 205169689Skan CASE_MATHFN (EXP10) 206169689Skan CASE_MATHFN (EXP2) 207169689Skan CASE_MATHFN (EXPM1) 208169689Skan CASE_MATHFN (FABS) 209169689Skan CASE_MATHFN (GAMMA) 210169689Skan CASE_MATHFN (J0) 211169689Skan CASE_MATHFN (J1) 212169689Skan CASE_MATHFN (LGAMMA) 213169689Skan CASE_MATHFN (LOG) 214169689Skan CASE_MATHFN (LOG10) 215169689Skan CASE_MATHFN (LOG1P) 216169689Skan CASE_MATHFN (LOG2) 217169689Skan CASE_MATHFN (LOGB) 218169689Skan CASE_MATHFN (POW10) 219169689Skan CASE_MATHFN (SIN) 220169689Skan CASE_MATHFN (SINH) 221169689Skan CASE_MATHFN (SQRT) 222169689Skan CASE_MATHFN (TAN) 223169689Skan CASE_MATHFN (TANH) 224169689Skan CASE_MATHFN (TGAMMA) 225169689Skan CASE_MATHFN (Y0) 226169689Skan CASE_MATHFN (Y1) 227169689Skan#undef CASE_MATHFN 228169689Skan { 229169689Skan tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1))); 230169689Skan tree newtype = type; 231132718Skan 232169689Skan /* We have (outertype)sqrt((innertype)x). Choose the wider mode from 233169689Skan the both as the safe type for operation. */ 234169689Skan if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type)) 235169689Skan newtype = TREE_TYPE (arg0); 236132718Skan 237169689Skan /* Be careful about integer to fp conversions. 238169689Skan These may overflow still. */ 239169689Skan if (FLOAT_TYPE_P (TREE_TYPE (arg0)) 240169689Skan && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype) 241169689Skan && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node) 242169689Skan || TYPE_MODE (newtype) == TYPE_MODE (float_type_node))) 243169689Skan { 244169689Skan tree arglist; 245169689Skan tree fn = mathfn_built_in (newtype, fcode); 246132718Skan 247169689Skan if (fn) 248169689Skan { 249169689Skan arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0))); 250169689Skan expr = build_function_call_expr (fn, arglist); 251169689Skan if (newtype == type) 252169689Skan return expr; 253169689Skan } 254169689Skan } 255132718Skan } 256169689Skan default: 257169689Skan break; 258132718Skan } 259132718Skan } 260132718Skan if (optimize 261132718Skan && (((fcode == BUILT_IN_FLOORL 262132718Skan || fcode == BUILT_IN_CEILL 263169689Skan || fcode == BUILT_IN_ROUNDL 264169689Skan || fcode == BUILT_IN_RINTL 265169689Skan || fcode == BUILT_IN_TRUNCL 266169689Skan || fcode == BUILT_IN_NEARBYINTL) 267132718Skan && (TYPE_MODE (type) == TYPE_MODE (double_type_node) 268132718Skan || TYPE_MODE (type) == TYPE_MODE (float_type_node))) 269132718Skan || ((fcode == BUILT_IN_FLOOR 270132718Skan || fcode == BUILT_IN_CEIL 271132718Skan || fcode == BUILT_IN_ROUND 272169689Skan || fcode == BUILT_IN_RINT 273132718Skan || fcode == BUILT_IN_TRUNC 274132718Skan || fcode == BUILT_IN_NEARBYINT) 275132718Skan && (TYPE_MODE (type) == TYPE_MODE (float_type_node))))) 276132718Skan { 277132718Skan tree fn = mathfn_built_in (type, fcode); 278132718Skan 279132718Skan if (fn) 280132718Skan { 281169689Skan tree arg 282169689Skan = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1))); 283132718Skan 284169689Skan /* Make sure (type)arg0 is an extension, otherwise we could end up 285169689Skan changing (float)floor(double d) into floorf((float)d), which is 286169689Skan incorrect because (float)d uses round-to-nearest and can round 287169689Skan up to the next integer. */ 288169689Skan if (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (arg))) 289169689Skan return 290169689Skan build_function_call_expr (fn, 291169689Skan build_tree_list (NULL_TREE, 292169689Skan fold (convert_to_real (type, arg)))); 293132718Skan } 294132718Skan } 295132718Skan 296132718Skan /* Propagate the cast into the operation. */ 297132718Skan if (itype != type && FLOAT_TYPE_P (type)) 298132718Skan switch (TREE_CODE (expr)) 299132718Skan { 300169689Skan /* Convert (float)-x into -(float)x. This is safe for 301169689Skan round-to-nearest rounding mode. */ 302132718Skan case ABS_EXPR: 303132718Skan case NEGATE_EXPR: 304169689Skan if (!flag_rounding_math 305169689Skan && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (expr))) 306132718Skan return build1 (TREE_CODE (expr), type, 307132718Skan fold (convert_to_real (type, 308132718Skan TREE_OPERAND (expr, 0)))); 309132718Skan break; 310132718Skan /* Convert (outertype)((innertype0)a+(innertype1)b) 311132718Skan into ((newtype)a+(newtype)b) where newtype 312132718Skan is the widest mode from all of these. */ 313132718Skan case PLUS_EXPR: 314132718Skan case MINUS_EXPR: 315132718Skan case MULT_EXPR: 316132718Skan case RDIV_EXPR: 317132718Skan { 318132718Skan tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0)); 319132718Skan tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1)); 320132718Skan 321132718Skan if (FLOAT_TYPE_P (TREE_TYPE (arg0)) 322132718Skan && FLOAT_TYPE_P (TREE_TYPE (arg1))) 323132718Skan { 324132718Skan tree newtype = type; 325169689Skan 326169689Skan if (TYPE_MODE (TREE_TYPE (arg0)) == SDmode 327169689Skan || TYPE_MODE (TREE_TYPE (arg1)) == SDmode) 328169689Skan newtype = dfloat32_type_node; 329169689Skan if (TYPE_MODE (TREE_TYPE (arg0)) == DDmode 330169689Skan || TYPE_MODE (TREE_TYPE (arg1)) == DDmode) 331169689Skan newtype = dfloat64_type_node; 332169689Skan if (TYPE_MODE (TREE_TYPE (arg0)) == TDmode 333169689Skan || TYPE_MODE (TREE_TYPE (arg1)) == TDmode) 334169689Skan newtype = dfloat128_type_node; 335169689Skan if (newtype == dfloat32_type_node 336169689Skan || newtype == dfloat64_type_node 337169689Skan || newtype == dfloat128_type_node) 338169689Skan { 339169689Skan expr = build2 (TREE_CODE (expr), newtype, 340169689Skan fold (convert_to_real (newtype, arg0)), 341169689Skan fold (convert_to_real (newtype, arg1))); 342169689Skan if (newtype == type) 343169689Skan return expr; 344169689Skan break; 345169689Skan } 346169689Skan 347132718Skan if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype)) 348132718Skan newtype = TREE_TYPE (arg0); 349132718Skan if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype)) 350132718Skan newtype = TREE_TYPE (arg1); 351132718Skan if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)) 352132718Skan { 353169689Skan expr = build2 (TREE_CODE (expr), newtype, 354169689Skan fold (convert_to_real (newtype, arg0)), 355169689Skan fold (convert_to_real (newtype, arg1))); 356132718Skan if (newtype == type) 357132718Skan return expr; 358132718Skan } 359132718Skan } 360132718Skan } 361132718Skan break; 362132718Skan default: 363132718Skan break; 364132718Skan } 365132718Skan 36650397Sobrien switch (TREE_CODE (TREE_TYPE (expr))) 36750397Sobrien { 36850397Sobrien case REAL_TYPE: 369169689Skan /* Ignore the conversion if we don't need to store intermediate 370169689Skan results and neither type is a decimal float. */ 371169689Skan return build1 ((flag_float_store 372169689Skan || DECIMAL_FLOAT_TYPE_P (type) 373169689Skan || DECIMAL_FLOAT_TYPE_P (itype)) 374169689Skan ? CONVERT_EXPR : NOP_EXPR, type, expr); 37518334Speter 37650397Sobrien case INTEGER_TYPE: 37750397Sobrien case ENUMERAL_TYPE: 37850397Sobrien case BOOLEAN_TYPE: 37950397Sobrien return build1 (FLOAT_EXPR, type, expr); 38018334Speter 38150397Sobrien case COMPLEX_TYPE: 38250397Sobrien return convert (type, 383169689Skan fold_build1 (REALPART_EXPR, 384169689Skan TREE_TYPE (TREE_TYPE (expr)), expr)); 38518334Speter 38650397Sobrien case POINTER_TYPE: 38750397Sobrien case REFERENCE_TYPE: 38850397Sobrien error ("pointer value used where a floating point value was expected"); 38950397Sobrien return convert_to_real (type, integer_zero_node); 39018334Speter 39150397Sobrien default: 39250397Sobrien error ("aggregate value used where a float was expected"); 39350397Sobrien return convert_to_real (type, integer_zero_node); 39450397Sobrien } 39518334Speter} 39618334Speter 39718334Speter/* Convert EXPR to some integer (or enum) type TYPE. 39818334Speter 39990075Sobrien EXPR must be pointer, integer, discrete (enum, char, or bool), float, or 40090075Sobrien vector; in other cases error is called. 40118334Speter 40218334Speter The result of this is always supposed to be a newly created tree node 40318334Speter not in use in any existing structure. */ 40418334Speter 40518334Spetertree 406132718Skanconvert_to_integer (tree type, tree expr) 40718334Speter{ 40850397Sobrien enum tree_code ex_form = TREE_CODE (expr); 40950397Sobrien tree intype = TREE_TYPE (expr); 41090075Sobrien unsigned int inprec = TYPE_PRECISION (intype); 41190075Sobrien unsigned int outprec = TYPE_PRECISION (type); 41218334Speter 41352284Sobrien /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can 41452284Sobrien be. Consider `enum E = { a, b = (enum E) 3 };'. */ 41590075Sobrien if (!COMPLETE_TYPE_P (type)) 41652284Sobrien { 41752284Sobrien error ("conversion to incomplete type"); 41852284Sobrien return error_mark_node; 41952284Sobrien } 42052284Sobrien 421169689Skan /* Convert e.g. (long)round(d) -> lround(d). */ 422169689Skan /* If we're converting to char, we may encounter differing behavior 423169689Skan between converting from double->char vs double->long->char. 424169689Skan We're in "undefined" territory but we prefer to be conservative, 425169689Skan so only proceed in "unsafe" math mode. */ 426169689Skan if (optimize 427169689Skan && (flag_unsafe_math_optimizations 428169689Skan || (long_integer_type_node 429169689Skan && outprec >= TYPE_PRECISION (long_integer_type_node)))) 430169689Skan { 431169689Skan tree s_expr = strip_float_extensions (expr); 432169689Skan tree s_intype = TREE_TYPE (s_expr); 433169689Skan const enum built_in_function fcode = builtin_mathfn_code (s_expr); 434169689Skan tree fn = 0; 435169689Skan 436169689Skan switch (fcode) 437169689Skan { 438169689Skan CASE_FLT_FN (BUILT_IN_CEIL): 439169689Skan /* Only convert in ISO C99 mode. */ 440169689Skan if (!TARGET_C99_FUNCTIONS) 441169689Skan break; 442169689Skan if (outprec < TYPE_PRECISION (long_integer_type_node) 443169689Skan || (outprec == TYPE_PRECISION (long_integer_type_node) 444169689Skan && !TYPE_UNSIGNED (type))) 445169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL); 446169689Skan else if (outprec == TYPE_PRECISION (long_long_integer_type_node) 447169689Skan && !TYPE_UNSIGNED (type)) 448169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL); 449169689Skan break; 450169689Skan 451169689Skan CASE_FLT_FN (BUILT_IN_FLOOR): 452169689Skan /* Only convert in ISO C99 mode. */ 453169689Skan if (!TARGET_C99_FUNCTIONS) 454169689Skan break; 455169689Skan if (outprec < TYPE_PRECISION (long_integer_type_node) 456169689Skan || (outprec == TYPE_PRECISION (long_integer_type_node) 457169689Skan && !TYPE_UNSIGNED (type))) 458169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR); 459169689Skan else if (outprec == TYPE_PRECISION (long_long_integer_type_node) 460169689Skan && !TYPE_UNSIGNED (type)) 461169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR); 462169689Skan break; 463169689Skan 464169689Skan CASE_FLT_FN (BUILT_IN_ROUND): 465169689Skan if (outprec < TYPE_PRECISION (long_integer_type_node) 466169689Skan || (outprec == TYPE_PRECISION (long_integer_type_node) 467169689Skan && !TYPE_UNSIGNED (type))) 468169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LROUND); 469169689Skan else if (outprec == TYPE_PRECISION (long_long_integer_type_node) 470169689Skan && !TYPE_UNSIGNED (type)) 471169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND); 472169689Skan break; 473169689Skan 474169689Skan CASE_FLT_FN (BUILT_IN_NEARBYINT): 475169689Skan /* Only convert nearbyint* if we can ignore math exceptions. */ 476169689Skan if (flag_trapping_math) 477169689Skan break; 478169689Skan /* ... Fall through ... */ 479169689Skan CASE_FLT_FN (BUILT_IN_RINT): 480169689Skan if (outprec < TYPE_PRECISION (long_integer_type_node) 481169689Skan || (outprec == TYPE_PRECISION (long_integer_type_node) 482169689Skan && !TYPE_UNSIGNED (type))) 483169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LRINT); 484169689Skan else if (outprec == TYPE_PRECISION (long_long_integer_type_node) 485169689Skan && !TYPE_UNSIGNED (type)) 486169689Skan fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT); 487169689Skan break; 488169689Skan 489169689Skan CASE_FLT_FN (BUILT_IN_TRUNC): 490169689Skan { 491169689Skan tree arglist = TREE_OPERAND (s_expr, 1); 492169689Skan return convert_to_integer (type, TREE_VALUE (arglist)); 493169689Skan } 494169689Skan 495169689Skan default: 496169689Skan break; 497169689Skan } 498169689Skan 499169689Skan if (fn) 500169689Skan { 501169689Skan tree arglist = TREE_OPERAND (s_expr, 1); 502169689Skan tree newexpr = build_function_call_expr (fn, arglist); 503169689Skan return convert_to_integer (type, newexpr); 504169689Skan } 505169689Skan } 506169689Skan 50750397Sobrien switch (TREE_CODE (intype)) 50818334Speter { 50950397Sobrien case POINTER_TYPE: 51050397Sobrien case REFERENCE_TYPE: 511261188Spfg /* APPLE LOCAL radar 6035389 */ 512261188Spfg case BLOCK_POINTER_TYPE: 51318334Speter if (integer_zerop (expr)) 514169689Skan return build_int_cst (type, 0); 51518334Speter 516169689Skan /* Convert to an unsigned integer of the correct width first, 517169689Skan and from there widen/truncate to the required type. */ 518169689Skan expr = fold_build1 (CONVERT_EXPR, 519169689Skan lang_hooks.types.type_for_size (POINTER_SIZE, 0), 520169689Skan expr); 521169689Skan return fold_convert (type, expr); 52218334Speter 52350397Sobrien case INTEGER_TYPE: 52450397Sobrien case ENUMERAL_TYPE: 52550397Sobrien case BOOLEAN_TYPE: 52650397Sobrien /* If this is a logical operation, which just returns 0 or 1, we can 527169689Skan change the type of the expression. */ 52818334Speter 529169689Skan if (TREE_CODE_CLASS (ex_form) == tcc_comparison) 53018334Speter { 531132718Skan expr = copy_node (expr); 53218334Speter TREE_TYPE (expr) = type; 53318334Speter return expr; 53418334Speter } 53550397Sobrien 53650397Sobrien /* If we are widening the type, put in an explicit conversion. 53750397Sobrien Similarly if we are not changing the width. After this, we know 53850397Sobrien we are truncating EXPR. */ 53950397Sobrien 54018334Speter else if (outprec >= inprec) 541132718Skan { 542132718Skan enum tree_code code; 543169689Skan tree tem; 54418334Speter 545132718Skan /* If the precision of the EXPR's type is K bits and the 546132718Skan destination mode has more bits, and the sign is changing, 547132718Skan it is not safe to use a NOP_EXPR. For example, suppose 548132718Skan that EXPR's type is a 3-bit unsigned integer type, the 549132718Skan TYPE is a 3-bit signed integer type, and the machine mode 550132718Skan for the types is 8-bit QImode. In that case, the 551132718Skan conversion necessitates an explicit sign-extension. In 552132718Skan the signed-to-unsigned case the high-order bits have to 553132718Skan be cleared. */ 554169689Skan if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr)) 555132718Skan && (TYPE_PRECISION (TREE_TYPE (expr)) 556132718Skan != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))))) 557132718Skan code = CONVERT_EXPR; 558132718Skan else 559132718Skan code = NOP_EXPR; 560132718Skan 561169689Skan tem = fold_unary (code, type, expr); 562169689Skan if (tem) 563169689Skan return tem; 564169689Skan 565169689Skan tem = build1 (code, type, expr); 566169689Skan TREE_NO_WARNING (tem) = 1; 567169689Skan return tem; 568132718Skan } 569132718Skan 57018334Speter /* If TYPE is an enumeral type or a type with a precision less 57118334Speter than the number of bits in its mode, do the conversion to the 57218334Speter type corresponding to its mode, then do a nop conversion 57318334Speter to TYPE. */ 57418334Speter else if (TREE_CODE (type) == ENUMERAL_TYPE 57518334Speter || outprec != GET_MODE_BITSIZE (TYPE_MODE (type))) 57618334Speter return build1 (NOP_EXPR, type, 577169689Skan convert (lang_hooks.types.type_for_mode 578169689Skan (TYPE_MODE (type), TYPE_UNSIGNED (type)), 57918334Speter expr)); 58018334Speter 58118334Speter /* Here detect when we can distribute the truncation down past some 58218334Speter arithmetic. For example, if adding two longs and converting to an 58318334Speter int, we can equally well convert both to ints and then add. 58418334Speter For the operations handled here, such truncation distribution 58518334Speter is always safe. 58618334Speter It is desirable in these cases: 58718334Speter 1) when truncating down to full-word from a larger size 58818334Speter 2) when truncating takes no work. 58918334Speter 3) when at least one operand of the arithmetic has been extended 59018334Speter (as by C's default conversions). In this case we need two conversions 59118334Speter if we do the arithmetic as already requested, so we might as well 59218334Speter truncate both and then combine. Perhaps that way we need only one. 59318334Speter 59418334Speter Note that in general we cannot do the arithmetic in a type 59518334Speter shorter than the desired result of conversion, even if the operands 59618334Speter are both extended from a shorter type, because they might overflow 59718334Speter if combined in that type. The exceptions to this--the times when 59818334Speter two narrow values can be combined in their narrow type even to 59918334Speter make a wider result--are handled by "shorten" in build_binary_op. */ 60018334Speter 60118334Speter switch (ex_form) 60218334Speter { 60318334Speter case RSHIFT_EXPR: 60418334Speter /* We can pass truncation down through right shifting 60518334Speter when the shift count is a nonpositive constant. */ 60618334Speter if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST 607169689Skan && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0) 60818334Speter goto trunc1; 60918334Speter break; 61018334Speter 61118334Speter case LSHIFT_EXPR: 61218334Speter /* We can pass truncation down through left shifting 613102780Skan when the shift count is a nonnegative constant and 614102780Skan the target type is unsigned. */ 61518334Speter if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST 61618334Speter && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0 617169689Skan && TYPE_UNSIGNED (type) 61818334Speter && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) 61918334Speter { 62018334Speter /* If shift count is less than the width of the truncated type, 62118334Speter really shift. */ 62218334Speter if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type))) 62318334Speter /* In this case, shifting is like multiplication. */ 62418334Speter goto trunc1; 62518334Speter else 62618334Speter { 62718334Speter /* If it is >= that width, result is zero. 62818334Speter Handling this with trunc1 would give the wrong result: 62918334Speter (int) ((long long) a << 32) is well defined (as 0) 63018334Speter but (int) a << 32 is undefined and would get a 63118334Speter warning. */ 63218334Speter 633169689Skan tree t = build_int_cst (type, 0); 63418334Speter 63518334Speter /* If the original expression had side-effects, we must 63618334Speter preserve it. */ 63718334Speter if (TREE_SIDE_EFFECTS (expr)) 638169689Skan return build2 (COMPOUND_EXPR, type, expr, t); 63918334Speter else 64018334Speter return t; 64118334Speter } 64218334Speter } 64318334Speter break; 64418334Speter 64518334Speter case MAX_EXPR: 64618334Speter case MIN_EXPR: 64718334Speter case MULT_EXPR: 64818334Speter { 64918334Speter tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); 65018334Speter tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); 65118334Speter 65218334Speter /* Don't distribute unless the output precision is at least as big 65318334Speter as the actual inputs. Otherwise, the comparison of the 65418334Speter truncated values will be wrong. */ 65518334Speter if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0)) 65618334Speter && outprec >= TYPE_PRECISION (TREE_TYPE (arg1)) 65718334Speter /* If signedness of arg0 and arg1 don't match, 65818334Speter we can't necessarily find a type to compare them in. */ 659169689Skan && (TYPE_UNSIGNED (TREE_TYPE (arg0)) 660169689Skan == TYPE_UNSIGNED (TREE_TYPE (arg1)))) 66118334Speter goto trunc1; 66218334Speter break; 66318334Speter } 66418334Speter 66518334Speter case PLUS_EXPR: 66618334Speter case MINUS_EXPR: 66718334Speter case BIT_AND_EXPR: 66818334Speter case BIT_IOR_EXPR: 66918334Speter case BIT_XOR_EXPR: 67018334Speter trunc1: 67118334Speter { 67218334Speter tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); 67318334Speter tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); 67418334Speter 67518334Speter if (outprec >= BITS_PER_WORD 67618334Speter || TRULY_NOOP_TRUNCATION (outprec, inprec) 67718334Speter || inprec > TYPE_PRECISION (TREE_TYPE (arg0)) 67818334Speter || inprec > TYPE_PRECISION (TREE_TYPE (arg1))) 67918334Speter { 68018334Speter /* Do the arithmetic in type TYPEX, 68118334Speter then convert result to TYPE. */ 68290075Sobrien tree typex = type; 68318334Speter 68418334Speter /* Can't do arithmetic in enumeral types 68518334Speter so use an integer type that will hold the values. */ 68618334Speter if (TREE_CODE (typex) == ENUMERAL_TYPE) 687169689Skan typex = lang_hooks.types.type_for_size 688169689Skan (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex)); 68918334Speter 69018334Speter /* But now perhaps TYPEX is as wide as INPREC. 69118334Speter In that case, do nothing special here. 69218334Speter (Otherwise would recurse infinitely in convert. */ 69318334Speter if (TYPE_PRECISION (typex) != inprec) 69418334Speter { 69518334Speter /* Don't do unsigned arithmetic where signed was wanted, 69618334Speter or vice versa. 69790075Sobrien Exception: if both of the original operands were 698132718Skan unsigned then we can safely do the work as unsigned. 699117395Skan Exception: shift operations take their type solely 700117395Skan from the first argument. 701117395Skan Exception: the LSHIFT_EXPR case above requires that 702117395Skan we perform this operation unsigned lest we produce 703117395Skan signed-overflow undefinedness. 70418334Speter And we may need to do it as unsigned 70518334Speter if we truncate to the original size. */ 706169689Skan if (TYPE_UNSIGNED (TREE_TYPE (expr)) 707169689Skan || (TYPE_UNSIGNED (TREE_TYPE (arg0)) 708169689Skan && (TYPE_UNSIGNED (TREE_TYPE (arg1)) 709117395Skan || ex_form == LSHIFT_EXPR 710117395Skan || ex_form == RSHIFT_EXPR 711117395Skan || ex_form == LROTATE_EXPR 712117395Skan || ex_form == RROTATE_EXPR)) 713169689Skan || ex_form == LSHIFT_EXPR 714169689Skan /* If we have !flag_wrapv, and either ARG0 or 715169689Skan ARG1 is of a signed type, we have to do 716169689Skan PLUS_EXPR or MINUS_EXPR in an unsigned 717169689Skan type. Otherwise, we would introduce 718169689Skan signed-overflow undefinedness. */ 719169689Skan || ((!TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)) 720169689Skan || !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1))) 721169689Skan && (ex_form == PLUS_EXPR 722169689Skan || ex_form == MINUS_EXPR))) 723169689Skan typex = lang_hooks.types.unsigned_type (typex); 724117395Skan else 725169689Skan typex = lang_hooks.types.signed_type (typex); 72618334Speter return convert (type, 727169689Skan fold_build2 (ex_form, typex, 72818334Speter convert (typex, arg0), 729169689Skan convert (typex, arg1))); 73018334Speter } 73118334Speter } 73218334Speter } 73318334Speter break; 73418334Speter 73518334Speter case NEGATE_EXPR: 73618334Speter case BIT_NOT_EXPR: 73718334Speter /* This is not correct for ABS_EXPR, 73818334Speter since we must test the sign before truncation. */ 73918334Speter { 740169689Skan tree typex; 74118334Speter 742169689Skan /* Don't do unsigned arithmetic where signed was wanted, 743169689Skan or vice versa. */ 744169689Skan if (TYPE_UNSIGNED (TREE_TYPE (expr))) 745169689Skan typex = lang_hooks.types.unsigned_type (type); 746169689Skan else 747169689Skan typex = lang_hooks.types.signed_type (type); 748169689Skan return convert (type, 749169689Skan fold_build1 (ex_form, typex, 750169689Skan convert (typex, 751169689Skan TREE_OPERAND (expr, 0)))); 75218334Speter } 75318334Speter 75418334Speter case NOP_EXPR: 755117395Skan /* Don't introduce a 756117395Skan "can't convert between vector values of different size" error. */ 757117395Skan if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE 758117395Skan && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0)))) 759117395Skan != GET_MODE_SIZE (TYPE_MODE (type)))) 760117395Skan break; 76118334Speter /* If truncating after truncating, might as well do all at once. 76218334Speter If truncating after extending, we may get rid of wasted work. */ 76318334Speter return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type)); 76418334Speter 76518334Speter case COND_EXPR: 76650397Sobrien /* It is sometimes worthwhile to push the narrowing down through 76750397Sobrien the conditional and never loses. */ 768169689Skan return fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), 769132718Skan convert (type, TREE_OPERAND (expr, 1)), 770169689Skan convert (type, TREE_OPERAND (expr, 2))); 77118334Speter 77250397Sobrien default: 77350397Sobrien break; 77418334Speter } 77518334Speter 776169689Skan return build1 (CONVERT_EXPR, type, expr); 77718334Speter 77850397Sobrien case REAL_TYPE: 77950397Sobrien return build1 (FIX_TRUNC_EXPR, type, expr); 78018334Speter 78150397Sobrien case COMPLEX_TYPE: 78250397Sobrien return convert (type, 783169689Skan fold_build1 (REALPART_EXPR, 784169689Skan TREE_TYPE (TREE_TYPE (expr)), expr)); 78518334Speter 78690075Sobrien case VECTOR_TYPE: 787169689Skan if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr)))) 78890075Sobrien { 78990075Sobrien error ("can't convert between vector values of different size"); 79090075Sobrien return error_mark_node; 79190075Sobrien } 792169689Skan return build1 (VIEW_CONVERT_EXPR, type, expr); 79390075Sobrien 79450397Sobrien default: 79550397Sobrien error ("aggregate value used where an integer was expected"); 79650397Sobrien return convert (type, integer_zero_node); 79750397Sobrien } 79818334Speter} 79918334Speter 80018334Speter/* Convert EXPR to the complex type TYPE in the usual ways. */ 80118334Speter 80218334Spetertree 803132718Skanconvert_to_complex (tree type, tree expr) 80418334Speter{ 80518334Speter tree subtype = TREE_TYPE (type); 806132718Skan 80750397Sobrien switch (TREE_CODE (TREE_TYPE (expr))) 80818334Speter { 80950397Sobrien case REAL_TYPE: 81050397Sobrien case INTEGER_TYPE: 81150397Sobrien case ENUMERAL_TYPE: 81250397Sobrien case BOOLEAN_TYPE: 813169689Skan return build2 (COMPLEX_EXPR, type, convert (subtype, expr), 814169689Skan convert (subtype, integer_zero_node)); 81518334Speter 81650397Sobrien case COMPLEX_TYPE: 81750397Sobrien { 81850397Sobrien tree elt_type = TREE_TYPE (TREE_TYPE (expr)); 81950397Sobrien 82050397Sobrien if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype)) 82150397Sobrien return expr; 82250397Sobrien else if (TREE_CODE (expr) == COMPLEX_EXPR) 823169689Skan return fold_build2 (COMPLEX_EXPR, type, 82450397Sobrien convert (subtype, TREE_OPERAND (expr, 0)), 825169689Skan convert (subtype, TREE_OPERAND (expr, 1))); 82650397Sobrien else 82750397Sobrien { 82850397Sobrien expr = save_expr (expr); 82950397Sobrien return 830169689Skan fold_build2 (COMPLEX_EXPR, type, 83150397Sobrien convert (subtype, 832169689Skan fold_build1 (REALPART_EXPR, 833169689Skan TREE_TYPE (TREE_TYPE (expr)), 834169689Skan expr)), 835169689Skan convert (subtype, 836169689Skan fold_build1 (IMAGPART_EXPR, 837169689Skan TREE_TYPE (TREE_TYPE (expr)), 838169689Skan expr))); 83950397Sobrien } 84050397Sobrien } 84150397Sobrien 84250397Sobrien case POINTER_TYPE: 84350397Sobrien case REFERENCE_TYPE: 84450397Sobrien error ("pointer value used where a complex was expected"); 84550397Sobrien return convert_to_complex (type, integer_zero_node); 84650397Sobrien 84750397Sobrien default: 84850397Sobrien error ("aggregate value used where a complex was expected"); 84950397Sobrien return convert_to_complex (type, integer_zero_node); 85018334Speter } 85118334Speter} 85290075Sobrien 85390075Sobrien/* Convert EXPR to the vector type TYPE in the usual ways. */ 85490075Sobrien 85590075Sobrientree 856132718Skanconvert_to_vector (tree type, tree expr) 85790075Sobrien{ 85890075Sobrien switch (TREE_CODE (TREE_TYPE (expr))) 85990075Sobrien { 86090075Sobrien case INTEGER_TYPE: 86190075Sobrien case VECTOR_TYPE: 862169689Skan if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr)))) 86390075Sobrien { 86490075Sobrien error ("can't convert between vector values of different size"); 86590075Sobrien return error_mark_node; 86690075Sobrien } 867169689Skan return build1 (VIEW_CONVERT_EXPR, type, expr); 86890075Sobrien 86990075Sobrien default: 87090075Sobrien error ("can't convert value to a vector"); 871169689Skan return error_mark_node; 87290075Sobrien } 87390075Sobrien} 874