9 int satvar = 3; /* 1 = false, 2 = true */
10 #define SVAR(n, i) ((n)->vars[(i) < (n)->size ? (i) : (n)->size - 1])
33 assert(s->type == SYMBITS);
34 n->size = s->size + ((s->flags & SYMFSIGNED) == 0);
35 n->vars = emalloc(sizeof(int) * n->size);
36 for(i = 0; i < s->size; i++){
38 s->vars[i] = satvar++;
39 n->vars[i] = s->vars[i];
41 if((s->flags & SYMFSIGNED) == 0)
56 n->vars = emalloc(sizeof(int) * sz);
57 for(i = 0; i < m->top; i++){
58 for(j = 0; j < Dbits; j++)
59 if(i * Dbits + j < sz-1)
60 n->vars[i * Dbits + j] = 1 + ((m->p[i] >> j & 1) != 0);
66 nodevars(Node *n, int nv)
71 n->vars = emalloc(sizeof(int) * nv);
72 for(i = 0; i < nv; i++)
77 assign(Node *t, Node *n)
83 for(i = 0; i < s->size; i++){
85 s->vars[i] = n->vars[i];
87 s->vars[i] = n->vars[n->size - 1];
92 opeq(Node *r, Node *n1, Node *n2, int neq)
97 m = max(n1->size, n2->size);
98 t = malloc(m * sizeof(int));
99 for(i = 0; i < m; i++){
102 t[i] = satlogicv(sat, neq ? 6 : 9, a, b, 0);
105 r->vars[0] = sator1(sat, t, m);
107 r->vars[0] = satand1(sat, t, m);
112 oplogic(Node *r, Node *n1, Node *n2, int op)
116 m = max(n1->size, n2->size);
119 for(i = 0; i < m; i++){
124 t[i] = satorv(sat, a, b, 0);
127 t[i] = satandv(sat, a, b, 0);
130 t[i] = satlogicv(sat, 6, a, b, 0);
142 for(i = 1; i < n->size; i++)
147 return sator1(sat, n->vars, n->size);
151 opllogic(Node *rn, Node *n1, Node *n2, int op)
160 rn->vars[0] = satandv(sat, a, b, 0);
163 rn->vars[0] = satorv(sat, a, b, 0);
166 rn->vars[0] = satorv(sat, -a, b, 0);
169 rn->vars[0] = satlogicv(sat, 9, a, b, 0);
177 opcom(Node *r, Node *n1)
181 nodevars(r, n1->size);
182 for(i = 0; i < n1->size; i++)
183 r->vars[i] = -n1->vars[i];
187 opneg(Node *r, Node *n1)
191 nodevars(r, n1->size);
193 for(i = 0; i < n1->size; i++){
194 r->vars[i] = satlogicv(sat, 9, n1->vars[i], c, 0);
196 c = satandv(sat, -n1->vars[i], c, 0);
201 opnot(Node *r, Node *n1)
204 r->vars[0] = -tologic(n1);
208 opadd(Node *rn, Node *n1, Node *n2, int sub)
212 m = max(n1->size, n2->size) + 1;
216 for(i = 0; i < m; i++){
218 b = SVAR(n2, i) * sub;
219 rn->vars[i] = satlogicv(sat, 0x96, c, a, b, 0);
220 c = satlogicv(sat, 0xe8, c, a, b, 0);
225 oplt(Node *rn, Node *n1, Node *n2, int le)
227 int i, m, a, b, t, *r;
230 m = max(n1->size, n2->size);
231 r = emalloc(sizeof(int) * (m + le));
233 for(i = m; --i >= 0; ){
241 r[i] = satandv(sat, -a, b, t, 0);
242 t = satlogicv(sat, 0x90, a, b, t, 0);
246 rn->vars[0] = sator1(sat, r, m + le);
250 opidx(Node *rn, Node *n1, Node *n2, Node *n3)
256 else j = mptoi(n3->num);
263 for(i = 0; i < s; i++)
264 rn->vars[i] = SVAR(n1, j + i);
268 oprsh(Node *rn, Node *n1, Node *n2)
272 nodevars(rn, n1->size);
273 memcpy(rn->vars, n1->vars, sizeof(int) * n1->size);
274 for(i = 0; i < n2->size; i++){
275 if(n2->vars[i] == 1) continue;
276 if(n2->vars[i] == 2){
277 for(j = 0; j < n1->size; j++)
278 rn->vars[j] = SVAR(rn, j + (1<<i));
281 for(j = 0; j < n1->size; j++){
283 b = SVAR(rn, j + (1<<i));
285 rn->vars[j] = satlogicv(sat, 0xca, a, b, q, 0);
291 oplsh(Node *rn, Node *n1, Node *n2, uint sz)
297 for(i = n2->size; --i >= 0; )
298 m = m << 1 | n2->vars[i] != m;
302 for(i = 0; i < m; i++)
303 rn->vars[i] = SVAR(n1, i);
304 for(i = 0; i < n2->size; i++){
305 if(n2->vars[i] == 1) continue;
306 if(n2->vars[i] == 2){
307 for(j = m; --j >= 0; )
308 rn->vars[j] = j >= 1<<i ? rn->vars[j - (1<<i)] : 1;
311 for(j = m; --j >= 0; ){
313 b = j >= 1<<i ? rn->vars[j - (1<<i)] : 1;
315 rn->vars[j] = satlogicv(sat, 0xca, a, b, q, 0);
321 optern(Node *rn, Node *n1, Node *n2, Node *n3, uint sz)
327 if(n3->size > m) m = n3->size;
331 for(i = 0; i < m; i++){
334 rn->vars[i] = satlogicv(sat, 0xca, a, b, q, 0);
339 opmul(int *n1v, int s1, int *n2v, int s2)
342 int *r, *q0, *q1, *z, nq0, nq1, nq;
346 r = emalloc(sizeof(int) * (s1 + s2 + 2));
347 nq = 2 * (min(s1, s2) + 2);
348 q0 = emalloc(nq * sizeof(int));
349 q1 = emalloc(nq * sizeof(int));
351 for(k = 0; k <= s1 + s2 + 1; k++){
352 if(k == s1 || k == s1 + s2 + 1){ assert(nq0 < nq); q0[nq0++] = 2; }
353 if(k == s2){ assert(nq0 < nq); q0[nq0++] = 2; }
354 for(i = max(0, k - s2); i <= k && i <= s1; i++){
356 t = satandv(sat, n1v[i], n2v[k - i], 0);
357 q0[nq0++] = i == s1 ^ k-i == s2 ? -t : t;
362 t = satlogicv(sat, 0x6, q0[0], q0[1], 0);
363 s = satandv(sat, q0[0], q0[1], 0);
369 t = satlogicv(sat, 0x96, q0[nq0-3], q0[nq0-2], q0[nq0-1], 0);
370 s = satlogicv(sat, 0xe8, q0[nq0-3], q0[nq0-2], q0[nq0-1], 0);
387 opabs(Node *q, Node *n)
392 nodevars(q, n->size + 1);
393 s = n->vars[n->size - 1];
395 for(i = 0; i < n->size; i++){
396 q->vars[i] = satlogicv(sat, 0x96, n->vars[i], s, c, 0);
397 c = satandv(sat, -n->vars[i], c, 0);
402 opdiv(Node *q, Node *r, Node *n1, Node *n2)
407 if(q == nil) q = node(ASTTEMP);
408 if(r == nil) r = node(ASTTEMP);
409 nodevars(q, n1->size);
410 nodevars(r, n2->size);
411 for(i = 0; i < n1->size; i++)
412 q->vars[i] = satvar++;
413 for(i = 0; i < n2->size; i++)
414 r->vars[i] = satvar++;
415 s = node(ASTBIN, OPEQ, node(ASTBIN, OPADD, node(ASTBIN, OPMUL, q, n2), r), n1); convert(s, -1); assume(s);
416 s = node(ASTBIN, OPLT, node(ASTUN, OPABS, r), node(ASTUN, OPABS, n2)); convert(s, -1); assume(s);
417 s1 = n1->vars[n1->size - 1];
418 sr = r->vars[r->size - 1];
419 zr = -sator1(sat, r->vars, r->size);
420 sataddv(sat, zr, sr, -s1, 0);
421 sataddv(sat, zr, -sr, s1, 0);
425 convert(Node *n, uint sz)
427 if(n->size > 0) return;
440 if(n->n1 == nil || n->n1->type != ASTSYM)
441 error(n, "convert: '%ε' invalid lval", n->n1);
442 convert(n->n2, n->n1->sym->size);
443 assert(n->n2->size > 0);
444 assign(n->n1, n->n2);
448 case OPAND: case OPOR: case OPXOR:
449 case OPADD: case OPSUB: case OPLSH:
458 assert(n->n1->size > 0);
459 assert(n->n2->size > 0);
461 case OPCOMMA: n->size = n->n2->size; n->vars = n->n2->vars; break;
462 case OPEQ: opeq(n, n->n1, n->n2, 0); break;
463 case OPNEQ: opeq(n, n->n1, n->n2, 1); break;
464 case OPLT: oplt(n, n->n1, n->n2, 0); break;
465 case OPLE: oplt(n, n->n1, n->n2, 1); break;
466 case OPGT: oplt(n, n->n2, n->n1, 0); break;
467 case OPGE: oplt(n, n->n2, n->n1, 1); break;
468 case OPXOR: case OPAND: case OPOR: oplogic(n, n->n1, n->n2, n->op); break;
469 case OPLAND: case OPLOR: case OPIMP: case OPEQV: opllogic(n, n->n1, n->n2, n->op); break;
470 case OPADD: opadd(n, n->n1, n->n2, 0); break;
471 case OPSUB: opadd(n, n->n1, n->n2, 1); break;
472 case OPLSH: oplsh(n, n->n1, n->n2, sz); break;
473 case OPRSH: oprsh(n, n->n1, n->n2); break;
474 case OPMUL: n->vars = opmul(n->n1->vars, n->n1->size, n->n2->vars, n->n2->size); n->size = n->n1->size + n->n2->size; break;
475 case OPDIV: opdiv(n, nil, n->n1, n->n2); break;
476 case OPMOD: opdiv(nil, n, n->n1, n->n2); break;
478 error(n, "convert: unimplemented op %O", n->op);
484 case OPCOM: opcom(n, n->n1); break;
485 case OPNEG: opneg(n, n->n1); break;
486 case OPNOT: opnot(n, n->n1); break;
487 case OPABS: opabs(n, n->n1); break;
489 error(n, "convert: unimplemented op %O", n->op);
493 if(n->n2->type != ASTNUM || n->n3 != nil && n->n3->type != ASTNUM)
494 error(n, "non-constant in indexing expression");
495 convert(n->n1, n->n3 != nil ? mptoi(n->n3->num) - mptoi(n->n2->num) + 1 : 1);
496 opidx(n, n->n1, n->n2, n->n3);
502 optern(n, n->n1, n->n2, n->n3, sz);
505 error(n, "convert: unimplemented %α", n->type);
513 satadd1(sat, n->vars, n->size);
519 assertvar = realloc(assertvar, sizeof(int) * (nassertvar + 1));
520 assert(assertvar != nil);
521 assertvar[nassertvar++] = -tologic(n);
527 sat = sataddv(nil, -1, 0);