13e12c5d1SDavid du Colombier #include "cc.h"
23e12c5d1SDavid du Colombier
3d40255d8SDavid du Colombier typedef struct Com Com;
4d40255d8SDavid du Colombier struct Com
5d40255d8SDavid du Colombier {
6d40255d8SDavid du Colombier int n;
7d40255d8SDavid du Colombier Node *t[500];
8d40255d8SDavid du Colombier };
9d40255d8SDavid du Colombier
1022a127bbSDavid du Colombier int compar(Node*, int);
11d40255d8SDavid du Colombier static void comma(Node*);
12d40255d8SDavid du Colombier static Node* commas(Com*, Node*);
1322a127bbSDavid du Colombier
143e12c5d1SDavid du Colombier void
complex(Node * n)153e12c5d1SDavid du Colombier complex(Node *n)
163e12c5d1SDavid du Colombier {
173e12c5d1SDavid du Colombier
183e12c5d1SDavid du Colombier if(n == Z)
193e12c5d1SDavid du Colombier return;
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier nearln = n->lineno;
223e12c5d1SDavid du Colombier if(debug['t'])
233e12c5d1SDavid du Colombier if(n->op != OCONST)
243e12c5d1SDavid du Colombier prtree(n, "pre complex");
253e12c5d1SDavid du Colombier if(tcom(n))
263e12c5d1SDavid du Colombier return;
27d40255d8SDavid du Colombier if(debug['y'] || 1)
28d40255d8SDavid du Colombier comma(n);
293e12c5d1SDavid du Colombier if(debug['t'])
303e12c5d1SDavid du Colombier if(n->op != OCONST)
313e12c5d1SDavid du Colombier prtree(n, "t complex");
323e12c5d1SDavid du Colombier ccom(n);
333e12c5d1SDavid du Colombier if(debug['t'])
343e12c5d1SDavid du Colombier if(n->op != OCONST)
353e12c5d1SDavid du Colombier prtree(n, "c complex");
363e12c5d1SDavid du Colombier acom(n);
373e12c5d1SDavid du Colombier if(debug['t'])
383e12c5d1SDavid du Colombier if(n->op != OCONST)
393e12c5d1SDavid du Colombier prtree(n, "a complex");
403e12c5d1SDavid du Colombier xcom(n);
413e12c5d1SDavid du Colombier if(debug['t'])
423e12c5d1SDavid du Colombier if(n->op != OCONST)
433e12c5d1SDavid du Colombier prtree(n, "x complex");
443e12c5d1SDavid du Colombier }
453e12c5d1SDavid du Colombier
463e12c5d1SDavid du Colombier /*
473e12c5d1SDavid du Colombier * evaluate types
483e12c5d1SDavid du Colombier * evaluate lvalues (addable == 1)
493e12c5d1SDavid du Colombier */
503e12c5d1SDavid du Colombier enum
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier ADDROF = 1<<0,
533e12c5d1SDavid du Colombier CASTOF = 1<<1,
543e12c5d1SDavid du Colombier ADDROP = 1<<2,
553e12c5d1SDavid du Colombier };
563e12c5d1SDavid du Colombier
573e12c5d1SDavid du Colombier int
tcom(Node * n)583e12c5d1SDavid du Colombier tcom(Node *n)
593e12c5d1SDavid du Colombier {
603e12c5d1SDavid du Colombier
613e12c5d1SDavid du Colombier return tcomo(n, ADDROF);
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier
643e12c5d1SDavid du Colombier int
tcomo(Node * n,int f)653e12c5d1SDavid du Colombier tcomo(Node *n, int f)
663e12c5d1SDavid du Colombier {
673e12c5d1SDavid du Colombier Node *l, *r;
68219b2ee8SDavid du Colombier Type *t;
693e12c5d1SDavid du Colombier int o;
70*82726826SDavid du Colombier static TRune zer;
713e12c5d1SDavid du Colombier
723e12c5d1SDavid du Colombier if(n == Z) {
733e12c5d1SDavid du Colombier diag(Z, "Z in tcom");
743e12c5d1SDavid du Colombier errorexit();
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier n->addable = 0;
773e12c5d1SDavid du Colombier l = n->left;
783e12c5d1SDavid du Colombier r = n->right;
79219b2ee8SDavid du Colombier
803e12c5d1SDavid du Colombier switch(n->op) {
813e12c5d1SDavid du Colombier default:
823e12c5d1SDavid du Colombier diag(n, "unknown op in type complex: %O", n->op);
833e12c5d1SDavid du Colombier goto bad;
843e12c5d1SDavid du Colombier
853e12c5d1SDavid du Colombier case ODOTDOT:
863e12c5d1SDavid du Colombier /*
873e12c5d1SDavid du Colombier * tcom has already been called on this subtree
883e12c5d1SDavid du Colombier */
893e12c5d1SDavid du Colombier *n = *n->left;
903e12c5d1SDavid du Colombier if(n->type == T)
913e12c5d1SDavid du Colombier goto bad;
923e12c5d1SDavid du Colombier break;
933e12c5d1SDavid du Colombier
943e12c5d1SDavid du Colombier case OCAST:
95219b2ee8SDavid du Colombier if(n->type == T)
96219b2ee8SDavid du Colombier break;
973e12c5d1SDavid du Colombier if(n->type->width == types[TLONG]->width) {
983e12c5d1SDavid du Colombier if(tcomo(l, ADDROF|CASTOF))
993e12c5d1SDavid du Colombier goto bad;
1003e12c5d1SDavid du Colombier } else
1013e12c5d1SDavid du Colombier if(tcom(l))
1023e12c5d1SDavid du Colombier goto bad;
10380ee5cbfSDavid du Colombier if(isfunct(n))
10480ee5cbfSDavid du Colombier break;
1053e12c5d1SDavid du Colombier if(tcompat(n, l->type, n->type, tcast))
1063e12c5d1SDavid du Colombier goto bad;
1073e12c5d1SDavid du Colombier break;
1083e12c5d1SDavid du Colombier
1093e12c5d1SDavid du Colombier case ORETURN:
1103e12c5d1SDavid du Colombier if(l == Z) {
1113e12c5d1SDavid du Colombier if(n->type->etype != TVOID)
1123e12c5d1SDavid du Colombier warn(n, "null return of a typed function");
1133e12c5d1SDavid du Colombier break;
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier if(tcom(l))
1163e12c5d1SDavid du Colombier goto bad;
1173e12c5d1SDavid du Colombier typeext(n->type, l);
1183e12c5d1SDavid du Colombier if(tcompat(n, n->type, l->type, tasign))
1193e12c5d1SDavid du Colombier break;
1207dd7cddfSDavid du Colombier constas(n, n->type, l->type);
1213e12c5d1SDavid du Colombier if(!sametype(n->type, l->type)) {
1223e12c5d1SDavid du Colombier l = new1(OCAST, l, Z);
1233e12c5d1SDavid du Colombier l->type = n->type;
1243e12c5d1SDavid du Colombier n->left = l;
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier break;
1273e12c5d1SDavid du Colombier
1287dd7cddfSDavid du Colombier case OASI: /* same as as, but no test for const */
1297dd7cddfSDavid du Colombier n->op = OAS;
1307dd7cddfSDavid du Colombier o = tcom(l);
1317dd7cddfSDavid du Colombier if(o | tcom(r))
1327dd7cddfSDavid du Colombier goto bad;
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier typeext(l->type, r);
1357dd7cddfSDavid du Colombier if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))
1367dd7cddfSDavid du Colombier goto bad;
1377dd7cddfSDavid du Colombier if(!sametype(l->type, r->type)) {
1387dd7cddfSDavid du Colombier r = new1(OCAST, r, Z);
1397dd7cddfSDavid du Colombier r->type = l->type;
1407dd7cddfSDavid du Colombier n->right = r;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier n->type = l->type;
1437dd7cddfSDavid du Colombier break;
1447dd7cddfSDavid du Colombier
145219b2ee8SDavid du Colombier case OAS:
146219b2ee8SDavid du Colombier o = tcom(l);
147219b2ee8SDavid du Colombier if(o | tcom(r))
148219b2ee8SDavid du Colombier goto bad;
14980ee5cbfSDavid du Colombier if(tlvalue(l))
15080ee5cbfSDavid du Colombier goto bad;
15180ee5cbfSDavid du Colombier if(isfunct(n))
15280ee5cbfSDavid du Colombier break;
153219b2ee8SDavid du Colombier typeext(l->type, r);
15480ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tasign))
155219b2ee8SDavid du Colombier goto bad;
1567dd7cddfSDavid du Colombier constas(n, l->type, r->type);
157219b2ee8SDavid du Colombier if(!sametype(l->type, r->type)) {
158219b2ee8SDavid du Colombier r = new1(OCAST, r, Z);
159219b2ee8SDavid du Colombier r->type = l->type;
160219b2ee8SDavid du Colombier n->right = r;
161219b2ee8SDavid du Colombier }
162219b2ee8SDavid du Colombier n->type = l->type;
163219b2ee8SDavid du Colombier break;
164219b2ee8SDavid du Colombier
1653e12c5d1SDavid du Colombier case OASADD:
1663e12c5d1SDavid du Colombier case OASSUB:
1673e12c5d1SDavid du Colombier o = tcom(l);
1683e12c5d1SDavid du Colombier if(o | tcom(r))
1693e12c5d1SDavid du Colombier goto bad;
17080ee5cbfSDavid du Colombier if(tlvalue(l))
17180ee5cbfSDavid du Colombier goto bad;
17280ee5cbfSDavid du Colombier if(isfunct(n))
17380ee5cbfSDavid du Colombier break;
174219b2ee8SDavid du Colombier typeext1(l->type, r);
17580ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tasadd))
1763e12c5d1SDavid du Colombier goto bad;
1777dd7cddfSDavid du Colombier constas(n, l->type, r->type);
178219b2ee8SDavid du Colombier t = l->type;
1793e12c5d1SDavid du Colombier arith(n, 0);
180219b2ee8SDavid du Colombier while(n->left->op == OCAST)
181219b2ee8SDavid du Colombier n->left = n->left->left;
182ce941d97SDavid du Colombier if(!sametype(t, n->type) && !mixedasop(t, n->type)) {
183219b2ee8SDavid du Colombier r = new1(OCAST, n->right, Z);
184219b2ee8SDavid du Colombier r->type = t;
185219b2ee8SDavid du Colombier n->right = r;
186219b2ee8SDavid du Colombier n->type = t;
187219b2ee8SDavid du Colombier }
1883e12c5d1SDavid du Colombier break;
1893e12c5d1SDavid du Colombier
1903e12c5d1SDavid du Colombier case OASMUL:
1913e12c5d1SDavid du Colombier case OASLMUL:
1923e12c5d1SDavid du Colombier case OASDIV:
1933e12c5d1SDavid du Colombier case OASLDIV:
1943e12c5d1SDavid du Colombier o = tcom(l);
1953e12c5d1SDavid du Colombier if(o | tcom(r))
1963e12c5d1SDavid du Colombier goto bad;
19780ee5cbfSDavid du Colombier if(tlvalue(l))
19880ee5cbfSDavid du Colombier goto bad;
19980ee5cbfSDavid du Colombier if(isfunct(n))
20080ee5cbfSDavid du Colombier break;
201219b2ee8SDavid du Colombier typeext1(l->type, r);
20280ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tmul))
2033e12c5d1SDavid du Colombier goto bad;
2047dd7cddfSDavid du Colombier constas(n, l->type, r->type);
205219b2ee8SDavid du Colombier t = l->type;
2063e12c5d1SDavid du Colombier arith(n, 0);
207219b2ee8SDavid du Colombier while(n->left->op == OCAST)
208219b2ee8SDavid du Colombier n->left = n->left->left;
209ce941d97SDavid du Colombier if(!sametype(t, n->type) && !mixedasop(t, n->type)) {
210219b2ee8SDavid du Colombier r = new1(OCAST, n->right, Z);
211219b2ee8SDavid du Colombier r->type = t;
212219b2ee8SDavid du Colombier n->right = r;
213219b2ee8SDavid du Colombier n->type = t;
214219b2ee8SDavid du Colombier }
2153e12c5d1SDavid du Colombier if(typeu[n->type->etype]) {
2163e12c5d1SDavid du Colombier if(n->op == OASDIV)
2173e12c5d1SDavid du Colombier n->op = OASLDIV;
2183e12c5d1SDavid du Colombier if(n->op == OASMUL)
2193e12c5d1SDavid du Colombier n->op = OASLMUL;
2203e12c5d1SDavid du Colombier }
2213e12c5d1SDavid du Colombier break;
2223e12c5d1SDavid du Colombier
2233e12c5d1SDavid du Colombier case OASLSHR:
2243e12c5d1SDavid du Colombier case OASASHR:
2253e12c5d1SDavid du Colombier case OASASHL:
2263e12c5d1SDavid du Colombier o = tcom(l);
2273e12c5d1SDavid du Colombier if(o | tcom(r))
2283e12c5d1SDavid du Colombier goto bad;
22980ee5cbfSDavid du Colombier if(tlvalue(l))
23080ee5cbfSDavid du Colombier goto bad;
23180ee5cbfSDavid du Colombier if(isfunct(n))
23280ee5cbfSDavid du Colombier break;
23380ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tand))
2343e12c5d1SDavid du Colombier goto bad;
2353e12c5d1SDavid du Colombier n->type = l->type;
2366891d857SDavid du Colombier n->right = new1(OCAST, r, Z);
2376891d857SDavid du Colombier n->right->type = types[TINT];
2383e12c5d1SDavid du Colombier if(typeu[n->type->etype]) {
2393e12c5d1SDavid du Colombier if(n->op == OASASHR)
2403e12c5d1SDavid du Colombier n->op = OASLSHR;
2413e12c5d1SDavid du Colombier }
2423e12c5d1SDavid du Colombier break;
2433e12c5d1SDavid du Colombier
2443e12c5d1SDavid du Colombier case OASMOD:
2453e12c5d1SDavid du Colombier case OASLMOD:
2463e12c5d1SDavid du Colombier case OASOR:
2473e12c5d1SDavid du Colombier case OASAND:
2483e12c5d1SDavid du Colombier case OASXOR:
2493e12c5d1SDavid du Colombier o = tcom(l);
2503e12c5d1SDavid du Colombier if(o | tcom(r))
2513e12c5d1SDavid du Colombier goto bad;
25280ee5cbfSDavid du Colombier if(tlvalue(l))
25380ee5cbfSDavid du Colombier goto bad;
25480ee5cbfSDavid du Colombier if(isfunct(n))
25580ee5cbfSDavid du Colombier break;
25680ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tand))
2573e12c5d1SDavid du Colombier goto bad;
258219b2ee8SDavid du Colombier t = l->type;
2593e12c5d1SDavid du Colombier arith(n, 0);
260219b2ee8SDavid du Colombier while(n->left->op == OCAST)
261219b2ee8SDavid du Colombier n->left = n->left->left;
262ce941d97SDavid du Colombier if(!sametype(t, n->type) && !mixedasop(t, n->type)) {
263219b2ee8SDavid du Colombier r = new1(OCAST, n->right, Z);
264219b2ee8SDavid du Colombier r->type = t;
265219b2ee8SDavid du Colombier n->right = r;
266219b2ee8SDavid du Colombier n->type = t;
267219b2ee8SDavid du Colombier }
2683e12c5d1SDavid du Colombier if(typeu[n->type->etype]) {
2693e12c5d1SDavid du Colombier if(n->op == OASMOD)
2703e12c5d1SDavid du Colombier n->op = OASLMOD;
2713e12c5d1SDavid du Colombier }
2723e12c5d1SDavid du Colombier break;
2733e12c5d1SDavid du Colombier
2743e12c5d1SDavid du Colombier case OPREINC:
2753e12c5d1SDavid du Colombier case OPREDEC:
2763e12c5d1SDavid du Colombier case OPOSTINC:
2773e12c5d1SDavid du Colombier case OPOSTDEC:
2783e12c5d1SDavid du Colombier if(tcom(l))
2793e12c5d1SDavid du Colombier goto bad;
28080ee5cbfSDavid du Colombier if(tlvalue(l))
28180ee5cbfSDavid du Colombier goto bad;
28280ee5cbfSDavid du Colombier if(isfunct(n))
28380ee5cbfSDavid du Colombier break;
28480ee5cbfSDavid du Colombier if(tcompat(n, l->type, types[TINT], tadd))
2853e12c5d1SDavid du Colombier goto bad;
2863e12c5d1SDavid du Colombier n->type = l->type;
2873e12c5d1SDavid du Colombier if(n->type->etype == TIND)
288d40255d8SDavid du Colombier if(n->type->link->width < 1) {
289d40255d8SDavid du Colombier snap(n->type->link);
2903e12c5d1SDavid du Colombier if(n->type->link->width < 1)
2917dd7cddfSDavid du Colombier diag(n, "inc/dec of a void pointer");
292d40255d8SDavid du Colombier }
2933e12c5d1SDavid du Colombier break;
2943e12c5d1SDavid du Colombier
2953e12c5d1SDavid du Colombier case OEQ:
2963e12c5d1SDavid du Colombier case ONE:
2973e12c5d1SDavid du Colombier o = tcom(l);
2983e12c5d1SDavid du Colombier if(o | tcom(r))
2993e12c5d1SDavid du Colombier goto bad;
30080ee5cbfSDavid du Colombier if(isfunct(n))
30180ee5cbfSDavid du Colombier break;
3023e12c5d1SDavid du Colombier typeext(l->type, r);
3033e12c5d1SDavid du Colombier typeext(r->type, l);
3043e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, trel))
3053e12c5d1SDavid du Colombier goto bad;
3063e12c5d1SDavid du Colombier arith(n, 0);
3077dd7cddfSDavid du Colombier n->type = types[TINT];
3083e12c5d1SDavid du Colombier break;
3093e12c5d1SDavid du Colombier
3103e12c5d1SDavid du Colombier case OLT:
3113e12c5d1SDavid du Colombier case OGE:
3123e12c5d1SDavid du Colombier case OGT:
3133e12c5d1SDavid du Colombier case OLE:
3143e12c5d1SDavid du Colombier o = tcom(l);
3153e12c5d1SDavid du Colombier if(o | tcom(r))
3163e12c5d1SDavid du Colombier goto bad;
31780ee5cbfSDavid du Colombier if(isfunct(n))
31880ee5cbfSDavid du Colombier break;
319219b2ee8SDavid du Colombier typeext1(l->type, r);
320219b2ee8SDavid du Colombier typeext1(r->type, l);
3213e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, trel))
3223e12c5d1SDavid du Colombier goto bad;
3233e12c5d1SDavid du Colombier arith(n, 0);
3243e12c5d1SDavid du Colombier if(typeu[n->type->etype])
3253e12c5d1SDavid du Colombier n->op = logrel[relindex(n->op)];
3267dd7cddfSDavid du Colombier n->type = types[TINT];
3273e12c5d1SDavid du Colombier break;
3283e12c5d1SDavid du Colombier
3293e12c5d1SDavid du Colombier case OCOND:
3303e12c5d1SDavid du Colombier o = tcom(l);
3313e12c5d1SDavid du Colombier o |= tcom(r->left);
3323e12c5d1SDavid du Colombier if(o | tcom(r->right))
3333e12c5d1SDavid du Colombier goto bad;
3343e12c5d1SDavid du Colombier if(r->right->type->etype == TIND && vconst(r->left) == 0) {
3353e12c5d1SDavid du Colombier r->left->type = r->right->type;
336219b2ee8SDavid du Colombier r->left->vconst = 0;
3373e12c5d1SDavid du Colombier }
3383e12c5d1SDavid du Colombier if(r->left->type->etype == TIND && vconst(r->right) == 0) {
3393e12c5d1SDavid du Colombier r->right->type = r->left->type;
340219b2ee8SDavid du Colombier r->right->vconst = 0;
3413e12c5d1SDavid du Colombier }
3423e12c5d1SDavid du Colombier if(sametype(r->right->type, r->left->type)) {
3433e12c5d1SDavid du Colombier r->type = r->right->type;
3443e12c5d1SDavid du Colombier n->type = r->type;
3453e12c5d1SDavid du Colombier break;
3463e12c5d1SDavid du Colombier }
3473e12c5d1SDavid du Colombier if(tcompat(r, r->left->type, r->right->type, trel))
3483e12c5d1SDavid du Colombier goto bad;
3493e12c5d1SDavid du Colombier arith(r, 0);
3503e12c5d1SDavid du Colombier n->type = r->type;
3513e12c5d1SDavid du Colombier break;
3523e12c5d1SDavid du Colombier
3533e12c5d1SDavid du Colombier case OADD:
3543e12c5d1SDavid du Colombier o = tcom(l);
3553e12c5d1SDavid du Colombier if(o | tcom(r))
3563e12c5d1SDavid du Colombier goto bad;
35780ee5cbfSDavid du Colombier if(isfunct(n))
35880ee5cbfSDavid du Colombier break;
3593e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, tadd))
3603e12c5d1SDavid du Colombier goto bad;
3613e12c5d1SDavid du Colombier arith(n, 1);
3623e12c5d1SDavid du Colombier break;
3633e12c5d1SDavid du Colombier
3643e12c5d1SDavid du Colombier case OSUB:
3653e12c5d1SDavid du Colombier o = tcom(l);
3663e12c5d1SDavid du Colombier if(o | tcom(r))
3673e12c5d1SDavid du Colombier goto bad;
36880ee5cbfSDavid du Colombier if(isfunct(n))
36980ee5cbfSDavid du Colombier break;
3703e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, tsub))
3713e12c5d1SDavid du Colombier goto bad;
3723e12c5d1SDavid du Colombier arith(n, 1);
3733e12c5d1SDavid du Colombier break;
3743e12c5d1SDavid du Colombier
3753e12c5d1SDavid du Colombier case OMUL:
3763e12c5d1SDavid du Colombier case OLMUL:
3773e12c5d1SDavid du Colombier case ODIV:
3783e12c5d1SDavid du Colombier case OLDIV:
3793e12c5d1SDavid du Colombier o = tcom(l);
3803e12c5d1SDavid du Colombier if(o | tcom(r))
3813e12c5d1SDavid du Colombier goto bad;
38280ee5cbfSDavid du Colombier if(isfunct(n))
38380ee5cbfSDavid du Colombier break;
3843e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, tmul))
3853e12c5d1SDavid du Colombier goto bad;
3863e12c5d1SDavid du Colombier arith(n, 1);
3873e12c5d1SDavid du Colombier if(typeu[n->type->etype]) {
3883e12c5d1SDavid du Colombier if(n->op == ODIV)
3893e12c5d1SDavid du Colombier n->op = OLDIV;
3903e12c5d1SDavid du Colombier if(n->op == OMUL)
3913e12c5d1SDavid du Colombier n->op = OLMUL;
3923e12c5d1SDavid du Colombier }
3933e12c5d1SDavid du Colombier break;
3943e12c5d1SDavid du Colombier
3953e12c5d1SDavid du Colombier case OLSHR:
3963e12c5d1SDavid du Colombier case OASHL:
3973e12c5d1SDavid du Colombier case OASHR:
3983e12c5d1SDavid du Colombier o = tcom(l);
3993e12c5d1SDavid du Colombier if(o | tcom(r))
4003e12c5d1SDavid du Colombier goto bad;
40180ee5cbfSDavid du Colombier if(isfunct(n))
40280ee5cbfSDavid du Colombier break;
4033e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, tand))
4043e12c5d1SDavid du Colombier goto bad;
4053e12c5d1SDavid du Colombier n->right = Z;
4063e12c5d1SDavid du Colombier arith(n, 1);
4073e12c5d1SDavid du Colombier n->right = new1(OCAST, r, Z);
4087dd7cddfSDavid du Colombier n->right->type = types[TINT];
4093e12c5d1SDavid du Colombier if(typeu[n->type->etype])
4103e12c5d1SDavid du Colombier if(n->op == OASHR)
4113e12c5d1SDavid du Colombier n->op = OLSHR;
4123e12c5d1SDavid du Colombier break;
4133e12c5d1SDavid du Colombier
4143e12c5d1SDavid du Colombier case OAND:
4153e12c5d1SDavid du Colombier case OOR:
4163e12c5d1SDavid du Colombier case OXOR:
4173e12c5d1SDavid du Colombier o = tcom(l);
4183e12c5d1SDavid du Colombier if(o | tcom(r))
4193e12c5d1SDavid du Colombier goto bad;
42080ee5cbfSDavid du Colombier if(isfunct(n))
42180ee5cbfSDavid du Colombier break;
4223e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, tand))
4233e12c5d1SDavid du Colombier goto bad;
4243e12c5d1SDavid du Colombier arith(n, 1);
4253e12c5d1SDavid du Colombier break;
4263e12c5d1SDavid du Colombier
4273e12c5d1SDavid du Colombier case OMOD:
4283e12c5d1SDavid du Colombier case OLMOD:
4293e12c5d1SDavid du Colombier o = tcom(l);
4303e12c5d1SDavid du Colombier if(o | tcom(r))
4313e12c5d1SDavid du Colombier goto bad;
43280ee5cbfSDavid du Colombier if(isfunct(n))
43380ee5cbfSDavid du Colombier break;
4343e12c5d1SDavid du Colombier if(tcompat(n, l->type, r->type, tand))
4353e12c5d1SDavid du Colombier goto bad;
4363e12c5d1SDavid du Colombier arith(n, 1);
4373e12c5d1SDavid du Colombier if(typeu[n->type->etype])
4383e12c5d1SDavid du Colombier n->op = OLMOD;
4393e12c5d1SDavid du Colombier break;
4403e12c5d1SDavid du Colombier
44180ee5cbfSDavid du Colombier case OPOS:
44280ee5cbfSDavid du Colombier if(tcom(l))
44380ee5cbfSDavid du Colombier goto bad;
44480ee5cbfSDavid du Colombier if(isfunct(n))
44580ee5cbfSDavid du Colombier break;
44680ee5cbfSDavid du Colombier
44780ee5cbfSDavid du Colombier r = l;
44880ee5cbfSDavid du Colombier l = new(OCONST, Z, Z);
44980ee5cbfSDavid du Colombier l->vconst = 0;
45080ee5cbfSDavid du Colombier l->type = types[TINT];
45180ee5cbfSDavid du Colombier n->op = OADD;
45280ee5cbfSDavid du Colombier n->right = r;
45380ee5cbfSDavid du Colombier n->left = l;
45480ee5cbfSDavid du Colombier
45580ee5cbfSDavid du Colombier if(tcom(l))
45680ee5cbfSDavid du Colombier goto bad;
45780ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tsub))
45880ee5cbfSDavid du Colombier goto bad;
45980ee5cbfSDavid du Colombier arith(n, 1);
46080ee5cbfSDavid du Colombier break;
46180ee5cbfSDavid du Colombier
46280ee5cbfSDavid du Colombier case ONEG:
46380ee5cbfSDavid du Colombier if(tcom(l))
46480ee5cbfSDavid du Colombier goto bad;
46580ee5cbfSDavid du Colombier if(isfunct(n))
46680ee5cbfSDavid du Colombier break;
46780ee5cbfSDavid du Colombier
468da51d93aSDavid du Colombier if(!machcap(n)) {
46980ee5cbfSDavid du Colombier r = l;
47080ee5cbfSDavid du Colombier l = new(OCONST, Z, Z);
47180ee5cbfSDavid du Colombier l->vconst = 0;
47280ee5cbfSDavid du Colombier l->type = types[TINT];
47380ee5cbfSDavid du Colombier n->op = OSUB;
47480ee5cbfSDavid du Colombier n->right = r;
47580ee5cbfSDavid du Colombier n->left = l;
47680ee5cbfSDavid du Colombier
47780ee5cbfSDavid du Colombier if(tcom(l))
47880ee5cbfSDavid du Colombier goto bad;
47980ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tsub))
48080ee5cbfSDavid du Colombier goto bad;
481da51d93aSDavid du Colombier }
48280ee5cbfSDavid du Colombier arith(n, 1);
48380ee5cbfSDavid du Colombier break;
48480ee5cbfSDavid du Colombier
48580ee5cbfSDavid du Colombier case OCOM:
48680ee5cbfSDavid du Colombier if(tcom(l))
48780ee5cbfSDavid du Colombier goto bad;
48880ee5cbfSDavid du Colombier if(isfunct(n))
48980ee5cbfSDavid du Colombier break;
49080ee5cbfSDavid du Colombier
491da51d93aSDavid du Colombier if(!machcap(n)) {
49280ee5cbfSDavid du Colombier r = l;
49380ee5cbfSDavid du Colombier l = new(OCONST, Z, Z);
49480ee5cbfSDavid du Colombier l->vconst = -1;
49580ee5cbfSDavid du Colombier l->type = types[TINT];
49680ee5cbfSDavid du Colombier n->op = OXOR;
49780ee5cbfSDavid du Colombier n->right = r;
49880ee5cbfSDavid du Colombier n->left = l;
49980ee5cbfSDavid du Colombier
50080ee5cbfSDavid du Colombier if(tcom(l))
50180ee5cbfSDavid du Colombier goto bad;
50280ee5cbfSDavid du Colombier if(tcompat(n, l->type, r->type, tand))
50380ee5cbfSDavid du Colombier goto bad;
504da51d93aSDavid du Colombier }
50580ee5cbfSDavid du Colombier arith(n, 1);
50680ee5cbfSDavid du Colombier break;
50780ee5cbfSDavid du Colombier
5083e12c5d1SDavid du Colombier case ONOT:
5093e12c5d1SDavid du Colombier if(tcom(l))
5103e12c5d1SDavid du Colombier goto bad;
51180ee5cbfSDavid du Colombier if(isfunct(n))
51280ee5cbfSDavid du Colombier break;
5133e12c5d1SDavid du Colombier if(tcompat(n, T, l->type, tnot))
5143e12c5d1SDavid du Colombier goto bad;
5157dd7cddfSDavid du Colombier n->type = types[TINT];
5163e12c5d1SDavid du Colombier break;
5173e12c5d1SDavid du Colombier
5183e12c5d1SDavid du Colombier case OANDAND:
5193e12c5d1SDavid du Colombier case OOROR:
5203e12c5d1SDavid du Colombier o = tcom(l);
5213e12c5d1SDavid du Colombier if(o | tcom(r))
5223e12c5d1SDavid du Colombier goto bad;
5233e12c5d1SDavid du Colombier if(tcompat(n, T, l->type, tnot) |
5243e12c5d1SDavid du Colombier tcompat(n, T, r->type, tnot))
5253e12c5d1SDavid du Colombier goto bad;
5267dd7cddfSDavid du Colombier n->type = types[TINT];
5273e12c5d1SDavid du Colombier break;
5283e12c5d1SDavid du Colombier
5293e12c5d1SDavid du Colombier case OCOMMA:
5303e12c5d1SDavid du Colombier o = tcom(l);
5313e12c5d1SDavid du Colombier if(o | tcom(r))
5323e12c5d1SDavid du Colombier goto bad;
5333e12c5d1SDavid du Colombier n->type = r->type;
5343e12c5d1SDavid du Colombier break;
5353e12c5d1SDavid du Colombier
5363e12c5d1SDavid du Colombier
5377dd7cddfSDavid du Colombier case OSIGN: /* extension signof(type) returns a hash */
5387dd7cddfSDavid du Colombier if(l != Z) {
5397dd7cddfSDavid du Colombier if(l->op != OSTRING && l->op != OLSTRING)
5407dd7cddfSDavid du Colombier if(tcomo(l, 0))
5417dd7cddfSDavid du Colombier goto bad;
5427dd7cddfSDavid du Colombier if(l->op == OBIT) {
5437dd7cddfSDavid du Colombier diag(n, "signof bitfield");
5447dd7cddfSDavid du Colombier goto bad;
5457dd7cddfSDavid du Colombier }
5467dd7cddfSDavid du Colombier n->type = l->type;
5477dd7cddfSDavid du Colombier }
5487dd7cddfSDavid du Colombier if(n->type == T)
5497dd7cddfSDavid du Colombier goto bad;
5507dd7cddfSDavid du Colombier if(n->type->width < 0) {
5517dd7cddfSDavid du Colombier diag(n, "signof undefined type");
5527dd7cddfSDavid du Colombier goto bad;
5537dd7cddfSDavid du Colombier }
5547dd7cddfSDavid du Colombier n->op = OCONST;
5557dd7cddfSDavid du Colombier n->left = Z;
5567dd7cddfSDavid du Colombier n->right = Z;
557375daca8SDavid du Colombier n->vconst = convvtox(signature(n->type), TULONG);
5587dd7cddfSDavid du Colombier n->type = types[TULONG];
5597dd7cddfSDavid du Colombier break;
5607dd7cddfSDavid du Colombier
5613e12c5d1SDavid du Colombier case OSIZE:
5623e12c5d1SDavid du Colombier if(l != Z) {
5633e12c5d1SDavid du Colombier if(l->op != OSTRING && l->op != OLSTRING)
5643e12c5d1SDavid du Colombier if(tcomo(l, 0))
5653e12c5d1SDavid du Colombier goto bad;
5663e12c5d1SDavid du Colombier if(l->op == OBIT) {
5673e12c5d1SDavid du Colombier diag(n, "sizeof bitfield");
5683e12c5d1SDavid du Colombier goto bad;
5693e12c5d1SDavid du Colombier }
5703e12c5d1SDavid du Colombier n->type = l->type;
5713e12c5d1SDavid du Colombier }
5723e12c5d1SDavid du Colombier if(n->type == T)
5733e12c5d1SDavid du Colombier goto bad;
574219b2ee8SDavid du Colombier if(n->type->width <= 0) {
5753e12c5d1SDavid du Colombier diag(n, "sizeof undefined type");
5763e12c5d1SDavid du Colombier goto bad;
5773e12c5d1SDavid du Colombier }
5783e12c5d1SDavid du Colombier if(n->type->etype == TFUNC) {
5793e12c5d1SDavid du Colombier diag(n, "sizeof function");
5803e12c5d1SDavid du Colombier goto bad;
5813e12c5d1SDavid du Colombier }
5823e12c5d1SDavid du Colombier n->op = OCONST;
5833e12c5d1SDavid du Colombier n->left = Z;
5843e12c5d1SDavid du Colombier n->right = Z;
5857dd7cddfSDavid du Colombier n->vconst = convvtox(n->type->width, TINT);
5867dd7cddfSDavid du Colombier n->type = types[TINT];
5873e12c5d1SDavid du Colombier break;
5883e12c5d1SDavid du Colombier
5893e12c5d1SDavid du Colombier case OFUNC:
5903e12c5d1SDavid du Colombier o = tcomo(l, 0);
5913e12c5d1SDavid du Colombier if(o)
5923e12c5d1SDavid du Colombier goto bad;
5933e12c5d1SDavid du Colombier if(l->type->etype == TIND && l->type->link->etype == TFUNC) {
5943e12c5d1SDavid du Colombier l = new1(OIND, l, Z);
5953e12c5d1SDavid du Colombier l->type = l->left->type->link;
5963e12c5d1SDavid du Colombier n->left = l;
5973e12c5d1SDavid du Colombier }
5983e12c5d1SDavid du Colombier if(tcompat(n, T, l->type, tfunct))
5993e12c5d1SDavid du Colombier goto bad;
6003e12c5d1SDavid du Colombier if(o | tcoma(l, r, l->type->down, 1))
6013e12c5d1SDavid du Colombier goto bad;
6023e12c5d1SDavid du Colombier n->type = l->type->link;
6033e12c5d1SDavid du Colombier if(!debug['B'])
6043e12c5d1SDavid du Colombier if(l->type->down == T || l->type->down->etype == TOLD) {
6053e12c5d1SDavid du Colombier nerrors--;
6063e12c5d1SDavid du Colombier diag(n, "function args not checked: %F", l);
6073e12c5d1SDavid du Colombier }
6087dd7cddfSDavid du Colombier dpcheck(n);
6093e12c5d1SDavid du Colombier break;
6103e12c5d1SDavid du Colombier
6113e12c5d1SDavid du Colombier case ONAME:
6123e12c5d1SDavid du Colombier if(n->type == T) {
6133e12c5d1SDavid du Colombier diag(n, "name not declared: %F", n);
6143e12c5d1SDavid du Colombier goto bad;
6153e12c5d1SDavid du Colombier }
6163e12c5d1SDavid du Colombier if(n->type->etype == TENUM) {
6173e12c5d1SDavid du Colombier n->op = OCONST;
618219b2ee8SDavid du Colombier n->type = n->sym->tenum;
619219b2ee8SDavid du Colombier if(!typefd[n->type->etype])
620219b2ee8SDavid du Colombier n->vconst = n->sym->vconst;
621219b2ee8SDavid du Colombier else
622219b2ee8SDavid du Colombier n->fconst = n->sym->fconst;
6233e12c5d1SDavid du Colombier break;
6243e12c5d1SDavid du Colombier }
6253e12c5d1SDavid du Colombier n->addable = 1;
6263e12c5d1SDavid du Colombier if(n->class == CEXREG) {
6273e12c5d1SDavid du Colombier n->op = OREGISTER;
628d40255d8SDavid du Colombier if(thechar == '8')
629d40255d8SDavid du Colombier n->op = OEXREG;
6303e12c5d1SDavid du Colombier n->reg = n->sym->offset;
631219b2ee8SDavid du Colombier n->xoffset = 0;
6323e12c5d1SDavid du Colombier break;
6333e12c5d1SDavid du Colombier }
6343e12c5d1SDavid du Colombier break;
6353e12c5d1SDavid du Colombier
6363e12c5d1SDavid du Colombier case OLSTRING:
637*82726826SDavid du Colombier if(n->type->link != types[TRUNE]) {
6383e12c5d1SDavid du Colombier o = outstring(0, 0);
6393e12c5d1SDavid du Colombier while(o & 3) {
640*82726826SDavid du Colombier outlstring(&zer, sizeof(TRune));
6413e12c5d1SDavid du Colombier o = outlstring(0, 0);
6423e12c5d1SDavid du Colombier }
6433e12c5d1SDavid du Colombier }
6443e12c5d1SDavid du Colombier n->op = ONAME;
645219b2ee8SDavid du Colombier n->xoffset = outlstring(n->rstring, n->type->width);
6463e12c5d1SDavid du Colombier n->addable = 1;
6473e12c5d1SDavid du Colombier break;
6483e12c5d1SDavid du Colombier
6493e12c5d1SDavid du Colombier case OSTRING:
6503e12c5d1SDavid du Colombier if(n->type->link != types[TCHAR]) {
6513e12c5d1SDavid du Colombier o = outstring(0, 0);
6523e12c5d1SDavid du Colombier while(o & 3) {
6533e12c5d1SDavid du Colombier outstring("", 1);
6543e12c5d1SDavid du Colombier o = outstring(0, 0);
6553e12c5d1SDavid du Colombier }
6563e12c5d1SDavid du Colombier }
6573e12c5d1SDavid du Colombier n->op = ONAME;
658219b2ee8SDavid du Colombier n->xoffset = outstring(n->cstring, n->type->width);
6593e12c5d1SDavid du Colombier n->addable = 1;
6603e12c5d1SDavid du Colombier break;
6613e12c5d1SDavid du Colombier
6623e12c5d1SDavid du Colombier case OCONST:
6633e12c5d1SDavid du Colombier break;
6643e12c5d1SDavid du Colombier
6653e12c5d1SDavid du Colombier case ODOT:
6663e12c5d1SDavid du Colombier if(tcom(l))
6673e12c5d1SDavid du Colombier goto bad;
6683e12c5d1SDavid du Colombier if(tcompat(n, T, l->type, tdot))
6693e12c5d1SDavid du Colombier goto bad;
6703e12c5d1SDavid du Colombier if(tcomd(n))
6713e12c5d1SDavid du Colombier goto bad;
6723e12c5d1SDavid du Colombier break;
6733e12c5d1SDavid du Colombier
6743e12c5d1SDavid du Colombier case OADDR:
6753e12c5d1SDavid du Colombier if(tcomo(l, ADDROP))
6763e12c5d1SDavid du Colombier goto bad;
6773e12c5d1SDavid du Colombier if(tlvalue(l))
6783e12c5d1SDavid du Colombier goto bad;
6793e12c5d1SDavid du Colombier if(l->type->nbits) {
6803e12c5d1SDavid du Colombier diag(n, "address of a bit field");
6813e12c5d1SDavid du Colombier goto bad;
6823e12c5d1SDavid du Colombier }
6833e12c5d1SDavid du Colombier if(l->op == OREGISTER) {
6843e12c5d1SDavid du Colombier diag(n, "address of a register");
6853e12c5d1SDavid du Colombier goto bad;
6863e12c5d1SDavid du Colombier }
6873e12c5d1SDavid du Colombier n->type = typ(TIND, l->type);
6883e12c5d1SDavid du Colombier n->type->width = types[TIND]->width;
6893e12c5d1SDavid du Colombier break;
6903e12c5d1SDavid du Colombier
6913e12c5d1SDavid du Colombier case OIND:
6923e12c5d1SDavid du Colombier if(tcom(l))
6933e12c5d1SDavid du Colombier goto bad;
6943e12c5d1SDavid du Colombier if(tcompat(n, T, l->type, tindir))
6953e12c5d1SDavid du Colombier goto bad;
6963e12c5d1SDavid du Colombier n->type = l->type->link;
6973e12c5d1SDavid du Colombier n->addable = 1;
6983e12c5d1SDavid du Colombier break;
6993e12c5d1SDavid du Colombier
7003e12c5d1SDavid du Colombier case OSTRUCT:
7013e12c5d1SDavid du Colombier if(tcomx(n))
7023e12c5d1SDavid du Colombier goto bad;
7033e12c5d1SDavid du Colombier break;
7043e12c5d1SDavid du Colombier }
7057dd7cddfSDavid du Colombier t = n->type;
7067dd7cddfSDavid du Colombier if(t == T)
707219b2ee8SDavid du Colombier goto bad;
7087dd7cddfSDavid du Colombier if(t->width < 0) {
7097dd7cddfSDavid du Colombier snap(t);
7107dd7cddfSDavid du Colombier if(t->width < 0) {
7117dd7cddfSDavid du Colombier if(typesu[t->etype] && t->tag)
7127dd7cddfSDavid du Colombier diag(n, "structure not fully declared %s", t->tag->name);
7137dd7cddfSDavid du Colombier else
7143e12c5d1SDavid du Colombier diag(n, "structure not fully declared");
7153e12c5d1SDavid du Colombier goto bad;
7163e12c5d1SDavid du Colombier }
7177dd7cddfSDavid du Colombier }
7187dd7cddfSDavid du Colombier if(typeaf[t->etype]) {
7193e12c5d1SDavid du Colombier if(f & ADDROF)
7203e12c5d1SDavid du Colombier goto addaddr;
7213e12c5d1SDavid du Colombier if(f & ADDROP)
7223e12c5d1SDavid du Colombier warn(n, "address of array/func ignored");
7233e12c5d1SDavid du Colombier }
7243e12c5d1SDavid du Colombier return 0;
7253e12c5d1SDavid du Colombier
7263e12c5d1SDavid du Colombier addaddr:
7273e12c5d1SDavid du Colombier if(tlvalue(n))
7283e12c5d1SDavid du Colombier goto bad;
7293e12c5d1SDavid du Colombier l = new1(OXXX, Z, Z);
7303e12c5d1SDavid du Colombier *l = *n;
7313e12c5d1SDavid du Colombier n->op = OADDR;
7323e12c5d1SDavid du Colombier if(l->type->etype == TARRAY)
7333e12c5d1SDavid du Colombier l->type = l->type->link;
7343e12c5d1SDavid du Colombier n->left = l;
7353e12c5d1SDavid du Colombier n->right = Z;
7363e12c5d1SDavid du Colombier n->addable = 0;
7373e12c5d1SDavid du Colombier n->type = typ(TIND, l->type);
7383e12c5d1SDavid du Colombier n->type->width = types[TIND]->width;
7393e12c5d1SDavid du Colombier return 0;
7403e12c5d1SDavid du Colombier
7413e12c5d1SDavid du Colombier bad:
7423e12c5d1SDavid du Colombier n->type = T;
7433e12c5d1SDavid du Colombier return 1;
7443e12c5d1SDavid du Colombier }
7453e12c5d1SDavid du Colombier
7463e12c5d1SDavid du Colombier int
tcoma(Node * l,Node * n,Type * t,int f)7473e12c5d1SDavid du Colombier tcoma(Node *l, Node *n, Type *t, int f)
7483e12c5d1SDavid du Colombier {
7493e12c5d1SDavid du Colombier Node *n1;
7503e12c5d1SDavid du Colombier int o;
7513e12c5d1SDavid du Colombier
7523e12c5d1SDavid du Colombier if(t != T)
7533e12c5d1SDavid du Colombier if(t->etype == TOLD || t->etype == TDOT) /* .../old in prototype */
7543e12c5d1SDavid du Colombier t = T;
7553e12c5d1SDavid du Colombier if(n == Z) {
7563e12c5d1SDavid du Colombier if(t != T && !sametype(t, types[TVOID])) {
7573e12c5d1SDavid du Colombier diag(n, "not enough function arguments: %F", l);
7583e12c5d1SDavid du Colombier return 1;
7593e12c5d1SDavid du Colombier }
7603e12c5d1SDavid du Colombier return 0;
7613e12c5d1SDavid du Colombier }
7623e12c5d1SDavid du Colombier if(n->op == OLIST) {
7633e12c5d1SDavid du Colombier o = tcoma(l, n->left, t, 0);
7643e12c5d1SDavid du Colombier if(t != T) {
7653e12c5d1SDavid du Colombier t = t->down;
7663e12c5d1SDavid du Colombier if(t == T)
7673e12c5d1SDavid du Colombier t = types[TVOID];
7683e12c5d1SDavid du Colombier }
7693e12c5d1SDavid du Colombier return o | tcoma(l, n->right, t, 1);
7703e12c5d1SDavid du Colombier }
7713e12c5d1SDavid du Colombier if(f && t != T)
7723e12c5d1SDavid du Colombier tcoma(l, Z, t->down, 0);
7733e12c5d1SDavid du Colombier if(tcom(n) || tcompat(n, T, n->type, targ))
7743e12c5d1SDavid du Colombier return 1;
7753e12c5d1SDavid du Colombier if(sametype(t, types[TVOID])) {
7763e12c5d1SDavid du Colombier diag(n, "too many function arguments: %F", l);
7773e12c5d1SDavid du Colombier return 1;
7783e12c5d1SDavid du Colombier }
7793e12c5d1SDavid du Colombier if(t != T) {
7803e12c5d1SDavid du Colombier typeext(t, n);
7813e12c5d1SDavid du Colombier if(stcompat(nodproto, t, n->type, tasign)) {
7823e12c5d1SDavid du Colombier diag(l, "argument prototype mismatch \"%T\" for \"%T\": %F",
7833e12c5d1SDavid du Colombier n->type, t, l);
7843e12c5d1SDavid du Colombier return 1;
7853e12c5d1SDavid du Colombier }
7863e12c5d1SDavid du Colombier switch(t->etype) {
7873e12c5d1SDavid du Colombier case TCHAR:
7883e12c5d1SDavid du Colombier case TSHORT:
7897dd7cddfSDavid du Colombier t = types[TINT];
7903e12c5d1SDavid du Colombier break;
7913e12c5d1SDavid du Colombier
7923e12c5d1SDavid du Colombier case TUCHAR:
7933e12c5d1SDavid du Colombier case TUSHORT:
7947dd7cddfSDavid du Colombier t = types[TUINT];
7953e12c5d1SDavid du Colombier break;
7963e12c5d1SDavid du Colombier }
7973e12c5d1SDavid du Colombier } else
7983e12c5d1SDavid du Colombier switch(n->type->etype)
7993e12c5d1SDavid du Colombier {
8003e12c5d1SDavid du Colombier case TCHAR:
8013e12c5d1SDavid du Colombier case TSHORT:
8027dd7cddfSDavid du Colombier t = types[TINT];
8033e12c5d1SDavid du Colombier break;
8043e12c5d1SDavid du Colombier
8053e12c5d1SDavid du Colombier case TUCHAR:
8063e12c5d1SDavid du Colombier case TUSHORT:
8077dd7cddfSDavid du Colombier t = types[TUINT];
8083e12c5d1SDavid du Colombier break;
8093e12c5d1SDavid du Colombier
8103e12c5d1SDavid du Colombier case TFLOAT:
8113e12c5d1SDavid du Colombier t = types[TDOUBLE];
8123e12c5d1SDavid du Colombier }
8133e12c5d1SDavid du Colombier if(t != T && !sametype(t, n->type)) {
8143e12c5d1SDavid du Colombier n1 = new1(OXXX, Z, Z);
8153e12c5d1SDavid du Colombier *n1 = *n;
8163e12c5d1SDavid du Colombier n->op = OCAST;
8173e12c5d1SDavid du Colombier n->left = n1;
8183e12c5d1SDavid du Colombier n->right = Z;
8193e12c5d1SDavid du Colombier n->type = t;
8203e12c5d1SDavid du Colombier n->addable = 0;
8213e12c5d1SDavid du Colombier }
8223e12c5d1SDavid du Colombier return 0;
8233e12c5d1SDavid du Colombier }
8243e12c5d1SDavid du Colombier
8253e12c5d1SDavid du Colombier int
tcomd(Node * n)8263e12c5d1SDavid du Colombier tcomd(Node *n)
8273e12c5d1SDavid du Colombier {
8283e12c5d1SDavid du Colombier Type *t;
8293e12c5d1SDavid du Colombier long o;
8303e12c5d1SDavid du Colombier
8313e12c5d1SDavid du Colombier o = 0;
83280ee5cbfSDavid du Colombier t = dotsearch(n->sym, n->left->type->link, n, &o);
8333e12c5d1SDavid du Colombier if(t == T) {
8343e12c5d1SDavid du Colombier diag(n, "not a member of struct/union: %F", n);
8353e12c5d1SDavid du Colombier return 1;
8363e12c5d1SDavid du Colombier }
8373e12c5d1SDavid du Colombier makedot(n, t, o);
8383e12c5d1SDavid du Colombier return 0;
8393e12c5d1SDavid du Colombier }
8403e12c5d1SDavid du Colombier
8413e12c5d1SDavid du Colombier int
tcomx(Node * n)8423e12c5d1SDavid du Colombier tcomx(Node *n)
8433e12c5d1SDavid du Colombier {
8443e12c5d1SDavid du Colombier Type *t;
8453e12c5d1SDavid du Colombier Node *l, *r, **ar, **al;
8463e12c5d1SDavid du Colombier int e;
8473e12c5d1SDavid du Colombier
8483e12c5d1SDavid du Colombier e = 0;
8493e12c5d1SDavid du Colombier if(n->type->etype != TSTRUCT) {
8503e12c5d1SDavid du Colombier diag(n, "constructor must be a structure");
8513e12c5d1SDavid du Colombier return 1;
8523e12c5d1SDavid du Colombier }
8533e12c5d1SDavid du Colombier l = invert(n->left);
8543e12c5d1SDavid du Colombier n->left = l;
8553e12c5d1SDavid du Colombier al = &n->left;
8563e12c5d1SDavid du Colombier for(t = n->type->link; t != T; t = t->down) {
8573e12c5d1SDavid du Colombier if(l == Z) {
8583e12c5d1SDavid du Colombier diag(n, "constructor list too short");
8593e12c5d1SDavid du Colombier return 1;
8603e12c5d1SDavid du Colombier }
8613e12c5d1SDavid du Colombier if(l->op == OLIST) {
8623e12c5d1SDavid du Colombier r = l->left;
8633e12c5d1SDavid du Colombier ar = &l->left;
8643e12c5d1SDavid du Colombier al = &l->right;
8653e12c5d1SDavid du Colombier l = l->right;
8663e12c5d1SDavid du Colombier } else {
8673e12c5d1SDavid du Colombier r = l;
8683e12c5d1SDavid du Colombier ar = al;
8693e12c5d1SDavid du Colombier l = Z;
8703e12c5d1SDavid du Colombier }
8713e12c5d1SDavid du Colombier if(tcom(r))
8723e12c5d1SDavid du Colombier e++;
8733e12c5d1SDavid du Colombier typeext(t, r);
8743e12c5d1SDavid du Colombier if(tcompat(n, t, r->type, tasign))
8753e12c5d1SDavid du Colombier e++;
8767dd7cddfSDavid du Colombier constas(n, t, r->type);
8773e12c5d1SDavid du Colombier if(!e && !sametype(t, r->type)) {
8783e12c5d1SDavid du Colombier r = new1(OCAST, r, Z);
8793e12c5d1SDavid du Colombier r->type = t;
8803e12c5d1SDavid du Colombier *ar = r;
8813e12c5d1SDavid du Colombier }
8823e12c5d1SDavid du Colombier }
8833e12c5d1SDavid du Colombier if(l != Z) {
8843e12c5d1SDavid du Colombier diag(n, "constructor list too long");
8853e12c5d1SDavid du Colombier return 1;
8863e12c5d1SDavid du Colombier }
8873e12c5d1SDavid du Colombier return e;
8883e12c5d1SDavid du Colombier }
8893e12c5d1SDavid du Colombier
8903e12c5d1SDavid du Colombier int
tlvalue(Node * n)8913e12c5d1SDavid du Colombier tlvalue(Node *n)
8923e12c5d1SDavid du Colombier {
8933e12c5d1SDavid du Colombier
8943e12c5d1SDavid du Colombier if(!n->addable) {
8953e12c5d1SDavid du Colombier diag(n, "not an l-value");
8963e12c5d1SDavid du Colombier return 1;
8973e12c5d1SDavid du Colombier }
8983e12c5d1SDavid du Colombier return 0;
8993e12c5d1SDavid du Colombier }
9003e12c5d1SDavid du Colombier
9013e12c5d1SDavid du Colombier /*
902d40255d8SDavid du Colombier * hoist comma operators out of expressions
903d40255d8SDavid du Colombier * (a,b) OP c => (a, b OP c)
904d40255d8SDavid du Colombier * OP(a,b) => (a, OP b)
905d40255d8SDavid du Colombier * a OP (b,c) => (b, a OP c)
906d40255d8SDavid du Colombier */
907d40255d8SDavid du Colombier
908d40255d8SDavid du Colombier static Node*
comargs(Com * com,Node * n)909d40255d8SDavid du Colombier comargs(Com *com, Node *n)
910d40255d8SDavid du Colombier {
911d40255d8SDavid du Colombier if(n != Z && n->op == OLIST){
912d40255d8SDavid du Colombier n->left = comargs(com, n->left);
913d40255d8SDavid du Colombier n->right = comargs(com, n->right);
914d40255d8SDavid du Colombier }
915d40255d8SDavid du Colombier return commas(com, n);
916d40255d8SDavid du Colombier }
917d40255d8SDavid du Colombier
918d40255d8SDavid du Colombier static Node*
commas(Com * com,Node * n)919d40255d8SDavid du Colombier commas(Com *com, Node *n)
920d40255d8SDavid du Colombier {
921d40255d8SDavid du Colombier Node *t;
922d40255d8SDavid du Colombier
923d40255d8SDavid du Colombier if(n == Z)
924d40255d8SDavid du Colombier return n;
925d40255d8SDavid du Colombier switch(n->op){
926d40255d8SDavid du Colombier case OREGISTER:
927d40255d8SDavid du Colombier case OINDREG:
928d40255d8SDavid du Colombier case OCONST:
929d40255d8SDavid du Colombier case ONAME:
930d40255d8SDavid du Colombier case OSTRING:
931d40255d8SDavid du Colombier /* leaf */
932d40255d8SDavid du Colombier return n;
933d40255d8SDavid du Colombier
934d40255d8SDavid du Colombier case OCOMMA:
935d40255d8SDavid du Colombier t = commas(com, n->left);
936d40255d8SDavid du Colombier if(com->n >= nelem(com->t))
937d40255d8SDavid du Colombier fatal(n, "comma list overflow");
938d40255d8SDavid du Colombier com->t[com->n++] = t;
939d40255d8SDavid du Colombier return commas(com, n->right);
940d40255d8SDavid du Colombier
941d40255d8SDavid du Colombier case OFUNC:
942d40255d8SDavid du Colombier n->left = commas(com, n->left);
943d40255d8SDavid du Colombier n->right = comargs(com, n->right);
944d40255d8SDavid du Colombier return n;
945d40255d8SDavid du Colombier
946d40255d8SDavid du Colombier case OCOND:
947d40255d8SDavid du Colombier n->left = commas(com, n->left);
948d40255d8SDavid du Colombier comma(n->right->left);
949d40255d8SDavid du Colombier comma(n->right->right);
950d40255d8SDavid du Colombier return n;
951d40255d8SDavid du Colombier
952d40255d8SDavid du Colombier case OANDAND:
953d40255d8SDavid du Colombier case OOROR:
954d40255d8SDavid du Colombier n->left = commas(com, n->left);
955d40255d8SDavid du Colombier comma(n->right);
956d40255d8SDavid du Colombier return n;
957d40255d8SDavid du Colombier
958d40255d8SDavid du Colombier case ORETURN:
959d40255d8SDavid du Colombier comma(n->left);
960d40255d8SDavid du Colombier return n;
961d40255d8SDavid du Colombier }
962d40255d8SDavid du Colombier n->left = commas(com, n->left);
963d40255d8SDavid du Colombier if(n->right != Z)
964d40255d8SDavid du Colombier n->right = commas(com, n->right);
965d40255d8SDavid du Colombier return n;
966d40255d8SDavid du Colombier }
967d40255d8SDavid du Colombier
968d40255d8SDavid du Colombier static void
comma(Node * n)969d40255d8SDavid du Colombier comma(Node *n)
970d40255d8SDavid du Colombier {
971d40255d8SDavid du Colombier Com com;
972d40255d8SDavid du Colombier Node *nn;
973d40255d8SDavid du Colombier
974d40255d8SDavid du Colombier com.n = 0;
975d40255d8SDavid du Colombier nn = commas(&com, n);
976d40255d8SDavid du Colombier if(com.n > 0){
977d40255d8SDavid du Colombier if(debug['y'])print("n=%d\n", com.n);
978d40255d8SDavid du Colombier if(debug['y']) prtree(nn, "res");
979d40255d8SDavid du Colombier if(nn != n)
980d40255d8SDavid du Colombier *n = *nn;
981d40255d8SDavid du Colombier while(com.n > 0){
982d40255d8SDavid du Colombier if(debug['y']) prtree(com.t[com.n-1], "tree");
983d40255d8SDavid du Colombier nn = new1(OXXX, Z, Z);
984d40255d8SDavid du Colombier *nn = *n;
985d40255d8SDavid du Colombier n->op = OCOMMA;
986d40255d8SDavid du Colombier n->type = nn->type;
987d40255d8SDavid du Colombier n->left = com.t[--com.n];
988d40255d8SDavid du Colombier n->right = nn;
989d40255d8SDavid du Colombier n->lineno = n->left->lineno;
990d40255d8SDavid du Colombier }
991d40255d8SDavid du Colombier if(debug['y']) prtree(n, "final");
992d40255d8SDavid du Colombier }else if(n != nn)
993d40255d8SDavid du Colombier fatal(n, "odd tree");
994d40255d8SDavid du Colombier }
995d40255d8SDavid du Colombier
996d40255d8SDavid du Colombier /*
9973e12c5d1SDavid du Colombier * general rewrite
9983e12c5d1SDavid du Colombier * (IND(ADDR x)) ==> x
9993e12c5d1SDavid du Colombier * (ADDR(IND x)) ==> x
10003e12c5d1SDavid du Colombier * remove some zero operands
10013e12c5d1SDavid du Colombier * remove no op casts
10023e12c5d1SDavid du Colombier * evaluate constants
10033e12c5d1SDavid du Colombier */
10043e12c5d1SDavid du Colombier void
ccom(Node * n)10053e12c5d1SDavid du Colombier ccom(Node *n)
10063e12c5d1SDavid du Colombier {
10073e12c5d1SDavid du Colombier Node *l, *r;
10083e12c5d1SDavid du Colombier int t;
10093e12c5d1SDavid du Colombier
10103e12c5d1SDavid du Colombier loop:
10113e12c5d1SDavid du Colombier if(n == Z)
10123e12c5d1SDavid du Colombier return;
10133e12c5d1SDavid du Colombier l = n->left;
10143e12c5d1SDavid du Colombier r = n->right;
10153e12c5d1SDavid du Colombier switch(n->op) {
1016375daca8SDavid du Colombier
10173e12c5d1SDavid du Colombier case OAS:
10183e12c5d1SDavid du Colombier case OASXOR:
10193e12c5d1SDavid du Colombier case OASAND:
10203e12c5d1SDavid du Colombier case OASOR:
10213e12c5d1SDavid du Colombier case OASMOD:
10223e12c5d1SDavid du Colombier case OASLMOD:
10233e12c5d1SDavid du Colombier case OASLSHR:
10243e12c5d1SDavid du Colombier case OASASHR:
10253e12c5d1SDavid du Colombier case OASASHL:
10263e12c5d1SDavid du Colombier case OASDIV:
10273e12c5d1SDavid du Colombier case OASLDIV:
10283e12c5d1SDavid du Colombier case OASMUL:
10293e12c5d1SDavid du Colombier case OASLMUL:
10303e12c5d1SDavid du Colombier case OASSUB:
10313e12c5d1SDavid du Colombier case OASADD:
10323e12c5d1SDavid du Colombier ccom(l);
10333e12c5d1SDavid du Colombier ccom(r);
10343e12c5d1SDavid du Colombier if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL)
10353e12c5d1SDavid du Colombier if(r->op == OCONST) {
10363e12c5d1SDavid du Colombier t = n->type->width * 8; /* bits per byte */
1037219b2ee8SDavid du Colombier if(r->vconst >= t || r->vconst < 0)
10387dd7cddfSDavid du Colombier warn(n, "stupid shift: %lld", r->vconst);
10393e12c5d1SDavid du Colombier }
10403e12c5d1SDavid du Colombier break;
10413e12c5d1SDavid du Colombier
10423e12c5d1SDavid du Colombier case OCAST:
10433e12c5d1SDavid du Colombier ccom(l);
10443e12c5d1SDavid du Colombier if(l->op == OCONST) {
10453e12c5d1SDavid du Colombier evconst(n);
10463e12c5d1SDavid du Colombier if(n->op == OCONST)
10473e12c5d1SDavid du Colombier break;
10483e12c5d1SDavid du Colombier }
1049d40255d8SDavid du Colombier if(nocast(l->type, n->type) &&
1050d40255d8SDavid du Colombier (!typefd[l->type->etype] || typeu[l->type->etype] && typeu[n->type->etype])) {
10513e12c5d1SDavid du Colombier l->type = n->type;
10523e12c5d1SDavid du Colombier *n = *l;
10533e12c5d1SDavid du Colombier }
10543e12c5d1SDavid du Colombier break;
10553e12c5d1SDavid du Colombier
10563e12c5d1SDavid du Colombier case OCOND:
10573e12c5d1SDavid du Colombier ccom(l);
10583e12c5d1SDavid du Colombier ccom(r);
10593e12c5d1SDavid du Colombier if(l->op == OCONST)
10603e12c5d1SDavid du Colombier if(vconst(l) == 0)
10613e12c5d1SDavid du Colombier *n = *r->right;
10623e12c5d1SDavid du Colombier else
10633e12c5d1SDavid du Colombier *n = *r->left;
10643e12c5d1SDavid du Colombier break;
10653e12c5d1SDavid du Colombier
10663e12c5d1SDavid du Colombier case OREGISTER:
10673e12c5d1SDavid du Colombier case OINDREG:
10683e12c5d1SDavid du Colombier case OCONST:
10693e12c5d1SDavid du Colombier case ONAME:
10703e12c5d1SDavid du Colombier break;
10713e12c5d1SDavid du Colombier
10723e12c5d1SDavid du Colombier case OADDR:
10733e12c5d1SDavid du Colombier ccom(l);
10743e12c5d1SDavid du Colombier l->etype = TVOID;
10753e12c5d1SDavid du Colombier if(l->op == OIND) {
10763e12c5d1SDavid du Colombier l->left->type = n->type;
10773e12c5d1SDavid du Colombier *n = *l->left;
10783e12c5d1SDavid du Colombier break;
10793e12c5d1SDavid du Colombier }
10803e12c5d1SDavid du Colombier goto common;
10813e12c5d1SDavid du Colombier
10823e12c5d1SDavid du Colombier case OIND:
10833e12c5d1SDavid du Colombier ccom(l);
10843e12c5d1SDavid du Colombier if(l->op == OADDR) {
10853e12c5d1SDavid du Colombier l->left->type = n->type;
10863e12c5d1SDavid du Colombier *n = *l->left;
10873e12c5d1SDavid du Colombier break;
10883e12c5d1SDavid du Colombier }
10893e12c5d1SDavid du Colombier goto common;
10903e12c5d1SDavid du Colombier
10913e12c5d1SDavid du Colombier case OEQ:
10923e12c5d1SDavid du Colombier case ONE:
10933e12c5d1SDavid du Colombier
10943e12c5d1SDavid du Colombier case OLE:
10953e12c5d1SDavid du Colombier case OGE:
10963e12c5d1SDavid du Colombier case OLT:
10973e12c5d1SDavid du Colombier case OGT:
10983e12c5d1SDavid du Colombier
10993e12c5d1SDavid du Colombier case OLS:
11003e12c5d1SDavid du Colombier case OHS:
11013e12c5d1SDavid du Colombier case OLO:
11023e12c5d1SDavid du Colombier case OHI:
11033e12c5d1SDavid du Colombier ccom(l);
11043e12c5d1SDavid du Colombier ccom(r);
110522a127bbSDavid du Colombier if(compar(n, 0) || compar(n, 1))
110622a127bbSDavid du Colombier break;
11073e12c5d1SDavid du Colombier relcon(l, r);
11083e12c5d1SDavid du Colombier relcon(r, l);
11093e12c5d1SDavid du Colombier goto common;
11103e12c5d1SDavid du Colombier
11113e12c5d1SDavid du Colombier case OASHR:
11123e12c5d1SDavid du Colombier case OASHL:
11133e12c5d1SDavid du Colombier case OLSHR:
11143e12c5d1SDavid du Colombier ccom(l);
11153e12c5d1SDavid du Colombier if(vconst(l) == 0 && !side(r)) {
11163e12c5d1SDavid du Colombier *n = *l;
11173e12c5d1SDavid du Colombier break;
11183e12c5d1SDavid du Colombier }
11193e12c5d1SDavid du Colombier ccom(r);
11203e12c5d1SDavid du Colombier if(vconst(r) == 0) {
11213e12c5d1SDavid du Colombier *n = *l;
11223e12c5d1SDavid du Colombier break;
11233e12c5d1SDavid du Colombier }
11243e12c5d1SDavid du Colombier if(r->op == OCONST) {
11253e12c5d1SDavid du Colombier t = n->type->width * 8; /* bits per byte */
1126219b2ee8SDavid du Colombier if(r->vconst >= t || r->vconst <= -t)
11277dd7cddfSDavid du Colombier warn(n, "stupid shift: %lld", r->vconst);
11283e12c5d1SDavid du Colombier }
11293e12c5d1SDavid du Colombier goto common;
11303e12c5d1SDavid du Colombier
11313e12c5d1SDavid du Colombier case OMUL:
11323e12c5d1SDavid du Colombier case OLMUL:
11333e12c5d1SDavid du Colombier ccom(l);
11343e12c5d1SDavid du Colombier t = vconst(l);
11353e12c5d1SDavid du Colombier if(t == 0 && !side(r)) {
11363e12c5d1SDavid du Colombier *n = *l;
11373e12c5d1SDavid du Colombier break;
11383e12c5d1SDavid du Colombier }
11393e12c5d1SDavid du Colombier if(t == 1) {
11403e12c5d1SDavid du Colombier *n = *r;
11413e12c5d1SDavid du Colombier goto loop;
11423e12c5d1SDavid du Colombier }
11433e12c5d1SDavid du Colombier ccom(r);
11443e12c5d1SDavid du Colombier t = vconst(r);
11453e12c5d1SDavid du Colombier if(t == 0 && !side(l)) {
11463e12c5d1SDavid du Colombier *n = *r;
11473e12c5d1SDavid du Colombier break;
11483e12c5d1SDavid du Colombier }
11493e12c5d1SDavid du Colombier if(t == 1) {
11503e12c5d1SDavid du Colombier *n = *l;
11513e12c5d1SDavid du Colombier break;
11523e12c5d1SDavid du Colombier }
11533e12c5d1SDavid du Colombier goto common;
11543e12c5d1SDavid du Colombier
11553e12c5d1SDavid du Colombier case ODIV:
11563e12c5d1SDavid du Colombier case OLDIV:
11573e12c5d1SDavid du Colombier ccom(l);
11583e12c5d1SDavid du Colombier if(vconst(l) == 0 && !side(r)) {
11593e12c5d1SDavid du Colombier *n = *l;
11603e12c5d1SDavid du Colombier break;
11613e12c5d1SDavid du Colombier }
11623e12c5d1SDavid du Colombier ccom(r);
11633e12c5d1SDavid du Colombier t = vconst(r);
11643e12c5d1SDavid du Colombier if(t == 0) {
11653e12c5d1SDavid du Colombier diag(n, "divide check");
11663e12c5d1SDavid du Colombier *n = *r;
11673e12c5d1SDavid du Colombier break;
11683e12c5d1SDavid du Colombier }
11693e12c5d1SDavid du Colombier if(t == 1) {
11703e12c5d1SDavid du Colombier *n = *l;
11713e12c5d1SDavid du Colombier break;
11723e12c5d1SDavid du Colombier }
11733e12c5d1SDavid du Colombier goto common;
11743e12c5d1SDavid du Colombier
11753e12c5d1SDavid du Colombier case OSUB:
11763e12c5d1SDavid du Colombier ccom(r);
11773e12c5d1SDavid du Colombier if(r->op == OCONST) {
1178219b2ee8SDavid du Colombier if(typefd[r->type->etype]) {
11793e12c5d1SDavid du Colombier n->op = OADD;
1180219b2ee8SDavid du Colombier r->fconst = -r->fconst;
11813e12c5d1SDavid du Colombier goto loop;
1182219b2ee8SDavid du Colombier } else {
11833e12c5d1SDavid du Colombier n->op = OADD;
1184219b2ee8SDavid du Colombier r->vconst = -r->vconst;
11853e12c5d1SDavid du Colombier goto loop;
11863e12c5d1SDavid du Colombier }
11873e12c5d1SDavid du Colombier }
11883e12c5d1SDavid du Colombier ccom(l);
11893e12c5d1SDavid du Colombier goto common;
11903e12c5d1SDavid du Colombier
11913e12c5d1SDavid du Colombier case OXOR:
11923e12c5d1SDavid du Colombier case OOR:
11933e12c5d1SDavid du Colombier case OADD:
11943e12c5d1SDavid du Colombier ccom(l);
11953e12c5d1SDavid du Colombier if(vconst(l) == 0) {
11963e12c5d1SDavid du Colombier *n = *r;
11973e12c5d1SDavid du Colombier goto loop;
11983e12c5d1SDavid du Colombier }
11993e12c5d1SDavid du Colombier ccom(r);
12003e12c5d1SDavid du Colombier if(vconst(r) == 0) {
12013e12c5d1SDavid du Colombier *n = *l;
12023e12c5d1SDavid du Colombier break;
12033e12c5d1SDavid du Colombier }
120422a127bbSDavid du Colombier goto commute;
12053e12c5d1SDavid du Colombier
12063e12c5d1SDavid du Colombier case OAND:
12073e12c5d1SDavid du Colombier ccom(l);
12083e12c5d1SDavid du Colombier ccom(r);
12093e12c5d1SDavid du Colombier if(vconst(l) == 0 && !side(r)) {
12103e12c5d1SDavid du Colombier *n = *l;
12113e12c5d1SDavid du Colombier break;
12123e12c5d1SDavid du Colombier }
12133e12c5d1SDavid du Colombier if(vconst(r) == 0 && !side(l)) {
12143e12c5d1SDavid du Colombier *n = *r;
12153e12c5d1SDavid du Colombier break;
12163e12c5d1SDavid du Colombier }
1217219b2ee8SDavid du Colombier
121822a127bbSDavid du Colombier commute:
1219219b2ee8SDavid du Colombier /* look for commutative constant */
1220219b2ee8SDavid du Colombier if(r->op == OCONST) {
1221219b2ee8SDavid du Colombier if(l->op == n->op) {
1222219b2ee8SDavid du Colombier if(l->left->op == OCONST) {
1223219b2ee8SDavid du Colombier n->right = l->right;
1224219b2ee8SDavid du Colombier l->right = r;
1225219b2ee8SDavid du Colombier goto loop;
1226219b2ee8SDavid du Colombier }
1227219b2ee8SDavid du Colombier if(l->right->op == OCONST) {
1228219b2ee8SDavid du Colombier n->right = l->left;
1229219b2ee8SDavid du Colombier l->left = r;
1230219b2ee8SDavid du Colombier goto loop;
1231219b2ee8SDavid du Colombier }
1232219b2ee8SDavid du Colombier }
1233219b2ee8SDavid du Colombier }
1234219b2ee8SDavid du Colombier if(l->op == OCONST) {
1235219b2ee8SDavid du Colombier if(r->op == n->op) {
1236219b2ee8SDavid du Colombier if(r->left->op == OCONST) {
1237219b2ee8SDavid du Colombier n->left = r->right;
1238219b2ee8SDavid du Colombier r->right = l;
1239219b2ee8SDavid du Colombier goto loop;
1240219b2ee8SDavid du Colombier }
1241219b2ee8SDavid du Colombier if(r->right->op == OCONST) {
1242219b2ee8SDavid du Colombier n->left = r->left;
1243219b2ee8SDavid du Colombier r->left = l;
1244219b2ee8SDavid du Colombier goto loop;
1245219b2ee8SDavid du Colombier }
1246219b2ee8SDavid du Colombier }
1247219b2ee8SDavid du Colombier }
12483e12c5d1SDavid du Colombier goto common;
12493e12c5d1SDavid du Colombier
12503e12c5d1SDavid du Colombier case OANDAND:
12513e12c5d1SDavid du Colombier ccom(l);
1252219b2ee8SDavid du Colombier if(vconst(l) == 0) {
12533e12c5d1SDavid du Colombier *n = *l;
12543e12c5d1SDavid du Colombier break;
12553e12c5d1SDavid du Colombier }
12563e12c5d1SDavid du Colombier ccom(r);
12573e12c5d1SDavid du Colombier goto common;
12583e12c5d1SDavid du Colombier
12593e12c5d1SDavid du Colombier case OOROR:
12603e12c5d1SDavid du Colombier ccom(l);
1261219b2ee8SDavid du Colombier if(l->op == OCONST && l->vconst != 0) {
12623e12c5d1SDavid du Colombier *n = *l;
1263219b2ee8SDavid du Colombier n->vconst = 1;
12643e12c5d1SDavid du Colombier break;
12653e12c5d1SDavid du Colombier }
12663e12c5d1SDavid du Colombier ccom(r);
12673e12c5d1SDavid du Colombier goto common;
12683e12c5d1SDavid du Colombier
12693e12c5d1SDavid du Colombier default:
12703e12c5d1SDavid du Colombier if(l != Z)
12713e12c5d1SDavid du Colombier ccom(l);
12723e12c5d1SDavid du Colombier if(r != Z)
12733e12c5d1SDavid du Colombier ccom(r);
12743e12c5d1SDavid du Colombier common:
12753e12c5d1SDavid du Colombier if(l != Z)
12763e12c5d1SDavid du Colombier if(l->op != OCONST)
12773e12c5d1SDavid du Colombier break;
12783e12c5d1SDavid du Colombier if(r != Z)
12793e12c5d1SDavid du Colombier if(r->op != OCONST)
12803e12c5d1SDavid du Colombier break;
12813e12c5d1SDavid du Colombier evconst(n);
12823e12c5d1SDavid du Colombier }
12833e12c5d1SDavid du Colombier }
128422a127bbSDavid du Colombier
128522a127bbSDavid du Colombier /* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */
128622a127bbSDavid du Colombier static char *cmps[12] =
128722a127bbSDavid du Colombier {
128822a127bbSDavid du Colombier "==", "!=", "<=", "<=", "<", "<", ">=", ">=", ">", ">",
128922a127bbSDavid du Colombier };
129022a127bbSDavid du Colombier
129122a127bbSDavid du Colombier /* 128-bit numbers */
129222a127bbSDavid du Colombier typedef struct Big Big;
129322a127bbSDavid du Colombier struct Big
129422a127bbSDavid du Colombier {
129522a127bbSDavid du Colombier vlong a;
129622a127bbSDavid du Colombier uvlong b;
129722a127bbSDavid du Colombier };
129822a127bbSDavid du Colombier static int
cmp(Big x,Big y)129922a127bbSDavid du Colombier cmp(Big x, Big y)
130022a127bbSDavid du Colombier {
130122a127bbSDavid du Colombier if(x.a != y.a){
130222a127bbSDavid du Colombier if(x.a < y.a)
130322a127bbSDavid du Colombier return -1;
130422a127bbSDavid du Colombier return 1;
130522a127bbSDavid du Colombier }
130622a127bbSDavid du Colombier if(x.b != y.b){
130722a127bbSDavid du Colombier if(x.b < y.b)
130822a127bbSDavid du Colombier return -1;
130922a127bbSDavid du Colombier return 1;
131022a127bbSDavid du Colombier }
131122a127bbSDavid du Colombier return 0;
131222a127bbSDavid du Colombier }
131322a127bbSDavid du Colombier static Big
add(Big x,int y)131422a127bbSDavid du Colombier add(Big x, int y)
131522a127bbSDavid du Colombier {
131622a127bbSDavid du Colombier uvlong ob;
131722a127bbSDavid du Colombier
131822a127bbSDavid du Colombier ob = x.b;
131922a127bbSDavid du Colombier x.b += y;
132022a127bbSDavid du Colombier if(y > 0 && x.b < ob)
132122a127bbSDavid du Colombier x.a++;
132222a127bbSDavid du Colombier if(y < 0 && x.b > ob)
132322a127bbSDavid du Colombier x.a--;
132422a127bbSDavid du Colombier return x;
132522a127bbSDavid du Colombier }
132622a127bbSDavid du Colombier
132722a127bbSDavid du Colombier Big
big(vlong a,uvlong b)132822a127bbSDavid du Colombier big(vlong a, uvlong b)
132922a127bbSDavid du Colombier {
133022a127bbSDavid du Colombier Big x;
133122a127bbSDavid du Colombier
133222a127bbSDavid du Colombier x.a = a;
133322a127bbSDavid du Colombier x.b = b;
133422a127bbSDavid du Colombier return x;
133522a127bbSDavid du Colombier }
133622a127bbSDavid du Colombier
133722a127bbSDavid du Colombier int
compar(Node * n,int reverse)133822a127bbSDavid du Colombier compar(Node *n, int reverse)
133922a127bbSDavid du Colombier {
134022a127bbSDavid du Colombier Big lo, hi, x;
134122a127bbSDavid du Colombier int op;
134222a127bbSDavid du Colombier char xbuf[40], cmpbuf[50];
134322a127bbSDavid du Colombier Node *l, *r;
134422a127bbSDavid du Colombier Type *lt, *rt;
134522a127bbSDavid du Colombier
134622a127bbSDavid du Colombier /*
134722a127bbSDavid du Colombier * The point of this function is to diagnose comparisons
134822a127bbSDavid du Colombier * that can never be true or that look misleading because
134922a127bbSDavid du Colombier * of the `usual arithmetic conversions'. As an example
135022a127bbSDavid du Colombier * of the latter, if x is a ulong, then if(x <= -1) really means
135122a127bbSDavid du Colombier * if(x <= 0xFFFFFFFF), while if(x <= -1LL) really means
135222a127bbSDavid du Colombier * what it says (but 8c compiles it wrong anyway).
135322a127bbSDavid du Colombier */
135422a127bbSDavid du Colombier
135522a127bbSDavid du Colombier if(reverse){
135622a127bbSDavid du Colombier r = n->left;
135722a127bbSDavid du Colombier l = n->right;
135822a127bbSDavid du Colombier op = comrel[relindex(n->op)];
135922a127bbSDavid du Colombier }else{
136022a127bbSDavid du Colombier l = n->left;
136122a127bbSDavid du Colombier r = n->right;
136222a127bbSDavid du Colombier op = n->op;
136322a127bbSDavid du Colombier }
136422a127bbSDavid du Colombier
136522a127bbSDavid du Colombier /*
136622a127bbSDavid du Colombier * Skip over left casts to find out the original expression range.
136722a127bbSDavid du Colombier */
136822a127bbSDavid du Colombier while(l->op == OCAST)
136922a127bbSDavid du Colombier l = l->left;
137022a127bbSDavid du Colombier if(l->op == OCONST)
137122a127bbSDavid du Colombier return 0;
137222a127bbSDavid du Colombier lt = l->type;
1373208510e1SDavid du Colombier if(l->op == ONAME && l->sym->type){
137422a127bbSDavid du Colombier lt = l->sym->type;
13755ede6b93SDavid du Colombier if(lt->etype == TARRAY)
137622a127bbSDavid du Colombier lt = lt->link;
137722a127bbSDavid du Colombier }
137822a127bbSDavid du Colombier if(lt == T)
137922a127bbSDavid du Colombier return 0;
138022a127bbSDavid du Colombier if(lt->etype == TXXX || lt->etype > TUVLONG)
138122a127bbSDavid du Colombier return 0;
138222a127bbSDavid du Colombier
138322a127bbSDavid du Colombier /*
138422a127bbSDavid du Colombier * Skip over the right casts to find the on-screen value.
138522a127bbSDavid du Colombier */
138622a127bbSDavid du Colombier if(r->op != OCONST)
138722a127bbSDavid du Colombier return 0;
138822a127bbSDavid du Colombier while(r->oldop == OCAST && !r->xcast)
138922a127bbSDavid du Colombier r = r->left;
139022a127bbSDavid du Colombier rt = r->type;
139122a127bbSDavid du Colombier if(rt == T)
139222a127bbSDavid du Colombier return 0;
139322a127bbSDavid du Colombier
139422a127bbSDavid du Colombier x.b = r->vconst;
139522a127bbSDavid du Colombier x.a = 0;
139622a127bbSDavid du Colombier if((rt->etype&1) && r->vconst < 0) /* signed negative */
139722a127bbSDavid du Colombier x.a = ~0ULL;
139822a127bbSDavid du Colombier
139922a127bbSDavid du Colombier if((lt->etype&1)==0){
140022a127bbSDavid du Colombier /* unsigned */
140122a127bbSDavid du Colombier lo = big(0, 0);
140222a127bbSDavid du Colombier if(lt->width == 8)
140322a127bbSDavid du Colombier hi = big(0, ~0ULL);
140422a127bbSDavid du Colombier else
140522a127bbSDavid du Colombier hi = big(0, (1LL<<(l->type->width*8))-1);
140622a127bbSDavid du Colombier }else{
140722a127bbSDavid du Colombier lo = big(~0ULL, -(1LL<<(l->type->width*8-1)));
140822a127bbSDavid du Colombier hi = big(0, (1LL<<(l->type->width*8-1))-1);
140922a127bbSDavid du Colombier }
141022a127bbSDavid du Colombier
141122a127bbSDavid du Colombier switch(op){
141222a127bbSDavid du Colombier case OLT:
141322a127bbSDavid du Colombier case OLO:
141422a127bbSDavid du Colombier case OGE:
141522a127bbSDavid du Colombier case OHS:
141622a127bbSDavid du Colombier if(cmp(x, lo) <= 0)
141722a127bbSDavid du Colombier goto useless;
141822a127bbSDavid du Colombier if(cmp(x, add(hi, 1)) >= 0)
141922a127bbSDavid du Colombier goto useless;
142022a127bbSDavid du Colombier break;
142122a127bbSDavid du Colombier case OLE:
142222a127bbSDavid du Colombier case OLS:
142322a127bbSDavid du Colombier case OGT:
142422a127bbSDavid du Colombier case OHI:
142522a127bbSDavid du Colombier if(cmp(x, add(lo, -1)) <= 0)
142622a127bbSDavid du Colombier goto useless;
142722a127bbSDavid du Colombier if(cmp(x, hi) >= 0)
142822a127bbSDavid du Colombier goto useless;
142922a127bbSDavid du Colombier break;
143022a127bbSDavid du Colombier case OEQ:
143122a127bbSDavid du Colombier case ONE:
143222a127bbSDavid du Colombier /*
143322a127bbSDavid du Colombier * Don't warn about comparisons if the expression
143422a127bbSDavid du Colombier * is as wide as the value: the compiler-supplied casts
143522a127bbSDavid du Colombier * will make both outcomes possible.
143622a127bbSDavid du Colombier */
143722a127bbSDavid du Colombier if(lt->width >= rt->width && debug['w'] < 2)
143822a127bbSDavid du Colombier return 0;
143922a127bbSDavid du Colombier if(cmp(x, lo) < 0 || cmp(x, hi) > 0)
144022a127bbSDavid du Colombier goto useless;
144122a127bbSDavid du Colombier break;
144222a127bbSDavid du Colombier }
144322a127bbSDavid du Colombier return 0;
144422a127bbSDavid du Colombier
144522a127bbSDavid du Colombier useless:
144622a127bbSDavid du Colombier if((x.a==0 && x.b<=9) || (x.a==~0LL && x.b >= -9ULL))
144722a127bbSDavid du Colombier snprint(xbuf, sizeof xbuf, "%lld", x.b);
144822a127bbSDavid du Colombier else if(x.a == 0)
144922a127bbSDavid du Colombier snprint(xbuf, sizeof xbuf, "%#llux", x.b);
145022a127bbSDavid du Colombier else
145122a127bbSDavid du Colombier snprint(xbuf, sizeof xbuf, "%#llx", x.b);
145222a127bbSDavid du Colombier if(reverse)
145322a127bbSDavid du Colombier snprint(cmpbuf, sizeof cmpbuf, "%s %s %T",
145422a127bbSDavid du Colombier xbuf, cmps[relindex(n->op)], lt);
145522a127bbSDavid du Colombier else
145622a127bbSDavid du Colombier snprint(cmpbuf, sizeof cmpbuf, "%T %s %s",
145722a127bbSDavid du Colombier lt, cmps[relindex(n->op)], xbuf);
1458d40255d8SDavid du Colombier if(debug['y']) prtree(n, "strange");
145922a127bbSDavid du Colombier warn(n, "useless or misleading comparison: %s", cmpbuf);
146022a127bbSDavid du Colombier return 0;
146122a127bbSDavid du Colombier }
146222a127bbSDavid du Colombier
1463