xref: /plan9-contrib/sys/src/cmd/cc/com.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "cc.h"
2 
3 void
4 complex(Node *n)
5 {
6 
7 	if(n == Z)
8 		return;
9 
10 
11 	nearln = n->lineno;
12 	if(debug['t'])
13 		if(n->op != OCONST)
14 			prtree(n, "pre complex");
15 	if(tcom(n))
16 		return;
17 	if(debug['t'])
18 		if(n->op != OCONST)
19 			prtree(n, "t complex");
20 	ccom(n);
21 	if(debug['t'])
22 		if(n->op != OCONST)
23 			prtree(n, "c complex");
24 	acom(n);
25 	if(debug['t'])
26 		if(n->op != OCONST)
27 			prtree(n, "a complex");
28 	xcom(n);
29 	if(debug['t'])
30 		if(n->op != OCONST)
31 			prtree(n, "x complex");
32 }
33 
34 /*
35  * evaluate types
36  * evaluate lvalues (addable == 1)
37  */
38 enum
39 {
40 	ADDROF	= 1<<0,
41 	CASTOF	= 1<<1,
42 	ADDROP	= 1<<2,
43 };
44 
45 int
46 tcom(Node *n)
47 {
48 
49 	return tcomo(n, ADDROF);
50 }
51 
52 int
53 tcomo(Node *n, int f)
54 {
55 	Node *l, *r;
56 	Type *t;
57 	int o;
58 
59 	if(n == Z) {
60 		diag(Z, "Z in tcom");
61 		errorexit();
62 	}
63 	n->addable = 0;
64 	l = n->left;
65 	r = n->right;
66 
67 	switch(n->op) {
68 	default:
69 		diag(n, "unknown op in type complex: %O", n->op);
70 		goto bad;
71 
72 	case ODOTDOT:
73 		/*
74 		 * tcom has already been called on this subtree
75 		 */
76 		*n = *n->left;
77 		if(n->type == T)
78 			goto bad;
79 		break;
80 
81 	case OCAST:
82 		if(n->type == T)
83 			break;
84 		if(n->type->width == types[TLONG]->width) {
85 			if(tcomo(l, ADDROF|CASTOF))
86 					goto bad;
87 		} else
88 			if(tcom(l))
89 				goto bad;
90 		if(tcompat(n, l->type, n->type, tcast))
91 			goto bad;
92 		break;
93 
94 	case ORETURN:
95 		if(l == Z) {
96 			if(n->type->etype != TVOID)
97 				warn(n, "null return of a typed function");
98 			break;
99 		}
100 		if(tcom(l))
101 			goto bad;
102 		typeext(n->type, l);
103 		if(tcompat(n, n->type, l->type, tasign))
104 			break;
105 		if(!sametype(n->type, l->type)) {
106 			l = new1(OCAST, l, Z);
107 			l->type = n->type;
108 			n->left = l;
109 		}
110 		break;
111 
112 	case OAS:
113 		o = tcom(l);
114 		if(o | tcom(r))
115 			goto bad;
116 
117 		typeext(l->type, r);
118 		if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))
119 			goto bad;
120 		if(!sametype(l->type, r->type)) {
121 			r = new1(OCAST, r, Z);
122 			r->type = l->type;
123 			n->right = r;
124 		}
125 		n->type = l->type;
126 		break;
127 
128 	case OASADD:
129 	case OASSUB:
130 		o = tcom(l);
131 		if(o | tcom(r))
132 			goto bad;
133 		typeext1(l->type, r);
134 		if(tlvalue(l) || tcompat(n, l->type, r->type, tasadd))
135 			goto bad;
136 		t = l->type;
137 		arith(n, 0);
138 		while(n->left->op == OCAST)
139 			n->left = n->left->left;
140 		if(!sametype(t, n->type)) {
141 			r = new1(OCAST, n->right, Z);
142 			r->type = t;
143 			n->right = r;
144 			n->type = t;
145 		}
146 		break;
147 
148 	case OASMUL:
149 	case OASLMUL:
150 	case OASDIV:
151 	case OASLDIV:
152 		o = tcom(l);
153 		if(o | tcom(r))
154 			goto bad;
155 		typeext1(l->type, r);
156 		if(tlvalue(l) || tcompat(n, l->type, r->type, tmul))
157 			goto bad;
158 		t = l->type;
159 		arith(n, 0);
160 		while(n->left->op == OCAST)
161 			n->left = n->left->left;
162 		if(!sametype(t, n->type)) {
163 			r = new1(OCAST, n->right, Z);
164 			r->type = t;
165 			n->right = r;
166 			n->type = t;
167 		}
168 		if(typeu[n->type->etype]) {
169 			if(n->op == OASDIV)
170 				n->op = OASLDIV;
171 			if(n->op == OASMUL)
172 				n->op = OASLMUL;
173 		}
174 		break;
175 
176 	case OASLSHR:
177 	case OASASHR:
178 	case OASASHL:
179 		o = tcom(l);
180 		if(o | tcom(r))
181 			goto bad;
182 		if(tlvalue(l) || tcompat(n, l->type, r->type, tand))
183 			goto bad;
184 		n->type = l->type;
185 		if(typeu[n->type->etype]) {
186 			if(n->op == OASASHR)
187 				n->op = OASLSHR;
188 		}
189 		break;
190 
191 	case OASMOD:
192 	case OASLMOD:
193 	case OASOR:
194 	case OASAND:
195 	case OASXOR:
196 		o = tcom(l);
197 		if(o | tcom(r))
198 			goto bad;
199 		if(tlvalue(l) || tcompat(n, l->type, r->type, tand))
200 			goto bad;
201 		t = l->type;
202 		arith(n, 0);
203 		while(n->left->op == OCAST)
204 			n->left = n->left->left;
205 		if(!sametype(t, n->type)) {
206 			r = new1(OCAST, n->right, Z);
207 			r->type = t;
208 			n->right = r;
209 			n->type = t;
210 		}
211 		if(typeu[n->type->etype]) {
212 			if(n->op == OASMOD)
213 				n->op = OASLMOD;
214 		}
215 		break;
216 
217 	case OPREINC:
218 	case OPREDEC:
219 	case OPOSTINC:
220 	case OPOSTDEC:
221 		if(tcom(l))
222 			goto bad;
223 		if(tlvalue(l) || tcompat(n, l->type, tint, tadd))
224 			goto bad;
225 		n->type = l->type;
226 		if(n->type->etype == TIND)
227 		if(n->type->link->width < 1)
228 			diag(n, "illegal pointer operation");
229 		break;
230 
231 	case OEQ:
232 	case ONE:
233 		o = tcom(l);
234 		if(o | tcom(r))
235 			goto bad;
236 		typeext(l->type, r);
237 		typeext(r->type, l);
238 		if(tcompat(n, l->type, r->type, trel))
239 			goto bad;
240 		arith(n, 0);
241 		n->type = tint;
242 		break;
243 
244 	case OLT:
245 	case OGE:
246 	case OGT:
247 	case OLE:
248 		o = tcom(l);
249 		if(o | tcom(r))
250 			goto bad;
251 		typeext1(l->type, r);
252 		typeext1(r->type, l);
253 		if(tcompat(n, l->type, r->type, trel))
254 			goto bad;
255 		arith(n, 0);
256 		if(typeu[n->type->etype])
257 			n->op = logrel[relindex(n->op)];
258 		n->type = tint;
259 		break;
260 
261 	case OCOND:
262 		o = tcom(l);
263 		o |= tcom(r->left);
264 		if(o | tcom(r->right))
265 			goto bad;
266 		if(r->right->type->etype == TIND && vconst(r->left) == 0) {
267 			r->left->type = r->right->type;
268 			r->left->vconst = 0;
269 		}
270 		if(r->left->type->etype == TIND && vconst(r->right) == 0) {
271 			r->right->type = r->left->type;
272 			r->right->vconst = 0;
273 		}
274 		if(sametype(r->right->type, r->left->type)) {
275 			r->type = r->right->type;
276 			n->type = r->type;
277 			break;
278 		}
279 		if(tcompat(r, r->left->type, r->right->type, trel))
280 			goto bad;
281 		arith(r, 0);
282 		n->type = r->type;
283 		break;
284 
285 	case OADD:
286 		o = tcom(l);
287 		if(o | tcom(r))
288 			goto bad;
289 		if(tcompat(n, l->type, r->type, tadd))
290 			goto bad;
291 		arith(n, 1);
292 		break;
293 
294 	case OSUB:
295 		o = tcom(l);
296 		if(o | tcom(r))
297 			goto bad;
298 		if(tcompat(n, l->type, r->type, tsub))
299 			goto bad;
300 		arith(n, 1);
301 		break;
302 
303 	case OMUL:
304 	case OLMUL:
305 	case ODIV:
306 	case OLDIV:
307 		o = tcom(l);
308 		if(o | tcom(r))
309 			goto bad;
310 		if(tcompat(n, l->type, r->type, tmul))
311 			goto bad;
312 		arith(n, 1);
313 		if(typeu[n->type->etype]) {
314 			if(n->op == ODIV)
315 				n->op = OLDIV;
316 			if(n->op == OMUL)
317 				n->op = OLMUL;
318 		}
319 		break;
320 
321 	case OLSHR:
322 	case OASHL:
323 	case OASHR:
324 		o = tcom(l);
325 		if(o | tcom(r))
326 			goto bad;
327 		if(tcompat(n, l->type, r->type, tand))
328 			goto bad;
329 		n->right = Z;
330 		arith(n, 1);
331 		n->right = new1(OCAST, r, Z);
332 		n->right->type = tint;
333 		if(typeu[n->type->etype])
334 			if(n->op == OASHR)
335 				n->op = OLSHR;
336 		break;
337 
338 	case OAND:
339 	case OOR:
340 	case OXOR:
341 		o = tcom(l);
342 		if(o | tcom(r))
343 			goto bad;
344 		if(tcompat(n, l->type, r->type, tand))
345 			goto bad;
346 		arith(n, 1);
347 		break;
348 
349 	case OMOD:
350 	case OLMOD:
351 		o = tcom(l);
352 		if(o | tcom(r))
353 			goto bad;
354 		if(tcompat(n, l->type, r->type, tand))
355 			goto bad;
356 		arith(n, 1);
357 		if(typeu[n->type->etype])
358 			n->op = OLMOD;
359 		break;
360 
361 	case ONOT:
362 		if(tcom(l))
363 			goto bad;
364 		if(tcompat(n, T, l->type, tnot))
365 			goto bad;
366 		n->type = tint;
367 		break;
368 
369 	case OANDAND:
370 	case OOROR:
371 		o = tcom(l);
372 		if(o | tcom(r))
373 			goto bad;
374 		if(tcompat(n, T, l->type, tnot) |
375 		   tcompat(n, T, r->type, tnot))
376 			goto bad;
377 		n->type = tint;
378 		break;
379 
380 	case OCOMMA:
381 		o = tcom(l);
382 		if(o | tcom(r))
383 			goto bad;
384 		n->type = r->type;
385 		break;
386 
387 
388 	case OSIZE:
389 		if(l != Z) {
390 			if(l->op != OSTRING && l->op != OLSTRING)
391 				if(tcomo(l, 0))
392 					goto bad;
393 			if(l->op == OBIT) {
394 				diag(n, "sizeof bitfield");
395 				goto bad;
396 			}
397 			n->type = l->type;
398 		}
399 		if(n->type == T)
400 			goto bad;
401 		if(n->type->width <= 0) {
402 			diag(n, "sizeof undefined type");
403 			goto bad;
404 		}
405 		if(n->type->etype == TFUNC) {
406 			diag(n, "sizeof function");
407 			goto bad;
408 		}
409 		n->op = OCONST;
410 		n->left = Z;
411 		n->right = Z;
412 		n->vconst = convvtox(n->type->width, tint->etype);
413 		n->type = tint;
414 		break;
415 
416 	case OFUNC:
417 		o = tcomo(l, 0);
418 		if(o)
419 			goto bad;
420 		if(l->type->etype == TIND && l->type->link->etype == TFUNC) {
421 			l = new1(OIND, l, Z);
422 			l->type = l->left->type->link;
423 			n->left = l;
424 		}
425 		if(tcompat(n, T, l->type, tfunct))
426 			goto bad;
427 		if(o | tcoma(l, r, l->type->down, 1))
428 			goto bad;
429 		n->type = l->type->link;
430 		if(!debug['B'])
431 			if(l->type->down == T || l->type->down->etype == TOLD) {
432 				nerrors--;
433 				diag(n, "function args not checked: %F", l);
434 			}
435 		break;
436 
437 	case ONAME:
438 		if(n->type == T) {
439 			diag(n, "name not declared: %F", n);
440 			goto bad;
441 		}
442 		if(n->type->etype == TENUM) {
443 			n->op = OCONST;
444 			n->type = n->sym->tenum;
445 			if(!typefd[n->type->etype])
446 				n->vconst = n->sym->vconst;
447 			else
448 				n->fconst = n->sym->fconst;
449 			break;
450 		}
451 		n->addable = 1;
452 		if(n->class == CEXREG) {
453 			n->op = OREGISTER;
454 			n->reg = n->sym->offset;
455 			n->xoffset = 0;
456 			break;
457 		}
458 		break;
459 
460 	case OLSTRING:
461 		if(n->type->link != types[TUSHORT]) {
462 			o = outstring(0, 0);
463 			while(o & 3) {
464 				outlstring(L"", sizeof(ushort));
465 				o = outlstring(0, 0);
466 			}
467 		}
468 		n->op = ONAME;
469 		n->xoffset = outlstring(n->rstring, n->type->width);
470 		n->addable = 1;
471 		break;
472 
473 	case OSTRING:
474 		if(n->type->link != types[TCHAR]) {
475 			o = outstring(0, 0);
476 			while(o & 3) {
477 				outstring("", 1);
478 				o = outstring(0, 0);
479 			}
480 		}
481 		n->op = ONAME;
482 		n->xoffset = outstring(n->cstring, n->type->width);
483 		n->addable = 1;
484 		break;
485 
486 	case OCONST:
487 		break;
488 
489 	case ODOT:
490 		if(tcom(l))
491 			goto bad;
492 		if(tcompat(n, T, l->type, tdot))
493 			goto bad;
494 		if(tcomd(n))
495 			goto bad;
496 		break;
497 
498 	case OADDR:
499 		if(tcomo(l, ADDROP))
500 			goto bad;
501 		if(tlvalue(l))
502 			goto bad;
503 		if(l->type->nbits) {
504 			diag(n, "address of a bit field");
505 			goto bad;
506 		}
507 		if(l->op == OREGISTER) {
508 			diag(n, "address of a register");
509 			goto bad;
510 		}
511 		n->type = typ(TIND, l->type);
512 		n->type->width = types[TIND]->width;
513 		break;
514 
515 	case OIND:
516 		if(tcom(l))
517 			goto bad;
518 		if(tcompat(n, T, l->type, tindir))
519 			goto bad;
520 		n->type = l->type->link;
521 		n->addable = 1;
522 		break;
523 
524 	case OSTRUCT:
525 		if(tcomx(n))
526 			goto bad;
527 		break;
528 	}
529 	if(n->type == T)
530 		goto bad;
531 	if(n->type->width < 0) {
532 		diag(n, "structure not fully declared");
533 		goto bad;
534 	}
535 	if(typeaf[n->type->etype]) {
536 		if(f & ADDROF)
537 			goto addaddr;
538 		if(f & ADDROP)
539 			warn(n, "address of array/func ignored");
540 	}
541 	return 0;
542 
543 addaddr:
544 	if(tlvalue(n))
545 		goto bad;
546 	l = new1(OXXX, Z, Z);
547 	*l = *n;
548 	n->op = OADDR;
549 	if(l->type->etype == TARRAY)
550 		l->type = l->type->link;
551 	n->left = l;
552 	n->right = Z;
553 	n->addable = 0;
554 	n->type = typ(TIND, l->type);
555 	n->type->width = types[TIND]->width;
556 	return 0;
557 
558 bad:
559 	n->type = T;
560 	return 1;
561 }
562 
563 int
564 tcoma(Node *l, Node *n, Type *t, int f)
565 {
566 	Node *n1;
567 	int o;
568 
569 	if(t != T)
570 	if(t->etype == TOLD || t->etype == TDOT)	/* .../old in prototype */
571 		t = T;
572 	if(n == Z) {
573 		if(t != T && !sametype(t, types[TVOID])) {
574 			diag(n, "not enough function arguments: %F", l);
575 			return 1;
576 		}
577 		return 0;
578 	}
579 	if(n->op == OLIST) {
580 		o = tcoma(l, n->left, t, 0);
581 		if(t != T) {
582 			t = t->down;
583 			if(t == T)
584 				t = types[TVOID];
585 		}
586 		return o | tcoma(l, n->right, t, 1);
587 	}
588 	if(f && t != T)
589 		tcoma(l, Z, t->down, 0);
590 	if(tcom(n) || tcompat(n, T, n->type, targ))
591 		return 1;
592 	if(sametype(t, types[TVOID])) {
593 		diag(n, "too many function arguments: %F", l);
594 		return 1;
595 	}
596 	if(t != T) {
597 		typeext(t, n);
598 		if(stcompat(nodproto, t, n->type, tasign)) {
599 			diag(l, "argument prototype mismatch \"%T\" for \"%T\": %F",
600 				n->type, t, l);
601 			return 1;
602 		}
603 		switch(t->etype) {
604 		case TCHAR:
605 		case TSHORT:
606 			t = tint;
607 			break;
608 
609 		case TUCHAR:
610 		case TUSHORT:
611 			t = tuint;
612 			break;
613 		}
614 	} else
615 	switch(n->type->etype)
616 	{
617 	case TCHAR:
618 	case TSHORT:
619 		t = tint;
620 		break;
621 
622 	case TUCHAR:
623 	case TUSHORT:
624 		t = tuint;
625 		break;
626 
627 	case TFLOAT:
628 		t = types[TDOUBLE];
629 	}
630 	if(t != T && !sametype(t, n->type)) {
631 		n1 = new1(OXXX, Z, Z);
632 		*n1 = *n;
633 		n->op = OCAST;
634 		n->left = n1;
635 		n->right = Z;
636 		n->type = t;
637 		n->addable = 0;
638 	}
639 	return 0;
640 }
641 
642 int
643 tcomd(Node *n)
644 {
645 	Type *t;
646 	long o;
647 
648 	o = 0;
649 	t = n->left->type;
650 	for(;;) {
651 		t = dotsearch(n->sym, t->link, n);
652 		if(t == T) {
653 			diag(n, "not a member of struct/union: %F", n);
654 			return 1;
655 		}
656 		o += t->offset;
657 		if(t->sym == n->sym)
658 			break;
659 		if(sametype(t, n->sym->type))
660 			break;
661 	}
662 	makedot(n, t, o);
663 	return 0;
664 }
665 
666 int
667 tcomx(Node *n)
668 {
669 	Type *t;
670 	Node *l, *r, **ar, **al;
671 	int e;
672 
673 	e = 0;
674 	if(n->type->etype != TSTRUCT) {
675 		diag(n, "constructor must be a structure");
676 		return 1;
677 	}
678 	l = invert(n->left);
679 	n->left = l;
680 	al = &n->left;
681 	for(t = n->type->link; t != T; t = t->down) {
682 		if(l == Z) {
683 			diag(n, "constructor list too short");
684 			return 1;
685 		}
686 		if(l->op == OLIST) {
687 			r = l->left;
688 			ar = &l->left;
689 			al = &l->right;
690 			l = l->right;
691 		} else {
692 			r = l;
693 			ar = al;
694 			l = Z;
695 		}
696 		if(tcom(r))
697 			e++;
698 		typeext(t, r);
699 		if(tcompat(n, t, r->type, tasign))
700 			e++;
701 		if(!e && !sametype(t, r->type)) {
702 			r = new1(OCAST, r, Z);
703 			r->type = t;
704 			*ar = r;
705 		}
706 	}
707 	if(l != Z) {
708 		diag(n, "constructor list too long");
709 		return 1;
710 	}
711 	return e;
712 }
713 
714 int
715 tlvalue(Node *n)
716 {
717 
718 	if(!n->addable) {
719 		diag(n, "not an l-value");
720 		return 1;
721 	}
722 	return 0;
723 }
724 
725 /*
726  *	general rewrite
727  *	(IND(ADDR x)) ==> x
728  *	(ADDR(IND x)) ==> x
729  *	remove some zero operands
730  *	remove no op casts
731  *	evaluate constants
732  */
733 void
734 ccom(Node *n)
735 {
736 	Node *l, *r;
737 	int t;
738 
739 loop:
740 	if(n == Z)
741 		return;
742 	l = n->left;
743 	r = n->right;
744 	switch(n->op) {
745 
746 	case OAS:
747 	case OASXOR:
748 	case OASAND:
749 	case OASOR:
750 	case OASMOD:
751 	case OASLMOD:
752 	case OASLSHR:
753 	case OASASHR:
754 	case OASASHL:
755 	case OASDIV:
756 	case OASLDIV:
757 	case OASMUL:
758 	case OASLMUL:
759 	case OASSUB:
760 	case OASADD:
761 		ccom(l);
762 		ccom(r);
763 		if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL)
764 		if(r->op == OCONST) {
765 			t = n->type->width * 8;	/* bits per byte */
766 			if(r->vconst >= t || r->vconst < 0)
767 				warn(n, "stupid shift: %ld", r->vconst);
768 		}
769 		break;
770 
771 	case OCAST:
772 		ccom(l);
773 		if(l->op == OCONST) {
774 			evconst(n);
775 			if(n->op == OCONST)
776 				break;
777 		}
778 		if(nocast(l->type, n->type)) {
779 			l->type = n->type;
780 			*n = *l;
781 		}
782 		break;
783 
784 	case OCOND:
785 		ccom(l);
786 		ccom(r);
787 		if(l->op == OCONST)
788 			if(vconst(l) == 0)
789 				*n = *r->right;
790 			else
791 				*n = *r->left;
792 		break;
793 
794 	case OREGISTER:
795 	case OINDREG:
796 	case OCONST:
797 	case ONAME:
798 		break;
799 
800 	case OADDR:
801 		ccom(l);
802 		l->etype = TVOID;
803 		if(l->op == OIND) {
804 			l->left->type = n->type;
805 			*n = *l->left;
806 			break;
807 		}
808 		goto common;
809 
810 	case OIND:
811 		ccom(l);
812 		if(l->op == OADDR) {
813 			l->left->type = n->type;
814 			*n = *l->left;
815 			break;
816 		}
817 		goto common;
818 
819 	case OEQ:
820 	case ONE:
821 
822 	case OLE:
823 	case OGE:
824 	case OLT:
825 	case OGT:
826 
827 	case OLS:
828 	case OHS:
829 	case OLO:
830 	case OHI:
831 		ccom(l);
832 		ccom(r);
833 		relcon(l, r);
834 		relcon(r, l);
835 		goto common;
836 
837 	case OASHR:
838 	case OASHL:
839 	case OLSHR:
840 		ccom(l);
841 		if(vconst(l) == 0 && !side(r)) {
842 			*n = *l;
843 			break;
844 		}
845 		ccom(r);
846 		if(vconst(r) == 0) {
847 			*n = *l;
848 			break;
849 		}
850 		if(r->op == OCONST) {
851 			t = n->type->width * 8;	/* bits per byte */
852 			if(r->vconst >= t || r->vconst <= -t)
853 				warn(n, "stupid shift: %ld", r->vconst);
854 		}
855 		goto common;
856 
857 	case OMUL:
858 	case OLMUL:
859 		ccom(l);
860 		t = vconst(l);
861 		if(t == 0 && !side(r)) {
862 			*n = *l;
863 			break;
864 		}
865 		if(t == 1) {
866 			*n = *r;
867 			goto loop;
868 		}
869 		ccom(r);
870 		t = vconst(r);
871 		if(t == 0 && !side(l)) {
872 			*n = *r;
873 			break;
874 		}
875 		if(t == 1) {
876 			*n = *l;
877 			break;
878 		}
879 		goto common;
880 
881 	case ODIV:
882 	case OLDIV:
883 		ccom(l);
884 		if(vconst(l) == 0 && !side(r)) {
885 			*n = *l;
886 			break;
887 		}
888 		ccom(r);
889 		t = vconst(r);
890 		if(t == 0) {
891 			diag(n, "divide check");
892 			*n = *r;
893 			break;
894 		}
895 		if(t == 1) {
896 			*n = *l;
897 			break;
898 		}
899 		goto common;
900 
901 	case OSUB:
902 		ccom(r);
903 		if(r->op == OCONST) {
904 			if(typefd[r->type->etype]) {
905 				n->op = OADD;
906 				r->fconst = -r->fconst;
907 				goto loop;
908 			} else {
909 				n->op = OADD;
910 				r->vconst = -r->vconst;
911 				goto loop;
912 			}
913 		}
914 		ccom(l);
915 		goto common;
916 
917 	case OXOR:
918 	case OOR:
919 	case OADD:
920 		ccom(l);
921 		if(vconst(l) == 0) {
922 			*n = *r;
923 			goto loop;
924 		}
925 		ccom(r);
926 		if(vconst(r) == 0) {
927 			*n = *l;
928 			break;
929 		}
930 		goto commun;
931 
932 	case OAND:
933 		ccom(l);
934 		ccom(r);
935 		if(vconst(l) == 0 && !side(r)) {
936 			*n = *l;
937 			break;
938 		}
939 		if(vconst(r) == 0 && !side(l)) {
940 			*n = *r;
941 			break;
942 		}
943 
944 	commun:
945 		/* look for commutative constant */
946 		if(r->op == OCONST) {
947 			if(l->op == n->op) {
948 				if(l->left->op == OCONST) {
949 					n->right = l->right;
950 					l->right = r;
951 					goto loop;
952 				}
953 				if(l->right->op == OCONST) {
954 					n->right = l->left;
955 					l->left = r;
956 					goto loop;
957 				}
958 			}
959 		}
960 		if(l->op == OCONST) {
961 			if(r->op == n->op) {
962 				if(r->left->op == OCONST) {
963 					n->left = r->right;
964 					r->right = l;
965 					goto loop;
966 				}
967 				if(r->right->op == OCONST) {
968 					n->left = r->left;
969 					r->left = l;
970 					goto loop;
971 				}
972 			}
973 		}
974 		goto common;
975 
976 	case OANDAND:
977 		ccom(l);
978 		if(vconst(l) == 0) {
979 			*n = *l;
980 			break;
981 		}
982 		ccom(r);
983 		goto common;
984 
985 	case OOROR:
986 		ccom(l);
987 		if(l->op == OCONST && l->vconst != 0) {
988 			*n = *l;
989 			n->vconst = 1;
990 			break;
991 		}
992 		ccom(r);
993 		goto common;
994 
995 	default:
996 		if(l != Z)
997 			ccom(l);
998 		if(r != Z)
999 			ccom(r);
1000 	common:
1001 		if(l != Z)
1002 		if(l->op != OCONST)
1003 			break;
1004 		if(r != Z)
1005 		if(r->op != OCONST)
1006 			break;
1007 		evconst(n);
1008 	}
1009 }
1010