13e12c5d1SDavid du Colombier #include "l.h" 23e12c5d1SDavid du Colombier 33305c317SDavid du Colombier /* can't include a.out.h due to name clashes, but these are taken from it */ 43305c317SDavid du Colombier #define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7)) 53305c317SDavid du Colombier #define V_MAGIC _MAGIC(0, 16) /* mips 3000 BE */ 63305c317SDavid du Colombier #define M_MAGIC _MAGIC(0, 18) /* mips 4000 BE */ 73305c317SDavid du Colombier #define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */ 83305c317SDavid du Colombier #define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */ 93305c317SDavid du Colombier 10bd389b36SDavid du Colombier long OFFSET; 11bd389b36SDavid du Colombier /* 12bd389b36SDavid du Colombier long BADOFFSET = -1; 13bd389b36SDavid du Colombier 14bd389b36SDavid du Colombier if(OFFSET <= BADOFFSET && OFFSET+4 > BADOFFSET)\ 15bd389b36SDavid du Colombier abort();\ 16bd389b36SDavid du Colombier OFFSET += 4;\ 17bd389b36SDavid du Colombier 18bd389b36SDavid du Colombier if(OFFSET == BADOFFSET)\ 19bd389b36SDavid du Colombier abort();\ 20bd389b36SDavid du Colombier OFFSET++;\ 21bd389b36SDavid du Colombier */ 22bd389b36SDavid du Colombier 2391178603SDavid du Colombier #define LPUT(l) { \ 2491178603SDavid du Colombier if (little) { \ 2591178603SDavid du Colombier LLEPUT(l); \ 2691178603SDavid du Colombier } else { \ 2791178603SDavid du Colombier LBEPUT(l); \ 2891178603SDavid du Colombier } \ 2991178603SDavid du Colombier } 3091178603SDavid du Colombier 3191178603SDavid du Colombier #define LLEPUT(c)\ 3291178603SDavid du Colombier {\ 3391178603SDavid du Colombier cbp[0] = (c);\ 3491178603SDavid du Colombier cbp[1] = (c)>>8;\ 3591178603SDavid du Colombier cbp[2] = (c)>>16;\ 3691178603SDavid du Colombier cbp[3] = (c)>>24;\ 3791178603SDavid du Colombier cbp += 4;\ 3891178603SDavid du Colombier cbc -= 4;\ 3991178603SDavid du Colombier if(cbc <= 0)\ 4091178603SDavid du Colombier cflush();\ 4191178603SDavid du Colombier } 4291178603SDavid du Colombier 4391178603SDavid du Colombier #define LBEPUT(c)\ 443e12c5d1SDavid du Colombier {\ 453e12c5d1SDavid du Colombier cbp[0] = (c)>>24;\ 463e12c5d1SDavid du Colombier cbp[1] = (c)>>16;\ 473e12c5d1SDavid du Colombier cbp[2] = (c)>>8;\ 483e12c5d1SDavid du Colombier cbp[3] = (c);\ 493e12c5d1SDavid du Colombier cbp += 4;\ 503e12c5d1SDavid du Colombier cbc -= 4;\ 513e12c5d1SDavid du Colombier if(cbc <= 0)\ 523e12c5d1SDavid du Colombier cflush();\ 533e12c5d1SDavid du Colombier } 543e12c5d1SDavid du Colombier 55bfb6eab9SDavid du Colombier #define HPUT(h) { \ 56bfb6eab9SDavid du Colombier if (little) { \ 57bfb6eab9SDavid du Colombier HLEPUT(h); \ 58bfb6eab9SDavid du Colombier } else { \ 59bfb6eab9SDavid du Colombier HBEPUT(h); \ 60bfb6eab9SDavid du Colombier } \ 61bfb6eab9SDavid du Colombier } 62bfb6eab9SDavid du Colombier 63bfb6eab9SDavid du Colombier #define HLEPUT(c)\ 64bfb6eab9SDavid du Colombier {\ 65bfb6eab9SDavid du Colombier cbp[0] = (c);\ 66bfb6eab9SDavid du Colombier cbp[1] = (c)>>8;\ 67bfb6eab9SDavid du Colombier cbp += 2;\ 68bfb6eab9SDavid du Colombier cbc -= 2;\ 69bfb6eab9SDavid du Colombier if(cbc <= 0)\ 70bfb6eab9SDavid du Colombier cflush();\ 71bfb6eab9SDavid du Colombier } 72bfb6eab9SDavid du Colombier 73bfb6eab9SDavid du Colombier #define HBEPUT(c)\ 74bfb6eab9SDavid du Colombier {\ 75bfb6eab9SDavid du Colombier cbp[0] = (c)>>8;\ 76bfb6eab9SDavid du Colombier cbp[1] = (c);\ 77bfb6eab9SDavid du Colombier cbp += 2;\ 78bfb6eab9SDavid du Colombier cbc -= 2;\ 79bfb6eab9SDavid du Colombier if(cbc <= 0)\ 80bfb6eab9SDavid du Colombier cflush();\ 81bfb6eab9SDavid du Colombier } 82bfb6eab9SDavid du Colombier 8391178603SDavid du Colombier 843e12c5d1SDavid du Colombier #define CPUT(c)\ 853e12c5d1SDavid du Colombier {\ 863e12c5d1SDavid du Colombier cbp[0] = (c);\ 873e12c5d1SDavid du Colombier cbp++;\ 883e12c5d1SDavid du Colombier cbc--;\ 893e12c5d1SDavid du Colombier if(cbc <= 0)\ 903e12c5d1SDavid du Colombier cflush();\ 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier 9391178603SDavid du Colombier void 948153b942SDavid du Colombier cput(long l) 958153b942SDavid du Colombier { 968153b942SDavid du Colombier CPUT(l); 978153b942SDavid du Colombier } 988153b942SDavid du Colombier 998153b942SDavid du Colombier void 10091178603SDavid du Colombier objput(long l) /* emit long in byte order appropriate to object machine */ 10191178603SDavid du Colombier { 10291178603SDavid du Colombier LPUT(l); 10391178603SDavid du Colombier } 10491178603SDavid du Colombier 10591178603SDavid du Colombier void 106bfb6eab9SDavid du Colombier objhput(short s) 107bfb6eab9SDavid du Colombier { 108bfb6eab9SDavid du Colombier HPUT(s); 109bfb6eab9SDavid du Colombier } 110bfb6eab9SDavid du Colombier 111bfb6eab9SDavid du Colombier void 1128153b942SDavid du Colombier wput(long l) 1138153b942SDavid du Colombier { 1148153b942SDavid du Colombier 1158153b942SDavid du Colombier cbp[0] = l>>8; 1168153b942SDavid du Colombier cbp[1] = l; 1178153b942SDavid du Colombier cbp += 2; 1188153b942SDavid du Colombier cbc -= 2; 1198153b942SDavid du Colombier if(cbc <= 0) 1208153b942SDavid du Colombier cflush(); 1218153b942SDavid du Colombier } 1228153b942SDavid du Colombier 1238153b942SDavid du Colombier void 1248153b942SDavid du Colombier wputl(long l) 1258153b942SDavid du Colombier { 1268153b942SDavid du Colombier 1278153b942SDavid du Colombier cbp[0] = l; 1288153b942SDavid du Colombier cbp[1] = l>>8; 1298153b942SDavid du Colombier cbp += 2; 1308153b942SDavid du Colombier cbc -= 2; 1318153b942SDavid du Colombier if(cbc <= 0) 1328153b942SDavid du Colombier cflush(); 1338153b942SDavid du Colombier } 1348153b942SDavid du Colombier 1358153b942SDavid du Colombier void 13691178603SDavid du Colombier lput(long l) /* emit long in big-endian byte order */ 13791178603SDavid du Colombier { 13891178603SDavid du Colombier LBEPUT(l); 13991178603SDavid du Colombier } 14091178603SDavid du Colombier 1418153b942SDavid du Colombier void 1428153b942SDavid du Colombier lputl(long l) /* emit long in big-endian byte order */ 1438153b942SDavid du Colombier { 1448153b942SDavid du Colombier LLEPUT(l); 1458153b942SDavid du Colombier } 1468153b942SDavid du Colombier 1478153b942SDavid du Colombier void 1488153b942SDavid du Colombier llput(vlong v) 1498153b942SDavid du Colombier { 1508153b942SDavid du Colombier lput(v>>32); 1518153b942SDavid du Colombier lput(v); 1528153b942SDavid du Colombier } 1538153b942SDavid du Colombier 1548153b942SDavid du Colombier void 1558153b942SDavid du Colombier llputl(vlong v) 1568153b942SDavid du Colombier { 1578153b942SDavid du Colombier lputl(v); 1588153b942SDavid du Colombier lputl(v>>32); 1598153b942SDavid du Colombier } 1608153b942SDavid du Colombier 1613e12c5d1SDavid du Colombier long 1623e12c5d1SDavid du Colombier entryvalue(void) 1633e12c5d1SDavid du Colombier { 1643e12c5d1SDavid du Colombier char *a; 1653e12c5d1SDavid du Colombier Sym *s; 1663e12c5d1SDavid du Colombier 1673e12c5d1SDavid du Colombier a = INITENTRY; 1683e12c5d1SDavid du Colombier if(*a >= '0' && *a <= '9') 1693e12c5d1SDavid du Colombier return atolwhex(a); 1703e12c5d1SDavid du Colombier s = lookup(a, 0); 1713e12c5d1SDavid du Colombier if(s->type == 0) 1723e12c5d1SDavid du Colombier return INITTEXT; 1733e12c5d1SDavid du Colombier if(s->type != STEXT && s->type != SLEAF) 1743e12c5d1SDavid du Colombier diag("entry not text: %s", s->name); 1753e12c5d1SDavid du Colombier return s->value; 1763e12c5d1SDavid du Colombier } 1773e12c5d1SDavid du Colombier 178*5482313dSDavid du Colombier static void 179*5482313dSDavid du Colombier plan9bootimage(ulong sects, ulong submagicvers, ulong tm, 180*5482313dSDavid du Colombier ulong hdrtxtsz, ulong textsz, ulong textva, ulong lcsize) 181*5482313dSDavid du Colombier { 182*5482313dSDavid du Colombier lput(0x160L<<16|sects); /* magic and sections */ 183*5482313dSDavid du Colombier lput(tm); /* time and date */ 184*5482313dSDavid du Colombier lput(hdrtxtsz+datsize); /* offset to symbol table */ 185*5482313dSDavid du Colombier lput(symsize); /* size of symbol table */ 186*5482313dSDavid du Colombier lput((0x38L<<16)|7L); /* size of optional hdr and flags */ 187*5482313dSDavid du Colombier lput(submagicvers); /* magic and version */ 188*5482313dSDavid du Colombier 189*5482313dSDavid du Colombier lput(textsz); /* segment sizes */ 190*5482313dSDavid du Colombier lput(datsize); 191*5482313dSDavid du Colombier lput(bsssize); 192*5482313dSDavid du Colombier 193*5482313dSDavid du Colombier lput(entryvalue()); /* va of entry */ 194*5482313dSDavid du Colombier lput(textva); /* va of base of text */ 195*5482313dSDavid du Colombier lput(INITDAT); /* va of base of data */ 196*5482313dSDavid du Colombier lput(INITDAT+datsize); /* va of base of bss */ 197*5482313dSDavid du Colombier 198*5482313dSDavid du Colombier lput(~0); /* gp reg mask */ 199*5482313dSDavid du Colombier lput(lcsize); /* pcsize / cprmask[0] */ 200*5482313dSDavid du Colombier lput(0); /* coproc reg masks[1⋯3] */ 201*5482313dSDavid du Colombier lput(0); 202*5482313dSDavid du Colombier lput(0); 203*5482313dSDavid du Colombier lput(~0); /* gp value ?? */ 204*5482313dSDavid du Colombier } 205*5482313dSDavid du Colombier 206*5482313dSDavid du Colombier static void 207*5482313dSDavid du Colombier symhdrs(ulong hdrtxtsz) 208*5482313dSDavid du Colombier { 209*5482313dSDavid du Colombier strnput(".text", 8); /* text segment */ 210*5482313dSDavid du Colombier lput(INITTEXT); /* address */ 211*5482313dSDavid du Colombier lput(INITTEXT); 212*5482313dSDavid du Colombier lput(textsize); 213*5482313dSDavid du Colombier lput(HEADR); 214*5482313dSDavid du Colombier lput(0); 215*5482313dSDavid du Colombier lput(HEADR+textsize+datsize+symsize); 216*5482313dSDavid du Colombier lput(lcsize); /* line number size */ 217*5482313dSDavid du Colombier lput(0x20); /* flags */ 218*5482313dSDavid du Colombier 219*5482313dSDavid du Colombier strnput(".data", 8); /* data segment */ 220*5482313dSDavid du Colombier lput(INITDAT); /* address */ 221*5482313dSDavid du Colombier lput(INITDAT); 222*5482313dSDavid du Colombier lput(datsize); 223*5482313dSDavid du Colombier lput(hdrtxtsz); 224*5482313dSDavid du Colombier lput(0); 225*5482313dSDavid du Colombier lput(0); 226*5482313dSDavid du Colombier lput(0); 227*5482313dSDavid du Colombier lput(0x40); /* flags */ 228*5482313dSDavid du Colombier 229*5482313dSDavid du Colombier strnput(".bss", 8); /* bss segment */ 230*5482313dSDavid du Colombier lput(INITDAT+datsize); /* address */ 231*5482313dSDavid du Colombier lput(INITDAT+datsize); 232*5482313dSDavid du Colombier lput(bsssize); 233*5482313dSDavid du Colombier lput(0); 234*5482313dSDavid du Colombier lput(0); 235*5482313dSDavid du Colombier lput(0); 236*5482313dSDavid du Colombier lput(0); 237*5482313dSDavid du Colombier lput(0x80); /* flags */ 238*5482313dSDavid du Colombier } 239*5482313dSDavid du Colombier 2403e12c5d1SDavid du Colombier void 2413e12c5d1SDavid du Colombier asmb(void) 2423e12c5d1SDavid du Colombier { 2433e12c5d1SDavid du Colombier Prog *p; 244*5482313dSDavid du Colombier long tm; 245*5482313dSDavid du Colombier ulong rndtxtsz; 246a587111cSDavid du Colombier vlong t, etext; 2473e12c5d1SDavid du Colombier Optab *o; 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier if(debug['v']) 2503e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f asm\n", cputime()); 2513e12c5d1SDavid du Colombier Bflush(&bso); 252bd389b36SDavid du Colombier OFFSET = HEADR; 253bd389b36SDavid du Colombier seek(cout, OFFSET, 0); 2543e12c5d1SDavid du Colombier pc = INITTEXT; 2553e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 2563e12c5d1SDavid du Colombier if(p->as == ATEXT) { 2573e12c5d1SDavid du Colombier curtext = p; 2583e12c5d1SDavid du Colombier autosize = p->to.offset + 4; 2593e12c5d1SDavid du Colombier } 2603e12c5d1SDavid du Colombier if(p->pc != pc) { 261a587111cSDavid du Colombier diag("phase error %llux sb %llux", p->pc, pc); 2623e12c5d1SDavid du Colombier if(!debug['a']) 2633e12c5d1SDavid du Colombier prasm(curp); 2643e12c5d1SDavid du Colombier pc = p->pc; 2653e12c5d1SDavid du Colombier } 2663e12c5d1SDavid du Colombier curp = p; 2673e12c5d1SDavid du Colombier o = oplook(p); /* could probably avoid this call */ 2683e12c5d1SDavid du Colombier if(asmout(p, o, 0)) { 2693e12c5d1SDavid du Colombier p = p->link; 2703e12c5d1SDavid du Colombier pc += 4; 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier pc += o->size; 2733e12c5d1SDavid du Colombier } 2743e12c5d1SDavid du Colombier if(debug['a']) 2753e12c5d1SDavid du Colombier Bprint(&bso, "\n"); 2763e12c5d1SDavid du Colombier Bflush(&bso); 2773e12c5d1SDavid du Colombier cflush(); 2783e12c5d1SDavid du Colombier 2799a747e4fSDavid du Colombier etext = INITTEXT + textsize; 2809a747e4fSDavid du Colombier for(t = pc; t < etext; t += sizeof(buf)-100) { 2819a747e4fSDavid du Colombier if(etext-t > sizeof(buf)-100) 2829a747e4fSDavid du Colombier datblk(t, sizeof(buf)-100, 1); 2839a747e4fSDavid du Colombier else 2849a747e4fSDavid du Colombier datblk(t, etext-t, 1); 2859a747e4fSDavid du Colombier } 2869a747e4fSDavid du Colombier 2879a747e4fSDavid du Colombier Bflush(&bso); 2889a747e4fSDavid du Colombier cflush(); 2899a747e4fSDavid du Colombier 2903e12c5d1SDavid du Colombier curtext = P; 2913e12c5d1SDavid du Colombier switch(HEADTYPE) { 2923e12c5d1SDavid du Colombier case 0: 293219b2ee8SDavid du Colombier case 4: 294bd389b36SDavid du Colombier OFFSET = rnd(HEADR+textsize, 4096); 295bd389b36SDavid du Colombier seek(cout, OFFSET, 0); 2963e12c5d1SDavid du Colombier break; 2973e12c5d1SDavid du Colombier case 1: 2983e12c5d1SDavid du Colombier case 2: 299219b2ee8SDavid du Colombier case 3: 300219b2ee8SDavid du Colombier case 5: 30191178603SDavid du Colombier case 6: 302bd389b36SDavid du Colombier OFFSET = HEADR+textsize; 303bd389b36SDavid du Colombier seek(cout, OFFSET, 0); 3043e12c5d1SDavid du Colombier break; 3053e12c5d1SDavid du Colombier } 3063e12c5d1SDavid du Colombier for(t = 0; t < datsize; t += sizeof(buf)-100) { 3073e12c5d1SDavid du Colombier if(datsize-t > sizeof(buf)-100) 3089a747e4fSDavid du Colombier datblk(t, sizeof(buf)-100, 0); 3093e12c5d1SDavid du Colombier else 3109a747e4fSDavid du Colombier datblk(t, datsize-t, 0); 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier symsize = 0; 3143e12c5d1SDavid du Colombier lcsize = 0; 3153e12c5d1SDavid du Colombier if(!debug['s']) { 3163e12c5d1SDavid du Colombier if(debug['v']) 3173e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f sym\n", cputime()); 3183e12c5d1SDavid du Colombier Bflush(&bso); 3193e12c5d1SDavid du Colombier switch(HEADTYPE) { 3203e12c5d1SDavid du Colombier case 0: 321219b2ee8SDavid du Colombier case 4: 322bd389b36SDavid du Colombier OFFSET = rnd(HEADR+textsize, 4096)+datsize; 323bd389b36SDavid du Colombier seek(cout, OFFSET, 0); 3243e12c5d1SDavid du Colombier break; 325219b2ee8SDavid du Colombier case 3: 3263e12c5d1SDavid du Colombier case 2: 3273e12c5d1SDavid du Colombier case 1: 328219b2ee8SDavid du Colombier case 5: 32991178603SDavid du Colombier case 6: 330bd389b36SDavid du Colombier OFFSET = HEADR+textsize+datsize; 331bd389b36SDavid du Colombier seek(cout, OFFSET, 0); 3323e12c5d1SDavid du Colombier break; 3333e12c5d1SDavid du Colombier } 3343e12c5d1SDavid du Colombier if(!debug['s']) 3353e12c5d1SDavid du Colombier asmsym(); 3363e12c5d1SDavid du Colombier if(debug['v']) 3373e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f pc\n", cputime()); 3383e12c5d1SDavid du Colombier Bflush(&bso); 3393e12c5d1SDavid du Colombier if(!debug['s']) 3403e12c5d1SDavid du Colombier asmlc(); 3413e12c5d1SDavid du Colombier cflush(); 3423e12c5d1SDavid du Colombier } 3433e12c5d1SDavid du Colombier 3443e12c5d1SDavid du Colombier if(debug['v']) 3453e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f header\n", cputime()); 3463e12c5d1SDavid du Colombier Bflush(&bso); 347bd389b36SDavid du Colombier OFFSET = 0; 348bd389b36SDavid du Colombier seek(cout, OFFSET, 0); 349*5482313dSDavid du Colombier 350*5482313dSDavid du Colombier rndtxtsz = rnd(HEADR+textsize, (INITRND > 0? INITRND: 4096)); 351*5482313dSDavid du Colombier tm = time(0); 3523e12c5d1SDavid du Colombier switch(HEADTYPE) { 3533e12c5d1SDavid du Colombier case 0: 354*5482313dSDavid du Colombier /* 0413: plan 9 boot image, text segment rounded (to 4KB) */ 355*5482313dSDavid du Colombier plan9bootimage(0, 0413<<16|0437, 0, rndtxtsz, rndtxtsz, 356*5482313dSDavid du Colombier INITTEXT-HEADR, 0); 3573e12c5d1SDavid du Colombier break; 3583e12c5d1SDavid du Colombier case 1: 359*5482313dSDavid du Colombier /* 0407: plan 9 boot image, extra word */ 360*5482313dSDavid du Colombier plan9bootimage(0, 0407<<16|0437, 0, HEADR+textsize, textsize, 361*5482313dSDavid du Colombier INITTEXT, lcsize); 362*5482313dSDavid du Colombier lput(0); /* extra; complete mystery */ 3633e12c5d1SDavid du Colombier break; 3643305c317SDavid du Colombier case 2: /* plan 9 format */ 36591178603SDavid du Colombier if (little) 3663305c317SDavid du Colombier lput(P_MAGIC); /* mips 3000 LE */ 36791178603SDavid du Colombier else 3683305c317SDavid du Colombier lput(V_MAGIC); /* mips 3000 BE */ 3693e12c5d1SDavid du Colombier lput(textsize); /* sizes */ 3703e12c5d1SDavid du Colombier lput(datsize); 3713e12c5d1SDavid du Colombier lput(bsssize); 3723e12c5d1SDavid du Colombier lput(symsize); /* nsyms */ 3733e12c5d1SDavid du Colombier lput(entryvalue()); /* va of entry */ 3743e12c5d1SDavid du Colombier lput(0L); 3753e12c5d1SDavid du Colombier lput(lcsize); 3763e12c5d1SDavid du Colombier break; 377219b2ee8SDavid du Colombier case 3: 378*5482313dSDavid du Colombier /* 0407: plan 9 mips 4k boot image with symbols */ 379*5482313dSDavid du Colombier plan9bootimage(3, 0407<<16|0437, tm, HEADR+textsize, textsize, 380*5482313dSDavid du Colombier INITTEXT, lcsize); 381*5482313dSDavid du Colombier symhdrs(HEADR+textsize); 382219b2ee8SDavid du Colombier break; 383219b2ee8SDavid du Colombier case 4: 384*5482313dSDavid du Colombier /* 0413: plan 9 mips 4k boot image with symbols */ 385*5482313dSDavid du Colombier plan9bootimage(3, 0413<<16|01012, tm, rndtxtsz, textsize, 386*5482313dSDavid du Colombier INITTEXT, lcsize); 387*5482313dSDavid du Colombier symhdrs(rndtxtsz); 388219b2ee8SDavid du Colombier break; 389219b2ee8SDavid du Colombier case 5: 3908153b942SDavid du Colombier elf32(MIPS, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil); 39191178603SDavid du Colombier break; 39291178603SDavid du Colombier case 6: 39391178603SDavid du Colombier break; 394a587111cSDavid du Colombier case 7: 395a587111cSDavid du Colombier elf64(MIPSR4K, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil); 396a587111cSDavid du Colombier break; 3973e12c5d1SDavid du Colombier } 3983e12c5d1SDavid du Colombier cflush(); 3993e12c5d1SDavid du Colombier } 4003e12c5d1SDavid du Colombier 4013e12c5d1SDavid du Colombier void 402219b2ee8SDavid du Colombier strnput(char *s, int n) 403219b2ee8SDavid du Colombier { 404219b2ee8SDavid du Colombier for(; *s; s++){ 405219b2ee8SDavid du Colombier CPUT(*s); 406219b2ee8SDavid du Colombier n--; 407219b2ee8SDavid du Colombier } 408219b2ee8SDavid du Colombier for(; n > 0; n--) 409219b2ee8SDavid du Colombier CPUT(0); 410219b2ee8SDavid du Colombier } 411219b2ee8SDavid du Colombier 412219b2ee8SDavid du Colombier void 4133e12c5d1SDavid du Colombier cflush(void) 4143e12c5d1SDavid du Colombier { 4153e12c5d1SDavid du Colombier int n; 4163e12c5d1SDavid du Colombier 4173e12c5d1SDavid du Colombier n = sizeof(buf.cbuf) - cbc; 4183e12c5d1SDavid du Colombier if(n) 4193e12c5d1SDavid du Colombier write(cout, buf.cbuf, n); 4203e12c5d1SDavid du Colombier cbp = buf.cbuf; 4213e12c5d1SDavid du Colombier cbc = sizeof(buf.cbuf); 4223e12c5d1SDavid du Colombier } 4233e12c5d1SDavid du Colombier 4243e12c5d1SDavid du Colombier void 425219b2ee8SDavid du Colombier nopstat(char *f, Count *c) 426219b2ee8SDavid du Colombier { 427219b2ee8SDavid du Colombier if(c->outof) 428219b2ee8SDavid du Colombier Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f, 429219b2ee8SDavid du Colombier c->outof - c->count, c->outof, 430219b2ee8SDavid du Colombier (double)(c->outof - c->count)/c->outof); 431219b2ee8SDavid du Colombier } 432219b2ee8SDavid du Colombier 433219b2ee8SDavid du Colombier void 4343e12c5d1SDavid du Colombier asmsym(void) 4353e12c5d1SDavid du Colombier { 4363e12c5d1SDavid du Colombier Prog *p; 4373e12c5d1SDavid du Colombier Auto *a; 4383e12c5d1SDavid du Colombier Sym *s; 4393e12c5d1SDavid du Colombier int h; 4403e12c5d1SDavid du Colombier 4413e12c5d1SDavid du Colombier s = lookup("etext", 0); 4423e12c5d1SDavid du Colombier if(s->type == STEXT) 4433e12c5d1SDavid du Colombier putsymb(s->name, 'T', s->value, s->version); 4443e12c5d1SDavid du Colombier 4453e12c5d1SDavid du Colombier for(h=0; h<NHASH; h++) 4463e12c5d1SDavid du Colombier for(s=hash[h]; s!=S; s=s->link) 4473e12c5d1SDavid du Colombier switch(s->type) { 448219b2ee8SDavid du Colombier case SCONST: 449219b2ee8SDavid du Colombier putsymb(s->name, 'D', s->value, s->version); 450219b2ee8SDavid du Colombier continue; 451219b2ee8SDavid du Colombier 4529a747e4fSDavid du Colombier case SSTRING: 4539a747e4fSDavid du Colombier putsymb(s->name, 'T', s->value, s->version); 4549a747e4fSDavid du Colombier continue; 4559a747e4fSDavid du Colombier 4563e12c5d1SDavid du Colombier case SDATA: 4573e12c5d1SDavid du Colombier putsymb(s->name, 'D', s->value+INITDAT, s->version); 4583e12c5d1SDavid du Colombier continue; 4593e12c5d1SDavid du Colombier 4603e12c5d1SDavid du Colombier case SBSS: 4613e12c5d1SDavid du Colombier putsymb(s->name, 'B', s->value+INITDAT, s->version); 4623e12c5d1SDavid du Colombier continue; 4633e12c5d1SDavid du Colombier 4643e12c5d1SDavid du Colombier case SFILE: 4653e12c5d1SDavid du Colombier putsymb(s->name, 'f', s->value, s->version); 4663e12c5d1SDavid du Colombier continue; 4673e12c5d1SDavid du Colombier } 4683e12c5d1SDavid du Colombier 4693e12c5d1SDavid du Colombier for(p=textp; p!=P; p=p->cond) { 4703e12c5d1SDavid du Colombier s = p->from.sym; 4713e12c5d1SDavid du Colombier if(s->type != STEXT && s->type != SLEAF) 4723e12c5d1SDavid du Colombier continue; 4733e12c5d1SDavid du Colombier 4743e12c5d1SDavid du Colombier /* filenames first */ 4753e12c5d1SDavid du Colombier for(a=p->to.autom; a; a=a->link) 4763e12c5d1SDavid du Colombier if(a->type == D_FILE) 4777dd7cddfSDavid du Colombier putsymb(a->asym->name, 'z', a->aoffset, 0); 4783e12c5d1SDavid du Colombier else 479219b2ee8SDavid du Colombier if(a->type == D_FILE1) 4807dd7cddfSDavid du Colombier putsymb(a->asym->name, 'Z', a->aoffset, 0); 4813e12c5d1SDavid du Colombier 4823e12c5d1SDavid du Colombier if(s->type == STEXT) 4833e12c5d1SDavid du Colombier putsymb(s->name, 'T', s->value, s->version); 4843e12c5d1SDavid du Colombier else 4853e12c5d1SDavid du Colombier putsymb(s->name, 'L', s->value, s->version); 4863e12c5d1SDavid du Colombier 4873e12c5d1SDavid du Colombier /* frame, auto and param after */ 488219b2ee8SDavid du Colombier putsymb(".frame", 'm', p->to.offset+4, 0); 4893e12c5d1SDavid du Colombier for(a=p->to.autom; a; a=a->link) 4903e12c5d1SDavid du Colombier if(a->type == D_AUTO) 4917dd7cddfSDavid du Colombier putsymb(a->asym->name, 'a', -a->aoffset, 0); 4923e12c5d1SDavid du Colombier else 4933e12c5d1SDavid du Colombier if(a->type == D_PARAM) 4947dd7cddfSDavid du Colombier putsymb(a->asym->name, 'p', a->aoffset, 0); 4953e12c5d1SDavid du Colombier } 4963e12c5d1SDavid du Colombier if(debug['v'] || debug['n']) 4973e12c5d1SDavid du Colombier Bprint(&bso, "symsize = %lud\n", symsize); 4983e12c5d1SDavid du Colombier Bflush(&bso); 4993e12c5d1SDavid du Colombier } 5003e12c5d1SDavid du Colombier 5013e12c5d1SDavid du Colombier void 5023e12c5d1SDavid du Colombier putsymb(char *s, int t, long v, int ver) 5033e12c5d1SDavid du Colombier { 5043e12c5d1SDavid du Colombier int i, f; 5053e12c5d1SDavid du Colombier 5063e12c5d1SDavid du Colombier if(t == 'f') 5073e12c5d1SDavid du Colombier s++; 50891178603SDavid du Colombier LBEPUT(v); 5093e12c5d1SDavid du Colombier if(ver) 5103e12c5d1SDavid du Colombier t += 'a' - 'A'; 511219b2ee8SDavid du Colombier CPUT(t+0x80); /* 0x80 is variable length */ 512219b2ee8SDavid du Colombier 513219b2ee8SDavid du Colombier if(t == 'Z' || t == 'z') { 514219b2ee8SDavid du Colombier CPUT(s[0]); 515219b2ee8SDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) { 516219b2ee8SDavid du Colombier CPUT(s[i]); 517219b2ee8SDavid du Colombier CPUT(s[i+1]); 518219b2ee8SDavid du Colombier } 519219b2ee8SDavid du Colombier CPUT(0); 520219b2ee8SDavid du Colombier CPUT(0); 521219b2ee8SDavid du Colombier i++; 522219b2ee8SDavid du Colombier } 523219b2ee8SDavid du Colombier else { 524219b2ee8SDavid du Colombier for(i=0; s[i]; i++) 5253e12c5d1SDavid du Colombier CPUT(s[i]); 5263e12c5d1SDavid du Colombier CPUT(0); 527219b2ee8SDavid du Colombier } 528219b2ee8SDavid du Colombier symsize += 4 + 1 + i + 1; 529219b2ee8SDavid du Colombier 5303e12c5d1SDavid du Colombier if(debug['n']) { 5313e12c5d1SDavid du Colombier if(t == 'z' || t == 'Z') { 532219b2ee8SDavid du Colombier Bprint(&bso, "%c %.8lux ", t, v); 533219b2ee8SDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) { 5343e12c5d1SDavid du Colombier f = ((s[i]&0xff) << 8) | (s[i+1]&0xff); 535219b2ee8SDavid du Colombier Bprint(&bso, "/%x", f); 5363e12c5d1SDavid du Colombier } 537219b2ee8SDavid du Colombier Bprint(&bso, "\n"); 5383e12c5d1SDavid du Colombier return; 5393e12c5d1SDavid du Colombier } 5403e12c5d1SDavid du Colombier if(ver) 5413e12c5d1SDavid du Colombier Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver); 5423e12c5d1SDavid du Colombier else 5433e12c5d1SDavid du Colombier Bprint(&bso, "%c %.8lux %s\n", t, v, s); 5443e12c5d1SDavid du Colombier } 5453e12c5d1SDavid du Colombier } 5463e12c5d1SDavid du Colombier 5473e12c5d1SDavid du Colombier #define MINLC 4 5483e12c5d1SDavid du Colombier void 5493e12c5d1SDavid du Colombier asmlc(void) 5503e12c5d1SDavid du Colombier { 551a587111cSDavid du Colombier long oldlc, v, s; 552a587111cSDavid du Colombier vlong oldpc; 5533e12c5d1SDavid du Colombier Prog *p; 5543e12c5d1SDavid du Colombier 5553e12c5d1SDavid du Colombier oldpc = INITTEXT; 5563e12c5d1SDavid du Colombier oldlc = 0; 5573e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 5583e12c5d1SDavid du Colombier if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) { 5593e12c5d1SDavid du Colombier if(p->as == ATEXT) 5603e12c5d1SDavid du Colombier curtext = p; 561b87cd620SDavid du Colombier if(debug['V']) 562a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p); 5633e12c5d1SDavid du Colombier continue; 5643e12c5d1SDavid du Colombier } 565b87cd620SDavid du Colombier if(debug['V']) 5663e12c5d1SDavid du Colombier Bprint(&bso, "\t\t%6ld", lcsize); 5673e12c5d1SDavid du Colombier v = (p->pc - oldpc) / MINLC; 5683e12c5d1SDavid du Colombier while(v) { 5693e12c5d1SDavid du Colombier s = 127; 5703e12c5d1SDavid du Colombier if(v < 127) 5713e12c5d1SDavid du Colombier s = v; 5723e12c5d1SDavid du Colombier CPUT(s+128); /* 129-255 +pc */ 573b87cd620SDavid du Colombier if(debug['V']) 5743e12c5d1SDavid du Colombier Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128); 5753e12c5d1SDavid du Colombier v -= s; 5763e12c5d1SDavid du Colombier lcsize++; 5773e12c5d1SDavid du Colombier } 5783e12c5d1SDavid du Colombier s = p->line - oldlc; 5793e12c5d1SDavid du Colombier oldlc = p->line; 5803e12c5d1SDavid du Colombier oldpc = p->pc + MINLC; 5813e12c5d1SDavid du Colombier if(s > 64 || s < -64) { 5823e12c5d1SDavid du Colombier CPUT(0); /* 0 vv +lc */ 5833e12c5d1SDavid du Colombier CPUT(s>>24); 5843e12c5d1SDavid du Colombier CPUT(s>>16); 5853e12c5d1SDavid du Colombier CPUT(s>>8); 5863e12c5d1SDavid du Colombier CPUT(s); 587b87cd620SDavid du Colombier if(debug['V']) { 5883e12c5d1SDavid du Colombier if(s > 0) 5893e12c5d1SDavid du Colombier Bprint(&bso, " lc+%ld(%d,%ld)\n", 5903e12c5d1SDavid du Colombier s, 0, s); 5913e12c5d1SDavid du Colombier else 5923e12c5d1SDavid du Colombier Bprint(&bso, " lc%ld(%d,%ld)\n", 5933e12c5d1SDavid du Colombier s, 0, s); 594a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p); 5953e12c5d1SDavid du Colombier } 5963e12c5d1SDavid du Colombier lcsize += 5; 5973e12c5d1SDavid du Colombier continue; 5983e12c5d1SDavid du Colombier } 5993e12c5d1SDavid du Colombier if(s > 0) { 6003e12c5d1SDavid du Colombier CPUT(0+s); /* 1-64 +lc */ 601b87cd620SDavid du Colombier if(debug['V']) { 6023e12c5d1SDavid du Colombier Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s); 603a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p); 6043e12c5d1SDavid du Colombier } 6053e12c5d1SDavid du Colombier } else { 6063e12c5d1SDavid du Colombier CPUT(64-s); /* 65-128 -lc */ 607b87cd620SDavid du Colombier if(debug['V']) { 6083e12c5d1SDavid du Colombier Bprint(&bso, " lc%ld(%ld)\n", s, 64-s); 609a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p); 6103e12c5d1SDavid du Colombier } 6113e12c5d1SDavid du Colombier } 6123e12c5d1SDavid du Colombier lcsize++; 6133e12c5d1SDavid du Colombier } 6143e12c5d1SDavid du Colombier while(lcsize & 1) { 6153e12c5d1SDavid du Colombier s = 129; 6163e12c5d1SDavid du Colombier CPUT(s); 6173e12c5d1SDavid du Colombier lcsize++; 6183e12c5d1SDavid du Colombier } 619b87cd620SDavid du Colombier if(debug['v'] || debug['V']) 6203e12c5d1SDavid du Colombier Bprint(&bso, "lcsize = %ld\n", lcsize); 6213e12c5d1SDavid du Colombier Bflush(&bso); 6223e12c5d1SDavid du Colombier } 6233e12c5d1SDavid du Colombier 6243e12c5d1SDavid du Colombier void 6259a747e4fSDavid du Colombier datblk(long s, long n, int str) 6263e12c5d1SDavid du Colombier { 6273e12c5d1SDavid du Colombier Prog *p; 6283e12c5d1SDavid du Colombier char *cast; 6293e12c5d1SDavid du Colombier long l, fl, j, d; 6303e12c5d1SDavid du Colombier int i, c; 6313e12c5d1SDavid du Colombier 6323e12c5d1SDavid du Colombier memset(buf.dbuf, 0, n+100); 6333e12c5d1SDavid du Colombier for(p = datap; p != P; p = p->link) { 6343e12c5d1SDavid du Colombier curp = p; 6359a747e4fSDavid du Colombier if(str != (p->from.sym->type == SSTRING)) 6369a747e4fSDavid du Colombier continue; 6373e12c5d1SDavid du Colombier l = p->from.sym->value + p->from.offset - s; 6383e12c5d1SDavid du Colombier c = p->reg; 6393e12c5d1SDavid du Colombier i = 0; 6403e12c5d1SDavid du Colombier if(l < 0) { 6413e12c5d1SDavid du Colombier if(l+c <= 0) 6423e12c5d1SDavid du Colombier continue; 6433e12c5d1SDavid du Colombier while(l < 0) { 6443e12c5d1SDavid du Colombier l++; 6453e12c5d1SDavid du Colombier i++; 6463e12c5d1SDavid du Colombier } 6473e12c5d1SDavid du Colombier } 6483e12c5d1SDavid du Colombier if(l >= n) 6493e12c5d1SDavid du Colombier continue; 650219b2ee8SDavid du Colombier if(p->as != AINIT && p->as != ADYNT) { 6513e12c5d1SDavid du Colombier for(j=l+(c-i)-1; j>=l; j--) 6523e12c5d1SDavid du Colombier if(buf.dbuf[j]) { 6533e12c5d1SDavid du Colombier print("%P\n", p); 6546b6b9ac8SDavid du Colombier diag("multiple initialization"); 6553e12c5d1SDavid du Colombier break; 6563e12c5d1SDavid du Colombier } 657219b2ee8SDavid du Colombier } 6583e12c5d1SDavid du Colombier switch(p->to.type) { 6593e12c5d1SDavid du Colombier default: 6606b6b9ac8SDavid du Colombier diag("unknown mode in initialization\n%P", p); 6613e12c5d1SDavid du Colombier break; 6623e12c5d1SDavid du Colombier 6633e12c5d1SDavid du Colombier case D_FCONST: 6643e12c5d1SDavid du Colombier switch(c) { 6653e12c5d1SDavid du Colombier default: 6663e12c5d1SDavid du Colombier case 4: 6673e12c5d1SDavid du Colombier fl = ieeedtof(p->to.ieee); 6683e12c5d1SDavid du Colombier cast = (char*)&fl; 6693e12c5d1SDavid du Colombier for(; i<c; i++) { 6703e12c5d1SDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i+4]]; 6713e12c5d1SDavid du Colombier l++; 6723e12c5d1SDavid du Colombier } 6733e12c5d1SDavid du Colombier break; 6743e12c5d1SDavid du Colombier case 8: 6753e12c5d1SDavid du Colombier cast = (char*)p->to.ieee; 6763e12c5d1SDavid du Colombier for(; i<c; i++) { 6773e12c5d1SDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i]]; 6783e12c5d1SDavid du Colombier l++; 6793e12c5d1SDavid du Colombier } 6803e12c5d1SDavid du Colombier break; 6813e12c5d1SDavid du Colombier } 6823e12c5d1SDavid du Colombier break; 6833e12c5d1SDavid du Colombier 6843e12c5d1SDavid du Colombier case D_SCONST: 6853e12c5d1SDavid du Colombier for(; i<c; i++) { 6863e12c5d1SDavid du Colombier buf.dbuf[l] = p->to.sval[i]; 6873e12c5d1SDavid du Colombier l++; 6883e12c5d1SDavid du Colombier } 6893e12c5d1SDavid du Colombier break; 6903e12c5d1SDavid du Colombier 6913e12c5d1SDavid du Colombier case D_CONST: 6923e12c5d1SDavid du Colombier d = p->to.offset; 6933e12c5d1SDavid du Colombier if(p->to.sym) { 6949a747e4fSDavid du Colombier switch(p->to.sym->type) { 6959a747e4fSDavid du Colombier case STEXT: 6969a747e4fSDavid du Colombier case SLEAF: 6979a747e4fSDavid du Colombier case SSTRING: 6983e12c5d1SDavid du Colombier d += p->to.sym->value; 6999a747e4fSDavid du Colombier break; 7009a747e4fSDavid du Colombier case SDATA: 7019a747e4fSDavid du Colombier case SBSS: 7023e12c5d1SDavid du Colombier d += p->to.sym->value + INITDAT; 7039a747e4fSDavid du Colombier break; 7049a747e4fSDavid du Colombier } 7053e12c5d1SDavid du Colombier } 7063e12c5d1SDavid du Colombier cast = (char*)&d; 7073e12c5d1SDavid du Colombier switch(c) { 7083e12c5d1SDavid du Colombier default: 7096b6b9ac8SDavid du Colombier diag("bad nuxi %d %d\n%P", c, i, curp); 7103e12c5d1SDavid du Colombier break; 7113e12c5d1SDavid du Colombier case 1: 7123e12c5d1SDavid du Colombier for(; i<c; i++) { 7133e12c5d1SDavid du Colombier buf.dbuf[l] = cast[inuxi1[i]]; 7143e12c5d1SDavid du Colombier l++; 7153e12c5d1SDavid du Colombier } 7163e12c5d1SDavid du Colombier break; 7173e12c5d1SDavid du Colombier case 2: 7183e12c5d1SDavid du Colombier for(; i<c; i++) { 7193e12c5d1SDavid du Colombier buf.dbuf[l] = cast[inuxi2[i]]; 7203e12c5d1SDavid du Colombier l++; 7213e12c5d1SDavid du Colombier } 7223e12c5d1SDavid du Colombier break; 7233e12c5d1SDavid du Colombier case 4: 7243e12c5d1SDavid du Colombier for(; i<c; i++) { 7253e12c5d1SDavid du Colombier buf.dbuf[l] = cast[inuxi4[i]]; 7263e12c5d1SDavid du Colombier l++; 7273e12c5d1SDavid du Colombier } 7283e12c5d1SDavid du Colombier break; 7293e12c5d1SDavid du Colombier } 7303e12c5d1SDavid du Colombier break; 7313e12c5d1SDavid du Colombier } 7323e12c5d1SDavid du Colombier } 7333e12c5d1SDavid du Colombier write(cout, buf.dbuf, n); 7343e12c5d1SDavid du Colombier } 7353e12c5d1SDavid du Colombier 7363e12c5d1SDavid du Colombier #define OP_RRR(op,r1,r2,r3)\ 7373e12c5d1SDavid du Colombier (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11)) 7383e12c5d1SDavid du Colombier #define OP_IRR(op,i,r2,r3)\ 7393e12c5d1SDavid du Colombier (op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16)) 7403e12c5d1SDavid du Colombier #define OP_SRR(op,s,r2,r3)\ 7413e12c5d1SDavid du Colombier (op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11)) 7423e12c5d1SDavid du Colombier #define OP_FRRR(op,r1,r2,r3)\ 7433e12c5d1SDavid du Colombier (op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6)) 7443e12c5d1SDavid du Colombier #define OP_JMP(op,i)\ 7453e12c5d1SDavid du Colombier ((op)|((i)&0x3ffffffL)) 7463e12c5d1SDavid du Colombier 747219b2ee8SDavid du Colombier #define OP(x,y)\ 748219b2ee8SDavid du Colombier (((x)<<3)|((y)<<0)) 749219b2ee8SDavid du Colombier #define SP(x,y)\ 750219b2ee8SDavid du Colombier (((x)<<29)|((y)<<26)) 751219b2ee8SDavid du Colombier #define BCOND(x,y)\ 752219b2ee8SDavid du Colombier (((x)<<19)|((y)<<16)) 753219b2ee8SDavid du Colombier #define MMU(x,y)\ 754219b2ee8SDavid du Colombier (SP(2,0)|(16<<21)|((x)<<3)|((y)<<0)) 755219b2ee8SDavid du Colombier #define FPF(x,y)\ 756219b2ee8SDavid du Colombier (SP(2,1)|(16<<21)|((x)<<3)|((y)<<0)) 757219b2ee8SDavid du Colombier #define FPD(x,y)\ 758219b2ee8SDavid du Colombier (SP(2,1)|(17<<21)|((x)<<3)|((y)<<0)) 759219b2ee8SDavid du Colombier #define FPW(x,y)\ 760219b2ee8SDavid du Colombier (SP(2,1)|(20<<21)|((x)<<3)|((y)<<0)) 761219b2ee8SDavid du Colombier 762dc5a79c1SDavid du Colombier int vshift(int); 763dc5a79c1SDavid du Colombier 7643e12c5d1SDavid du Colombier int 7653e12c5d1SDavid du Colombier asmout(Prog *p, Optab *o, int aflag) 7663e12c5d1SDavid du Colombier { 7677dd7cddfSDavid du Colombier long o1, o2, o3, o4, o5, o6, o7, v; 7683e12c5d1SDavid du Colombier Prog *ct; 7693e12c5d1SDavid du Colombier int r, a; 7703e12c5d1SDavid du Colombier 7713e12c5d1SDavid du Colombier o1 = 0; 7723e12c5d1SDavid du Colombier o2 = 0; 7733e12c5d1SDavid du Colombier o3 = 0; 7743e12c5d1SDavid du Colombier o4 = 0; 775219b2ee8SDavid du Colombier o5 = 0; 7767dd7cddfSDavid du Colombier o6 = 0; 7777dd7cddfSDavid du Colombier o7 = 0; 7783e12c5d1SDavid du Colombier switch(o->type) { 7793e12c5d1SDavid du Colombier default: 7806b6b9ac8SDavid du Colombier diag("unknown type %d", o->type); 7813e12c5d1SDavid du Colombier if(!debug['a']) 7823e12c5d1SDavid du Colombier prasm(p); 7833e12c5d1SDavid du Colombier break; 7843e12c5d1SDavid du Colombier 7853e12c5d1SDavid du Colombier case 0: /* pseudo ops */ 7863e12c5d1SDavid du Colombier if(aflag) { 7873e12c5d1SDavid du Colombier if(p->link) { 7883e12c5d1SDavid du Colombier if(p->as == ATEXT) { 7893e12c5d1SDavid du Colombier ct = curtext; 7903e12c5d1SDavid du Colombier o2 = autosize; 7913e12c5d1SDavid du Colombier curtext = p; 7923e12c5d1SDavid du Colombier autosize = p->to.offset + 4; 7933e12c5d1SDavid du Colombier o1 = asmout(p->link, oplook(p->link), aflag); 7943e12c5d1SDavid du Colombier curtext = ct; 7953e12c5d1SDavid du Colombier autosize = o2; 7963e12c5d1SDavid du Colombier } else 7973e12c5d1SDavid du Colombier o1 = asmout(p->link, oplook(p->link), aflag); 7983e12c5d1SDavid du Colombier } 7993e12c5d1SDavid du Colombier return o1; 8003e12c5d1SDavid du Colombier } 8013e12c5d1SDavid du Colombier break; 8023e12c5d1SDavid du Colombier 803219b2ee8SDavid du Colombier case 1: /* mov[v] r1,r2 ==> OR r1,r0,r2 */ 8043e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg); 8053e12c5d1SDavid du Colombier break; 8063e12c5d1SDavid du Colombier 8073e12c5d1SDavid du Colombier case 2: /* add/sub r1,[r2],r3 */ 8083e12c5d1SDavid du Colombier r = p->reg; 8093e12c5d1SDavid du Colombier if(r == NREG) 8103e12c5d1SDavid du Colombier r = p->to.reg; 8113e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg); 8123e12c5d1SDavid du Colombier break; 8133e12c5d1SDavid du Colombier 8143e12c5d1SDavid du Colombier case 3: /* mov $soreg, r ==> or/add $i,o,r */ 8153e12c5d1SDavid du Colombier v = regoff(&p->from); 8163e12c5d1SDavid du Colombier r = p->from.reg; 8173e12c5d1SDavid du Colombier if(r == NREG) 8183e12c5d1SDavid du Colombier r = o->param; 819219b2ee8SDavid du Colombier a = AADDU; 8203e12c5d1SDavid du Colombier if(o->a1 == C_ANDCON) 8213e12c5d1SDavid du Colombier a = AOR; 8223e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(a), v, r, p->to.reg); 8233e12c5d1SDavid du Colombier break; 8243e12c5d1SDavid du Colombier 8253e12c5d1SDavid du Colombier case 4: /* add $scon,[r1],r2 */ 8263e12c5d1SDavid du Colombier v = regoff(&p->from); 8273e12c5d1SDavid du Colombier r = p->reg; 8283e12c5d1SDavid du Colombier if(r == NREG) 8293e12c5d1SDavid du Colombier r = p->to.reg; 8303e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(p->as), v, r, p->to.reg); 8313e12c5d1SDavid du Colombier break; 8323e12c5d1SDavid du Colombier 8333e12c5d1SDavid du Colombier case 5: /* syscall */ 8343e12c5d1SDavid du Colombier if(aflag) 8353e12c5d1SDavid du Colombier return 0; 8363e12c5d1SDavid du Colombier o1 = oprrr(p->as); 8373e12c5d1SDavid du Colombier break; 8383e12c5d1SDavid du Colombier 8393e12c5d1SDavid du Colombier case 6: /* beq r1,[r2],sbra */ 8403e12c5d1SDavid du Colombier if(aflag) 8413e12c5d1SDavid du Colombier return 0; 8423e12c5d1SDavid du Colombier if(p->cond == P) 8433e12c5d1SDavid du Colombier v = -4 >> 2; 8443e12c5d1SDavid du Colombier else 8453e12c5d1SDavid du Colombier v = (p->cond->pc - pc-4) >> 2; 8467dd7cddfSDavid du Colombier if(((v << 16) >> 16) != v) 847406758d9SDavid du Colombier diag("short branch too far: %ld\n%P", v, p); 8483e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg); 8493e12c5d1SDavid du Colombier break; 8503e12c5d1SDavid du Colombier 8513e12c5d1SDavid du Colombier case 7: /* mov r, soreg ==> sw o(r) */ 8523e12c5d1SDavid du Colombier r = p->to.reg; 8533e12c5d1SDavid du Colombier if(r == NREG) 8543e12c5d1SDavid du Colombier r = o->param; 8553e12c5d1SDavid du Colombier v = regoff(&p->to); 8563e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(p->as), v, r, p->from.reg); 8573e12c5d1SDavid du Colombier break; 8583e12c5d1SDavid du Colombier 8593e12c5d1SDavid du Colombier case 8: /* mov soreg, r ==> lw o(r) */ 8603e12c5d1SDavid du Colombier r = p->from.reg; 8613e12c5d1SDavid du Colombier if(r == NREG) 8623e12c5d1SDavid du Colombier r = o->param; 8633e12c5d1SDavid du Colombier v = regoff(&p->from); 864219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg); 8653e12c5d1SDavid du Colombier break; 8663e12c5d1SDavid du Colombier 8673e12c5d1SDavid du Colombier case 9: /* asl r1,[r2],r3 */ 8683e12c5d1SDavid du Colombier r = p->reg; 8693e12c5d1SDavid du Colombier if(r == NREG) 8703e12c5d1SDavid du Colombier r = p->to.reg; 8713e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg); 8723e12c5d1SDavid du Colombier break; 8733e12c5d1SDavid du Colombier 8743e12c5d1SDavid du Colombier case 10: /* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */ 8753e12c5d1SDavid du Colombier v = regoff(&p->from); 8763e12c5d1SDavid du Colombier r = AOR; 8773e12c5d1SDavid du Colombier if(v < 0) 878219b2ee8SDavid du Colombier r = AADDU; 8793e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(r), v, 0, REGTMP); 8803e12c5d1SDavid du Colombier r = p->reg; 8813e12c5d1SDavid du Colombier if(r == NREG) 8823e12c5d1SDavid du Colombier r = p->to.reg; 8833e12c5d1SDavid du Colombier o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); 8843e12c5d1SDavid du Colombier break; 8853e12c5d1SDavid du Colombier 8863e12c5d1SDavid du Colombier case 11: /* jmp lbra */ 8873e12c5d1SDavid du Colombier if(aflag) 8883e12c5d1SDavid du Colombier return 0; 8893e12c5d1SDavid du Colombier if(p->cond == P) 8903e12c5d1SDavid du Colombier v = p->pc >> 2; 8913e12c5d1SDavid du Colombier else 8923e12c5d1SDavid du Colombier v = p->cond->pc >> 2; 8933e12c5d1SDavid du Colombier o1 = OP_JMP(opirr(p->as), v); 894219b2ee8SDavid du Colombier if(!debug['Y'] && p->link && p->cond && isnop(p->link)) { 895219b2ee8SDavid du Colombier nop.branch.count--; 896219b2ee8SDavid du Colombier nop.branch.outof--; 897219b2ee8SDavid du Colombier nop.jump.outof++; 8983e12c5d1SDavid du Colombier o2 = asmout(p->cond, oplook(p->cond), 1); 8993e12c5d1SDavid du Colombier if(o2) { 9003e12c5d1SDavid du Colombier o1 += 1; 9013e12c5d1SDavid du Colombier if(debug['a']) 902a587111cSDavid du Colombier Bprint(&bso, " %.8llux: %.8lux %.8lux%P\n", 903219b2ee8SDavid du Colombier p->pc, o1, o2, p); 9043e12c5d1SDavid du Colombier LPUT(o1); 9053e12c5d1SDavid du Colombier LPUT(o2); 9063e12c5d1SDavid du Colombier return 1; 9073e12c5d1SDavid du Colombier } 9083e12c5d1SDavid du Colombier } 9093e12c5d1SDavid du Colombier break; 9103e12c5d1SDavid du Colombier 9113e12c5d1SDavid du Colombier case 12: /* movbs r,r */ 9123e12c5d1SDavid du Colombier v = 16; 9133e12c5d1SDavid du Colombier if(p->as == AMOVB) 9143e12c5d1SDavid du Colombier v = 24; 9153e12c5d1SDavid du Colombier o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg); 9163e12c5d1SDavid du Colombier o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg); 9173e12c5d1SDavid du Colombier break; 9183e12c5d1SDavid du Colombier 9193e12c5d1SDavid du Colombier case 13: /* movbu r,r */ 9203e12c5d1SDavid du Colombier if(p->as == AMOVBU) 9213e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg); 9223e12c5d1SDavid du Colombier else 9233e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg); 9243e12c5d1SDavid du Colombier break; 9253e12c5d1SDavid du Colombier 9263e12c5d1SDavid du Colombier case 16: /* sll $c,[r1],r2 */ 9273e12c5d1SDavid du Colombier v = regoff(&p->from); 9283e12c5d1SDavid du Colombier r = p->reg; 9293e12c5d1SDavid du Colombier if(r == NREG) 9303e12c5d1SDavid du Colombier r = p->to.reg; 931dc5a79c1SDavid du Colombier 932dc5a79c1SDavid du Colombier /* OP_SRR will use only the low 5 bits of the shift value */ 933dc5a79c1SDavid du Colombier if(v >= 32 && vshift(p->as)) 934219b2ee8SDavid du Colombier o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg); 935219b2ee8SDavid du Colombier else 9363e12c5d1SDavid du Colombier o1 = OP_SRR(opirr(p->as), v, r, p->to.reg); 9373e12c5d1SDavid du Colombier break; 9383e12c5d1SDavid du Colombier 9393e12c5d1SDavid du Colombier case 18: /* jmp [r1],0(r2) */ 9403e12c5d1SDavid du Colombier if(aflag) 9413e12c5d1SDavid du Colombier return 0; 9423e12c5d1SDavid du Colombier r = p->reg; 9433e12c5d1SDavid du Colombier if(r == NREG) 9443e12c5d1SDavid du Colombier r = o->param; 9453e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r); 9463e12c5d1SDavid du Colombier break; 9473e12c5d1SDavid du Colombier 9483e12c5d1SDavid du Colombier case 19: /* mov $lcon,r ==> lu+or */ 9493e12c5d1SDavid du Colombier v = regoff(&p->from); 950219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg); 9513e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg); 9523e12c5d1SDavid du Colombier break; 9533e12c5d1SDavid du Colombier 954219b2ee8SDavid du Colombier case 20: /* mov lohi,r */ 955219b2ee8SDavid du Colombier r = OP(2,0); /* mfhi */ 9563e12c5d1SDavid du Colombier if(p->from.type == D_LO) 957219b2ee8SDavid du Colombier r = OP(2,2); /* mflo */ 958219b2ee8SDavid du Colombier o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg); 9593e12c5d1SDavid du Colombier break; 9603e12c5d1SDavid du Colombier 961219b2ee8SDavid du Colombier case 21: /* mov r,lohi */ 962219b2ee8SDavid du Colombier r = OP(2,1); /* mthi */ 9633e12c5d1SDavid du Colombier if(p->to.type == D_LO) 964219b2ee8SDavid du Colombier r = OP(2,3); /* mtlo */ 965219b2ee8SDavid du Colombier o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO); 9663e12c5d1SDavid du Colombier break; 9673e12c5d1SDavid du Colombier 9683e12c5d1SDavid du Colombier case 22: /* mul r1,r2 */ 9693e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO); 9703e12c5d1SDavid du Colombier break; 9713e12c5d1SDavid du Colombier 9723e12c5d1SDavid du Colombier case 23: /* add $lcon,r1,r2 ==> lu+or+add */ 9733e12c5d1SDavid du Colombier v = regoff(&p->from); 9743e12c5d1SDavid du Colombier if(p->to.reg == REGTMP || p->reg == REGTMP) 9756b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p); 976219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 9773e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 9783e12c5d1SDavid du Colombier r = p->reg; 9793e12c5d1SDavid du Colombier if(r == NREG) 9803e12c5d1SDavid du Colombier r = p->to.reg; 9813e12c5d1SDavid du Colombier o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); 9823e12c5d1SDavid du Colombier break; 9833e12c5d1SDavid du Colombier 9843e12c5d1SDavid du Colombier case 24: /* mov $ucon,,r ==> lu r */ 9853e12c5d1SDavid du Colombier v = regoff(&p->from); 986219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg); 9873e12c5d1SDavid du Colombier break; 9883e12c5d1SDavid du Colombier 9893e12c5d1SDavid du Colombier case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */ 9903e12c5d1SDavid du Colombier v = regoff(&p->from); 991219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 9923e12c5d1SDavid du Colombier r = p->reg; 9933e12c5d1SDavid du Colombier if(r == NREG) 9943e12c5d1SDavid du Colombier r = p->to.reg; 9953e12c5d1SDavid du Colombier o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg); 9963e12c5d1SDavid du Colombier break; 9973e12c5d1SDavid du Colombier 9983e12c5d1SDavid du Colombier case 26: /* mov $lsext/auto/oreg,,r2 ==> lu+or+add */ 9993e12c5d1SDavid du Colombier v = regoff(&p->from); 10003e12c5d1SDavid du Colombier if(p->to.reg == REGTMP) 10016b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p); 1002219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 10033e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 10043e12c5d1SDavid du Colombier r = p->from.reg; 10053e12c5d1SDavid du Colombier if(r == NREG) 10063e12c5d1SDavid du Colombier r = o->param; 1007219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg); 10083e12c5d1SDavid du Colombier break; 10093e12c5d1SDavid du Colombier 10103e12c5d1SDavid du Colombier case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */ 10113e12c5d1SDavid du Colombier r = p->from.reg; 10123e12c5d1SDavid du Colombier if(r == NREG) 10133e12c5d1SDavid du Colombier r = o->param; 10143e12c5d1SDavid du Colombier v = regoff(&p->from); 10153e12c5d1SDavid du Colombier switch(o->size) { 1016219b2ee8SDavid du Colombier case 20: 1017219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1018219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1019219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1020219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1); 1021219b2ee8SDavid du Colombier o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg); 10223e12c5d1SDavid du Colombier break; 1023219b2ee8SDavid du Colombier case 16: 1024219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1025219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1026219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1027219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg); 10283e12c5d1SDavid du Colombier break; 10293e12c5d1SDavid du Colombier case 8: 1030219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1); 1031219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg); 10323e12c5d1SDavid du Colombier break; 10333e12c5d1SDavid du Colombier case 4: 1034219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg); 10353e12c5d1SDavid du Colombier break; 10363e12c5d1SDavid du Colombier } 10373e12c5d1SDavid du Colombier break; 10383e12c5d1SDavid du Colombier 10393e12c5d1SDavid du Colombier case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */ 10403e12c5d1SDavid du Colombier r = p->to.reg; 10413e12c5d1SDavid du Colombier if(r == NREG) 10423e12c5d1SDavid du Colombier r = o->param; 10433e12c5d1SDavid du Colombier v = regoff(&p->to); 10443e12c5d1SDavid du Colombier switch(o->size) { 1045219b2ee8SDavid du Colombier case 20: 1046219b2ee8SDavid du Colombier if(r == REGTMP) 10476b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p); 1048219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1049219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1050219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1051219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1); 1052219b2ee8SDavid du Colombier o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg); 10533e12c5d1SDavid du Colombier break; 1054219b2ee8SDavid du Colombier case 16: 1055219b2ee8SDavid du Colombier if(r == REGTMP) 10566b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p); 1057219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1058219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1059219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1060219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg); 10613e12c5d1SDavid du Colombier break; 10623e12c5d1SDavid du Colombier case 8: 10633e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1); 10643e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg); 10653e12c5d1SDavid du Colombier break; 10663e12c5d1SDavid du Colombier case 4: 10673e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg); 10683e12c5d1SDavid du Colombier break; 10693e12c5d1SDavid du Colombier } 10703e12c5d1SDavid du Colombier break; 10713e12c5d1SDavid du Colombier 10723e12c5d1SDavid du Colombier case 30: /* movw r,fr */ 1073219b2ee8SDavid du Colombier r = SP(2,1)|(4<<21); /* mtc1 */ 1074219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); 10753e12c5d1SDavid du Colombier break; 10763e12c5d1SDavid du Colombier 10773e12c5d1SDavid du Colombier case 31: /* movw fr,r */ 1078219b2ee8SDavid du Colombier r = SP(2,1)|(0<<21); /* mfc1 */ 1079219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); 10803e12c5d1SDavid du Colombier break; 10813e12c5d1SDavid du Colombier 10823e12c5d1SDavid du Colombier case 32: /* fadd fr1,[fr2],fr3 */ 10833e12c5d1SDavid du Colombier r = p->reg; 10843e12c5d1SDavid du Colombier if(r == NREG) 10853e12c5d1SDavid du Colombier o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg); 10863e12c5d1SDavid du Colombier else 10873e12c5d1SDavid du Colombier o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg); 10883e12c5d1SDavid du Colombier break; 10893e12c5d1SDavid du Colombier 10903e12c5d1SDavid du Colombier case 33: /* fabs fr1,fr3 */ 10913e12c5d1SDavid du Colombier o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg); 10923e12c5d1SDavid du Colombier break; 10933e12c5d1SDavid du Colombier 10943e12c5d1SDavid du Colombier case 34: /* mov $con,fr ==> or/add $i,r,r2 */ 10953e12c5d1SDavid du Colombier v = regoff(&p->from); 1096219b2ee8SDavid du Colombier r = AADDU; 10973e12c5d1SDavid du Colombier if(o->a1 == C_ANDCON) 10983e12c5d1SDavid du Colombier r = AOR; 10993e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(r), v, 0, REGTMP); 1100219b2ee8SDavid du Colombier o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg); /* mtc1 */ 11013e12c5d1SDavid du Colombier break; 11023e12c5d1SDavid du Colombier 11033e12c5d1SDavid du Colombier case 35: /* mov r,lext/luto/oreg ==> sw o(r) */ 1104219b2ee8SDavid du Colombier /* 1105219b2ee8SDavid du Colombier * the lowbits of the constant cannot 1106219b2ee8SDavid du Colombier * be moved into the offset of the load 1107219b2ee8SDavid du Colombier * because the mips 4000 in 64-bit mode 1108219b2ee8SDavid du Colombier * does a 64-bit add and it will screw up. 1109219b2ee8SDavid du Colombier */ 11103e12c5d1SDavid du Colombier v = regoff(&p->to); 11113e12c5d1SDavid du Colombier r = p->to.reg; 11123e12c5d1SDavid du Colombier if(r == NREG) 11133e12c5d1SDavid du Colombier r = o->param; 1114219b2ee8SDavid du Colombier if(r == REGTMP) 11156b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p); 1116219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1117219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1118219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1119219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg); 11203e12c5d1SDavid du Colombier break; 11213e12c5d1SDavid du Colombier 11223e12c5d1SDavid du Colombier case 36: /* mov lext/lauto/lreg,r ==> lw o(r30) */ 11233e12c5d1SDavid du Colombier v = regoff(&p->from); 11243e12c5d1SDavid du Colombier r = p->from.reg; 11253e12c5d1SDavid du Colombier if(r == NREG) 11263e12c5d1SDavid du Colombier r = o->param; 1127219b2ee8SDavid du Colombier if(r == REGTMP) 11286b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p); 1129219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 1130219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP); 1131219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP); 1132219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg); 11333e12c5d1SDavid du Colombier break; 11343e12c5d1SDavid du Colombier 11353e12c5d1SDavid du Colombier case 37: /* movw r,mr */ 1136219b2ee8SDavid du Colombier r = SP(2,0)|(4<<21); /* mtc0 */ 1137219b2ee8SDavid du Colombier if(p->as == AMOVV) 1138219b2ee8SDavid du Colombier r = SP(2,0)|(5<<21); /* dmtc0 */ 1139219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->from.reg, 0, p->to.reg); 11403e12c5d1SDavid du Colombier break; 11413e12c5d1SDavid du Colombier 11423e12c5d1SDavid du Colombier case 38: /* movw mr,r */ 1143219b2ee8SDavid du Colombier r = SP(2,0)|(0<<21); /* mfc0 */ 1144219b2ee8SDavid du Colombier if(p->as == AMOVV) 1145219b2ee8SDavid du Colombier r = SP(2,0)|(1<<21); /* dmfc0 */ 1146219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->to.reg, 0, p->from.reg); 11473e12c5d1SDavid du Colombier break; 11483e12c5d1SDavid du Colombier 11493e12c5d1SDavid du Colombier case 39: /* rfe ==> jmp+rfe */ 11503e12c5d1SDavid du Colombier if(aflag) 11513e12c5d1SDavid du Colombier return 0; 11523e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO); 11533e12c5d1SDavid du Colombier o2 = oprrr(p->as); 11543e12c5d1SDavid du Colombier break; 11553e12c5d1SDavid du Colombier 11563e12c5d1SDavid du Colombier case 40: /* word */ 11573e12c5d1SDavid du Colombier if(aflag) 11583e12c5d1SDavid du Colombier return 0; 11593e12c5d1SDavid du Colombier o1 = regoff(&p->to); 11603e12c5d1SDavid du Colombier break; 11613e12c5d1SDavid du Colombier 11623e12c5d1SDavid du Colombier case 41: /* movw r,fcr */ 1163219b2ee8SDavid du Colombier o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); /* mfcc1 */ 1164219b2ee8SDavid du Colombier o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */ 11653e12c5d1SDavid du Colombier break; 11663e12c5d1SDavid du Colombier 11673e12c5d1SDavid du Colombier case 42: /* movw fcr,r */ 1168219b2ee8SDavid du Colombier o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */ 11693e12c5d1SDavid du Colombier break; 11707dd7cddfSDavid du Colombier 11717dd7cddfSDavid du Colombier case 45: /* case r */ 11727dd7cddfSDavid du Colombier if(p->link == P) 11737dd7cddfSDavid du Colombier v = p->pc+28; 11747dd7cddfSDavid du Colombier else 11757dd7cddfSDavid du Colombier v = p->link->pc; 11767dd7cddfSDavid du Colombier if(v & (1<<15)) 11777dd7cddfSDavid du Colombier o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP); 11787dd7cddfSDavid du Colombier else 11797dd7cddfSDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP); 11807dd7cddfSDavid du Colombier o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg); 11817dd7cddfSDavid du Colombier o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP); 11827dd7cddfSDavid du Colombier o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP); 11837dd7cddfSDavid du Colombier o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO); 11847dd7cddfSDavid du Colombier o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO); 11857dd7cddfSDavid du Colombier o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO); 11867dd7cddfSDavid du Colombier break; 11877dd7cddfSDavid du Colombier 11887dd7cddfSDavid du Colombier case 46: /* bcase $con,lbra */ 11897dd7cddfSDavid du Colombier if(p->cond == P) 11907dd7cddfSDavid du Colombier v = p->pc; 11917dd7cddfSDavid du Colombier else 11927dd7cddfSDavid du Colombier v = p->cond->pc; 11937dd7cddfSDavid du Colombier o1 = v; 11947dd7cddfSDavid du Colombier break; 11953e12c5d1SDavid du Colombier } 11963e12c5d1SDavid du Colombier if(aflag) 11973e12c5d1SDavid du Colombier return o1; 11983e12c5d1SDavid du Colombier v = p->pc; 11993e12c5d1SDavid du Colombier switch(o->size) { 12003e12c5d1SDavid du Colombier default: 12013e12c5d1SDavid du Colombier if(debug['a']) 12023e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux:\t\t%P\n", v, p); 12033e12c5d1SDavid du Colombier break; 12043e12c5d1SDavid du Colombier case 4: 12053e12c5d1SDavid du Colombier if(debug['a']) 12063e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p); 12073e12c5d1SDavid du Colombier LPUT(o1); 12083e12c5d1SDavid du Colombier break; 12093e12c5d1SDavid du Colombier case 8: 12103e12c5d1SDavid du Colombier if(debug['a']) 12113e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p); 12123e12c5d1SDavid du Colombier LPUT(o1); 12133e12c5d1SDavid du Colombier LPUT(o2); 12143e12c5d1SDavid du Colombier break; 12153e12c5d1SDavid du Colombier case 12: 12163e12c5d1SDavid du Colombier if(debug['a']) 12173e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p); 12183e12c5d1SDavid du Colombier LPUT(o1); 12193e12c5d1SDavid du Colombier LPUT(o2); 12203e12c5d1SDavid du Colombier LPUT(o3); 12213e12c5d1SDavid du Colombier break; 12223e12c5d1SDavid du Colombier case 16: 12233e12c5d1SDavid du Colombier if(debug['a']) 12243e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n", 12253e12c5d1SDavid du Colombier v, o1, o2, o3, o4, p); 12263e12c5d1SDavid du Colombier LPUT(o1); 12273e12c5d1SDavid du Colombier LPUT(o2); 12283e12c5d1SDavid du Colombier LPUT(o3); 12293e12c5d1SDavid du Colombier LPUT(o4); 12303e12c5d1SDavid du Colombier break; 1231219b2ee8SDavid du Colombier case 20: 1232219b2ee8SDavid du Colombier if(debug['a']) 1233219b2ee8SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", 1234219b2ee8SDavid du Colombier v, o1, o2, o3, o4, o5, p); 1235219b2ee8SDavid du Colombier LPUT(o1); 1236219b2ee8SDavid du Colombier LPUT(o2); 1237219b2ee8SDavid du Colombier LPUT(o3); 1238219b2ee8SDavid du Colombier LPUT(o4); 1239219b2ee8SDavid du Colombier LPUT(o5); 1240219b2ee8SDavid du Colombier break; 12417dd7cddfSDavid du Colombier 12427dd7cddfSDavid du Colombier case 28: 12437dd7cddfSDavid du Colombier if(debug['a']) 12447dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n", 12457dd7cddfSDavid du Colombier v, o1, o2, o3, o4, o5, o6, o7, p); 12467dd7cddfSDavid du Colombier LPUT(o1); 12477dd7cddfSDavid du Colombier LPUT(o2); 12487dd7cddfSDavid du Colombier LPUT(o3); 12497dd7cddfSDavid du Colombier LPUT(o4); 12507dd7cddfSDavid du Colombier LPUT(o5); 12517dd7cddfSDavid du Colombier LPUT(o6); 12527dd7cddfSDavid du Colombier LPUT(o7); 12537dd7cddfSDavid du Colombier break; 12543e12c5d1SDavid du Colombier } 12553e12c5d1SDavid du Colombier return 0; 12563e12c5d1SDavid du Colombier } 12573e12c5d1SDavid du Colombier 1258219b2ee8SDavid du Colombier int 1259219b2ee8SDavid du Colombier isnop(Prog *p) 1260219b2ee8SDavid du Colombier { 1261219b2ee8SDavid du Colombier if(p->as != ANOR) 1262219b2ee8SDavid du Colombier return 0; 1263219b2ee8SDavid du Colombier if(p->reg != REGZERO && p->reg != NREG) 1264219b2ee8SDavid du Colombier return 0; 1265219b2ee8SDavid du Colombier if(p->from.type != D_REG || p->from.reg != REGZERO) 1266219b2ee8SDavid du Colombier return 0; 1267219b2ee8SDavid du Colombier if(p->to.type != D_REG || p->to.reg != REGZERO) 1268219b2ee8SDavid du Colombier return 0; 1269219b2ee8SDavid du Colombier return 1; 1270219b2ee8SDavid du Colombier } 12713e12c5d1SDavid du Colombier 12723e12c5d1SDavid du Colombier long 12733e12c5d1SDavid du Colombier oprrr(int a) 12743e12c5d1SDavid du Colombier { 12753e12c5d1SDavid du Colombier switch(a) { 12763e12c5d1SDavid du Colombier case AADD: return OP(4,0); 12773e12c5d1SDavid du Colombier case AADDU: return OP(4,1); 12783e12c5d1SDavid du Colombier case ASGT: return OP(5,2); 12793e12c5d1SDavid du Colombier case ASGTU: return OP(5,3); 12803e12c5d1SDavid du Colombier case AAND: return OP(4,4); 12813e12c5d1SDavid du Colombier case AOR: return OP(4,5); 12823e12c5d1SDavid du Colombier case AXOR: return OP(4,6); 12833e12c5d1SDavid du Colombier case ASUB: return OP(4,2); 12843e12c5d1SDavid du Colombier case ASUBU: return OP(4,3); 12853e12c5d1SDavid du Colombier case ANOR: return OP(4,7); 12863e12c5d1SDavid du Colombier case ASLL: return OP(0,4); 12873e12c5d1SDavid du Colombier case ASRL: return OP(0,6); 12883e12c5d1SDavid du Colombier case ASRA: return OP(0,7); 12893e12c5d1SDavid du Colombier 12903e12c5d1SDavid du Colombier case AREM: 12913e12c5d1SDavid du Colombier case ADIV: return OP(3,2); 12923e12c5d1SDavid du Colombier case AREMU: 12933e12c5d1SDavid du Colombier case ADIVU: return OP(3,3); 12943e12c5d1SDavid du Colombier case AMUL: return OP(3,0); 12953e12c5d1SDavid du Colombier case AMULU: return OP(3,1); 12963e12c5d1SDavid du Colombier 12973e12c5d1SDavid du Colombier case AJMP: return OP(1,0); 12983e12c5d1SDavid du Colombier case AJAL: return OP(1,1); 12993e12c5d1SDavid du Colombier 13003e12c5d1SDavid du Colombier case ABREAK: return OP(1,5); 13013e12c5d1SDavid du Colombier case ASYSCALL: return OP(1,4); 13023e12c5d1SDavid du Colombier case ATLBP: return MMU(1,0); 13033e12c5d1SDavid du Colombier case ATLBR: return MMU(0,1); 13043e12c5d1SDavid du Colombier case ATLBWI: return MMU(0,2); 13053e12c5d1SDavid du Colombier case ATLBWR: return MMU(0,6); 13063e12c5d1SDavid du Colombier case ARFE: return MMU(2,0); 13073e12c5d1SDavid du Colombier 13083e12c5d1SDavid du Colombier case ADIVF: return FPF(0,3); 13093e12c5d1SDavid du Colombier case ADIVD: return FPD(0,3); 13103e12c5d1SDavid du Colombier case AMULF: return FPF(0,2); 13113e12c5d1SDavid du Colombier case AMULD: return FPD(0,2); 13123e12c5d1SDavid du Colombier case ASUBF: return FPF(0,1); 13133e12c5d1SDavid du Colombier case ASUBD: return FPD(0,1); 13143e12c5d1SDavid du Colombier case AADDF: return FPF(0,0); 13153e12c5d1SDavid du Colombier case AADDD: return FPD(0,0); 13163e12c5d1SDavid du Colombier 13173e12c5d1SDavid du Colombier case AMOVFW: return FPF(4,4); 13183e12c5d1SDavid du Colombier case AMOVDW: return FPD(4,4); 13193e12c5d1SDavid du Colombier case AMOVWF: return FPW(4,0); 13203e12c5d1SDavid du Colombier case AMOVDF: return FPD(4,0); 13213e12c5d1SDavid du Colombier case AMOVWD: return FPW(4,1); 13223e12c5d1SDavid du Colombier case AMOVFD: return FPF(4,1); 13233e12c5d1SDavid du Colombier case AABSF: return FPF(0,5); 13243e12c5d1SDavid du Colombier case AABSD: return FPD(0,5); 13253e12c5d1SDavid du Colombier case AMOVF: return FPF(0,6); 13263e12c5d1SDavid du Colombier case AMOVD: return FPD(0,6); 13273e12c5d1SDavid du Colombier case ANEGF: return FPF(0,7); 13283e12c5d1SDavid du Colombier case ANEGD: return FPD(0,7); 13293e12c5d1SDavid du Colombier 13303e12c5d1SDavid du Colombier case ACMPEQF: return FPF(6,2); 13313e12c5d1SDavid du Colombier case ACMPEQD: return FPD(6,2); 13323e12c5d1SDavid du Colombier case ACMPGTF: return FPF(7,4); 13333e12c5d1SDavid du Colombier case ACMPGTD: return FPD(7,4); 13343e12c5d1SDavid du Colombier case ACMPGEF: return FPF(7,6); 13353e12c5d1SDavid du Colombier case ACMPGED: return FPD(7,6); 13367dd7cddfSDavid du Colombier 13377dd7cddfSDavid du Colombier case ADIVV: return OP(3,6); 13387dd7cddfSDavid du Colombier case ADIVVU: return OP(3,7); 13397dd7cddfSDavid du Colombier case AADDV: return OP(5,4); 13407dd7cddfSDavid du Colombier case AADDVU: return OP(5,5); 13413e12c5d1SDavid du Colombier } 13426b6b9ac8SDavid du Colombier diag("bad rrr %d", a); 13433e12c5d1SDavid du Colombier return 0; 13443e12c5d1SDavid du Colombier } 13453e12c5d1SDavid du Colombier 13463e12c5d1SDavid du Colombier long 13473e12c5d1SDavid du Colombier opirr(int a) 13483e12c5d1SDavid du Colombier { 13493e12c5d1SDavid du Colombier switch(a) { 13503e12c5d1SDavid du Colombier case AADD: return SP(1,0); 13513e12c5d1SDavid du Colombier case AADDU: return SP(1,1); 13523e12c5d1SDavid du Colombier case ASGT: return SP(1,2); 13533e12c5d1SDavid du Colombier case ASGTU: return SP(1,3); 13543e12c5d1SDavid du Colombier case AAND: return SP(1,4); 13553e12c5d1SDavid du Colombier case AOR: return SP(1,5); 13563e12c5d1SDavid du Colombier case AXOR: return SP(1,6); 1357219b2ee8SDavid du Colombier case ALAST: return SP(1,7); 13583e12c5d1SDavid du Colombier case ASLL: return OP(0,0); 13593e12c5d1SDavid du Colombier case ASRL: return OP(0,2); 13603e12c5d1SDavid du Colombier case ASRA: return OP(0,3); 13613e12c5d1SDavid du Colombier 13623e12c5d1SDavid du Colombier case AJMP: return SP(0,2); 13633e12c5d1SDavid du Colombier case AJAL: return SP(0,3); 13643e12c5d1SDavid du Colombier case ABEQ: return SP(0,4); 13653e12c5d1SDavid du Colombier case ABNE: return SP(0,5); 13663e12c5d1SDavid du Colombier 13673e12c5d1SDavid du Colombier case ABGEZ: return SP(0,1)|BCOND(0,1); 13683e12c5d1SDavid du Colombier case ABGEZAL: return SP(0,1)|BCOND(2,1); 13693e12c5d1SDavid du Colombier case ABGTZ: return SP(0,7); 13703e12c5d1SDavid du Colombier case ABLEZ: return SP(0,6); 13713e12c5d1SDavid du Colombier case ABLTZ: return SP(0,1)|BCOND(0,0); 13723e12c5d1SDavid du Colombier case ABLTZAL: return SP(0,1)|BCOND(2,0); 13733e12c5d1SDavid du Colombier 13743e12c5d1SDavid du Colombier case ABFPT: return SP(2,1)|(257<<16); 13753e12c5d1SDavid du Colombier case ABFPF: return SP(2,1)|(256<<16); 13763e12c5d1SDavid du Colombier 13773e12c5d1SDavid du Colombier case AMOVB: 13783e12c5d1SDavid du Colombier case AMOVBU: return SP(5,0); 13793e12c5d1SDavid du Colombier case AMOVH: 13803e12c5d1SDavid du Colombier case AMOVHU: return SP(5,1); 13813e12c5d1SDavid du Colombier case AMOVW: return SP(5,3); 1382219b2ee8SDavid du Colombier case AMOVV: return SP(7,7); 13833e12c5d1SDavid du Colombier case AMOVF: return SP(7,1); 13843e12c5d1SDavid du Colombier case AMOVWL: return SP(5,2); 13853e12c5d1SDavid du Colombier case AMOVWR: return SP(5,6); 1386219b2ee8SDavid du Colombier case AMOVVL: return SP(5,4); 1387219b2ee8SDavid du Colombier case AMOVVR: return SP(5,5); 13883e12c5d1SDavid du Colombier 1389bd389b36SDavid du Colombier case ABREAK: return SP(5,7); 1390bd389b36SDavid du Colombier 1391219b2ee8SDavid du Colombier case AMOVWL+ALAST: return SP(4,2); 1392219b2ee8SDavid du Colombier case AMOVWR+ALAST: return SP(4,6); 1393219b2ee8SDavid du Colombier case AMOVVL+ALAST: return SP(3,2); 1394219b2ee8SDavid du Colombier case AMOVVR+ALAST: return SP(3,3); 1395219b2ee8SDavid du Colombier case AMOVB+ALAST: return SP(4,0); 1396219b2ee8SDavid du Colombier case AMOVBU+ALAST: return SP(4,4); 1397219b2ee8SDavid du Colombier case AMOVH+ALAST: return SP(4,1); 1398219b2ee8SDavid du Colombier case AMOVHU+ALAST: return SP(4,5); 1399219b2ee8SDavid du Colombier case AMOVW+ALAST: return SP(4,3); 1400219b2ee8SDavid du Colombier case AMOVV+ALAST: return SP(6,7); 1401219b2ee8SDavid du Colombier case AMOVF+ALAST: return SP(6,1); 14023e12c5d1SDavid du Colombier 1403219b2ee8SDavid du Colombier case ASLLV: return OP(7,0); 1404219b2ee8SDavid du Colombier case ASRLV: return OP(7,2); 1405219b2ee8SDavid du Colombier case ASRAV: return OP(7,3); 1406219b2ee8SDavid du Colombier case ASLLV+ALAST: return OP(7,4); 1407219b2ee8SDavid du Colombier case ASRLV+ALAST: return OP(7,6); 1408219b2ee8SDavid du Colombier case ASRAV+ALAST: return OP(7,7); 14097dd7cddfSDavid du Colombier 14107dd7cddfSDavid du Colombier case AADDV: return SP(3,0); 14117dd7cddfSDavid du Colombier case AADDVU: return SP(3,1); 14123e12c5d1SDavid du Colombier } 14136b6b9ac8SDavid du Colombier diag("bad irr %d", a); 1414dc5a79c1SDavid du Colombier abort(); 1415dc5a79c1SDavid du Colombier return 0; 1416dc5a79c1SDavid du Colombier } 1417dc5a79c1SDavid du Colombier 1418dc5a79c1SDavid du Colombier int 1419dc5a79c1SDavid du Colombier vshift(int a) 1420dc5a79c1SDavid du Colombier { 1421dc5a79c1SDavid du Colombier switch(a){ 1422dc5a79c1SDavid du Colombier case ASLLV: return 1; 1423dc5a79c1SDavid du Colombier case ASRLV: return 1; 1424dc5a79c1SDavid du Colombier case ASRAV: return 1; 1425dc5a79c1SDavid du Colombier } 14263e12c5d1SDavid du Colombier return 0; 14273e12c5d1SDavid du Colombier } 1428