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