qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

simpl.c (1463B)


      1 #include "all.h"
      2 
      3 static void
      4 blit(Ref sd[2], int sz, Fn *fn)
      5 {
      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 }
     11 	};
     12 	Ref r, r1, ro;
     13 	int off, fwd, n;
     14 
     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;
     30 		}
     31 }
     32 
     33 static void
     34 ins(Ins **pi, int *new, Blk *b, Fn *fn)
     35 {
     36 	ulong ni;
     37 	Ins *i;
     38 
     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;
     53 		}
     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;
     61 	}
     62 }
     63 
     64 void
     65 simpl(Fn *fn)
     66 {
     67 	Blk *b;
     68 	Ins *i;
     69 	int new;
     70 
     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);
     76 		}
     77 		if (new) {
     78 			b->nins = &insb[NIns] - curi;
     79 			idup(&b->ins, curi, b->nins);
     80 		}
     81 	}
     82 }