]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/convert.c
* convert.c (convert_to_real): Reformat using switch stmt.
[thirdparty/gcc.git] / gcc / convert.c
CommitLineData
5e6908ea 1/* Utility routines for data type conversion for GCC.
78bd5210 2 Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
2a9f2ad3 3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
76e616db 4
1322177d 5This file is part of GCC.
76e616db 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
76e616db 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
76e616db
BK
16
17You should have received a copy of the GNU General Public License
1322177d
LB
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
76e616db
BK
21
22
23/* These routines are somewhat language-independent utility function
0f41302f 24 intended to be called by the language-specific convert () functions. */
76e616db
BK
25
26#include "config.h"
c5c76735 27#include "system.h"
4977bab6
ZW
28#include "coretypes.h"
29#include "tm.h"
76e616db
BK
30#include "tree.h"
31#include "flags.h"
32#include "convert.h"
10f0ad3d 33#include "toplev.h"
b0c48229 34#include "langhooks.h"
77f9af81 35#include "real.h"
98c76e3c 36/* Convert EXPR to some pointer or reference type TYPE.
76e616db 37
98c76e3c 38 EXPR must be pointer, reference, integer, enumeral, or literal zero;
0f41302f 39 in other cases error is called. */
76e616db
BK
40
41tree
159b3be1 42convert_to_pointer (tree type, tree expr)
76e616db 43{
76e616db
BK
44 if (integer_zerop (expr))
45 {
76e616db
BK
46 expr = build_int_2 (0, 0);
47 TREE_TYPE (expr) = type;
48 return expr;
49 }
50
f5963e61 51 switch (TREE_CODE (TREE_TYPE (expr)))
76e616db 52 {
f5963e61
JL
53 case POINTER_TYPE:
54 case REFERENCE_TYPE:
55 return build1 (NOP_EXPR, type, expr);
56
57 case INTEGER_TYPE:
58 case ENUMERAL_TYPE:
59 case BOOLEAN_TYPE:
60 case CHAR_TYPE:
61 if (TYPE_PRECISION (TREE_TYPE (expr)) == POINTER_SIZE)
76e616db 62 return build1 (CONVERT_EXPR, type, expr);
76e616db 63
f5963e61
JL
64 return
65 convert_to_pointer (type,
ae2bcd98 66 convert (lang_hooks.types.type_for_size
b0c48229 67 (POINTER_SIZE, 0), expr));
76e616db 68
f5963e61
JL
69 default:
70 error ("cannot convert to a pointer type");
71 return convert_to_pointer (type, integer_zero_node);
72 }
76e616db
BK
73}
74
4977bab6 75/* Avoid any floating point extensions from EXP. */
77f9af81 76tree
159b3be1 77strip_float_extensions (tree exp)
4977bab6
ZW
78{
79 tree sub, expt, subt;
80
77f9af81
JH
81 /* For floating point constant look up the narrowest type that can hold
82 it properly and handle it like (type)(narrowest_type)constant.
83 This way we can optimize for instance a=a*2.0 where "a" is float
84 but 2.0 is double constant. */
85 if (TREE_CODE (exp) == REAL_CST)
86 {
87 REAL_VALUE_TYPE orig;
88 tree type = NULL;
89
90 orig = TREE_REAL_CST (exp);
91 if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
92 && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
93 type = float_type_node;
94 else if (TYPE_PRECISION (TREE_TYPE (exp))
95 > TYPE_PRECISION (double_type_node)
96 && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
97 type = double_type_node;
98 if (type)
99 return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
100 }
101
4977bab6
ZW
102 if (TREE_CODE (exp) != NOP_EXPR)
103 return exp;
104
105 sub = TREE_OPERAND (exp, 0);
106 subt = TREE_TYPE (sub);
107 expt = TREE_TYPE (exp);
108
109 if (!FLOAT_TYPE_P (subt))
110 return exp;
111
112 if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
113 return exp;
114
115 return strip_float_extensions (sub);
116}
117
118
76e616db
BK
119/* Convert EXPR to some floating-point type TYPE.
120
121 EXPR must be float, integer, or enumeral;
0f41302f 122 in other cases error is called. */
76e616db
BK
123
124tree
159b3be1 125convert_to_real (tree type, tree expr)
76e616db 126{
27a6aa72 127 enum built_in_function fcode = builtin_mathfn_code (expr);
4977bab6
ZW
128 tree itype = TREE_TYPE (expr);
129
4b207444
JH
130 /* Disable until we figure out how to decide whether the functions are
131 present in runtime. */
4977bab6 132 /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
78bd5210 133 if (optimize
4977bab6
ZW
134 && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
135 || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
136 {
b3810360
KG
137 switch (fcode)
138 {
139#define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
140 CASE_MATHFN (SQRT)
141 CASE_MATHFN (SIN)
142 CASE_MATHFN (COS)
143 CASE_MATHFN (EXP)
144 CASE_MATHFN (LOG)
145#undef CASE_MATHFN
4977bab6 146 {
b3810360
KG
147 tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
148 tree newtype = type;
149
150 /* We have (outertype)sqrt((innertype)x). Choose the wider mode from
151 the both as the safe type for operation. */
152 if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
153 newtype = TREE_TYPE (arg0);
154
155 /* Be careful about integer to fp conversions.
156 These may overflow still. */
157 if (FLOAT_TYPE_P (TREE_TYPE (arg0))
158 && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
159 && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
160 || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
161 {
162 tree arglist;
163 tree fn = mathfn_built_in (newtype, fcode);
164
165 if (fn)
166 {
167 arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
168 expr = build_function_call_expr (fn, arglist);
169 if (newtype == type)
170 return expr;
171 }
172 }
4977bab6 173 }
b3810360
KG
174 default:
175 break;
4977bab6
ZW
176 }
177 }
27a6aa72
JH
178 if (optimize
179 && (((fcode == BUILT_IN_FLOORL
180 || fcode == BUILT_IN_CEILL
b57051b2 181 || fcode == BUILT_IN_ROUNDL
d093738d 182 || fcode == BUILT_IN_RINTL
b57051b2
KG
183 || fcode == BUILT_IN_TRUNCL
184 || fcode == BUILT_IN_NEARBYINTL)
27a6aa72
JH
185 && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
186 || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
187 || ((fcode == BUILT_IN_FLOOR
188 || fcode == BUILT_IN_CEIL
189 || fcode == BUILT_IN_ROUND
d093738d 190 || fcode == BUILT_IN_RINT
27a6aa72
JH
191 || fcode == BUILT_IN_TRUNC
192 || fcode == BUILT_IN_NEARBYINT)
193 && (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
194 {
195 tree fn = mathfn_built_in (type, fcode);
196
197 if (fn)
198 {
199 tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr,
159b3be1 200 1)));
27a6aa72 201 tree arglist = build_tree_list (NULL_TREE,
159b3be1 202 fold (convert_to_real (type, arg0)));
27a6aa72
JH
203
204 return build_function_call_expr (fn, arglist);
205 }
206 }
4977bab6
ZW
207
208 /* Propagate the cast into the operation. */
209 if (itype != type && FLOAT_TYPE_P (type))
210 switch (TREE_CODE (expr))
211 {
beb235f8 212 /* Convert (float)-x into -(float)x. This is always safe. */
4977bab6
ZW
213 case ABS_EXPR:
214 case NEGATE_EXPR:
b1a6f8db
JH
215 if (TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (expr)))
216 return build1 (TREE_CODE (expr), type,
217 fold (convert_to_real (type,
218 TREE_OPERAND (expr, 0))));
219 break;
beb235f8 220 /* Convert (outertype)((innertype0)a+(innertype1)b)
4977bab6
ZW
221 into ((newtype)a+(newtype)b) where newtype
222 is the widest mode from all of these. */
223 case PLUS_EXPR:
224 case MINUS_EXPR:
225 case MULT_EXPR:
226 case RDIV_EXPR:
227 {
228 tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
229 tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
230
231 if (FLOAT_TYPE_P (TREE_TYPE (arg0))
232 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
233 {
234 tree newtype = type;
235 if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
236 newtype = TREE_TYPE (arg0);
237 if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
238 newtype = TREE_TYPE (arg1);
239 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
240 {
241 expr = build (TREE_CODE (expr), newtype,
242 fold (convert_to_real (newtype, arg0)),
243 fold (convert_to_real (newtype, arg1)));
244 if (newtype == type)
245 return expr;
246 }
247 }
248 }
249 break;
250 default:
251 break;
252 }
253
f5963e61
JL
254 switch (TREE_CODE (TREE_TYPE (expr)))
255 {
256 case REAL_TYPE:
257 return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
258 type, expr);
259
260 case INTEGER_TYPE:
261 case ENUMERAL_TYPE:
262 case BOOLEAN_TYPE:
263 case CHAR_TYPE:
264 return build1 (FLOAT_EXPR, type, expr);
265
266 case COMPLEX_TYPE:
267 return convert (type,
268 fold (build1 (REALPART_EXPR,
269 TREE_TYPE (TREE_TYPE (expr)), expr)));
270
271 case POINTER_TYPE:
272 case REFERENCE_TYPE:
273 error ("pointer value used where a floating point value was expected");
274 return convert_to_real (type, integer_zero_node);
275
276 default:
277 error ("aggregate value used where a float was expected");
278 return convert_to_real (type, integer_zero_node);
279 }
76e616db
BK
280}
281
282/* Convert EXPR to some integer (or enum) type TYPE.
283
0b4565c9
BS
284 EXPR must be pointer, integer, discrete (enum, char, or bool), float, or
285 vector; in other cases error is called.
76e616db
BK
286
287 The result of this is always supposed to be a newly created tree node
288 not in use in any existing structure. */
289
290tree
159b3be1 291convert_to_integer (tree type, tree expr)
76e616db 292{
f5963e61
JL
293 enum tree_code ex_form = TREE_CODE (expr);
294 tree intype = TREE_TYPE (expr);
770ae6cc
RK
295 unsigned int inprec = TYPE_PRECISION (intype);
296 unsigned int outprec = TYPE_PRECISION (type);
76e616db 297
9c4cb3a3
MM
298 /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
299 be. Consider `enum E = { a, b = (enum E) 3 };'. */
d0f062fb 300 if (!COMPLETE_TYPE_P (type))
9c4cb3a3
MM
301 {
302 error ("conversion to incomplete type");
303 return error_mark_node;
304 }
305
f5963e61 306 switch (TREE_CODE (intype))
76e616db 307 {
f5963e61
JL
308 case POINTER_TYPE:
309 case REFERENCE_TYPE:
76e616db
BK
310 if (integer_zerop (expr))
311 expr = integer_zero_node;
312 else
ae2bcd98
RS
313 expr = fold (build1 (CONVERT_EXPR,
314 lang_hooks.types.type_for_size (POINTER_SIZE, 0),
315 expr));
76e616db 316
f5963e61 317 return convert_to_integer (type, expr);
76e616db 318
f5963e61
JL
319 case INTEGER_TYPE:
320 case ENUMERAL_TYPE:
321 case BOOLEAN_TYPE:
322 case CHAR_TYPE:
323 /* If this is a logical operation, which just returns 0 or 1, we can
324 change the type of the expression. For some logical operations,
325 we must also change the types of the operands to maintain type
c9529354 326 correctness. */
76e616db 327
c9529354 328 if (TREE_CODE_CLASS (ex_form) == '<')
76e616db 329 {
5dfa45d0 330 expr = copy_node (expr);
76e616db
BK
331 TREE_TYPE (expr) = type;
332 return expr;
333 }
f5963e61 334
c9529354
RK
335 else if (ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR
336 || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
337 || ex_form == TRUTH_XOR_EXPR)
338 {
5dfa45d0 339 expr = copy_node (expr);
c9529354
RK
340 TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
341 TREE_OPERAND (expr, 1) = convert (type, TREE_OPERAND (expr, 1));
342 TREE_TYPE (expr) = type;
343 return expr;
344 }
f5963e61 345
c9529354
RK
346 else if (ex_form == TRUTH_NOT_EXPR)
347 {
5dfa45d0 348 expr = copy_node (expr);
c9529354
RK
349 TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
350 TREE_TYPE (expr) = type;
351 return expr;
352 }
f5963e61
JL
353
354 /* If we are widening the type, put in an explicit conversion.
355 Similarly if we are not changing the width. After this, we know
356 we are truncating EXPR. */
357
76e616db 358 else if (outprec >= inprec)
4b0d3cbe
MM
359 {
360 enum tree_code code;
361
362 /* If the precision of the EXPR's type is K bits and the
363 destination mode has more bits, and the sign is changing,
364 it is not safe to use a NOP_EXPR. For example, suppose
365 that EXPR's type is a 3-bit unsigned integer type, the
366 TYPE is a 3-bit signed integer type, and the machine mode
367 for the types is 8-bit QImode. In that case, the
368 conversion necessitates an explicit sign-extension. In
369 the signed-to-unsigned case the high-order bits have to
370 be cleared. */
371 if (TREE_UNSIGNED (type) != TREE_UNSIGNED (TREE_TYPE (expr))
372 && (TYPE_PRECISION (TREE_TYPE (expr))
373 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
374 code = CONVERT_EXPR;
375 else
376 code = NOP_EXPR;
377
378 return build1 (code, type, expr);
379 }
76e616db 380
1c013b45
RK
381 /* If TYPE is an enumeral type or a type with a precision less
382 than the number of bits in its mode, do the conversion to the
383 type corresponding to its mode, then do a nop conversion
384 to TYPE. */
385 else if (TREE_CODE (type) == ENUMERAL_TYPE
386 || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
387 return build1 (NOP_EXPR, type,
ae2bcd98 388 convert (lang_hooks.types.type_for_mode
b0c48229 389 (TYPE_MODE (type), TREE_UNSIGNED (type)),
1c013b45
RK
390 expr));
391
ab29fdfc
RK
392 /* Here detect when we can distribute the truncation down past some
393 arithmetic. For example, if adding two longs and converting to an
394 int, we can equally well convert both to ints and then add.
395 For the operations handled here, such truncation distribution
396 is always safe.
397 It is desirable in these cases:
398 1) when truncating down to full-word from a larger size
399 2) when truncating takes no work.
400 3) when at least one operand of the arithmetic has been extended
401 (as by C's default conversions). In this case we need two conversions
402 if we do the arithmetic as already requested, so we might as well
403 truncate both and then combine. Perhaps that way we need only one.
404
405 Note that in general we cannot do the arithmetic in a type
406 shorter than the desired result of conversion, even if the operands
407 are both extended from a shorter type, because they might overflow
408 if combined in that type. The exceptions to this--the times when
409 two narrow values can be combined in their narrow type even to
410 make a wider result--are handled by "shorten" in build_binary_op. */
76e616db
BK
411
412 switch (ex_form)
413 {
414 case RSHIFT_EXPR:
415 /* We can pass truncation down through right shifting
416 when the shift count is a nonpositive constant. */
417 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
ab29fdfc
RK
418 && tree_int_cst_lt (TREE_OPERAND (expr, 1),
419 convert (TREE_TYPE (TREE_OPERAND (expr, 1)),
420 integer_one_node)))
76e616db
BK
421 goto trunc1;
422 break;
423
424 case LSHIFT_EXPR:
425 /* We can pass truncation down through left shifting
43e4a9d8
EB
426 when the shift count is a nonnegative constant and
427 the target type is unsigned. */
76e616db 428 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
ab29fdfc 429 && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
43e4a9d8 430 && TREE_UNSIGNED (type)
76e616db
BK
431 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
432 {
433 /* If shift count is less than the width of the truncated type,
434 really shift. */
435 if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
436 /* In this case, shifting is like multiplication. */
437 goto trunc1;
438 else
d9a9c5a7
RK
439 {
440 /* If it is >= that width, result is zero.
441 Handling this with trunc1 would give the wrong result:
442 (int) ((long long) a << 32) is well defined (as 0)
443 but (int) a << 32 is undefined and would get a
444 warning. */
445
446 tree t = convert_to_integer (type, integer_zero_node);
447
448 /* If the original expression had side-effects, we must
449 preserve it. */
450 if (TREE_SIDE_EFFECTS (expr))
451 return build (COMPOUND_EXPR, type, expr, t);
452 else
453 return t;
454 }
76e616db
BK
455 }
456 break;
457
458 case MAX_EXPR:
459 case MIN_EXPR:
460 case MULT_EXPR:
461 {
462 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
463 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
464
465 /* Don't distribute unless the output precision is at least as big
466 as the actual inputs. Otherwise, the comparison of the
467 truncated values will be wrong. */
468 if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
469 && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
470 /* If signedness of arg0 and arg1 don't match,
471 we can't necessarily find a type to compare them in. */
472 && (TREE_UNSIGNED (TREE_TYPE (arg0))
473 == TREE_UNSIGNED (TREE_TYPE (arg1))))
474 goto trunc1;
475 break;
476 }
477
478 case PLUS_EXPR:
479 case MINUS_EXPR:
480 case BIT_AND_EXPR:
481 case BIT_IOR_EXPR:
482 case BIT_XOR_EXPR:
76e616db
BK
483 trunc1:
484 {
485 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
486 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
487
488 if (outprec >= BITS_PER_WORD
489 || TRULY_NOOP_TRUNCATION (outprec, inprec)
490 || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
491 || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
492 {
493 /* Do the arithmetic in type TYPEX,
494 then convert result to TYPE. */
b3694847 495 tree typex = type;
76e616db
BK
496
497 /* Can't do arithmetic in enumeral types
498 so use an integer type that will hold the values. */
499 if (TREE_CODE (typex) == ENUMERAL_TYPE)
ae2bcd98 500 typex = lang_hooks.types.type_for_size
b0c48229 501 (TYPE_PRECISION (typex), TREE_UNSIGNED (typex));
76e616db
BK
502
503 /* But now perhaps TYPEX is as wide as INPREC.
504 In that case, do nothing special here.
505 (Otherwise would recurse infinitely in convert. */
506 if (TYPE_PRECISION (typex) != inprec)
507 {
508 /* Don't do unsigned arithmetic where signed was wanted,
509 or vice versa.
3cc247a8 510 Exception: if both of the original operands were
159b3be1 511 unsigned then we can safely do the work as unsigned.
43e4a9d8
EB
512 Exception: shift operations take their type solely
513 from the first argument.
514 Exception: the LSHIFT_EXPR case above requires that
515 we perform this operation unsigned lest we produce
516 signed-overflow undefinedness.
76e616db
BK
517 And we may need to do it as unsigned
518 if we truncate to the original size. */
ceef8ce4
NB
519 if (TREE_UNSIGNED (TREE_TYPE (expr))
520 || (TREE_UNSIGNED (TREE_TYPE (arg0))
43e4a9d8
EB
521 && (TREE_UNSIGNED (TREE_TYPE (arg1))
522 || ex_form == LSHIFT_EXPR
523 || ex_form == RSHIFT_EXPR
524 || ex_form == LROTATE_EXPR
525 || ex_form == RROTATE_EXPR))
526 || ex_form == LSHIFT_EXPR)
ae2bcd98 527 typex = lang_hooks.types.unsigned_type (typex);
ceef8ce4 528 else
ae2bcd98 529 typex = lang_hooks.types.signed_type (typex);
76e616db 530 return convert (type,
95e78909
RK
531 fold (build (ex_form, typex,
532 convert (typex, arg0),
4221057e 533 convert (typex, arg1))));
76e616db
BK
534 }
535 }
536 }
537 break;
538
539 case NEGATE_EXPR:
540 case BIT_NOT_EXPR:
d283912a
RS
541 /* This is not correct for ABS_EXPR,
542 since we must test the sign before truncation. */
76e616db 543 {
b3694847 544 tree typex = type;
76e616db
BK
545
546 /* Can't do arithmetic in enumeral types
547 so use an integer type that will hold the values. */
548 if (TREE_CODE (typex) == ENUMERAL_TYPE)
ae2bcd98 549 typex = lang_hooks.types.type_for_size
b0c48229 550 (TYPE_PRECISION (typex), TREE_UNSIGNED (typex));
76e616db
BK
551
552 /* But now perhaps TYPEX is as wide as INPREC.
553 In that case, do nothing special here.
554 (Otherwise would recurse infinitely in convert. */
555 if (TYPE_PRECISION (typex) != inprec)
556 {
557 /* Don't do unsigned arithmetic where signed was wanted,
558 or vice versa. */
ceef8ce4 559 if (TREE_UNSIGNED (TREE_TYPE (expr)))
ae2bcd98 560 typex = lang_hooks.types.unsigned_type (typex);
ceef8ce4 561 else
ae2bcd98 562 typex = lang_hooks.types.signed_type (typex);
76e616db 563 return convert (type,
95e78909
RK
564 fold (build1 (ex_form, typex,
565 convert (typex,
566 TREE_OPERAND (expr, 0)))));
76e616db
BK
567 }
568 }
569
570 case NOP_EXPR:
3767c0fd
R
571 /* Don't introduce a
572 "can't convert between vector values of different size" error. */
573 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
574 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
575 != GET_MODE_SIZE (TYPE_MODE (type))))
576 break;
76e616db
BK
577 /* If truncating after truncating, might as well do all at once.
578 If truncating after extending, we may get rid of wasted work. */
579 return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
580
581 case COND_EXPR:
f5963e61
JL
582 /* It is sometimes worthwhile to push the narrowing down through
583 the conditional and never loses. */
584 return fold (build (COND_EXPR, type, TREE_OPERAND (expr, 0),
159b3be1 585 convert (type, TREE_OPERAND (expr, 1)),
f5963e61 586 convert (type, TREE_OPERAND (expr, 2))));
76e616db 587
31031edd
JL
588 default:
589 break;
76e616db
BK
590 }
591
592 return build1 (NOP_EXPR, type, expr);
76e616db 593
f5963e61
JL
594 case REAL_TYPE:
595 return build1 (FIX_TRUNC_EXPR, type, expr);
76e616db 596
f5963e61
JL
597 case COMPLEX_TYPE:
598 return convert (type,
599 fold (build1 (REALPART_EXPR,
600 TREE_TYPE (TREE_TYPE (expr)), expr)));
0b127821 601
0b4565c9
BS
602 case VECTOR_TYPE:
603 if (GET_MODE_SIZE (TYPE_MODE (type))
604 != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
605 {
606 error ("can't convert between vector values of different size");
607 return error_mark_node;
608 }
609 return build1 (NOP_EXPR, type, expr);
610
f5963e61
JL
611 default:
612 error ("aggregate value used where an integer was expected");
613 return convert (type, integer_zero_node);
614 }
76e616db 615}
0b127821
RS
616
617/* Convert EXPR to the complex type TYPE in the usual ways. */
618
619tree
159b3be1 620convert_to_complex (tree type, tree expr)
0b127821 621{
0b127821 622 tree subtype = TREE_TYPE (type);
159b3be1 623
f5963e61 624 switch (TREE_CODE (TREE_TYPE (expr)))
0b127821 625 {
f5963e61
JL
626 case REAL_TYPE:
627 case INTEGER_TYPE:
628 case ENUMERAL_TYPE:
629 case BOOLEAN_TYPE:
630 case CHAR_TYPE:
631 return build (COMPLEX_EXPR, type, convert (subtype, expr),
0b127821 632 convert (subtype, integer_zero_node));
0b127821 633
f5963e61
JL
634 case COMPLEX_TYPE:
635 {
636 tree elt_type = TREE_TYPE (TREE_TYPE (expr));
637
638 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
639 return expr;
640 else if (TREE_CODE (expr) == COMPLEX_EXPR)
0b127821
RS
641 return fold (build (COMPLEX_EXPR,
642 type,
f5963e61
JL
643 convert (subtype, TREE_OPERAND (expr, 0)),
644 convert (subtype, TREE_OPERAND (expr, 1))));
645 else
646 {
647 expr = save_expr (expr);
648 return
649 fold (build (COMPLEX_EXPR,
650 type, convert (subtype,
651 fold (build1 (REALPART_EXPR,
652 TREE_TYPE (TREE_TYPE (expr)),
653 expr))),
654 convert (subtype,
655 fold (build1 (IMAGPART_EXPR,
656 TREE_TYPE (TREE_TYPE (expr)),
657 expr)))));
658 }
659 }
0b127821 660
f5963e61
JL
661 case POINTER_TYPE:
662 case REFERENCE_TYPE:
663 error ("pointer value used where a complex was expected");
664 return convert_to_complex (type, integer_zero_node);
665
666 default:
667 error ("aggregate value used where a complex was expected");
668 return convert_to_complex (type, integer_zero_node);
669 }
0b127821 670}
0b4565c9
BS
671
672/* Convert EXPR to the vector type TYPE in the usual ways. */
673
674tree
159b3be1 675convert_to_vector (tree type, tree expr)
0b4565c9 676{
0b4565c9
BS
677 switch (TREE_CODE (TREE_TYPE (expr)))
678 {
679 case INTEGER_TYPE:
680 case VECTOR_TYPE:
681 if (GET_MODE_SIZE (TYPE_MODE (type))
682 != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
683 {
684 error ("can't convert between vector values of different size");
685 return error_mark_node;
686 }
687 return build1 (NOP_EXPR, type, expr);
688
689 default:
690 error ("can't convert value to a vector");
691 return convert_to_vector (type, integer_zero_node);
692 }
693}