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
00030 #include "config.h"
00031 #include "system.h"
00032 #ifdef SGI_MONGOOSE
00033
00034 #include "rtl.h"
00035 #endif
00036 #include "tree.h"
00037 #include "flags.h"
00038 #include "convert.h"
00039 #include "toplev.h"
00040 #include "langhooks.h"
00041
00042
00043
00044
00045
00046
00047 tree
00048 convert_to_pointer (type, expr)
00049 tree type, expr;
00050 {
00051 if (integer_zerop (expr))
00052 {
00053 expr = build_int_2 (0, 0);
00054 TREE_TYPE (expr) = type;
00055 return expr;
00056 }
00057
00058 switch (TREE_CODE (TREE_TYPE (expr)))
00059 {
00060 case POINTER_TYPE:
00061 case REFERENCE_TYPE:
00062 return build1 (NOP_EXPR, type, expr);
00063
00064 case INTEGER_TYPE:
00065 case ENUMERAL_TYPE:
00066 case BOOLEAN_TYPE:
00067 case CHAR_TYPE:
00068 if (TYPE_PRECISION (TREE_TYPE (expr)) == POINTER_SIZE)
00069 return build1 (CONVERT_EXPR, type, expr);
00070
00071 return
00072 convert_to_pointer (type,
00073 convert ((*lang_hooks.types.type_for_size)
00074 (POINTER_SIZE, 0), expr));
00075
00076 default:
00077 error ("cannot convert to a pointer type");
00078 return convert_to_pointer (type, integer_zero_node);
00079 }
00080 }
00081
00082
00083
00084
00085
00086
00087 tree
00088 convert_to_real (type, expr)
00089 tree type, expr;
00090 {
00091 switch (TREE_CODE (TREE_TYPE (expr)))
00092 {
00093 case REAL_TYPE:
00094 return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
00095 type, expr);
00096
00097 case INTEGER_TYPE:
00098 case ENUMERAL_TYPE:
00099 case BOOLEAN_TYPE:
00100 case CHAR_TYPE:
00101 return build1 (FLOAT_EXPR, type, expr);
00102
00103 case COMPLEX_TYPE:
00104 return convert (type,
00105 fold (build1 (REALPART_EXPR,
00106 TREE_TYPE (TREE_TYPE (expr)), expr)));
00107
00108 case POINTER_TYPE:
00109 case REFERENCE_TYPE:
00110 error ("pointer value used where a floating point value was expected");
00111 return convert_to_real (type, integer_zero_node);
00112
00113 default:
00114 error ("aggregate value used where a float was expected");
00115 return convert_to_real (type, integer_zero_node);
00116 }
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 tree
00128 convert_to_integer (type, expr)
00129 tree type, expr;
00130 {
00131 enum tree_code ex_form = TREE_CODE (expr);
00132 tree intype = TREE_TYPE (expr);
00133 unsigned int inprec = TYPE_PRECISION (intype);
00134 unsigned int outprec = TYPE_PRECISION (type);
00135
00136
00137
00138 if (!COMPLETE_TYPE_P (type))
00139 {
00140 error ("conversion to incomplete type");
00141 return error_mark_node;
00142 }
00143
00144 switch (TREE_CODE (intype))
00145 {
00146 case POINTER_TYPE:
00147 case REFERENCE_TYPE:
00148 if (integer_zerop (expr))
00149 expr = integer_zero_node;
00150 else
00151 expr = fold (build1 (CONVERT_EXPR, (*lang_hooks.types.type_for_size)
00152 (POINTER_SIZE, 0), expr));
00153
00154 return convert_to_integer (type, expr);
00155
00156 case INTEGER_TYPE:
00157 case ENUMERAL_TYPE:
00158 case BOOLEAN_TYPE:
00159 case CHAR_TYPE:
00160
00161
00162
00163
00164
00165 if (TREE_CODE_CLASS (ex_form) == '<')
00166 {
00167 expr = copy_node (expr);
00168 TREE_TYPE (expr) = type;
00169 return expr;
00170 }
00171
00172 else if (ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR
00173 || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
00174 || ex_form == TRUTH_XOR_EXPR)
00175 {
00176 expr = copy_node (expr);
00177 TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
00178 TREE_OPERAND (expr, 1) = convert (type, TREE_OPERAND (expr, 1));
00179 TREE_TYPE (expr) = type;
00180 return expr;
00181 }
00182
00183 else if (ex_form == TRUTH_NOT_EXPR)
00184 {
00185 expr = copy_node (expr);
00186 TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
00187 TREE_TYPE (expr) = type;
00188 return expr;
00189 }
00190
00191
00192
00193
00194
00195 else if (outprec >= inprec)
00196 return build1 (NOP_EXPR, type, expr);
00197
00198
00199
00200
00201
00202 else if (TREE_CODE (type) == ENUMERAL_TYPE
00203 || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
00204 return build1 (NOP_EXPR, type,
00205 convert ((*lang_hooks.types.type_for_mode)
00206 (TYPE_MODE (type), TREE_UNSIGNED (type)),
00207 expr));
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 switch (ex_form)
00230 {
00231 case RSHIFT_EXPR:
00232
00233
00234 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
00235 && tree_int_cst_lt (TREE_OPERAND (expr, 1),
00236 convert (TREE_TYPE (TREE_OPERAND (expr, 1)),
00237 integer_one_node)))
00238 goto trunc1;
00239 break;
00240
00241 case LSHIFT_EXPR:
00242
00243
00244
00245 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
00246 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
00247 && TREE_UNSIGNED (type)
00248 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
00249 {
00250
00251
00252 if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
00253
00254 goto trunc1;
00255 else
00256 {
00257
00258
00259
00260
00261
00262
00263 tree t = convert_to_integer (type, integer_zero_node);
00264
00265
00266
00267 if (TREE_SIDE_EFFECTS (expr))
00268 return build (COMPOUND_EXPR, type, expr, t);
00269 else
00270 return t;
00271 }
00272 }
00273 break;
00274
00275 case MAX_EXPR:
00276 case MIN_EXPR:
00277 case MULT_EXPR:
00278 {
00279 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
00280 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
00281
00282
00283
00284
00285 if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
00286 && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
00287
00288
00289 && (TREE_UNSIGNED (TREE_TYPE (arg0))
00290 == TREE_UNSIGNED (TREE_TYPE (arg1))))
00291 goto trunc1;
00292 break;
00293 }
00294
00295 case PLUS_EXPR:
00296 case MINUS_EXPR:
00297 case BIT_AND_EXPR:
00298 case BIT_IOR_EXPR:
00299 case BIT_XOR_EXPR:
00300 case BIT_ANDTC_EXPR:
00301 trunc1:
00302 {
00303 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
00304 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
00305
00306 if (outprec >= BITS_PER_WORD
00307 || TRULY_NOOP_TRUNCATION (outprec, inprec)
00308 || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
00309 || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
00310 {
00311
00312
00313 tree typex = type;
00314
00315
00316
00317 if (TREE_CODE (typex) == ENUMERAL_TYPE)
00318 typex = (*lang_hooks.types.type_for_size)
00319 (TYPE_PRECISION (typex), TREE_UNSIGNED (typex));
00320
00321
00322
00323
00324 if (TYPE_PRECISION (typex) != inprec)
00325 {
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 if (TREE_UNSIGNED (TREE_TYPE (expr))
00338 || (TREE_UNSIGNED (TREE_TYPE (arg0))
00339 && (TREE_UNSIGNED (TREE_TYPE (arg1))
00340 || ex_form == LSHIFT_EXPR
00341 || ex_form == RSHIFT_EXPR
00342 || ex_form == LROTATE_EXPR
00343 || ex_form == RROTATE_EXPR))
00344 || ex_form == LSHIFT_EXPR)
00345 typex = (*lang_hooks.types.unsigned_type) (typex);
00346 else
00347 typex = (*lang_hooks.types.signed_type) (typex);
00348 return convert (type,
00349 fold (build (ex_form, typex,
00350 convert (typex, arg0),
00351 convert (typex, arg1),
00352 0)));
00353 }
00354 }
00355 }
00356 break;
00357
00358 case NEGATE_EXPR:
00359 case BIT_NOT_EXPR:
00360
00361
00362 {
00363 tree typex = type;
00364
00365
00366
00367 if (TREE_CODE (typex) == ENUMERAL_TYPE)
00368 typex = (*lang_hooks.types.type_for_size)
00369 (TYPE_PRECISION (typex), TREE_UNSIGNED (typex));
00370
00371
00372
00373
00374 if (TYPE_PRECISION (typex) != inprec)
00375 {
00376
00377
00378 if (TREE_UNSIGNED (TREE_TYPE (expr)))
00379 typex = (*lang_hooks.types.unsigned_type) (typex);
00380 else
00381 typex = (*lang_hooks.types.signed_type) (typex);
00382 return convert (type,
00383 fold (build1 (ex_form, typex,
00384 convert (typex,
00385 TREE_OPERAND (expr, 0)))));
00386 }
00387 }
00388
00389 case NOP_EXPR:
00390
00391
00392 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
00393 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
00394 != GET_MODE_SIZE (TYPE_MODE (type))))
00395 break;
00396
00397
00398 return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
00399
00400 case COND_EXPR:
00401
00402
00403 return fold (build (COND_EXPR, type, TREE_OPERAND (expr, 0),
00404 convert (type, TREE_OPERAND (expr, 1)),
00405 convert (type, TREE_OPERAND (expr, 2))));
00406
00407 default:
00408 break;
00409 }
00410
00411 return build1 (NOP_EXPR, type, expr);
00412
00413 case REAL_TYPE:
00414 return build1 (FIX_TRUNC_EXPR, type, expr);
00415
00416 case COMPLEX_TYPE:
00417 return convert (type,
00418 fold (build1 (REALPART_EXPR,
00419 TREE_TYPE (TREE_TYPE (expr)), expr)));
00420
00421 case VECTOR_TYPE:
00422 if (GET_MODE_SIZE (TYPE_MODE (type))
00423 != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
00424 {
00425 error ("can't convert between vector values of different size");
00426 return error_mark_node;
00427 }
00428 return build1 (NOP_EXPR, type, expr);
00429
00430 default:
00431 error ("aggregate value used where an integer was expected");
00432 return convert (type, integer_zero_node);
00433 }
00434 }
00435
00436
00437
00438 tree
00439 convert_to_complex (type, expr)
00440 tree type, expr;
00441 {
00442 tree subtype = TREE_TYPE (type);
00443
00444 switch (TREE_CODE (TREE_TYPE (expr)))
00445 {
00446 case REAL_TYPE:
00447 case INTEGER_TYPE:
00448 case ENUMERAL_TYPE:
00449 case BOOLEAN_TYPE:
00450 case CHAR_TYPE:
00451 return build (COMPLEX_EXPR, type, convert (subtype, expr),
00452 convert (subtype, integer_zero_node));
00453
00454 case COMPLEX_TYPE:
00455 {
00456 tree elt_type = TREE_TYPE (TREE_TYPE (expr));
00457
00458 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
00459 return expr;
00460 else if (TREE_CODE (expr) == COMPLEX_EXPR)
00461 return fold (build (COMPLEX_EXPR,
00462 type,
00463 convert (subtype, TREE_OPERAND (expr, 0)),
00464 convert (subtype, TREE_OPERAND (expr, 1))));
00465 else
00466 {
00467 expr = save_expr (expr);
00468 return
00469 fold (build (COMPLEX_EXPR,
00470 type, convert (subtype,
00471 fold (build1 (REALPART_EXPR,
00472 TREE_TYPE (TREE_TYPE (expr)),
00473 expr))),
00474 convert (subtype,
00475 fold (build1 (IMAGPART_EXPR,
00476 TREE_TYPE (TREE_TYPE (expr)),
00477 expr)))));
00478 }
00479 }
00480
00481 case POINTER_TYPE:
00482 case REFERENCE_TYPE:
00483 error ("pointer value used where a complex was expected");
00484 return convert_to_complex (type, integer_zero_node);
00485
00486 default:
00487 error ("aggregate value used where a complex was expected");
00488 return convert_to_complex (type, integer_zero_node);
00489 }
00490 }
00491
00492
00493
00494 tree
00495 convert_to_vector (type, expr)
00496 tree type, expr;
00497 {
00498 switch (TREE_CODE (TREE_TYPE (expr)))
00499 {
00500 case INTEGER_TYPE:
00501 case VECTOR_TYPE:
00502 if (GET_MODE_SIZE (TYPE_MODE (type))
00503 != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
00504 {
00505 error ("can't convert between vector values of different size");
00506 return error_mark_node;
00507 }
00508 return build1 (NOP_EXPR, type, expr);
00509
00510 default:
00511 error ("can't convert value to a vector");
00512 return convert_to_vector (type, integer_zero_node);
00513 }
00514 }