4 * Copyright (C) 2003 Transmeta Corp.
7 * Licensed under the Open Software License version 1.1
9 * expand constant expressions.
26 #include "expression.h"
28 static void expand_expression(struct expression
*);
29 static void expand_statement(struct statement
*);
31 static void expand_symbol_expression(struct expression
*expr
)
33 struct symbol
*sym
= expr
->symbol
;
36 * The preprocessor can cause unknown symbols to be generated
39 warn(expr
->pos
, "undefined preprocessor identifier '%s'", show_ident(expr
->symbol_name
));
40 expr
->type
= EXPR_VALUE
;
46 static long long get_longlong(struct expression
*expr
)
48 int no_expand
= expr
->ctype
->ctype
.modifiers
& MOD_UNSIGNED
;
49 long long mask
= 1ULL << (expr
->ctype
->bit_size
- 1);
50 long long value
= expr
->value
;
51 long long ormask
, andmask
;
55 andmask
= mask
| (mask
-1);
59 return (value
& andmask
) | ormask
;
62 void cast_value(struct expression
*expr
, struct symbol
*newtype
,
63 struct expression
*old
, struct symbol
*oldtype
)
65 int old_size
= oldtype
->bit_size
;
66 int new_size
= newtype
->bit_size
;
67 long long value
, mask
;
69 if (newtype
->ctype
.base_type
== &fp_type
||
70 oldtype
->ctype
.base_type
== &fp_type
)
73 // For pointers and integers, we can just move the value around
74 expr
->type
= EXPR_VALUE
;
75 if (old_size
== new_size
) {
76 expr
->value
= old
->value
;
80 // expand it to the full "long long" value
81 value
= get_longlong(old
);
84 // Truncate it to the new size
85 mask
= 1ULL << (new_size
-1);
86 mask
= mask
| (mask
-1);
87 expr
->value
= value
& mask
;
91 if (newtype
->ctype
.base_type
!= &fp_type
) {
92 value
= (long long)old
->fvalue
;
93 expr
->type
= EXPR_VALUE
;
97 if (oldtype
->ctype
.base_type
!= &fp_type
)
98 expr
->fvalue
= (long double)get_longlong(old
);
100 expr
->fvalue
= old
->value
;
102 if (!(newtype
->ctype
.modifiers
& MOD_LONGLONG
)) {
103 if ((newtype
->ctype
.modifiers
& MOD_LONG
))
104 expr
->fvalue
= (double)expr
->fvalue
;
106 expr
->fvalue
= (float)expr
->fvalue
;
108 expr
->type
= EXPR_FVALUE
;
111 static int check_shift_count(struct expression
*expr
, struct symbol
*ctype
, unsigned int count
)
113 if (count
>= ctype
->bit_size
) {
114 warn(expr
->pos
, "shift too big for type (%x)", ctype
->ctype
.modifiers
);
115 count
&= ctype
->bit_size
-1;
121 * CAREFUL! We need to get the size and sign of the
124 static int simplify_int_binop(struct expression
*expr
, struct symbol
*ctype
)
126 struct expression
*left
= expr
->left
, *right
= expr
->right
;
127 unsigned long long v
, l
, r
, mask
;
128 signed long long s
, sl
, sr
;
129 int is_signed
, shift
;
131 if (left
->type
!= EXPR_VALUE
|| right
->type
!= EXPR_VALUE
)
133 l
= left
->value
; r
= right
->value
;
134 is_signed
= !(ctype
->ctype
.modifiers
& MOD_UNSIGNED
);
135 mask
= 1ULL << (ctype
->bit_size
-1);
137 if (is_signed
&& (sl
& mask
))
139 if (is_signed
&& (sr
& mask
))
143 case '+': v
= l
+ r
; s
= v
; break;
144 case '-': v
= l
- r
; s
= v
; break;
145 case '&': v
= l
& r
; s
= v
; break;
146 case '|': v
= l
| r
; s
= v
; break;
147 case '^': v
= l
^ r
; s
= v
; break;
148 case '*': v
= l
* r
; s
= sl
* sr
; break;
149 case '/': if (!r
) goto Div
; v
= l
/ r
; s
= sl
/ sr
; break;
150 case '%': if (!r
) goto Div
; v
= l
% r
; s
= sl
% sr
; break;
151 case SPECIAL_LEFTSHIFT
: shift
= check_shift_count(expr
, ctype
, r
); v
= l
<< shift
; s
= v
; break;
152 case SPECIAL_RIGHTSHIFT
:shift
= check_shift_count(expr
, ctype
, r
); v
= l
>> shift
; s
= sl
>> shift
; break;
157 mask
= mask
| (mask
-1);
158 expr
->value
= v
& mask
;
159 expr
->type
= EXPR_VALUE
;
162 warn(expr
->pos
, "division by zero");
166 static int simplify_cmp_binop(struct expression
*expr
, struct symbol
*ctype
)
168 struct expression
*left
= expr
->left
, *right
= expr
->right
;
169 unsigned long long l
, r
, mask
;
170 signed long long sl
, sr
;
172 if (left
->type
!= EXPR_VALUE
|| right
->type
!= EXPR_VALUE
)
174 l
= left
->value
; r
= right
->value
;
175 mask
= 1ULL << (ctype
->bit_size
-1);
182 case '<': expr
->value
= sl
< sr
; break;
183 case '>': expr
->value
= sl
> sr
; break;
184 case SPECIAL_LTE
: expr
->value
= sl
<= sr
; break;
185 case SPECIAL_GTE
: expr
->value
= sl
>= sr
; break;
186 case SPECIAL_EQUAL
: expr
->value
= l
== r
; break;
187 case SPECIAL_NOTEQUAL
: expr
->value
= l
!= r
; break;
188 case SPECIAL_UNSIGNED_LT
:expr
->value
= l
< r
; break;
189 case SPECIAL_UNSIGNED_GT
:expr
->value
= l
> r
; break;
190 case SPECIAL_UNSIGNED_LTE
:expr
->value
= l
<= r
; break;
191 case SPECIAL_UNSIGNED_GTE
:expr
->value
= l
>= r
; break;
193 expr
->type
= EXPR_VALUE
;
197 static int simplify_float_binop(struct expression
*expr
)
199 struct expression
*left
= expr
->left
, *right
= expr
->right
;
200 unsigned long mod
= expr
->ctype
->ctype
.modifiers
;
201 long double l
= left
->fvalue
;
202 long double r
= right
->fvalue
;
205 if (left
->type
!= EXPR_FVALUE
|| right
->type
!= EXPR_FVALUE
)
207 if (mod
& MOD_LONGLONG
) {
209 case '+': res
= l
+ r
; break;
210 case '-': res
= l
- r
; break;
211 case '*': res
= l
* r
; break;
212 case '/': if (!r
) goto Div
;
216 } else if (mod
& MOD_LONG
) {
218 case '+': res
= (double) l
+ (double) r
; break;
219 case '-': res
= (double) l
- (double) r
; break;
220 case '*': res
= (double) l
* (double) r
; break;
221 case '/': if (!r
) goto Div
;
222 res
= (double) l
/ (double) r
; break;
227 case '+': res
= (float)l
+ (float)r
; break;
228 case '-': res
= (float)l
- (float)r
; break;
229 case '*': res
= (float)l
* (float)r
; break;
230 case '/': if (!r
) goto Div
;
231 res
= (float)l
/ (float)r
; break;
235 expr
->type
= EXPR_FVALUE
;
239 warn(expr
->pos
, "division by zero");
243 static int simplify_float_cmp(struct expression
*expr
, struct symbol
*ctype
)
245 struct expression
*left
= expr
->left
, *right
= expr
->right
;
246 long double l
= left
->fvalue
, r
= right
->fvalue
;
248 if (left
->type
!= EXPR_FVALUE
|| right
->type
!= EXPR_FVALUE
)
252 case '<': expr
->value
= l
< r
; break;
253 case '>': expr
->value
= l
> r
; break;
254 case SPECIAL_LTE
: expr
->value
= l
<= r
; break;
255 case SPECIAL_GTE
: expr
->value
= l
>= r
; break;
256 case SPECIAL_EQUAL
: expr
->value
= l
== r
; break;
257 case SPECIAL_NOTEQUAL
: expr
->value
= l
!= r
; break;
259 expr
->type
= EXPR_VALUE
;
263 static void expand_binop(struct expression
*expr
)
265 if (simplify_int_binop(expr
, expr
->ctype
))
267 simplify_float_binop(expr
);
270 static void expand_logical(struct expression
*expr
)
272 struct expression
*left
= expr
->left
;
273 struct expression
*right
;
275 /* Do immediate short-circuiting ... */
276 expand_expression(left
);
277 if (left
->type
== EXPR_VALUE
) {
278 if (expr
->op
== SPECIAL_LOGICAL_AND
) {
280 expr
->type
= EXPR_VALUE
;
286 expr
->type
= EXPR_VALUE
;
294 expand_expression(right
);
295 if (left
->type
== EXPR_VALUE
&& right
->type
== EXPR_VALUE
) {
297 * We know the left value doesn't matter, since
298 * otherwise we would have short-circuited it..
300 expr
->type
= EXPR_VALUE
;
301 expr
->value
= right
->value
!= 0;
305 static void expand_comma(struct expression
*expr
)
307 if (expr
->left
->type
== EXPR_VALUE
|| expr
->left
->type
== EXPR_FVALUE
)
308 *expr
= *expr
->right
;
311 #define MOD_IGN (MOD_VOLATILE | MOD_CONST)
313 static int compare_types(int op
, struct symbol
*left
, struct symbol
*right
)
317 return !type_difference(left
, right
, MOD_IGN
, MOD_IGN
);
318 case SPECIAL_NOTEQUAL
:
319 return type_difference(left
, right
, MOD_IGN
, MOD_IGN
) != NULL
;
321 return left
->bit_size
< right
->bit_size
;
323 return left
->bit_size
> right
->bit_size
;
325 return left
->bit_size
<= right
->bit_size
;
327 return left
->bit_size
>= right
->bit_size
;
332 static void expand_compare(struct expression
*expr
)
334 struct expression
*left
= expr
->left
, *right
= expr
->right
;
336 /* Type comparison? */
337 if (left
&& right
&& left
->type
== EXPR_TYPE
&& right
->type
== EXPR_TYPE
) {
339 expr
->type
= EXPR_VALUE
;
340 expr
->value
= compare_types(op
, left
->symbol
, right
->symbol
);
343 if (simplify_cmp_binop(expr
, left
->ctype
))
345 simplify_float_cmp(expr
, left
->ctype
);
348 static void expand_conditional(struct expression
*expr
)
350 struct expression
*cond
= expr
->conditional
;
352 if (cond
->type
== EXPR_VALUE
) {
353 struct expression
*true, *false;
355 true = expr
->cond_true
? : cond
;
356 false = expr
->cond_false
;
364 static void expand_assignment(struct expression
*expr
)
368 static void expand_addressof(struct expression
*expr
)
372 static void expand_dereference(struct expression
*expr
)
374 struct expression
*unop
= expr
->unop
;
377 * NOTE! We get a bogus warning right now for some special
378 * cases: apparently I've screwed up the optimization of
379 * a zero-offset derefence, and the ctype is wrong.
381 * Leave the warning in anyway, since this is also a good
382 * test for me to get the type evaluation right..
384 if (expr
->ctype
->ctype
.modifiers
& MOD_NODEREF
)
385 warn(unop
->pos
, "dereference of noderef expression");
387 if (unop
->type
== EXPR_SYMBOL
) {
388 struct symbol
*sym
= unop
->symbol
;
390 /* Const symbol with a constant initializer? */
391 if (!(sym
->ctype
.modifiers
& (MOD_ASSIGNED
| MOD_ADDRESSABLE
))) {
392 struct expression
*value
= sym
->initializer
;
394 if (value
->type
== EXPR_VALUE
) {
395 expr
->type
= EXPR_VALUE
;
396 expr
->value
= value
->value
;
397 } else if (value
->type
== EXPR_FVALUE
) {
398 expr
->type
= EXPR_FVALUE
;
399 expr
->fvalue
= value
->fvalue
;
406 static int simplify_preop(struct expression
*expr
)
408 struct expression
*op
= expr
->unop
;
409 unsigned long long v
, mask
;
411 if (op
->type
!= EXPR_VALUE
)
416 case '-': v
= -v
; break;
417 case '!': v
= !v
; break;
418 case '~': v
= ~v
; break;
421 mask
= 1ULL << (expr
->ctype
->bit_size
-1);
422 mask
= mask
| (mask
-1);
423 expr
->value
= v
& mask
;
424 expr
->type
= EXPR_VALUE
;
428 static int simplify_float_preop(struct expression
*expr
)
430 struct expression
*op
= expr
->unop
;
433 if (op
->type
!= EXPR_FVALUE
)
438 case '-': v
= -v
; break;
442 expr
->type
= EXPR_FVALUE
;
447 * Unary post-ops: x++ and x--
449 static void expand_postop(struct expression
*expr
)
453 static void expand_preop(struct expression
*expr
)
457 expand_dereference(expr
);
461 expand_addressof(expr
);
464 case SPECIAL_INCREMENT
:
465 case SPECIAL_DECREMENT
:
467 * From a type evaluation standpoint the pre-ops are
468 * the same as the postops
476 if (simplify_preop(expr
))
478 simplify_float_preop(expr
);
481 static void expand_arguments(struct expression_list
*head
)
483 struct expression
*expr
;
485 FOR_EACH_PTR (head
, expr
) {
486 expand_expression(expr
);
490 static void expand_cast(struct expression
*expr
)
492 struct expression
*target
= expr
->cast_expression
;
494 expand_expression(target
);
496 /* Simplify normal integer casts.. */
497 if (target
->type
== EXPR_VALUE
|| target
->type
== EXPR_FVALUE
)
498 cast_value(expr
, expr
->ctype
, target
, target
->ctype
);
502 * expand a call expression with a symbol. This
503 * should expand inline functions, and expand
506 static void expand_symbol_call(struct expression
*expr
)
508 struct expression
*fn
= expr
->fn
;
509 struct symbol
*ctype
= fn
->ctype
;
511 if (fn
->type
!= EXPR_PREOP
)
514 if (ctype
->op
&& ctype
->op
->expand
) {
515 ctype
->op
->expand(expr
);
520 static void expand_call(struct expression
*expr
)
523 struct expression
*fn
= expr
->fn
;
526 expand_arguments(expr
->args
);
527 if (sym
->type
== SYM_NODE
)
528 expand_symbol_call(expr
);
531 static void expand_expression_list(struct expression_list
*list
)
533 struct expression
*expr
;
535 FOR_EACH_PTR(list
, expr
) {
536 expand_expression(expr
);
540 static void expand_expression(struct expression
*expr
)
547 switch (expr
->type
) {
554 expand_symbol_expression(expr
);
557 expand_expression(expr
->left
);
558 expand_expression(expr
->right
);
563 expand_logical(expr
);
567 expand_expression(expr
->left
);
568 expand_expression(expr
->right
);
573 expand_expression(expr
->left
);
574 expand_expression(expr
->right
);
575 expand_compare(expr
);
578 case EXPR_ASSIGNMENT
:
579 expand_expression(expr
->left
);
580 expand_expression(expr
->right
);
581 expand_assignment(expr
);
585 expand_expression(expr
->unop
);
590 expand_expression(expr
->unop
);
606 expand_expression(expr
->address
);
609 case EXPR_CONDITIONAL
:
610 expand_expression(expr
->conditional
);
611 expand_expression(expr
->cond_false
);
612 expand_expression(expr
->cond_true
);
613 expand_conditional(expr
);
617 expand_statement(expr
->statement
);
623 case EXPR_INITIALIZER
:
624 expand_expression_list(expr
->expr_list
);
627 case EXPR_IDENTIFIER
:
634 expand_expression(expr
->init_expr
);
639 warn(expr
->pos
, "internal front-end error: sizeof in expansion?");
645 static void expand_const_expression(struct expression
*expr
, const char *where
)
648 expand_expression(expr
);
649 if (expr
->type
!= EXPR_VALUE
)
650 warn(expr
->pos
, "Expected constant expression in %s", where
);
654 void expand_symbol(struct symbol
*sym
)
656 struct symbol
*base_type
;
660 base_type
= sym
->ctype
.base_type
;
664 expand_expression(sym
->initializer
);
665 /* expand the body of the symbol */
666 if (base_type
->type
== SYM_FN
) {
668 expand_statement(base_type
->stmt
);
672 static void expand_return_expression(struct statement
*stmt
)
674 expand_expression(stmt
->expression
);
677 static void expand_if_statement(struct statement
*stmt
)
679 struct expression
*expr
= stmt
->if_conditional
;
681 if (!expr
|| !expr
->ctype
)
684 expand_expression(expr
);
686 /* This is only valid if nobody jumps into the "dead" side */
688 /* Simplify constant conditionals without even evaluating the false side */
689 if (expr
->type
== EXPR_VALUE
) {
690 struct statement
*simple
;
691 simple
= expr
->value
? stmt
->if_true
: stmt
->if_false
;
695 stmt
->type
= STMT_NONE
;
698 expand_statement(simple
);
703 expand_statement(stmt
->if_true
);
704 expand_statement(stmt
->if_false
);
707 static void expand_statement(struct statement
*stmt
)
712 switch (stmt
->type
) {
714 expand_return_expression(stmt
);
717 case STMT_EXPRESSION
:
718 expand_expression(stmt
->expression
);
721 case STMT_COMPOUND
: {
725 FOR_EACH_PTR(stmt
->syms
, sym
) {
728 expand_symbol(stmt
->ret
);
730 FOR_EACH_PTR(stmt
->stmts
, s
) {
737 expand_if_statement(stmt
);
741 expand_expression(stmt
->iterator_pre_condition
);
742 expand_expression(stmt
->iterator_post_condition
);
743 expand_statement(stmt
->iterator_pre_statement
);
744 expand_statement(stmt
->iterator_statement
);
745 expand_statement(stmt
->iterator_post_statement
);
749 expand_expression(stmt
->switch_expression
);
750 expand_statement(stmt
->switch_statement
);
754 expand_const_expression(stmt
->case_expression
, "case statement");
755 expand_const_expression(stmt
->case_to
, "case statement");
756 expand_statement(stmt
->case_statement
);
760 expand_statement(stmt
->label_statement
);
764 expand_expression(stmt
->goto_expression
);
770 /* FIXME! Do the asm parameter evaluation! */
775 long long get_expression_value(struct expression
*expr
)
777 long long value
, mask
;
778 struct symbol
*ctype
;
782 ctype
= evaluate_expression(expr
);
784 warn(expr
->pos
, "bad constant expression type");
787 expand_expression(expr
);
788 if (expr
->type
!= EXPR_VALUE
) {
789 warn(expr
->pos
, "bad constant expression");
794 mask
= 1ULL << (ctype
->bit_size
-1);
797 while (ctype
->type
!= SYM_BASETYPE
)
798 ctype
= ctype
->ctype
.base_type
;
799 if (!(ctype
->ctype
.modifiers
& MOD_UNSIGNED
))
800 value
= value
| mask
| ~(mask
-1);