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