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, 11bd389b36SDavid 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; 28bd389b36SDavid du Colombier long offset; 29bd389b36SDavid du Colombier char size; 303e12c5d1SDavid du Colombier char nop; 313e12c5d1SDavid du Colombier char comp; 323e12c5d1SDavid du Colombier }; 333e12c5d1SDavid du Colombier 34*219b2ee8SDavid du Colombier void regused(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 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; 53*219b2ee8SDavid du Colombier regused(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); 59*219b2ee8SDavid du Colombier if(s->comp) 60*219b2ee8SDavid du Colombier Bprint(&bso, "; compound"); 61*219b2ee8SDavid du Colombier if(s->p.mark & LOAD) 62*219b2ee8SDavid du Colombier Bprint(&bso, "; load"); 63*219b2ee8SDavid du Colombier if(s->p.mark & BRANCH) 64*219b2ee8SDavid du Colombier Bprint(&bso, "; branch"); 65*219b2ee8SDavid du Colombier if(s->p.mark & FCMP) 66*219b2ee8SDavid 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 201*219b2ee8SDavid du Colombier regused(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; 210*219b2ee8SDavid du Colombier if(s->comp) { 211*219b2ee8SDavid du Colombier s->set.ireg |= 1<<REGTMP; 212*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGTMP; 213*219b2ee8SDavid 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: 224*219b2ee8SDavid 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; 370bd389b36SDavid du Colombier s->offset = 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: 385*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSP; 3863e12c5d1SDavid du Colombier break; 3873e12c5d1SDavid du Colombier case C_SECON: 3883e12c5d1SDavid du Colombier case C_LECON: 389*219b2ee8SDavid 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; 417bd389b36SDavid du Colombier s->offset = 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; 434bd389b36SDavid du Colombier s->offset = 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: 463*219b2ee8SDavid du Colombier c = p->from.reg; 464*219b2ee8SDavid du Colombier if(c != NREG) 465*219b2ee8SDavid 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; 486bd389b36SDavid du Colombier s->offset = 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; 524bd389b36SDavid du Colombier s->offset = 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; 540bd389b36SDavid du Colombier s->offset = 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 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 598bd389b36SDavid du Colombier offoverlap(Sch *sa, Sch *sb) 5993e12c5d1SDavid du Colombier { 6003e12c5d1SDavid du Colombier 601bd389b36SDavid du Colombier if(sa->offset < sb->offset) { 602bd389b36SDavid du Colombier if(sa->offset+sa->size > sb->offset) 6033e12c5d1SDavid du Colombier return 1; 604bd389b36SDavid du Colombier return 0; 6053e12c5d1SDavid du Colombier } 606bd389b36SDavid du Colombier if(sb->offset+sb->size > sa->offset) 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 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 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 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