1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
19 HASHTABLE_DEFINE(expr_hashtable
, EXPR_HASHSIZE
);
21 static struct expr
*expr_eliminate_yn(struct expr
*e
);
24 * expr_lookup - return the expression with the given type and sub-nodes
25 * This looks up an expression with the specified type and sub-nodes. If such
26 * an expression is found in the hash table, it is returned. Otherwise, a new
27 * expression node is allocated and added to the hash table.
28 * @type: expression type
33 static struct expr
*expr_lookup(enum expr_type type
, void *l
, void *r
)
38 hash
= hash_32((unsigned int)type
^ hash_ptr(l
) ^ hash_ptr(r
));
40 hash_for_each_possible(expr_hashtable
, e
, node
, hash
) {
41 if (e
->type
== type
&& e
->left
._initdata
== l
&&
42 e
->right
._initdata
== r
)
46 e
= xmalloc(sizeof(*e
));
48 e
->left
._initdata
= l
;
49 e
->right
._initdata
= r
;
50 e
->val_is_valid
= false;
52 hash_add(expr_hashtable
, &e
->node
, hash
);
57 struct expr
*expr_alloc_symbol(struct symbol
*sym
)
59 return expr_lookup(E_SYMBOL
, sym
, NULL
);
62 struct expr
*expr_alloc_one(enum expr_type type
, struct expr
*ce
)
64 return expr_lookup(type
, ce
, NULL
);
67 struct expr
*expr_alloc_two(enum expr_type type
, struct expr
*e1
, struct expr
*e2
)
69 return expr_lookup(type
, e1
, e2
);
72 struct expr
*expr_alloc_comp(enum expr_type type
, struct symbol
*s1
, struct symbol
*s2
)
74 return expr_lookup(type
, s1
, s2
);
77 struct expr
*expr_alloc_and(struct expr
*e1
, struct expr
*e2
)
81 return e2
? expr_alloc_two(E_AND
, e1
, e2
) : e1
;
84 struct expr
*expr_alloc_or(struct expr
*e1
, struct expr
*e2
)
88 return e2
? expr_alloc_two(E_OR
, e1
, e2
) : e1
;
91 static int trans_count
;
94 * expr_eliminate_eq() helper.
96 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
97 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
98 * against all other leaves. Two equal leaves are both replaced with either 'y'
99 * or 'n' as appropriate for 'type', to be eliminated later.
101 static void __expr_eliminate_eq(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
105 /* Recurse down to leaves */
107 if ((*ep1
)->type
== type
) {
108 l
= (*ep1
)->left
.expr
;
109 r
= (*ep1
)->right
.expr
;
110 __expr_eliminate_eq(type
, &l
, ep2
);
111 __expr_eliminate_eq(type
, &r
, ep2
);
112 *ep1
= expr_alloc_two(type
, l
, r
);
115 if ((*ep2
)->type
== type
) {
116 l
= (*ep2
)->left
.expr
;
117 r
= (*ep2
)->right
.expr
;
118 __expr_eliminate_eq(type
, ep1
, &l
);
119 __expr_eliminate_eq(type
, ep1
, &r
);
120 *ep2
= expr_alloc_two(type
, l
, r
);
124 /* *ep1 and *ep2 are leaves. Compare them. */
126 if ((*ep1
)->type
== E_SYMBOL
&& (*ep2
)->type
== E_SYMBOL
&&
127 (*ep1
)->left
.sym
== (*ep2
)->left
.sym
&&
128 ((*ep1
)->left
.sym
== &symbol_yes
|| (*ep1
)->left
.sym
== &symbol_no
))
130 if (!expr_eq(*ep1
, *ep2
))
133 /* *ep1 and *ep2 are equal leaves. Prepare them for elimination. */
138 *ep1
= expr_alloc_symbol(&symbol_no
);
139 *ep2
= expr_alloc_symbol(&symbol_no
);
142 *ep1
= expr_alloc_symbol(&symbol_yes
);
143 *ep2
= expr_alloc_symbol(&symbol_yes
);
151 * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
152 * Example reductions:
154 * ep1: A && B -> ep1: y
155 * ep2: A && B && C -> ep2: C
157 * ep1: A || B -> ep1: n
158 * ep2: A || B || C -> ep2: C
160 * ep1: A && (B && FOO) -> ep1: FOO
161 * ep2: (BAR && B) && A -> ep2: BAR
163 * ep1: A && (B || C) -> ep1: y
164 * ep2: (C || B) && A -> ep2: y
166 * Comparisons are done between all operands at the same "level" of && or ||.
167 * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the
168 * following operands will be compared:
170 * - 'e1', 'e2 || e3', and 'e4 || e5', against each other
174 * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
175 * '(e1 && e2) && e3' are both a single level.
177 * See __expr_eliminate_eq() as well.
179 void expr_eliminate_eq(struct expr
**ep1
, struct expr
**ep2
)
183 switch ((*ep1
)->type
) {
186 __expr_eliminate_eq((*ep1
)->type
, ep1
, ep2
);
190 if ((*ep1
)->type
!= (*ep2
)->type
) switch ((*ep2
)->type
) {
193 __expr_eliminate_eq((*ep2
)->type
, ep1
, ep2
);
197 *ep1
= expr_eliminate_yn(*ep1
);
198 *ep2
= expr_eliminate_yn(*ep2
);
202 * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two
203 * &&/|| expressions are considered equal if every operand in one expression
204 * equals some operand in the other (operands do not need to appear in the same
205 * order), recursively.
207 bool expr_eq(struct expr
*e1
, struct expr
*e2
)
213 * A NULL expr is taken to be yes, but there's also a different way to
214 * represent yes. expr_is_yes() checks for either representation.
217 return expr_is_yes(e1
) && expr_is_yes(e2
);
219 if (e1
->type
!= e2
->type
)
228 return e1
->left
.sym
== e2
->left
.sym
&& e1
->right
.sym
== e2
->right
.sym
;
230 return e1
->left
.sym
== e2
->left
.sym
;
232 return expr_eq(e1
->left
.expr
, e2
->left
.expr
);
235 old_count
= trans_count
;
236 expr_eliminate_eq(&e1
, &e2
);
237 res
= (e1
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
&&
238 e1
->left
.sym
== e2
->left
.sym
);
239 trans_count
= old_count
;
247 expr_fprint(e1
, stdout
);
249 expr_fprint(e2
, stdout
);
257 * Recursively performs the following simplifications (as well as the
258 * corresponding simplifications with swapped operands):
265 * Returns the optimized expression.
267 static struct expr
*expr_eliminate_yn(struct expr
*e
)
271 if (e
) switch (e
->type
) {
273 l
= expr_eliminate_yn(e
->left
.expr
);
274 r
= expr_eliminate_yn(e
->right
.expr
);
275 if (l
->type
== E_SYMBOL
) {
276 if (l
->left
.sym
== &symbol_no
)
278 else if (l
->left
.sym
== &symbol_yes
)
281 if (r
->type
== E_SYMBOL
) {
282 if (r
->left
.sym
== &symbol_no
)
284 else if (r
->left
.sym
== &symbol_yes
)
289 l
= expr_eliminate_yn(e
->left
.expr
);
290 r
= expr_eliminate_yn(e
->right
.expr
);
291 if (l
->type
== E_SYMBOL
) {
292 if (l
->left
.sym
== &symbol_no
)
294 else if (l
->left
.sym
== &symbol_yes
)
297 if (r
->type
== E_SYMBOL
) {
298 if (r
->left
.sym
== &symbol_no
)
300 else if (r
->left
.sym
== &symbol_yes
)
313 static struct expr
*expr_join_or(struct expr
*e1
, struct expr
*e2
)
316 struct symbol
*sym1
, *sym2
;
320 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
322 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
324 if (e1
->type
== E_NOT
) {
326 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
328 sym1
= tmp
->left
.sym
;
331 if (e2
->type
== E_NOT
) {
332 if (e2
->left
.expr
->type
!= E_SYMBOL
)
334 sym2
= e2
->left
.expr
->left
.sym
;
339 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
341 if (sym1
->type
== S_TRISTATE
) {
342 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
343 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
344 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
))) {
345 // (a='y') || (a='m') -> (a!='n')
346 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_no
);
348 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
349 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
350 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
))) {
351 // (a='y') || (a='n') -> (a!='m')
352 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_mod
);
354 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
355 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
356 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
))) {
357 // (a='m') || (a='n') -> (a!='y')
358 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_yes
);
361 if (sym1
->type
== S_BOOLEAN
) {
363 if ((e1
->type
== E_NOT
&& e1
->left
.expr
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
) ||
364 (e2
->type
== E_NOT
&& e2
->left
.expr
->type
== E_SYMBOL
&& e1
->type
== E_SYMBOL
))
365 return expr_alloc_symbol(&symbol_yes
);
369 printf("optimize (");
370 expr_fprint(e1
, stdout
);
372 expr_fprint(e2
, stdout
);
378 static struct expr
*expr_join_and(struct expr
*e1
, struct expr
*e2
)
381 struct symbol
*sym1
, *sym2
;
385 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
387 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
389 if (e1
->type
== E_NOT
) {
391 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
393 sym1
= tmp
->left
.sym
;
396 if (e2
->type
== E_NOT
) {
397 if (e2
->left
.expr
->type
!= E_SYMBOL
)
399 sym2
= e2
->left
.expr
->left
.sym
;
404 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
407 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
408 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_yes
))
409 // (a) && (a='y') -> (a='y')
410 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
412 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_no
) ||
413 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_no
))
414 // (a) && (a!='n') -> (a)
415 return expr_alloc_symbol(sym1
);
417 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
418 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_mod
))
419 // (a) && (a!='m') -> (a='y')
420 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
422 if (sym1
->type
== S_TRISTATE
) {
423 if (e1
->type
== E_EQUAL
&& e2
->type
== E_UNEQUAL
) {
424 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
425 sym2
= e1
->right
.sym
;
426 if ((e2
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
427 return sym2
!= e2
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
428 : expr_alloc_symbol(&symbol_no
);
430 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_EQUAL
) {
431 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
432 sym2
= e2
->right
.sym
;
433 if ((e1
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
434 return sym2
!= e1
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
435 : expr_alloc_symbol(&symbol_no
);
437 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
438 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
439 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
)))
440 // (a!='y') && (a!='n') -> (a='m')
441 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_mod
);
443 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
444 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
445 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
)))
446 // (a!='y') && (a!='m') -> (a='n')
447 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_no
);
449 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
450 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
451 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
)))
452 // (a!='m') && (a!='n') -> (a='m')
453 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
455 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
456 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_mod
) ||
457 (e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
458 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_yes
))
463 printf("optimize (");
464 expr_fprint(e1
, stdout
);
466 expr_fprint(e2
, stdout
);
473 * expr_eliminate_dups() helper.
475 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
476 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
477 * against all other leaves to look for simplifications.
479 static void expr_eliminate_dups1(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
481 struct expr
*tmp
, *l
, *r
;
483 /* Recurse down to leaves */
485 if ((*ep1
)->type
== type
) {
486 l
= (*ep1
)->left
.expr
;
487 r
= (*ep1
)->right
.expr
;
488 expr_eliminate_dups1(type
, &l
, ep2
);
489 expr_eliminate_dups1(type
, &r
, ep2
);
490 *ep1
= expr_alloc_two(type
, l
, r
);
493 if ((*ep2
)->type
== type
) {
494 l
= (*ep2
)->left
.expr
;
495 r
= (*ep2
)->right
.expr
;
496 expr_eliminate_dups1(type
, ep1
, &l
);
497 expr_eliminate_dups1(type
, ep1
, &r
);
498 *ep2
= expr_alloc_two(type
, l
, r
);
502 /* *ep1 and *ep2 are leaves. Compare and process them. */
506 tmp
= expr_join_or(*ep1
, *ep2
);
508 *ep1
= expr_alloc_symbol(&symbol_no
);
514 tmp
= expr_join_and(*ep1
, *ep2
);
516 *ep1
= expr_alloc_symbol(&symbol_yes
);
527 * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
530 * Example simplifications:
532 * A || B || A -> A || B
533 * A && B && A=y -> A=y && B
535 * Returns the deduplicated expression.
537 struct expr
*expr_eliminate_dups(struct expr
*e
)
543 oldcount
= trans_count
;
549 case E_OR
: case E_AND
:
550 l
= expr_eliminate_dups(e
->left
.expr
);
551 r
= expr_eliminate_dups(e
->right
.expr
);
552 expr_eliminate_dups1(e
->type
, &l
, &r
);
553 e
= expr_alloc_two(e
->type
, l
, r
);
557 e
= expr_eliminate_yn(e
);
558 } while (trans_count
); /* repeat until we get no more simplifications */
559 trans_count
= oldcount
;
564 * Performs various simplifications involving logical operators and
583 * !(A || B) -> !A && !B
584 * !(A && B) -> !A || !B
591 * Allocates and returns a new expression.
593 struct expr
*expr_transform(struct expr
*e
)
607 e
= expr_alloc_two(e
->type
,
608 expr_transform(e
->left
.expr
),
609 expr_transform(e
->right
.expr
));
614 if (e
->left
.sym
->type
!= S_BOOLEAN
)
616 if (e
->right
.sym
== &symbol_no
) {
618 e
= expr_alloc_one(E_NOT
, expr_alloc_symbol(e
->left
.sym
));
621 if (e
->right
.sym
== &symbol_mod
) {
623 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e
->left
.sym
->name
);
624 e
= expr_alloc_symbol(&symbol_no
);
627 if (e
->right
.sym
== &symbol_yes
) {
629 e
= expr_alloc_symbol(e
->left
.sym
);
634 if (e
->left
.sym
->type
!= S_BOOLEAN
)
636 if (e
->right
.sym
== &symbol_no
) {
638 e
= expr_alloc_symbol(e
->left
.sym
);
641 if (e
->right
.sym
== &symbol_mod
) {
643 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e
->left
.sym
->name
);
644 e
= expr_alloc_symbol(&symbol_yes
);
647 if (e
->right
.sym
== &symbol_yes
) {
649 e
= expr_alloc_one(E_NOT
, e
->left
.expr
);
654 switch (e
->left
.expr
->type
) {
657 e
= e
->left
.expr
->left
.expr
;
662 e
= expr_alloc_comp(e
->left
.expr
->type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
,
663 e
->left
.expr
->left
.sym
,
664 e
->left
.expr
->right
.sym
);
669 e
= expr_alloc_comp(e
->left
.expr
->type
== E_LEQ
? E_GTH
: E_LTH
,
670 e
->left
.expr
->left
.sym
,
671 e
->left
.expr
->right
.sym
);
676 e
= expr_alloc_comp(e
->left
.expr
->type
== E_LTH
? E_GEQ
: E_LEQ
,
677 e
->left
.expr
->left
.sym
,
678 e
->left
.expr
->right
.sym
);
681 // !(A || B) -> !A && !B
682 e
= expr_alloc_and(expr_alloc_one(E_NOT
, e
->left
.expr
->left
.expr
),
683 expr_alloc_one(E_NOT
, e
->left
.expr
->right
.expr
));
684 e
= expr_transform(e
);
687 // !(A && B) -> !A || !B
688 e
= expr_alloc_or(expr_alloc_one(E_NOT
, e
->left
.expr
->left
.expr
),
689 expr_alloc_one(E_NOT
, e
->left
.expr
->right
.expr
));
690 e
= expr_transform(e
);
693 if (e
->left
.expr
->left
.sym
== &symbol_yes
)
695 e
= expr_alloc_symbol(&symbol_no
);
696 else if (e
->left
.expr
->left
.sym
== &symbol_mod
)
698 e
= expr_alloc_symbol(&symbol_mod
);
699 else if (e
->left
.expr
->left
.sym
== &symbol_no
)
701 e
= expr_alloc_symbol(&symbol_yes
);
713 bool expr_contains_symbol(struct expr
*dep
, struct symbol
*sym
)
721 return expr_contains_symbol(dep
->left
.expr
, sym
) ||
722 expr_contains_symbol(dep
->right
.expr
, sym
);
724 return dep
->left
.sym
== sym
;
731 return dep
->left
.sym
== sym
||
732 dep
->right
.sym
== sym
;
734 return expr_contains_symbol(dep
->left
.expr
, sym
);
741 bool expr_depends_symbol(struct expr
*dep
, struct symbol
*sym
)
748 return expr_depends_symbol(dep
->left
.expr
, sym
) ||
749 expr_depends_symbol(dep
->right
.expr
, sym
);
751 return dep
->left
.sym
== sym
;
753 if (dep
->left
.sym
== sym
) {
754 if (dep
->right
.sym
== &symbol_yes
|| dep
->right
.sym
== &symbol_mod
)
759 if (dep
->left
.sym
== sym
) {
760 if (dep
->right
.sym
== &symbol_no
)
771 * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
774 * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
778 * A && B -> !(A=n || B=n)
779 * A || B -> !(A=n && B=n)
780 * A && (B || C) -> !(A=n || (B=n && C=n))
782 * Allocates and returns a new expression.
784 struct expr
*expr_trans_compare(struct expr
*e
, enum expr_type type
, struct symbol
*sym
)
786 struct expr
*e1
, *e2
;
789 e
= expr_alloc_symbol(sym
);
790 if (type
== E_UNEQUAL
)
791 e
= expr_alloc_one(E_NOT
, e
);
796 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
797 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
798 if (sym
== &symbol_yes
)
799 e
= expr_alloc_two(E_AND
, e1
, e2
);
800 if (sym
== &symbol_no
)
801 e
= expr_alloc_two(E_OR
, e1
, e2
);
802 if (type
== E_UNEQUAL
)
803 e
= expr_alloc_one(E_NOT
, e
);
806 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
807 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
808 if (sym
== &symbol_yes
)
809 e
= expr_alloc_two(E_OR
, e1
, e2
);
810 if (sym
== &symbol_no
)
811 e
= expr_alloc_two(E_AND
, e1
, e2
);
812 if (type
== E_UNEQUAL
)
813 e
= expr_alloc_one(E_NOT
, e
);
816 return expr_trans_compare(e
->left
.expr
, type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
, sym
);
823 if (type
== E_EQUAL
) {
824 if (sym
== &symbol_yes
)
826 if (sym
== &symbol_mod
)
827 return expr_alloc_symbol(&symbol_no
);
828 if (sym
== &symbol_no
)
829 return expr_alloc_one(E_NOT
, e
);
831 if (sym
== &symbol_yes
)
832 return expr_alloc_one(E_NOT
, e
);
833 if (sym
== &symbol_mod
)
834 return expr_alloc_symbol(&symbol_yes
);
835 if (sym
== &symbol_no
)
840 return expr_alloc_comp(type
, e
->left
.sym
, sym
);
848 enum string_value_kind
{
855 unsigned long long u
;
859 static enum string_value_kind
expr_parse_string(const char *str
,
860 enum symbol_type type
,
861 union string_value
*val
)
864 enum string_value_kind kind
;
870 val
->s
= !strcmp(str
, "n") ? 0 :
871 !strcmp(str
, "m") ? 1 :
872 !strcmp(str
, "y") ? 2 : -1;
875 val
->s
= strtoll(str
, &tail
, 10);
879 val
->u
= strtoull(str
, &tail
, 16);
883 val
->s
= strtoll(str
, &tail
, 0);
887 return !errno
&& !*tail
&& tail
> str
&& isxdigit(tail
[-1])
891 static tristate
__expr_calc_value(struct expr
*e
)
894 const char *str1
, *str2
;
895 enum string_value_kind k1
= k_string
, k2
= k_string
;
896 union string_value lval
= {}, rval
= {};
901 sym_calc_value(e
->left
.sym
);
902 return e
->left
.sym
->curr
.tri
;
904 val1
= expr_calc_value(e
->left
.expr
);
905 val2
= expr_calc_value(e
->right
.expr
);
906 return EXPR_AND(val1
, val2
);
908 val1
= expr_calc_value(e
->left
.expr
);
909 val2
= expr_calc_value(e
->right
.expr
);
910 return EXPR_OR(val1
, val2
);
912 val1
= expr_calc_value(e
->left
.expr
);
913 return EXPR_NOT(val1
);
922 printf("expr_calc_value: %d?\n", e
->type
);
926 sym_calc_value(e
->left
.sym
);
927 sym_calc_value(e
->right
.sym
);
928 str1
= sym_get_string_value(e
->left
.sym
);
929 str2
= sym_get_string_value(e
->right
.sym
);
931 if (e
->left
.sym
->type
!= S_STRING
|| e
->right
.sym
->type
!= S_STRING
) {
932 k1
= expr_parse_string(str1
, e
->left
.sym
->type
, &lval
);
933 k2
= expr_parse_string(str2
, e
->right
.sym
->type
, &rval
);
936 if (k1
== k_string
|| k2
== k_string
)
937 res
= strcmp(str1
, str2
);
938 else if (k1
== k_unsigned
|| k2
== k_unsigned
)
939 res
= (lval
.u
> rval
.u
) - (lval
.u
< rval
.u
);
940 else /* if (k1 == k_signed && k2 == k_signed) */
941 res
= (lval
.s
> rval
.s
) - (lval
.s
< rval
.s
);
945 return res
? no
: yes
;
947 return res
>= 0 ? yes
: no
;
949 return res
> 0 ? yes
: no
;
951 return res
<= 0 ? yes
: no
;
953 return res
< 0 ? yes
: no
;
955 return res
? yes
: no
;
957 printf("expr_calc_value: relation %d?\n", e
->type
);
963 * expr_calc_value - return the tristate value of the given expression
965 * return: tristate value of the expression
967 tristate
expr_calc_value(struct expr
*e
)
972 if (!e
->val_is_valid
) {
973 e
->val
= __expr_calc_value(e
);
974 e
->val_is_valid
= true;
981 * expr_invalidate_all - invalidate all cached expression values
983 void expr_invalidate_all(void)
987 hash_for_each(expr_hashtable
, e
, node
)
988 e
->val_is_valid
= false;
991 static int expr_compare_type(enum expr_type t1
, enum expr_type t2
)
1000 if (t2
== E_EQUAL
|| t2
== E_UNEQUAL
)
1022 void expr_print(const struct expr
*e
,
1023 void (*fn
)(void *, struct symbol
*, const char *),
1024 void *data
, int prevtoken
)
1027 fn(data
, NULL
, "y");
1031 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1032 fn(data
, NULL
, "(");
1035 if (e
->left
.sym
->name
)
1036 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1038 fn(data
, NULL
, "<choice>");
1041 fn(data
, NULL
, "!");
1042 expr_print(e
->left
.expr
, fn
, data
, E_NOT
);
1045 if (e
->left
.sym
->name
)
1046 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1048 fn(data
, NULL
, "<choice>");
1049 fn(data
, NULL
, "=");
1050 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1054 if (e
->left
.sym
->name
)
1055 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1057 fn(data
, NULL
, "<choice>");
1058 fn(data
, NULL
, e
->type
== E_LEQ
? "<=" : "<");
1059 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1063 if (e
->left
.sym
->name
)
1064 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1066 fn(data
, NULL
, "<choice>");
1067 fn(data
, NULL
, e
->type
== E_GEQ
? ">=" : ">");
1068 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1071 if (e
->left
.sym
->name
)
1072 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1074 fn(data
, NULL
, "<choice>");
1075 fn(data
, NULL
, "!=");
1076 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1079 expr_print(e
->left
.expr
, fn
, data
, E_OR
);
1080 fn(data
, NULL
, " || ");
1081 expr_print(e
->right
.expr
, fn
, data
, E_OR
);
1084 expr_print(e
->left
.expr
, fn
, data
, E_AND
);
1085 fn(data
, NULL
, " && ");
1086 expr_print(e
->right
.expr
, fn
, data
, E_AND
);
1089 fn(data
, NULL
, "[");
1090 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1091 fn(data
, NULL
, " ");
1092 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1093 fn(data
, NULL
, "]");
1098 sprintf(buf
, "<unknown type %d>", e
->type
);
1099 fn(data
, NULL
, buf
);
1103 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1104 fn(data
, NULL
, ")");
1107 static void expr_print_file_helper(void *data
, struct symbol
*sym
, const char *str
)
1109 xfwrite(str
, strlen(str
), 1, data
);
1112 void expr_fprint(struct expr
*e
, FILE *out
)
1114 expr_print(e
, expr_print_file_helper
, out
, E_NONE
);
1117 static void expr_print_gstr_helper(void *data
, struct symbol
*sym
, const char *str
)
1119 struct gstr
*gs
= (struct gstr
*)data
;
1120 const char *sym_str
= NULL
;
1123 sym_str
= sym_get_string_value(sym
);
1125 if (gs
->max_width
) {
1126 unsigned extra_length
= strlen(str
);
1127 const char *last_cr
= strrchr(gs
->s
, '\n');
1128 unsigned last_line_length
;
1131 extra_length
+= 4 + strlen(sym_str
);
1136 last_line_length
= strlen(gs
->s
) - (last_cr
- gs
->s
);
1138 if ((last_line_length
+ extra_length
) > gs
->max_width
)
1139 str_append(gs
, "\\\n");
1142 str_append(gs
, str
);
1143 if (sym
&& sym
->type
!= S_UNKNOWN
)
1144 str_printf(gs
, " [=%s]", sym_str
);
1147 void expr_gstr_print(const struct expr
*e
, struct gstr
*gs
)
1149 expr_print(e
, expr_print_gstr_helper
, gs
, E_NONE
);
1153 * Transform the top level "||" tokens into newlines and prepend each
1154 * line with a minus. This makes expressions much easier to read.
1155 * Suitable for reverse dependency expressions.
1157 static void expr_print_revdep(struct expr
*e
,
1158 void (*fn
)(void *, struct symbol
*, const char *),
1159 void *data
, tristate pr_type
, const char **title
)
1161 if (e
->type
== E_OR
) {
1162 expr_print_revdep(e
->left
.expr
, fn
, data
, pr_type
, title
);
1163 expr_print_revdep(e
->right
.expr
, fn
, data
, pr_type
, title
);
1164 } else if (expr_calc_value(e
) == pr_type
) {
1166 fn(data
, NULL
, *title
);
1170 fn(data
, NULL
, " - ");
1171 expr_print(e
, fn
, data
, E_NONE
);
1172 fn(data
, NULL
, "\n");
1176 void expr_gstr_print_revdep(struct expr
*e
, struct gstr
*gs
,
1177 tristate pr_type
, const char *title
)
1179 expr_print_revdep(e
, expr_print_gstr_helper
, gs
, pr_type
, &title
);