13e12c5d1SDavid du Colombier #include "l.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier void 47dd7cddfSDavid du Colombier pagebug(Prog *p) 53e12c5d1SDavid du Colombier { 67dd7cddfSDavid du Colombier Prog *q; 73e12c5d1SDavid du Colombier 8219b2ee8SDavid du Colombier switch(p->as) { 9219b2ee8SDavid du Colombier case ABGEZAL: 10219b2ee8SDavid du Colombier case ABLTZAL: 11219b2ee8SDavid du Colombier case AJAL: 12219b2ee8SDavid du Colombier case ABEQ: 13219b2ee8SDavid du Colombier case ABGEZ: 14219b2ee8SDavid du Colombier case ABGTZ: 15219b2ee8SDavid du Colombier case ABLEZ: 16219b2ee8SDavid du Colombier case ABLTZ: 17219b2ee8SDavid du Colombier case ABNE: 18219b2ee8SDavid du Colombier case ABFPT: 19219b2ee8SDavid du Colombier case ABFPF: 20219b2ee8SDavid du Colombier case AJMP: 21219b2ee8SDavid du Colombier q = prg(); 22219b2ee8SDavid du Colombier *q = *p; 23219b2ee8SDavid du Colombier p->link = q; 24219b2ee8SDavid du Colombier p->as = ANOR; 25219b2ee8SDavid du Colombier p->optab = 0; 26219b2ee8SDavid du Colombier p->from = zprg.from; 27219b2ee8SDavid du Colombier p->from.type = D_REG; 28219b2ee8SDavid du Colombier p->from.reg = REGZERO; 29219b2ee8SDavid du Colombier p->to = p->from; 30219b2ee8SDavid du Colombier } 31219b2ee8SDavid du Colombier } 327dd7cddfSDavid du Colombier 337dd7cddfSDavid du Colombier void 347dd7cddfSDavid du Colombier span(void) 357dd7cddfSDavid du Colombier { 367dd7cddfSDavid du Colombier Prog *p, *q; 37*9a747e4fSDavid du Colombier Sym *setext, *s; 387dd7cddfSDavid du Colombier Optab *o; 39*9a747e4fSDavid du Colombier int m, bflag, i; 40*9a747e4fSDavid du Colombier long c, otxt, v; 417dd7cddfSDavid du Colombier 427dd7cddfSDavid du Colombier if(debug['v']) 437dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f span\n", cputime()); 447dd7cddfSDavid du Colombier Bflush(&bso); 457dd7cddfSDavid du Colombier 467dd7cddfSDavid du Colombier bflag = 0; 477dd7cddfSDavid du Colombier c = INITTEXT; 487dd7cddfSDavid du Colombier otxt = c; 497dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) { 507dd7cddfSDavid du Colombier /* bug in early 4000 chips delayslot on page boundary */ 517dd7cddfSDavid du Colombier if((c&(0x1000-1)) == 0xffc) 527dd7cddfSDavid du Colombier pagebug(p); 533e12c5d1SDavid du Colombier p->pc = c; 543e12c5d1SDavid du Colombier o = oplook(p); 553e12c5d1SDavid du Colombier m = o->size; 563e12c5d1SDavid du Colombier if(m == 0) { 573e12c5d1SDavid du Colombier if(p->as == ATEXT) { 583e12c5d1SDavid du Colombier curtext = p; 593e12c5d1SDavid du Colombier autosize = p->to.offset + 4; 603e12c5d1SDavid du Colombier if(p->from.sym != S) 613e12c5d1SDavid du Colombier p->from.sym->value = c; 627dd7cddfSDavid du Colombier /* need passes to resolve branches */ 637dd7cddfSDavid du Colombier if(c-otxt >= 1L<<17) 647dd7cddfSDavid du Colombier bflag = 1; 657dd7cddfSDavid du Colombier otxt = c; 667dd7cddfSDavid du Colombier continue; 677dd7cddfSDavid du Colombier } 687dd7cddfSDavid du Colombier diag("zero-width instruction\n%P\n", p); 697dd7cddfSDavid du Colombier continue; 707dd7cddfSDavid du Colombier } 717dd7cddfSDavid du Colombier c += m; 727dd7cddfSDavid du Colombier } 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier /* 757dd7cddfSDavid du Colombier * if any procedure is large enough to 767dd7cddfSDavid du Colombier * generate a large SBRA branch, then 777dd7cddfSDavid du Colombier * generate extra passes putting branches 787dd7cddfSDavid du Colombier * around jmps to fix. this is rare. 797dd7cddfSDavid du Colombier */ 807dd7cddfSDavid du Colombier while(bflag) { 817dd7cddfSDavid du Colombier if(debug['v']) 827dd7cddfSDavid du Colombier Bprint(&bso, "%5.2f span1\n", cputime()); 837dd7cddfSDavid du Colombier bflag = 0; 847dd7cddfSDavid du Colombier c = INITTEXT; 857dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) { 867dd7cddfSDavid du Colombier /* bug in early 4000 chips delayslot on page boundary */ 877dd7cddfSDavid du Colombier if((c&(0x1000-1)) == 0xffc) 887dd7cddfSDavid du Colombier pagebug(p); 897dd7cddfSDavid du Colombier p->pc = c; 907dd7cddfSDavid du Colombier o = oplook(p); 917dd7cddfSDavid du Colombier if(o->type == 6 && p->cond) { 927dd7cddfSDavid du Colombier otxt = p->cond->pc - c; 937dd7cddfSDavid du Colombier if(otxt < 0) 947dd7cddfSDavid du Colombier otxt = -otxt; 957dd7cddfSDavid du Colombier if(otxt >= (1L<<17) - 10) { 967dd7cddfSDavid du Colombier q = prg(); 977dd7cddfSDavid du Colombier q->link = p->link; 987dd7cddfSDavid du Colombier p->link = q; 997dd7cddfSDavid du Colombier q->as = AJMP; 1007dd7cddfSDavid du Colombier q->to.type = D_BRANCH; 1017dd7cddfSDavid du Colombier q->cond = p->cond; 1027dd7cddfSDavid du Colombier p->cond = q; 1037dd7cddfSDavid du Colombier q = prg(); 1047dd7cddfSDavid du Colombier q->link = p->link; 1057dd7cddfSDavid du Colombier p->link = q; 1067dd7cddfSDavid du Colombier q->as = AJMP; 1077dd7cddfSDavid du Colombier q->to.type = D_BRANCH; 1087dd7cddfSDavid du Colombier q->cond = q->link->link; 1097dd7cddfSDavid du Colombier addnop(p->link); 1107dd7cddfSDavid du Colombier addnop(p); 1117dd7cddfSDavid du Colombier bflag = 1; 1127dd7cddfSDavid du Colombier } 1137dd7cddfSDavid du Colombier } 1147dd7cddfSDavid du Colombier m = o->size; 1157dd7cddfSDavid du Colombier if(m == 0) { 1167dd7cddfSDavid du Colombier if(p->as == ATEXT) { 1177dd7cddfSDavid du Colombier curtext = p; 1187dd7cddfSDavid du Colombier autosize = p->to.offset + 4; 1197dd7cddfSDavid du Colombier if(p->from.sym != S) 1207dd7cddfSDavid du Colombier p->from.sym->value = c; 1213e12c5d1SDavid du Colombier continue; 1223e12c5d1SDavid du Colombier } 1233e12c5d1SDavid du Colombier diag("zero-width instruction\n%P\n", p); 1243e12c5d1SDavid du Colombier continue; 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier c += m; 1273e12c5d1SDavid du Colombier } 1287dd7cddfSDavid du Colombier } 129*9a747e4fSDavid du Colombier 130*9a747e4fSDavid du Colombier if(debug['t']) { 131*9a747e4fSDavid du Colombier /* 132*9a747e4fSDavid du Colombier * add strings to text segment 133*9a747e4fSDavid du Colombier */ 134*9a747e4fSDavid du Colombier c = rnd(c, 8); 135*9a747e4fSDavid du Colombier for(i=0; i<NHASH; i++) 136*9a747e4fSDavid du Colombier for(s = hash[i]; s != S; s = s->link) { 137*9a747e4fSDavid du Colombier if(s->type != SSTRING) 138*9a747e4fSDavid du Colombier continue; 139*9a747e4fSDavid du Colombier v = s->value; 140*9a747e4fSDavid du Colombier while(v & 3) 141*9a747e4fSDavid du Colombier v++; 142*9a747e4fSDavid du Colombier s->value = c; 143*9a747e4fSDavid du Colombier c += v; 144*9a747e4fSDavid du Colombier } 145*9a747e4fSDavid du Colombier } 146*9a747e4fSDavid du Colombier 1473e12c5d1SDavid du Colombier c = rnd(c, 8); 1483e12c5d1SDavid du Colombier 1493e12c5d1SDavid du Colombier setext = lookup("etext", 0); 1503e12c5d1SDavid du Colombier if(setext != S) { 1513e12c5d1SDavid du Colombier setext->value = c; 1523e12c5d1SDavid du Colombier textsize = c - INITTEXT; 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier if(INITRND) 1553e12c5d1SDavid du Colombier INITDAT = rnd(c, INITRND); 1563e12c5d1SDavid du Colombier if(debug['v']) 1573e12c5d1SDavid du Colombier Bprint(&bso, "tsize = %lux\n", textsize); 1583e12c5d1SDavid du Colombier Bflush(&bso); 1593e12c5d1SDavid du Colombier } 1603e12c5d1SDavid du Colombier 1613e12c5d1SDavid du Colombier void 1623e12c5d1SDavid du Colombier xdefine(char *p, int t, long v) 1633e12c5d1SDavid du Colombier { 1643e12c5d1SDavid du Colombier Sym *s; 1653e12c5d1SDavid du Colombier 1663e12c5d1SDavid du Colombier s = lookup(p, 0); 1673e12c5d1SDavid du Colombier if(s->type == 0 || s->type == SXREF) { 1683e12c5d1SDavid du Colombier s->type = t; 1693e12c5d1SDavid du Colombier s->value = v; 1703e12c5d1SDavid du Colombier } 1713e12c5d1SDavid du Colombier } 1723e12c5d1SDavid du Colombier 1733e12c5d1SDavid du Colombier long 1743e12c5d1SDavid du Colombier regoff(Adr *a) 1753e12c5d1SDavid du Colombier { 1763e12c5d1SDavid du Colombier 1777dd7cddfSDavid du Colombier instoffset = 0; 1783e12c5d1SDavid du Colombier aclass(a); 1797dd7cddfSDavid du Colombier return instoffset; 1803e12c5d1SDavid du Colombier } 1813e12c5d1SDavid du Colombier 1823e12c5d1SDavid du Colombier aclass(Adr *a) 1833e12c5d1SDavid du Colombier { 1843e12c5d1SDavid du Colombier Sym *s; 1853e12c5d1SDavid du Colombier int t; 1863e12c5d1SDavid du Colombier 1873e12c5d1SDavid du Colombier switch(a->type) { 1883e12c5d1SDavid du Colombier case D_NONE: 1893e12c5d1SDavid du Colombier return C_NONE; 1903e12c5d1SDavid du Colombier 1913e12c5d1SDavid du Colombier case D_REG: 1923e12c5d1SDavid du Colombier return C_REG; 1933e12c5d1SDavid du Colombier 1943e12c5d1SDavid du Colombier case D_FREG: 1953e12c5d1SDavid du Colombier return C_FREG; 1963e12c5d1SDavid du Colombier 1973e12c5d1SDavid du Colombier case D_FCREG: 1983e12c5d1SDavid du Colombier return C_FCREG; 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier case D_MREG: 2013e12c5d1SDavid du Colombier return C_MREG; 2023e12c5d1SDavid du Colombier 2033e12c5d1SDavid du Colombier case D_OREG: 2043e12c5d1SDavid du Colombier switch(a->name) { 2053e12c5d1SDavid du Colombier case D_EXTERN: 2063e12c5d1SDavid du Colombier case D_STATIC: 207219b2ee8SDavid du Colombier if(a->sym == 0 || a->sym->name == 0) { 2083e12c5d1SDavid du Colombier print("null sym external\n"); 2093e12c5d1SDavid du Colombier print("%D\n", a); 2103e12c5d1SDavid du Colombier return C_GOK; 2113e12c5d1SDavid du Colombier } 2123e12c5d1SDavid du Colombier t = a->sym->type; 2133e12c5d1SDavid du Colombier if(t == 0 || t == SXREF) { 2143e12c5d1SDavid du Colombier diag("undefined external: %s in %s\n", 2153e12c5d1SDavid du Colombier a->sym->name, TNAME); 2163e12c5d1SDavid du Colombier a->sym->type = SDATA; 2173e12c5d1SDavid du Colombier } 2187dd7cddfSDavid du Colombier instoffset = a->sym->value + a->offset - BIG; 2197dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG) 2203e12c5d1SDavid du Colombier return C_SEXT; 2213e12c5d1SDavid du Colombier return C_LEXT; 2223e12c5d1SDavid du Colombier case D_AUTO: 2237dd7cddfSDavid du Colombier instoffset = autosize + a->offset; 2247dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG) 2253e12c5d1SDavid du Colombier return C_SAUTO; 2263e12c5d1SDavid du Colombier return C_LAUTO; 2273e12c5d1SDavid du Colombier 2283e12c5d1SDavid du Colombier case D_PARAM: 2297dd7cddfSDavid du Colombier instoffset = autosize + a->offset + 4L; 2307dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG) 2313e12c5d1SDavid du Colombier return C_SAUTO; 2323e12c5d1SDavid du Colombier return C_LAUTO; 2333e12c5d1SDavid du Colombier case D_NONE: 2347dd7cddfSDavid du Colombier instoffset = a->offset; 2357dd7cddfSDavid du Colombier if(instoffset == 0) 2363e12c5d1SDavid du Colombier return C_ZOREG; 2377dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG) 2383e12c5d1SDavid du Colombier return C_SOREG; 2393e12c5d1SDavid du Colombier return C_LOREG; 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier return C_GOK; 2423e12c5d1SDavid du Colombier 2433e12c5d1SDavid du Colombier case D_HI: 2443e12c5d1SDavid du Colombier return C_LO; 2453e12c5d1SDavid du Colombier case D_LO: 2463e12c5d1SDavid du Colombier return C_HI; 2473e12c5d1SDavid du Colombier 248219b2ee8SDavid du Colombier case D_OCONST: 249219b2ee8SDavid du Colombier switch(a->name) { 250219b2ee8SDavid du Colombier case D_EXTERN: 251219b2ee8SDavid du Colombier case D_STATIC: 252219b2ee8SDavid du Colombier s = a->sym; 253219b2ee8SDavid du Colombier t = s->type; 254219b2ee8SDavid du Colombier if(t == 0 || t == SXREF) { 255219b2ee8SDavid du Colombier diag("undefined external: %s in %s\n", 256219b2ee8SDavid du Colombier s->name, TNAME); 257219b2ee8SDavid du Colombier s->type = SDATA; 258219b2ee8SDavid du Colombier } 2597dd7cddfSDavid du Colombier instoffset = s->value + a->offset + INITDAT; 260219b2ee8SDavid du Colombier if(s->type == STEXT || s->type == SLEAF) 2617dd7cddfSDavid du Colombier instoffset = s->value + a->offset; 262219b2ee8SDavid du Colombier return C_LCON; 263219b2ee8SDavid du Colombier } 264219b2ee8SDavid du Colombier return C_GOK; 265219b2ee8SDavid du Colombier 2663e12c5d1SDavid du Colombier case D_CONST: 2673e12c5d1SDavid du Colombier switch(a->name) { 2683e12c5d1SDavid du Colombier 2693e12c5d1SDavid du Colombier case D_NONE: 2707dd7cddfSDavid du Colombier instoffset = a->offset; 271219b2ee8SDavid du Colombier consize: 2727dd7cddfSDavid du Colombier if(instoffset > 0) { 2737dd7cddfSDavid du Colombier if(instoffset <= 0x7fff) 2743e12c5d1SDavid du Colombier return C_SCON; 2757dd7cddfSDavid du Colombier if(instoffset <= 0xffff) 2763e12c5d1SDavid du Colombier return C_ANDCON; 2777dd7cddfSDavid du Colombier if((instoffset & 0xffff) == 0) 2783e12c5d1SDavid du Colombier return C_UCON; 2793e12c5d1SDavid du Colombier return C_LCON; 2803e12c5d1SDavid du Colombier } 2817dd7cddfSDavid du Colombier if(instoffset == 0) 2823e12c5d1SDavid du Colombier return C_ZCON; 2837dd7cddfSDavid du Colombier if(instoffset >= -0x8000) 2843e12c5d1SDavid du Colombier return C_ADDCON; 2857dd7cddfSDavid du Colombier if((instoffset & 0xffff) == 0) 2863e12c5d1SDavid du Colombier return C_UCON; 2873e12c5d1SDavid du Colombier return C_LCON; 2883e12c5d1SDavid du Colombier 2893e12c5d1SDavid du Colombier case D_EXTERN: 2903e12c5d1SDavid du Colombier case D_STATIC: 2913e12c5d1SDavid du Colombier s = a->sym; 292219b2ee8SDavid du Colombier if(s == S) 293219b2ee8SDavid du Colombier break; 2943e12c5d1SDavid du Colombier t = s->type; 295219b2ee8SDavid du Colombier switch(t) { 296219b2ee8SDavid du Colombier case 0: 297219b2ee8SDavid du Colombier case SXREF: 2983e12c5d1SDavid du Colombier diag("undefined external: %s in %s\n", 2993e12c5d1SDavid du Colombier s->name, TNAME); 3003e12c5d1SDavid du Colombier s->type = SDATA; 301219b2ee8SDavid du Colombier break; 302219b2ee8SDavid du Colombier case SCONST: 3037dd7cddfSDavid du Colombier instoffset = s->value + a->offset; 304219b2ee8SDavid du Colombier goto consize; 305219b2ee8SDavid du Colombier case STEXT: 306219b2ee8SDavid du Colombier case SLEAF: 307*9a747e4fSDavid du Colombier case SSTRING: 3087dd7cddfSDavid du Colombier instoffset = s->value + a->offset; 3093e12c5d1SDavid du Colombier return C_LCON; 3103e12c5d1SDavid du Colombier } 3117dd7cddfSDavid du Colombier instoffset = s->value + a->offset - BIG; 3127dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG && instoffset != 0L) 3133e12c5d1SDavid du Colombier return C_SECON; 3147dd7cddfSDavid du Colombier instoffset = s->value + a->offset + INITDAT; 3153e12c5d1SDavid du Colombier return C_LCON; 3163e12c5d1SDavid du Colombier 3173e12c5d1SDavid du Colombier case D_AUTO: 3187dd7cddfSDavid du Colombier instoffset = autosize + a->offset; 3197dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG) 3203e12c5d1SDavid du Colombier return C_SACON; 3213e12c5d1SDavid du Colombier return C_LACON; 3223e12c5d1SDavid du Colombier 3233e12c5d1SDavid du Colombier case D_PARAM: 3247dd7cddfSDavid du Colombier instoffset = autosize + a->offset + 4L; 3257dd7cddfSDavid du Colombier if(instoffset >= -BIG && instoffset < BIG) 3263e12c5d1SDavid du Colombier return C_SACON; 3273e12c5d1SDavid du Colombier return C_LACON; 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier return C_GOK; 3303e12c5d1SDavid du Colombier 3313e12c5d1SDavid du Colombier case D_BRANCH: 3323e12c5d1SDavid du Colombier return C_SBRA; 3333e12c5d1SDavid du Colombier } 3343e12c5d1SDavid du Colombier return C_GOK; 3353e12c5d1SDavid du Colombier } 3363e12c5d1SDavid du Colombier 3373e12c5d1SDavid du Colombier Optab* 3383e12c5d1SDavid du Colombier oplook(Prog *p) 3393e12c5d1SDavid du Colombier { 3403e12c5d1SDavid du Colombier int a1, a2, a3, r; 3413e12c5d1SDavid du Colombier char *c1, *c3; 3423e12c5d1SDavid du Colombier Optab *o, *e; 3433e12c5d1SDavid du Colombier 3443e12c5d1SDavid du Colombier a1 = p->optab; 3453e12c5d1SDavid du Colombier if(a1) 3463e12c5d1SDavid du Colombier return optab+(a1-1); 3473e12c5d1SDavid du Colombier a1 = p->from.class; 3483e12c5d1SDavid du Colombier if(a1 == 0) { 3493e12c5d1SDavid du Colombier a1 = aclass(&p->from) + 1; 3503e12c5d1SDavid du Colombier p->from.class = a1; 3513e12c5d1SDavid du Colombier } 3523e12c5d1SDavid du Colombier a1--; 3533e12c5d1SDavid du Colombier a3 = p->to.class; 3543e12c5d1SDavid du Colombier if(a3 == 0) { 3553e12c5d1SDavid du Colombier a3 = aclass(&p->to) + 1; 3563e12c5d1SDavid du Colombier p->to.class = a3; 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier a3--; 3593e12c5d1SDavid du Colombier a2 = C_NONE; 3603e12c5d1SDavid du Colombier if(p->reg != NREG) 3613e12c5d1SDavid du Colombier a2 = C_REG; 3623e12c5d1SDavid du Colombier r = p->as; 3633e12c5d1SDavid du Colombier o = oprange[r].start; 3643e12c5d1SDavid du Colombier if(o == 0) { 3653e12c5d1SDavid du Colombier a1 = opcross[repop[r]][a1][a2][a3]; 3663e12c5d1SDavid du Colombier if(a1) { 3673e12c5d1SDavid du Colombier p->optab = a1+1; 3683e12c5d1SDavid du Colombier return optab+a1; 3693e12c5d1SDavid du Colombier } 3703e12c5d1SDavid du Colombier o = oprange[r].stop; /* just generate an error */ 3713e12c5d1SDavid du Colombier } 3723e12c5d1SDavid du Colombier e = oprange[r].stop; 3733e12c5d1SDavid du Colombier c1 = xcmp[a1]; 3743e12c5d1SDavid du Colombier c3 = xcmp[a3]; 3753e12c5d1SDavid du Colombier for(; o<e; o++) 3763e12c5d1SDavid du Colombier if(o->a2 == a2) 3773e12c5d1SDavid du Colombier if(c1[o->a1]) 3783e12c5d1SDavid du Colombier if(c3[o->a3]) { 3793e12c5d1SDavid du Colombier p->optab = (o-optab)+1; 3803e12c5d1SDavid du Colombier return o; 3813e12c5d1SDavid du Colombier } 3823e12c5d1SDavid du Colombier diag("illegal combination %A %d %d %d\n", 3833e12c5d1SDavid du Colombier p->as, a1, a2, a3); 3843e12c5d1SDavid du Colombier if(!debug['a']) 3853e12c5d1SDavid du Colombier prasm(p); 3867dd7cddfSDavid du Colombier o = optab; 3877dd7cddfSDavid du Colombier p->optab = (o-optab)+1; 3883e12c5d1SDavid du Colombier return o; 3893e12c5d1SDavid du Colombier } 3903e12c5d1SDavid du Colombier 3913e12c5d1SDavid du Colombier int 3923e12c5d1SDavid du Colombier cmp(int a, int b) 3933e12c5d1SDavid du Colombier { 3943e12c5d1SDavid du Colombier 3953e12c5d1SDavid du Colombier if(a == b) 3963e12c5d1SDavid du Colombier return 1; 3973e12c5d1SDavid du Colombier switch(a) { 3983e12c5d1SDavid du Colombier case C_LCON: 3993e12c5d1SDavid du Colombier if(b == C_ZCON || b == C_SCON || b == C_UCON || 4003e12c5d1SDavid du Colombier b == C_ADDCON || b == C_ANDCON) 4013e12c5d1SDavid du Colombier return 1; 4023e12c5d1SDavid du Colombier break; 4033e12c5d1SDavid du Colombier case C_ADD0CON: 4043e12c5d1SDavid du Colombier if(b == C_ADDCON) 4053e12c5d1SDavid du Colombier return 1; 4063e12c5d1SDavid du Colombier case C_ADDCON: 4073e12c5d1SDavid du Colombier if(b == C_ZCON || b == C_SCON) 4083e12c5d1SDavid du Colombier return 1; 4093e12c5d1SDavid du Colombier break; 4103e12c5d1SDavid du Colombier case C_AND0CON: 4113e12c5d1SDavid du Colombier if(b == C_ANDCON) 4123e12c5d1SDavid du Colombier return 1; 4133e12c5d1SDavid du Colombier case C_ANDCON: 4143e12c5d1SDavid du Colombier if(b == C_ZCON || b == C_SCON) 4153e12c5d1SDavid du Colombier return 1; 4163e12c5d1SDavid du Colombier break; 4173e12c5d1SDavid du Colombier case C_UCON: 4183e12c5d1SDavid du Colombier if(b == C_ZCON) 4193e12c5d1SDavid du Colombier return 1; 4203e12c5d1SDavid du Colombier break; 4213e12c5d1SDavid du Colombier case C_SCON: 4223e12c5d1SDavid du Colombier if(b == C_ZCON) 4233e12c5d1SDavid du Colombier return 1; 4243e12c5d1SDavid du Colombier break; 4253e12c5d1SDavid du Colombier case C_LACON: 4263e12c5d1SDavid du Colombier if(b == C_SACON) 4273e12c5d1SDavid du Colombier return 1; 4283e12c5d1SDavid du Colombier break; 4293e12c5d1SDavid du Colombier case C_LBRA: 4303e12c5d1SDavid du Colombier if(b == C_SBRA) 4313e12c5d1SDavid du Colombier return 1; 4323e12c5d1SDavid du Colombier break; 4333e12c5d1SDavid du Colombier case C_LEXT: 4343e12c5d1SDavid du Colombier if(b == C_SEXT) 4353e12c5d1SDavid du Colombier return 1; 4363e12c5d1SDavid du Colombier break; 4373e12c5d1SDavid du Colombier case C_LAUTO: 4383e12c5d1SDavid du Colombier if(b == C_SAUTO) 4393e12c5d1SDavid du Colombier return 1; 4403e12c5d1SDavid du Colombier break; 4413e12c5d1SDavid du Colombier case C_REG: 4423e12c5d1SDavid du Colombier if(b == C_ZCON) 4433e12c5d1SDavid du Colombier return 1; 4443e12c5d1SDavid du Colombier break; 4453e12c5d1SDavid du Colombier case C_LOREG: 4463e12c5d1SDavid du Colombier if(b == C_ZOREG || b == C_SOREG) 4473e12c5d1SDavid du Colombier return 1; 4483e12c5d1SDavid du Colombier break; 4493e12c5d1SDavid du Colombier case C_SOREG: 4503e12c5d1SDavid du Colombier if(b == C_ZOREG) 4513e12c5d1SDavid du Colombier return 1; 4523e12c5d1SDavid du Colombier break; 4533e12c5d1SDavid du Colombier } 4543e12c5d1SDavid du Colombier return 0; 4553e12c5d1SDavid du Colombier } 4563e12c5d1SDavid du Colombier 4573e12c5d1SDavid du Colombier int 4587dd7cddfSDavid du Colombier ocmp(const void *a1, const void *a2) 4593e12c5d1SDavid du Colombier { 4603e12c5d1SDavid du Colombier Optab *p1, *p2; 4613e12c5d1SDavid du Colombier int n; 4623e12c5d1SDavid du Colombier 4637dd7cddfSDavid du Colombier p1 = (Optab*)a1; 4647dd7cddfSDavid du Colombier p2 = (Optab*)a2; 4653e12c5d1SDavid du Colombier n = p1->as - p2->as; 4663e12c5d1SDavid du Colombier if(n) 4673e12c5d1SDavid du Colombier return n; 4683e12c5d1SDavid du Colombier n = p1->a1 - p2->a1; 4693e12c5d1SDavid du Colombier if(n) 4703e12c5d1SDavid du Colombier return n; 4713e12c5d1SDavid du Colombier n = p1->a2 - p2->a2; 4723e12c5d1SDavid du Colombier if(n) 4733e12c5d1SDavid du Colombier return n; 4743e12c5d1SDavid du Colombier n = p1->a3 - p2->a3; 4753e12c5d1SDavid du Colombier if(n) 4763e12c5d1SDavid du Colombier return n; 4773e12c5d1SDavid du Colombier return 0; 4783e12c5d1SDavid du Colombier } 4793e12c5d1SDavid du Colombier 4803e12c5d1SDavid du Colombier void 4813e12c5d1SDavid du Colombier buildop(void) 4823e12c5d1SDavid du Colombier { 4833e12c5d1SDavid du Colombier int i, n, r; 4843e12c5d1SDavid du Colombier 4853e12c5d1SDavid du Colombier for(i=0; i<32; i++) 4863e12c5d1SDavid du Colombier for(n=0; n<32; n++) 4873e12c5d1SDavid du Colombier xcmp[i][n] = cmp(n, i); 4883e12c5d1SDavid du Colombier for(n=0; optab[n].as != AXXX; n++) 4893e12c5d1SDavid du Colombier ; 4903e12c5d1SDavid du Colombier qsort(optab, n, sizeof(optab[0]), ocmp); 4913e12c5d1SDavid du Colombier for(i=0; i<n; i++) { 4923e12c5d1SDavid du Colombier r = optab[i].as; 4933e12c5d1SDavid du Colombier oprange[r].start = optab+i; 4943e12c5d1SDavid du Colombier while(optab[i].as == r) 4953e12c5d1SDavid du Colombier i++; 4963e12c5d1SDavid du Colombier oprange[r].stop = optab+i; 4973e12c5d1SDavid du Colombier i--; 4983e12c5d1SDavid du Colombier 4993e12c5d1SDavid du Colombier switch(r) 5003e12c5d1SDavid du Colombier { 5013e12c5d1SDavid du Colombier default: 5023e12c5d1SDavid du Colombier diag("unknown op in build: %A\n", r); 5033e12c5d1SDavid du Colombier errorexit(); 5043e12c5d1SDavid du Colombier case AABSF: 5053e12c5d1SDavid du Colombier oprange[AMOVFD] = oprange[r]; 5063e12c5d1SDavid du Colombier oprange[AMOVDF] = oprange[r]; 5073e12c5d1SDavid du Colombier oprange[AMOVWF] = oprange[r]; 5083e12c5d1SDavid du Colombier oprange[AMOVFW] = oprange[r]; 5093e12c5d1SDavid du Colombier oprange[AMOVWD] = oprange[r]; 5103e12c5d1SDavid du Colombier oprange[AMOVDW] = oprange[r]; 5113e12c5d1SDavid du Colombier oprange[ANEGF] = oprange[r]; 5123e12c5d1SDavid du Colombier oprange[ANEGD] = oprange[r]; 5133e12c5d1SDavid du Colombier oprange[AABSD] = oprange[r]; 5143e12c5d1SDavid du Colombier break; 5153e12c5d1SDavid du Colombier case AADD: 5163e12c5d1SDavid du Colombier buildrep(1, AADD); 5173e12c5d1SDavid du Colombier oprange[ASGT] = oprange[r]; 5183e12c5d1SDavid du Colombier repop[ASGT] = 1; 5193e12c5d1SDavid du Colombier oprange[ASGTU] = oprange[r]; 5203e12c5d1SDavid du Colombier repop[ASGTU] = 1; 5213e12c5d1SDavid du Colombier oprange[AADDU] = oprange[r]; 5223e12c5d1SDavid du Colombier repop[AADDU] = 1; 5237dd7cddfSDavid du Colombier oprange[AADDVU] = oprange[r]; 5247dd7cddfSDavid du Colombier repop[AADDVU] = 1; 5253e12c5d1SDavid du Colombier break; 5263e12c5d1SDavid du Colombier case AADDF: 5273e12c5d1SDavid du Colombier oprange[ADIVF] = oprange[r]; 5283e12c5d1SDavid du Colombier oprange[ADIVD] = oprange[r]; 5293e12c5d1SDavid du Colombier oprange[AMULF] = oprange[r]; 5303e12c5d1SDavid du Colombier oprange[AMULD] = oprange[r]; 5313e12c5d1SDavid du Colombier oprange[ASUBF] = oprange[r]; 5323e12c5d1SDavid du Colombier oprange[ASUBD] = oprange[r]; 5333e12c5d1SDavid du Colombier oprange[AADDD] = oprange[r]; 5343e12c5d1SDavid du Colombier break; 5353e12c5d1SDavid du Colombier case AAND: 5363e12c5d1SDavid du Colombier buildrep(2, AAND); 5373e12c5d1SDavid du Colombier oprange[AXOR] = oprange[r]; 5383e12c5d1SDavid du Colombier repop[AXOR] = 2; 5393e12c5d1SDavid du Colombier oprange[AOR] = oprange[r]; 5403e12c5d1SDavid du Colombier repop[AOR] = 2; 5413e12c5d1SDavid du Colombier break; 5423e12c5d1SDavid du Colombier case ABEQ: 5433e12c5d1SDavid du Colombier oprange[ABNE] = oprange[r]; 5443e12c5d1SDavid du Colombier break; 5453e12c5d1SDavid du Colombier case ABLEZ: 5463e12c5d1SDavid du Colombier oprange[ABGEZ] = oprange[r]; 5473e12c5d1SDavid du Colombier oprange[ABGEZAL] = oprange[r]; 5483e12c5d1SDavid du Colombier oprange[ABLTZ] = oprange[r]; 5493e12c5d1SDavid du Colombier oprange[ABLTZAL] = oprange[r]; 5503e12c5d1SDavid du Colombier oprange[ABGTZ] = oprange[r]; 5513e12c5d1SDavid du Colombier break; 5523e12c5d1SDavid du Colombier case AMOVB: 5533e12c5d1SDavid du Colombier buildrep(3, AMOVB); 5543e12c5d1SDavid du Colombier oprange[AMOVH] = oprange[r]; 5553e12c5d1SDavid du Colombier repop[AMOVH] = 3; 5563e12c5d1SDavid du Colombier break; 5573e12c5d1SDavid du Colombier case AMOVBU: 5583e12c5d1SDavid du Colombier buildrep(4, AMOVBU); 5593e12c5d1SDavid du Colombier oprange[AMOVHU] = oprange[r]; 5603e12c5d1SDavid du Colombier repop[AMOVHU] = 4; 5613e12c5d1SDavid du Colombier break; 5623e12c5d1SDavid du Colombier case AMUL: 5633e12c5d1SDavid du Colombier oprange[AREM] = oprange[r]; 5643e12c5d1SDavid du Colombier oprange[AREMU] = oprange[r]; 5653e12c5d1SDavid du Colombier oprange[ADIVU] = oprange[r]; 5663e12c5d1SDavid du Colombier oprange[AMULU] = oprange[r]; 5673e12c5d1SDavid du Colombier oprange[ADIV] = oprange[r]; 5687dd7cddfSDavid du Colombier oprange[ADIVVU] = oprange[r]; 5697dd7cddfSDavid du Colombier oprange[ADIVV] = oprange[r]; 5703e12c5d1SDavid du Colombier break; 5713e12c5d1SDavid du Colombier case ASLL: 5723e12c5d1SDavid du Colombier oprange[ASRL] = oprange[r]; 5733e12c5d1SDavid du Colombier oprange[ASRA] = oprange[r]; 574219b2ee8SDavid du Colombier oprange[ASLLV] = oprange[r]; 575219b2ee8SDavid du Colombier oprange[ASRAV] = oprange[r]; 576219b2ee8SDavid du Colombier oprange[ASRLV] = oprange[r]; 5773e12c5d1SDavid du Colombier break; 5783e12c5d1SDavid du Colombier case ASUB: 5793e12c5d1SDavid du Colombier oprange[ASUBU] = oprange[r]; 5803e12c5d1SDavid du Colombier oprange[ANOR] = oprange[r]; 5813e12c5d1SDavid du Colombier break; 5823e12c5d1SDavid du Colombier case ASYSCALL: 5833e12c5d1SDavid du Colombier oprange[ATLBP] = oprange[r]; 5843e12c5d1SDavid du Colombier oprange[ATLBR] = oprange[r]; 5853e12c5d1SDavid du Colombier oprange[ATLBWI] = oprange[r]; 5863e12c5d1SDavid du Colombier oprange[ATLBWR] = oprange[r]; 5873e12c5d1SDavid du Colombier break; 5883e12c5d1SDavid du Colombier case ACMPEQF: 5893e12c5d1SDavid du Colombier oprange[ACMPGTF] = oprange[r]; 5903e12c5d1SDavid du Colombier oprange[ACMPGTD] = oprange[r]; 5913e12c5d1SDavid du Colombier oprange[ACMPGEF] = oprange[r]; 5923e12c5d1SDavid du Colombier oprange[ACMPGED] = oprange[r]; 5933e12c5d1SDavid du Colombier oprange[ACMPEQD] = oprange[r]; 5943e12c5d1SDavid du Colombier break; 5953e12c5d1SDavid du Colombier case ABFPT: 5963e12c5d1SDavid du Colombier oprange[ABFPF] = oprange[r]; 5973e12c5d1SDavid du Colombier break; 5983e12c5d1SDavid du Colombier case AMOVWL: 5993e12c5d1SDavid du Colombier oprange[AMOVWR] = oprange[r]; 600219b2ee8SDavid du Colombier oprange[AMOVVR] = oprange[r]; 601219b2ee8SDavid du Colombier oprange[AMOVVL] = oprange[r]; 6023e12c5d1SDavid du Colombier break; 6033e12c5d1SDavid du Colombier case AMOVW: 6047dd7cddfSDavid du Colombier buildrep(5, AMOVW); 6053e12c5d1SDavid du Colombier break; 6063e12c5d1SDavid du Colombier case AMOVD: 6077dd7cddfSDavid du Colombier buildrep(6, AMOVD); 6083e12c5d1SDavid du Colombier break; 6093e12c5d1SDavid du Colombier case AMOVF: 6107dd7cddfSDavid du Colombier buildrep(7, AMOVF); 6113e12c5d1SDavid du Colombier break; 612219b2ee8SDavid du Colombier case AMOVV: 6137dd7cddfSDavid du Colombier buildrep(8, AMOVV); 614219b2ee8SDavid du Colombier break; 615bd389b36SDavid du Colombier case ABREAK: 6163e12c5d1SDavid du Colombier case AWORD: 6173e12c5d1SDavid du Colombier case ARFE: 6183e12c5d1SDavid du Colombier case AJAL: 6193e12c5d1SDavid du Colombier case AJMP: 6203e12c5d1SDavid du Colombier case ATEXT: 6217dd7cddfSDavid du Colombier case ACASE: 6227dd7cddfSDavid du Colombier case ABCASE: 6233e12c5d1SDavid du Colombier break; 6243e12c5d1SDavid du Colombier } 6253e12c5d1SDavid du Colombier } 6263e12c5d1SDavid du Colombier } 6273e12c5d1SDavid du Colombier 6283e12c5d1SDavid du Colombier void 6293e12c5d1SDavid du Colombier buildrep(int x, int as) 6303e12c5d1SDavid du Colombier { 6313e12c5d1SDavid du Colombier Opcross *p; 6323e12c5d1SDavid du Colombier Optab *e, *s, *o; 6333e12c5d1SDavid du Colombier int a1, a2, a3, n; 6343e12c5d1SDavid du Colombier 635219b2ee8SDavid du Colombier if(C_NONE != 0 || C_REG != 1 || C_GOK >= 32 || x >= nelem(opcross)) { 6363e12c5d1SDavid du Colombier diag("assumptions fail in buildrep"); 6373e12c5d1SDavid du Colombier errorexit(); 6383e12c5d1SDavid du Colombier } 6393e12c5d1SDavid du Colombier repop[as] = x; 6403e12c5d1SDavid du Colombier p = (opcross + x); 6413e12c5d1SDavid du Colombier s = oprange[as].start; 6423e12c5d1SDavid du Colombier e = oprange[as].stop; 6433e12c5d1SDavid du Colombier for(o=e-1; o>=s; o--) { 6443e12c5d1SDavid du Colombier n = o-optab; 6453e12c5d1SDavid du Colombier for(a2=0; a2<2; a2++) { 6463e12c5d1SDavid du Colombier if(a2) { 6473e12c5d1SDavid du Colombier if(o->a2 == C_NONE) 6483e12c5d1SDavid du Colombier continue; 6493e12c5d1SDavid du Colombier } else 6503e12c5d1SDavid du Colombier if(o->a2 != C_NONE) 6513e12c5d1SDavid du Colombier continue; 6523e12c5d1SDavid du Colombier for(a1=0; a1<32; a1++) { 6533e12c5d1SDavid du Colombier if(!xcmp[a1][o->a1]) 6543e12c5d1SDavid du Colombier continue; 6553e12c5d1SDavid du Colombier for(a3=0; a3<32; a3++) 6563e12c5d1SDavid du Colombier if(xcmp[a3][o->a3]) 6573e12c5d1SDavid du Colombier (*p)[a1][a2][a3] = n; 6583e12c5d1SDavid du Colombier } 6593e12c5d1SDavid du Colombier } 6603e12c5d1SDavid du Colombier } 6613e12c5d1SDavid du Colombier oprange[as].start = 0; 6623e12c5d1SDavid du Colombier } 663