xref: /inferno-os/utils/c2l/scon.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1 #include "cc.h"
2 
3 void
evconst(Node * n)4 evconst(Node *n)
5 {
6 	Node *l, *r;
7 	int et, isf;
8 	vlong v;
9 	double d;
10 
11 	if(n == Z || n->type == T)
12 		return;
13 
14 	et = n->type->etype;
15 	isf = typefd[et];
16 
17 	l = n->left;
18 	r = n->right;
19 
20 	d = 0;
21 	v = 0;
22 
23 	switch(n->op) {
24 	default:
25 		return;
26 
27 	case OCAST:
28 		if(et == TVOID)
29 			return;
30 		et = l->type->etype;
31 		if(isf) {
32 			if(typefd[et])
33 				d = l->fconst;
34 			else
35 				d = l->vconst;
36 		} else {
37 			if(typefd[et])
38 				v = l->fconst;
39 			else
40 				v = convvtox(l->vconst, n->type->etype);
41 		}
42 		break;
43 
44 	case OCONST:
45 		break;
46 
47 	case OADD:
48 		if(isf)
49 			d = l->fconst + r->fconst;
50 		else {
51 			v = l->vconst + r->vconst;
52 		}
53 		break;
54 
55 	case OSUB:
56 		if(isf)
57 			d = l->fconst - r->fconst;
58 		else
59 			v = l->vconst - r->vconst;
60 		break;
61 
62 	case OMUL:
63 		if(isf)
64 			d = l->fconst * r->fconst;
65 		else {
66 			v = l->vconst * r->vconst;
67 		}
68 		break;
69 
70 	case OLMUL:
71 		v = (uvlong)l->vconst * (uvlong)r->vconst;
72 		break;
73 
74 
75 	case ODIV:
76 		if(vconst(r) == 0) {
77 			warn(n, "divide by zero");
78 			return;
79 		}
80 		if(isf)
81 			d = l->fconst / r->fconst;
82 		else
83 			v = l->vconst / r->vconst;
84 		break;
85 
86 	case OLDIV:
87 		if(vconst(r) == 0) {
88 			warn(n, "divide by zero");
89 			return;
90 		}
91 		v = (uvlong)l->vconst / (uvlong)r->vconst;
92 		break;
93 
94 	case OMOD:
95 		if(vconst(r) == 0) {
96 			warn(n, "modulo by zero");
97 			return;
98 		}
99 		v = l->vconst % r->vconst;
100 		break;
101 
102 	case OLMOD:
103 		if(vconst(r) == 0) {
104 			warn(n, "modulo by zero");
105 			return;
106 		}
107 		v = (uvlong)l->vconst % (uvlong)r->vconst;
108 		break;
109 
110 	case OAND:
111 		v = l->vconst & r->vconst;
112 		break;
113 
114 	case OOR:
115 		v = l->vconst | r->vconst;
116 		break;
117 
118 	case OXOR:
119 		v = l->vconst ^ r->vconst;
120 		break;
121 
122 	case OLSHR:
123 		v = (uvlong)l->vconst >> r->vconst;
124 		break;
125 
126 	case OASHR:
127 		v = l->vconst >> r->vconst;
128 		break;
129 
130 	case OASHL:
131 		v = l->vconst << r->vconst;
132 		break;
133 
134 	case OLO:
135 		v = (uvlong)l->vconst < (uvlong)r->vconst;
136 		break;
137 
138 	case OLT:
139 		if(typefd[l->type->etype])
140 			v = l->fconst < r->fconst;
141 		else
142 			v = l->vconst < r->vconst;
143 		break;
144 
145 	case OHI:
146 		v = (uvlong)l->vconst > (uvlong)r->vconst;
147 		break;
148 
149 	case OGT:
150 		if(typefd[l->type->etype])
151 			v = l->fconst > r->fconst;
152 		else
153 			v = l->vconst > r->vconst;
154 		break;
155 
156 	case OLS:
157 		v = (uvlong)l->vconst <= (uvlong)r->vconst;
158 		break;
159 
160 	case OLE:
161 		if(typefd[l->type->etype])
162 			v = l->fconst <= r->fconst;
163 		else
164 			v = l->vconst <= r->vconst;
165 		break;
166 
167 	case OHS:
168 		v = (uvlong)l->vconst >= (uvlong)r->vconst;
169 		break;
170 
171 	case OGE:
172 		if(typefd[l->type->etype])
173 			v = l->fconst >= r->fconst;
174 		else
175 			v = l->vconst >= r->vconst;
176 		break;
177 
178 	case OEQ:
179 		if(typefd[l->type->etype])
180 			v = l->fconst == r->fconst;
181 		else
182 			v = l->vconst == r->vconst;
183 		break;
184 
185 	case ONE:
186 		if(typefd[l->type->etype])
187 			v = l->fconst != r->fconst;
188 		else
189 			v = l->vconst != r->vconst;
190 		break;
191 
192 	case ONOT:
193 		if(typefd[l->type->etype])
194 			v = !l->fconst;
195 		else
196 			v = !l->vconst;
197 		break;
198 
199 	case OANDAND:
200 		if(typefd[l->type->etype])
201 			v = l->fconst && r->fconst;
202 		else
203 			v = l->vconst && r->vconst;
204 		break;
205 
206 	case OOROR:
207 		if(typefd[l->type->etype])
208 			v = l->fconst || r->fconst;
209 		else
210 			v = l->vconst || r->vconst;
211 		break;
212 
213 	case OPOS:
214 		if(isf)
215 			d = l->fconst;
216 		else
217 			v = l->vconst;
218 		break;
219 
220 	case ONEG:
221 		if(isf)
222 			d = -l->fconst;
223 		else
224 			v = -l->vconst;
225 		break;
226 
227 	case OCOM:
228 		if(typefd[l->type->etype])
229 			v = 0;	/* ~l->fconst */
230 		else
231 			v = ~l->vconst;
232 		break;
233 	}
234 
235 	n->left = ncopy(n);
236 	n->op = OCONST;
237 	/* n->left = Z; */
238 	n->right = Z;
239 	if(isf) {
240 		n->fconst = d;
241 	} else {
242 		n->vconst = convvtox(v, n->type->etype);
243 	}
244 }
245 
246 void
acom(Node * n)247 acom(Node *n)
248 {
249 	USED(n);
250 }
251