00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028 #include "coretypes.h"
00029 #include "tm.h"
00030 #include "tree.h"
00031 #include "flags.h"
00032 #include "convert.h"
00033 #include "toplev.h"
00034 #include "langhooks.h"
00035 #include "real.h"
00036
00037
00038
00039
00040
00041 tree
00042 convert_to_pointer (tree type, tree expr)
00043 {
00044 if (integer_zerop (expr))
00045 {
00046 expr = build_int_cst (type, 0);
00047 return expr;
00048 }
00049
00050 switch (TREE_CODE (TREE_TYPE (expr)))
00051 {
00052 case POINTER_TYPE:
00053 case REFERENCE_TYPE:
00054 return build1 (NOP_EXPR, type, expr);
00055
00056 case INTEGER_TYPE:
00057 case ENUMERAL_TYPE:
00058 case BOOLEAN_TYPE:
00059 case CHAR_TYPE:
00060 if (TYPE_PRECISION (TREE_TYPE (expr)) == POINTER_SIZE)
00061 return build1 (CONVERT_EXPR, type, expr);
00062
00063 return
00064 convert_to_pointer (type,
00065 convert (lang_hooks.types.type_for_size
00066 (POINTER_SIZE, 0), expr));
00067
00068 default:
00069 error ("cannot convert to a pointer type");
00070 return convert_to_pointer (type, integer_zero_node);
00071 }
00072 }
00073
00074
00075 tree
00076 strip_float_extensions (tree exp)
00077 {
00078 tree sub, expt, subt;
00079
00080
00081
00082
00083
00084 if (TREE_CODE (exp) == REAL_CST)
00085 {
00086 REAL_VALUE_TYPE orig;
00087 tree type = NULL;
00088
00089 orig = TREE_REAL_CST (exp);
00090 if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
00091 && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
00092 type = float_type_node;
00093 else if (TYPE_PRECISION (TREE_TYPE (exp))
00094 > TYPE_PRECISION (double_type_node)
00095 && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
00096 type = double_type_node;
00097 if (type)
00098 return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
00099 }
00100
00101 if (TREE_CODE (exp) != NOP_EXPR
00102 && TREE_CODE (exp) != CONVERT_EXPR)
00103 return exp;
00104
00105 sub = TREE_OPERAND (exp, 0);
00106 subt = TREE_TYPE (sub);
00107 expt = TREE_TYPE (exp);
00108
00109 if (!FLOAT_TYPE_P (subt))
00110 return exp;
00111
00112 if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
00113 return exp;
00114
00115 return strip_float_extensions (sub);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 tree
00125 convert_to_real (tree type, tree expr)
00126 {
00127 enum built_in_function fcode = builtin_mathfn_code (expr);
00128 tree itype = TREE_TYPE (expr);
00129
00130
00131
00132
00133 if (optimize
00134 && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
00135 || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
00136 {
00137 switch (fcode)
00138 {
00139 #define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
00140 CASE_MATHFN (ACOS)
00141 CASE_MATHFN (ACOSH)
00142 CASE_MATHFN (ASIN)
00143 CASE_MATHFN (ASINH)
00144 CASE_MATHFN (ATAN)
00145 CASE_MATHFN (ATANH)
00146 CASE_MATHFN (CBRT)
00147 CASE_MATHFN (COS)
00148 CASE_MATHFN (COSH)
00149 CASE_MATHFN (ERF)
00150 CASE_MATHFN (ERFC)
00151 CASE_MATHFN (EXP)
00152 CASE_MATHFN (EXP10)
00153 CASE_MATHFN (EXP2)
00154 CASE_MATHFN (EXPM1)
00155 CASE_MATHFN (FABS)
00156 CASE_MATHFN (GAMMA)
00157 CASE_MATHFN (J0)
00158 CASE_MATHFN (J1)
00159 CASE_MATHFN (LGAMMA)
00160 CASE_MATHFN (LOG)
00161 CASE_MATHFN (LOG10)
00162 CASE_MATHFN (LOG1P)
00163 CASE_MATHFN (LOG2)
00164 CASE_MATHFN (LOGB)
00165 CASE_MATHFN (POW10)
00166 CASE_MATHFN (SIN)
00167 CASE_MATHFN (SINH)
00168 CASE_MATHFN (SQRT)
00169 CASE_MATHFN (TAN)
00170 CASE_MATHFN (TANH)
00171 CASE_MATHFN (TGAMMA)
00172 CASE_MATHFN (Y0)
00173 CASE_MATHFN (Y1)
00174 #undef CASE_MATHFN
00175 {
00176 tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
00177 tree newtype = type;
00178
00179
00180
00181 if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
00182 newtype = TREE_TYPE (arg0);
00183
00184
00185
00186 if (FLOAT_TYPE_P (TREE_TYPE (arg0))
00187 && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
00188 && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
00189 || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
00190 {
00191 tree arglist;
00192 tree fn = mathfn_built_in (newtype, fcode);
00193
00194 if (fn)
00195 {
00196 arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
00197 expr = build_function_call_expr (fn, arglist);
00198 if (newtype == type)
00199 return expr;
00200 }
00201 }
00202 }
00203 default:
00204 break;
00205 }
00206 }
00207 if (optimize
00208 && (((fcode == BUILT_IN_FLOORL
00209 || fcode == BUILT_IN_CEILL
00210 || fcode == BUILT_IN_ROUNDL
00211 || fcode == BUILT_IN_RINTL
00212 || fcode == BUILT_IN_TRUNCL
00213 || fcode == BUILT_IN_NEARBYINTL)
00214 && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
00215 || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
00216 || ((fcode == BUILT_IN_FLOOR
00217 || fcode == BUILT_IN_CEIL
00218 || fcode == BUILT_IN_ROUND
00219 || fcode == BUILT_IN_RINT
00220 || fcode == BUILT_IN_TRUNC
00221 || fcode == BUILT_IN_NEARBYINT)
00222 && (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
00223 {
00224 tree fn = mathfn_built_in (type, fcode);
00225
00226 if (fn)
00227 {
00228 tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr,
00229 1)));
00230 tree arglist = build_tree_list (NULL_TREE,
00231 fold (convert_to_real (type, arg0)));
00232
00233 return build_function_call_expr (fn, arglist);
00234 }
00235 }
00236
00237
00238 if (itype != type && FLOAT_TYPE_P (type))
00239 switch (TREE_CODE (expr))
00240 {
00241
00242 case ABS_EXPR:
00243 case NEGATE_EXPR:
00244 if (TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (expr)))
00245 return build1 (TREE_CODE (expr), type,
00246 fold (convert_to_real (type,
00247 TREE_OPERAND (expr, 0))));
00248 break;
00249
00250
00251
00252 case PLUS_EXPR:
00253 case MINUS_EXPR:
00254 case MULT_EXPR:
00255 case RDIV_EXPR:
00256 {
00257 tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
00258 tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
00259
00260 if (FLOAT_TYPE_P (TREE_TYPE (arg0))
00261 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
00262 {
00263 tree newtype = type;
00264 if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
00265 newtype = TREE_TYPE (arg0);
00266 if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
00267 newtype = TREE_TYPE (arg1);
00268 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
00269 {
00270 expr = build2 (TREE_CODE (expr), newtype,
00271 fold (convert_to_real (newtype, arg0)),
00272 fold (convert_to_real (newtype, arg1)));
00273 if (newtype == type)
00274 return expr;
00275 }
00276 }
00277 }
00278 break;
00279 default:
00280 break;
00281 }
00282
00283 switch (TREE_CODE (TREE_TYPE (expr)))
00284 {
00285 case REAL_TYPE:
00286 return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
00287 type, expr);
00288
00289 case INTEGER_TYPE:
00290 case ENUMERAL_TYPE:
00291 case BOOLEAN_TYPE:
00292 case CHAR_TYPE:
00293 return build1 (FLOAT_EXPR, type, expr);
00294
00295 case COMPLEX_TYPE:
00296 return convert (type,
00297 fold (build1 (REALPART_EXPR,
00298 TREE_TYPE (TREE_TYPE (expr)), expr)));
00299
00300 case POINTER_TYPE:
00301 case REFERENCE_TYPE:
00302 error ("pointer value used where a floating point value was expected");
00303 return convert_to_real (type, integer_zero_node);
00304
00305 default:
00306 error ("aggregate value used where a float was expected");
00307 return convert_to_real (type, integer_zero_node);
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 tree
00320 convert_to_integer (tree type, tree expr)
00321 {
00322 enum tree_code ex_form = TREE_CODE (expr);
00323 tree intype = TREE_TYPE (expr);
00324 unsigned int inprec = TYPE_PRECISION (intype);
00325 unsigned int outprec = TYPE_PRECISION (type);
00326
00327
00328
00329 if (!COMPLETE_TYPE_P (type))
00330 {
00331 error ("conversion to incomplete type");
00332 return error_mark_node;
00333 }
00334
00335
00336
00337
00338
00339
00340 if (optimize
00341 && (flag_unsafe_math_optimizations
00342 || (long_integer_type_node
00343 && outprec >= TYPE_PRECISION (long_integer_type_node))))
00344 {
00345 tree s_expr = strip_float_extensions (expr);
00346 tree s_intype = TREE_TYPE (s_expr);
00347 const enum built_in_function fcode = builtin_mathfn_code (s_expr);
00348 tree fn = 0;
00349
00350 switch (fcode)
00351 {
00352 case BUILT_IN_ROUND: case BUILT_IN_ROUNDF: case BUILT_IN_ROUNDL:
00353 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
00354 fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
00355 else
00356 fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
00357 break;
00358
00359 case BUILT_IN_RINT: case BUILT_IN_RINTF: case BUILT_IN_RINTL:
00360
00361 if (flag_trapping_math)
00362 break;
00363
00364 case BUILT_IN_NEARBYINT: case BUILT_IN_NEARBYINTF: case BUILT_IN_NEARBYINTL:
00365 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
00366 fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
00367 else
00368 fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
00369 break;
00370 default:
00371 break;
00372 }
00373
00374 if (fn)
00375 {
00376 tree arglist = TREE_OPERAND (s_expr, 1);
00377 tree newexpr = build_function_call_expr (fn, arglist);
00378 return convert_to_integer (type, newexpr);
00379 }
00380 }
00381
00382 switch (TREE_CODE (intype))
00383 {
00384 case POINTER_TYPE:
00385 case REFERENCE_TYPE:
00386 if (integer_zerop (expr))
00387 expr = integer_zero_node;
00388 else
00389 expr = fold (build1 (CONVERT_EXPR,
00390 lang_hooks.types.type_for_size (POINTER_SIZE, 0),
00391 expr));
00392
00393 return convert_to_integer (type, expr);
00394
00395 case INTEGER_TYPE:
00396 case ENUMERAL_TYPE:
00397 case BOOLEAN_TYPE:
00398 case CHAR_TYPE:
00399
00400
00401
00402 if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
00403 {
00404 expr = copy_node (expr);
00405 TREE_TYPE (expr) = type;
00406 return expr;
00407 }
00408
00409
00410
00411
00412
00413 else if (outprec >= inprec)
00414 {
00415 enum tree_code code;
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
00427 && (TYPE_PRECISION (TREE_TYPE (expr))
00428 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
00429 code = CONVERT_EXPR;
00430 else
00431 code = NOP_EXPR;
00432
00433 return build1 (code, type, expr);
00434 }
00435
00436
00437
00438
00439
00440 else if (TREE_CODE (type) == ENUMERAL_TYPE
00441 || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
00442 return build1 (NOP_EXPR, type,
00443 convert (lang_hooks.types.type_for_mode
00444 (TYPE_MODE (type), TYPE_UNSIGNED (type)),
00445 expr));
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 switch (ex_form)
00468 {
00469 case RSHIFT_EXPR:
00470
00471
00472 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
00473 && tree_int_cst_lt (TREE_OPERAND (expr, 1),
00474 convert (TREE_TYPE (TREE_OPERAND (expr, 1)),
00475 integer_one_node)))
00476 goto trunc1;
00477 break;
00478
00479 case LSHIFT_EXPR:
00480
00481
00482
00483 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
00484 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
00485 && TYPE_UNSIGNED (type)
00486 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
00487 {
00488
00489
00490 if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
00491
00492 goto trunc1;
00493 else
00494 {
00495
00496
00497
00498
00499
00500
00501 tree t = convert_to_integer (type, integer_zero_node);
00502
00503
00504
00505 if (TREE_SIDE_EFFECTS (expr))
00506 return build2 (COMPOUND_EXPR, type, expr, t);
00507 else
00508 return t;
00509 }
00510 }
00511 break;
00512
00513 case MAX_EXPR:
00514 case MIN_EXPR:
00515 case MULT_EXPR:
00516 {
00517 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
00518 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
00519
00520
00521
00522
00523 if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
00524 && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
00525
00526
00527 && (TYPE_UNSIGNED (TREE_TYPE (arg0))
00528 == TYPE_UNSIGNED (TREE_TYPE (arg1))))
00529 goto trunc1;
00530 break;
00531 }
00532
00533 case PLUS_EXPR:
00534 case MINUS_EXPR:
00535 case BIT_AND_EXPR:
00536 case BIT_IOR_EXPR:
00537 case BIT_XOR_EXPR:
00538 trunc1:
00539 {
00540 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
00541 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
00542
00543 if (outprec >= BITS_PER_WORD
00544 || TRULY_NOOP_TRUNCATION (outprec, inprec)
00545 || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
00546 || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
00547 {
00548
00549
00550 tree typex = type;
00551
00552
00553
00554 if (TREE_CODE (typex) == ENUMERAL_TYPE)
00555 typex = lang_hooks.types.type_for_size
00556 (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex));
00557
00558
00559
00560
00561 if (TYPE_PRECISION (typex) != inprec)
00562 {
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 if (TYPE_UNSIGNED (TREE_TYPE (expr))
00575 || (TYPE_UNSIGNED (TREE_TYPE (arg0))
00576 && (TYPE_UNSIGNED (TREE_TYPE (arg1))
00577 || ex_form == LSHIFT_EXPR
00578 || ex_form == RSHIFT_EXPR
00579 || ex_form == LROTATE_EXPR
00580 || ex_form == RROTATE_EXPR))
00581 || ex_form == LSHIFT_EXPR)
00582 typex = lang_hooks.types.unsigned_type (typex);
00583 else
00584 typex = lang_hooks.types.signed_type (typex);
00585 return convert (type,
00586 fold (build2 (ex_form, typex,
00587 convert (typex, arg0),
00588 convert (typex, arg1))));
00589 }
00590 }
00591 }
00592 break;
00593
00594 case NEGATE_EXPR:
00595 case BIT_NOT_EXPR:
00596
00597
00598 {
00599 tree typex = type;
00600
00601
00602
00603 if (TREE_CODE (typex) == ENUMERAL_TYPE)
00604 typex = lang_hooks.types.type_for_size
00605 (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex));
00606
00607
00608
00609
00610 if (TYPE_PRECISION (typex) != inprec)
00611 {
00612
00613
00614 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
00615 typex = lang_hooks.types.unsigned_type (typex);
00616 else
00617 typex = lang_hooks.types.signed_type (typex);
00618 return convert (type,
00619 fold (build1 (ex_form, typex,
00620 convert (typex,
00621 TREE_OPERAND (expr, 0)))));
00622 }
00623 }
00624
00625 case NOP_EXPR:
00626
00627
00628 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
00629 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
00630 != GET_MODE_SIZE (TYPE_MODE (type))))
00631 break;
00632
00633
00634 return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
00635
00636 case COND_EXPR:
00637
00638
00639 return fold (build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
00640 convert (type, TREE_OPERAND (expr, 1)),
00641 convert (type, TREE_OPERAND (expr, 2))));
00642
00643 default:
00644 break;
00645 }
00646
00647 return build1 (CONVERT_EXPR, type, expr);
00648
00649 case REAL_TYPE:
00650 return build1 (FIX_TRUNC_EXPR, type, expr);
00651
00652 case COMPLEX_TYPE:
00653 return convert (type,
00654 fold (build1 (REALPART_EXPR,
00655 TREE_TYPE (TREE_TYPE (expr)), expr)));
00656
00657 case VECTOR_TYPE:
00658 if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
00659 {
00660 error ("can't convert between vector values of different size");
00661 return error_mark_node;
00662 }
00663 return build1 (VIEW_CONVERT_EXPR, type, expr);
00664
00665 default:
00666 error ("aggregate value used where an integer was expected");
00667 return convert (type, integer_zero_node);
00668 }
00669 }
00670
00671
00672
00673 tree
00674 convert_to_complex (tree type, tree expr)
00675 {
00676 tree subtype = TREE_TYPE (type);
00677
00678 switch (TREE_CODE (TREE_TYPE (expr)))
00679 {
00680 case REAL_TYPE:
00681 case INTEGER_TYPE:
00682 case ENUMERAL_TYPE:
00683 case BOOLEAN_TYPE:
00684 case CHAR_TYPE:
00685 return build2 (COMPLEX_EXPR, type, convert (subtype, expr),
00686 convert (subtype, integer_zero_node));
00687
00688 case COMPLEX_TYPE:
00689 {
00690 tree elt_type = TREE_TYPE (TREE_TYPE (expr));
00691
00692 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
00693 return expr;
00694 else if (TREE_CODE (expr) == COMPLEX_EXPR)
00695 return fold (build2 (COMPLEX_EXPR, type,
00696 convert (subtype, TREE_OPERAND (expr, 0)),
00697 convert (subtype, TREE_OPERAND (expr, 1))));
00698 else
00699 {
00700 expr = save_expr (expr);
00701 return
00702 fold (build2 (COMPLEX_EXPR, type,
00703 convert (subtype,
00704 fold (build1 (REALPART_EXPR,
00705 TREE_TYPE (TREE_TYPE (expr)),
00706 expr))),
00707 convert (subtype,
00708 fold (build1 (IMAGPART_EXPR,
00709 TREE_TYPE (TREE_TYPE (expr)),
00710 expr)))));
00711 }
00712 }
00713
00714 case POINTER_TYPE:
00715 case REFERENCE_TYPE:
00716 error ("pointer value used where a complex was expected");
00717 return convert_to_complex (type, integer_zero_node);
00718
00719 default:
00720 error ("aggregate value used where a complex was expected");
00721 return convert_to_complex (type, integer_zero_node);
00722 }
00723 }
00724
00725
00726
00727 tree
00728 convert_to_vector (tree type, tree expr)
00729 {
00730 switch (TREE_CODE (TREE_TYPE (expr)))
00731 {
00732 case INTEGER_TYPE:
00733 case VECTOR_TYPE:
00734 if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
00735 {
00736 error ("can't convert between vector values of different size");
00737 return error_mark_node;
00738 }
00739 return build1 (VIEW_CONVERT_EXPR, type, expr);
00740
00741 default:
00742 error ("can't convert value to a vector");
00743 return error_mark_node;
00744 }
00745 }