4 static char rcsid
[] = "$Id$";
6 #define foldcnst(TYPE,VAR,OP) \
7 if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
8 return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)
10 if (generic(R->op) == CNST && generic(L->op) != CNST) \
11 do { Tree t = L; L = R; R = t; } while(0)
12 #define xfoldcnst(TYPE,VAR,OP,FUNC)\
13 if (l->op == CNST+TYPE && r->op == CNST+TYPE\
14 && FUNC(l->u.v.VAR,r->u.v.VAR,\
15 ty->u.sym->u.limits.min.VAR,\
16 ty->u.sym->u.limits.max.VAR, needconst)) \
17 return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)
18 #define xcvtcnst(FTYPE,SRC,DST,VAR,EXPR) \
19 if (l->op == CNST+FTYPE) do {\
21 && ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
22 warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\
24 || !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
25 return cnsttree(ty, (EXPR)); } while(0)
26 #define identity(X,Y,TYPE,VAR,VAL) \
27 if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y
28 #define zerofield(OP,TYPE,VAR) \
30 && r->op == CNST+TYPE && r->u.v.VAR == 0)\
31 return eqtree(OP, bittree(BAND, l->kids[0],\
32 cnsttree(unsignedtype, \
33 (unsigned long)fieldmask(l->u.field)<<fieldright(l->u.field))), r)
34 #define cfoldcnst(TYPE,VAR,OP) \
35 if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
36 return cnsttree(inttype, (long)(l->u.v.VAR OP r->u.v.VAR))
37 #define foldaddp(L,R,RTYPE,VAR) \
38 if (L->op == CNST+P && R->op == CNST+RTYPE) { \
39 Tree e = tree(CNST+P, ty, NULL, NULL);\
40 e->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\
42 #define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP
43 #define sfoldcnst(OP) \
44 if (l->op == CNST+U && r->op == CNST+I \
45 && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) \
46 return cnsttree(ty, (unsigned long)(l->u.v.u OP r->u.v.i))
48 if (R->op == CNST+U && R->u.v.u == 0) do { \
49 warning("result of unsigned comparison is constant\n"); \
50 return tree(RIGHT, inttype, root(L), cnsttree(inttype, (long)(V))); } while(0)
51 #define idempotent(OP) if (l->op == OP) return l->kids[0]
55 static int addi(long x
, long y
, long min
, long max
, int needconst
) {
56 int cond
= x
== 0 || y
== 0
57 || x
< 0 && y
< 0 && x
>= min
- y
60 || x
> 0 && y
> 0 && x
<= max
- y
;
61 if (!cond
&& needconst
) {
62 warning("overflow in constant expression\n");
70 static int addd(double x
, double y
, double min
, double max
, int needconst
) {
71 int cond
= x
== 0 || y
== 0
72 || x
< 0 && y
< 0 && x
>= min
- y
75 || x
> 0 && y
> 0 && x
<= max
- y
;
76 if (!cond
&& needconst
) {
77 warning("overflow in constant expression\n");
85 static Tree
addrtree(Tree e
, long n
, Type ty
) {
86 Symbol p
= e
->u
.sym
, q
;
88 if (p
->scope
== GLOBAL
89 || p
->sclass
== STATIC
|| p
->sclass
== EXTERN
)
93 q
->name
= stringd(genlabel(1));
94 q
->sclass
= p
->sclass
;
96 assert(isptr(ty
) || isarray(ty
));
97 q
->type
= isptr(ty
) ? ty
->type
: ty
;
98 q
->temporary
= p
->temporary
;
99 q
->generated
= p
->generated
;
100 q
->addressed
= p
->addressed
;
105 if (p
->scope
== GLOBAL
106 || p
->sclass
== STATIC
|| p
->sclass
== EXTERN
) {
107 if (p
->sclass
== AUTO
)
109 (*IR
->address
)(q
, p
, n
);
116 cp
->u
.addr
.offset
= n
;
118 e
= tree(e
->op
, ty
, NULL
, NULL
);
123 /* div[id] - return 1 if min <= x/y <= max, 0 otherwise */
124 static int divi(long x
, long y
, long min
, long max
, int needconst
) {
125 int cond
= y
!= 0 && !(x
== min
&& y
== -1);
126 if (!cond
&& needconst
) {
127 warning("overflow in constant expression\n");
135 static int divd(double x
, double y
, double min
, double max
, int needconst
) {
140 cond
= y
!= 0 && !(y
< 1 && x
> max
*y
);
141 if (!cond
&& needconst
) {
142 warning("overflow in constant expression\n");
149 /* mul[id] - return 1 if min <= x*y <= max, 0 otherwise */
150 static int muli(long x
, long y
, long min
, long max
, int needconst
) {
151 int cond
= x
> -1 && x
<= 1 || y
> -1 && y
<= 1
152 || x
< 0 && y
< 0 && -x
<= max
/-y
153 || x
< 0 && y
> 0 && x
>= min
/y
154 || x
> 0 && y
< 0 && y
>= min
/x
155 || x
> 0 && y
> 0 && x
<= max
/y
;
156 if (!cond
&& needconst
) {
157 warning("overflow in constant expression\n");
165 static int muld(double x
, double y
, double min
, double max
, int needconst
) {
166 int cond
= x
>= -1 && x
<= 1 || y
>= -1 && y
<= 1
167 || x
< 0 && y
< 0 && -x
<= max
/-y
168 || x
< 0 && y
> 0 && x
>= min
/y
169 || x
> 0 && y
< 0 && y
>= min
/x
170 || x
> 0 && y
> 0 && x
<= max
/y
;
171 if (!cond
&& needconst
) {
172 warning("overflow in constant expression\n");
179 /* sub[id] - return 1 if min <= x-y <= max, 0 otherwise */
180 static int subi(long x
, long y
, long min
, long max
, int needconst
) {
181 return addi(x
, -y
, min
, max
, needconst
);
184 static int subd(double x
, double y
, double min
, double max
, int needconst
) {
185 return addd(x
, -y
, min
, max
, needconst
);
187 Tree
constexpr(int tok
) {
196 int intexpr(int tok
, int n
) {
197 Tree p
= constexpr(tok
);
200 if (p
->op
== CNST
+I
|| p
->op
== CNST
+U
)
201 n
= cast(p
, inttype
)->u
.v
.i
;
203 error("integer expression must be constant\n");
207 Tree
simplify(int op
, Type ty
, Tree l
, Tree r
) {
220 xfoldcnst(I
,i
,+,addi
);
225 xcvtcnst(I
,l
->u
.v
.i
,ty
,i
,(long)extend(l
->u
.v
.i
,ty
));
228 if (l
->op
== CNST
+U
) {
229 if (!explicitCast
&& l
->u
.v
.u
> ty
->u
.sym
->u
.limits
.max
.i
)
230 warning("overflow in converting constant expression from `%t' to `%t'\n", l
->type
, ty
);
231 if (needconst
|| !(l
->u
.v
.u
> ty
->u
.sym
->u
.limits
.max
.i
))
232 return cnsttree(ty
, (long)extend(l
->u
.v
.u
,ty
));
236 xcvtcnst(P
,(unsigned long)l
->u
.v
.p
,ty
,u
,(unsigned long)l
->u
.v
.p
);
239 xcvtcnst(U
,(void*)l
->u
.v
.u
,ty
,p
,(void*)l
->u
.v
.u
);
242 xcvtcnst(P
,l
->u
.v
.p
,ty
,p
,l
->u
.v
.p
);
245 xcvtcnst(I
,l
->u
.v
.i
,ty
,u
,((unsigned long)l
->u
.v
.i
)&ones(8*ty
->size
));
248 xcvtcnst(U
,l
->u
.v
.u
,ty
,u
,l
->u
.v
.u
&ones(8*ty
->size
));
252 xcvtcnst(I
,l
->u
.v
.i
,ty
,d
,(long double)l
->u
.v
.i
);
254 xcvtcnst(U
,l
->u
.v
.u
,ty
,d
,(long double)l
->u
.v
.u
);
257 xcvtcnst(F
,l
->u
.v
.d
,ty
,i
,(long)l
->u
.v
.d
);
262 if (l
->u
.v
.d
< ty
->u
.sym
->u
.limits
.min
.d
)
263 d
= ty
->u
.sym
->u
.limits
.min
.d
;
264 else if (l
->u
.v
.d
> ty
->u
.sym
->u
.limits
.max
.d
)
265 d
= ty
->u
.sym
->u
.limits
.max
.d
;
268 xcvtcnst(F
,l
->u
.v
.d
,ty
,d
,(long double)d
);
274 identity(r
,l
,U
,u
,ones(8*ty
->size
));
275 if (r
->op
== CNST
+U
&& r
->u
.v
.u
== 0)
276 return tree(RIGHT
, ty
, root(l
), cnsttree(ty
, 0UL));
281 identity(r
,l
,I
,i
,ones(8*ty
->size
));
282 if (r
->op
== CNST
+I
&& r
->u
.v
.u
== 0)
283 return tree(RIGHT
, ty
, root(l
), cnsttree(ty
, 0L));
288 if (l
->op
== CNST
+U
&& (n
= ispow2(l
->u
.v
.u
)) != 0)
289 return simplify(LSH
, ty
, r
, cnsttree(inttype
, (long)n
));
310 identity(r
,retype(l
,ty
),I
,i
,0);
311 identity(r
,retype(l
,ty
),U
,u
,0);
313 Some assemblers, e.g., the MIPS, can't handle offsets
314 larger than 16 bits. A better solution would be to change
315 the interface so that address() could fail.
317 if (l
->op
== ADDRG
+P
&& l
->u
.sym
->generated
318 && (r
->op
== CNST
+I
&& (r
->u
.v
.i
> 32767 || r
->u
.v
.i
< -32768)
319 || r
->op
== CNST
+U
&& r
->u
.v
.u
> 65536))
323 && (r
->op
== CNST
+I
&& r
->u
.v
.i
<= longtype
->u
.sym
->u
.limits
.max
.i
324 && r
->u
.v
.i
>= longtype
->u
.sym
->u
.limits
.min
.i
325 || r
->op
== CNST
+U
&& r
->u
.v
.u
<= longtype
->u
.sym
->u
.limits
.max
.i
))
326 return addrtree(l
, cast(r
, longtype
)->u
.v
.i
, ty
);
328 && l
->op
== ADD
+P
&& isaddrop(l
->kids
[1]->op
)
329 && (r
->op
== CNST
+I
&& r
->u
.v
.i
<= longtype
->u
.sym
->u
.limits
.max
.i
330 && r
->u
.v
.i
>= longtype
->u
.sym
->u
.limits
.min
.i
331 || r
->op
== CNST
+U
&& r
->u
.v
.u
<= longtype
->u
.sym
->u
.limits
.max
.i
))
332 return simplify(ADD
+P
, ty
, l
->kids
[0],
333 addrtree(l
->kids
[1], cast(r
, longtype
)->u
.v
.i
, ty
));
334 if ((l
->op
== ADD
+I
|| l
->op
== SUB
+I
)
335 && l
->kids
[1]->op
== CNST
+I
&& isaddrop(r
->op
))
336 return simplify(ADD
+P
, ty
, l
->kids
[0],
337 simplify(generic(l
->op
)+P
, ty
, r
, l
->kids
[1]));
338 if (l
->op
== ADD
+P
&& generic(l
->kids
[1]->op
) == CNST
339 && generic(r
->op
) == CNST
)
340 return simplify(ADD
+P
, ty
, l
->kids
[0],
341 simplify(ADD
, l
->kids
[1]->type
, l
->kids
[1], r
));
342 if (l
->op
== ADD
+I
&& generic(l
->kids
[1]->op
) == CNST
343 && r
->op
== ADD
+P
&& generic(r
->kids
[1]->op
) == CNST
)
344 return simplify(ADD
+P
, ty
, l
->kids
[0],
345 simplify(ADD
+P
, ty
, r
->kids
[0],
346 simplify(ADD
, r
->kids
[1]->type
, l
->kids
[1], r
->kids
[1])));
347 if (l
->op
== RIGHT
&& l
->kids
[1])
348 return tree(RIGHT
, ty
, l
->kids
[0],
349 simplify(ADD
+P
, ty
, l
->kids
[1], r
));
350 else if (l
->op
== RIGHT
&& l
->kids
[0])
351 return tree(RIGHT
, ty
,
352 simplify(ADD
+P
, ty
, l
->kids
[0], r
), NULL
);
356 xfoldcnst(F
,d
,+,addd
);
361 ufoldcnst(I
,l
->u
.v
.i
? cond(r
) : l
); /* 0&&r => 0, 1&&r => r */
365 /* 0||r => r, 1||r => 1 */
366 ufoldcnst(I
,l
->u
.v
.i
? cnsttree(ty
, 1L) : cond(r
));
369 ufoldcnst(I
,cnsttree(ty
, (long)extend((~l
->u
.v
.i
)&ones(8*ty
->size
), ty
)));
373 ufoldcnst(U
,cnsttree(ty
, (unsigned long)((~l
->u
.v
.u
)&ones(8*ty
->size
))));
397 xfoldcnst(F
,d
,/,divd
);
401 if (r
->op
== CNST
+I
&& r
->u
.v
.i
== 0
402 || l
->op
== CNST
+I
&& l
->u
.v
.i
== ty
->u
.sym
->u
.limits
.min
.i
403 && r
->op
== CNST
+I
&& r
->u
.v
.i
== -1)
405 xfoldcnst(I
,i
,/,divi
);
409 if (r
->op
== CNST
+U
&& r
->u
.v
.u
== 0)
411 if (r
->op
== CNST
+U
&& (n
= ispow2(r
->u
.v
.u
)) != 0)
412 return simplify(RSH
, ty
, l
, cnsttree(inttype
, (long)n
));
424 case GE
+F
: cfoldcnst(F
,d
,>=); break;
425 case GE
+I
: cfoldcnst(I
,i
,>=); break;
427 geu(l
,r
,1); /* l >= 0 => (l,1) */
429 if (l
->op
== CNST
+U
&& l
->u
.v
.u
== 0) /* 0 >= r => r == 0 */
430 return eqtree(EQ
, r
, l
);
432 case GT
+F
: cfoldcnst(F
,d
, >); break;
433 case GT
+I
: cfoldcnst(I
,i
, >); break;
435 geu(r
,l
,0); /* 0 > r => (r,0) */
437 if (r
->op
== CNST
+U
&& r
->u
.v
.u
== 0) /* l > 0 => l != 0 */
438 return eqtree(NE
, l
, r
);
440 case LE
+F
: cfoldcnst(F
,d
,<=); break;
441 case LE
+I
: cfoldcnst(I
,i
,<=); break;
443 geu(r
,l
,1); /* 0 <= r => (r,1) */
445 if (r
->op
== CNST
+U
&& r
->u
.v
.u
== 0) /* l <= 0 => l == 0 */
446 return eqtree(EQ
, l
, r
);
450 if (l
->op
== CNST
+I
&& r
->op
== CNST
+I
451 && r
->u
.v
.i
>= 0 && r
->u
.v
.i
< 8*l
->type
->size
452 && muli(l
->u
.v
.i
, 1<<r
->u
.v
.i
, ty
->u
.sym
->u
.limits
.min
.i
, ty
->u
.sym
->u
.limits
.max
.i
, needconst
))
453 return cnsttree(ty
, (long)(l
->u
.v
.i
<<r
->u
.v
.i
));
454 if (r
->op
== CNST
+I
&& (r
->u
.v
.i
>= 8*ty
->size
|| r
->u
.v
.i
< 0)) {
455 warning("shifting an `%t' by %d bits is undefined\n", ty
, r
->u
.v
.i
);
463 if (r
->op
== CNST
+I
&& (r
->u
.v
.i
>= 8*ty
->size
|| r
->u
.v
.i
< 0)) {
464 warning("shifting an `%t' by %d bits is undefined\n", ty
, r
->u
.v
.i
);
470 case LT
+F
: cfoldcnst(F
,d
, <); break;
471 case LT
+I
: cfoldcnst(I
,i
, <); break;
473 geu(l
,r
,0); /* l < 0 => (l,0) */
475 if (l
->op
== CNST
+U
&& l
->u
.v
.u
== 0) /* 0 < r => r != 0 */
476 return eqtree(NE
, r
, l
);
479 if (r
->op
== CNST
+I
&& r
->u
.v
.i
== 0
480 || l
->op
== CNST
+I
&& l
->u
.v
.i
== ty
->u
.sym
->u
.limits
.min
.i
481 && r
->op
== CNST
+I
&& r
->u
.v
.i
== -1)
483 xfoldcnst(I
,i
,%,divi
);
484 if (r
->op
== CNST
+I
&& r
->u
.v
.i
== 1) /* l%1 => (l,0) */
485 return tree(RIGHT
, ty
, root(l
), cnsttree(ty
, 0L));
488 if (r
->op
== CNST
+U
&& ispow2(r
->u
.v
.u
)) /* l%2^n => l&(2^n-1) */
489 return bittree(BAND
, l
, cnsttree(ty
, r
->u
.v
.u
- 1));
490 if (r
->op
== CNST
+U
&& r
->u
.v
.u
== 0)
495 xfoldcnst(F
,d
,*,muld
);
500 xfoldcnst(I
,i
,*,muli
);
501 if (l
->op
== CNST
+I
&& r
->op
== ADD
+I
&& r
->kids
[1]->op
== CNST
+I
)
502 /* c1*(x + c2) => c1*x + c1*c2 */
503 return simplify(ADD
, ty
, simplify(MUL
, ty
, l
, r
->kids
[0]),
504 simplify(MUL
, ty
, l
, r
->kids
[1]));
505 if (l
->op
== CNST
+I
&& r
->op
== SUB
+I
&& r
->kids
[1]->op
== CNST
+I
)
506 /* c1*(x - c2) => c1*x - c1*c2 */
507 return simplify(SUB
, ty
, simplify(MUL
, ty
, l
, r
->kids
[0]),
508 simplify(MUL
, ty
, l
, r
->kids
[1]));
509 if (l
->op
== CNST
+I
&& l
->u
.v
.i
> 0 && (n
= ispow2(l
->u
.v
.i
)) != 0)
510 /* 2^n * r => r<<n */
511 return simplify(LSH
, ty
, r
, cnsttree(inttype
, (long)n
));
524 ufoldcnst(F
,cnsttree(ty
, -l
->u
.v
.d
));
528 if (l
->op
== CNST
+I
) {
529 if (needconst
&& l
->u
.v
.i
== ty
->u
.sym
->u
.limits
.min
.i
)
530 warning("overflow in constant expression\n");
531 if (needconst
|| l
->u
.v
.i
!= ty
->u
.sym
->u
.limits
.min
.i
)
532 return cnsttree(ty
, -l
->u
.v
.i
);
538 ufoldcnst(I
,cnsttree(ty
, !l
->u
.v
.i
));
542 if (l
->op
== CNST
+I
&& r
->op
== CNST
+I
543 && r
->u
.v
.i
>= 0 && r
->u
.v
.i
< 8*l
->type
->size
) {
544 long n
= l
->u
.v
.i
>>r
->u
.v
.i
;
546 n
|= ~0UL<<(8*l
->type
->size
- r
->u
.v
.i
);
547 return cnsttree(ty
, n
);
549 if (r
->op
== CNST
+I
&& (r
->u
.v
.i
>= 8*ty
->size
|| r
->u
.v
.i
< 0)) {
550 warning("shifting an `%t' by %d bits is undefined\n", ty
, r
->u
.v
.i
);
558 if (r
->op
== CNST
+I
&& (r
->u
.v
.i
>= 8*ty
->size
|| r
->u
.v
.i
< 0)) {
559 warning("shifting an `%t' by %d bits is undefined\n", ty
, r
->u
.v
.i
);
565 xfoldcnst(F
,d
,-,subd
);
568 xfoldcnst(I
,i
,-,subi
);
576 if (l
->op
== CNST
+P
&& r
->op
== CNST
+P
)
577 return cnsttree(ty
, (long)((char *)l
->u
.v
.p
- (char *)r
->u
.v
.p
));
578 if (r
->op
== CNST
+I
|| r
->op
== CNST
+U
)
579 return simplify(ADD
, ty
, l
,
580 cnsttree(inttype
, r
->op
== CNST
+I
? -r
->u
.v
.i
: -(long)r
->u
.v
.u
));
581 if (isaddrop(l
->op
) && r
->op
== ADD
+I
&& r
->kids
[1]->op
== CNST
+I
)
582 /* l - (x + c) => l-c - x */
583 return simplify(SUB
, ty
,
584 simplify(SUB
, ty
, l
, r
->kids
[1]), r
->kids
[0]);
588 return tree(op
, ty
, l
, r
);
590 /* ispow2 - if u > 1 && u == 2^n, return n, otherwise return 0 */
591 int ispow2(unsigned long u
) {
594 if (u
> 1 && (u
&(u
-1)) == 0)
595 for (n
= 0; u
; u
>>= 1, n
++)