source: trunk/third/gcc/convert.c @ 8834

Revision 8834, 15.0 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* Utility routines for data type conversion for GNU C.
2   Copyright (C) 1987, 88, 91, 92, 94, 1995 Free Software Foundation, Inc.
3
4This file is part of GNU C.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
22/* These routines are somewhat language-independent utility function
23   intended to be called by the language-specific convert () functions. */
24
25#include "config.h"
26#include "tree.h"
27#include "flags.h"
28#include "convert.h"
29
30/* Convert EXPR to some pointer or reference type TYPE.
31
32   EXPR must be pointer, reference, integer, enumeral, or literal zero;
33   in other cases error is called. */
34
35tree
36convert_to_pointer (type, expr)
37     tree type, expr;
38{
39  register tree intype = TREE_TYPE (expr);
40  register enum tree_code form = TREE_CODE (intype);
41 
42  if (integer_zerop (expr))
43    {
44      expr = build_int_2 (0, 0);
45      TREE_TYPE (expr) = type;
46      return expr;
47    }
48
49  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
50    return build1 (NOP_EXPR, type, expr);
51
52
53  if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
54    {
55      if (type_precision (intype) == POINTER_SIZE)
56        return build1 (CONVERT_EXPR, type, expr);
57      expr = convert (type_for_size (POINTER_SIZE, 0), expr);
58      /* Modes may be different but sizes should be the same.  */
59      if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
60          != GET_MODE_SIZE (TYPE_MODE (type)))
61        /* There is supposed to be some integral type
62           that is the same width as a pointer.  */
63        abort ();
64      return convert_to_pointer (type, expr);
65    }
66
67  error ("cannot convert to a pointer type");
68
69  expr = build_int_2 (0, 0);
70  TREE_TYPE (expr) = type;
71  return expr;
72}
73
74/* Convert EXPR to some floating-point type TYPE.
75
76   EXPR must be float, integer, or enumeral;
77   in other cases error is called. */
78
79tree
80convert_to_real (type, expr)
81     tree type, expr;
82{
83  register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
84
85  if (form == REAL_TYPE)
86    return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
87                   type, expr);
88
89  if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
90    return build1 (FLOAT_EXPR, type, expr);
91
92  if (form == COMPLEX_TYPE)
93    return convert (type, fold (build1 (REALPART_EXPR,
94                                        TREE_TYPE (TREE_TYPE (expr)), expr)));
95
96  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
97    error ("pointer value used where a floating point value was expected");
98  else
99    error ("aggregate value used where a float was expected");
100
101  {
102    register tree tem = make_node (REAL_CST);
103    TREE_TYPE (tem) = type;
104    TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0", TYPE_MODE (type));
105    return tem;
106  }
107}
108
109/* Convert EXPR to some integer (or enum) type TYPE.
110
111   EXPR must be pointer, integer, discrete (enum, char, or bool), or float;
112   in other cases error is called.
113
114   The result of this is always supposed to be a newly created tree node
115   not in use in any existing structure.  */
116
117tree
118convert_to_integer (type, expr)
119     tree type, expr;
120{
121  register tree intype = TREE_TYPE (expr);
122  register enum tree_code form = TREE_CODE (intype);
123
124  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
125    {
126      if (integer_zerop (expr))
127        expr = integer_zero_node;
128      else
129        expr = fold (build1 (CONVERT_EXPR,
130                             type_for_size (POINTER_SIZE, 0), expr));
131      intype = TREE_TYPE (expr);
132      form = TREE_CODE (intype);
133      if (intype == type)
134        return expr;
135    }
136
137  if (form == INTEGER_TYPE || form == ENUMERAL_TYPE
138      || form == BOOLEAN_TYPE || form == CHAR_TYPE)
139    {
140      register unsigned outprec = TYPE_PRECISION (type);
141      register unsigned inprec = TYPE_PRECISION (intype);
142      register enum tree_code ex_form = TREE_CODE (expr);
143
144      /* If we are widening the type, put in an explicit conversion.
145         Similarly if we are not changing the width.  However, if this is
146         a logical operation that just returns 0 or 1, we can change the
147         type of the expression.  For logical operations, we must
148         also change the types of the operands to maintain type
149         correctness.  */
150
151      if (TREE_CODE_CLASS (ex_form) == '<')
152        {
153          TREE_TYPE (expr) = type;
154          return expr;
155        }
156      else if (ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR
157               || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
158               || ex_form == TRUTH_XOR_EXPR)
159        {
160          TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
161          TREE_OPERAND (expr, 1) = convert (type, TREE_OPERAND (expr, 1));
162          TREE_TYPE (expr) = type;
163          return expr;
164        }
165      else if (ex_form == TRUTH_NOT_EXPR)
166        {
167          TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
168          TREE_TYPE (expr) = type;
169          return expr;
170        }
171      else if (outprec >= inprec)
172        return build1 (NOP_EXPR, type, expr);
173
174      /* If TYPE is an enumeral type or a type with a precision less
175         than the number of bits in its mode, do the conversion to the
176         type corresponding to its mode, then do a nop conversion
177         to TYPE.  */
178      else if (TREE_CODE (type) == ENUMERAL_TYPE
179               || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
180        return build1 (NOP_EXPR, type,
181                       convert (type_for_mode (TYPE_MODE (type),
182                                               TREE_UNSIGNED (type)),
183                                expr));
184
185      /* Here detect when we can distribute the truncation down past some
186         arithmetic.  For example, if adding two longs and converting to an
187         int, we can equally well convert both to ints and then add.
188         For the operations handled here, such truncation distribution
189         is always safe.
190         It is desirable in these cases:
191         1) when truncating down to full-word from a larger size
192         2) when truncating takes no work.
193         3) when at least one operand of the arithmetic has been extended
194         (as by C's default conversions).  In this case we need two conversions
195         if we do the arithmetic as already requested, so we might as well
196         truncate both and then combine.  Perhaps that way we need only one.
197
198         Note that in general we cannot do the arithmetic in a type
199         shorter than the desired result of conversion, even if the operands
200         are both extended from a shorter type, because they might overflow
201         if combined in that type.  The exceptions to this--the times when
202         two narrow values can be combined in their narrow type even to
203         make a wider result--are handled by "shorten" in build_binary_op.  */
204
205      switch (ex_form)
206        {
207        case RSHIFT_EXPR:
208          /* We can pass truncation down through right shifting
209             when the shift count is a nonpositive constant.  */
210          if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
211              && tree_int_cst_lt (TREE_OPERAND (expr, 1),
212                                  convert (TREE_TYPE (TREE_OPERAND (expr, 1)),
213                                           integer_one_node)))
214            goto trunc1;
215          break;
216
217        case LSHIFT_EXPR:
218          /* We can pass truncation down through left shifting
219             when the shift count is a nonnegative constant.  */
220          if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
221              && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
222              && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
223            {
224              /* If shift count is less than the width of the truncated type,
225                 really shift.  */
226              if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
227                /* In this case, shifting is like multiplication.  */
228                goto trunc1;
229              else
230                {
231                  /* If it is >= that width, result is zero.
232                     Handling this with trunc1 would give the wrong result:
233                     (int) ((long long) a << 32) is well defined (as 0)
234                     but (int) a << 32 is undefined and would get a
235                     warning.  */
236
237                  tree t = convert_to_integer (type, integer_zero_node);
238
239                  /* If the original expression had side-effects, we must
240                     preserve it.  */
241                  if (TREE_SIDE_EFFECTS (expr))
242                    return build (COMPOUND_EXPR, type, expr, t);
243                  else
244                    return t;
245                }
246            }
247          break;
248
249        case MAX_EXPR:
250        case MIN_EXPR:
251        case MULT_EXPR:
252          {
253            tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
254            tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
255
256            /* Don't distribute unless the output precision is at least as big
257               as the actual inputs.  Otherwise, the comparison of the
258               truncated values will be wrong.  */
259            if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
260                && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
261                /* If signedness of arg0 and arg1 don't match,
262                   we can't necessarily find a type to compare them in.  */
263                && (TREE_UNSIGNED (TREE_TYPE (arg0))
264                    == TREE_UNSIGNED (TREE_TYPE (arg1))))
265              goto trunc1;
266            break;
267          }
268
269        case PLUS_EXPR:
270        case MINUS_EXPR:
271        case BIT_AND_EXPR:
272        case BIT_IOR_EXPR:
273        case BIT_XOR_EXPR:
274        case BIT_ANDTC_EXPR:
275        trunc1:
276          {
277            tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
278            tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
279
280            if (outprec >= BITS_PER_WORD
281                || TRULY_NOOP_TRUNCATION (outprec, inprec)
282                || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
283                || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
284              {
285                /* Do the arithmetic in type TYPEX,
286                   then convert result to TYPE.  */
287                register tree typex = type;
288
289                /* Can't do arithmetic in enumeral types
290                   so use an integer type that will hold the values.  */
291                if (TREE_CODE (typex) == ENUMERAL_TYPE)
292                  typex = type_for_size (TYPE_PRECISION (typex),
293                                         TREE_UNSIGNED (typex));
294
295                /* But now perhaps TYPEX is as wide as INPREC.
296                   In that case, do nothing special here.
297                   (Otherwise would recurse infinitely in convert.  */
298                if (TYPE_PRECISION (typex) != inprec)
299                  {
300                    /* Don't do unsigned arithmetic where signed was wanted,
301                       or vice versa.
302                       Exception: if either of the original operands were
303                       unsigned then can safely do the work as unsigned.
304                       And we may need to do it as unsigned
305                       if we truncate to the original size.  */
306                    typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
307                              || TREE_UNSIGNED (TREE_TYPE (arg0))
308                              || TREE_UNSIGNED (TREE_TYPE (arg1)))
309                             ? unsigned_type (typex) : signed_type (typex));
310                    return convert (type,
311                                    fold (build (ex_form, typex,
312                                                 convert (typex, arg0),
313                                                 convert (typex, arg1),
314                                                 0)));
315                  }
316              }
317          }
318          break;
319
320        case NEGATE_EXPR:
321        case BIT_NOT_EXPR:
322          /* This is not correct for ABS_EXPR,
323             since we must test the sign before truncation.  */
324          {
325            register tree typex = type;
326
327            /* Can't do arithmetic in enumeral types
328               so use an integer type that will hold the values.  */
329            if (TREE_CODE (typex) == ENUMERAL_TYPE)
330              typex = type_for_size (TYPE_PRECISION (typex),
331                                     TREE_UNSIGNED (typex));
332
333            /* But now perhaps TYPEX is as wide as INPREC.
334               In that case, do nothing special here.
335               (Otherwise would recurse infinitely in convert.  */
336            if (TYPE_PRECISION (typex) != inprec)
337              {
338                /* Don't do unsigned arithmetic where signed was wanted,
339                   or vice versa.  */
340                typex = (TREE_UNSIGNED (TREE_TYPE (expr))
341                         ? unsigned_type (typex) : signed_type (typex));
342                return convert (type,
343                                fold (build1 (ex_form, typex,
344                                              convert (typex,
345                                                       TREE_OPERAND (expr, 0)))));
346              }
347          }
348
349        case NOP_EXPR:
350          /* If truncating after truncating, might as well do all at once.
351             If truncating after extending, we may get rid of wasted work.  */
352          return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
353
354        case COND_EXPR:
355          /* Can treat the two alternative values like the operands
356             of an arithmetic expression.  */
357          {
358            tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
359            tree arg2 = get_unwidened (TREE_OPERAND (expr, 2), type);
360
361            if (outprec >= BITS_PER_WORD
362                || TRULY_NOOP_TRUNCATION (outprec, inprec)
363                || inprec > TYPE_PRECISION (TREE_TYPE (arg1))
364                || inprec > TYPE_PRECISION (TREE_TYPE (arg2)))
365              {
366                /* Do the arithmetic in type TYPEX,
367                   then convert result to TYPE.  */
368                register tree typex = type;
369
370                /* Can't do arithmetic in enumeral types
371                   so use an integer type that will hold the values.  */
372                if (TREE_CODE (typex) == ENUMERAL_TYPE)
373                  typex = type_for_size (TYPE_PRECISION (typex),
374                                         TREE_UNSIGNED (typex));
375
376                /* But now perhaps TYPEX is as wide as INPREC.
377                   In that case, do nothing special here.
378                   (Otherwise would recurse infinitely in convert.  */
379                if (TYPE_PRECISION (typex) != inprec)
380                  {
381                    /* Don't do unsigned arithmetic where signed was wanted,
382                       or vice versa.  */
383                    typex = (TREE_UNSIGNED (TREE_TYPE (expr))
384                             ? unsigned_type (typex) : signed_type (typex));
385                    return convert (type,
386                                    fold (build (COND_EXPR, typex,
387                                                 TREE_OPERAND (expr, 0),
388                                                 convert (typex, arg1),
389                                                 convert (typex, arg2))));
390                  }
391                else
392                  /* It is sometimes worthwhile
393                     to push the narrowing down through the conditional.  */
394                  return fold (build (COND_EXPR, type,
395                                      TREE_OPERAND (expr, 0),
396                                      convert (type, TREE_OPERAND (expr, 1)),
397                                      convert (type, TREE_OPERAND (expr, 2))));
398              }
399          }
400
401        }
402
403      return build1 (NOP_EXPR, type, expr);
404    }
405
406  if (form == REAL_TYPE)
407    return build1 (FIX_TRUNC_EXPR, type, expr);
408
409  if (form == COMPLEX_TYPE)
410    return convert (type, fold (build1 (REALPART_EXPR,
411                                        TREE_TYPE (TREE_TYPE (expr)), expr)));
412
413  error ("aggregate value used where an integer was expected");
414
415  {
416    register tree tem = build_int_2 (0, 0);
417    TREE_TYPE (tem) = type;
418    return tem;
419  }
420}
421
422/* Convert EXPR to the complex type TYPE in the usual ways.  */
423
424tree
425convert_to_complex (type, expr)
426     tree type, expr;
427{
428  register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
429  tree subtype = TREE_TYPE (type);
430 
431  if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
432    {
433      expr = convert (subtype, expr);
434      return build (COMPLEX_EXPR, type, expr,
435                    convert (subtype, integer_zero_node));
436    }
437
438  if (form == COMPLEX_TYPE)
439    {
440      tree elt_type = TREE_TYPE (TREE_TYPE (expr));
441      if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
442        return expr;
443      else if (TREE_CODE (expr) == COMPLEX_EXPR)
444        return fold (build (COMPLEX_EXPR,
445                            type,
446                            convert (subtype, TREE_OPERAND (expr, 0)),
447                            convert (subtype, TREE_OPERAND (expr, 1))));
448      else
449        {
450          expr = save_expr (expr);
451          return fold (build (COMPLEX_EXPR,
452                              type,
453                              convert (subtype,
454                                       fold (build1 (REALPART_EXPR,
455                                                     TREE_TYPE (TREE_TYPE (expr)),
456                                                     expr))),
457                              convert (subtype,
458                                       fold (build1 (IMAGPART_EXPR,
459                                                     TREE_TYPE (TREE_TYPE (expr)),
460                                                     expr)))));
461        }
462    }
463
464  if (form == POINTER_TYPE || form == REFERENCE_TYPE)
465    error ("pointer value used where a complex was expected");
466  else
467    error ("aggregate value used where a complex was expected");
468 
469  return build (COMPLEX_EXPR, type,
470                convert (subtype, integer_zero_node),
471                convert (subtype, integer_zero_node));
472}
Note: See TracBrowser for help on using the repository browser.