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
cput(long l)948153b942SDavid du Colombier cput(long l)
958153b942SDavid du Colombier {
968153b942SDavid du Colombier CPUT(l);
978153b942SDavid du Colombier }
988153b942SDavid du Colombier
998153b942SDavid du Colombier void
objput(long l)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
objhput(short s)106bfb6eab9SDavid du Colombier objhput(short s)
107bfb6eab9SDavid du Colombier {
108bfb6eab9SDavid du Colombier HPUT(s);
109bfb6eab9SDavid du Colombier }
110bfb6eab9SDavid du Colombier
111bfb6eab9SDavid du Colombier void
wput(long l)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
wputl(long l)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
lput(long l)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
lputl(long l)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
llput(vlong v)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
llputl(vlong v)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
entryvalue(void)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
1785482313dSDavid du Colombier static void
plan9bootimage(ulong sects,ulong submagicvers,ulong tm,ulong hdrtxtsz,ulong textsz,ulong textva,ulong lcsize)1795482313dSDavid du Colombier plan9bootimage(ulong sects, ulong submagicvers, ulong tm,
1805482313dSDavid du Colombier ulong hdrtxtsz, ulong textsz, ulong textva, ulong lcsize)
1815482313dSDavid du Colombier {
1825482313dSDavid du Colombier lput(0x160L<<16|sects); /* magic and sections */
1835482313dSDavid du Colombier lput(tm); /* time and date */
1845482313dSDavid du Colombier lput(hdrtxtsz+datsize); /* offset to symbol table */
1855482313dSDavid du Colombier lput(symsize); /* size of symbol table */
1865482313dSDavid du Colombier lput((0x38L<<16)|7L); /* size of optional hdr and flags */
1875482313dSDavid du Colombier lput(submagicvers); /* magic and version */
1885482313dSDavid du Colombier
1895482313dSDavid du Colombier lput(textsz); /* segment sizes */
1905482313dSDavid du Colombier lput(datsize);
1915482313dSDavid du Colombier lput(bsssize);
1925482313dSDavid du Colombier
1935482313dSDavid du Colombier lput(entryvalue()); /* va of entry */
1945482313dSDavid du Colombier lput(textva); /* va of base of text */
1955482313dSDavid du Colombier lput(INITDAT); /* va of base of data */
1965482313dSDavid du Colombier lput(INITDAT+datsize); /* va of base of bss */
1975482313dSDavid du Colombier
1985482313dSDavid du Colombier lput(~0); /* gp reg mask */
1995482313dSDavid du Colombier lput(lcsize); /* pcsize / cprmask[0] */
2005482313dSDavid du Colombier lput(0); /* coproc reg masks[1⋯3] */
2015482313dSDavid du Colombier lput(0);
2025482313dSDavid du Colombier lput(0);
2035482313dSDavid du Colombier lput(~0); /* gp value ?? */
2045482313dSDavid du Colombier }
2055482313dSDavid du Colombier
2065482313dSDavid du Colombier static void
symhdrs(ulong hdrtxtsz)2075482313dSDavid du Colombier symhdrs(ulong hdrtxtsz)
2085482313dSDavid du Colombier {
2095482313dSDavid du Colombier strnput(".text", 8); /* text segment */
2105482313dSDavid du Colombier lput(INITTEXT); /* address */
2115482313dSDavid du Colombier lput(INITTEXT);
2125482313dSDavid du Colombier lput(textsize);
2135482313dSDavid du Colombier lput(HEADR);
2145482313dSDavid du Colombier lput(0);
2155482313dSDavid du Colombier lput(HEADR+textsize+datsize+symsize);
2165482313dSDavid du Colombier lput(lcsize); /* line number size */
2175482313dSDavid du Colombier lput(0x20); /* flags */
2185482313dSDavid du Colombier
2195482313dSDavid du Colombier strnput(".data", 8); /* data segment */
2205482313dSDavid du Colombier lput(INITDAT); /* address */
2215482313dSDavid du Colombier lput(INITDAT);
2225482313dSDavid du Colombier lput(datsize);
2235482313dSDavid du Colombier lput(hdrtxtsz);
2245482313dSDavid du Colombier lput(0);
2255482313dSDavid du Colombier lput(0);
2265482313dSDavid du Colombier lput(0);
2275482313dSDavid du Colombier lput(0x40); /* flags */
2285482313dSDavid du Colombier
2295482313dSDavid du Colombier strnput(".bss", 8); /* bss segment */
2305482313dSDavid du Colombier lput(INITDAT+datsize); /* address */
2315482313dSDavid du Colombier lput(INITDAT+datsize);
2325482313dSDavid du Colombier lput(bsssize);
2335482313dSDavid du Colombier lput(0);
2345482313dSDavid du Colombier lput(0);
2355482313dSDavid du Colombier lput(0);
2365482313dSDavid du Colombier lput(0);
2375482313dSDavid du Colombier lput(0x80); /* flags */
2385482313dSDavid du Colombier }
2395482313dSDavid du Colombier
2403e12c5d1SDavid du Colombier void
asmb(void)2413e12c5d1SDavid du Colombier asmb(void)
2423e12c5d1SDavid du Colombier {
2433e12c5d1SDavid du Colombier Prog *p;
2445482313dSDavid du Colombier long tm;
2455482313dSDavid 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;
29708d89a7dSDavid du Colombier case 6:
29808d89a7dSDavid du Colombier OFFSET = rnd(HEADR+textsize, INITRND);
29908d89a7dSDavid du Colombier seek(cout, OFFSET, 0);
30008d89a7dSDavid du Colombier break;
3013e12c5d1SDavid du Colombier case 1:
3023e12c5d1SDavid du Colombier case 2:
303219b2ee8SDavid du Colombier case 3:
304219b2ee8SDavid du Colombier case 5:
305a826b788SDavid du Colombier case 7:
306bd389b36SDavid du Colombier OFFSET = HEADR+textsize;
307bd389b36SDavid du Colombier seek(cout, OFFSET, 0);
3083e12c5d1SDavid du Colombier break;
3093e12c5d1SDavid du Colombier }
3103e12c5d1SDavid du Colombier for(t = 0; t < datsize; t += sizeof(buf)-100) {
3113e12c5d1SDavid du Colombier if(datsize-t > sizeof(buf)-100)
3129a747e4fSDavid du Colombier datblk(t, sizeof(buf)-100, 0);
3133e12c5d1SDavid du Colombier else
3149a747e4fSDavid du Colombier datblk(t, datsize-t, 0);
3153e12c5d1SDavid du Colombier }
3163e12c5d1SDavid du Colombier
3173e12c5d1SDavid du Colombier symsize = 0;
3183e12c5d1SDavid du Colombier lcsize = 0;
3193e12c5d1SDavid du Colombier if(!debug['s']) {
3203e12c5d1SDavid du Colombier if(debug['v'])
3213e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f sym\n", cputime());
3223e12c5d1SDavid du Colombier Bflush(&bso);
3233e12c5d1SDavid du Colombier switch(HEADTYPE) {
3243e12c5d1SDavid du Colombier case 0:
325219b2ee8SDavid du Colombier case 4:
326bd389b36SDavid du Colombier OFFSET = rnd(HEADR+textsize, 4096)+datsize;
327bd389b36SDavid du Colombier seek(cout, OFFSET, 0);
3283e12c5d1SDavid du Colombier break;
32908d89a7dSDavid du Colombier case 6:
33008d89a7dSDavid du Colombier OFFSET = rnd(HEADR+textsize, INITRND)+datsize;
33108d89a7dSDavid du Colombier seek(cout, OFFSET, 0);
33208d89a7dSDavid du Colombier break;
333219b2ee8SDavid du Colombier case 3:
3343e12c5d1SDavid du Colombier case 2:
3353e12c5d1SDavid du Colombier case 1:
336219b2ee8SDavid du Colombier case 5:
337a826b788SDavid du Colombier case 7:
338bd389b36SDavid du Colombier OFFSET = HEADR+textsize+datsize;
339bd389b36SDavid du Colombier seek(cout, OFFSET, 0);
3403e12c5d1SDavid du Colombier break;
3413e12c5d1SDavid du Colombier }
3423e12c5d1SDavid du Colombier if(!debug['s'])
3433e12c5d1SDavid du Colombier asmsym();
3443e12c5d1SDavid du Colombier if(debug['v'])
3453e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f pc\n", cputime());
3463e12c5d1SDavid du Colombier Bflush(&bso);
3473e12c5d1SDavid du Colombier if(!debug['s'])
3483e12c5d1SDavid du Colombier asmlc();
3493e12c5d1SDavid du Colombier cflush();
3503e12c5d1SDavid du Colombier }
3513e12c5d1SDavid du Colombier
3523e12c5d1SDavid du Colombier if(debug['v'])
3533e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f header\n", cputime());
3543e12c5d1SDavid du Colombier Bflush(&bso);
355bd389b36SDavid du Colombier OFFSET = 0;
356bd389b36SDavid du Colombier seek(cout, OFFSET, 0);
3575482313dSDavid du Colombier
3585482313dSDavid du Colombier rndtxtsz = rnd(HEADR+textsize, (INITRND > 0? INITRND: 4096));
3595482313dSDavid du Colombier tm = time(0);
3603e12c5d1SDavid du Colombier switch(HEADTYPE) {
3613e12c5d1SDavid du Colombier case 0:
3625482313dSDavid du Colombier /* 0413: plan 9 boot image, text segment rounded (to 4KB) */
3635482313dSDavid du Colombier plan9bootimage(0, 0413<<16|0437, 0, rndtxtsz, rndtxtsz,
3645482313dSDavid du Colombier INITTEXT-HEADR, 0);
3653e12c5d1SDavid du Colombier break;
3663e12c5d1SDavid du Colombier case 1:
3675482313dSDavid du Colombier /* 0407: plan 9 boot image, extra word */
3685482313dSDavid du Colombier plan9bootimage(0, 0407<<16|0437, 0, HEADR+textsize, textsize,
3695482313dSDavid du Colombier INITTEXT, lcsize);
3705482313dSDavid du Colombier lput(0); /* extra; complete mystery */
3713e12c5d1SDavid du Colombier break;
3723305c317SDavid du Colombier case 2: /* plan 9 format */
37391178603SDavid du Colombier if (little)
3743305c317SDavid du Colombier lput(P_MAGIC); /* mips 3000 LE */
37591178603SDavid du Colombier else
3763305c317SDavid du Colombier lput(V_MAGIC); /* mips 3000 BE */
3773e12c5d1SDavid du Colombier lput(textsize); /* sizes */
3783e12c5d1SDavid du Colombier lput(datsize);
3793e12c5d1SDavid du Colombier lput(bsssize);
3803e12c5d1SDavid du Colombier lput(symsize); /* nsyms */
3813e12c5d1SDavid du Colombier lput(entryvalue()); /* va of entry */
3823e12c5d1SDavid du Colombier lput(0L);
3833e12c5d1SDavid du Colombier lput(lcsize);
3843e12c5d1SDavid du Colombier break;
385219b2ee8SDavid du Colombier case 3:
3865482313dSDavid du Colombier /* 0407: plan 9 mips 4k boot image with symbols */
3875482313dSDavid du Colombier plan9bootimage(3, 0407<<16|0437, tm, HEADR+textsize, textsize,
3885482313dSDavid du Colombier INITTEXT, lcsize);
3895482313dSDavid du Colombier symhdrs(HEADR+textsize);
390219b2ee8SDavid du Colombier break;
391219b2ee8SDavid du Colombier case 4:
3925482313dSDavid du Colombier /* 0413: plan 9 mips 4k boot image with symbols */
3935482313dSDavid du Colombier plan9bootimage(3, 0413<<16|01012, tm, rndtxtsz, textsize,
3945482313dSDavid du Colombier INITTEXT, lcsize);
3955482313dSDavid du Colombier symhdrs(rndtxtsz);
396219b2ee8SDavid du Colombier break;
397219b2ee8SDavid du Colombier case 5:
3988153b942SDavid du Colombier elf32(MIPS, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
39991178603SDavid du Colombier break;
40091178603SDavid du Colombier case 6:
40191178603SDavid du Colombier break;
402a587111cSDavid du Colombier case 7:
403a587111cSDavid du Colombier elf64(MIPSR4K, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
404a587111cSDavid du Colombier break;
4053e12c5d1SDavid du Colombier }
4063e12c5d1SDavid du Colombier cflush();
4073e12c5d1SDavid du Colombier }
4083e12c5d1SDavid du Colombier
4093e12c5d1SDavid du Colombier void
strnput(char * s,int n)410219b2ee8SDavid du Colombier strnput(char *s, int n)
411219b2ee8SDavid du Colombier {
412219b2ee8SDavid du Colombier for(; *s; s++){
413219b2ee8SDavid du Colombier CPUT(*s);
414219b2ee8SDavid du Colombier n--;
415219b2ee8SDavid du Colombier }
416219b2ee8SDavid du Colombier for(; n > 0; n--)
417219b2ee8SDavid du Colombier CPUT(0);
418219b2ee8SDavid du Colombier }
419219b2ee8SDavid du Colombier
420219b2ee8SDavid du Colombier void
cflush(void)4213e12c5d1SDavid du Colombier cflush(void)
4223e12c5d1SDavid du Colombier {
4233e12c5d1SDavid du Colombier int n;
4243e12c5d1SDavid du Colombier
4253e12c5d1SDavid du Colombier n = sizeof(buf.cbuf) - cbc;
4263e12c5d1SDavid du Colombier if(n)
4273e12c5d1SDavid du Colombier write(cout, buf.cbuf, n);
4283e12c5d1SDavid du Colombier cbp = buf.cbuf;
4293e12c5d1SDavid du Colombier cbc = sizeof(buf.cbuf);
4303e12c5d1SDavid du Colombier }
4313e12c5d1SDavid du Colombier
4323e12c5d1SDavid du Colombier void
nopstat(char * f,Count * c)433219b2ee8SDavid du Colombier nopstat(char *f, Count *c)
434219b2ee8SDavid du Colombier {
435219b2ee8SDavid du Colombier if(c->outof)
436219b2ee8SDavid du Colombier Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
437219b2ee8SDavid du Colombier c->outof - c->count, c->outof,
438219b2ee8SDavid du Colombier (double)(c->outof - c->count)/c->outof);
439219b2ee8SDavid du Colombier }
440219b2ee8SDavid du Colombier
441219b2ee8SDavid du Colombier void
asmsym(void)4423e12c5d1SDavid du Colombier asmsym(void)
4433e12c5d1SDavid du Colombier {
4443e12c5d1SDavid du Colombier Prog *p;
4453e12c5d1SDavid du Colombier Auto *a;
4463e12c5d1SDavid du Colombier Sym *s;
4473e12c5d1SDavid du Colombier int h;
4483e12c5d1SDavid du Colombier
4493e12c5d1SDavid du Colombier s = lookup("etext", 0);
4503e12c5d1SDavid du Colombier if(s->type == STEXT)
4513e12c5d1SDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
4523e12c5d1SDavid du Colombier
4533e12c5d1SDavid du Colombier for(h=0; h<NHASH; h++)
4543e12c5d1SDavid du Colombier for(s=hash[h]; s!=S; s=s->link)
4553e12c5d1SDavid du Colombier switch(s->type) {
456219b2ee8SDavid du Colombier case SCONST:
457219b2ee8SDavid du Colombier putsymb(s->name, 'D', s->value, s->version);
458219b2ee8SDavid du Colombier continue;
459219b2ee8SDavid du Colombier
4609a747e4fSDavid du Colombier case SSTRING:
4619a747e4fSDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
4629a747e4fSDavid du Colombier continue;
4639a747e4fSDavid du Colombier
4643e12c5d1SDavid du Colombier case SDATA:
4653e12c5d1SDavid du Colombier putsymb(s->name, 'D', s->value+INITDAT, s->version);
4663e12c5d1SDavid du Colombier continue;
4673e12c5d1SDavid du Colombier
4683e12c5d1SDavid du Colombier case SBSS:
4693e12c5d1SDavid du Colombier putsymb(s->name, 'B', s->value+INITDAT, s->version);
4703e12c5d1SDavid du Colombier continue;
4713e12c5d1SDavid du Colombier
4723e12c5d1SDavid du Colombier case SFILE:
4733e12c5d1SDavid du Colombier putsymb(s->name, 'f', s->value, s->version);
4743e12c5d1SDavid du Colombier continue;
4753e12c5d1SDavid du Colombier }
4763e12c5d1SDavid du Colombier
4773e12c5d1SDavid du Colombier for(p=textp; p!=P; p=p->cond) {
4783e12c5d1SDavid du Colombier s = p->from.sym;
4793e12c5d1SDavid du Colombier if(s->type != STEXT && s->type != SLEAF)
4803e12c5d1SDavid du Colombier continue;
4813e12c5d1SDavid du Colombier
4823e12c5d1SDavid du Colombier /* filenames first */
4833e12c5d1SDavid du Colombier for(a=p->to.autom; a; a=a->link)
4843e12c5d1SDavid du Colombier if(a->type == D_FILE)
4857dd7cddfSDavid du Colombier putsymb(a->asym->name, 'z', a->aoffset, 0);
4863e12c5d1SDavid du Colombier else
487219b2ee8SDavid du Colombier if(a->type == D_FILE1)
4887dd7cddfSDavid du Colombier putsymb(a->asym->name, 'Z', a->aoffset, 0);
4893e12c5d1SDavid du Colombier
4903e12c5d1SDavid du Colombier if(s->type == STEXT)
4913e12c5d1SDavid du Colombier putsymb(s->name, 'T', s->value, s->version);
4923e12c5d1SDavid du Colombier else
4933e12c5d1SDavid du Colombier putsymb(s->name, 'L', s->value, s->version);
4943e12c5d1SDavid du Colombier
4953e12c5d1SDavid du Colombier /* frame, auto and param after */
496219b2ee8SDavid du Colombier putsymb(".frame", 'm', p->to.offset+4, 0);
4973e12c5d1SDavid du Colombier for(a=p->to.autom; a; a=a->link)
4983e12c5d1SDavid du Colombier if(a->type == D_AUTO)
4997dd7cddfSDavid du Colombier putsymb(a->asym->name, 'a', -a->aoffset, 0);
5003e12c5d1SDavid du Colombier else
5013e12c5d1SDavid du Colombier if(a->type == D_PARAM)
5027dd7cddfSDavid du Colombier putsymb(a->asym->name, 'p', a->aoffset, 0);
5033e12c5d1SDavid du Colombier }
5043e12c5d1SDavid du Colombier if(debug['v'] || debug['n'])
5053e12c5d1SDavid du Colombier Bprint(&bso, "symsize = %lud\n", symsize);
5063e12c5d1SDavid du Colombier Bflush(&bso);
5073e12c5d1SDavid du Colombier }
5083e12c5d1SDavid du Colombier
5093e12c5d1SDavid du Colombier void
putsymb(char * s,int t,long v,int ver)5103e12c5d1SDavid du Colombier putsymb(char *s, int t, long v, int ver)
5113e12c5d1SDavid du Colombier {
5123e12c5d1SDavid du Colombier int i, f;
5133e12c5d1SDavid du Colombier
5143e12c5d1SDavid du Colombier if(t == 'f')
5153e12c5d1SDavid du Colombier s++;
51691178603SDavid du Colombier LBEPUT(v);
5173e12c5d1SDavid du Colombier if(ver)
5183e12c5d1SDavid du Colombier t += 'a' - 'A';
519219b2ee8SDavid du Colombier CPUT(t+0x80); /* 0x80 is variable length */
520219b2ee8SDavid du Colombier
521219b2ee8SDavid du Colombier if(t == 'Z' || t == 'z') {
522219b2ee8SDavid du Colombier CPUT(s[0]);
523219b2ee8SDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
524219b2ee8SDavid du Colombier CPUT(s[i]);
525219b2ee8SDavid du Colombier CPUT(s[i+1]);
526219b2ee8SDavid du Colombier }
527219b2ee8SDavid du Colombier CPUT(0);
528219b2ee8SDavid du Colombier CPUT(0);
529219b2ee8SDavid du Colombier i++;
530219b2ee8SDavid du Colombier }
531219b2ee8SDavid du Colombier else {
532219b2ee8SDavid du Colombier for(i=0; s[i]; i++)
5333e12c5d1SDavid du Colombier CPUT(s[i]);
5343e12c5d1SDavid du Colombier CPUT(0);
535219b2ee8SDavid du Colombier }
536219b2ee8SDavid du Colombier symsize += 4 + 1 + i + 1;
537219b2ee8SDavid du Colombier
5383e12c5d1SDavid du Colombier if(debug['n']) {
5393e12c5d1SDavid du Colombier if(t == 'z' || t == 'Z') {
540219b2ee8SDavid du Colombier Bprint(&bso, "%c %.8lux ", t, v);
541219b2ee8SDavid du Colombier for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
5423e12c5d1SDavid du Colombier f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
543219b2ee8SDavid du Colombier Bprint(&bso, "/%x", f);
5443e12c5d1SDavid du Colombier }
545219b2ee8SDavid du Colombier Bprint(&bso, "\n");
5463e12c5d1SDavid du Colombier return;
5473e12c5d1SDavid du Colombier }
5483e12c5d1SDavid du Colombier if(ver)
5493e12c5d1SDavid du Colombier Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
5503e12c5d1SDavid du Colombier else
5513e12c5d1SDavid du Colombier Bprint(&bso, "%c %.8lux %s\n", t, v, s);
5523e12c5d1SDavid du Colombier }
5533e12c5d1SDavid du Colombier }
5543e12c5d1SDavid du Colombier
5553e12c5d1SDavid du Colombier #define MINLC 4
5563e12c5d1SDavid du Colombier void
asmlc(void)5573e12c5d1SDavid du Colombier asmlc(void)
5583e12c5d1SDavid du Colombier {
559a587111cSDavid du Colombier long oldlc, v, s;
560a587111cSDavid du Colombier vlong oldpc;
5613e12c5d1SDavid du Colombier Prog *p;
5623e12c5d1SDavid du Colombier
5633e12c5d1SDavid du Colombier oldpc = INITTEXT;
5643e12c5d1SDavid du Colombier oldlc = 0;
5653e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
5663e12c5d1SDavid du Colombier if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
5673e12c5d1SDavid du Colombier if(p->as == ATEXT)
5683e12c5d1SDavid du Colombier curtext = p;
569b87cd620SDavid du Colombier if(debug['V'])
570a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p);
5713e12c5d1SDavid du Colombier continue;
5723e12c5d1SDavid du Colombier }
573b87cd620SDavid du Colombier if(debug['V'])
5743e12c5d1SDavid du Colombier Bprint(&bso, "\t\t%6ld", lcsize);
5753e12c5d1SDavid du Colombier v = (p->pc - oldpc) / MINLC;
5763e12c5d1SDavid du Colombier while(v) {
5773e12c5d1SDavid du Colombier s = 127;
5783e12c5d1SDavid du Colombier if(v < 127)
5793e12c5d1SDavid du Colombier s = v;
5803e12c5d1SDavid du Colombier CPUT(s+128); /* 129-255 +pc */
581b87cd620SDavid du Colombier if(debug['V'])
5823e12c5d1SDavid du Colombier Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
5833e12c5d1SDavid du Colombier v -= s;
5843e12c5d1SDavid du Colombier lcsize++;
5853e12c5d1SDavid du Colombier }
5863e12c5d1SDavid du Colombier s = p->line - oldlc;
5873e12c5d1SDavid du Colombier oldlc = p->line;
5883e12c5d1SDavid du Colombier oldpc = p->pc + MINLC;
5893e12c5d1SDavid du Colombier if(s > 64 || s < -64) {
5903e12c5d1SDavid du Colombier CPUT(0); /* 0 vv +lc */
5913e12c5d1SDavid du Colombier CPUT(s>>24);
5923e12c5d1SDavid du Colombier CPUT(s>>16);
5933e12c5d1SDavid du Colombier CPUT(s>>8);
5943e12c5d1SDavid du Colombier CPUT(s);
595b87cd620SDavid du Colombier if(debug['V']) {
5963e12c5d1SDavid du Colombier if(s > 0)
5973e12c5d1SDavid du Colombier Bprint(&bso, " lc+%ld(%d,%ld)\n",
5983e12c5d1SDavid du Colombier s, 0, s);
5993e12c5d1SDavid du Colombier else
6003e12c5d1SDavid du Colombier Bprint(&bso, " lc%ld(%d,%ld)\n",
6013e12c5d1SDavid du Colombier s, 0, s);
602a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p);
6033e12c5d1SDavid du Colombier }
6043e12c5d1SDavid du Colombier lcsize += 5;
6053e12c5d1SDavid du Colombier continue;
6063e12c5d1SDavid du Colombier }
6073e12c5d1SDavid du Colombier if(s > 0) {
6083e12c5d1SDavid du Colombier CPUT(0+s); /* 1-64 +lc */
609b87cd620SDavid du Colombier if(debug['V']) {
6103e12c5d1SDavid du Colombier Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
611a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p);
6123e12c5d1SDavid du Colombier }
6133e12c5d1SDavid du Colombier } else {
6143e12c5d1SDavid du Colombier CPUT(64-s); /* 65-128 -lc */
615b87cd620SDavid du Colombier if(debug['V']) {
6163e12c5d1SDavid du Colombier Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
617a587111cSDavid du Colombier Bprint(&bso, "%6llux %P\n", p->pc, p);
6183e12c5d1SDavid du Colombier }
6193e12c5d1SDavid du Colombier }
6203e12c5d1SDavid du Colombier lcsize++;
6213e12c5d1SDavid du Colombier }
6223e12c5d1SDavid du Colombier while(lcsize & 1) {
6233e12c5d1SDavid du Colombier s = 129;
6243e12c5d1SDavid du Colombier CPUT(s);
6253e12c5d1SDavid du Colombier lcsize++;
6263e12c5d1SDavid du Colombier }
627b87cd620SDavid du Colombier if(debug['v'] || debug['V'])
6283e12c5d1SDavid du Colombier Bprint(&bso, "lcsize = %ld\n", lcsize);
6293e12c5d1SDavid du Colombier Bflush(&bso);
6303e12c5d1SDavid du Colombier }
6313e12c5d1SDavid du Colombier
6323e12c5d1SDavid du Colombier void
datblk(long s,long n,int str)6339a747e4fSDavid du Colombier datblk(long s, long n, int str)
6343e12c5d1SDavid du Colombier {
6353e12c5d1SDavid du Colombier Prog *p;
6363e12c5d1SDavid du Colombier char *cast;
6373e12c5d1SDavid du Colombier long l, fl, j, d;
6383e12c5d1SDavid du Colombier int i, c;
6393e12c5d1SDavid du Colombier
6403e12c5d1SDavid du Colombier memset(buf.dbuf, 0, n+100);
6413e12c5d1SDavid du Colombier for(p = datap; p != P; p = p->link) {
6423e12c5d1SDavid du Colombier curp = p;
6439a747e4fSDavid du Colombier if(str != (p->from.sym->type == SSTRING))
6449a747e4fSDavid du Colombier continue;
6453e12c5d1SDavid du Colombier l = p->from.sym->value + p->from.offset - s;
6463e12c5d1SDavid du Colombier c = p->reg;
6473e12c5d1SDavid du Colombier i = 0;
6483e12c5d1SDavid du Colombier if(l < 0) {
6493e12c5d1SDavid du Colombier if(l+c <= 0)
6503e12c5d1SDavid du Colombier continue;
6513e12c5d1SDavid du Colombier while(l < 0) {
6523e12c5d1SDavid du Colombier l++;
6533e12c5d1SDavid du Colombier i++;
6543e12c5d1SDavid du Colombier }
6553e12c5d1SDavid du Colombier }
6563e12c5d1SDavid du Colombier if(l >= n)
6573e12c5d1SDavid du Colombier continue;
658219b2ee8SDavid du Colombier if(p->as != AINIT && p->as != ADYNT) {
6593e12c5d1SDavid du Colombier for(j=l+(c-i)-1; j>=l; j--)
6603e12c5d1SDavid du Colombier if(buf.dbuf[j]) {
6613e12c5d1SDavid du Colombier print("%P\n", p);
6626b6b9ac8SDavid du Colombier diag("multiple initialization");
6633e12c5d1SDavid du Colombier break;
6643e12c5d1SDavid du Colombier }
665219b2ee8SDavid du Colombier }
6663e12c5d1SDavid du Colombier switch(p->to.type) {
6673e12c5d1SDavid du Colombier default:
6686b6b9ac8SDavid du Colombier diag("unknown mode in initialization\n%P", p);
6693e12c5d1SDavid du Colombier break;
6703e12c5d1SDavid du Colombier
6713e12c5d1SDavid du Colombier case D_FCONST:
6723e12c5d1SDavid du Colombier switch(c) {
6733e12c5d1SDavid du Colombier default:
6743e12c5d1SDavid du Colombier case 4:
6753e12c5d1SDavid du Colombier fl = ieeedtof(p->to.ieee);
6763e12c5d1SDavid du Colombier cast = (char*)&fl;
6773e12c5d1SDavid du Colombier for(; i<c; i++) {
678*12b1df16SDavid du Colombier if(little)
679*12b1df16SDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i]];
680*12b1df16SDavid du Colombier else
6813e12c5d1SDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i+4]];
6823e12c5d1SDavid du Colombier l++;
6833e12c5d1SDavid du Colombier }
6843e12c5d1SDavid du Colombier break;
6853e12c5d1SDavid du Colombier case 8:
6863e12c5d1SDavid du Colombier cast = (char*)p->to.ieee;
6873e12c5d1SDavid du Colombier for(; i<c; i++) {
6883e12c5d1SDavid du Colombier buf.dbuf[l] = cast[fnuxi8[i]];
6893e12c5d1SDavid du Colombier l++;
6903e12c5d1SDavid du Colombier }
6913e12c5d1SDavid du Colombier break;
6923e12c5d1SDavid du Colombier }
6933e12c5d1SDavid du Colombier break;
6943e12c5d1SDavid du Colombier
6953e12c5d1SDavid du Colombier case D_SCONST:
6963e12c5d1SDavid du Colombier for(; i<c; i++) {
6973e12c5d1SDavid du Colombier buf.dbuf[l] = p->to.sval[i];
6983e12c5d1SDavid du Colombier l++;
6993e12c5d1SDavid du Colombier }
7003e12c5d1SDavid du Colombier break;
7013e12c5d1SDavid du Colombier
7023e12c5d1SDavid du Colombier case D_CONST:
7033e12c5d1SDavid du Colombier d = p->to.offset;
7043e12c5d1SDavid du Colombier if(p->to.sym) {
7059a747e4fSDavid du Colombier switch(p->to.sym->type) {
7069a747e4fSDavid du Colombier case STEXT:
7079a747e4fSDavid du Colombier case SLEAF:
7089a747e4fSDavid du Colombier case SSTRING:
7093e12c5d1SDavid du Colombier d += p->to.sym->value;
7109a747e4fSDavid du Colombier break;
7119a747e4fSDavid du Colombier case SDATA:
7129a747e4fSDavid du Colombier case SBSS:
7133e12c5d1SDavid du Colombier d += p->to.sym->value + INITDAT;
7149a747e4fSDavid du Colombier break;
7159a747e4fSDavid du Colombier }
7163e12c5d1SDavid du Colombier }
7173e12c5d1SDavid du Colombier cast = (char*)&d;
7183e12c5d1SDavid du Colombier switch(c) {
7193e12c5d1SDavid du Colombier default:
7206b6b9ac8SDavid du Colombier diag("bad nuxi %d %d\n%P", c, i, curp);
7213e12c5d1SDavid du Colombier break;
7223e12c5d1SDavid du Colombier case 1:
7233e12c5d1SDavid du Colombier for(; i<c; i++) {
7243e12c5d1SDavid du Colombier buf.dbuf[l] = cast[inuxi1[i]];
7253e12c5d1SDavid du Colombier l++;
7263e12c5d1SDavid du Colombier }
7273e12c5d1SDavid du Colombier break;
7283e12c5d1SDavid du Colombier case 2:
7293e12c5d1SDavid du Colombier for(; i<c; i++) {
7303e12c5d1SDavid du Colombier buf.dbuf[l] = cast[inuxi2[i]];
7313e12c5d1SDavid du Colombier l++;
7323e12c5d1SDavid du Colombier }
7333e12c5d1SDavid du Colombier break;
7343e12c5d1SDavid du Colombier case 4:
7353e12c5d1SDavid du Colombier for(; i<c; i++) {
7363e12c5d1SDavid du Colombier buf.dbuf[l] = cast[inuxi4[i]];
7373e12c5d1SDavid du Colombier l++;
7383e12c5d1SDavid du Colombier }
7393e12c5d1SDavid du Colombier break;
7403e12c5d1SDavid du Colombier }
7413e12c5d1SDavid du Colombier break;
7423e12c5d1SDavid du Colombier }
7433e12c5d1SDavid du Colombier }
7443e12c5d1SDavid du Colombier write(cout, buf.dbuf, n);
7453e12c5d1SDavid du Colombier }
7463e12c5d1SDavid du Colombier
7473e12c5d1SDavid du Colombier #define OP_RRR(op,r1,r2,r3)\
7483e12c5d1SDavid du Colombier (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))
7493e12c5d1SDavid du Colombier #define OP_IRR(op,i,r2,r3)\
7503e12c5d1SDavid du Colombier (op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))
7513e12c5d1SDavid du Colombier #define OP_SRR(op,s,r2,r3)\
7523e12c5d1SDavid du Colombier (op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))
7533e12c5d1SDavid du Colombier #define OP_FRRR(op,r1,r2,r3)\
7543e12c5d1SDavid du Colombier (op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))
7553e12c5d1SDavid du Colombier #define OP_JMP(op,i)\
7563e12c5d1SDavid du Colombier ((op)|((i)&0x3ffffffL))
7573e12c5d1SDavid du Colombier
758219b2ee8SDavid du Colombier #define OP(x,y)\
759219b2ee8SDavid du Colombier (((x)<<3)|((y)<<0))
760219b2ee8SDavid du Colombier #define SP(x,y)\
761219b2ee8SDavid du Colombier (((x)<<29)|((y)<<26))
762219b2ee8SDavid du Colombier #define BCOND(x,y)\
763219b2ee8SDavid du Colombier (((x)<<19)|((y)<<16))
764219b2ee8SDavid du Colombier #define MMU(x,y)\
765219b2ee8SDavid du Colombier (SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))
766219b2ee8SDavid du Colombier #define FPF(x,y)\
767219b2ee8SDavid du Colombier (SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))
768219b2ee8SDavid du Colombier #define FPD(x,y)\
769219b2ee8SDavid du Colombier (SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))
770219b2ee8SDavid du Colombier #define FPW(x,y)\
771219b2ee8SDavid du Colombier (SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))
772219b2ee8SDavid du Colombier
773dc5a79c1SDavid du Colombier int vshift(int);
774dc5a79c1SDavid du Colombier
7753e12c5d1SDavid du Colombier int
asmout(Prog * p,Optab * o,int aflag)7763e12c5d1SDavid du Colombier asmout(Prog *p, Optab *o, int aflag)
7773e12c5d1SDavid du Colombier {
7787dd7cddfSDavid du Colombier long o1, o2, o3, o4, o5, o6, o7, v;
7793e12c5d1SDavid du Colombier Prog *ct;
7803e12c5d1SDavid du Colombier int r, a;
7813e12c5d1SDavid du Colombier
7823e12c5d1SDavid du Colombier o1 = 0;
7833e12c5d1SDavid du Colombier o2 = 0;
7843e12c5d1SDavid du Colombier o3 = 0;
7853e12c5d1SDavid du Colombier o4 = 0;
786219b2ee8SDavid du Colombier o5 = 0;
7877dd7cddfSDavid du Colombier o6 = 0;
7887dd7cddfSDavid du Colombier o7 = 0;
7893e12c5d1SDavid du Colombier switch(o->type) {
7903e12c5d1SDavid du Colombier default:
7916b6b9ac8SDavid du Colombier diag("unknown type %d", o->type);
7923e12c5d1SDavid du Colombier if(!debug['a'])
7933e12c5d1SDavid du Colombier prasm(p);
7943e12c5d1SDavid du Colombier break;
7953e12c5d1SDavid du Colombier
7963e12c5d1SDavid du Colombier case 0: /* pseudo ops */
7973e12c5d1SDavid du Colombier if(aflag) {
7983e12c5d1SDavid du Colombier if(p->link) {
7993e12c5d1SDavid du Colombier if(p->as == ATEXT) {
8003e12c5d1SDavid du Colombier ct = curtext;
8013e12c5d1SDavid du Colombier o2 = autosize;
8023e12c5d1SDavid du Colombier curtext = p;
8033e12c5d1SDavid du Colombier autosize = p->to.offset + 4;
8043e12c5d1SDavid du Colombier o1 = asmout(p->link, oplook(p->link), aflag);
8053e12c5d1SDavid du Colombier curtext = ct;
8063e12c5d1SDavid du Colombier autosize = o2;
8073e12c5d1SDavid du Colombier } else
8083e12c5d1SDavid du Colombier o1 = asmout(p->link, oplook(p->link), aflag);
8093e12c5d1SDavid du Colombier }
8103e12c5d1SDavid du Colombier return o1;
8113e12c5d1SDavid du Colombier }
8123e12c5d1SDavid du Colombier break;
8133e12c5d1SDavid du Colombier
814219b2ee8SDavid du Colombier case 1: /* mov[v] r1,r2 ==> OR r1,r0,r2 */
8153e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg);
8163e12c5d1SDavid du Colombier break;
8173e12c5d1SDavid du Colombier
8183e12c5d1SDavid du Colombier case 2: /* add/sub r1,[r2],r3 */
8193e12c5d1SDavid du Colombier r = p->reg;
8203e12c5d1SDavid du Colombier if(r == NREG)
8213e12c5d1SDavid du Colombier r = p->to.reg;
8223e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg);
8233e12c5d1SDavid du Colombier break;
8243e12c5d1SDavid du Colombier
8253e12c5d1SDavid du Colombier case 3: /* mov $soreg, r ==> or/add $i,o,r */
8263e12c5d1SDavid du Colombier v = regoff(&p->from);
8273e12c5d1SDavid du Colombier r = p->from.reg;
8283e12c5d1SDavid du Colombier if(r == NREG)
8293e12c5d1SDavid du Colombier r = o->param;
830219b2ee8SDavid du Colombier a = AADDU;
8313e12c5d1SDavid du Colombier if(o->a1 == C_ANDCON)
8323e12c5d1SDavid du Colombier a = AOR;
8333e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(a), v, r, p->to.reg);
8343e12c5d1SDavid du Colombier break;
8353e12c5d1SDavid du Colombier
8363e12c5d1SDavid du Colombier case 4: /* add $scon,[r1],r2 */
8373e12c5d1SDavid du Colombier v = regoff(&p->from);
8383e12c5d1SDavid du Colombier r = p->reg;
8393e12c5d1SDavid du Colombier if(r == NREG)
8403e12c5d1SDavid du Colombier r = p->to.reg;
8413e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(p->as), v, r, p->to.reg);
8423e12c5d1SDavid du Colombier break;
8433e12c5d1SDavid du Colombier
8443e12c5d1SDavid du Colombier case 5: /* syscall */
8453e12c5d1SDavid du Colombier if(aflag)
8463e12c5d1SDavid du Colombier return 0;
8473e12c5d1SDavid du Colombier o1 = oprrr(p->as);
8483e12c5d1SDavid du Colombier break;
8493e12c5d1SDavid du Colombier
8503e12c5d1SDavid du Colombier case 6: /* beq r1,[r2],sbra */
8513e12c5d1SDavid du Colombier if(aflag)
8523e12c5d1SDavid du Colombier return 0;
8533e12c5d1SDavid du Colombier if(p->cond == P)
8543e12c5d1SDavid du Colombier v = -4 >> 2;
8553e12c5d1SDavid du Colombier else
8563e12c5d1SDavid du Colombier v = (p->cond->pc - pc-4) >> 2;
8577dd7cddfSDavid du Colombier if(((v << 16) >> 16) != v)
858406758d9SDavid du Colombier diag("short branch too far: %ld\n%P", v, p);
8593e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg);
8603e12c5d1SDavid du Colombier break;
8613e12c5d1SDavid du Colombier
8623e12c5d1SDavid du Colombier case 7: /* mov r, soreg ==> sw o(r) */
8633e12c5d1SDavid du Colombier r = p->to.reg;
8643e12c5d1SDavid du Colombier if(r == NREG)
8653e12c5d1SDavid du Colombier r = o->param;
8663e12c5d1SDavid du Colombier v = regoff(&p->to);
8673e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(p->as), v, r, p->from.reg);
8683e12c5d1SDavid du Colombier break;
8693e12c5d1SDavid du Colombier
8703e12c5d1SDavid du Colombier case 8: /* mov soreg, r ==> lw o(r) */
8713e12c5d1SDavid du Colombier r = p->from.reg;
8723e12c5d1SDavid du Colombier if(r == NREG)
8733e12c5d1SDavid du Colombier r = o->param;
8743e12c5d1SDavid du Colombier v = regoff(&p->from);
875219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg);
8763e12c5d1SDavid du Colombier break;
8773e12c5d1SDavid du Colombier
8783e12c5d1SDavid du Colombier case 9: /* asl r1,[r2],r3 */
8793e12c5d1SDavid du Colombier r = p->reg;
8803e12c5d1SDavid du Colombier if(r == NREG)
8813e12c5d1SDavid du Colombier r = p->to.reg;
8823e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
8833e12c5d1SDavid du Colombier break;
8843e12c5d1SDavid du Colombier
8853e12c5d1SDavid du Colombier case 10: /* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */
8863e12c5d1SDavid du Colombier v = regoff(&p->from);
8873e12c5d1SDavid du Colombier r = AOR;
8883e12c5d1SDavid du Colombier if(v < 0)
889219b2ee8SDavid du Colombier r = AADDU;
8903e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(r), v, 0, REGTMP);
8913e12c5d1SDavid du Colombier r = p->reg;
8923e12c5d1SDavid du Colombier if(r == NREG)
8933e12c5d1SDavid du Colombier r = p->to.reg;
8943e12c5d1SDavid du Colombier o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
8953e12c5d1SDavid du Colombier break;
8963e12c5d1SDavid du Colombier
8973e12c5d1SDavid du Colombier case 11: /* jmp lbra */
8983e12c5d1SDavid du Colombier if(aflag)
8993e12c5d1SDavid du Colombier return 0;
9003e12c5d1SDavid du Colombier if(p->cond == P)
9013e12c5d1SDavid du Colombier v = p->pc >> 2;
9023e12c5d1SDavid du Colombier else
9033e12c5d1SDavid du Colombier v = p->cond->pc >> 2;
9043e12c5d1SDavid du Colombier o1 = OP_JMP(opirr(p->as), v);
905219b2ee8SDavid du Colombier if(!debug['Y'] && p->link && p->cond && isnop(p->link)) {
906219b2ee8SDavid du Colombier nop.branch.count--;
907219b2ee8SDavid du Colombier nop.branch.outof--;
908219b2ee8SDavid du Colombier nop.jump.outof++;
9093e12c5d1SDavid du Colombier o2 = asmout(p->cond, oplook(p->cond), 1);
9103e12c5d1SDavid du Colombier if(o2) {
9113e12c5d1SDavid du Colombier o1 += 1;
9123e12c5d1SDavid du Colombier if(debug['a'])
913a587111cSDavid du Colombier Bprint(&bso, " %.8llux: %.8lux %.8lux%P\n",
914219b2ee8SDavid du Colombier p->pc, o1, o2, p);
9153e12c5d1SDavid du Colombier LPUT(o1);
9163e12c5d1SDavid du Colombier LPUT(o2);
9173e12c5d1SDavid du Colombier return 1;
9183e12c5d1SDavid du Colombier }
9193e12c5d1SDavid du Colombier }
9203e12c5d1SDavid du Colombier break;
9213e12c5d1SDavid du Colombier
9223e12c5d1SDavid du Colombier case 12: /* movbs r,r */
9233e12c5d1SDavid du Colombier v = 16;
9243e12c5d1SDavid du Colombier if(p->as == AMOVB)
9253e12c5d1SDavid du Colombier v = 24;
9263e12c5d1SDavid du Colombier o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg);
9273e12c5d1SDavid du Colombier o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg);
9283e12c5d1SDavid du Colombier break;
9293e12c5d1SDavid du Colombier
9303e12c5d1SDavid du Colombier case 13: /* movbu r,r */
9313e12c5d1SDavid du Colombier if(p->as == AMOVBU)
9323e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg);
9333e12c5d1SDavid du Colombier else
9343e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg);
9353e12c5d1SDavid du Colombier break;
9363e12c5d1SDavid du Colombier
9373e12c5d1SDavid du Colombier case 16: /* sll $c,[r1],r2 */
9383e12c5d1SDavid du Colombier v = regoff(&p->from);
9393e12c5d1SDavid du Colombier r = p->reg;
9403e12c5d1SDavid du Colombier if(r == NREG)
9413e12c5d1SDavid du Colombier r = p->to.reg;
942dc5a79c1SDavid du Colombier
943dc5a79c1SDavid du Colombier /* OP_SRR will use only the low 5 bits of the shift value */
944dc5a79c1SDavid du Colombier if(v >= 32 && vshift(p->as))
945219b2ee8SDavid du Colombier o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg);
946219b2ee8SDavid du Colombier else
9473e12c5d1SDavid du Colombier o1 = OP_SRR(opirr(p->as), v, r, p->to.reg);
9483e12c5d1SDavid du Colombier break;
9493e12c5d1SDavid du Colombier
9503e12c5d1SDavid du Colombier case 18: /* jmp [r1],0(r2) */
9513e12c5d1SDavid du Colombier if(aflag)
9523e12c5d1SDavid du Colombier return 0;
9533e12c5d1SDavid du Colombier r = p->reg;
9543e12c5d1SDavid du Colombier if(r == NREG)
9553e12c5d1SDavid du Colombier r = o->param;
9563e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r);
9573e12c5d1SDavid du Colombier break;
9583e12c5d1SDavid du Colombier
9593e12c5d1SDavid du Colombier case 19: /* mov $lcon,r ==> lu+or */
9603e12c5d1SDavid du Colombier v = regoff(&p->from);
961219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9623e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg);
9633e12c5d1SDavid du Colombier break;
9643e12c5d1SDavid du Colombier
965219b2ee8SDavid du Colombier case 20: /* mov lohi,r */
966219b2ee8SDavid du Colombier r = OP(2,0); /* mfhi */
9673e12c5d1SDavid du Colombier if(p->from.type == D_LO)
968219b2ee8SDavid du Colombier r = OP(2,2); /* mflo */
969219b2ee8SDavid du Colombier o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg);
9703e12c5d1SDavid du Colombier break;
9713e12c5d1SDavid du Colombier
972219b2ee8SDavid du Colombier case 21: /* mov r,lohi */
973219b2ee8SDavid du Colombier r = OP(2,1); /* mthi */
9743e12c5d1SDavid du Colombier if(p->to.type == D_LO)
975219b2ee8SDavid du Colombier r = OP(2,3); /* mtlo */
976219b2ee8SDavid du Colombier o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO);
9773e12c5d1SDavid du Colombier break;
9783e12c5d1SDavid du Colombier
9793e12c5d1SDavid du Colombier case 22: /* mul r1,r2 */
9803e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO);
9813e12c5d1SDavid du Colombier break;
9823e12c5d1SDavid du Colombier
9833e12c5d1SDavid du Colombier case 23: /* add $lcon,r1,r2 ==> lu+or+add */
9843e12c5d1SDavid du Colombier v = regoff(&p->from);
9853e12c5d1SDavid du Colombier if(p->to.reg == REGTMP || p->reg == REGTMP)
9866b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p);
987219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
9883e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
9893e12c5d1SDavid du Colombier r = p->reg;
9903e12c5d1SDavid du Colombier if(r == NREG)
9913e12c5d1SDavid du Colombier r = p->to.reg;
9923e12c5d1SDavid du Colombier o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
9933e12c5d1SDavid du Colombier break;
9943e12c5d1SDavid du Colombier
9953e12c5d1SDavid du Colombier case 24: /* mov $ucon,,r ==> lu r */
9963e12c5d1SDavid du Colombier v = regoff(&p->from);
997219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
9983e12c5d1SDavid du Colombier break;
9993e12c5d1SDavid du Colombier
10003e12c5d1SDavid du Colombier case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */
10013e12c5d1SDavid du Colombier v = regoff(&p->from);
1002219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
10033e12c5d1SDavid du Colombier r = p->reg;
10043e12c5d1SDavid du Colombier if(r == NREG)
10053e12c5d1SDavid du Colombier r = p->to.reg;
10063e12c5d1SDavid du Colombier o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
10073e12c5d1SDavid du Colombier break;
10083e12c5d1SDavid du Colombier
10093e12c5d1SDavid du Colombier case 26: /* mov $lsext/auto/oreg,,r2 ==> lu+or+add */
10103e12c5d1SDavid du Colombier v = regoff(&p->from);
10113e12c5d1SDavid du Colombier if(p->to.reg == REGTMP)
10126b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p);
1013219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
10143e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
10153e12c5d1SDavid du Colombier r = p->from.reg;
10163e12c5d1SDavid du Colombier if(r == NREG)
10173e12c5d1SDavid du Colombier r = o->param;
1018219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg);
10193e12c5d1SDavid du Colombier break;
10203e12c5d1SDavid du Colombier
10213e12c5d1SDavid du Colombier case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
10223e12c5d1SDavid du Colombier r = p->from.reg;
10233e12c5d1SDavid du Colombier if(r == NREG)
10243e12c5d1SDavid du Colombier r = o->param;
10253e12c5d1SDavid du Colombier v = regoff(&p->from);
10263e12c5d1SDavid du Colombier switch(o->size) {
1027219b2ee8SDavid du Colombier case 20:
1028219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1029219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1030219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1031*12b1df16SDavid du Colombier if(little) {
1032*12b1df16SDavid du Colombier o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg);
1033*12b1df16SDavid du Colombier o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg+1);
1034*12b1df16SDavid du Colombier } else {
1035219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1);
1036219b2ee8SDavid du Colombier o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg);
1037*12b1df16SDavid du Colombier }
10383e12c5d1SDavid du Colombier break;
1039219b2ee8SDavid du Colombier case 16:
1040219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1041219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1042219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1043219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg);
10443e12c5d1SDavid du Colombier break;
10453e12c5d1SDavid du Colombier case 8:
1046*12b1df16SDavid du Colombier if(little) {
1047*12b1df16SDavid du Colombier o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg);
1048*12b1df16SDavid du Colombier o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg+1);
1049*12b1df16SDavid du Colombier } else {
1050219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1);
1051219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg);
1052*12b1df16SDavid du Colombier }
10533e12c5d1SDavid du Colombier break;
10543e12c5d1SDavid du Colombier case 4:
1055219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg);
10563e12c5d1SDavid du Colombier break;
10573e12c5d1SDavid du Colombier }
10583e12c5d1SDavid du Colombier break;
10593e12c5d1SDavid du Colombier
10603e12c5d1SDavid du Colombier case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */
10613e12c5d1SDavid du Colombier r = p->to.reg;
10623e12c5d1SDavid du Colombier if(r == NREG)
10633e12c5d1SDavid du Colombier r = o->param;
10643e12c5d1SDavid du Colombier v = regoff(&p->to);
10653e12c5d1SDavid du Colombier switch(o->size) {
1066219b2ee8SDavid du Colombier case 20:
1067219b2ee8SDavid du Colombier if(r == REGTMP)
10686b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p);
1069219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1070219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1071219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1072*12b1df16SDavid du Colombier if(little) {
1073*12b1df16SDavid du Colombier o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg);
1074*12b1df16SDavid du Colombier o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg+1);
1075*12b1df16SDavid du Colombier } else {
1076219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1);
1077219b2ee8SDavid du Colombier o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg);
1078*12b1df16SDavid du Colombier }
10793e12c5d1SDavid du Colombier break;
1080219b2ee8SDavid du Colombier case 16:
1081219b2ee8SDavid du Colombier if(r == REGTMP)
10826b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p);
1083219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1084219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1085219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1086219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg);
10873e12c5d1SDavid du Colombier break;
10883e12c5d1SDavid du Colombier case 8:
1089*12b1df16SDavid du Colombier if(little) {
1090*12b1df16SDavid du Colombier o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg);
1091*12b1df16SDavid du Colombier o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg+1);
1092*12b1df16SDavid du Colombier } else {
10933e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1);
10943e12c5d1SDavid du Colombier o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg);
1095*12b1df16SDavid du Colombier }
10963e12c5d1SDavid du Colombier break;
10973e12c5d1SDavid du Colombier case 4:
10983e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg);
10993e12c5d1SDavid du Colombier break;
11003e12c5d1SDavid du Colombier }
11013e12c5d1SDavid du Colombier break;
11023e12c5d1SDavid du Colombier
11033e12c5d1SDavid du Colombier case 30: /* movw r,fr */
1104219b2ee8SDavid du Colombier r = SP(2,1)|(4<<21); /* mtc1 */
1105219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
11063e12c5d1SDavid du Colombier break;
11073e12c5d1SDavid du Colombier
11083e12c5d1SDavid du Colombier case 31: /* movw fr,r */
1109219b2ee8SDavid du Colombier r = SP(2,1)|(0<<21); /* mfc1 */
1110219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
11113e12c5d1SDavid du Colombier break;
11123e12c5d1SDavid du Colombier
11133e12c5d1SDavid du Colombier case 32: /* fadd fr1,[fr2],fr3 */
11143e12c5d1SDavid du Colombier r = p->reg;
11153e12c5d1SDavid du Colombier if(r == NREG)
11163e12c5d1SDavid du Colombier o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg);
11173e12c5d1SDavid du Colombier else
11183e12c5d1SDavid du Colombier o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg);
11193e12c5d1SDavid du Colombier break;
11203e12c5d1SDavid du Colombier
11213e12c5d1SDavid du Colombier case 33: /* fabs fr1,fr3 */
11223e12c5d1SDavid du Colombier o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg);
11233e12c5d1SDavid du Colombier break;
11243e12c5d1SDavid du Colombier
11253e12c5d1SDavid du Colombier case 34: /* mov $con,fr ==> or/add $i,r,r2 */
11263e12c5d1SDavid du Colombier v = regoff(&p->from);
1127219b2ee8SDavid du Colombier r = AADDU;
11283e12c5d1SDavid du Colombier if(o->a1 == C_ANDCON)
11293e12c5d1SDavid du Colombier r = AOR;
11303e12c5d1SDavid du Colombier o1 = OP_IRR(opirr(r), v, 0, REGTMP);
1131219b2ee8SDavid du Colombier o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg); /* mtc1 */
11323e12c5d1SDavid du Colombier break;
11333e12c5d1SDavid du Colombier
11343e12c5d1SDavid du Colombier case 35: /* mov r,lext/luto/oreg ==> sw o(r) */
1135219b2ee8SDavid du Colombier /*
1136219b2ee8SDavid du Colombier * the lowbits of the constant cannot
1137219b2ee8SDavid du Colombier * be moved into the offset of the load
1138219b2ee8SDavid du Colombier * because the mips 4000 in 64-bit mode
1139219b2ee8SDavid du Colombier * does a 64-bit add and it will screw up.
1140219b2ee8SDavid du Colombier */
11413e12c5d1SDavid du Colombier v = regoff(&p->to);
11423e12c5d1SDavid du Colombier r = p->to.reg;
11433e12c5d1SDavid du Colombier if(r == NREG)
11443e12c5d1SDavid du Colombier r = o->param;
1145219b2ee8SDavid du Colombier if(r == REGTMP)
11466b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p);
1147219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1148219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1149219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1150219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg);
11513e12c5d1SDavid du Colombier break;
11523e12c5d1SDavid du Colombier
11533e12c5d1SDavid du Colombier case 36: /* mov lext/lauto/lreg,r ==> lw o(r30) */
11543e12c5d1SDavid du Colombier v = regoff(&p->from);
11553e12c5d1SDavid du Colombier r = p->from.reg;
11563e12c5d1SDavid du Colombier if(r == NREG)
11573e12c5d1SDavid du Colombier r = o->param;
1158219b2ee8SDavid du Colombier if(r == REGTMP)
11596b6b9ac8SDavid du Colombier diag("cant synthesize large constant\n%P", p);
1160219b2ee8SDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
1161219b2ee8SDavid du Colombier o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
1162219b2ee8SDavid du Colombier o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
1163219b2ee8SDavid du Colombier o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg);
11643e12c5d1SDavid du Colombier break;
11653e12c5d1SDavid du Colombier
11663e12c5d1SDavid du Colombier case 37: /* movw r,mr */
1167219b2ee8SDavid du Colombier r = SP(2,0)|(4<<21); /* mtc0 */
1168219b2ee8SDavid du Colombier if(p->as == AMOVV)
1169219b2ee8SDavid du Colombier r = SP(2,0)|(5<<21); /* dmtc0 */
1170219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
11713e12c5d1SDavid du Colombier break;
11723e12c5d1SDavid du Colombier
11733e12c5d1SDavid du Colombier case 38: /* movw mr,r */
1174219b2ee8SDavid du Colombier r = SP(2,0)|(0<<21); /* mfc0 */
1175219b2ee8SDavid du Colombier if(p->as == AMOVV)
1176219b2ee8SDavid du Colombier r = SP(2,0)|(1<<21); /* dmfc0 */
1177219b2ee8SDavid du Colombier o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
11783e12c5d1SDavid du Colombier break;
11793e12c5d1SDavid du Colombier
11803e12c5d1SDavid du Colombier case 39: /* rfe ==> jmp+rfe */
11813e12c5d1SDavid du Colombier if(aflag)
11823e12c5d1SDavid du Colombier return 0;
11833e12c5d1SDavid du Colombier o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO);
11843e12c5d1SDavid du Colombier o2 = oprrr(p->as);
11853e12c5d1SDavid du Colombier break;
11863e12c5d1SDavid du Colombier
11873e12c5d1SDavid du Colombier case 40: /* word */
11883e12c5d1SDavid du Colombier if(aflag)
11893e12c5d1SDavid du Colombier return 0;
11903e12c5d1SDavid du Colombier o1 = regoff(&p->to);
11913e12c5d1SDavid du Colombier break;
11923e12c5d1SDavid du Colombier
11933e12c5d1SDavid du Colombier case 41: /* movw r,fcr */
1194219b2ee8SDavid du Colombier o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); /* mfcc1 */
1195219b2ee8SDavid du Colombier o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */
11963e12c5d1SDavid du Colombier break;
11973e12c5d1SDavid du Colombier
11983e12c5d1SDavid du Colombier case 42: /* movw fcr,r */
1199219b2ee8SDavid du Colombier o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */
12003e12c5d1SDavid du Colombier break;
12017dd7cddfSDavid du Colombier
12027dd7cddfSDavid du Colombier case 45: /* case r */
12037dd7cddfSDavid du Colombier if(p->link == P)
12047dd7cddfSDavid du Colombier v = p->pc+28;
12057dd7cddfSDavid du Colombier else
12067dd7cddfSDavid du Colombier v = p->link->pc;
12077dd7cddfSDavid du Colombier if(v & (1<<15))
12087dd7cddfSDavid du Colombier o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP);
12097dd7cddfSDavid du Colombier else
12107dd7cddfSDavid du Colombier o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
12117dd7cddfSDavid du Colombier o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg);
12127dd7cddfSDavid du Colombier o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP);
12137dd7cddfSDavid du Colombier o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP);
12147dd7cddfSDavid du Colombier o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
12157dd7cddfSDavid du Colombier o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO);
12167dd7cddfSDavid du Colombier o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
12177dd7cddfSDavid du Colombier break;
12187dd7cddfSDavid du Colombier
12197dd7cddfSDavid du Colombier case 46: /* bcase $con,lbra */
12207dd7cddfSDavid du Colombier if(p->cond == P)
12217dd7cddfSDavid du Colombier v = p->pc;
12227dd7cddfSDavid du Colombier else
12237dd7cddfSDavid du Colombier v = p->cond->pc;
12247dd7cddfSDavid du Colombier o1 = v;
12257dd7cddfSDavid du Colombier break;
12263e12c5d1SDavid du Colombier }
12273e12c5d1SDavid du Colombier if(aflag)
12283e12c5d1SDavid du Colombier return o1;
12293e12c5d1SDavid du Colombier v = p->pc;
12303e12c5d1SDavid du Colombier switch(o->size) {
12313e12c5d1SDavid du Colombier default:
12323e12c5d1SDavid du Colombier if(debug['a'])
12333e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
12343e12c5d1SDavid du Colombier break;
12353e12c5d1SDavid du Colombier case 4:
12363e12c5d1SDavid du Colombier if(debug['a'])
12373e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
12383e12c5d1SDavid du Colombier LPUT(o1);
12393e12c5d1SDavid du Colombier break;
12403e12c5d1SDavid du Colombier case 8:
12413e12c5d1SDavid du Colombier if(debug['a'])
12423e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
12433e12c5d1SDavid du Colombier LPUT(o1);
12443e12c5d1SDavid du Colombier LPUT(o2);
12453e12c5d1SDavid du Colombier break;
12463e12c5d1SDavid du Colombier case 12:
12473e12c5d1SDavid du Colombier if(debug['a'])
12483e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
12493e12c5d1SDavid du Colombier LPUT(o1);
12503e12c5d1SDavid du Colombier LPUT(o2);
12513e12c5d1SDavid du Colombier LPUT(o3);
12523e12c5d1SDavid du Colombier break;
12533e12c5d1SDavid du Colombier case 16:
12543e12c5d1SDavid du Colombier if(debug['a'])
12553e12c5d1SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
12563e12c5d1SDavid du Colombier v, o1, o2, o3, o4, p);
12573e12c5d1SDavid du Colombier LPUT(o1);
12583e12c5d1SDavid du Colombier LPUT(o2);
12593e12c5d1SDavid du Colombier LPUT(o3);
12603e12c5d1SDavid du Colombier LPUT(o4);
12613e12c5d1SDavid du Colombier break;
1262219b2ee8SDavid du Colombier case 20:
1263219b2ee8SDavid du Colombier if(debug['a'])
1264219b2ee8SDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
1265219b2ee8SDavid du Colombier v, o1, o2, o3, o4, o5, p);
1266219b2ee8SDavid du Colombier LPUT(o1);
1267219b2ee8SDavid du Colombier LPUT(o2);
1268219b2ee8SDavid du Colombier LPUT(o3);
1269219b2ee8SDavid du Colombier LPUT(o4);
1270219b2ee8SDavid du Colombier LPUT(o5);
1271219b2ee8SDavid du Colombier break;
12727dd7cddfSDavid du Colombier
12737dd7cddfSDavid du Colombier case 28:
12747dd7cddfSDavid du Colombier if(debug['a'])
12757dd7cddfSDavid du Colombier Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
12767dd7cddfSDavid du Colombier v, o1, o2, o3, o4, o5, o6, o7, p);
12777dd7cddfSDavid du Colombier LPUT(o1);
12787dd7cddfSDavid du Colombier LPUT(o2);
12797dd7cddfSDavid du Colombier LPUT(o3);
12807dd7cddfSDavid du Colombier LPUT(o4);
12817dd7cddfSDavid du Colombier LPUT(o5);
12827dd7cddfSDavid du Colombier LPUT(o6);
12837dd7cddfSDavid du Colombier LPUT(o7);
12847dd7cddfSDavid du Colombier break;
12853e12c5d1SDavid du Colombier }
12863e12c5d1SDavid du Colombier return 0;
12873e12c5d1SDavid du Colombier }
12883e12c5d1SDavid du Colombier
1289219b2ee8SDavid du Colombier int
isnop(Prog * p)1290219b2ee8SDavid du Colombier isnop(Prog *p)
1291219b2ee8SDavid du Colombier {
1292219b2ee8SDavid du Colombier if(p->as != ANOR)
1293219b2ee8SDavid du Colombier return 0;
1294219b2ee8SDavid du Colombier if(p->reg != REGZERO && p->reg != NREG)
1295219b2ee8SDavid du Colombier return 0;
1296219b2ee8SDavid du Colombier if(p->from.type != D_REG || p->from.reg != REGZERO)
1297219b2ee8SDavid du Colombier return 0;
1298219b2ee8SDavid du Colombier if(p->to.type != D_REG || p->to.reg != REGZERO)
1299219b2ee8SDavid du Colombier return 0;
1300219b2ee8SDavid du Colombier return 1;
1301219b2ee8SDavid du Colombier }
13023e12c5d1SDavid du Colombier
13033e12c5d1SDavid du Colombier long
oprrr(int a)13043e12c5d1SDavid du Colombier oprrr(int a)
13053e12c5d1SDavid du Colombier {
13063e12c5d1SDavid du Colombier switch(a) {
13073e12c5d1SDavid du Colombier case AADD: return OP(4,0);
13083e12c5d1SDavid du Colombier case AADDU: return OP(4,1);
13093e12c5d1SDavid du Colombier case ASGT: return OP(5,2);
13103e12c5d1SDavid du Colombier case ASGTU: return OP(5,3);
13113e12c5d1SDavid du Colombier case AAND: return OP(4,4);
13123e12c5d1SDavid du Colombier case AOR: return OP(4,5);
13133e12c5d1SDavid du Colombier case AXOR: return OP(4,6);
13143e12c5d1SDavid du Colombier case ASUB: return OP(4,2);
13153e12c5d1SDavid du Colombier case ASUBU: return OP(4,3);
13163e12c5d1SDavid du Colombier case ANOR: return OP(4,7);
13173e12c5d1SDavid du Colombier case ASLL: return OP(0,4);
13183e12c5d1SDavid du Colombier case ASRL: return OP(0,6);
13193e12c5d1SDavid du Colombier case ASRA: return OP(0,7);
13203e12c5d1SDavid du Colombier
13213e12c5d1SDavid du Colombier case AREM:
13223e12c5d1SDavid du Colombier case ADIV: return OP(3,2);
13233e12c5d1SDavid du Colombier case AREMU:
13243e12c5d1SDavid du Colombier case ADIVU: return OP(3,3);
13253e12c5d1SDavid du Colombier case AMUL: return OP(3,0);
13263e12c5d1SDavid du Colombier case AMULU: return OP(3,1);
13273e12c5d1SDavid du Colombier
13283e12c5d1SDavid du Colombier case AJMP: return OP(1,0);
13293e12c5d1SDavid du Colombier case AJAL: return OP(1,1);
13303e12c5d1SDavid du Colombier
13313e12c5d1SDavid du Colombier case ABREAK: return OP(1,5);
13323e12c5d1SDavid du Colombier case ASYSCALL: return OP(1,4);
13333e12c5d1SDavid du Colombier case ATLBP: return MMU(1,0);
13343e12c5d1SDavid du Colombier case ATLBR: return MMU(0,1);
13353e12c5d1SDavid du Colombier case ATLBWI: return MMU(0,2);
13363e12c5d1SDavid du Colombier case ATLBWR: return MMU(0,6);
13373e12c5d1SDavid du Colombier case ARFE: return MMU(2,0);
13383e12c5d1SDavid du Colombier
13393e12c5d1SDavid du Colombier case ADIVF: return FPF(0,3);
13403e12c5d1SDavid du Colombier case ADIVD: return FPD(0,3);
13413e12c5d1SDavid du Colombier case AMULF: return FPF(0,2);
13423e12c5d1SDavid du Colombier case AMULD: return FPD(0,2);
13433e12c5d1SDavid du Colombier case ASUBF: return FPF(0,1);
13443e12c5d1SDavid du Colombier case ASUBD: return FPD(0,1);
13453e12c5d1SDavid du Colombier case AADDF: return FPF(0,0);
13463e12c5d1SDavid du Colombier case AADDD: return FPD(0,0);
13473e12c5d1SDavid du Colombier
13483e12c5d1SDavid du Colombier case AMOVFW: return FPF(4,4);
13493e12c5d1SDavid du Colombier case AMOVDW: return FPD(4,4);
13503e12c5d1SDavid du Colombier case AMOVWF: return FPW(4,0);
13513e12c5d1SDavid du Colombier case AMOVDF: return FPD(4,0);
13523e12c5d1SDavid du Colombier case AMOVWD: return FPW(4,1);
13533e12c5d1SDavid du Colombier case AMOVFD: return FPF(4,1);
13543e12c5d1SDavid du Colombier case AABSF: return FPF(0,5);
13553e12c5d1SDavid du Colombier case AABSD: return FPD(0,5);
13563e12c5d1SDavid du Colombier case AMOVF: return FPF(0,6);
13573e12c5d1SDavid du Colombier case AMOVD: return FPD(0,6);
13583e12c5d1SDavid du Colombier case ANEGF: return FPF(0,7);
13593e12c5d1SDavid du Colombier case ANEGD: return FPD(0,7);
13603e12c5d1SDavid du Colombier
13613e12c5d1SDavid du Colombier case ACMPEQF: return FPF(6,2);
13623e12c5d1SDavid du Colombier case ACMPEQD: return FPD(6,2);
13633e12c5d1SDavid du Colombier case ACMPGTF: return FPF(7,4);
13643e12c5d1SDavid du Colombier case ACMPGTD: return FPD(7,4);
13653e12c5d1SDavid du Colombier case ACMPGEF: return FPF(7,6);
13663e12c5d1SDavid du Colombier case ACMPGED: return FPD(7,6);
13677dd7cddfSDavid du Colombier
13687dd7cddfSDavid du Colombier case ADIVV: return OP(3,6);
13697dd7cddfSDavid du Colombier case ADIVVU: return OP(3,7);
13707dd7cddfSDavid du Colombier case AADDV: return OP(5,4);
13717dd7cddfSDavid du Colombier case AADDVU: return OP(5,5);
13723e12c5d1SDavid du Colombier }
13736b6b9ac8SDavid du Colombier diag("bad rrr %d", a);
13743e12c5d1SDavid du Colombier return 0;
13753e12c5d1SDavid du Colombier }
13763e12c5d1SDavid du Colombier
13773e12c5d1SDavid du Colombier long
opirr(int a)13783e12c5d1SDavid du Colombier opirr(int a)
13793e12c5d1SDavid du Colombier {
13803e12c5d1SDavid du Colombier switch(a) {
13813e12c5d1SDavid du Colombier case AADD: return SP(1,0);
13823e12c5d1SDavid du Colombier case AADDU: return SP(1,1);
13833e12c5d1SDavid du Colombier case ASGT: return SP(1,2);
13843e12c5d1SDavid du Colombier case ASGTU: return SP(1,3);
13853e12c5d1SDavid du Colombier case AAND: return SP(1,4);
13863e12c5d1SDavid du Colombier case AOR: return SP(1,5);
13873e12c5d1SDavid du Colombier case AXOR: return SP(1,6);
1388219b2ee8SDavid du Colombier case ALAST: return SP(1,7);
13893e12c5d1SDavid du Colombier case ASLL: return OP(0,0);
13903e12c5d1SDavid du Colombier case ASRL: return OP(0,2);
13913e12c5d1SDavid du Colombier case ASRA: return OP(0,3);
13923e12c5d1SDavid du Colombier
13933e12c5d1SDavid du Colombier case AJMP: return SP(0,2);
13943e12c5d1SDavid du Colombier case AJAL: return SP(0,3);
13953e12c5d1SDavid du Colombier case ABEQ: return SP(0,4);
13963e12c5d1SDavid du Colombier case ABNE: return SP(0,5);
13973e12c5d1SDavid du Colombier
13983e12c5d1SDavid du Colombier case ABGEZ: return SP(0,1)|BCOND(0,1);
13993e12c5d1SDavid du Colombier case ABGEZAL: return SP(0,1)|BCOND(2,1);
14003e12c5d1SDavid du Colombier case ABGTZ: return SP(0,7);
14013e12c5d1SDavid du Colombier case ABLEZ: return SP(0,6);
14023e12c5d1SDavid du Colombier case ABLTZ: return SP(0,1)|BCOND(0,0);
14033e12c5d1SDavid du Colombier case ABLTZAL: return SP(0,1)|BCOND(2,0);
14043e12c5d1SDavid du Colombier
14053e12c5d1SDavid du Colombier case ABFPT: return SP(2,1)|(257<<16);
14063e12c5d1SDavid du Colombier case ABFPF: return SP(2,1)|(256<<16);
14073e12c5d1SDavid du Colombier
14083e12c5d1SDavid du Colombier case AMOVB:
14093e12c5d1SDavid du Colombier case AMOVBU: return SP(5,0);
14103e12c5d1SDavid du Colombier case AMOVH:
14113e12c5d1SDavid du Colombier case AMOVHU: return SP(5,1);
14123e12c5d1SDavid du Colombier case AMOVW: return SP(5,3);
1413219b2ee8SDavid du Colombier case AMOVV: return SP(7,7);
14143e12c5d1SDavid du Colombier case AMOVF: return SP(7,1);
14153e12c5d1SDavid du Colombier case AMOVWL: return SP(5,2);
14163e12c5d1SDavid du Colombier case AMOVWR: return SP(5,6);
1417219b2ee8SDavid du Colombier case AMOVVL: return SP(5,4);
1418219b2ee8SDavid du Colombier case AMOVVR: return SP(5,5);
14193e12c5d1SDavid du Colombier
1420bd389b36SDavid du Colombier case ABREAK: return SP(5,7);
1421bd389b36SDavid du Colombier
1422219b2ee8SDavid du Colombier case AMOVWL+ALAST: return SP(4,2);
1423219b2ee8SDavid du Colombier case AMOVWR+ALAST: return SP(4,6);
1424219b2ee8SDavid du Colombier case AMOVVL+ALAST: return SP(3,2);
1425219b2ee8SDavid du Colombier case AMOVVR+ALAST: return SP(3,3);
1426219b2ee8SDavid du Colombier case AMOVB+ALAST: return SP(4,0);
1427219b2ee8SDavid du Colombier case AMOVBU+ALAST: return SP(4,4);
1428219b2ee8SDavid du Colombier case AMOVH+ALAST: return SP(4,1);
1429219b2ee8SDavid du Colombier case AMOVHU+ALAST: return SP(4,5);
1430219b2ee8SDavid du Colombier case AMOVW+ALAST: return SP(4,3);
1431219b2ee8SDavid du Colombier case AMOVV+ALAST: return SP(6,7);
1432219b2ee8SDavid du Colombier case AMOVF+ALAST: return SP(6,1);
14333e12c5d1SDavid du Colombier
1434219b2ee8SDavid du Colombier case ASLLV: return OP(7,0);
1435219b2ee8SDavid du Colombier case ASRLV: return OP(7,2);
1436219b2ee8SDavid du Colombier case ASRAV: return OP(7,3);
1437219b2ee8SDavid du Colombier case ASLLV+ALAST: return OP(7,4);
1438219b2ee8SDavid du Colombier case ASRLV+ALAST: return OP(7,6);
1439219b2ee8SDavid du Colombier case ASRAV+ALAST: return OP(7,7);
14407dd7cddfSDavid du Colombier
14417dd7cddfSDavid du Colombier case AADDV: return SP(3,0);
14427dd7cddfSDavid du Colombier case AADDVU: return SP(3,1);
14433e12c5d1SDavid du Colombier }
14446b6b9ac8SDavid du Colombier diag("bad irr %d", a);
1445dc5a79c1SDavid du Colombier abort();
1446dc5a79c1SDavid du Colombier return 0;
1447dc5a79c1SDavid du Colombier }
1448dc5a79c1SDavid du Colombier
1449dc5a79c1SDavid du Colombier int
vshift(int a)1450dc5a79c1SDavid du Colombier vshift(int a)
1451dc5a79c1SDavid du Colombier {
1452dc5a79c1SDavid du Colombier switch(a){
1453dc5a79c1SDavid du Colombier case ASLLV: return 1;
1454dc5a79c1SDavid du Colombier case ASRLV: return 1;
1455dc5a79c1SDavid du Colombier case ASRAV: return 1;
1456dc5a79c1SDavid du Colombier }
14573e12c5d1SDavid du Colombier return 0;
14583e12c5d1SDavid du Colombier }
1459