13e12c5d1SDavid du Colombier #include "l.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier enum
43e12c5d1SDavid du Colombier {
5bd389b36SDavid du Colombier E_ICC = 1<<0,
6bd389b36SDavid du Colombier E_FCC = 1<<1,
7bd389b36SDavid du Colombier E_MEM = 1<<2,
8bd389b36SDavid du Colombier E_MEMSP = 1<<3, /* uses offset and size */
9bd389b36SDavid du Colombier E_MEMSB = 1<<4, /* uses offset and size */
10bd389b36SDavid du Colombier ANYMEM = E_MEM|E_MEMSP|E_MEMSB,
11*375daca8SDavid du Colombier ALL = ~0
123e12c5d1SDavid du Colombier };
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier typedef struct Sch Sch;
15bd389b36SDavid du Colombier typedef struct Dep Dep;
16bd389b36SDavid du Colombier
17bd389b36SDavid du Colombier struct Dep
18bd389b36SDavid du Colombier {
19bd389b36SDavid du Colombier ulong ireg;
20bd389b36SDavid du Colombier ulong freg;
21bd389b36SDavid du Colombier ulong cc;
22bd389b36SDavid du Colombier };
233e12c5d1SDavid du Colombier struct Sch
243e12c5d1SDavid du Colombier {
253e12c5d1SDavid du Colombier Prog p;
26bd389b36SDavid du Colombier Dep set;
27bd389b36SDavid du Colombier Dep used;
287dd7cddfSDavid du Colombier long soffset;
29bd389b36SDavid du Colombier char size;
303e12c5d1SDavid du Colombier char nop;
313e12c5d1SDavid du Colombier char comp;
323e12c5d1SDavid du Colombier };
333e12c5d1SDavid du Colombier
347dd7cddfSDavid du Colombier void regsused(Sch*, Prog*);
35bd389b36SDavid du Colombier int depend(Sch*, Sch*);
36bd389b36SDavid du Colombier int conflict(Sch*, Sch*);
37bd389b36SDavid du Colombier int offoverlap(Sch*, Sch*);
38bd389b36SDavid du Colombier void dumpbits(Sch*, Dep*);
393e12c5d1SDavid du Colombier
403e12c5d1SDavid du Colombier void
sched(Prog * p0,Prog * pe)413e12c5d1SDavid du Colombier sched(Prog *p0, Prog *pe)
423e12c5d1SDavid du Colombier {
433e12c5d1SDavid du Colombier Prog *p, *q;
443e12c5d1SDavid du Colombier Sch sch[NSCHED], *s, *t, *u, *se, stmp;
453e12c5d1SDavid du Colombier
463e12c5d1SDavid du Colombier /*
473e12c5d1SDavid du Colombier * build side structure
483e12c5d1SDavid du Colombier */
493e12c5d1SDavid du Colombier s = sch;
503e12c5d1SDavid du Colombier for(p=p0;; p=p->link) {
51bd389b36SDavid du Colombier memset(s, 0, sizeof(*s));
523e12c5d1SDavid du Colombier s->p = *p;
537dd7cddfSDavid du Colombier regsused(s, p);
54bd389b36SDavid du Colombier if(debug['X']) {
55bd389b36SDavid du Colombier Bprint(&bso, "%P\tset", &s->p);
56bd389b36SDavid du Colombier dumpbits(s, &s->set);
57bd389b36SDavid du Colombier Bprint(&bso, "; used");
58bd389b36SDavid du Colombier dumpbits(s, &s->used);
59219b2ee8SDavid du Colombier if(s->comp)
60219b2ee8SDavid du Colombier Bprint(&bso, "; compound");
61219b2ee8SDavid du Colombier if(s->p.mark & LOAD)
62219b2ee8SDavid du Colombier Bprint(&bso, "; load");
63219b2ee8SDavid du Colombier if(s->p.mark & BRANCH)
64219b2ee8SDavid du Colombier Bprint(&bso, "; branch");
65219b2ee8SDavid du Colombier if(s->p.mark & FCMP)
66219b2ee8SDavid du Colombier Bprint(&bso, "; fcmp");
67bd389b36SDavid du Colombier Bprint(&bso, "\n");
68bd389b36SDavid du Colombier }
693e12c5d1SDavid du Colombier s++;
703e12c5d1SDavid du Colombier if(p == pe)
713e12c5d1SDavid du Colombier break;
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier se = s;
743e12c5d1SDavid du Colombier
753e12c5d1SDavid du Colombier for(s=se-1; s>=sch; s--) {
763e12c5d1SDavid du Colombier /*
773e12c5d1SDavid du Colombier * branch delay slot
783e12c5d1SDavid du Colombier */
793e12c5d1SDavid du Colombier if(s->p.mark & BRANCH) {
803e12c5d1SDavid du Colombier /* t is the trial instruction to use */
813e12c5d1SDavid du Colombier for(t=s-1; t>=sch; t--) {
823e12c5d1SDavid du Colombier if(t->comp || (t->p.mark & FCMP))
833e12c5d1SDavid du Colombier goto no1;
843e12c5d1SDavid du Colombier for(u=t+1; u<=s; u++)
85bd389b36SDavid du Colombier if(depend(u, t))
863e12c5d1SDavid du Colombier goto no1;
873e12c5d1SDavid du Colombier goto out1;
883e12c5d1SDavid du Colombier no1:;
893e12c5d1SDavid du Colombier }
903e12c5d1SDavid du Colombier if(debug['X'])
913e12c5d1SDavid du Colombier Bprint(&bso, "?b%P\n", &s->p);
923e12c5d1SDavid du Colombier s->nop = 1;
933e12c5d1SDavid du Colombier continue;
943e12c5d1SDavid du Colombier
953e12c5d1SDavid du Colombier out1:
963e12c5d1SDavid du Colombier if(debug['X']) {
973e12c5d1SDavid du Colombier Bprint(&bso, "!b%P\n", &t->p);
983e12c5d1SDavid du Colombier Bprint(&bso, "%P\n", &s->p);
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier stmp = *t;
1013e12c5d1SDavid du Colombier memmove(t, t+1, (uchar*)s - (uchar*)t);
1023e12c5d1SDavid du Colombier *s = stmp;
1033e12c5d1SDavid du Colombier s--;
1043e12c5d1SDavid du Colombier continue;
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier
1073e12c5d1SDavid du Colombier /*
1083e12c5d1SDavid du Colombier * load delay. interlocked.
1093e12c5d1SDavid du Colombier */
1103e12c5d1SDavid du Colombier if(s->p.mark & LOAD) {
1113e12c5d1SDavid du Colombier if(s >= se-1)
1123e12c5d1SDavid du Colombier continue;
113bd389b36SDavid du Colombier if(!conflict(s, (s+1)))
1143e12c5d1SDavid du Colombier continue;
115bd389b36SDavid du Colombier /*
116bd389b36SDavid du Colombier * s is load, s+1 is immediate use of result
117bd389b36SDavid du Colombier * t is the trial instruction to insert between s and s+1
118bd389b36SDavid du Colombier */
1193e12c5d1SDavid du Colombier for(t=s-1; t>=sch; t--) {
1203e12c5d1SDavid du Colombier if(t->p.mark & BRANCH)
1213e12c5d1SDavid du Colombier goto no2;
1223e12c5d1SDavid du Colombier if(t->p.mark & FCMP)
1233e12c5d1SDavid du Colombier if((s+1)->p.mark & BRANCH)
1243e12c5d1SDavid du Colombier goto no2;
1253e12c5d1SDavid du Colombier if(t->p.mark & LOAD)
126bd389b36SDavid du Colombier if(conflict(t, (s+1)))
1273e12c5d1SDavid du Colombier goto no2;
1283e12c5d1SDavid du Colombier for(u=t+1; u<=s; u++)
129bd389b36SDavid du Colombier if(depend(u, t))
1303e12c5d1SDavid du Colombier goto no2;
1313e12c5d1SDavid du Colombier goto out2;
1323e12c5d1SDavid du Colombier no2:;
1333e12c5d1SDavid du Colombier }
1343e12c5d1SDavid du Colombier if(debug['X'])
1353e12c5d1SDavid du Colombier Bprint(&bso, "?l%P\n", &s->p);
1363e12c5d1SDavid du Colombier continue;
1373e12c5d1SDavid du Colombier out2:
1383e12c5d1SDavid du Colombier if(debug['X']) {
1393e12c5d1SDavid du Colombier Bprint(&bso, "!l%P\n", &t->p);
1403e12c5d1SDavid du Colombier Bprint(&bso, "%P\n", &s->p);
1413e12c5d1SDavid du Colombier }
1423e12c5d1SDavid du Colombier stmp = *t;
1433e12c5d1SDavid du Colombier memmove(t, t+1, (uchar*)s - (uchar*)t);
1443e12c5d1SDavid du Colombier *s = stmp;
1453e12c5d1SDavid du Colombier s--;
1463e12c5d1SDavid du Colombier continue;
1473e12c5d1SDavid du Colombier }
1483e12c5d1SDavid du Colombier
1493e12c5d1SDavid du Colombier /*
1503e12c5d1SDavid du Colombier * fop2 delay.
1513e12c5d1SDavid du Colombier */
1523e12c5d1SDavid du Colombier if(s->p.mark & FCMP) {
1533e12c5d1SDavid du Colombier if(s >= se-1) {
1543e12c5d1SDavid du Colombier s->nop = 1;
1553e12c5d1SDavid du Colombier continue;
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier if(!((s+1)->p.mark & BRANCH))
1583e12c5d1SDavid du Colombier continue;
1593e12c5d1SDavid du Colombier /* t is the trial instruction to use */
1603e12c5d1SDavid du Colombier for(t=s-1; t>=sch; t--) {
1613e12c5d1SDavid du Colombier for(u=t+1; u<=s; u++)
162bd389b36SDavid du Colombier if(depend(u, t))
1633e12c5d1SDavid du Colombier goto no3;
1643e12c5d1SDavid du Colombier goto out3;
1653e12c5d1SDavid du Colombier no3:;
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier if(debug['X'])
1683e12c5d1SDavid du Colombier Bprint(&bso, "?f%P\n", &s->p);
1693e12c5d1SDavid du Colombier s->nop = 1;
1703e12c5d1SDavid du Colombier continue;
1713e12c5d1SDavid du Colombier out3:
1723e12c5d1SDavid du Colombier if(debug['X']) {
1733e12c5d1SDavid du Colombier Bprint(&bso, "!f%P\n", &t->p);
1743e12c5d1SDavid du Colombier Bprint(&bso, "%P\n", &s->p);
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier stmp = *t;
1773e12c5d1SDavid du Colombier memmove(t, t+1, (uchar*)s - (uchar*)t);
1783e12c5d1SDavid du Colombier *s = stmp;
1793e12c5d1SDavid du Colombier s--;
1803e12c5d1SDavid du Colombier continue;
1813e12c5d1SDavid du Colombier }
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier
1843e12c5d1SDavid du Colombier /*
1853e12c5d1SDavid du Colombier * put it all back
1863e12c5d1SDavid du Colombier */
1873e12c5d1SDavid du Colombier for(s=sch, p=p0; s<se; s++, p=q) {
1883e12c5d1SDavid du Colombier q = p->link;
1893e12c5d1SDavid du Colombier if(q != s->p.link) {
1903e12c5d1SDavid du Colombier *p = s->p;
1913e12c5d1SDavid du Colombier p->link = q;
1923e12c5d1SDavid du Colombier }
1933e12c5d1SDavid du Colombier if(s->nop)
1943e12c5d1SDavid du Colombier addnop(p);
1953e12c5d1SDavid du Colombier }
1963e12c5d1SDavid du Colombier if(debug['X'])
1973e12c5d1SDavid du Colombier Bprint(&bso, "\n");
1983e12c5d1SDavid du Colombier }
1993e12c5d1SDavid du Colombier
200bd389b36SDavid du Colombier void
regsused(Sch * s,Prog * realp)2017dd7cddfSDavid du Colombier regsused(Sch *s, Prog *realp)
2023e12c5d1SDavid du Colombier {
203bd389b36SDavid du Colombier int c, ar, ad, ld, sz;
204bd389b36SDavid du Colombier ulong m;
205bd389b36SDavid du Colombier Prog *p;
2063e12c5d1SDavid du Colombier
207bd389b36SDavid du Colombier p = &s->p;
208bd389b36SDavid du Colombier s->comp = compound(p);
209bd389b36SDavid du Colombier s->nop = 0;
210219b2ee8SDavid du Colombier if(s->comp) {
211219b2ee8SDavid du Colombier s->set.ireg |= 1<<REGTMP;
212219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGTMP;
213219b2ee8SDavid du Colombier }
2143e12c5d1SDavid du Colombier ar = 0; /* dest is really reference */
215bd389b36SDavid du Colombier ad = 0; /* source/dest is really address */
2163e12c5d1SDavid du Colombier ld = 0; /* opcode is load instruction */
217bd389b36SDavid du Colombier sz = 20; /* size of load/store for overlap computation */
2183e12c5d1SDavid du Colombier
219bd389b36SDavid du Colombier /*
220bd389b36SDavid du Colombier * flags based on opcode
221bd389b36SDavid du Colombier */
2223e12c5d1SDavid du Colombier switch(p->as) {
2233e12c5d1SDavid du Colombier case ATEXT:
224219b2ee8SDavid du Colombier curtext = realp;
2253e12c5d1SDavid du Colombier autosize = p->to.offset + 4;
226bd389b36SDavid du Colombier ad = 1;
2273e12c5d1SDavid du Colombier break;
2283e12c5d1SDavid du Colombier case AJMPL:
2293e12c5d1SDavid du Colombier c = p->reg;
2303e12c5d1SDavid du Colombier if(c == NREG)
2313e12c5d1SDavid du Colombier c = REGLINK;
232bd389b36SDavid du Colombier s->set.ireg |= 1<<c;
2333e12c5d1SDavid du Colombier ar = 1;
234bd389b36SDavid du Colombier ad = 1;
2353e12c5d1SDavid du Colombier break;
2363e12c5d1SDavid du Colombier case AJMP:
2373e12c5d1SDavid du Colombier ar = 1;
2383e12c5d1SDavid du Colombier ad = 1;
2393e12c5d1SDavid du Colombier break;
2403e12c5d1SDavid du Colombier case ACMP:
241bd389b36SDavid du Colombier s->set.cc |= E_ICC;
2423e12c5d1SDavid du Colombier ar = 1;
2433e12c5d1SDavid du Colombier break;
2443e12c5d1SDavid du Colombier case AFCMPD:
2453e12c5d1SDavid du Colombier case AFCMPED:
2463e12c5d1SDavid du Colombier case AFCMPEF:
2473e12c5d1SDavid du Colombier case AFCMPEX:
2483e12c5d1SDavid du Colombier case AFCMPF:
2493e12c5d1SDavid du Colombier case AFCMPX:
250bd389b36SDavid du Colombier s->set.cc |= E_FCC;
2513e12c5d1SDavid du Colombier ar = 1;
2523e12c5d1SDavid du Colombier break;
2533e12c5d1SDavid du Colombier case ABE:
2543e12c5d1SDavid du Colombier case ABNE:
2553e12c5d1SDavid du Colombier case ABLE:
2563e12c5d1SDavid du Colombier case ABG:
2573e12c5d1SDavid du Colombier case ABL:
2583e12c5d1SDavid du Colombier case ABGE:
2593e12c5d1SDavid du Colombier case ABLEU:
2603e12c5d1SDavid du Colombier case ABGU:
2613e12c5d1SDavid du Colombier case ABCS:
2623e12c5d1SDavid du Colombier case ABCC:
2633e12c5d1SDavid du Colombier case ABNEG:
2643e12c5d1SDavid du Colombier case ABPOS:
2653e12c5d1SDavid du Colombier case ABVC:
2663e12c5d1SDavid du Colombier case ABVS:
267bd389b36SDavid du Colombier s->used.cc |= E_ICC;
2683e12c5d1SDavid du Colombier ar = 1;
2693e12c5d1SDavid du Colombier break;
2703e12c5d1SDavid du Colombier case AFBE:
2713e12c5d1SDavid du Colombier case AFBLG:
2723e12c5d1SDavid du Colombier case AFBG:
2733e12c5d1SDavid du Colombier case AFBLE:
2743e12c5d1SDavid du Colombier case AFBGE:
2753e12c5d1SDavid du Colombier case AFBL:
276bd389b36SDavid du Colombier s->used.cc |= E_FCC;
2773e12c5d1SDavid du Colombier ar = 1;
2783e12c5d1SDavid du Colombier break;
2793e12c5d1SDavid du Colombier case AMOVB:
2803e12c5d1SDavid du Colombier case AMOVBU:
281bd389b36SDavid du Colombier sz = 1;
282bd389b36SDavid du Colombier ld = 1;
283bd389b36SDavid du Colombier break;
2843e12c5d1SDavid du Colombier case AMOVH:
2853e12c5d1SDavid du Colombier case AMOVHU:
286bd389b36SDavid du Colombier sz = 2;
2873e12c5d1SDavid du Colombier ld = 1;
2883e12c5d1SDavid du Colombier break;
289bd389b36SDavid du Colombier case AFMOVF:
290bd389b36SDavid du Colombier case AMOVW:
291bd389b36SDavid du Colombier sz = 4;
292bd389b36SDavid du Colombier ld = 1;
293bd389b36SDavid du Colombier break;
294bd389b36SDavid du Colombier case AMOVD:
295bd389b36SDavid du Colombier case AFMOVD:
296bd389b36SDavid du Colombier sz = 8;
297bd389b36SDavid du Colombier ld = 1;
298bd389b36SDavid du Colombier break;
299bd389b36SDavid du Colombier case AFMOVX: /* gok */
300bd389b36SDavid du Colombier sz = 16;
301bd389b36SDavid du Colombier ld = 1;
302bd389b36SDavid du Colombier break;
303bd389b36SDavid du Colombier case AADDCC:
304bd389b36SDavid du Colombier case AADDXCC:
305bd389b36SDavid du Colombier case AANDCC:
306bd389b36SDavid du Colombier case AANDNCC:
307bd389b36SDavid du Colombier case AORCC:
308bd389b36SDavid du Colombier case AORNCC:
309bd389b36SDavid du Colombier case ASUBCC:
310bd389b36SDavid du Colombier case ASUBXCC:
311bd389b36SDavid du Colombier case ATADDCC:
312bd389b36SDavid du Colombier case ATADDCCTV:
313bd389b36SDavid du Colombier case ATSUBCC:
314bd389b36SDavid du Colombier case ATSUBCCTV:
315bd389b36SDavid du Colombier case AXNORCC:
316bd389b36SDavid du Colombier case AXORCC:
317bd389b36SDavid du Colombier s->set.cc |= E_ICC;
318bd389b36SDavid du Colombier break;
3193e12c5d1SDavid du Colombier case ADIV:
3203e12c5d1SDavid du Colombier case ADIVL:
3213e12c5d1SDavid du Colombier case AMOD:
3223e12c5d1SDavid du Colombier case AMODL:
3233e12c5d1SDavid du Colombier case AMUL:
3243e12c5d1SDavid du Colombier case AMULSCC:
325bd389b36SDavid du Colombier case ATAS:
326bd389b36SDavid du Colombier s->set.ireg = ALL;
327bd389b36SDavid du Colombier s->set.freg = ALL;
328bd389b36SDavid du Colombier s->set.cc = ALL;
3293e12c5d1SDavid du Colombier break;
3303e12c5d1SDavid du Colombier }
3313e12c5d1SDavid du Colombier
332bd389b36SDavid du Colombier /*
333bd389b36SDavid du Colombier * flags based on 'to' field
334bd389b36SDavid du Colombier */
3353e12c5d1SDavid du Colombier c = p->to.class;
3363e12c5d1SDavid du Colombier if(c == 0) {
3373e12c5d1SDavid du Colombier c = aclass(&p->to) + 1;
3383e12c5d1SDavid du Colombier p->to.class = c;
3393e12c5d1SDavid du Colombier }
3403e12c5d1SDavid du Colombier c--;
3413e12c5d1SDavid du Colombier switch(c) {
3423e12c5d1SDavid du Colombier default:
3433e12c5d1SDavid du Colombier print("unknown class %d %D\n", c, &p->to);
3443e12c5d1SDavid du Colombier
3453e12c5d1SDavid du Colombier case C_ZCON:
3463e12c5d1SDavid du Colombier case C_SCON:
3473e12c5d1SDavid du Colombier case C_UCON:
3483e12c5d1SDavid du Colombier case C_LCON:
3493e12c5d1SDavid du Colombier case C_NONE:
3503e12c5d1SDavid du Colombier case C_SBRA:
3513e12c5d1SDavid du Colombier case C_LBRA:
3523e12c5d1SDavid du Colombier break;
3533e12c5d1SDavid du Colombier case C_CREG:
3543e12c5d1SDavid du Colombier case C_FSR:
3553e12c5d1SDavid du Colombier case C_FQ:
3563e12c5d1SDavid du Colombier case C_PREG:
357bd389b36SDavid du Colombier s->set.ireg = ALL;
358bd389b36SDavid du Colombier s->set.freg = ALL;
359bd389b36SDavid du Colombier s->set.cc = ALL;
3603e12c5d1SDavid du Colombier break;
3613e12c5d1SDavid du Colombier case C_ZOREG:
3623e12c5d1SDavid du Colombier case C_SOREG:
3633e12c5d1SDavid du Colombier case C_LOREG:
3643e12c5d1SDavid du Colombier case C_ASI:
365bd389b36SDavid du Colombier c = p->to.reg;
366bd389b36SDavid du Colombier s->used.ireg |= 1<<c;
367bd389b36SDavid du Colombier if(ad)
368bd389b36SDavid du Colombier break;
369bd389b36SDavid du Colombier s->size = sz;
3707dd7cddfSDavid du Colombier s->soffset = regoff(&p->to);
371bd389b36SDavid du Colombier
372bd389b36SDavid du Colombier m = ANYMEM;
373bd389b36SDavid du Colombier if(c == REGSB)
374bd389b36SDavid du Colombier m = E_MEMSB;
375bd389b36SDavid du Colombier if(c == REGSP)
376bd389b36SDavid du Colombier m = E_MEMSP;
377bd389b36SDavid du Colombier
378bd389b36SDavid du Colombier if(ar)
379bd389b36SDavid du Colombier s->used.cc |= m;
380bd389b36SDavid du Colombier else
381bd389b36SDavid du Colombier s->set.cc |= m;
3823e12c5d1SDavid du Colombier break;
3833e12c5d1SDavid du Colombier case C_SACON:
3843e12c5d1SDavid du Colombier case C_LACON:
385219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSP;
3863e12c5d1SDavid du Colombier break;
3873e12c5d1SDavid du Colombier case C_SECON:
3883e12c5d1SDavid du Colombier case C_LECON:
389219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSB;
3903e12c5d1SDavid du Colombier break;
3913e12c5d1SDavid du Colombier case C_REG:
3923e12c5d1SDavid du Colombier if(ar)
393bd389b36SDavid du Colombier s->used.ireg |= 1<<p->to.reg;
3943e12c5d1SDavid du Colombier else
395bd389b36SDavid du Colombier s->set.ireg |= 1<<p->to.reg;
3963e12c5d1SDavid du Colombier break;
3973e12c5d1SDavid du Colombier case C_FREG:
398bd389b36SDavid du Colombier /* do better -- determine double prec */
399bd389b36SDavid du Colombier if(ar) {
400bd389b36SDavid du Colombier s->used.freg |= 1<<p->to.reg;
401bd389b36SDavid du Colombier s->used.freg |= 1<<(p->to.reg|1);
402bd389b36SDavid du Colombier } else {
403bd389b36SDavid du Colombier s->set.freg |= 1<<p->to.reg;
404bd389b36SDavid du Colombier s->set.freg |= 1<<(p->to.reg|1);
405bd389b36SDavid du Colombier }
4063e12c5d1SDavid du Colombier break;
4073e12c5d1SDavid du Colombier case C_SAUTO:
4083e12c5d1SDavid du Colombier case C_LAUTO:
4093e12c5d1SDavid du Colombier case C_ESAUTO:
4103e12c5d1SDavid du Colombier case C_OSAUTO:
4113e12c5d1SDavid du Colombier case C_ELAUTO:
4123e12c5d1SDavid du Colombier case C_OLAUTO:
413bd389b36SDavid du Colombier s->used.ireg |= 1<<REGSP;
414bd389b36SDavid du Colombier if(ad)
415bd389b36SDavid du Colombier break;
416bd389b36SDavid du Colombier s->size = sz;
4177dd7cddfSDavid du Colombier s->soffset = regoff(&p->to);
418bd389b36SDavid du Colombier
419bd389b36SDavid du Colombier if(ar)
420bd389b36SDavid du Colombier s->used.cc |= E_MEMSP;
421bd389b36SDavid du Colombier else
422bd389b36SDavid du Colombier s->set.cc |= E_MEMSP;
4233e12c5d1SDavid du Colombier break;
4243e12c5d1SDavid du Colombier case C_SEXT:
4253e12c5d1SDavid du Colombier case C_LEXT:
4263e12c5d1SDavid du Colombier case C_ESEXT:
4273e12c5d1SDavid du Colombier case C_OSEXT:
4283e12c5d1SDavid du Colombier case C_ELEXT:
4293e12c5d1SDavid du Colombier case C_OLEXT:
430bd389b36SDavid du Colombier s->used.ireg |= 1<<REGSB;
431bd389b36SDavid du Colombier if(ad)
432bd389b36SDavid du Colombier break;
433bd389b36SDavid du Colombier s->size = sz;
4347dd7cddfSDavid du Colombier s->soffset = regoff(&p->to);
435bd389b36SDavid du Colombier
436bd389b36SDavid du Colombier if(ar)
437bd389b36SDavid du Colombier s->used.cc |= E_MEMSB;
438bd389b36SDavid du Colombier else
439bd389b36SDavid du Colombier s->set.cc |= E_MEMSB;
4403e12c5d1SDavid du Colombier break;
4413e12c5d1SDavid du Colombier }
4423e12c5d1SDavid du Colombier
443bd389b36SDavid du Colombier /*
444bd389b36SDavid du Colombier * flags based on 'from' field
445bd389b36SDavid du Colombier */
4463e12c5d1SDavid du Colombier c = p->from.class;
4473e12c5d1SDavid du Colombier if(c == 0) {
4483e12c5d1SDavid du Colombier c = aclass(&p->from) + 1;
4493e12c5d1SDavid du Colombier p->from.class = c;
4503e12c5d1SDavid du Colombier }
4513e12c5d1SDavid du Colombier c--;
4523e12c5d1SDavid du Colombier switch(c) {
4533e12c5d1SDavid du Colombier default:
4543e12c5d1SDavid du Colombier print("unknown class %d %D\n", c, &p->from);
4553e12c5d1SDavid du Colombier
4563e12c5d1SDavid du Colombier case C_ZCON:
4573e12c5d1SDavid du Colombier case C_SCON:
4583e12c5d1SDavid du Colombier case C_UCON:
4593e12c5d1SDavid du Colombier case C_LCON:
4603e12c5d1SDavid du Colombier case C_NONE:
4613e12c5d1SDavid du Colombier case C_SBRA:
4623e12c5d1SDavid du Colombier case C_LBRA:
463219b2ee8SDavid du Colombier c = p->from.reg;
464219b2ee8SDavid du Colombier if(c != NREG)
465219b2ee8SDavid du Colombier s->used.ireg |= 1<<c;
4663e12c5d1SDavid du Colombier break;
4673e12c5d1SDavid du Colombier case C_CREG:
4683e12c5d1SDavid du Colombier case C_FSR:
4693e12c5d1SDavid du Colombier case C_FQ:
4703e12c5d1SDavid du Colombier case C_PREG:
471bd389b36SDavid du Colombier s->set.ireg = ALL;
472bd389b36SDavid du Colombier s->set.freg = ALL;
473bd389b36SDavid du Colombier s->set.cc = ALL;
4743e12c5d1SDavid du Colombier break;
4753e12c5d1SDavid du Colombier case C_ZOREG:
4763e12c5d1SDavid du Colombier case C_SOREG:
4773e12c5d1SDavid du Colombier case C_LOREG:
4783e12c5d1SDavid du Colombier case C_ASI:
479bd389b36SDavid du Colombier c = p->from.reg;
480bd389b36SDavid du Colombier s->used.ireg |= 1<<c;
4813e12c5d1SDavid du Colombier if(ld)
4823e12c5d1SDavid du Colombier p->mark |= LOAD;
483bd389b36SDavid du Colombier if(ad)
484bd389b36SDavid du Colombier break;
485bd389b36SDavid du Colombier s->size = sz;
4867dd7cddfSDavid du Colombier s->soffset = regoff(&p->from);
487bd389b36SDavid du Colombier
488bd389b36SDavid du Colombier m = ANYMEM;
489bd389b36SDavid du Colombier if(c == REGSB)
490bd389b36SDavid du Colombier m = E_MEMSB;
491bd389b36SDavid du Colombier if(c == REGSP)
492bd389b36SDavid du Colombier m = E_MEMSP;
493bd389b36SDavid du Colombier
494bd389b36SDavid du Colombier s->used.cc |= m;
4953e12c5d1SDavid du Colombier break;
4963e12c5d1SDavid du Colombier case C_SACON:
4973e12c5d1SDavid du Colombier case C_LACON:
498bd389b36SDavid du Colombier s->used.ireg |= 1<<REGSP;
4993e12c5d1SDavid du Colombier break;
5003e12c5d1SDavid du Colombier case C_SECON:
5013e12c5d1SDavid du Colombier case C_LECON:
502bd389b36SDavid du Colombier s->used.ireg |= 1<<REGSB;
5033e12c5d1SDavid du Colombier break;
5043e12c5d1SDavid du Colombier case C_REG:
505bd389b36SDavid du Colombier s->used.ireg |= 1<<p->from.reg;
5063e12c5d1SDavid du Colombier break;
5073e12c5d1SDavid du Colombier case C_FREG:
508bd389b36SDavid du Colombier /* do better -- determine double prec */
509bd389b36SDavid du Colombier s->used.freg |= 1<<p->from.reg;
510bd389b36SDavid du Colombier s->used.freg |= 1<<(p->from.reg|1);
5113e12c5d1SDavid du Colombier break;
5123e12c5d1SDavid du Colombier case C_SAUTO:
5133e12c5d1SDavid du Colombier case C_LAUTO:
5143e12c5d1SDavid du Colombier case C_ESAUTO:
5153e12c5d1SDavid du Colombier case C_ELAUTO:
5163e12c5d1SDavid du Colombier case C_OSAUTO:
5173e12c5d1SDavid du Colombier case C_OLAUTO:
518bd389b36SDavid du Colombier s->used.ireg |= 1<<REGSP;
5193e12c5d1SDavid du Colombier if(ld)
5203e12c5d1SDavid du Colombier p->mark |= LOAD;
521bd389b36SDavid du Colombier if(ad)
522bd389b36SDavid du Colombier break;
523bd389b36SDavid du Colombier s->size = sz;
5247dd7cddfSDavid du Colombier s->soffset = regoff(&p->from);
525bd389b36SDavid du Colombier
526bd389b36SDavid du Colombier s->used.cc |= E_MEMSP;
5273e12c5d1SDavid du Colombier break;
5283e12c5d1SDavid du Colombier case C_SEXT:
5293e12c5d1SDavid du Colombier case C_LEXT:
5303e12c5d1SDavid du Colombier case C_ESEXT:
5313e12c5d1SDavid du Colombier case C_ELEXT:
5323e12c5d1SDavid du Colombier case C_OSEXT:
5333e12c5d1SDavid du Colombier case C_OLEXT:
534bd389b36SDavid du Colombier s->used.ireg |= 1<<REGSB;
5353e12c5d1SDavid du Colombier if(ld)
5363e12c5d1SDavid du Colombier p->mark |= LOAD;
537bd389b36SDavid du Colombier if(ad)
538bd389b36SDavid du Colombier break;
539bd389b36SDavid du Colombier s->size = sz;
5407dd7cddfSDavid du Colombier s->soffset = regoff(&p->from);
541bd389b36SDavid du Colombier
542bd389b36SDavid du Colombier s->used.cc |= E_MEMSB;
5433e12c5d1SDavid du Colombier break;
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier
5463e12c5d1SDavid du Colombier c = p->reg;
5473e12c5d1SDavid du Colombier if(c != NREG) {
548bd389b36SDavid du Colombier if(p->from.type == D_FREG || p->to.type == D_FREG) {
549bd389b36SDavid du Colombier s->used.freg |= 1<<c;
550bd389b36SDavid du Colombier s->used.freg |= 1<<(c|1);
551bd389b36SDavid du Colombier } else
552bd389b36SDavid du Colombier s->used.ireg |= 1<<c;
553bd389b36SDavid du Colombier }
554bd389b36SDavid du Colombier s->set.ireg &= ~(1<<0); /* R0 cant be set */
5553e12c5d1SDavid du Colombier }
5563e12c5d1SDavid du Colombier
557bd389b36SDavid du Colombier /*
558bd389b36SDavid du Colombier * test to see if 2 instrictions can be
559bd389b36SDavid du Colombier * interchanged without changing semantics
560bd389b36SDavid du Colombier */
5613e12c5d1SDavid du Colombier int
depend(Sch * sa,Sch * sb)562bd389b36SDavid du Colombier depend(Sch *sa, Sch *sb)
5633e12c5d1SDavid du Colombier {
564bd389b36SDavid du Colombier ulong x;
5653e12c5d1SDavid du Colombier
566bd389b36SDavid du Colombier if(sa->set.ireg & (sb->set.ireg|sb->used.ireg))
567bd389b36SDavid du Colombier return 1;
568bd389b36SDavid du Colombier if(sb->set.ireg & sa->used.ireg)
569bd389b36SDavid du Colombier return 1;
5703e12c5d1SDavid du Colombier
571bd389b36SDavid du Colombier if(sa->set.freg & (sb->set.freg|sb->used.freg))
5723e12c5d1SDavid du Colombier return 1;
573bd389b36SDavid du Colombier if(sb->set.freg & sa->used.freg)
5743e12c5d1SDavid du Colombier return 1;
575bd389b36SDavid du Colombier
576bd389b36SDavid du Colombier x = (sa->set.cc & (sb->set.cc|sb->used.cc)) |
577bd389b36SDavid du Colombier (sb->set.cc & sa->used.cc);
578bd389b36SDavid du Colombier if(x) {
579bd389b36SDavid du Colombier /*
580bd389b36SDavid du Colombier * allow SB and SP to pass each other.
581bd389b36SDavid du Colombier * allow SB to pass SB iff doffsets are ok
582bd389b36SDavid du Colombier * anything else conflicts
583bd389b36SDavid du Colombier */
584bd389b36SDavid du Colombier if(x != E_MEMSP && x != E_MEMSB)
585bd389b36SDavid du Colombier return 1;
586bd389b36SDavid du Colombier x = sa->set.cc | sb->set.cc |
587bd389b36SDavid du Colombier sa->used.cc | sb->used.cc;
588bd389b36SDavid du Colombier if(x & E_MEM)
589bd389b36SDavid du Colombier return 1;
590bd389b36SDavid du Colombier if(offoverlap(sa, sb))
5913e12c5d1SDavid du Colombier return 1;
5923e12c5d1SDavid du Colombier }
5933e12c5d1SDavid du Colombier
5943e12c5d1SDavid du Colombier return 0;
5953e12c5d1SDavid du Colombier }
5963e12c5d1SDavid du Colombier
5973e12c5d1SDavid du Colombier int
offoverlap(Sch * sa,Sch * sb)598bd389b36SDavid du Colombier offoverlap(Sch *sa, Sch *sb)
5993e12c5d1SDavid du Colombier {
6003e12c5d1SDavid du Colombier
6017dd7cddfSDavid du Colombier if(sa->soffset < sb->soffset) {
6027dd7cddfSDavid du Colombier if(sa->soffset+sa->size > sb->soffset)
6033e12c5d1SDavid du Colombier return 1;
604bd389b36SDavid du Colombier return 0;
6053e12c5d1SDavid du Colombier }
6067dd7cddfSDavid du Colombier if(sb->soffset+sb->size > sa->soffset)
607bd389b36SDavid du Colombier return 1;
608bd389b36SDavid du Colombier return 0;
609bd389b36SDavid du Colombier }
610bd389b36SDavid du Colombier
611bd389b36SDavid du Colombier /*
612bd389b36SDavid du Colombier * test 2 adjacent instructions
613bd389b36SDavid du Colombier * and find out if inserted instructions
614bd389b36SDavid du Colombier * are desired to prevent stalls.
615bd389b36SDavid du Colombier * first instruction is a load instruction.
616bd389b36SDavid du Colombier */
617bd389b36SDavid du Colombier int
conflict(Sch * sa,Sch * sb)618bd389b36SDavid du Colombier conflict(Sch *sa, Sch *sb)
619bd389b36SDavid du Colombier {
620bd389b36SDavid du Colombier
621bd389b36SDavid du Colombier if(sa->set.ireg & sb->used.ireg)
622bd389b36SDavid du Colombier return 1;
623bd389b36SDavid du Colombier if(sa->set.freg & sb->used.freg)
624bd389b36SDavid du Colombier return 1;
6253e12c5d1SDavid du Colombier return 0;
6263e12c5d1SDavid du Colombier }
6273e12c5d1SDavid du Colombier
6283e12c5d1SDavid du Colombier int
compound(Prog * p)6293e12c5d1SDavid du Colombier compound(Prog *p)
6303e12c5d1SDavid du Colombier {
6313e12c5d1SDavid du Colombier Optab *o;
6323e12c5d1SDavid du Colombier
6333e12c5d1SDavid du Colombier o = oplook(p);
6343e12c5d1SDavid du Colombier if(o->size != 4)
6353e12c5d1SDavid du Colombier return 1;
6363e12c5d1SDavid du Colombier if(p->to.type == D_REG && p->to.reg == REGSB)
6373e12c5d1SDavid du Colombier return 1;
6383e12c5d1SDavid du Colombier return 0;
6393e12c5d1SDavid du Colombier }
640bd389b36SDavid du Colombier
641bd389b36SDavid du Colombier void
dumpbits(Sch * s,Dep * d)642bd389b36SDavid du Colombier dumpbits(Sch *s, Dep *d)
643bd389b36SDavid du Colombier {
644bd389b36SDavid du Colombier int i;
645bd389b36SDavid du Colombier
646bd389b36SDavid du Colombier for(i=0; i<32; i++)
647bd389b36SDavid du Colombier if(d->ireg & (1<<i))
648bd389b36SDavid du Colombier Bprint(&bso, " R%d", i);
649bd389b36SDavid du Colombier for(i=0; i<32; i++)
650bd389b36SDavid du Colombier if(d->freg & (1<<i))
651bd389b36SDavid du Colombier Bprint(&bso, " F%d", i);
652bd389b36SDavid du Colombier for(i=0; i<32; i++)
653bd389b36SDavid du Colombier switch(d->cc & (1<<i)) {
654bd389b36SDavid du Colombier default:
655bd389b36SDavid du Colombier break;
656bd389b36SDavid du Colombier case E_ICC:
657bd389b36SDavid du Colombier Bprint(&bso, " ICC");
658bd389b36SDavid du Colombier break;
659bd389b36SDavid du Colombier case E_FCC:
660bd389b36SDavid du Colombier Bprint(&bso, " FCC");
661bd389b36SDavid du Colombier break;
662bd389b36SDavid du Colombier case E_MEM:
663bd389b36SDavid du Colombier Bprint(&bso, " MEM%d", s->size);
664bd389b36SDavid du Colombier break;
665bd389b36SDavid du Colombier case E_MEMSB:
666bd389b36SDavid du Colombier Bprint(&bso, " SB%d", s->size);
667bd389b36SDavid du Colombier break;
668bd389b36SDavid du Colombier case E_MEMSP:
669bd389b36SDavid du Colombier Bprint(&bso, " SP%d", s->size);
670bd389b36SDavid du Colombier break;
671bd389b36SDavid du Colombier }
672bd389b36SDavid du Colombier }
673