OSDN Git Service

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