1*219b2ee8SDavid du Colombier #include "l.h" 2*219b2ee8SDavid du Colombier 3*219b2ee8SDavid du Colombier enum 4*219b2ee8SDavid du Colombier { 5*219b2ee8SDavid du Colombier E_HILO = 1<<0, 6*219b2ee8SDavid du Colombier E_FCR = 1<<1, 7*219b2ee8SDavid du Colombier E_MCR = 1<<2, 8*219b2ee8SDavid du Colombier E_MEM = 1<<3, 9*219b2ee8SDavid du Colombier E_MEMSP = 1<<4, /* uses offset and size */ 10*219b2ee8SDavid du Colombier E_MEMSB = 1<<5, /* uses offset and size */ 11*219b2ee8SDavid du Colombier ANYMEM = E_MEM|E_MEMSP|E_MEMSB, 12*219b2ee8SDavid du Colombier DELAY = BRANCH|LOAD|FCMP, 13*219b2ee8SDavid du Colombier }; 14*219b2ee8SDavid du Colombier 15*219b2ee8SDavid du Colombier typedef struct Sch Sch; 16*219b2ee8SDavid du Colombier typedef struct Dep Dep; 17*219b2ee8SDavid du Colombier 18*219b2ee8SDavid du Colombier struct Dep 19*219b2ee8SDavid du Colombier { 20*219b2ee8SDavid du Colombier ulong ireg; 21*219b2ee8SDavid du Colombier ulong freg; 22*219b2ee8SDavid du Colombier ulong cc; 23*219b2ee8SDavid du Colombier }; 24*219b2ee8SDavid du Colombier struct Sch 25*219b2ee8SDavid du Colombier { 26*219b2ee8SDavid du Colombier Prog p; 27*219b2ee8SDavid du Colombier Dep set; 28*219b2ee8SDavid du Colombier Dep used; 29*219b2ee8SDavid du Colombier long offset; 30*219b2ee8SDavid du Colombier char size; 31*219b2ee8SDavid du Colombier char nop; 32*219b2ee8SDavid du Colombier char comp; 33*219b2ee8SDavid du Colombier }; 34*219b2ee8SDavid du Colombier 35*219b2ee8SDavid du Colombier void regused(Sch*, Prog*); 36*219b2ee8SDavid du Colombier int depend(Sch*, Sch*); 37*219b2ee8SDavid du Colombier int conflict(Sch*, Sch*); 38*219b2ee8SDavid du Colombier int offoverlap(Sch*, Sch*); 39*219b2ee8SDavid du Colombier void dumpbits(Sch*, Dep*); 40*219b2ee8SDavid du Colombier 41*219b2ee8SDavid du Colombier void 42*219b2ee8SDavid du Colombier sched(Prog *p0, Prog *pe) 43*219b2ee8SDavid du Colombier { 44*219b2ee8SDavid du Colombier Prog *p, *q; 45*219b2ee8SDavid du Colombier Sch sch[NSCHED], *s, *t, *u, *se, stmp; 46*219b2ee8SDavid du Colombier 47*219b2ee8SDavid du Colombier /* 48*219b2ee8SDavid du Colombier * build side structure 49*219b2ee8SDavid du Colombier */ 50*219b2ee8SDavid du Colombier s = sch; 51*219b2ee8SDavid du Colombier for(p=p0;; p=p->link) { 52*219b2ee8SDavid du Colombier memset(s, 0, sizeof(*s)); 53*219b2ee8SDavid du Colombier s->p = *p; 54*219b2ee8SDavid du Colombier regused(s, p); 55*219b2ee8SDavid du Colombier if(debug['X']) { 56*219b2ee8SDavid du Colombier Bprint(&bso, "%P%|set", &s->p, 40); 57*219b2ee8SDavid du Colombier dumpbits(s, &s->set); 58*219b2ee8SDavid du Colombier Bprint(&bso, "; used"); 59*219b2ee8SDavid du Colombier dumpbits(s, &s->used); 60*219b2ee8SDavid du Colombier if(s->comp) 61*219b2ee8SDavid du Colombier Bprint(&bso, "; compound"); 62*219b2ee8SDavid du Colombier if(s->p.mark & LOAD) 63*219b2ee8SDavid du Colombier Bprint(&bso, "; load"); 64*219b2ee8SDavid du Colombier if(s->p.mark & BRANCH) 65*219b2ee8SDavid du Colombier Bprint(&bso, "; branch"); 66*219b2ee8SDavid du Colombier if(s->p.mark & FCMP) 67*219b2ee8SDavid du Colombier Bprint(&bso, "; fcmp"); 68*219b2ee8SDavid du Colombier Bprint(&bso, "\n"); 69*219b2ee8SDavid du Colombier } 70*219b2ee8SDavid du Colombier if(p == pe) 71*219b2ee8SDavid du Colombier break; 72*219b2ee8SDavid du Colombier s++; 73*219b2ee8SDavid du Colombier } 74*219b2ee8SDavid du Colombier se = s; 75*219b2ee8SDavid du Colombier 76*219b2ee8SDavid du Colombier /* 77*219b2ee8SDavid du Colombier * prepass to move things around 78*219b2ee8SDavid du Colombier * does nothing, but tries to make 79*219b2ee8SDavid du Colombier * the actual scheduler work better 80*219b2ee8SDavid du Colombier */ 81*219b2ee8SDavid du Colombier for(s=sch; s<=se; s++) { 82*219b2ee8SDavid du Colombier if(!(s->p.mark & LOAD)) 83*219b2ee8SDavid du Colombier continue; 84*219b2ee8SDavid du Colombier /* always good to put nonconflict loads together */ 85*219b2ee8SDavid du Colombier for(t=s+1; t<=se; t++) { 86*219b2ee8SDavid du Colombier if(!(t->p.mark & LOAD)) 87*219b2ee8SDavid du Colombier continue; 88*219b2ee8SDavid du Colombier if(t->p.mark & BRANCH) 89*219b2ee8SDavid du Colombier break; 90*219b2ee8SDavid du Colombier if(conflict(s, t)) 91*219b2ee8SDavid du Colombier break; 92*219b2ee8SDavid du Colombier for(u=t-1; u>s; u--) 93*219b2ee8SDavid du Colombier if(depend(u, t)) 94*219b2ee8SDavid du Colombier goto no11; 95*219b2ee8SDavid du Colombier u = s+1; 96*219b2ee8SDavid du Colombier stmp = *t; 97*219b2ee8SDavid du Colombier memmove(s+2, u, (uchar*)t - (uchar*)u); 98*219b2ee8SDavid du Colombier *u = stmp; 99*219b2ee8SDavid du Colombier break; 100*219b2ee8SDavid du Colombier } 101*219b2ee8SDavid du Colombier no11: 102*219b2ee8SDavid du Colombier 103*219b2ee8SDavid du Colombier /* put schedule fodder above load */ 104*219b2ee8SDavid du Colombier for(t=s+1; t<=se; t++) { 105*219b2ee8SDavid du Colombier if(t->p.mark & BRANCH) 106*219b2ee8SDavid du Colombier break; 107*219b2ee8SDavid du Colombier if(s > sch && conflict(s-1, t)) 108*219b2ee8SDavid du Colombier continue; 109*219b2ee8SDavid du Colombier for(u=t-1; u>=s; u--) 110*219b2ee8SDavid du Colombier if(depend(t, u)) 111*219b2ee8SDavid du Colombier goto no1; 112*219b2ee8SDavid du Colombier stmp = *t; 113*219b2ee8SDavid du Colombier memmove(s+1, s, (uchar*)t - (uchar*)s); 114*219b2ee8SDavid du Colombier *s = stmp; 115*219b2ee8SDavid du Colombier if(!(s->p.mark & LOAD)) 116*219b2ee8SDavid du Colombier break; 117*219b2ee8SDavid du Colombier no1:; 118*219b2ee8SDavid du Colombier } 119*219b2ee8SDavid du Colombier no12:; 120*219b2ee8SDavid du Colombier } 121*219b2ee8SDavid du Colombier 122*219b2ee8SDavid du Colombier for(s=se; s>=sch; s--) { 123*219b2ee8SDavid du Colombier if(!(s->p.mark & DELAY)) 124*219b2ee8SDavid du Colombier continue; 125*219b2ee8SDavid du Colombier if(s < se) 126*219b2ee8SDavid du Colombier if(!conflict(s, s+1)) 127*219b2ee8SDavid du Colombier goto out3; 128*219b2ee8SDavid du Colombier /* 129*219b2ee8SDavid du Colombier * s is load, s+1 is immediate use of result or end of block 130*219b2ee8SDavid du Colombier * t is the trial instruction to insert between s and s+1 131*219b2ee8SDavid du Colombier */ 132*219b2ee8SDavid du Colombier if(!debug['Y']) 133*219b2ee8SDavid du Colombier for(t=s-1; t>=sch; t--) { 134*219b2ee8SDavid du Colombier if(t->comp) 135*219b2ee8SDavid du Colombier if(s->p.mark & BRANCH) 136*219b2ee8SDavid du Colombier goto no2; 137*219b2ee8SDavid du Colombier if(t->p.mark & DELAY) 138*219b2ee8SDavid du Colombier if(s >= se || conflict(t, s+1)) 139*219b2ee8SDavid du Colombier goto no2; 140*219b2ee8SDavid du Colombier for(u=t+1; u<=s; u++) 141*219b2ee8SDavid du Colombier if(depend(u, t)) 142*219b2ee8SDavid du Colombier goto no2; 143*219b2ee8SDavid du Colombier goto out2; 144*219b2ee8SDavid du Colombier no2:; 145*219b2ee8SDavid du Colombier } 146*219b2ee8SDavid du Colombier if(debug['X']) 147*219b2ee8SDavid du Colombier Bprint(&bso, "?l%P\n", &s->p); 148*219b2ee8SDavid du Colombier s->nop = 1; 149*219b2ee8SDavid du Colombier if(debug['v']) { 150*219b2ee8SDavid du Colombier if(s->p.mark & LOAD) { 151*219b2ee8SDavid du Colombier nop.load.count++; 152*219b2ee8SDavid du Colombier nop.load.outof++; 153*219b2ee8SDavid du Colombier } 154*219b2ee8SDavid du Colombier if(s->p.mark & BRANCH) { 155*219b2ee8SDavid du Colombier nop.branch.count++; 156*219b2ee8SDavid du Colombier nop.branch.outof++; 157*219b2ee8SDavid du Colombier } 158*219b2ee8SDavid du Colombier if(s->p.mark & FCMP) { 159*219b2ee8SDavid du Colombier nop.fcmp.count++; 160*219b2ee8SDavid du Colombier nop.fcmp.outof++; 161*219b2ee8SDavid du Colombier } 162*219b2ee8SDavid du Colombier } 163*219b2ee8SDavid du Colombier continue; 164*219b2ee8SDavid du Colombier 165*219b2ee8SDavid du Colombier out2: 166*219b2ee8SDavid du Colombier if(debug['X']) { 167*219b2ee8SDavid du Colombier Bprint(&bso, "!l%P\n", &t->p); 168*219b2ee8SDavid du Colombier Bprint(&bso, "%P\n", &s->p); 169*219b2ee8SDavid du Colombier } 170*219b2ee8SDavid du Colombier stmp = *t; 171*219b2ee8SDavid du Colombier memmove(t, t+1, (uchar*)s - (uchar*)t); 172*219b2ee8SDavid du Colombier *s = stmp; 173*219b2ee8SDavid du Colombier s--; 174*219b2ee8SDavid du Colombier 175*219b2ee8SDavid du Colombier out3: 176*219b2ee8SDavid du Colombier if(debug['v']) { 177*219b2ee8SDavid du Colombier if(s->p.mark & LOAD) 178*219b2ee8SDavid du Colombier nop.load.outof++; 179*219b2ee8SDavid du Colombier if(s->p.mark & BRANCH) 180*219b2ee8SDavid du Colombier nop.branch.outof++; 181*219b2ee8SDavid du Colombier if(s->p.mark & FCMP) 182*219b2ee8SDavid du Colombier nop.fcmp.outof++; 183*219b2ee8SDavid du Colombier } 184*219b2ee8SDavid du Colombier } 185*219b2ee8SDavid du Colombier 186*219b2ee8SDavid du Colombier /* Avoid HI/LO use->set */ 187*219b2ee8SDavid du Colombier t = sch+1; 188*219b2ee8SDavid du Colombier for(s=sch; s<se-1; s++, t++) { 189*219b2ee8SDavid du Colombier if((s->used.cc & E_HILO) == 0) 190*219b2ee8SDavid du Colombier continue; 191*219b2ee8SDavid du Colombier if(t->set.cc & E_HILO) 192*219b2ee8SDavid du Colombier s->nop = 2; 193*219b2ee8SDavid du Colombier } 194*219b2ee8SDavid du Colombier 195*219b2ee8SDavid du Colombier /* 196*219b2ee8SDavid du Colombier * put it all back 197*219b2ee8SDavid du Colombier */ 198*219b2ee8SDavid du Colombier for(s=sch, p=p0; s<=se; s++, p=q) { 199*219b2ee8SDavid du Colombier q = p->link; 200*219b2ee8SDavid du Colombier if(q != s->p.link) { 201*219b2ee8SDavid du Colombier *p = s->p; 202*219b2ee8SDavid du Colombier p->link = q; 203*219b2ee8SDavid du Colombier } 204*219b2ee8SDavid du Colombier while(s->nop--) 205*219b2ee8SDavid du Colombier addnop(p); 206*219b2ee8SDavid du Colombier } 207*219b2ee8SDavid du Colombier if(debug['X']) { 208*219b2ee8SDavid du Colombier Bprint(&bso, "\n"); 209*219b2ee8SDavid du Colombier Bflush(&bso); 210*219b2ee8SDavid du Colombier } 211*219b2ee8SDavid du Colombier } 212*219b2ee8SDavid du Colombier 213*219b2ee8SDavid du Colombier void 214*219b2ee8SDavid du Colombier regused(Sch *s, Prog *realp) 215*219b2ee8SDavid du Colombier { 216*219b2ee8SDavid du Colombier int c, ar, ad, ld, sz; 217*219b2ee8SDavid du Colombier ulong m; 218*219b2ee8SDavid du Colombier Prog *p; 219*219b2ee8SDavid du Colombier 220*219b2ee8SDavid du Colombier p = &s->p; 221*219b2ee8SDavid du Colombier s->comp = compound(p); 222*219b2ee8SDavid du Colombier s->nop = 0; 223*219b2ee8SDavid du Colombier if(s->comp) { 224*219b2ee8SDavid du Colombier s->set.ireg |= 1<<REGTMP; 225*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGTMP; 226*219b2ee8SDavid du Colombier } 227*219b2ee8SDavid du Colombier 228*219b2ee8SDavid du Colombier ar = 0; /* dest is really reference */ 229*219b2ee8SDavid du Colombier ad = 0; /* source/dest is really address */ 230*219b2ee8SDavid du Colombier ld = 0; /* opcode is load instruction */ 231*219b2ee8SDavid du Colombier sz = 20; /* size of load/store for overlap computation */ 232*219b2ee8SDavid du Colombier 233*219b2ee8SDavid du Colombier /* 234*219b2ee8SDavid du Colombier * flags based on opcode 235*219b2ee8SDavid du Colombier */ 236*219b2ee8SDavid du Colombier switch(p->as) { 237*219b2ee8SDavid du Colombier case ATEXT: 238*219b2ee8SDavid du Colombier curtext = realp; 239*219b2ee8SDavid du Colombier autosize = p->to.offset + 4; 240*219b2ee8SDavid du Colombier ad = 1; 241*219b2ee8SDavid du Colombier break; 242*219b2ee8SDavid du Colombier case AJAL: 243*219b2ee8SDavid du Colombier c = p->reg; 244*219b2ee8SDavid du Colombier if(c == NREG) 245*219b2ee8SDavid du Colombier c = REGLINK; 246*219b2ee8SDavid du Colombier s->set.ireg |= 1<<c; 247*219b2ee8SDavid du Colombier ar = 1; 248*219b2ee8SDavid du Colombier ad = 1; 249*219b2ee8SDavid du Colombier break; 250*219b2ee8SDavid du Colombier case ABGEZAL: 251*219b2ee8SDavid du Colombier case ABLTZAL: 252*219b2ee8SDavid du Colombier s->set.ireg |= 1<<REGLINK; 253*219b2ee8SDavid du Colombier case ABEQ: 254*219b2ee8SDavid du Colombier case ABGEZ: 255*219b2ee8SDavid du Colombier case ABGTZ: 256*219b2ee8SDavid du Colombier case ABLEZ: 257*219b2ee8SDavid du Colombier case ABLTZ: 258*219b2ee8SDavid du Colombier case ABNE: 259*219b2ee8SDavid du Colombier ar = 1; 260*219b2ee8SDavid du Colombier ad = 1; 261*219b2ee8SDavid du Colombier break; 262*219b2ee8SDavid du Colombier case ABFPT: 263*219b2ee8SDavid du Colombier case ABFPF: 264*219b2ee8SDavid du Colombier ad = 1; 265*219b2ee8SDavid du Colombier s->used.cc |= E_FCR; 266*219b2ee8SDavid du Colombier break; 267*219b2ee8SDavid du Colombier case ACMPEQD: 268*219b2ee8SDavid du Colombier case ACMPEQF: 269*219b2ee8SDavid du Colombier case ACMPGED: 270*219b2ee8SDavid du Colombier case ACMPGEF: 271*219b2ee8SDavid du Colombier case ACMPGTD: 272*219b2ee8SDavid du Colombier case ACMPGTF: 273*219b2ee8SDavid du Colombier ar = 1; 274*219b2ee8SDavid du Colombier s->set.cc |= E_FCR; 275*219b2ee8SDavid du Colombier p->mark |= FCMP; 276*219b2ee8SDavid du Colombier break; 277*219b2ee8SDavid du Colombier case AJMP: 278*219b2ee8SDavid du Colombier ar = 1; 279*219b2ee8SDavid du Colombier ad = 1; 280*219b2ee8SDavid du Colombier break; 281*219b2ee8SDavid du Colombier case AMOVB: 282*219b2ee8SDavid du Colombier case AMOVBU: 283*219b2ee8SDavid du Colombier sz = 1; 284*219b2ee8SDavid du Colombier ld = 1; 285*219b2ee8SDavid du Colombier break; 286*219b2ee8SDavid du Colombier case AMOVH: 287*219b2ee8SDavid du Colombier case AMOVHU: 288*219b2ee8SDavid du Colombier sz = 2; 289*219b2ee8SDavid du Colombier ld = 1; 290*219b2ee8SDavid du Colombier break; 291*219b2ee8SDavid du Colombier case AMOVF: 292*219b2ee8SDavid du Colombier case AMOVW: 293*219b2ee8SDavid du Colombier case AMOVWL: 294*219b2ee8SDavid du Colombier case AMOVWR: 295*219b2ee8SDavid du Colombier sz = 4; 296*219b2ee8SDavid du Colombier ld = 1; 297*219b2ee8SDavid du Colombier break; 298*219b2ee8SDavid du Colombier case AMOVD: 299*219b2ee8SDavid du Colombier case AMOVV: 300*219b2ee8SDavid du Colombier case AMOVVL: 301*219b2ee8SDavid du Colombier case AMOVVR: 302*219b2ee8SDavid du Colombier sz = 8; 303*219b2ee8SDavid du Colombier ld = 1; 304*219b2ee8SDavid du Colombier break; 305*219b2ee8SDavid du Colombier case ADIV: 306*219b2ee8SDavid du Colombier case ADIVU: 307*219b2ee8SDavid du Colombier case AMUL: 308*219b2ee8SDavid du Colombier case AMULU: 309*219b2ee8SDavid du Colombier case AREM: 310*219b2ee8SDavid du Colombier case AREMU: 311*219b2ee8SDavid du Colombier s->set.cc = E_HILO; 312*219b2ee8SDavid du Colombier case AADD: 313*219b2ee8SDavid du Colombier case AADDU: 314*219b2ee8SDavid du Colombier case AAND: 315*219b2ee8SDavid du Colombier case ANOR: 316*219b2ee8SDavid du Colombier case AOR: 317*219b2ee8SDavid du Colombier case ASGT: 318*219b2ee8SDavid du Colombier case ASGTU: 319*219b2ee8SDavid du Colombier case ASLL: 320*219b2ee8SDavid du Colombier case ASRA: 321*219b2ee8SDavid du Colombier case ASRL: 322*219b2ee8SDavid du Colombier case ASUB: 323*219b2ee8SDavid du Colombier case ASUBU: 324*219b2ee8SDavid du Colombier case AXOR: 325*219b2ee8SDavid du Colombier 326*219b2ee8SDavid du Colombier case AADDD: 327*219b2ee8SDavid du Colombier case AADDF: 328*219b2ee8SDavid du Colombier case AADDW: 329*219b2ee8SDavid du Colombier case ASUBD: 330*219b2ee8SDavid du Colombier case ASUBF: 331*219b2ee8SDavid du Colombier case ASUBW: 332*219b2ee8SDavid du Colombier case AMULF: 333*219b2ee8SDavid du Colombier case AMULD: 334*219b2ee8SDavid du Colombier case AMULW: 335*219b2ee8SDavid du Colombier case ADIVF: 336*219b2ee8SDavid du Colombier case ADIVD: 337*219b2ee8SDavid du Colombier case ADIVW: 338*219b2ee8SDavid du Colombier if(p->reg == NREG) { 339*219b2ee8SDavid du Colombier if(p->to.type == D_REG || p->to.type == D_FREG) 340*219b2ee8SDavid du Colombier p->reg = p->to.reg; 341*219b2ee8SDavid du Colombier if(p->reg == NREG) 342*219b2ee8SDavid du Colombier print("botch %P\n", p); 343*219b2ee8SDavid du Colombier } 344*219b2ee8SDavid du Colombier break; 345*219b2ee8SDavid du Colombier } 346*219b2ee8SDavid du Colombier 347*219b2ee8SDavid du Colombier /* 348*219b2ee8SDavid du Colombier * flags based on 'to' field 349*219b2ee8SDavid du Colombier */ 350*219b2ee8SDavid du Colombier c = p->to.class; 351*219b2ee8SDavid du Colombier if(c == 0) { 352*219b2ee8SDavid du Colombier c = aclass(&p->to) + 1; 353*219b2ee8SDavid du Colombier p->to.class = c; 354*219b2ee8SDavid du Colombier } 355*219b2ee8SDavid du Colombier c--; 356*219b2ee8SDavid du Colombier switch(c) { 357*219b2ee8SDavid du Colombier default: 358*219b2ee8SDavid du Colombier print("unknown class %d %D\n", c, &p->to); 359*219b2ee8SDavid du Colombier 360*219b2ee8SDavid du Colombier case C_ZCON: 361*219b2ee8SDavid du Colombier case C_SCON: 362*219b2ee8SDavid du Colombier case C_ADD0CON: 363*219b2ee8SDavid du Colombier case C_AND0CON: 364*219b2ee8SDavid du Colombier case C_ADDCON: 365*219b2ee8SDavid du Colombier case C_ANDCON: 366*219b2ee8SDavid du Colombier case C_UCON: 367*219b2ee8SDavid du Colombier case C_LCON: 368*219b2ee8SDavid du Colombier case C_NONE: 369*219b2ee8SDavid du Colombier case C_SBRA: 370*219b2ee8SDavid du Colombier case C_LBRA: 371*219b2ee8SDavid du Colombier break; 372*219b2ee8SDavid du Colombier 373*219b2ee8SDavid du Colombier case C_HI: 374*219b2ee8SDavid du Colombier case C_LO: 375*219b2ee8SDavid du Colombier s->set.cc |= E_HILO; 376*219b2ee8SDavid du Colombier break; 377*219b2ee8SDavid du Colombier case C_FCREG: 378*219b2ee8SDavid du Colombier s->set.cc |= E_FCR; 379*219b2ee8SDavid du Colombier break; 380*219b2ee8SDavid du Colombier case C_MREG: 381*219b2ee8SDavid du Colombier s->set.cc |= E_MCR; 382*219b2ee8SDavid du Colombier break; 383*219b2ee8SDavid du Colombier case C_ZOREG: 384*219b2ee8SDavid du Colombier case C_SOREG: 385*219b2ee8SDavid du Colombier case C_LOREG: 386*219b2ee8SDavid du Colombier c = p->to.reg; 387*219b2ee8SDavid du Colombier s->used.ireg |= 1<<c; 388*219b2ee8SDavid du Colombier if(ad) 389*219b2ee8SDavid du Colombier break; 390*219b2ee8SDavid du Colombier s->size = sz; 391*219b2ee8SDavid du Colombier s->offset = regoff(&p->to); 392*219b2ee8SDavid du Colombier 393*219b2ee8SDavid du Colombier m = ANYMEM; 394*219b2ee8SDavid du Colombier if(c == REGSB) 395*219b2ee8SDavid du Colombier m = E_MEMSB; 396*219b2ee8SDavid du Colombier if(c == REGSP) 397*219b2ee8SDavid du Colombier m = E_MEMSP; 398*219b2ee8SDavid du Colombier 399*219b2ee8SDavid du Colombier if(ar) 400*219b2ee8SDavid du Colombier s->used.cc |= m; 401*219b2ee8SDavid du Colombier else 402*219b2ee8SDavid du Colombier s->set.cc |= m; 403*219b2ee8SDavid du Colombier break; 404*219b2ee8SDavid du Colombier case C_SACON: 405*219b2ee8SDavid du Colombier case C_LACON: 406*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSP; 407*219b2ee8SDavid du Colombier break; 408*219b2ee8SDavid du Colombier case C_SECON: 409*219b2ee8SDavid du Colombier case C_LECON: 410*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSB; 411*219b2ee8SDavid du Colombier break; 412*219b2ee8SDavid du Colombier case C_REG: 413*219b2ee8SDavid du Colombier if(ar) 414*219b2ee8SDavid du Colombier s->used.ireg |= 1<<p->to.reg; 415*219b2ee8SDavid du Colombier else 416*219b2ee8SDavid du Colombier s->set.ireg |= 1<<p->to.reg; 417*219b2ee8SDavid du Colombier break; 418*219b2ee8SDavid du Colombier case C_FREG: 419*219b2ee8SDavid du Colombier /* do better -- determine double prec */ 420*219b2ee8SDavid du Colombier if(ar) { 421*219b2ee8SDavid du Colombier s->used.freg |= 1<<p->to.reg; 422*219b2ee8SDavid du Colombier s->used.freg |= 1<<(p->to.reg|1); 423*219b2ee8SDavid du Colombier } else { 424*219b2ee8SDavid du Colombier s->set.freg |= 1<<p->to.reg; 425*219b2ee8SDavid du Colombier s->set.freg |= 1<<(p->to.reg|1); 426*219b2ee8SDavid du Colombier } 427*219b2ee8SDavid du Colombier if(ld && p->from.type == D_REG) 428*219b2ee8SDavid du Colombier p->mark |= LOAD; 429*219b2ee8SDavid du Colombier break; 430*219b2ee8SDavid du Colombier case C_SAUTO: 431*219b2ee8SDavid du Colombier case C_LAUTO: 432*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSP; 433*219b2ee8SDavid du Colombier if(ad) 434*219b2ee8SDavid du Colombier break; 435*219b2ee8SDavid du Colombier s->size = sz; 436*219b2ee8SDavid du Colombier s->offset = regoff(&p->to); 437*219b2ee8SDavid du Colombier 438*219b2ee8SDavid du Colombier if(ar) 439*219b2ee8SDavid du Colombier s->used.cc |= E_MEMSP; 440*219b2ee8SDavid du Colombier else 441*219b2ee8SDavid du Colombier s->set.cc |= E_MEMSP; 442*219b2ee8SDavid du Colombier break; 443*219b2ee8SDavid du Colombier case C_SEXT: 444*219b2ee8SDavid du Colombier case C_LEXT: 445*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSB; 446*219b2ee8SDavid du Colombier if(ad) 447*219b2ee8SDavid du Colombier break; 448*219b2ee8SDavid du Colombier s->size = sz; 449*219b2ee8SDavid du Colombier s->offset = regoff(&p->to); 450*219b2ee8SDavid du Colombier 451*219b2ee8SDavid du Colombier if(ar) 452*219b2ee8SDavid du Colombier s->used.cc |= E_MEMSB; 453*219b2ee8SDavid du Colombier else 454*219b2ee8SDavid du Colombier s->set.cc |= E_MEMSB; 455*219b2ee8SDavid du Colombier break; 456*219b2ee8SDavid du Colombier } 457*219b2ee8SDavid du Colombier 458*219b2ee8SDavid du Colombier /* 459*219b2ee8SDavid du Colombier * flags based on 'from' field 460*219b2ee8SDavid du Colombier */ 461*219b2ee8SDavid du Colombier c = p->from.class; 462*219b2ee8SDavid du Colombier if(c == 0) { 463*219b2ee8SDavid du Colombier c = aclass(&p->from) + 1; 464*219b2ee8SDavid du Colombier p->from.class = c; 465*219b2ee8SDavid du Colombier } 466*219b2ee8SDavid du Colombier c--; 467*219b2ee8SDavid du Colombier switch(c) { 468*219b2ee8SDavid du Colombier default: 469*219b2ee8SDavid du Colombier print("unknown class %d %D\n", c, &p->from); 470*219b2ee8SDavid du Colombier 471*219b2ee8SDavid du Colombier case C_ZCON: 472*219b2ee8SDavid du Colombier case C_SCON: 473*219b2ee8SDavid du Colombier case C_ADD0CON: 474*219b2ee8SDavid du Colombier case C_AND0CON: 475*219b2ee8SDavid du Colombier case C_ADDCON: 476*219b2ee8SDavid du Colombier case C_ANDCON: 477*219b2ee8SDavid du Colombier case C_UCON: 478*219b2ee8SDavid du Colombier case C_LCON: 479*219b2ee8SDavid du Colombier case C_NONE: 480*219b2ee8SDavid du Colombier case C_SBRA: 481*219b2ee8SDavid du Colombier case C_LBRA: 482*219b2ee8SDavid du Colombier break; 483*219b2ee8SDavid du Colombier case C_HI: 484*219b2ee8SDavid du Colombier case C_LO: 485*219b2ee8SDavid du Colombier s->used.cc |= E_HILO; 486*219b2ee8SDavid du Colombier break; 487*219b2ee8SDavid du Colombier case C_FCREG: 488*219b2ee8SDavid du Colombier s->used.cc |= E_FCR; 489*219b2ee8SDavid du Colombier break; 490*219b2ee8SDavid du Colombier case C_MREG: 491*219b2ee8SDavid du Colombier s->used.cc |= E_MCR; 492*219b2ee8SDavid du Colombier break; 493*219b2ee8SDavid du Colombier case C_ZOREG: 494*219b2ee8SDavid du Colombier case C_SOREG: 495*219b2ee8SDavid du Colombier case C_LOREG: 496*219b2ee8SDavid du Colombier c = p->from.reg; 497*219b2ee8SDavid du Colombier s->used.ireg |= 1<<c; 498*219b2ee8SDavid du Colombier if(ld) 499*219b2ee8SDavid du Colombier p->mark |= LOAD; 500*219b2ee8SDavid du Colombier s->size = sz; 501*219b2ee8SDavid du Colombier s->offset = regoff(&p->from); 502*219b2ee8SDavid du Colombier 503*219b2ee8SDavid du Colombier m = ANYMEM; 504*219b2ee8SDavid du Colombier if(c == REGSB) 505*219b2ee8SDavid du Colombier m = E_MEMSB; 506*219b2ee8SDavid du Colombier if(c == REGSP) 507*219b2ee8SDavid du Colombier m = E_MEMSP; 508*219b2ee8SDavid du Colombier 509*219b2ee8SDavid du Colombier s->used.cc |= m; 510*219b2ee8SDavid du Colombier break; 511*219b2ee8SDavid du Colombier case C_SACON: 512*219b2ee8SDavid du Colombier case C_LACON: 513*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSP; 514*219b2ee8SDavid du Colombier break; 515*219b2ee8SDavid du Colombier case C_SECON: 516*219b2ee8SDavid du Colombier case C_LECON: 517*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSB; 518*219b2ee8SDavid du Colombier break; 519*219b2ee8SDavid du Colombier case C_REG: 520*219b2ee8SDavid du Colombier s->used.ireg |= 1<<p->from.reg; 521*219b2ee8SDavid du Colombier break; 522*219b2ee8SDavid du Colombier case C_FREG: 523*219b2ee8SDavid du Colombier /* do better -- determine double prec */ 524*219b2ee8SDavid du Colombier s->used.freg |= 1<<p->from.reg; 525*219b2ee8SDavid du Colombier s->used.freg |= 1<<(p->from.reg|1); 526*219b2ee8SDavid du Colombier if(ld && p->to.type == D_REG) 527*219b2ee8SDavid du Colombier p->mark |= LOAD; 528*219b2ee8SDavid du Colombier break; 529*219b2ee8SDavid du Colombier case C_SAUTO: 530*219b2ee8SDavid du Colombier case C_LAUTO: 531*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSP; 532*219b2ee8SDavid du Colombier if(ld) 533*219b2ee8SDavid du Colombier p->mark |= LOAD; 534*219b2ee8SDavid du Colombier if(ad) 535*219b2ee8SDavid du Colombier break; 536*219b2ee8SDavid du Colombier s->size = sz; 537*219b2ee8SDavid du Colombier s->offset = regoff(&p->from); 538*219b2ee8SDavid du Colombier 539*219b2ee8SDavid du Colombier s->used.cc |= E_MEMSP; 540*219b2ee8SDavid du Colombier break; 541*219b2ee8SDavid du Colombier case C_SEXT: 542*219b2ee8SDavid du Colombier case C_LEXT: 543*219b2ee8SDavid du Colombier s->used.ireg |= 1<<REGSB; 544*219b2ee8SDavid du Colombier if(ld) 545*219b2ee8SDavid du Colombier p->mark |= LOAD; 546*219b2ee8SDavid du Colombier if(ad) 547*219b2ee8SDavid du Colombier break; 548*219b2ee8SDavid du Colombier s->size = sz; 549*219b2ee8SDavid du Colombier s->offset = regoff(&p->from); 550*219b2ee8SDavid du Colombier 551*219b2ee8SDavid du Colombier s->used.cc |= E_MEMSB; 552*219b2ee8SDavid du Colombier break; 553*219b2ee8SDavid du Colombier } 554*219b2ee8SDavid du Colombier 555*219b2ee8SDavid du Colombier c = p->reg; 556*219b2ee8SDavid du Colombier if(c != NREG) { 557*219b2ee8SDavid du Colombier if(p->from.type == D_FREG || p->to.type == D_FREG) { 558*219b2ee8SDavid du Colombier s->used.freg |= 1<<c; 559*219b2ee8SDavid du Colombier s->used.freg |= 1<<(c|1); 560*219b2ee8SDavid du Colombier } else 561*219b2ee8SDavid du Colombier s->used.ireg |= 1<<c; 562*219b2ee8SDavid du Colombier } 563*219b2ee8SDavid du Colombier s->set.ireg &= ~(1<<REGZERO); /* R0 cant be set */ 564*219b2ee8SDavid du Colombier } 565*219b2ee8SDavid du Colombier 566*219b2ee8SDavid du Colombier /* 567*219b2ee8SDavid du Colombier * test to see if 2 instrictions can be 568*219b2ee8SDavid du Colombier * interchanged without changing semantics 569*219b2ee8SDavid du Colombier */ 570*219b2ee8SDavid du Colombier int 571*219b2ee8SDavid du Colombier depend(Sch *sa, Sch *sb) 572*219b2ee8SDavid du Colombier { 573*219b2ee8SDavid du Colombier ulong x; 574*219b2ee8SDavid du Colombier 575*219b2ee8SDavid du Colombier if(sa->set.ireg & (sb->set.ireg|sb->used.ireg)) 576*219b2ee8SDavid du Colombier return 1; 577*219b2ee8SDavid du Colombier if(sb->set.ireg & sa->used.ireg) 578*219b2ee8SDavid du Colombier return 1; 579*219b2ee8SDavid du Colombier 580*219b2ee8SDavid du Colombier if(sa->set.freg & (sb->set.freg|sb->used.freg)) 581*219b2ee8SDavid du Colombier return 1; 582*219b2ee8SDavid du Colombier if(sb->set.freg & sa->used.freg) 583*219b2ee8SDavid du Colombier return 1; 584*219b2ee8SDavid du Colombier 585*219b2ee8SDavid du Colombier /* 586*219b2ee8SDavid du Colombier * special case. 587*219b2ee8SDavid du Colombier * loads from same address cannot pass. 588*219b2ee8SDavid du Colombier * this is for hardware fifo's and the like 589*219b2ee8SDavid du Colombier */ 590*219b2ee8SDavid du Colombier if(sa->used.cc & sb->used.cc & E_MEM) 591*219b2ee8SDavid du Colombier if(sa->p.reg == sb->p.reg) 592*219b2ee8SDavid du Colombier if(regoff(&sa->p.from) == regoff(&sb->p.from)) 593*219b2ee8SDavid du Colombier return 1; 594*219b2ee8SDavid du Colombier 595*219b2ee8SDavid du Colombier x = (sa->set.cc & (sb->set.cc|sb->used.cc)) | 596*219b2ee8SDavid du Colombier (sb->set.cc & sa->used.cc); 597*219b2ee8SDavid du Colombier if(x) { 598*219b2ee8SDavid du Colombier /* 599*219b2ee8SDavid du Colombier * allow SB and SP to pass each other. 600*219b2ee8SDavid du Colombier * allow SB to pass SB iff doffsets are ok 601*219b2ee8SDavid du Colombier * anything else conflicts 602*219b2ee8SDavid du Colombier */ 603*219b2ee8SDavid du Colombier if(x != E_MEMSP && x != E_MEMSB) 604*219b2ee8SDavid du Colombier return 1; 605*219b2ee8SDavid du Colombier x = sa->set.cc | sb->set.cc | 606*219b2ee8SDavid du Colombier sa->used.cc | sb->used.cc; 607*219b2ee8SDavid du Colombier if(x & E_MEM) 608*219b2ee8SDavid du Colombier return 1; 609*219b2ee8SDavid du Colombier if(offoverlap(sa, sb)) 610*219b2ee8SDavid du Colombier return 1; 611*219b2ee8SDavid du Colombier } 612*219b2ee8SDavid du Colombier 613*219b2ee8SDavid du Colombier return 0; 614*219b2ee8SDavid du Colombier } 615*219b2ee8SDavid du Colombier 616*219b2ee8SDavid du Colombier int 617*219b2ee8SDavid du Colombier offoverlap(Sch *sa, Sch *sb) 618*219b2ee8SDavid du Colombier { 619*219b2ee8SDavid du Colombier 620*219b2ee8SDavid du Colombier if(sa->offset < sb->offset) { 621*219b2ee8SDavid du Colombier if(sa->offset+sa->size > sb->offset) 622*219b2ee8SDavid du Colombier return 1; 623*219b2ee8SDavid du Colombier return 0; 624*219b2ee8SDavid du Colombier } 625*219b2ee8SDavid du Colombier if(sb->offset+sb->size > sa->offset) 626*219b2ee8SDavid du Colombier return 1; 627*219b2ee8SDavid du Colombier return 0; 628*219b2ee8SDavid du Colombier } 629*219b2ee8SDavid du Colombier 630*219b2ee8SDavid du Colombier /* 631*219b2ee8SDavid du Colombier * test 2 adjacent instructions 632*219b2ee8SDavid du Colombier * and find out if inserted instructions 633*219b2ee8SDavid du Colombier * are desired to prevent stalls. 634*219b2ee8SDavid du Colombier */ 635*219b2ee8SDavid du Colombier int 636*219b2ee8SDavid du Colombier conflict(Sch *sa, Sch *sb) 637*219b2ee8SDavid du Colombier { 638*219b2ee8SDavid du Colombier 639*219b2ee8SDavid du Colombier if(sa->set.ireg & sb->used.ireg) 640*219b2ee8SDavid du Colombier return 1; 641*219b2ee8SDavid du Colombier if(sa->set.freg & sb->used.freg) 642*219b2ee8SDavid du Colombier return 1; 643*219b2ee8SDavid du Colombier if(sa->set.cc & sb->used.cc) 644*219b2ee8SDavid du Colombier return 1; 645*219b2ee8SDavid du Colombier 646*219b2ee8SDavid du Colombier return 0; 647*219b2ee8SDavid du Colombier } 648*219b2ee8SDavid du Colombier 649*219b2ee8SDavid du Colombier int 650*219b2ee8SDavid du Colombier compound(Prog *p) 651*219b2ee8SDavid du Colombier { 652*219b2ee8SDavid du Colombier Optab *o; 653*219b2ee8SDavid du Colombier 654*219b2ee8SDavid du Colombier o = oplook(p); 655*219b2ee8SDavid du Colombier if(o->size != 4) 656*219b2ee8SDavid du Colombier return 1; 657*219b2ee8SDavid du Colombier if(p->to.type == D_REG && p->to.reg == REGSB) 658*219b2ee8SDavid du Colombier return 1; 659*219b2ee8SDavid du Colombier return 0; 660*219b2ee8SDavid du Colombier } 661*219b2ee8SDavid du Colombier 662*219b2ee8SDavid du Colombier void 663*219b2ee8SDavid du Colombier dumpbits(Sch *s, Dep *d) 664*219b2ee8SDavid du Colombier { 665*219b2ee8SDavid du Colombier int i; 666*219b2ee8SDavid du Colombier 667*219b2ee8SDavid du Colombier for(i=0; i<32; i++) 668*219b2ee8SDavid du Colombier if(d->ireg & (1<<i)) 669*219b2ee8SDavid du Colombier Bprint(&bso, " R%d", i); 670*219b2ee8SDavid du Colombier for(i=0; i<32; i++) 671*219b2ee8SDavid du Colombier if(d->freg & (1<<i)) 672*219b2ee8SDavid du Colombier Bprint(&bso, " F%d", i); 673*219b2ee8SDavid du Colombier for(i=0; i<32; i++) 674*219b2ee8SDavid du Colombier switch(d->cc & (1<<i)) { 675*219b2ee8SDavid du Colombier default: 676*219b2ee8SDavid du Colombier break; 677*219b2ee8SDavid du Colombier case E_HILO: 678*219b2ee8SDavid du Colombier Bprint(&bso, " HILO"); 679*219b2ee8SDavid du Colombier break; 680*219b2ee8SDavid du Colombier case E_FCR: 681*219b2ee8SDavid du Colombier Bprint(&bso, " FCR"); 682*219b2ee8SDavid du Colombier break; 683*219b2ee8SDavid du Colombier case E_MCR: 684*219b2ee8SDavid du Colombier Bprint(&bso, " MCR"); 685*219b2ee8SDavid du Colombier break; 686*219b2ee8SDavid du Colombier case E_MEM: 687*219b2ee8SDavid du Colombier Bprint(&bso, " MEM%d", s->size); 688*219b2ee8SDavid du Colombier break; 689*219b2ee8SDavid du Colombier case E_MEMSB: 690*219b2ee8SDavid du Colombier Bprint(&bso, " SB%d", s->size); 691*219b2ee8SDavid du Colombier break; 692*219b2ee8SDavid du Colombier case E_MEMSP: 693*219b2ee8SDavid du Colombier Bprint(&bso, " SP%d", s->size); 694*219b2ee8SDavid du Colombier break; 695*219b2ee8SDavid du Colombier } 696*219b2ee8SDavid du Colombier } 697