OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [convert.c] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* 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, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, 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
    return build_int_cst (type, 0);
46
 
47
  switch (TREE_CODE (TREE_TYPE (expr)))
48
    {
49
    case POINTER_TYPE:
50
    case REFERENCE_TYPE:
51
      return build1 (NOP_EXPR, type, expr);
52
 
53
    case INTEGER_TYPE:
54
    case ENUMERAL_TYPE:
55
    case BOOLEAN_TYPE:
56
    case CHAR_TYPE:
57
      if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE)
58
        expr = fold_build1 (NOP_EXPR,
59
                            lang_hooks.types.type_for_size (POINTER_SIZE, 0),
60
                            expr);
61
      return fold_build1 (CONVERT_EXPR, type, expr);
62
 
63
 
64
    default:
65
      error ("cannot convert to a pointer type");
66
      return convert_to_pointer (type, integer_zero_node);
67
    }
68
}
69
 
70
/* Avoid any floating point extensions from EXP.  */
71
tree
72
strip_float_extensions (tree exp)
73
{
74
  tree sub, expt, subt;
75
 
76
  /*  For floating point constant look up the narrowest type that can hold
77
      it properly and handle it like (type)(narrowest_type)constant.
78
      This way we can optimize for instance a=a*2.0 where "a" is float
79
      but 2.0 is double constant.  */
80
  if (TREE_CODE (exp) == REAL_CST)
81
    {
82
      REAL_VALUE_TYPE orig;
83
      tree type = NULL;
84
 
85
      orig = TREE_REAL_CST (exp);
86
      if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
87
          && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
88
        type = float_type_node;
89
      else if (TYPE_PRECISION (TREE_TYPE (exp))
90
               > TYPE_PRECISION (double_type_node)
91
               && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
92
        type = double_type_node;
93
      if (type)
94
        return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
95
    }
96
 
97
  if (TREE_CODE (exp) != NOP_EXPR
98
      && TREE_CODE (exp) != CONVERT_EXPR)
99
    return exp;
100
 
101
  sub = TREE_OPERAND (exp, 0);
102
  subt = TREE_TYPE (sub);
103
  expt = TREE_TYPE (exp);
104
 
105
  if (!FLOAT_TYPE_P (subt))
106
    return exp;
107
 
108
  if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
109
    return exp;
110
 
111
  return strip_float_extensions (sub);
112
}
113
 
114
 
115
/* Convert EXPR to some floating-point type TYPE.
116
 
117
   EXPR must be float, integer, or enumeral;
118
   in other cases error is called.  */
119
 
120
tree
121
convert_to_real (tree type, tree expr)
122
{
123
  enum built_in_function fcode = builtin_mathfn_code (expr);
124
  tree itype = TREE_TYPE (expr);
125
 
126
  /* Disable until we figure out how to decide whether the functions are
127
     present in runtime.  */
128
  /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
129
  if (optimize
130
      && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
131
          || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
132
    {
133
      switch (fcode)
134
        {
135
#define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
136
          CASE_MATHFN (ACOS)
137
          CASE_MATHFN (ACOSH)
138
          CASE_MATHFN (ASIN)
139
          CASE_MATHFN (ASINH)
140
          CASE_MATHFN (ATAN)
141
          CASE_MATHFN (ATANH)
142
          CASE_MATHFN (CBRT)
143
          CASE_MATHFN (COS)
144
          CASE_MATHFN (COSH)
145
          CASE_MATHFN (ERF)
146
          CASE_MATHFN (ERFC)
147
          CASE_MATHFN (EXP)
148
          CASE_MATHFN (EXP10)
149
          CASE_MATHFN (EXP2)
150
          CASE_MATHFN (EXPM1)
151
          CASE_MATHFN (FABS)
152
          CASE_MATHFN (GAMMA)
153
          CASE_MATHFN (J0)
154
          CASE_MATHFN (J1)
155
          CASE_MATHFN (LGAMMA)
156
          CASE_MATHFN (LOG)
157
          CASE_MATHFN (LOG10)
158
          CASE_MATHFN (LOG1P)
159
          CASE_MATHFN (LOG2)
160
          CASE_MATHFN (LOGB)
161
          CASE_MATHFN (POW10)
162
          CASE_MATHFN (SIN)
163
          CASE_MATHFN (SINH)
164
          CASE_MATHFN (SQRT)
165
          CASE_MATHFN (TAN)
166
          CASE_MATHFN (TANH)
167
          CASE_MATHFN (TGAMMA)
168
          CASE_MATHFN (Y0)
169
          CASE_MATHFN (Y1)
170
#undef CASE_MATHFN
171
            {
172
              tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
173
              tree newtype = type;
174
 
175
              /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
176
                 the both as the safe type for operation.  */
177
              if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
178
                newtype = TREE_TYPE (arg0);
179
 
180
              /* Be careful about integer to fp conversions.
181
                 These may overflow still.  */
182
              if (FLOAT_TYPE_P (TREE_TYPE (arg0))
183
                  && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
184
                  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
185
                      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
186
                {
187
                  tree arglist;
188
                  tree fn = mathfn_built_in (newtype, fcode);
189
 
190
                  if (fn)
191
                  {
192
                    arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
193
                    expr = build_function_call_expr (fn, arglist);
194
                    if (newtype == type)
195
                      return expr;
196
                  }
197
                }
198
            }
199
        default:
200
          break;
201
        }
202
    }
203
  if (optimize
204
      && (((fcode == BUILT_IN_FLOORL
205
           || fcode == BUILT_IN_CEILL
206
           || fcode == BUILT_IN_ROUNDL
207
           || fcode == BUILT_IN_RINTL
208
           || fcode == BUILT_IN_TRUNCL
209
           || fcode == BUILT_IN_NEARBYINTL)
210
          && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
211
              || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
212
          || ((fcode == BUILT_IN_FLOOR
213
               || fcode == BUILT_IN_CEIL
214
               || fcode == BUILT_IN_ROUND
215
               || fcode == BUILT_IN_RINT
216
               || fcode == BUILT_IN_TRUNC
217
               || fcode == BUILT_IN_NEARBYINT)
218
              && (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
219
    {
220
      tree fn = mathfn_built_in (type, fcode);
221
 
222
      if (fn)
223
        {
224
          tree arg
225
            = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
226
 
227
          /* Make sure (type)arg0 is an extension, otherwise we could end up
228
             changing (float)floor(double d) into floorf((float)d), which is
229
             incorrect because (float)d uses round-to-nearest and can round
230
             up to the next integer.  */
231
          if (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (arg)))
232
            return
233
              build_function_call_expr (fn,
234
                                        build_tree_list (NULL_TREE,
235
                                          fold (convert_to_real (type, arg))));
236
        }
237
    }
238
 
239
  /* Propagate the cast into the operation.  */
240
  if (itype != type && FLOAT_TYPE_P (type))
241
    switch (TREE_CODE (expr))
242
      {
243
        /* Convert (float)-x into -(float)x.  This is always safe.  */
244
        case ABS_EXPR:
245
        case NEGATE_EXPR:
246
          if (TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (expr)))
247
            return build1 (TREE_CODE (expr), type,
248
                           fold (convert_to_real (type,
249
                                                  TREE_OPERAND (expr, 0))));
250
          break;
251
        /* Convert (outertype)((innertype0)a+(innertype1)b)
252
           into ((newtype)a+(newtype)b) where newtype
253
           is the widest mode from all of these.  */
254
        case PLUS_EXPR:
255
        case MINUS_EXPR:
256
        case MULT_EXPR:
257
        case RDIV_EXPR:
258
           {
259
             tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
260
             tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
261
 
262
             if (FLOAT_TYPE_P (TREE_TYPE (arg0))
263
                 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
264
               {
265
                  tree newtype = type;
266
                  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
267
                    newtype = TREE_TYPE (arg0);
268
                  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
269
                    newtype = TREE_TYPE (arg1);
270
                  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
271
                    {
272
                      expr = build2 (TREE_CODE (expr), newtype,
273
                                     fold (convert_to_real (newtype, arg0)),
274
                                     fold (convert_to_real (newtype, arg1)));
275
                      if (newtype == type)
276
                        return expr;
277
                    }
278
               }
279
           }
280
          break;
281
        default:
282
          break;
283
      }
284
 
285
  switch (TREE_CODE (TREE_TYPE (expr)))
286
    {
287
    case REAL_TYPE:
288
      return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
289
                     type, expr);
290
 
291
    case INTEGER_TYPE:
292
    case ENUMERAL_TYPE:
293
    case BOOLEAN_TYPE:
294
    case CHAR_TYPE:
295
      return build1 (FLOAT_EXPR, type, expr);
296
 
297
    case COMPLEX_TYPE:
298
      return convert (type,
299
                      fold_build1 (REALPART_EXPR,
300
                                   TREE_TYPE (TREE_TYPE (expr)), expr));
301
 
302
    case POINTER_TYPE:
303
    case REFERENCE_TYPE:
304
      error ("pointer value used where a floating point value was expected");
305
      return convert_to_real (type, integer_zero_node);
306
 
307
    default:
308
      error ("aggregate value used where a float was expected");
309
      return convert_to_real (type, integer_zero_node);
310
    }
311
}
312
 
313
/* Convert EXPR to some integer (or enum) type TYPE.
314
 
315
   EXPR must be pointer, integer, discrete (enum, char, or bool), float, or
316
   vector; in other cases error is called.
317
 
318
   The result of this is always supposed to be a newly created tree node
319
   not in use in any existing structure.  */
320
 
321
tree
322
convert_to_integer (tree type, tree expr)
323
{
324
  enum tree_code ex_form = TREE_CODE (expr);
325
  tree intype = TREE_TYPE (expr);
326
  unsigned int inprec = TYPE_PRECISION (intype);
327
  unsigned int outprec = TYPE_PRECISION (type);
328
 
329
  /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
330
     be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
331
  if (!COMPLETE_TYPE_P (type))
332
    {
333
      error ("conversion to incomplete type");
334
      return error_mark_node;
335
    }
336
 
337
  /* Convert e.g. (long)round(d) -> lround(d).  */
338
  /* If we're converting to char, we may encounter differing behavior
339
     between converting from double->char vs double->long->char.
340
     We're in "undefined" territory but we prefer to be conservative,
341
     so only proceed in "unsafe" math mode.  */
342
  if (optimize
343
      && (flag_unsafe_math_optimizations
344
          || (long_integer_type_node
345
              && outprec >= TYPE_PRECISION (long_integer_type_node))))
346
    {
347
      tree s_expr = strip_float_extensions (expr);
348
      tree s_intype = TREE_TYPE (s_expr);
349
      const enum built_in_function fcode = builtin_mathfn_code (s_expr);
350
      tree fn = 0;
351
 
352
      switch (fcode)
353
        {
354
        case BUILT_IN_CEIL: case BUILT_IN_CEILF: case BUILT_IN_CEILL:
355
          /* Only convert in ISO C99 mode.  */
356
          if (!TARGET_C99_FUNCTIONS)
357
            break;
358
          if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
359
            fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
360
          else
361
            fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
362
          break;
363
 
364
        case BUILT_IN_FLOOR: case BUILT_IN_FLOORF: case BUILT_IN_FLOORL:
365
          /* Only convert in ISO C99 mode.  */
366
          if (!TARGET_C99_FUNCTIONS)
367
            break;
368
          if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
369
            fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
370
          else
371
            fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
372
          break;
373
 
374
        case BUILT_IN_ROUND: case BUILT_IN_ROUNDF: case BUILT_IN_ROUNDL:
375
          if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
376
            fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
377
          else
378
            fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
379
          break;
380
 
381
        case BUILT_IN_RINT: case BUILT_IN_RINTF: case BUILT_IN_RINTL:
382
          /* Only convert rint* if we can ignore math exceptions.  */
383
          if (flag_trapping_math)
384
            break;
385
          /* ... Fall through ...  */
386
        case BUILT_IN_NEARBYINT: case BUILT_IN_NEARBYINTF: case BUILT_IN_NEARBYINTL:
387
          if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
388
            fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
389
          else
390
            fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
391
          break;
392
 
393
        case BUILT_IN_TRUNC: case BUILT_IN_TRUNCF: case BUILT_IN_TRUNCL:
394
          {
395
            tree arglist = TREE_OPERAND (s_expr, 1);
396
            return convert_to_integer (type, TREE_VALUE (arglist));
397
          }
398
 
399
        default:
400
          break;
401
        }
402
 
403
      if (fn)
404
        {
405
          tree arglist = TREE_OPERAND (s_expr, 1);
406
          tree newexpr = build_function_call_expr (fn, arglist);
407
          return convert_to_integer (type, newexpr);
408
        }
409
    }
410
 
411
  switch (TREE_CODE (intype))
412
    {
413
    case POINTER_TYPE:
414
    case REFERENCE_TYPE:
415
      if (integer_zerop (expr))
416
        return build_int_cst (type, 0);
417
 
418
      /* Convert to an unsigned integer of the correct width first,
419
         and from there widen/truncate to the required type.  */
420
      expr = fold_build1 (CONVERT_EXPR,
421
                          lang_hooks.types.type_for_size (POINTER_SIZE, 0),
422
                          expr);
423
      return fold_build1 (NOP_EXPR, type, expr);
424
 
425
    case INTEGER_TYPE:
426
    case ENUMERAL_TYPE:
427
    case BOOLEAN_TYPE:
428
    case CHAR_TYPE:
429
      /* If this is a logical operation, which just returns 0 or 1, we can
430
         change the type of the expression.  */
431
 
432
      if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
433
        {
434
          expr = copy_node (expr);
435
          TREE_TYPE (expr) = type;
436
          return expr;
437
        }
438
 
439
      /* If we are widening the type, put in an explicit conversion.
440
         Similarly if we are not changing the width.  After this, we know
441
         we are truncating EXPR.  */
442
 
443
      else if (outprec >= inprec)
444
        {
445
          enum tree_code code;
446
 
447
          /* If the precision of the EXPR's type is K bits and the
448
             destination mode has more bits, and the sign is changing,
449
             it is not safe to use a NOP_EXPR.  For example, suppose
450
             that EXPR's type is a 3-bit unsigned integer type, the
451
             TYPE is a 3-bit signed integer type, and the machine mode
452
             for the types is 8-bit QImode.  In that case, the
453
             conversion necessitates an explicit sign-extension.  In
454
             the signed-to-unsigned case the high-order bits have to
455
             be cleared.  */
456
          if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
457
              && (TYPE_PRECISION (TREE_TYPE (expr))
458
                  != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
459
            code = CONVERT_EXPR;
460
          else
461
            code = NOP_EXPR;
462
 
463
          return fold_build1 (code, type, expr);
464
        }
465
 
466
      /* If TYPE is an enumeral type or a type with a precision less
467
         than the number of bits in its mode, do the conversion to the
468
         type corresponding to its mode, then do a nop conversion
469
         to TYPE.  */
470
      else if (TREE_CODE (type) == ENUMERAL_TYPE
471
               || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
472
        return build1 (NOP_EXPR, type,
473
                       convert (lang_hooks.types.type_for_mode
474
                                (TYPE_MODE (type), TYPE_UNSIGNED (type)),
475
                                expr));
476
 
477
      /* Here detect when we can distribute the truncation down past some
478
         arithmetic.  For example, if adding two longs and converting to an
479
         int, we can equally well convert both to ints and then add.
480
         For the operations handled here, such truncation distribution
481
         is always safe.
482
         It is desirable in these cases:
483
         1) when truncating down to full-word from a larger size
484
         2) when truncating takes no work.
485
         3) when at least one operand of the arithmetic has been extended
486
         (as by C's default conversions).  In this case we need two conversions
487
         if we do the arithmetic as already requested, so we might as well
488
         truncate both and then combine.  Perhaps that way we need only one.
489
 
490
         Note that in general we cannot do the arithmetic in a type
491
         shorter than the desired result of conversion, even if the operands
492
         are both extended from a shorter type, because they might overflow
493
         if combined in that type.  The exceptions to this--the times when
494
         two narrow values can be combined in their narrow type even to
495
         make a wider result--are handled by "shorten" in build_binary_op.  */
496
 
497
      switch (ex_form)
498
        {
499
        case RSHIFT_EXPR:
500
          /* We can pass truncation down through right shifting
501
             when the shift count is a nonpositive constant.  */
502
          if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
503
              && tree_int_cst_lt (TREE_OPERAND (expr, 1),
504
                                  convert (TREE_TYPE (TREE_OPERAND (expr, 1)),
505
                                           integer_one_node)))
506
            goto trunc1;
507
          break;
508
 
509
        case LSHIFT_EXPR:
510
          /* We can pass truncation down through left shifting
511
             when the shift count is a nonnegative constant and
512
             the target type is unsigned.  */
513
          if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
514
              && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
515
              && TYPE_UNSIGNED (type)
516
              && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
517
            {
518
              /* If shift count is less than the width of the truncated type,
519
                 really shift.  */
520
              if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
521
                /* In this case, shifting is like multiplication.  */
522
                goto trunc1;
523
              else
524
                {
525
                  /* If it is >= that width, result is zero.
526
                     Handling this with trunc1 would give the wrong result:
527
                     (int) ((long long) a << 32) is well defined (as 0)
528
                     but (int) a << 32 is undefined and would get a
529
                     warning.  */
530
 
531
                  tree t = convert_to_integer (type, integer_zero_node);
532
 
533
                  /* If the original expression had side-effects, we must
534
                     preserve it.  */
535
                  if (TREE_SIDE_EFFECTS (expr))
536
                    return build2 (COMPOUND_EXPR, type, expr, t);
537
                  else
538
                    return t;
539
                }
540
            }
541
          break;
542
 
543
        case MAX_EXPR:
544
        case MIN_EXPR:
545
        case MULT_EXPR:
546
          {
547
            tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
548
            tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
549
 
550
            /* Don't distribute unless the output precision is at least as big
551
               as the actual inputs.  Otherwise, the comparison of the
552
               truncated values will be wrong.  */
553
            if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
554
                && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
555
                /* If signedness of arg0 and arg1 don't match,
556
                   we can't necessarily find a type to compare them in.  */
557
                && (TYPE_UNSIGNED (TREE_TYPE (arg0))
558
                    == TYPE_UNSIGNED (TREE_TYPE (arg1))))
559
              goto trunc1;
560
            break;
561
          }
562
 
563
        case PLUS_EXPR:
564
        case MINUS_EXPR:
565
        case BIT_AND_EXPR:
566
        case BIT_IOR_EXPR:
567
        case BIT_XOR_EXPR:
568
        trunc1:
569
          {
570
            tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
571
            tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
572
 
573
            if (outprec >= BITS_PER_WORD
574
                || TRULY_NOOP_TRUNCATION (outprec, inprec)
575
                || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
576
                || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
577
              {
578
                /* Do the arithmetic in type TYPEX,
579
                   then convert result to TYPE.  */
580
                tree typex = type;
581
 
582
                /* Can't do arithmetic in enumeral types
583
                   so use an integer type that will hold the values.  */
584
                if (TREE_CODE (typex) == ENUMERAL_TYPE)
585
                  typex = lang_hooks.types.type_for_size
586
                    (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex));
587
 
588
                /* But now perhaps TYPEX is as wide as INPREC.
589
                   In that case, do nothing special here.
590
                   (Otherwise would recurse infinitely in convert.  */
591
                if (TYPE_PRECISION (typex) != inprec)
592
                  {
593
                    /* Don't do unsigned arithmetic where signed was wanted,
594
                       or vice versa.
595
                       Exception: if both of the original operands were
596
                       unsigned then we can safely do the work as unsigned.
597
                       Exception: shift operations take their type solely
598
                       from the first argument.
599
                       Exception: the LSHIFT_EXPR case above requires that
600
                       we perform this operation unsigned lest we produce
601
                       signed-overflow undefinedness.
602
                       And we may need to do it as unsigned
603
                       if we truncate to the original size.  */
604
                    if (TYPE_UNSIGNED (TREE_TYPE (expr))
605
                        || (TYPE_UNSIGNED (TREE_TYPE (arg0))
606
                            && (TYPE_UNSIGNED (TREE_TYPE (arg1))
607
                                || ex_form == LSHIFT_EXPR
608
                                || ex_form == RSHIFT_EXPR
609
                                || ex_form == LROTATE_EXPR
610
                                || ex_form == RROTATE_EXPR))
611
                        || ex_form == LSHIFT_EXPR
612
                        /* If we have !flag_wrapv, and either ARG0 or
613
                           ARG1 is of a signed type, we have to do
614
                           PLUS_EXPR or MINUS_EXPR in an unsigned
615
                           type.  Otherwise, we would introduce
616
                           signed-overflow undefinedness.  */
617
                        || (!flag_wrapv
618
                            && (ex_form == PLUS_EXPR
619
                                || ex_form == MINUS_EXPR)
620
                            && (!TYPE_UNSIGNED (TREE_TYPE (arg0))
621
                                || !TYPE_UNSIGNED (TREE_TYPE (arg1)))))
622
                      typex = lang_hooks.types.unsigned_type (typex);
623
                    else
624
                      typex = lang_hooks.types.signed_type (typex);
625
                    return convert (type,
626
                                    fold_build2 (ex_form, typex,
627
                                                 convert (typex, arg0),
628
                                                 convert (typex, arg1)));
629
                  }
630
              }
631
          }
632
          break;
633
 
634
        case NEGATE_EXPR:
635
        case BIT_NOT_EXPR:
636
          /* This is not correct for ABS_EXPR,
637
             since we must test the sign before truncation.  */
638
          {
639
            tree typex;
640
 
641
            /* Don't do unsigned arithmetic where signed was wanted,
642
               or vice versa.  */
643
            if (TYPE_UNSIGNED (TREE_TYPE (expr)))
644
              typex = lang_hooks.types.unsigned_type (type);
645
            else
646
              typex = lang_hooks.types.signed_type (type);
647
            return convert (type,
648
                            fold_build1 (ex_form, typex,
649
                                         convert (typex,
650
                                                  TREE_OPERAND (expr, 0))));
651
          }
652
 
653
        case NOP_EXPR:
654
          /* Don't introduce a
655
             "can't convert between vector values of different size" error.  */
656
          if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
657
              && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
658
                  != GET_MODE_SIZE (TYPE_MODE (type))))
659
            break;
660
          /* If truncating after truncating, might as well do all at once.
661
             If truncating after extending, we may get rid of wasted work.  */
662
          return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
663
 
664
        case COND_EXPR:
665
          /* It is sometimes worthwhile to push the narrowing down through
666
             the conditional and never loses.  */
667
          return fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
668
                              convert (type, TREE_OPERAND (expr, 1)),
669
                              convert (type, TREE_OPERAND (expr, 2)));
670
 
671
        default:
672
          break;
673
        }
674
 
675
      return build1 (CONVERT_EXPR, type, expr);
676
 
677
    case REAL_TYPE:
678
      return build1 (FIX_TRUNC_EXPR, type, expr);
679
 
680
    case COMPLEX_TYPE:
681
      return convert (type,
682
                      fold_build1 (REALPART_EXPR,
683
                                   TREE_TYPE (TREE_TYPE (expr)), expr));
684
 
685
    case VECTOR_TYPE:
686
      if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
687
        {
688
          error ("can't convert between vector values of different size");
689
          return error_mark_node;
690
        }
691
      return build1 (VIEW_CONVERT_EXPR, type, expr);
692
 
693
    default:
694
      error ("aggregate value used where an integer was expected");
695
      return convert (type, integer_zero_node);
696
    }
697
}
698
 
699
/* Convert EXPR to the complex type TYPE in the usual ways.  */
700
 
701
tree
702
convert_to_complex (tree type, tree expr)
703
{
704
  tree subtype = TREE_TYPE (type);
705
 
706
  switch (TREE_CODE (TREE_TYPE (expr)))
707
    {
708
    case REAL_TYPE:
709
    case INTEGER_TYPE:
710
    case ENUMERAL_TYPE:
711
    case BOOLEAN_TYPE:
712
    case CHAR_TYPE:
713
      return build2 (COMPLEX_EXPR, type, convert (subtype, expr),
714
                     convert (subtype, integer_zero_node));
715
 
716
    case COMPLEX_TYPE:
717
      {
718
        tree elt_type = TREE_TYPE (TREE_TYPE (expr));
719
 
720
        if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
721
          return expr;
722
        else if (TREE_CODE (expr) == COMPLEX_EXPR)
723
          return fold_build2 (COMPLEX_EXPR, type,
724
                              convert (subtype, TREE_OPERAND (expr, 0)),
725
                              convert (subtype, TREE_OPERAND (expr, 1)));
726
        else
727
          {
728
            expr = save_expr (expr);
729
            return
730
              fold_build2 (COMPLEX_EXPR, type,
731
                           convert (subtype,
732
                                    fold_build1 (REALPART_EXPR,
733
                                                 TREE_TYPE (TREE_TYPE (expr)),
734
                                                 expr)),
735
                           convert (subtype,
736
                                    fold_build1 (IMAGPART_EXPR,
737
                                                 TREE_TYPE (TREE_TYPE (expr)),
738
                                                 expr)));
739
          }
740
      }
741
 
742
    case POINTER_TYPE:
743
    case REFERENCE_TYPE:
744
      error ("pointer value used where a complex was expected");
745
      return convert_to_complex (type, integer_zero_node);
746
 
747
    default:
748
      error ("aggregate value used where a complex was expected");
749
      return convert_to_complex (type, integer_zero_node);
750
    }
751
}
752
 
753
/* Convert EXPR to the vector type TYPE in the usual ways.  */
754
 
755
tree
756
convert_to_vector (tree type, tree expr)
757
{
758
  switch (TREE_CODE (TREE_TYPE (expr)))
759
    {
760
    case INTEGER_TYPE:
761
    case VECTOR_TYPE:
762
      if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
763
        {
764
          error ("can't convert between vector values of different size");
765
          return error_mark_node;
766
        }
767
      return build1 (VIEW_CONVERT_EXPR, type, expr);
768
 
769
    default:
770
      error ("can't convert value to a vector");
771
      return error_mark_node;
772
    }
773
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.