Optab-driven copy detection
[qbe.git] / simpl.c
blob7001301b8c81024783b5eda88b46d0c2e8e6541a
1 #include "all.h"
3 static void
4 blit(Ref sd[2], int sz, Fn *fn)
6 struct { int st, ld, cls, size; } *p, tbl[] = {
7 { Ostorel, Oload, Kl, 8 },
8 { Ostorew, Oload, Kw, 4 },
9 { Ostoreh, Oloaduh, Kw, 2 },
10 { Ostoreb, Oloadub, Kw, 1 }
12 Ref r, r1, ro;
13 int off, fwd, n;
15 fwd = sz >= 0;
16 sz = abs(sz);
17 off = fwd ? sz : 0;
18 for (p=tbl; sz; p++)
19 for (n=p->size; sz>=n; sz-=n) {
20 off -= fwd ? n : 0;
21 r = newtmp("blt", Kl, fn);
22 r1 = newtmp("blt", Kl, fn);
23 ro = getcon(off, fn);
24 emit(p->st, 0, R, r, r1);
25 emit(Oadd, Kl, r1, sd[1], ro);
26 r1 = newtmp("blt", Kl, fn);
27 emit(p->ld, p->cls, r, r1, R);
28 emit(Oadd, Kl, r1, sd[0], ro);
29 off += fwd ? 0 : n;
33 static void
34 ins(Ins **pi, int *new, Blk *b, Fn *fn)
36 ulong ni;
37 Ins *i;
39 i = *pi;
40 /* simplify more instructions here;
41 * copy 0 into xor, mul 2^n into shift,
42 * bit rotations, ... */
43 switch (i->op) {
44 case Oblit1:
45 assert(i > b->ins);
46 assert((i-1)->op == Oblit0);
47 if (!*new) {
48 curi = &insb[NIns];
49 ni = &b->ins[b->nins] - (i+1);
50 curi -= ni;
51 icpy(curi, i+1, ni);
52 *new = 1;
54 blit((i-1)->arg, rsval(i->arg[0]), fn);
55 *pi = i-1;
56 break;
57 default:
58 if (*new)
59 emiti(*i);
60 break;
64 void
65 simpl(Fn *fn)
67 Blk *b;
68 Ins *i;
69 int new;
71 for (b=fn->start; b; b=b->link) {
72 new = 0;
73 for (i=&b->ins[b->nins]; i!=b->ins;) {
74 --i;
75 ins(&i, &new, b, fn);
77 if (new) {
78 b->nins = &insb[NIns] - curi;
79 idup(&b->ins, curi, b->nins);