4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
7 * Licensed under the Open Software License version 1.1
9 * expand constant expressions.
27 #include "expression.h"
29 /* Random cost numbers */
30 #define SIDE_EFFECTS 10000 /* The expression has side effects */
31 #define UNSAFE 100 /* The expression may be "infinitely costly" due to exceptions */
32 #define SELECT_COST 20 /* Cut-off for turning a conditional into a select */
33 #define BRANCH_COST 10 /* Cost of a conditional branch */
35 static int expand_expression(struct expression
*);
36 static int expand_statement(struct statement
*);
38 static int expand_symbol_expression(struct expression
*expr
)
40 struct symbol
*sym
= expr
->symbol
;
41 /* The cost of a symbol expression is lower for on-stack symbols */
42 return (sym
->ctype
.modifiers
& (MOD_STATIC
| MOD_EXTERN
)) ? 2 : 1;
45 static long long get_longlong(struct expression
*expr
)
47 int no_expand
= expr
->ctype
->ctype
.modifiers
& MOD_UNSIGNED
;
48 long long mask
= 1ULL << (expr
->ctype
->bit_size
- 1);
49 long long value
= expr
->value
;
50 long long ormask
, andmask
;
54 andmask
= mask
| (mask
-1);
58 return (value
& andmask
) | ormask
;
61 void cast_value(struct expression
*expr
, struct symbol
*newtype
,
62 struct expression
*old
, struct symbol
*oldtype
)
64 int old_size
= oldtype
->bit_size
;
65 int new_size
= newtype
->bit_size
;
66 long long value
, mask
, signmask
;
67 long long oldmask
, oldsignmask
, dropped
;
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 signmask
= 1ULL << (new_size
-1);
86 mask
= signmask
| (signmask
-1);
87 expr
->value
= value
& mask
;
89 // Check if we dropped any bits..
90 oldsignmask
= 1ULL << (old_size
-1);
91 oldmask
= oldsignmask
| (oldsignmask
-1);
92 dropped
= oldmask
& ~mask
;
94 // Ok if the bits were (and still are) purely sign bits
95 if (value
& dropped
) {
96 if (!(value
& oldsignmask
) || !(value
& signmask
) || (value
& dropped
) != dropped
)
97 warning(old
->pos
, "cast truncates bits from constant value (%llx becomes %llx)",
104 if (newtype
->ctype
.base_type
!= &fp_type
) {
105 value
= (long long)old
->fvalue
;
106 expr
->type
= EXPR_VALUE
;
110 if (oldtype
->ctype
.base_type
!= &fp_type
)
111 expr
->fvalue
= (long double)get_longlong(old
);
113 expr
->fvalue
= old
->value
;
115 if (!(newtype
->ctype
.modifiers
& MOD_LONGLONG
)) {
116 if ((newtype
->ctype
.modifiers
& MOD_LONG
))
117 expr
->fvalue
= (double)expr
->fvalue
;
119 expr
->fvalue
= (float)expr
->fvalue
;
121 expr
->type
= EXPR_FVALUE
;
124 static int check_shift_count(struct expression
*expr
, struct symbol
*ctype
, unsigned int count
)
126 if (count
>= ctype
->bit_size
) {
127 warning(expr
->pos
, "shift too big (%u) for type %s", count
, show_typename(ctype
));
128 count
&= ctype
->bit_size
-1;
134 * CAREFUL! We need to get the size and sign of the
137 #define CONVERT(op,s) (((op)<<1)+(s))
138 #define SIGNED(op) CONVERT(op, 1)
139 #define UNSIGNED(op) CONVERT(op, 0)
140 static int simplify_int_binop(struct expression
*expr
, struct symbol
*ctype
)
142 struct expression
*left
= expr
->left
, *right
= expr
->right
;
143 unsigned long long v
, l
, r
, mask
;
144 signed long long sl
, sr
;
147 if (right
->type
!= EXPR_VALUE
)
150 if (expr
->op
== SPECIAL_LEFTSHIFT
|| expr
->op
== SPECIAL_RIGHTSHIFT
) {
151 r
= check_shift_count(expr
, ctype
, r
);
154 if (left
->type
!= EXPR_VALUE
)
156 l
= left
->value
; r
= right
->value
;
157 is_signed
= !(ctype
->ctype
.modifiers
& MOD_UNSIGNED
);
158 mask
= 1ULL << (ctype
->bit_size
-1);
160 if (is_signed
&& (sl
& mask
))
162 if (is_signed
&& (sr
& mask
))
165 switch (CONVERT(expr
->op
,is_signed
)) {
202 if (l
== mask
&& sr
== -1)
223 case SIGNED(SPECIAL_LEFTSHIFT
):
224 case UNSIGNED(SPECIAL_LEFTSHIFT
):
228 case SIGNED(SPECIAL_RIGHTSHIFT
):
232 case UNSIGNED(SPECIAL_RIGHTSHIFT
):
239 mask
= mask
| (mask
-1);
240 expr
->value
= v
& mask
;
241 expr
->type
= EXPR_VALUE
;
244 warning(expr
->pos
, "division by zero");
247 warning(expr
->pos
, "constant integer operation overflow");
251 static int simplify_cmp_binop(struct expression
*expr
, struct symbol
*ctype
)
253 struct expression
*left
= expr
->left
, *right
= expr
->right
;
254 unsigned long long l
, r
, mask
;
255 signed long long sl
, sr
;
257 if (left
->type
!= EXPR_VALUE
|| right
->type
!= EXPR_VALUE
)
259 l
= left
->value
; r
= right
->value
;
260 mask
= 1ULL << (ctype
->bit_size
-1);
267 case '<': expr
->value
= sl
< sr
; break;
268 case '>': expr
->value
= sl
> sr
; break;
269 case SPECIAL_LTE
: expr
->value
= sl
<= sr
; break;
270 case SPECIAL_GTE
: expr
->value
= sl
>= sr
; break;
271 case SPECIAL_EQUAL
: expr
->value
= l
== r
; break;
272 case SPECIAL_NOTEQUAL
: expr
->value
= l
!= r
; break;
273 case SPECIAL_UNSIGNED_LT
:expr
->value
= l
< r
; break;
274 case SPECIAL_UNSIGNED_GT
:expr
->value
= l
> r
; break;
275 case SPECIAL_UNSIGNED_LTE
:expr
->value
= l
<= r
; break;
276 case SPECIAL_UNSIGNED_GTE
:expr
->value
= l
>= r
; break;
278 expr
->type
= EXPR_VALUE
;
282 static int simplify_float_binop(struct expression
*expr
)
284 struct expression
*left
= expr
->left
, *right
= expr
->right
;
285 unsigned long mod
= expr
->ctype
->ctype
.modifiers
;
286 long double l
, r
, res
;
288 if (left
->type
!= EXPR_FVALUE
|| right
->type
!= EXPR_FVALUE
)
294 if (mod
& MOD_LONGLONG
) {
296 case '+': res
= l
+ r
; break;
297 case '-': res
= l
- r
; break;
298 case '*': res
= l
* r
; break;
299 case '/': if (!r
) goto Div
;
303 } else if (mod
& MOD_LONG
) {
305 case '+': res
= (double) l
+ (double) r
; break;
306 case '-': res
= (double) l
- (double) r
; break;
307 case '*': res
= (double) l
* (double) r
; break;
308 case '/': if (!r
) goto Div
;
309 res
= (double) l
/ (double) r
; break;
314 case '+': res
= (float)l
+ (float)r
; break;
315 case '-': res
= (float)l
- (float)r
; break;
316 case '*': res
= (float)l
* (float)r
; break;
317 case '/': if (!r
) goto Div
;
318 res
= (float)l
/ (float)r
; break;
322 expr
->type
= EXPR_FVALUE
;
326 warning(expr
->pos
, "division by zero");
330 static int simplify_float_cmp(struct expression
*expr
, struct symbol
*ctype
)
332 struct expression
*left
= expr
->left
, *right
= expr
->right
;
335 if (left
->type
!= EXPR_FVALUE
|| right
->type
!= EXPR_FVALUE
)
341 case '<': expr
->value
= l
< r
; break;
342 case '>': expr
->value
= l
> r
; break;
343 case SPECIAL_LTE
: expr
->value
= l
<= r
; break;
344 case SPECIAL_GTE
: expr
->value
= l
>= r
; break;
345 case SPECIAL_EQUAL
: expr
->value
= l
== r
; break;
346 case SPECIAL_NOTEQUAL
: expr
->value
= l
!= r
; break;
348 expr
->type
= EXPR_VALUE
;
352 static int expand_binop(struct expression
*expr
)
356 cost
= expand_expression(expr
->left
);
357 cost
+= expand_expression(expr
->right
);
358 if (simplify_int_binop(expr
, expr
->ctype
))
360 if (simplify_float_binop(expr
))
365 static int expand_logical(struct expression
*expr
)
367 struct expression
*left
= expr
->left
;
368 struct expression
*right
;
371 /* Do immediate short-circuiting ... */
372 cost
= expand_expression(left
);
373 if (left
->type
== EXPR_VALUE
) {
374 if (expr
->op
== SPECIAL_LOGICAL_AND
) {
376 expr
->type
= EXPR_VALUE
;
382 expr
->type
= EXPR_VALUE
;
390 rcost
= expand_expression(right
);
391 if (left
->type
== EXPR_VALUE
&& right
->type
== EXPR_VALUE
) {
393 * We know the left value doesn't matter, since
394 * otherwise we would have short-circuited it..
396 expr
->type
= EXPR_VALUE
;
397 expr
->value
= right
->value
!= 0;
402 * If the right side is safe and cheaper than a branch,
403 * just avoid the branch and turn it into a regular binop
406 if (rcost
< BRANCH_COST
) {
407 expr
->type
= EXPR_BINOP
;
408 rcost
-= BRANCH_COST
- 1;
411 return cost
+ BRANCH_COST
+ rcost
;
414 static int expand_comma(struct expression
*expr
)
418 cost
= expand_expression(expr
->left
);
419 cost
+= expand_expression(expr
->right
);
420 if (expr
->left
->type
== EXPR_VALUE
|| expr
->left
->type
== EXPR_FVALUE
)
421 *expr
= *expr
->right
;
425 #define MOD_IGN (MOD_VOLATILE | MOD_CONST)
427 static int compare_types(int op
, struct symbol
*left
, struct symbol
*right
)
431 return !type_difference(left
, right
, MOD_IGN
, MOD_IGN
);
432 case SPECIAL_NOTEQUAL
:
433 return type_difference(left
, right
, MOD_IGN
, MOD_IGN
) != NULL
;
435 return left
->bit_size
< right
->bit_size
;
437 return left
->bit_size
> right
->bit_size
;
439 return left
->bit_size
<= right
->bit_size
;
441 return left
->bit_size
>= right
->bit_size
;
446 static int expand_compare(struct expression
*expr
)
448 struct expression
*left
= expr
->left
, *right
= expr
->right
;
451 cost
= expand_expression(left
);
452 cost
+= expand_expression(right
);
454 /* Type comparison? */
455 if (left
&& right
&& left
->type
== EXPR_TYPE
&& right
->type
== EXPR_TYPE
) {
457 expr
->type
= EXPR_VALUE
;
458 expr
->value
= compare_types(op
, left
->symbol
, right
->symbol
);
461 if (simplify_cmp_binop(expr
, left
->ctype
))
463 if (simplify_float_cmp(expr
, left
->ctype
))
468 static int expand_conditional(struct expression
*expr
)
470 struct expression
*cond
= expr
->conditional
;
471 struct expression
*true = expr
->cond_true
;
472 struct expression
*false = expr
->cond_false
;
475 cond_cost
= expand_expression(cond
);
476 if (cond
->type
== EXPR_VALUE
) {
482 return expand_expression(expr
);
485 cost
= expand_expression(true);
486 cost
+= expand_expression(false);
488 if (cost
< SELECT_COST
) {
489 expr
->type
= EXPR_SELECT
;
490 cost
-= BRANCH_COST
- 1;
493 return cost
+ cond_cost
+ BRANCH_COST
;
496 static int expand_assignment(struct expression
*expr
)
498 expand_expression(expr
->left
);
499 expand_expression(expr
->right
);
503 static int expand_addressof(struct expression
*expr
)
505 return expand_expression(expr
->unop
);
508 static int expand_dereference(struct expression
*expr
)
510 struct expression
*unop
= expr
->unop
;
512 expand_expression(unop
);
515 * NOTE! We get a bogus warning right now for some special
516 * cases: apparently I've screwed up the optimization of
517 * a zero-offset derefence, and the ctype is wrong.
519 * Leave the warning in anyway, since this is also a good
520 * test for me to get the type evaluation right..
522 if (expr
->ctype
->ctype
.modifiers
& MOD_NODEREF
)
523 warning(unop
->pos
, "dereference of noderef expression");
525 if (unop
->type
== EXPR_SYMBOL
) {
526 struct symbol
*sym
= unop
->symbol
;
528 /* Const symbol with a constant initializer? */
529 if (!(sym
->ctype
.modifiers
& (MOD_ASSIGNED
| MOD_ADDRESSABLE
))) {
530 struct expression
*value
= sym
->initializer
;
532 if (value
->type
== EXPR_VALUE
) {
533 expr
->type
= EXPR_VALUE
;
534 expr
->value
= value
->value
;
536 } else if (value
->type
== EXPR_FVALUE
) {
537 expr
->type
= EXPR_FVALUE
;
538 expr
->fvalue
= value
->fvalue
;
544 /* Direct symbol dereference? Cheap and safe */
545 return (sym
->ctype
.modifiers
& (MOD_STATIC
| MOD_EXTERN
)) ? 2 : 1;
550 static int simplify_preop(struct expression
*expr
)
552 struct expression
*op
= expr
->unop
;
553 unsigned long long v
, mask
;
555 if (op
->type
!= EXPR_VALUE
)
558 mask
= 1ULL << (expr
->ctype
->bit_size
-1);
563 if (v
== mask
&& !(expr
->ctype
->ctype
.modifiers
& MOD_UNSIGNED
))
567 case '!': v
= !v
; break;
568 case '~': v
= ~v
; break;
571 mask
= mask
| (mask
-1);
572 expr
->value
= v
& mask
;
573 expr
->type
= EXPR_VALUE
;
577 warning(expr
->pos
, "constant integer operation overflow");
581 static int simplify_float_preop(struct expression
*expr
)
583 struct expression
*op
= expr
->unop
;
586 if (op
->type
!= EXPR_FVALUE
)
591 case '-': v
= -v
; break;
595 expr
->type
= EXPR_FVALUE
;
600 * Unary post-ops: x++ and x--
602 static int expand_postop(struct expression
*expr
)
604 expand_expression(expr
->unop
);
608 static int expand_preop(struct expression
*expr
)
614 return expand_dereference(expr
);
617 return expand_addressof(expr
);
619 case SPECIAL_INCREMENT
:
620 case SPECIAL_DECREMENT
:
622 * From a type evaluation standpoint the pre-ops are
623 * the same as the postops
625 return expand_postop(expr
);
630 cost
= expand_expression(expr
->unop
);
632 if (simplify_preop(expr
))
634 if (simplify_float_preop(expr
))
639 static int expand_arguments(struct expression_list
*head
)
642 struct expression
*expr
;
644 FOR_EACH_PTR (head
, expr
) {
645 cost
+= expand_expression(expr
);
646 } END_FOR_EACH_PTR(expr
);
650 static int expand_cast(struct expression
*expr
)
653 struct expression
*target
= expr
->cast_expression
;
655 cost
= expand_expression(target
);
657 /* Simplify normal integer casts.. */
658 if (target
->type
== EXPR_VALUE
|| target
->type
== EXPR_FVALUE
) {
659 cast_value(expr
, expr
->ctype
, target
, target
->ctype
);
665 /* The arguments are constant if the cost of all of them is zero */
666 int expand_constant_p(struct expression
*expr
, int cost
)
668 expr
->type
= EXPR_VALUE
;
673 /* The arguments are safe, if their cost is less than SIDE_EFFECTS */
674 int expand_safe_p(struct expression
*expr
, int cost
)
676 expr
->type
= EXPR_VALUE
;
677 expr
->value
= (cost
< SIDE_EFFECTS
);
682 * expand a call expression with a symbol. This
683 * should expand builtins.
685 static int expand_symbol_call(struct expression
*expr
, int cost
)
687 struct expression
*fn
= expr
->fn
;
688 struct symbol
*ctype
= fn
->ctype
;
690 if (fn
->type
!= EXPR_PREOP
)
693 if (ctype
->op
&& ctype
->op
->expand
)
694 return ctype
->op
->expand(expr
, cost
);
699 static int expand_call(struct expression
*expr
)
703 struct expression
*fn
= expr
->fn
;
705 cost
= expand_arguments(expr
->args
);
708 error(expr
->pos
, "function has no type");
711 if (sym
->type
== SYM_NODE
)
712 return expand_symbol_call(expr
, cost
);
717 static int expand_expression_list(struct expression_list
*list
)
720 struct expression
*expr
;
722 FOR_EACH_PTR(list
, expr
) {
723 cost
+= expand_expression(expr
);
724 } END_FOR_EACH_PTR(expr
);
729 * We can simplify nested position expressions if
730 * this is a simple (single) positional expression.
732 static int expand_pos_expression(struct expression
*expr
)
734 struct expression
*nested
= expr
->init_expr
;
735 unsigned long offset
= expr
->init_offset
;
736 int nr
= expr
->init_nr
;
739 switch (nested
->type
) {
741 offset
+= nested
->init_offset
;
743 expr
->init_offset
= offset
;
747 case EXPR_INITIALIZER
: {
748 struct expression
*reuse
= nested
, *entry
;
750 FOR_EACH_PTR(expr
->expr_list
, entry
) {
751 if (entry
->type
== EXPR_POS
) {
752 entry
->init_offset
+= offset
;
756 * This happens rarely, but it can happen
757 * with bitfields that are all at offset
760 reuse
= alloc_expression(entry
->pos
, EXPR_POS
);
762 reuse
->type
= EXPR_POS
;
763 reuse
->ctype
= entry
->ctype
;
764 reuse
->init_offset
= offset
;
766 reuse
->init_expr
= entry
;
767 REPLACE_CURRENT_PTR(entry
, reuse
);
770 } END_FOR_EACH_PTR(entry
);
779 return expand_expression(nested
);
782 static int compare_expressions(const void *_a
, const void *_b
)
784 const struct expression
*a
= _a
;
785 const struct expression
*b
= _b
;
788 r
= (b
->type
!= EXPR_POS
) - (a
->type
!= EXPR_POS
);
791 if (a
->init_offset
< b
->init_offset
)
793 if (a
->init_offset
> b
->init_offset
)
795 /* Check bitfield offset.. */
799 if (a
->ctype
&& b
->ctype
) {
800 if (a
->ctype
->bit_offset
< b
->ctype
->bit_offset
)
808 static void sort_expression_list(struct expression_list
**list
)
810 sort_list((struct ptr_list
**)list
, compare_expressions
);
813 static int expand_expression(struct expression
*expr
)
820 switch (expr
->type
) {
827 return expand_symbol_expression(expr
);
829 return expand_binop(expr
);
832 return expand_logical(expr
);
835 return expand_comma(expr
);
838 return expand_compare(expr
);
840 case EXPR_ASSIGNMENT
:
841 return expand_assignment(expr
);
844 return expand_preop(expr
);
847 return expand_postop(expr
);
850 case EXPR_IMPLIED_CAST
:
851 return expand_cast(expr
);
854 return expand_call(expr
);
857 warning(expr
->pos
, "we should not have an EXPR_DEREF left at expansion time");
861 case EXPR_CONDITIONAL
:
862 return expand_conditional(expr
);
864 case EXPR_STATEMENT
: {
865 struct statement
*stmt
= expr
->statement
;
866 int cost
= expand_statement(stmt
);
868 if (stmt
->type
== STMT_EXPRESSION
&& stmt
->expression
)
869 *expr
= *stmt
->expression
;
876 case EXPR_INITIALIZER
:
877 sort_expression_list(&expr
->expr_list
);
878 return expand_expression_list(expr
->expr_list
);
880 case EXPR_IDENTIFIER
:
887 return expand_expression(expr
->base
) + 1;
890 return expand_pos_expression(expr
);
895 warning(expr
->pos
, "internal front-end error: sizeof in expansion?");
901 static void expand_const_expression(struct expression
*expr
, const char *where
)
904 expand_expression(expr
);
905 if (expr
->type
!= EXPR_VALUE
)
906 warning(expr
->pos
, "Expected constant expression in %s", where
);
910 void expand_symbol(struct symbol
*sym
)
912 struct symbol
*base_type
;
916 base_type
= sym
->ctype
.base_type
;
920 expand_expression(sym
->initializer
);
921 /* expand the body of the symbol */
922 if (base_type
->type
== SYM_FN
) {
924 expand_statement(base_type
->stmt
);
928 static void expand_return_expression(struct statement
*stmt
)
930 expand_expression(stmt
->expression
);
933 static int expand_if_statement(struct statement
*stmt
)
935 struct expression
*expr
= stmt
->if_conditional
;
937 if (!expr
|| !expr
->ctype
)
940 expand_expression(expr
);
942 /* This is only valid if nobody jumps into the "dead" side */
944 /* Simplify constant conditionals without even evaluating the false side */
945 if (expr
->type
== EXPR_VALUE
) {
946 struct statement
*simple
;
947 simple
= expr
->value
? stmt
->if_true
: stmt
->if_false
;
951 stmt
->type
= STMT_NONE
;
954 expand_statement(simple
);
959 expand_statement(stmt
->if_true
);
960 expand_statement(stmt
->if_false
);
965 * Expanding a compound statement is really just
966 * about adding up the costs of each individual
969 * We also collapse a simple compound statement:
970 * this would trigger for simple inline functions,
971 * except we would have to check the "return"
972 * symbol usage. Next time.
974 static int expand_compound(struct statement
*stmt
)
977 struct statement
*s
, *last
;
978 int cost
, symbols
, statements
;
981 FOR_EACH_PTR(stmt
->syms
, sym
) {
984 } END_FOR_EACH_PTR(sym
);
988 expand_symbol(stmt
->ret
);
994 FOR_EACH_PTR(stmt
->stmts
, s
) {
997 cost
+= expand_statement(s
);
998 } END_FOR_EACH_PTR(s
);
1000 if (!symbols
&& statements
== 1)
1006 static int expand_statement(struct statement
*stmt
)
1011 switch (stmt
->type
) {
1013 expand_return_expression(stmt
);
1014 return SIDE_EFFECTS
;
1016 case STMT_EXPRESSION
:
1017 return expand_expression(stmt
->expression
);
1020 return expand_compound(stmt
);
1023 return expand_if_statement(stmt
);
1026 expand_expression(stmt
->iterator_pre_condition
);
1027 expand_expression(stmt
->iterator_post_condition
);
1028 expand_statement(stmt
->iterator_pre_statement
);
1029 expand_statement(stmt
->iterator_statement
);
1030 expand_statement(stmt
->iterator_post_statement
);
1031 return SIDE_EFFECTS
;
1034 expand_expression(stmt
->switch_expression
);
1035 expand_statement(stmt
->switch_statement
);
1036 return SIDE_EFFECTS
;
1039 expand_const_expression(stmt
->case_expression
, "case statement");
1040 expand_const_expression(stmt
->case_to
, "case statement");
1041 expand_statement(stmt
->case_statement
);
1042 return SIDE_EFFECTS
;
1045 expand_statement(stmt
->label_statement
);
1046 return SIDE_EFFECTS
;
1049 expand_expression(stmt
->goto_expression
);
1050 return SIDE_EFFECTS
;
1055 /* FIXME! Do the asm parameter evaluation! */
1058 expand_expression(stmt
->expression
);
1061 expand_expression(stmt
->range_expression
);
1062 expand_expression(stmt
->range_low
);
1063 expand_expression(stmt
->range_high
);
1066 return SIDE_EFFECTS
;
1069 long long get_expression_value(struct expression
*expr
)
1071 long long value
, mask
;
1072 struct symbol
*ctype
;
1076 ctype
= evaluate_expression(expr
);
1078 warning(expr
->pos
, "bad constant expression type");
1081 expand_expression(expr
);
1082 if (expr
->type
!= EXPR_VALUE
) {
1083 warning(expr
->pos
, "bad constant expression");
1087 value
= expr
->value
;
1088 mask
= 1ULL << (ctype
->bit_size
-1);
1091 while (ctype
->type
!= SYM_BASETYPE
)
1092 ctype
= ctype
->ctype
.base_type
;
1093 if (!(ctype
->ctype
.modifiers
& MOD_UNSIGNED
))
1094 value
= value
| mask
| ~(mask
-1);