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 void cast_value(struct expression
*expr
, struct symbol
*newtype
,
47 struct expression
*old
, struct symbol
*oldtype
)
49 int old_size
= oldtype
->bit_size
;
50 int new_size
= newtype
->bit_size
;
51 long long value
, mask
, ormask
, andmask
;
54 // FIXME! We don't handle FP casts of constant values yet
55 if (newtype
->ctype
.base_type
== &fp_type
)
57 if (oldtype
->ctype
.base_type
== &fp_type
)
60 // For pointers and integers, we can just move the value around
61 expr
->type
= EXPR_VALUE
;
62 if (old_size
== new_size
) {
63 expr
->value
= old
->value
;
67 // expand it to the full "long long" value
68 is_signed
= !(oldtype
->ctype
.modifiers
& MOD_UNSIGNED
);
69 mask
= 1ULL << (old_size
-1);
73 andmask
= mask
| (mask
-1);
77 value
= (value
& andmask
) | ormask
;
79 // Truncate it to the new size
80 mask
= 1ULL << (new_size
-1);
81 mask
= mask
| (mask
-1);
82 expr
->value
= value
& mask
;
85 static int check_shift_count(struct expression
*expr
, struct symbol
*ctype
, unsigned int count
)
87 if (count
>= ctype
->bit_size
) {
88 warn(expr
->pos
, "shift too big for type (%x)", ctype
->ctype
.modifiers
);
89 count
&= ctype
->bit_size
-1;
95 * CAREFUL! We need to get the size and sign of the
98 static void simplify_int_binop(struct expression
*expr
, struct symbol
*ctype
)
100 struct expression
*left
= expr
->left
, *right
= expr
->right
;
101 unsigned long long v
, l
, r
, mask
;
102 signed long long s
, sl
, sr
;
103 int is_signed
, shift
;
105 if (left
->type
!= EXPR_VALUE
|| right
->type
!= EXPR_VALUE
)
107 l
= left
->value
; r
= right
->value
;
108 is_signed
= !(ctype
->ctype
.modifiers
& MOD_UNSIGNED
);
109 mask
= 1ULL << (ctype
->bit_size
-1);
111 if (is_signed
&& (sl
& mask
))
113 if (is_signed
&& (sr
& mask
))
117 case '+': v
= l
+ r
; s
= v
; break;
118 case '-': v
= l
- r
; s
= v
; break;
119 case '&': v
= l
& r
; s
= v
; break;
120 case '|': v
= l
| r
; s
= v
; break;
121 case '^': v
= l
^ r
; s
= v
; break;
122 case '*': v
= l
* r
; s
= sl
* sr
; break;
123 case '/': if (!r
) return; v
= l
/ r
; s
= sl
/ sr
; break;
124 case '%': if (!r
) return; v
= l
% r
; s
= sl
% sr
; break;
125 case SPECIAL_LEFTSHIFT
: shift
= check_shift_count(expr
, ctype
, r
); v
= l
<< shift
; s
= v
; break;
126 case SPECIAL_RIGHTSHIFT
:shift
= check_shift_count(expr
, ctype
, r
); v
= l
>> shift
; s
= sl
>> shift
; break;
127 case '<': v
= l
< r
; s
= sl
< sr
; break;
128 case '>': v
= l
> r
; s
= sl
> sr
; break;
129 case SPECIAL_LTE
: v
= l
<= r
; s
= sl
<= sr
; break;
130 case SPECIAL_GTE
: v
= l
>= r
; s
= sl
>= sr
; break;
131 case SPECIAL_EQUAL
: v
= l
== r
; s
= v
; break;
132 case SPECIAL_NOTEQUAL
: v
= l
!= r
; s
= v
; break;
137 mask
= mask
| (mask
-1);
138 expr
->value
= v
& mask
;
139 expr
->type
= EXPR_VALUE
;
142 static void expand_int_binop(struct expression
*expr
)
144 simplify_int_binop(expr
, expr
->ctype
);
147 static void expand_logical(struct expression
*expr
)
149 struct expression
*left
= expr
->left
;
150 struct expression
*right
;
152 /* Do immediate short-circuiting ... */
153 expand_expression(left
);
154 if (left
->type
== EXPR_VALUE
) {
155 if (expr
->op
== SPECIAL_LOGICAL_AND
) {
157 expr
->type
= EXPR_VALUE
;
163 expr
->type
= EXPR_VALUE
;
171 expand_expression(right
);
172 if (left
->type
== EXPR_VALUE
&& right
->type
== EXPR_VALUE
) {
174 * We know the left value doesn't matter, since
175 * otherwise we would have short-circuited it..
177 expr
->type
= EXPR_VALUE
;
178 expr
->value
= right
->value
;
182 static void expand_binop(struct expression
*expr
)
184 expand_int_binop(expr
);
187 static void expand_comma(struct expression
*expr
)
189 if (expr
->left
->type
== EXPR_VALUE
)
190 *expr
= *expr
->right
;
193 #define MOD_IGN (MOD_VOLATILE | MOD_CONST)
195 static int compare_types(int op
, struct symbol
*left
, struct symbol
*right
)
199 return !type_difference(left
, right
, MOD_IGN
, MOD_IGN
);
200 case SPECIAL_NOTEQUAL
:
201 return type_difference(left
, right
, MOD_IGN
, MOD_IGN
) != NULL
;
203 return left
->bit_size
< right
->bit_size
;
205 return left
->bit_size
> right
->bit_size
;
207 return left
->bit_size
<= right
->bit_size
;
209 return left
->bit_size
>= right
->bit_size
;
214 static void expand_compare(struct expression
*expr
)
216 struct expression
*left
= expr
->left
, *right
= expr
->right
;
218 /* Type comparison? */
219 if (left
&& right
&& left
->type
== EXPR_TYPE
&& right
->type
== EXPR_TYPE
) {
221 expr
->type
= EXPR_VALUE
;
222 expr
->value
= compare_types(op
, left
->symbol
, right
->symbol
);
225 simplify_int_binop(expr
, expr
->ctype
);
228 static void expand_conditional(struct expression
*expr
)
230 struct expression
*cond
= expr
->conditional
;
232 if (cond
->type
== EXPR_VALUE
) {
233 struct expression
*true, *false;
235 true = expr
->cond_true
? : cond
;
236 false = expr
->cond_false
;
244 static void expand_assignment(struct expression
*expr
)
248 static void expand_addressof(struct expression
*expr
)
252 static void expand_dereference(struct expression
*expr
)
254 struct expression
*unop
= expr
->unop
;
257 * NOTE! We get a bogus warning right now for some special
258 * cases: apparently I've screwed up the optimization of
259 * a zero-offset derefence, and the ctype is wrong.
261 * Leave the warning in anyway, since this is also a good
262 * test for me to get the type evaluation right..
264 if (expr
->ctype
->ctype
.modifiers
& MOD_NODEREF
)
265 warn(unop
->pos
, "dereference of noderef expression");
267 if (unop
->type
== EXPR_SYMBOL
) {
268 struct symbol
*sym
= unop
->symbol
;
270 /* Const symbol with a constant initializer? */
271 if (!(sym
->ctype
.modifiers
& (MOD_ASSIGNED
| MOD_ADDRESSABLE
))) {
272 struct expression
*value
= sym
->initializer
;
274 if (value
->type
== EXPR_VALUE
) {
275 expr
->type
= EXPR_VALUE
;
276 expr
->value
= value
->value
;
283 static void simplify_preop(struct expression
*expr
)
285 struct expression
*op
= expr
->unop
;
286 unsigned long long v
, mask
;
288 if (op
->type
!= EXPR_VALUE
)
293 case '-': v
= -v
; break;
294 case '!': v
= !v
; break;
295 case '~': v
= ~v
; break;
298 mask
= 1ULL << (expr
->ctype
->bit_size
-1);
299 mask
= mask
| (mask
-1);
300 expr
->value
= v
& mask
;
301 expr
->type
= EXPR_VALUE
;
305 * Unary post-ops: x++ and x--
307 static void expand_postop(struct expression
*expr
)
311 static void expand_preop(struct expression
*expr
)
315 expand_dereference(expr
);
319 expand_addressof(expr
);
322 case SPECIAL_INCREMENT
:
323 case SPECIAL_DECREMENT
:
325 * From a type evaluation standpoint the pre-ops are
326 * the same as the postops
334 simplify_preop(expr
);
337 static void expand_arguments(struct expression_list
*head
)
339 struct expression
*expr
;
341 FOR_EACH_PTR (head
, expr
) {
342 expand_expression(expr
);
346 static void expand_cast(struct expression
*expr
)
348 struct expression
*target
= expr
->cast_expression
;
350 expand_expression(target
);
352 /* Simplify normal integer casts.. */
353 if (target
->type
== EXPR_VALUE
)
354 cast_value(expr
, expr
->ctype
, target
, target
->ctype
);
358 * expand a call expression with a symbol. This
359 * should expand inline functions, and expand
362 static void expand_symbol_call(struct expression
*expr
)
364 struct expression
*fn
= expr
->fn
;
365 struct symbol
*ctype
= fn
->ctype
;
367 if (fn
->type
!= EXPR_PREOP
)
370 if (ctype
->op
&& ctype
->op
->expand
) {
371 ctype
->op
->expand(expr
);
376 static void expand_call(struct expression
*expr
)
379 struct expression
*fn
= expr
->fn
;
382 expand_arguments(expr
->args
);
383 if (sym
->type
== SYM_NODE
)
384 expand_symbol_call(expr
);
387 static void expand_expression_list(struct expression_list
*list
)
389 struct expression
*expr
;
391 FOR_EACH_PTR(list
, expr
) {
392 expand_expression(expr
);
396 static void expand_expression(struct expression
*expr
)
403 switch (expr
->type
) {
410 expand_symbol_expression(expr
);
413 expand_expression(expr
->left
);
414 expand_expression(expr
->right
);
419 expand_logical(expr
);
423 expand_expression(expr
->left
);
424 expand_expression(expr
->right
);
429 expand_expression(expr
->left
);
430 expand_expression(expr
->right
);
431 expand_compare(expr
);
434 case EXPR_ASSIGNMENT
:
435 expand_expression(expr
->left
);
436 expand_expression(expr
->right
);
437 expand_assignment(expr
);
441 expand_expression(expr
->unop
);
446 expand_expression(expr
->unop
);
462 expand_expression(expr
->address
);
465 case EXPR_CONDITIONAL
:
466 expand_expression(expr
->conditional
);
467 expand_expression(expr
->cond_false
);
468 expand_expression(expr
->cond_true
);
469 expand_conditional(expr
);
473 expand_statement(expr
->statement
);
479 case EXPR_INITIALIZER
:
480 expand_expression_list(expr
->expr_list
);
483 case EXPR_IDENTIFIER
:
490 expand_expression(expr
->init_expr
);
494 warn(expr
->pos
, "internal front-end error: sizeof in expansion?");
500 static void expand_const_expression(struct expression
*expr
, const char *where
)
503 expand_expression(expr
);
504 if (expr
->type
!= EXPR_VALUE
)
505 warn(expr
->pos
, "Expected constant expression in %s", where
);
509 void expand_symbol(struct symbol
*sym
)
511 struct symbol
*base_type
;
515 base_type
= sym
->ctype
.base_type
;
519 expand_expression(sym
->initializer
);
520 /* expand the body of the symbol */
521 if (base_type
->type
== SYM_FN
) {
523 expand_statement(base_type
->stmt
);
527 static void expand_return_expression(struct statement
*stmt
)
529 expand_expression(stmt
->expression
);
532 static void expand_if_statement(struct statement
*stmt
)
534 struct expression
*expr
= stmt
->if_conditional
;
536 if (!expr
|| !expr
->ctype
)
539 expand_expression(expr
);
541 /* This is only valid if nobody jumps into the "dead" side */
543 /* Simplify constant conditionals without even evaluating the false side */
544 if (expr
->type
== EXPR_VALUE
) {
545 struct statement
*simple
;
546 simple
= expr
->value
? stmt
->if_true
: stmt
->if_false
;
550 stmt
->type
= STMT_NONE
;
553 expand_statement(simple
);
558 expand_statement(stmt
->if_true
);
559 expand_statement(stmt
->if_false
);
562 static void expand_statement(struct statement
*stmt
)
567 switch (stmt
->type
) {
569 expand_return_expression(stmt
);
572 case STMT_EXPRESSION
:
573 expand_expression(stmt
->expression
);
576 case STMT_COMPOUND
: {
580 FOR_EACH_PTR(stmt
->syms
, sym
) {
583 expand_symbol(stmt
->ret
);
585 FOR_EACH_PTR(stmt
->stmts
, s
) {
592 expand_if_statement(stmt
);
596 expand_expression(stmt
->iterator_pre_condition
);
597 expand_expression(stmt
->iterator_post_condition
);
598 expand_statement(stmt
->iterator_pre_statement
);
599 expand_statement(stmt
->iterator_statement
);
600 expand_statement(stmt
->iterator_post_statement
);
604 expand_expression(stmt
->switch_expression
);
605 expand_statement(stmt
->switch_statement
);
609 expand_const_expression(stmt
->case_expression
, "case statement");
610 expand_const_expression(stmt
->case_to
, "case statement");
611 expand_statement(stmt
->case_statement
);
615 expand_statement(stmt
->label_statement
);
619 expand_expression(stmt
->goto_expression
);
625 /* FIXME! Do the asm parameter evaluation! */
630 long long get_expression_value(struct expression
*expr
)
632 long long value
, mask
;
633 struct symbol
*ctype
;
637 ctype
= evaluate_expression(expr
);
639 warn(expr
->pos
, "bad constant expression type");
642 expand_expression(expr
);
643 if (expr
->type
!= EXPR_VALUE
) {
644 warn(expr
->pos
, "bad constant expression");
649 mask
= 1ULL << (ctype
->bit_size
-1);
652 while (ctype
->type
!= SYM_BASETYPE
)
653 ctype
= ctype
->ctype
.base_type
;
654 if (!(ctype
->ctype
.modifiers
& MOD_UNSIGNED
))
655 value
= value
| mask
| ~(mask
-1);