17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <mach.h>
57dd7cddfSDavid du Colombier
67dd7cddfSDavid du Colombier /*
747ad9175SDavid du Colombier * PowerPC-specific debugger interface,
847ad9175SDavid du Colombier * including 64-bit modes
9b0dcc5a8SDavid du Colombier * forsyth@terzarima.net
107dd7cddfSDavid du Colombier */
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier static char *powerexcep(Map*, Rgetter);
134de34a7eSDavid du Colombier static int powerfoll(Map*, uvlong, Rgetter, uvlong*);
144de34a7eSDavid du Colombier static int powerinst(Map*, uvlong, char, char*, int);
154de34a7eSDavid du Colombier static int powerinstlen(Map*, uvlong);
164de34a7eSDavid du Colombier static int powerdas(Map*, uvlong, char*, int);
177dd7cddfSDavid du Colombier
187dd7cddfSDavid du Colombier /*
197dd7cddfSDavid du Colombier * Machine description
207dd7cddfSDavid du Colombier */
217dd7cddfSDavid du Colombier Machdata powermach =
227dd7cddfSDavid du Colombier {
237dd7cddfSDavid du Colombier {0x02, 0x8f, 0xff, 0xff}, /* break point */ /* BUG */
247dd7cddfSDavid du Colombier 4, /* break point size */
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier beswab, /* short to local byte order */
277dd7cddfSDavid du Colombier beswal, /* long to local byte order */
287dd7cddfSDavid du Colombier beswav, /* vlong to local byte order */
297dd7cddfSDavid du Colombier risctrace, /* print C traceback */
307dd7cddfSDavid du Colombier riscframe, /* frame finder */
317dd7cddfSDavid du Colombier powerexcep, /* print exception */
327dd7cddfSDavid du Colombier 0, /* breakpoint fixup */
337dd7cddfSDavid du Colombier beieeesftos, /* single precision float printer */
347dd7cddfSDavid du Colombier beieeedftos, /* double precisioin float printer */
357dd7cddfSDavid du Colombier powerfoll, /* following addresses */
367dd7cddfSDavid du Colombier powerinst, /* print instruction */
377dd7cddfSDavid du Colombier powerdas, /* dissembler */
387dd7cddfSDavid du Colombier powerinstlen, /* instruction size */
397dd7cddfSDavid du Colombier };
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier static char *excname[] =
427dd7cddfSDavid du Colombier {
437dd7cddfSDavid du Colombier "reserved 0",
447dd7cddfSDavid du Colombier "system reset",
457dd7cddfSDavid du Colombier "machine check",
467dd7cddfSDavid du Colombier "data access",
477dd7cddfSDavid du Colombier "instruction access",
487dd7cddfSDavid du Colombier "external interrupt",
497dd7cddfSDavid du Colombier "alignment",
507dd7cddfSDavid du Colombier "program exception",
517dd7cddfSDavid du Colombier "floating-point unavailable",
527dd7cddfSDavid du Colombier "decrementer",
537dd7cddfSDavid du Colombier "i/o controller interface error",
547dd7cddfSDavid du Colombier "reserved B",
557dd7cddfSDavid du Colombier "system call",
567dd7cddfSDavid du Colombier "trace trap",
577dd7cddfSDavid du Colombier "floating point assist",
587dd7cddfSDavid du Colombier "reserved",
597dd7cddfSDavid du Colombier "ITLB miss",
607dd7cddfSDavid du Colombier "DTLB load miss",
617dd7cddfSDavid du Colombier "DTLB store miss",
627dd7cddfSDavid du Colombier "instruction address breakpoint"
637dd7cddfSDavid du Colombier "SMI interrupt"
647dd7cddfSDavid du Colombier "reserved 15",
657dd7cddfSDavid du Colombier "reserved 16",
667dd7cddfSDavid du Colombier "reserved 17",
677dd7cddfSDavid du Colombier "reserved 18",
687dd7cddfSDavid du Colombier "reserved 19",
697dd7cddfSDavid du Colombier "reserved 1A",
707dd7cddfSDavid du Colombier /* the following are made up on a program exception */
717dd7cddfSDavid du Colombier "floating point exception", /* FPEXC */
727dd7cddfSDavid du Colombier "illegal instruction",
737dd7cddfSDavid du Colombier "privileged instruction",
747dd7cddfSDavid du Colombier "trap",
757dd7cddfSDavid du Colombier "illegal operation",
767dd7cddfSDavid du Colombier };
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier static char*
powerexcep(Map * map,Rgetter rget)797dd7cddfSDavid du Colombier powerexcep(Map *map, Rgetter rget)
807dd7cddfSDavid du Colombier {
817dd7cddfSDavid du Colombier long c;
827dd7cddfSDavid du Colombier static char buf[32];
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du Colombier c = (*rget)(map, "CAUSE") >> 8;
857dd7cddfSDavid du Colombier if(c < nelem(excname))
867dd7cddfSDavid du Colombier return excname[c];
877dd7cddfSDavid du Colombier sprint(buf, "unknown trap #%lx", c);
887dd7cddfSDavid du Colombier return buf;
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier /*
927dd7cddfSDavid du Colombier * disassemble PowerPC opcodes
937dd7cddfSDavid du Colombier */
947dd7cddfSDavid du Colombier
957dd7cddfSDavid du Colombier #define REGSP 1 /* should come from q.out.h, but there's a clash */
967dd7cddfSDavid du Colombier #define REGSB 2
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier static char FRAMENAME[] = ".frame";
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier static Map *mymap;
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier /*
1037dd7cddfSDavid du Colombier * ibm conventions for these: bit 0 is top bit
1047dd7cddfSDavid du Colombier * from table 10-1
1057dd7cddfSDavid du Colombier */
1067dd7cddfSDavid du Colombier typedef struct {
1077dd7cddfSDavid du Colombier uchar aa; /* bit 30 */
1087dd7cddfSDavid du Colombier uchar crba; /* bits 11-15 */
1097dd7cddfSDavid du Colombier uchar crbb; /* bits 16-20 */
1107dd7cddfSDavid du Colombier long bd; /* bits 16-29 */
1117dd7cddfSDavid du Colombier uchar crfd; /* bits 6-8 */
1127dd7cddfSDavid du Colombier uchar crfs; /* bits 11-13 */
1137dd7cddfSDavid du Colombier uchar bi; /* bits 11-15 */
1147dd7cddfSDavid du Colombier uchar bo; /* bits 6-10 */
1157dd7cddfSDavid du Colombier uchar crbd; /* bits 6-10 */
1167dd7cddfSDavid du Colombier union {
1177dd7cddfSDavid du Colombier short d; /* bits 16-31 */
1187dd7cddfSDavid du Colombier short simm;
1197dd7cddfSDavid du Colombier ushort uimm;
1207dd7cddfSDavid du Colombier };
1217dd7cddfSDavid du Colombier uchar fm; /* bits 7-14 */
1227dd7cddfSDavid du Colombier uchar fra; /* bits 11-15 */
1237dd7cddfSDavid du Colombier uchar frb; /* bits 16-20 */
1247dd7cddfSDavid du Colombier uchar frc; /* bits 21-25 */
1257dd7cddfSDavid du Colombier uchar frs; /* bits 6-10 */
1267dd7cddfSDavid du Colombier uchar frd; /* bits 6-10 */
1277dd7cddfSDavid du Colombier uchar crm; /* bits 12-19 */
1287dd7cddfSDavid du Colombier long li; /* bits 6-29 || b'00' */
1297dd7cddfSDavid du Colombier uchar lk; /* bit 31 */
1307dd7cddfSDavid du Colombier uchar mb; /* bits 21-25 */
1317dd7cddfSDavid du Colombier uchar me; /* bits 26-30 */
13247ad9175SDavid du Colombier uchar xmbe; /* bits 26,21-25: mb[5] || mb[0:4], also xme */
13347ad9175SDavid du Colombier uchar xsh; /* bits 30,16-20: sh[5] || sh[0:4] */
1347dd7cddfSDavid du Colombier uchar nb; /* bits 16-20 */
1357dd7cddfSDavid du Colombier uchar op; /* bits 0-5 */
1367dd7cddfSDavid du Colombier uchar oe; /* bit 21 */
1377dd7cddfSDavid du Colombier uchar ra; /* bits 11-15 */
1387dd7cddfSDavid du Colombier uchar rb; /* bits 16-20 */
1397dd7cddfSDavid du Colombier uchar rc; /* bit 31 */
1407dd7cddfSDavid du Colombier union {
1417dd7cddfSDavid du Colombier uchar rs; /* bits 6-10 */
1427dd7cddfSDavid du Colombier uchar rd;
1437dd7cddfSDavid du Colombier };
1447dd7cddfSDavid du Colombier uchar sh; /* bits 16-20 */
1457dd7cddfSDavid du Colombier ushort spr; /* bits 11-20 */
1467dd7cddfSDavid du Colombier uchar to; /* bits 6-10 */
1477dd7cddfSDavid du Colombier uchar imm; /* bits 16-19 */
1487dd7cddfSDavid du Colombier ushort xo; /* bits 21-30, 22-30, 26-30, or 30 (beware) */
14947ad9175SDavid du Colombier uvlong imm64;
1507dd7cddfSDavid du Colombier long w0;
1517dd7cddfSDavid du Colombier long w1;
1524de34a7eSDavid du Colombier uvlong addr; /* pc of instruction */
1537dd7cddfSDavid du Colombier short target;
15447ad9175SDavid du Colombier short m64; /* 64-bit mode */
1557dd7cddfSDavid du Colombier char *curr; /* current fill level in output buffer */
1567dd7cddfSDavid du Colombier char *end; /* end of buffer */
1577dd7cddfSDavid du Colombier int size; /* number of longs in instr */
1587dd7cddfSDavid du Colombier char *err; /* errmsg */
1597dd7cddfSDavid du Colombier } Instr;
1607dd7cddfSDavid du Colombier
1617dd7cddfSDavid du Colombier #define IBF(v,a,b) (((ulong)(v)>>(32-(b)-1)) & ~(~0L<<(((b)-(a)+1))))
1627dd7cddfSDavid du Colombier #define IB(v,b) IBF((v),(b),(b))
1637dd7cddfSDavid du Colombier
1641bd28109SDavid du Colombier #pragma varargck argpos bprint 2
1651bd28109SDavid du Colombier
1667dd7cddfSDavid du Colombier static void
bprint(Instr * i,char * fmt,...)1677dd7cddfSDavid du Colombier bprint(Instr *i, char *fmt, ...)
1687dd7cddfSDavid du Colombier {
1697dd7cddfSDavid du Colombier va_list arg;
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier va_start(arg, fmt);
1729a747e4fSDavid du Colombier i->curr = vseprint(i->curr, i->end, fmt, arg);
1737dd7cddfSDavid du Colombier va_end(arg);
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier static int
decode(uvlong pc,Instr * i)1774de34a7eSDavid du Colombier decode(uvlong pc, Instr *i)
1787dd7cddfSDavid du Colombier {
1794de34a7eSDavid du Colombier ulong w;
1807dd7cddfSDavid du Colombier
1817dd7cddfSDavid du Colombier if (get4(mymap, pc, &w) < 0) {
1827dd7cddfSDavid du Colombier werrstr("can't read instruction: %r");
1837dd7cddfSDavid du Colombier return -1;
1847dd7cddfSDavid du Colombier }
18547ad9175SDavid du Colombier i->m64 = asstype == APOWER64;
1867dd7cddfSDavid du Colombier i->aa = IB(w, 30);
1877dd7cddfSDavid du Colombier i->crba = IBF(w, 11, 15);
1887dd7cddfSDavid du Colombier i->crbb = IBF(w, 16, 20);
1897dd7cddfSDavid du Colombier i->bd = IBF(w, 16, 29)<<2;
1907dd7cddfSDavid du Colombier if(i->bd & 0x8000)
1917dd7cddfSDavid du Colombier i->bd |= ~0L<<16;
1927dd7cddfSDavid du Colombier i->crfd = IBF(w, 6, 8);
1937dd7cddfSDavid du Colombier i->crfs = IBF(w, 11, 13);
1947dd7cddfSDavid du Colombier i->bi = IBF(w, 11, 15);
1957dd7cddfSDavid du Colombier i->bo = IBF(w, 6, 10);
1967dd7cddfSDavid du Colombier i->crbd = IBF(w, 6, 10);
1977dd7cddfSDavid du Colombier i->uimm = IBF(w, 16, 31); /* also d, simm */
1987dd7cddfSDavid du Colombier i->fm = IBF(w, 7, 14);
1997dd7cddfSDavid du Colombier i->fra = IBF(w, 11, 15);
2007dd7cddfSDavid du Colombier i->frb = IBF(w, 16, 20);
2017dd7cddfSDavid du Colombier i->frc = IBF(w, 21, 25);
2027dd7cddfSDavid du Colombier i->frs = IBF(w, 6, 10);
2037dd7cddfSDavid du Colombier i->frd = IBF(w, 6, 10);
2047dd7cddfSDavid du Colombier i->crm = IBF(w, 12, 19);
2057dd7cddfSDavid du Colombier i->li = IBF(w, 6, 29)<<2;
2067dd7cddfSDavid du Colombier if(IB(w, 6))
2077dd7cddfSDavid du Colombier i->li |= ~0<<25;
2087dd7cddfSDavid du Colombier i->lk = IB(w, 31);
2097dd7cddfSDavid du Colombier i->mb = IBF(w, 21, 25);
2107dd7cddfSDavid du Colombier i->me = IBF(w, 26, 30);
21147ad9175SDavid du Colombier i->xmbe = (IB(w,26)<<5) | i->mb;
2127dd7cddfSDavid du Colombier i->nb = IBF(w, 16, 20);
2137dd7cddfSDavid du Colombier i->op = IBF(w, 0, 5);
2147dd7cddfSDavid du Colombier i->oe = IB(w, 21);
2157dd7cddfSDavid du Colombier i->ra = IBF(w, 11, 15);
2167dd7cddfSDavid du Colombier i->rb = IBF(w, 16, 20);
2177dd7cddfSDavid du Colombier i->rc = IB(w, 31);
2187dd7cddfSDavid du Colombier i->rs = IBF(w, 6, 10); /* also rd */
2197dd7cddfSDavid du Colombier i->sh = IBF(w, 16, 20);
22047ad9175SDavid du Colombier i->xsh = (IB(w, 30)<<5) | i->sh;
2217dd7cddfSDavid du Colombier i->spr = IBF(w, 11, 20);
2227dd7cddfSDavid du Colombier i->to = IBF(w, 6, 10);
2237dd7cddfSDavid du Colombier i->imm = IBF(w, 16, 19);
2247dd7cddfSDavid du Colombier i->xo = IBF(w, 21, 30); /* bits 21-30, 22-30, 26-30, or 30 (beware) */
22547ad9175SDavid du Colombier if(i->op == 58){ /* class of 64-bit loads */
22647ad9175SDavid du Colombier i->xo = i->simm & 3;
22747ad9175SDavid du Colombier i->simm &= ~3;
22847ad9175SDavid du Colombier }
22947ad9175SDavid du Colombier i->imm64 = i->simm;
2307dd7cddfSDavid du Colombier if(i->op == 15)
23147ad9175SDavid du Colombier i->imm64 <<= 16;
23247ad9175SDavid du Colombier else if(i->op == 25 || i->op == 27 || i->op == 29)
23347ad9175SDavid du Colombier i->imm64 = (uvlong)(i->uimm<<16);
2347dd7cddfSDavid du Colombier i->w0 = w;
2357dd7cddfSDavid du Colombier i->target = -1;
2367dd7cddfSDavid du Colombier i->addr = pc;
2377dd7cddfSDavid du Colombier i->size = 1;
2387dd7cddfSDavid du Colombier return 1;
2397dd7cddfSDavid du Colombier }
2407dd7cddfSDavid du Colombier
2417dd7cddfSDavid du Colombier static int
mkinstr(uvlong pc,Instr * i)2424de34a7eSDavid du Colombier mkinstr(uvlong pc, Instr *i)
2437dd7cddfSDavid du Colombier {
2447dd7cddfSDavid du Colombier Instr x;
2457dd7cddfSDavid du Colombier
2467dd7cddfSDavid du Colombier if(decode(pc, i) < 0)
2477dd7cddfSDavid du Colombier return -1;
2487dd7cddfSDavid du Colombier /*
2497dd7cddfSDavid du Colombier * combine ADDIS/ORI (CAU/ORIL) into MOVW
25047ad9175SDavid du Colombier * also ORIS/ORIL for unsigned in 64-bit mode
2517dd7cddfSDavid du Colombier */
25247ad9175SDavid du Colombier if ((i->op == 15 || i->op == 25) && i->ra==0) {
2537dd7cddfSDavid du Colombier if(decode(pc+4, &x) < 0)
2547dd7cddfSDavid du Colombier return -1;
2557dd7cddfSDavid du Colombier if (x.op == 24 && x.rs == x.ra && x.ra == i->rd) {
25647ad9175SDavid du Colombier i->imm64 |= (x.imm64 & 0xFFFF);
25747ad9175SDavid du Colombier if(i->op != 15)
25847ad9175SDavid du Colombier i->imm64 &= 0xFFFFFFFFUL;
2597dd7cddfSDavid du Colombier i->w1 = x.w0;
2607dd7cddfSDavid du Colombier i->target = x.rd;
2617dd7cddfSDavid du Colombier i->size++;
2627dd7cddfSDavid du Colombier return 1;
2637dd7cddfSDavid du Colombier }
2647dd7cddfSDavid du Colombier }
2657dd7cddfSDavid du Colombier return 1;
2667dd7cddfSDavid du Colombier }
2677dd7cddfSDavid du Colombier
2687dd7cddfSDavid du Colombier static int
plocal(Instr * i)2697dd7cddfSDavid du Colombier plocal(Instr *i)
2707dd7cddfSDavid du Colombier {
2711bd28109SDavid du Colombier long offset;
2727dd7cddfSDavid du Colombier Symbol s;
2737dd7cddfSDavid du Colombier
2747dd7cddfSDavid du Colombier if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
2757dd7cddfSDavid du Colombier return -1;
27647ad9175SDavid du Colombier offset = s.value - i->imm64;
2777dd7cddfSDavid du Colombier if (offset > 0) {
2787dd7cddfSDavid du Colombier if(getauto(&s, offset, CAUTO, &s)) {
2791bd28109SDavid du Colombier bprint(i, "%s+%lld(SP)", s.name, s.value);
2807dd7cddfSDavid du Colombier return 1;
2817dd7cddfSDavid du Colombier }
2827dd7cddfSDavid du Colombier } else {
2837dd7cddfSDavid du Colombier if (getauto(&s, -offset-4, CPARAM, &s)) {
2841bd28109SDavid du Colombier bprint(i, "%s+%ld(FP)", s.name, -offset);
2857dd7cddfSDavid du Colombier return 1;
2867dd7cddfSDavid du Colombier }
2877dd7cddfSDavid du Colombier }
2887dd7cddfSDavid du Colombier return -1;
2897dd7cddfSDavid du Colombier }
2907dd7cddfSDavid du Colombier
2917dd7cddfSDavid du Colombier static int
pglobal(Instr * i,uvlong off,int anyoff,char * reg)2924de34a7eSDavid du Colombier pglobal(Instr *i, uvlong off, int anyoff, char *reg)
2937dd7cddfSDavid du Colombier {
2947dd7cddfSDavid du Colombier Symbol s, s2;
2954de34a7eSDavid du Colombier uvlong off1;
2967dd7cddfSDavid du Colombier
2977dd7cddfSDavid du Colombier if(findsym(off, CANY, &s) &&
298*6891d857SDavid du Colombier off-s.value < 4096 &&
2997dd7cddfSDavid du Colombier (s.class == CDATA || s.class == CTEXT)) {
3007dd7cddfSDavid du Colombier if(off==s.value && s.name[0]=='$'){
3017dd7cddfSDavid du Colombier off1 = 0;
3024de34a7eSDavid du Colombier geta(mymap, s.value, &off1);
3037dd7cddfSDavid du Colombier if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){
3047dd7cddfSDavid du Colombier bprint(i, "$%s%s", s2.name, reg);
3057dd7cddfSDavid du Colombier return 1;
3067dd7cddfSDavid du Colombier }
3077dd7cddfSDavid du Colombier }
3087dd7cddfSDavid du Colombier bprint(i, "%s", s.name);
3097dd7cddfSDavid du Colombier if (s.value != off)
3101bd28109SDavid du Colombier bprint(i, "+%llux", off-s.value);
3117dd7cddfSDavid du Colombier bprint(i, reg);
3127dd7cddfSDavid du Colombier return 1;
3137dd7cddfSDavid du Colombier }
3147dd7cddfSDavid du Colombier if(!anyoff)
3157dd7cddfSDavid du Colombier return 0;
3161bd28109SDavid du Colombier bprint(i, "%llux%s", off, reg);
3177dd7cddfSDavid du Colombier return 1;
3187dd7cddfSDavid du Colombier }
3197dd7cddfSDavid du Colombier
3207dd7cddfSDavid du Colombier static void
address(Instr * i)3217dd7cddfSDavid du Colombier address(Instr *i)
3227dd7cddfSDavid du Colombier {
3237dd7cddfSDavid du Colombier if (i->ra == REGSP && plocal(i) >= 0)
3247dd7cddfSDavid du Colombier return;
325*6891d857SDavid du Colombier if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->imm64, 0, "(SB)"))
3267dd7cddfSDavid du Colombier return;
3277dd7cddfSDavid du Colombier if(i->simm < 0)
3281bd28109SDavid du Colombier bprint(i, "-%x(R%d)", -i->simm, i->ra);
3297dd7cddfSDavid du Colombier else
33047ad9175SDavid du Colombier bprint(i, "%llux(R%d)", i->imm64, i->ra);
3317dd7cddfSDavid du Colombier }
3327dd7cddfSDavid du Colombier
3337dd7cddfSDavid du Colombier static char *tcrbits[] = {"LT", "GT", "EQ", "VS"};
3347dd7cddfSDavid du Colombier static char *fcrbits[] = {"GE", "LE", "NE", "VC"};
3357dd7cddfSDavid du Colombier
3367dd7cddfSDavid du Colombier typedef struct Opcode Opcode;
3377dd7cddfSDavid du Colombier
3387dd7cddfSDavid du Colombier struct Opcode {
3397dd7cddfSDavid du Colombier uchar op;
3407dd7cddfSDavid du Colombier ushort xo;
3417dd7cddfSDavid du Colombier ushort xomask;
3427dd7cddfSDavid du Colombier char *mnemonic;
3437dd7cddfSDavid du Colombier void (*f)(Opcode *, Instr *);
3447dd7cddfSDavid du Colombier char *ken;
3457dd7cddfSDavid du Colombier int flags;
3467dd7cddfSDavid du Colombier };
3477dd7cddfSDavid du Colombier
3487dd7cddfSDavid du Colombier static void format(char *, Instr *, char *);
3497dd7cddfSDavid du Colombier
3507dd7cddfSDavid du Colombier static void
branch(Opcode * o,Instr * i)3517dd7cddfSDavid du Colombier branch(Opcode *o, Instr *i)
3527dd7cddfSDavid du Colombier {
3537dd7cddfSDavid du Colombier char buf[8];
3547dd7cddfSDavid du Colombier int bo, bi;
3557dd7cddfSDavid du Colombier
3567dd7cddfSDavid du Colombier bo = i->bo & ~1; /* ignore prediction bit */
3577dd7cddfSDavid du Colombier if(bo==4 || bo==12 || bo==20) { /* simple forms */
3587dd7cddfSDavid du Colombier if(bo != 20) {
3597dd7cddfSDavid du Colombier bi = i->bi&3;
3607dd7cddfSDavid du Colombier sprint(buf, "B%s%%L", bo==12? tcrbits[bi]: fcrbits[bi]);
361*6891d857SDavid du Colombier format(buf, i, nil);
3627dd7cddfSDavid du Colombier bprint(i, "\t");
3637dd7cddfSDavid du Colombier if(i->bi > 4)
3647dd7cddfSDavid du Colombier bprint(i, "CR(%d),", i->bi/4);
3657dd7cddfSDavid du Colombier } else
366*6891d857SDavid du Colombier format("BR%L\t", i, nil);
3677dd7cddfSDavid du Colombier if(i->op == 16)
3687dd7cddfSDavid du Colombier format(0, i, "%J");
3697dd7cddfSDavid du Colombier else if(i->op == 19 && i->xo == 528)
3707dd7cddfSDavid du Colombier format(0, i, "(CTR)");
3717dd7cddfSDavid du Colombier else if(i->op == 19 && i->xo == 16)
3727dd7cddfSDavid du Colombier format(0, i, "(LR)");
3737dd7cddfSDavid du Colombier } else
3747dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
3757dd7cddfSDavid du Colombier }
3767dd7cddfSDavid du Colombier
3777dd7cddfSDavid du Colombier static void
addi(Opcode * o,Instr * i)3787dd7cddfSDavid du Colombier addi(Opcode *o, Instr *i)
3797dd7cddfSDavid du Colombier {
3807dd7cddfSDavid du Colombier if (i->op==14 && i->ra == 0)
3817dd7cddfSDavid du Colombier format("MOVW", i, "%i,R%d");
3827dd7cddfSDavid du Colombier else if (i->ra == REGSB) {
3837dd7cddfSDavid du Colombier bprint(i, "MOVW\t$");
3847dd7cddfSDavid du Colombier address(i);
3857dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
3867dd7cddfSDavid du Colombier } else if(i->op==14 && i->simm < 0) {
3877dd7cddfSDavid du Colombier bprint(i, "SUB\t$%d,R%d", -i->simm, i->ra);
3887dd7cddfSDavid du Colombier if(i->rd != i->ra)
3897dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
3907dd7cddfSDavid du Colombier } else if(i->ra == i->rd) {
3917dd7cddfSDavid du Colombier format(o->mnemonic, i, "%i");
3927dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
3937dd7cddfSDavid du Colombier } else
3947dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
3957dd7cddfSDavid du Colombier }
3967dd7cddfSDavid du Colombier
3977dd7cddfSDavid du Colombier static void
addis(Opcode * o,Instr * i)3987dd7cddfSDavid du Colombier addis(Opcode *o, Instr *i)
3997dd7cddfSDavid du Colombier {
4007dd7cddfSDavid du Colombier long v;
4017dd7cddfSDavid du Colombier
40247ad9175SDavid du Colombier v = i->imm64;
4037dd7cddfSDavid du Colombier if (i->op==15 && i->ra == 0)
4047dd7cddfSDavid du Colombier bprint(i, "MOVW\t$%lux,R%d", v, i->rd);
4057dd7cddfSDavid du Colombier else if (i->op==15 && i->ra == REGSB) {
4067dd7cddfSDavid du Colombier bprint(i, "MOVW\t$");
4077dd7cddfSDavid du Colombier address(i);
4087dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
4097dd7cddfSDavid du Colombier } else if(i->op==15 && v < 0) {
4101bd28109SDavid du Colombier bprint(i, "SUB\t$%ld,R%d", -v, i->ra);
4117dd7cddfSDavid du Colombier if(i->rd != i->ra)
4127dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
4137dd7cddfSDavid du Colombier } else {
414*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
4157dd7cddfSDavid du Colombier bprint(i, "\t$%ld,R%d", v, i->ra);
4167dd7cddfSDavid du Colombier if(i->rd != i->ra)
4177dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
4187dd7cddfSDavid du Colombier }
4197dd7cddfSDavid du Colombier }
4207dd7cddfSDavid du Colombier
4217dd7cddfSDavid du Colombier static void
andi(Opcode * o,Instr * i)4227dd7cddfSDavid du Colombier andi(Opcode *o, Instr *i)
4237dd7cddfSDavid du Colombier {
4247dd7cddfSDavid du Colombier if (i->ra == i->rs)
4257dd7cddfSDavid du Colombier format(o->mnemonic, i, "%I,R%d");
4267dd7cddfSDavid du Colombier else
4277dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
4287dd7cddfSDavid du Colombier }
4297dd7cddfSDavid du Colombier
4307dd7cddfSDavid du Colombier static void
gencc(Opcode * o,Instr * i)4317dd7cddfSDavid du Colombier gencc(Opcode *o, Instr *i)
4327dd7cddfSDavid du Colombier {
4337dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
4347dd7cddfSDavid du Colombier }
4357dd7cddfSDavid du Colombier
4367dd7cddfSDavid du Colombier static void
gen(Opcode * o,Instr * i)4377dd7cddfSDavid du Colombier gen(Opcode *o, Instr *i)
4387dd7cddfSDavid du Colombier {
4397dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
4407dd7cddfSDavid du Colombier if (i->rc)
4417dd7cddfSDavid du Colombier bprint(i, " [illegal Rc]");
4427dd7cddfSDavid du Colombier }
4437dd7cddfSDavid du Colombier
4447dd7cddfSDavid du Colombier static void
ldx(Opcode * o,Instr * i)4457dd7cddfSDavid du Colombier ldx(Opcode *o, Instr *i)
4467dd7cddfSDavid du Colombier {
4477dd7cddfSDavid du Colombier if(i->ra == 0)
4487dd7cddfSDavid du Colombier format(o->mnemonic, i, "(R%b),R%d");
4497dd7cddfSDavid du Colombier else
4507dd7cddfSDavid du Colombier format(o->mnemonic, i, "(R%b+R%a),R%d");
4517dd7cddfSDavid du Colombier if(i->rc)
4527dd7cddfSDavid du Colombier bprint(i, " [illegal Rc]");
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier
4557dd7cddfSDavid du Colombier static void
stx(Opcode * o,Instr * i)4567dd7cddfSDavid du Colombier stx(Opcode *o, Instr *i)
4577dd7cddfSDavid du Colombier {
4587dd7cddfSDavid du Colombier if(i->ra == 0)
4597dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%d,(R%b)");
4607dd7cddfSDavid du Colombier else
4617dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%d,(R%b+R%a)");
4627dd7cddfSDavid du Colombier if(i->rc && i->xo != 150)
4637dd7cddfSDavid du Colombier bprint(i, " [illegal Rc]");
4647dd7cddfSDavid du Colombier }
4657dd7cddfSDavid du Colombier
4667dd7cddfSDavid du Colombier static void
fldx(Opcode * o,Instr * i)4677dd7cddfSDavid du Colombier fldx(Opcode *o, Instr *i)
4687dd7cddfSDavid du Colombier {
4697dd7cddfSDavid du Colombier if(i->ra == 0)
4707dd7cddfSDavid du Colombier format(o->mnemonic, i, "(R%b),F%d");
4717dd7cddfSDavid du Colombier else
4727dd7cddfSDavid du Colombier format(o->mnemonic, i, "(R%b+R%a),F%d");
4737dd7cddfSDavid du Colombier if(i->rc)
4747dd7cddfSDavid du Colombier bprint(i, " [illegal Rc]");
4757dd7cddfSDavid du Colombier }
4767dd7cddfSDavid du Colombier
4777dd7cddfSDavid du Colombier static void
fstx(Opcode * o,Instr * i)4787dd7cddfSDavid du Colombier fstx(Opcode *o, Instr *i)
4797dd7cddfSDavid du Colombier {
4807dd7cddfSDavid du Colombier if(i->ra == 0)
4817dd7cddfSDavid du Colombier format(o->mnemonic, i, "F%d,(R%b)");
4827dd7cddfSDavid du Colombier else
4837dd7cddfSDavid du Colombier format(o->mnemonic, i, "F%d,(R%b+R%a)");
4847dd7cddfSDavid du Colombier if(i->rc)
4857dd7cddfSDavid du Colombier bprint(i, " [illegal Rc]");
4867dd7cddfSDavid du Colombier }
4877dd7cddfSDavid du Colombier
4887dd7cddfSDavid du Colombier static void
dcb(Opcode * o,Instr * i)4897dd7cddfSDavid du Colombier dcb(Opcode *o, Instr *i)
4907dd7cddfSDavid du Colombier {
4917dd7cddfSDavid du Colombier if(i->ra == 0)
4927dd7cddfSDavid du Colombier format(o->mnemonic, i, "(R%b)");
4937dd7cddfSDavid du Colombier else
4947dd7cddfSDavid du Colombier format(o->mnemonic, i, "(R%b+R%a)");
4957dd7cddfSDavid du Colombier if(i->rd)
4967dd7cddfSDavid du Colombier bprint(i, " [illegal Rd]");
4977dd7cddfSDavid du Colombier if(i->rc)
4987dd7cddfSDavid du Colombier bprint(i, " [illegal Rc]");
4997dd7cddfSDavid du Colombier }
5007dd7cddfSDavid du Colombier
5017dd7cddfSDavid du Colombier static void
lw(Opcode * o,Instr * i,char r)5027dd7cddfSDavid du Colombier lw(Opcode *o, Instr *i, char r)
5037dd7cddfSDavid du Colombier {
504*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
50547ad9175SDavid du Colombier bprint(i, "\t");
5067dd7cddfSDavid du Colombier address(i);
5077dd7cddfSDavid du Colombier bprint(i, ",%c%d", r, i->rd);
5087dd7cddfSDavid du Colombier }
5097dd7cddfSDavid du Colombier
5107dd7cddfSDavid du Colombier static void
load(Opcode * o,Instr * i)5117dd7cddfSDavid du Colombier load(Opcode *o, Instr *i)
5127dd7cddfSDavid du Colombier {
5137dd7cddfSDavid du Colombier lw(o, i, 'R');
5147dd7cddfSDavid du Colombier }
5157dd7cddfSDavid du Colombier
5167dd7cddfSDavid du Colombier static void
fload(Opcode * o,Instr * i)5177dd7cddfSDavid du Colombier fload(Opcode *o, Instr *i)
5187dd7cddfSDavid du Colombier {
5197dd7cddfSDavid du Colombier lw(o, i, 'F');
5207dd7cddfSDavid du Colombier }
5217dd7cddfSDavid du Colombier
5227dd7cddfSDavid du Colombier static void
sw(Opcode * o,Instr * i,char r)5237dd7cddfSDavid du Colombier sw(Opcode *o, Instr *i, char r)
5247dd7cddfSDavid du Colombier {
5257dd7cddfSDavid du Colombier int offset;
5267dd7cddfSDavid du Colombier Symbol s;
5277dd7cddfSDavid du Colombier
5287dd7cddfSDavid du Colombier if (i->rs == REGSP) {
5297dd7cddfSDavid du Colombier if (findsym(i->addr, CTEXT, &s) && findlocal(&s, FRAMENAME, &s)) {
53047ad9175SDavid du Colombier offset = s.value-i->imm64;
5317dd7cddfSDavid du Colombier if (offset > 0 && getauto(&s, offset, CAUTO, &s)) {
532*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
533*6891d857SDavid du Colombier bprint(i, "\t%c%d,%s-%d(SP)", r, i->rd, s.name, offset);
5347dd7cddfSDavid du Colombier return;
5357dd7cddfSDavid du Colombier }
5367dd7cddfSDavid du Colombier }
5377dd7cddfSDavid du Colombier }
5387dd7cddfSDavid du Colombier if (i->rs == REGSB && mach->sb) {
539*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
540*6891d857SDavid du Colombier bprint(i, "\t%c%d,", r, i->rd);
5417dd7cddfSDavid du Colombier address(i);
5427dd7cddfSDavid du Colombier return;
5437dd7cddfSDavid du Colombier }
5447dd7cddfSDavid du Colombier if (r == 'F')
545*6891d857SDavid du Colombier format(o->mnemonic, i, "F%d,%l");
5467dd7cddfSDavid du Colombier else
547*6891d857SDavid du Colombier format(o->mnemonic, i, o->ken);
5487dd7cddfSDavid du Colombier }
5497dd7cddfSDavid du Colombier
5507dd7cddfSDavid du Colombier static void
store(Opcode * o,Instr * i)5517dd7cddfSDavid du Colombier store(Opcode *o, Instr *i)
5527dd7cddfSDavid du Colombier {
5537dd7cddfSDavid du Colombier sw(o, i, 'R');
5547dd7cddfSDavid du Colombier }
5557dd7cddfSDavid du Colombier
5567dd7cddfSDavid du Colombier static void
fstore(Opcode * o,Instr * i)5577dd7cddfSDavid du Colombier fstore(Opcode *o, Instr *i)
5587dd7cddfSDavid du Colombier {
5597dd7cddfSDavid du Colombier sw(o, i, 'F');
5607dd7cddfSDavid du Colombier }
5617dd7cddfSDavid du Colombier
5627dd7cddfSDavid du Colombier static void
shifti(Opcode * o,Instr * i)5637dd7cddfSDavid du Colombier shifti(Opcode *o, Instr *i)
5647dd7cddfSDavid du Colombier {
5657dd7cddfSDavid du Colombier if (i->ra == i->rs)
5667dd7cddfSDavid du Colombier format(o->mnemonic, i, "$%k,R%a");
5677dd7cddfSDavid du Colombier else
5687dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
5697dd7cddfSDavid du Colombier }
5707dd7cddfSDavid du Colombier
5717dd7cddfSDavid du Colombier static void
shift(Opcode * o,Instr * i)5727dd7cddfSDavid du Colombier shift(Opcode *o, Instr *i)
5737dd7cddfSDavid du Colombier {
5747dd7cddfSDavid du Colombier if (i->ra == i->rs)
5757dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%b,R%a");
5767dd7cddfSDavid du Colombier else
5777dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
5787dd7cddfSDavid du Colombier }
5797dd7cddfSDavid du Colombier
5807dd7cddfSDavid du Colombier static void
add(Opcode * o,Instr * i)5817dd7cddfSDavid du Colombier add(Opcode *o, Instr *i)
5827dd7cddfSDavid du Colombier {
5837dd7cddfSDavid du Colombier if (i->rd == i->ra)
5847dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%b,R%d");
5857dd7cddfSDavid du Colombier else if (i->rd == i->rb)
5867dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%a,R%d");
5877dd7cddfSDavid du Colombier else
5887dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
5897dd7cddfSDavid du Colombier }
5907dd7cddfSDavid du Colombier
5917dd7cddfSDavid du Colombier static void
sub(Opcode * o,Instr * i)5927dd7cddfSDavid du Colombier sub(Opcode *o, Instr *i)
5937dd7cddfSDavid du Colombier {
594*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
5957dd7cddfSDavid du Colombier bprint(i, "\t");
5967dd7cddfSDavid du Colombier if(i->op == 31) {
5977dd7cddfSDavid du Colombier bprint(i, "\tR%d,R%d", i->ra, i->rb); /* subtract Ra from Rb */
5987dd7cddfSDavid du Colombier if(i->rd != i->rb)
5997dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
6007dd7cddfSDavid du Colombier } else
6017dd7cddfSDavid du Colombier bprint(i, "\tR%d,$%d,R%d", i->ra, i->simm, i->rd);
6027dd7cddfSDavid du Colombier }
6037dd7cddfSDavid du Colombier
6047dd7cddfSDavid du Colombier static void
qdiv(Opcode * o,Instr * i)605b0dcc5a8SDavid du Colombier qdiv(Opcode *o, Instr *i)
6067dd7cddfSDavid du Colombier {
607*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
6087dd7cddfSDavid du Colombier if(i->op == 31)
6097dd7cddfSDavid du Colombier bprint(i, "\tR%d,R%d", i->rb, i->ra);
6107dd7cddfSDavid du Colombier else
6117dd7cddfSDavid du Colombier bprint(i, "\t$%d,R%d", i->simm, i->ra);
6127dd7cddfSDavid du Colombier if(i->ra != i->rd)
6137dd7cddfSDavid du Colombier bprint(i, ",R%d", i->rd);
6147dd7cddfSDavid du Colombier }
6157dd7cddfSDavid du Colombier
6167dd7cddfSDavid du Colombier static void
and(Opcode * o,Instr * i)6177dd7cddfSDavid du Colombier and(Opcode *o, Instr *i)
6187dd7cddfSDavid du Colombier {
6197dd7cddfSDavid du Colombier if (i->op == 31) {
6207dd7cddfSDavid du Colombier /* Rb,Rs,Ra */
6217dd7cddfSDavid du Colombier if (i->ra == i->rs)
6227dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%b,R%a");
6237dd7cddfSDavid du Colombier else if (i->ra == i->rb)
6247dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%s,R%a");
6257dd7cddfSDavid du Colombier else
6267dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
6277dd7cddfSDavid du Colombier } else {
6287dd7cddfSDavid du Colombier /* imm,Rs,Ra */
6297dd7cddfSDavid du Colombier if (i->ra == i->rs)
6307dd7cddfSDavid du Colombier format(o->mnemonic, i, "%I,R%a");
6317dd7cddfSDavid du Colombier else
6327dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
6337dd7cddfSDavid du Colombier }
6347dd7cddfSDavid du Colombier }
6357dd7cddfSDavid du Colombier
6367dd7cddfSDavid du Colombier static void
or(Opcode * o,Instr * i)6377dd7cddfSDavid du Colombier or(Opcode *o, Instr *i)
6387dd7cddfSDavid du Colombier {
6397dd7cddfSDavid du Colombier if (i->op == 31) {
6407dd7cddfSDavid du Colombier /* Rb,Rs,Ra */
6417dd7cddfSDavid du Colombier if (i->rs == 0 && i->ra == 0 && i->rb == 0)
642*6891d857SDavid du Colombier format("NOP", i, nil);
6437dd7cddfSDavid du Colombier else if (i->rs == i->rb)
6447dd7cddfSDavid du Colombier format("MOVW", i, "R%b,R%a");
6457dd7cddfSDavid du Colombier else
6467dd7cddfSDavid du Colombier and(o, i);
6477dd7cddfSDavid du Colombier } else
6487dd7cddfSDavid du Colombier and(o, i);
6497dd7cddfSDavid du Colombier }
6507dd7cddfSDavid du Colombier
6517dd7cddfSDavid du Colombier static void
shifted(Opcode * o,Instr * i)6527dd7cddfSDavid du Colombier shifted(Opcode *o, Instr *i)
6537dd7cddfSDavid du Colombier {
654*6891d857SDavid du Colombier format(o->mnemonic, i, nil);
6557dd7cddfSDavid du Colombier bprint(i, "\t$%lux,", (ulong)i->uimm<<16);
6567dd7cddfSDavid du Colombier if (i->rs == i->ra)
6577dd7cddfSDavid du Colombier bprint(i, "R%d", i->ra);
6587dd7cddfSDavid du Colombier else
6597dd7cddfSDavid du Colombier bprint(i, "R%d,R%d", i->rs, i->ra);
6607dd7cddfSDavid du Colombier }
6617dd7cddfSDavid du Colombier
6627dd7cddfSDavid du Colombier static void
neg(Opcode * o,Instr * i)6637dd7cddfSDavid du Colombier neg(Opcode *o, Instr *i)
6647dd7cddfSDavid du Colombier {
6657dd7cddfSDavid du Colombier if (i->rd == i->ra)
6667dd7cddfSDavid du Colombier format(o->mnemonic, i, "R%d");
6677dd7cddfSDavid du Colombier else
6687dd7cddfSDavid du Colombier format(o->mnemonic, i, o->ken);
6697dd7cddfSDavid du Colombier }
6707dd7cddfSDavid du Colombier
6717dd7cddfSDavid du Colombier static char ir2[] = "R%a,R%d"; /* reverse of IBM order */
6727dd7cddfSDavid du Colombier static char ir3[] = "R%b,R%a,R%d";
6737dd7cddfSDavid du Colombier static char ir3r[] = "R%a,R%b,R%d";
6747dd7cddfSDavid du Colombier static char il3[] = "R%b,R%s,R%a";
675*6891d857SDavid du Colombier static char il2u[] = "%I,R%d,R%a";
6767dd7cddfSDavid du Colombier static char il3s[] = "$%k,R%s,R%a";
6777dd7cddfSDavid du Colombier static char il2[] = "R%s,R%a";
6787dd7cddfSDavid du Colombier static char icmp3[] = "R%a,R%b,%D";
6797dd7cddfSDavid du Colombier static char cr3op[] = "%b,%a,%d";
6807dd7cddfSDavid du Colombier static char ir2i[] = "%i,R%a,R%d";
6817dd7cddfSDavid du Colombier static char fp2[] = "F%b,F%d";
6827dd7cddfSDavid du Colombier static char fp3[] = "F%b,F%a,F%d";
6837dd7cddfSDavid du Colombier static char fp3c[] = "F%c,F%a,F%d";
6847dd7cddfSDavid du Colombier static char fp4[] = "F%a,F%c,F%b,F%d";
6857dd7cddfSDavid du Colombier static char fpcmp[] = "F%a,F%b,%D";
6867dd7cddfSDavid du Colombier static char ldop[] = "%l,R%d";
6877dd7cddfSDavid du Colombier static char stop[] = "R%d,%l";
6887dd7cddfSDavid du Colombier static char fldop[] = "%l,F%d";
6897dd7cddfSDavid du Colombier static char fstop[] = "F%d,%l";
69047ad9175SDavid du Colombier static char rldc[] = "R%b,R%s,$%E,R%a";
6917dd7cddfSDavid du Colombier static char rlim[] = "R%b,R%s,$%z,R%a";
6927dd7cddfSDavid du Colombier static char rlimi[] = "$%k,R%s,$%z,R%a";
69347ad9175SDavid du Colombier static char rldi[] = "$%e,R%s,$%E,R%a";
6947dd7cddfSDavid du Colombier
6957dd7cddfSDavid du Colombier #define OEM IBF(~0,22,30)
6967dd7cddfSDavid du Colombier #define FP4 IBF(~0,26,30)
6977dd7cddfSDavid du Colombier #define ALL (~0)
69847ad9175SDavid du Colombier #define RLDC 0xF
69947ad9175SDavid du Colombier #define RLDI 0xE
7007dd7cddfSDavid du Colombier /*
7017dd7cddfSDavid du Colombier notes:
7027dd7cddfSDavid du Colombier 10-26: crfD = rD>>2; rD&3 mbz
7037dd7cddfSDavid du Colombier also, L bit (bit 10) mbz or selects 64-bit operands
7047dd7cddfSDavid du Colombier */
7057dd7cddfSDavid du Colombier
7067dd7cddfSDavid du Colombier static Opcode opcodes[] = {
7077dd7cddfSDavid du Colombier {31, 266, OEM, "ADD%V%C", add, ir3},
7087dd7cddfSDavid du Colombier {31, 10, OEM, "ADDC%V%C", add, ir3},
7097dd7cddfSDavid du Colombier {31, 138, OEM, "ADDE%V%C", add, ir3},
7107dd7cddfSDavid du Colombier {14, 0, 0, "ADD", addi, ir2i},
7117dd7cddfSDavid du Colombier {12, 0, 0, "ADDC", addi, ir2i},
7127dd7cddfSDavid du Colombier {13, 0, 0, "ADDCCC", addi, ir2i},
7137dd7cddfSDavid du Colombier {15, 0, 0, "ADD", addis, 0},
7147dd7cddfSDavid du Colombier {31, 234, OEM, "ADDME%V%C", gencc, ir2},
7157dd7cddfSDavid du Colombier {31, 202, OEM, "ADDZE%V%C", gencc, ir2},
7167dd7cddfSDavid du Colombier
7177dd7cddfSDavid du Colombier {31, 28, ALL, "AND%C", and, il3},
7187dd7cddfSDavid du Colombier {31, 60, ALL, "ANDN%C", and, il3},
7197dd7cddfSDavid du Colombier {28, 0, 0, "ANDCC", andi, il2u},
7207dd7cddfSDavid du Colombier {29, 0, 0, "ANDCC", shifted, 0},
7217dd7cddfSDavid du Colombier
7227dd7cddfSDavid du Colombier {18, 0, 0, "B%L", gencc, "%j"},
7237dd7cddfSDavid du Colombier {16, 0, 0, "BC%L", branch, "%d,%a,%J"},
7247dd7cddfSDavid du Colombier {19, 528, ALL, "BC%L", branch, "%d,%a,(CTR)"},
7257dd7cddfSDavid du Colombier {19, 16, ALL, "BC%L", branch, "%d,%a,(LR)"},
7267dd7cddfSDavid du Colombier
7277dd7cddfSDavid du Colombier {31, 0, ALL, "CMP", 0, icmp3},
7287dd7cddfSDavid du Colombier {11, 0, 0, "CMP", 0, "R%a,%i,%D"},
7297dd7cddfSDavid du Colombier {31, 32, ALL, "CMPU", 0, icmp3},
7307dd7cddfSDavid du Colombier {10, 0, 0, "CMPU", 0, "R%a,%I,%D"},
7317dd7cddfSDavid du Colombier
73247ad9175SDavid du Colombier {31, 58, ALL, "CNTLZD%C", gencc, ir2}, /* 64 */
73347ad9175SDavid du Colombier {31, 26, ALL, "CNTLZ%W%C", gencc, ir2},
7347dd7cddfSDavid du Colombier
7357dd7cddfSDavid du Colombier {19, 257, ALL, "CRAND", gen, cr3op},
7367dd7cddfSDavid du Colombier {19, 129, ALL, "CRANDN", gen, cr3op},
7377dd7cddfSDavid du Colombier {19, 289, ALL, "CREQV", gen, cr3op},
7387dd7cddfSDavid du Colombier {19, 225, ALL, "CRNAND", gen, cr3op},
7397dd7cddfSDavid du Colombier {19, 33, ALL, "CRNOR", gen, cr3op},
7407dd7cddfSDavid du Colombier {19, 449, ALL, "CROR", gen, cr3op},
7417dd7cddfSDavid du Colombier {19, 417, ALL, "CRORN", gen, cr3op},
7427dd7cddfSDavid du Colombier {19, 193, ALL, "CRXOR", gen, cr3op},
7437dd7cddfSDavid du Colombier
7447dd7cddfSDavid du Colombier {31, 86, ALL, "DCBF", dcb, 0},
7457dd7cddfSDavid du Colombier {31, 470, ALL, "DCBI", dcb, 0},
7467dd7cddfSDavid du Colombier {31, 54, ALL, "DCBST", dcb, 0},
7477dd7cddfSDavid du Colombier {31, 278, ALL, "DCBT", dcb, 0},
7487dd7cddfSDavid du Colombier {31, 246, ALL, "DCBTST", dcb, 0},
7497dd7cddfSDavid du Colombier {31, 1014, ALL, "DCBZ", dcb, 0},
750b0dcc5a8SDavid du Colombier {31, 454, ALL, "DCCCI", dcb, 0},
751b0dcc5a8SDavid du Colombier {31, 966, ALL, "ICCCI", dcb, 0},
7527dd7cddfSDavid du Colombier
75347ad9175SDavid du Colombier {31, 489, OEM, "DIVD%V%C", qdiv, ir3}, /* 64 */
75447ad9175SDavid du Colombier {31, 457, OEM, "DIVDU%V%C", qdiv, ir3}, /* 64 */
755b0dcc5a8SDavid du Colombier {31, 491, OEM, "DIVW%V%C", qdiv, ir3},
756b0dcc5a8SDavid du Colombier {31, 459, OEM, "DIVWU%V%C", qdiv, ir3},
7577dd7cddfSDavid du Colombier
7587dd7cddfSDavid du Colombier {31, 310, ALL, "ECIWX", ldx, 0},
7597dd7cddfSDavid du Colombier {31, 438, ALL, "ECOWX", stx, 0},
7607dd7cddfSDavid du Colombier {31, 854, ALL, "EIEIO", gen, 0},
7617dd7cddfSDavid du Colombier
7627dd7cddfSDavid du Colombier {31, 284, ALL, "EQV%C", gencc, il3},
7637dd7cddfSDavid du Colombier
7647dd7cddfSDavid du Colombier {31, 954, ALL, "EXTSB%C", gencc, il2},
7657dd7cddfSDavid du Colombier {31, 922, ALL, "EXTSH%C", gencc, il2},
76647ad9175SDavid du Colombier {31, 986, ALL, "EXTSW%C", gencc, il2}, /* 64 */
7677dd7cddfSDavid du Colombier
7687dd7cddfSDavid du Colombier {63, 264, ALL, "FABS%C", gencc, fp2},
7697dd7cddfSDavid du Colombier {63, 21, ALL, "FADD%C", gencc, fp3},
7707dd7cddfSDavid du Colombier {59, 21, ALL, "FADDS%C", gencc, fp3},
7717dd7cddfSDavid du Colombier {63, 32, ALL, "FCMPO", gen, fpcmp},
7727dd7cddfSDavid du Colombier {63, 0, ALL, "FCMPU", gen, fpcmp},
77347ad9175SDavid du Colombier {63, 846, ALL, "FCFID%C", gencc, fp2}, /* 64 */
77447ad9175SDavid du Colombier {63, 814, ALL, "FCTID%C", gencc, fp2}, /* 64 */
77547ad9175SDavid du Colombier {63, 815, ALL, "FCTIDZ%C", gencc, fp2}, /* 64 */
7767dd7cddfSDavid du Colombier {63, 14, ALL, "FCTIW%C", gencc, fp2},
7777dd7cddfSDavid du Colombier {63, 15, ALL, "FCTIWZ%C", gencc, fp2},
7787dd7cddfSDavid du Colombier {63, 18, ALL, "FDIV%C", gencc, fp3},
7797dd7cddfSDavid du Colombier {59, 18, ALL, "FDIVS%C", gencc, fp3},
7807dd7cddfSDavid du Colombier {63, 29, FP4, "FMADD%C", gencc, fp4},
7817dd7cddfSDavid du Colombier {59, 29, FP4, "FMADDS%C", gencc, fp4},
7827dd7cddfSDavid du Colombier {63, 72, ALL, "FMOVD%C", gencc, fp2},
7837dd7cddfSDavid du Colombier {63, 28, FP4, "FMSUB%C", gencc, fp4},
7847dd7cddfSDavid du Colombier {59, 28, FP4, "FMSUBS%C", gencc, fp4},
7857dd7cddfSDavid du Colombier {63, 25, FP4, "FMUL%C", gencc, fp3c},
7867dd7cddfSDavid du Colombier {59, 25, FP4, "FMULS%C", gencc, fp3c},
7877dd7cddfSDavid du Colombier {63, 136, ALL, "FNABS%C", gencc, fp2},
7887dd7cddfSDavid du Colombier {63, 40, ALL, "FNEG%C", gencc, fp2},
7897dd7cddfSDavid du Colombier {63, 31, FP4, "FNMADD%C", gencc, fp4},
7907dd7cddfSDavid du Colombier {59, 31, FP4, "FNMADDS%C", gencc, fp4},
7917dd7cddfSDavid du Colombier {63, 30, FP4, "FNMSUB%C", gencc, fp4},
7927dd7cddfSDavid du Colombier {59, 30, FP4, "FNMSUBS%C", gencc, fp4},
79347ad9175SDavid du Colombier {59, 24, ALL, "FRES%C", gencc, fp2}, /* optional */
7947dd7cddfSDavid du Colombier {63, 12, ALL, "FRSP%C", gencc, fp2},
79547ad9175SDavid du Colombier {63, 26, ALL, "FRSQRTE%C", gencc, fp2}, /* optional */
79647ad9175SDavid du Colombier {63, 23, FP4, "FSEL%CC", gencc, fp4}, /* optional */
79747ad9175SDavid du Colombier {63, 22, ALL, "FSQRT%C", gencc, fp2}, /* optional */
79847ad9175SDavid du Colombier {59, 22, ALL, "FSQRTS%C", gencc, fp2}, /* optional */
7997dd7cddfSDavid du Colombier {63, 20, FP4, "FSUB%C", gencc, fp3},
8007dd7cddfSDavid du Colombier {59, 20, FP4, "FSUBS%C", gencc, fp3},
8017dd7cddfSDavid du Colombier
80247ad9175SDavid du Colombier {31, 982, ALL, "ICBI", dcb, 0}, /* optional */
8037dd7cddfSDavid du Colombier {19, 150, ALL, "ISYNC", gen, 0},
8047dd7cddfSDavid du Colombier
8057dd7cddfSDavid du Colombier {34, 0, 0, "MOVBZ", load, ldop},
8067dd7cddfSDavid du Colombier {35, 0, 0, "MOVBZU", load, ldop},
8077dd7cddfSDavid du Colombier {31, 119, ALL, "MOVBZU", ldx, 0},
8087dd7cddfSDavid du Colombier {31, 87, ALL, "MOVBZ", ldx, 0},
8097dd7cddfSDavid du Colombier {50, 0, 0, "FMOVD", fload, fldop},
8107dd7cddfSDavid du Colombier {51, 0, 0, "FMOVDU", fload, fldop},
8117dd7cddfSDavid du Colombier {31, 631, ALL, "FMOVDU", fldx, 0},
8127dd7cddfSDavid du Colombier {31, 599, ALL, "FMOVD", fldx, 0},
8137dd7cddfSDavid du Colombier {48, 0, 0, "FMOVS", load, fldop},
8147dd7cddfSDavid du Colombier {49, 0, 0, "FMOVSU", load, fldop},
8157dd7cddfSDavid du Colombier {31, 567, ALL, "FMOVSU", fldx, 0},
8167dd7cddfSDavid du Colombier {31, 535, ALL, "FMOVS", fldx, 0},
8177dd7cddfSDavid du Colombier {42, 0, 0, "MOVH", load, ldop},
8187dd7cddfSDavid du Colombier {43, 0, 0, "MOVHU", load, ldop},
8197dd7cddfSDavid du Colombier {31, 375, ALL, "MOVHU", ldx, 0},
8207dd7cddfSDavid du Colombier {31, 343, ALL, "MOVH", ldx, 0},
8217dd7cddfSDavid du Colombier {31, 790, ALL, "MOVHBR", ldx, 0},
8227dd7cddfSDavid du Colombier {40, 0, 0, "MOVHZ", load, ldop},
8237dd7cddfSDavid du Colombier {41, 0, 0, "MOVHZU", load, ldop},
8247dd7cddfSDavid du Colombier {31, 311, ALL, "MOVHZU", ldx, 0},
8257dd7cddfSDavid du Colombier {31, 279, ALL, "MOVHZ", ldx, 0},
8267dd7cddfSDavid du Colombier {46, 0, 0, "MOVMW", load, ldop},
8277dd7cddfSDavid du Colombier {31, 597, ALL, "LSW", gen, "(R%a),$%n,R%d"},
8287dd7cddfSDavid du Colombier {31, 533, ALL, "LSW", ldx, 0},
8297dd7cddfSDavid du Colombier {31, 20, ALL, "LWAR", ldx, 0},
83047ad9175SDavid du Colombier {31, 84, ALL, "LWARD", ldx, 0}, /* 64 */
8317dd7cddfSDavid du Colombier
83247ad9175SDavid du Colombier {58, 0, ALL, "MOVD", load, ldop}, /* 64 */
83347ad9175SDavid du Colombier {58, 1, ALL, "MOVDU", load, ldop}, /* 64 */
83447ad9175SDavid du Colombier {31, 53, ALL, "MOVDU", ldx, 0}, /* 64 */
83547ad9175SDavid du Colombier {31, 21, ALL, "MOVD", ldx, 0}, /* 64 */
83647ad9175SDavid du Colombier
83747ad9175SDavid du Colombier {31, 534, ALL, "MOVWBR", ldx, 0},
83847ad9175SDavid du Colombier
83947ad9175SDavid du Colombier {58, 2, ALL, "MOVW", load, ldop}, /* 64 (lwa) */
84047ad9175SDavid du Colombier {31, 373, ALL, "MOVWU", ldx, 0}, /* 64 */
84147ad9175SDavid du Colombier {31, 341, ALL, "MOVW", ldx, 0}, /* 64 */
84247ad9175SDavid du Colombier
84347ad9175SDavid du Colombier {32, 0, 0, "MOVW%Z", load, ldop},
84447ad9175SDavid du Colombier {33, 0, 0, "MOVW%ZU", load, ldop},
84547ad9175SDavid du Colombier {31, 55, ALL, "MOVW%ZU", ldx, 0},
84647ad9175SDavid du Colombier {31, 23, ALL, "MOVW%Z", ldx, 0},
8477dd7cddfSDavid du Colombier
8487dd7cddfSDavid du Colombier {19, 0, ALL, "MOVFL", gen, "%S,%D"},
8497dd7cddfSDavid du Colombier {63, 64, ALL, "MOVCRFS", gen, "%S,%D"},
8507dd7cddfSDavid du Colombier {31, 512, ALL, "MOVW", gen, "XER,%D"},
8517dd7cddfSDavid du Colombier {31, 19, ALL, "MOVW", gen, "CR,R%d"},
8527dd7cddfSDavid du Colombier
8537dd7cddfSDavid du Colombier {63, 583, ALL, "MOVW%C", gen, "FPSCR, F%d"}, /* mffs */
8547dd7cddfSDavid du Colombier {31, 83, ALL, "MOVW", gen, "MSR,R%d"},
8557dd7cddfSDavid du Colombier {31, 339, ALL, "MOVW", gen, "%P,R%d"},
8567dd7cddfSDavid du Colombier {31, 595, ALL, "MOVW", gen, "SEG(%a),R%d"},
8577dd7cddfSDavid du Colombier {31, 659, ALL, "MOVW", gen, "SEG(R%b),R%d"},
858b0dcc5a8SDavid du Colombier {31, 323, ALL, "MOVW", gen, "DCR(%Q),R%d"},
859b0dcc5a8SDavid du Colombier {31, 451, ALL, "MOVW", gen, "R%s,DCR(%Q)"},
860*6891d857SDavid du Colombier {31, 259, ALL, "MOVW", gen, "DCR(R%a),R%d"},
861*6891d857SDavid du Colombier {31, 387, ALL, "MOVW", gen, "R%s,DCR(R%a)"},
8627dd7cddfSDavid du Colombier {31, 144, ALL, "MOVFL", gen, "R%s,%m,CR"},
8637dd7cddfSDavid du Colombier {63, 70, ALL, "MTFSB0%C", gencc, "%D"},
8647dd7cddfSDavid du Colombier {63, 38, ALL, "MTFSB1%C", gencc, "%D"},
8657dd7cddfSDavid du Colombier {63, 711, ALL, "MOVFL%C", gencc, "F%b,%M,FPSCR"}, /* mtfsf */
8667dd7cddfSDavid du Colombier {63, 134, ALL, "MOVFL%C", gencc, "%K,%D"},
8677dd7cddfSDavid du Colombier {31, 146, ALL, "MOVW", gen, "R%s,MSR"},
86847ad9175SDavid du Colombier {31, 178, ALL, "MOVD", gen, "R%s,MSR"},
8697dd7cddfSDavid du Colombier {31, 467, ALL, "MOVW", gen, "R%s,%P"},
8707dd7cddfSDavid du Colombier {31, 210, ALL, "MOVW", gen, "R%s,SEG(%a)"},
8717dd7cddfSDavid du Colombier {31, 242, ALL, "MOVW", gen, "R%s,SEG(R%b)"},
8727dd7cddfSDavid du Colombier
87347ad9175SDavid du Colombier {31, 73, ALL, "MULHD%C", gencc, ir3},
87447ad9175SDavid du Colombier {31, 9, ALL, "MULHDU%C", gencc, ir3},
87547ad9175SDavid du Colombier {31, 233, OEM, "MULLD%V%C", gencc, ir3},
8767dd7cddfSDavid du Colombier
87747ad9175SDavid du Colombier {31, 75, ALL, "MULHW%C", gencc, ir3},
87847ad9175SDavid du Colombier {31, 11, ALL, "MULHWU%C", gencc, ir3},
8797dd7cddfSDavid du Colombier {31, 235, OEM, "MULLW%V%C", gencc, ir3},
8807dd7cddfSDavid du Colombier
88147ad9175SDavid du Colombier {7, 0, 0, "MULLW", qdiv, "%i,R%a,R%d"},
8827dd7cddfSDavid du Colombier
8837dd7cddfSDavid du Colombier {31, 476, ALL, "NAND%C", gencc, il3},
8847dd7cddfSDavid du Colombier {31, 104, OEM, "NEG%V%C", neg, ir2},
8857dd7cddfSDavid du Colombier {31, 124, ALL, "NOR%C", gencc, il3},
8867dd7cddfSDavid du Colombier {31, 444, ALL, "OR%C", or, il3},
8877dd7cddfSDavid du Colombier {31, 412, ALL, "ORN%C", or, il3},
8887dd7cddfSDavid du Colombier {24, 0, 0, "OR", and, "%I,R%d,R%a"},
8897dd7cddfSDavid du Colombier {25, 0, 0, "OR", shifted, 0},
8907dd7cddfSDavid du Colombier
8917dd7cddfSDavid du Colombier {19, 50, ALL, "RFI", gen, 0},
892b0dcc5a8SDavid du Colombier {19, 51, ALL, "RFCI", gen, 0},
8937dd7cddfSDavid du Colombier
89447ad9175SDavid du Colombier {30, 8, RLDC, "RLDCL%C", gencc, rldc}, /* 64 */
89547ad9175SDavid du Colombier {30, 9, RLDC, "RLDCR%C", gencc, rldc}, /* 64 */
89647ad9175SDavid du Colombier {30, 0, RLDI, "RLDCL%C", gencc, rldi}, /* 64 */
89747ad9175SDavid du Colombier {30, 1<<1, RLDI, "RLDCR%C", gencc, rldi}, /* 64 */
89847ad9175SDavid du Colombier {30, 2<<1, RLDI, "RLDC%C", gencc, rldi}, /* 64 */
89947ad9175SDavid du Colombier {30, 3<<1, RLDI, "RLDMI%C", gencc, rldi}, /* 64 */
90047ad9175SDavid du Colombier
9017dd7cddfSDavid du Colombier {20, 0, 0, "RLWMI%C", gencc, rlimi},
9027dd7cddfSDavid du Colombier {21, 0, 0, "RLWNM%C", gencc, rlimi},
9037dd7cddfSDavid du Colombier {23, 0, 0, "RLWNM%C", gencc, rlim},
9047dd7cddfSDavid du Colombier
9057dd7cddfSDavid du Colombier {17, 1, ALL, "SYSCALL", gen, 0},
9067dd7cddfSDavid du Colombier
90747ad9175SDavid du Colombier {31, 27, ALL, "SLD%C", shift, il3}, /* 64 */
9087dd7cddfSDavid du Colombier {31, 24, ALL, "SLW%C", shift, il3},
9097dd7cddfSDavid du Colombier
91047ad9175SDavid du Colombier {31, 794, ALL, "SRAD%C", shift, il3}, /* 64 */
911*6891d857SDavid du Colombier {31, (413<<1)|0, ALL, "SRAD%C", shifti, il3s}, /* 64 */
912*6891d857SDavid du Colombier {31, (413<<1)|1, ALL, "SRAD%C", shifti, il3s}, /* 64 */
9137dd7cddfSDavid du Colombier {31, 792, ALL, "SRAW%C", shift, il3},
9147dd7cddfSDavid du Colombier {31, 824, ALL, "SRAW%C", shifti, il3s},
9157dd7cddfSDavid du Colombier
91647ad9175SDavid du Colombier {31, 539, ALL, "SRD%C", shift, il3}, /* 64 */
9177dd7cddfSDavid du Colombier {31, 536, ALL, "SRW%C", shift, il3},
9187dd7cddfSDavid du Colombier
9197dd7cddfSDavid du Colombier {38, 0, 0, "MOVB", store, stop},
9207dd7cddfSDavid du Colombier {39, 0, 0, "MOVBU", store, stop},
9217dd7cddfSDavid du Colombier {31, 247, ALL, "MOVBU", stx, 0},
9227dd7cddfSDavid du Colombier {31, 215, ALL, "MOVB", stx, 0},
9237dd7cddfSDavid du Colombier {54, 0, 0, "FMOVD", fstore, fstop},
9247dd7cddfSDavid du Colombier {55, 0, 0, "FMOVDU", fstore, fstop},
9257dd7cddfSDavid du Colombier {31, 759, ALL, "FMOVDU", fstx, 0},
9267dd7cddfSDavid du Colombier {31, 727, ALL, "FMOVD", fstx, 0},
9277dd7cddfSDavid du Colombier {52, 0, 0, "FMOVS", fstore, fstop},
9287dd7cddfSDavid du Colombier {53, 0, 0, "FMOVSU", fstore, fstop},
9297dd7cddfSDavid du Colombier {31, 695, ALL, "FMOVSU", fstx, 0},
9307dd7cddfSDavid du Colombier {31, 663, ALL, "FMOVS", fstx, 0},
9317dd7cddfSDavid du Colombier {44, 0, 0, "MOVH", store, stop},
9327dd7cddfSDavid du Colombier {31, 918, ALL, "MOVHBR", stx, 0},
9337dd7cddfSDavid du Colombier {45, 0, 0, "MOVHU", store, stop},
9347dd7cddfSDavid du Colombier {31, 439, ALL, "MOVHU", stx, 0},
9357dd7cddfSDavid du Colombier {31, 407, ALL, "MOVH", stx, 0},
9367dd7cddfSDavid du Colombier {47, 0, 0, "MOVMW", store, stop},
9377dd7cddfSDavid du Colombier {31, 725, ALL, "STSW", gen, "R%d,$%n,(R%a)"},
9387dd7cddfSDavid du Colombier {31, 661, ALL, "STSW", stx, 0},
9397dd7cddfSDavid du Colombier {36, 0, 0, "MOVW", store, stop},
9407dd7cddfSDavid du Colombier {31, 662, ALL, "MOVWBR", stx, 0},
9417dd7cddfSDavid du Colombier {31, 150, ALL, "STWCCC", stx, 0},
94247ad9175SDavid du Colombier {31, 214, ALL, "STDCCC", stx, 0}, /* 64 */
9437dd7cddfSDavid du Colombier {37, 0, 0, "MOVWU", store, stop},
9447dd7cddfSDavid du Colombier {31, 183, ALL, "MOVWU", stx, 0},
9457dd7cddfSDavid du Colombier {31, 151, ALL, "MOVW", stx, 0},
9467dd7cddfSDavid du Colombier
94747ad9175SDavid du Colombier {62, 0, 0, "MOVD%U", store, stop}, /* 64 */
94847ad9175SDavid du Colombier {31, 149, ALL, "MOVD", stx, 0,}, /* 64 */
94947ad9175SDavid du Colombier {31, 181, ALL, "MOVDU", stx, 0}, /* 64 */
95047ad9175SDavid du Colombier
95147ad9175SDavid du Colombier {31, 498, ALL, "SLBIA", gen, 0}, /* 64 */
95247ad9175SDavid du Colombier {31, 434, ALL, "SLBIE", gen, "R%b"}, /* 64 */
95347ad9175SDavid du Colombier {31, 466, ALL, "SLBIEX", gen, "R%b"}, /* 64 */
95447ad9175SDavid du Colombier {31, 915, ALL, "SLBMFEE", gen, "R%b,R%d"}, /* 64 */
95547ad9175SDavid du Colombier {31, 851, ALL, "SLBMFEV", gen, "R%b,R%d"}, /* 64 */
95647ad9175SDavid du Colombier {31, 402, ALL, "SLBMTE", gen, "R%s,R%b"}, /* 64 */
95747ad9175SDavid du Colombier
9587dd7cddfSDavid du Colombier {31, 40, OEM, "SUB%V%C", sub, ir3},
9597dd7cddfSDavid du Colombier {31, 8, OEM, "SUBC%V%C", sub, ir3},
9607dd7cddfSDavid du Colombier {31, 136, OEM, "SUBE%V%C", sub, ir3},
9617dd7cddfSDavid du Colombier {8, 0, 0, "SUBC", gen, "R%a,%i,R%d"},
9627dd7cddfSDavid du Colombier {31, 232, OEM, "SUBME%V%C", sub, ir2},
9637dd7cddfSDavid du Colombier {31, 200, OEM, "SUBZE%V%C", sub, ir2},
9647dd7cddfSDavid du Colombier
96547ad9175SDavid du Colombier {31, 598, ALL, "SYNC", gen, 0}, /* TO DO: there's a parameter buried in there */
96647ad9175SDavid du Colombier {2, 0, 0, "TD", gen, "%d,R%a,%i"}, /* 64 */
96747ad9175SDavid du Colombier {31, 370, ALL, "TLBIA", gen, 0}, /* optional */
96847ad9175SDavid du Colombier {31, 306, ALL, "TLBIE", gen, "R%b"}, /* optional */
96947ad9175SDavid du Colombier {31, 274, ALL, "TLBIEL", gen, "R%b"}, /* optional */
97047ad9175SDavid du Colombier {31, 1010, ALL, "TLBLI", gen, "R%b"}, /* optional */
97147ad9175SDavid du Colombier {31, 978, ALL, "TLBLD", gen, "R%b"}, /* optional */
97247ad9175SDavid du Colombier {31, 566, ALL, "TLBSYNC", gen, 0}, /* optional */
97347ad9175SDavid du Colombier {31, 68, ALL, "TD", gen, "%d,R%a,R%b"}, /* 64 */
9747dd7cddfSDavid du Colombier {31, 4, ALL, "TW", gen, "%d,R%a,R%b"},
9757dd7cddfSDavid du Colombier {3, 0, 0, "TW", gen, "%d,R%a,%i"},
9767dd7cddfSDavid du Colombier
9777dd7cddfSDavid du Colombier {31, 316, ALL, "XOR", and, il3},
9787dd7cddfSDavid du Colombier {26, 0, 0, "XOR", and, il2u},
9797dd7cddfSDavid du Colombier {27, 0, 0, "XOR", shifted, 0},
9807dd7cddfSDavid du Colombier
9817dd7cddfSDavid du Colombier {0},
9827dd7cddfSDavid du Colombier };
9837dd7cddfSDavid du Colombier
9847dd7cddfSDavid du Colombier typedef struct Spr Spr;
9857dd7cddfSDavid du Colombier struct Spr {
9867dd7cddfSDavid du Colombier int n;
9877dd7cddfSDavid du Colombier char *name;
9887dd7cddfSDavid du Colombier };
9897dd7cddfSDavid du Colombier
9907dd7cddfSDavid du Colombier static Spr sprname[] = {
9917dd7cddfSDavid du Colombier {0, "MQ"},
9927dd7cddfSDavid du Colombier {1, "XER"},
9937dd7cddfSDavid du Colombier {268, "TBL"},
9947dd7cddfSDavid du Colombier {269, "TBU"},
9957dd7cddfSDavid du Colombier {8, "LR"},
9967dd7cddfSDavid du Colombier {9, "CTR"},
9977dd7cddfSDavid du Colombier {528, "IBAT0U"},
9987dd7cddfSDavid du Colombier {529, "IBAT0L"},
9997dd7cddfSDavid du Colombier {530, "IBAT1U"},
10007dd7cddfSDavid du Colombier {531, "IBAT1L"},
10017dd7cddfSDavid du Colombier {532, "IBAT2U"},
10027dd7cddfSDavid du Colombier {533, "IBAT2L"},
10037dd7cddfSDavid du Colombier {534, "IBAT3U"},
10047dd7cddfSDavid du Colombier {535, "IBAT3L"},
10057dd7cddfSDavid du Colombier {536, "DBAT0U"},
10067dd7cddfSDavid du Colombier {537, "DBAT0L"},
10077dd7cddfSDavid du Colombier {538, "DBAT1U"},
10087dd7cddfSDavid du Colombier {539, "DBAT1L"},
10097dd7cddfSDavid du Colombier {540, "DBAT2U"},
10107dd7cddfSDavid du Colombier {541, "DBAT2L"},
10117dd7cddfSDavid du Colombier {542, "DBAT3U"},
10127dd7cddfSDavid du Colombier {543, "DBAT3L"},
10137dd7cddfSDavid du Colombier {25, "SDR1"},
10147dd7cddfSDavid du Colombier {19, "DAR"},
10157dd7cddfSDavid du Colombier {272, "SPRG0"},
10167dd7cddfSDavid du Colombier {273, "SPRG1"},
10177dd7cddfSDavid du Colombier {274, "SPRG2"},
10187dd7cddfSDavid du Colombier {275, "SPRG3"},
10197dd7cddfSDavid du Colombier {18, "DSISR"},
10207dd7cddfSDavid du Colombier {26, "SRR0"},
10217dd7cddfSDavid du Colombier {27, "SRR1"},
10227dd7cddfSDavid du Colombier {284, "TBLW"},
10237dd7cddfSDavid du Colombier {285, "TBUW"},
10247dd7cddfSDavid du Colombier {22, "DEC"},
10257dd7cddfSDavid du Colombier {282, "EAR"},
10267dd7cddfSDavid du Colombier {1008, "HID0"},
10277dd7cddfSDavid du Colombier {1009, "HID1"},
10287dd7cddfSDavid du Colombier {976, "DMISS"},
10297dd7cddfSDavid du Colombier {977, "DCMP"},
10307dd7cddfSDavid du Colombier {978, "HASH1"},
10317dd7cddfSDavid du Colombier {979, "HASH2"},
10327dd7cddfSDavid du Colombier {980, "IMISS"},
10337dd7cddfSDavid du Colombier {981, "ICMP"},
10347dd7cddfSDavid du Colombier {982, "RPA"},
10357dd7cddfSDavid du Colombier {1010, "IABR"},
1036b0dcc5a8SDavid du Colombier {1013, "DABR"},
10377dd7cddfSDavid du Colombier {0,0},
10387dd7cddfSDavid du Colombier };
10397dd7cddfSDavid du Colombier
104047ad9175SDavid du Colombier static int
shmask(uvlong * m)104147ad9175SDavid du Colombier shmask(uvlong *m)
104247ad9175SDavid du Colombier {
104347ad9175SDavid du Colombier int i;
104447ad9175SDavid du Colombier
104547ad9175SDavid du Colombier for(i=0; i<63; i++)
104647ad9175SDavid du Colombier if(*m & ((uvlong)1<<i))
104747ad9175SDavid du Colombier break;
104847ad9175SDavid du Colombier if(i > 63)
104947ad9175SDavid du Colombier return 0;
105047ad9175SDavid du Colombier if(*m & ~((uvlong)1<<i)){ /* more than one bit: do multiples of bytes */
105147ad9175SDavid du Colombier i = (i/8)*8;
105247ad9175SDavid du Colombier if(i == 0)
105347ad9175SDavid du Colombier return 0;
105447ad9175SDavid du Colombier }
105547ad9175SDavid du Colombier *m >>= i;
105647ad9175SDavid du Colombier return i;
105747ad9175SDavid du Colombier }
105847ad9175SDavid du Colombier
10597dd7cddfSDavid du Colombier static void
format(char * mnemonic,Instr * i,char * f)10607dd7cddfSDavid du Colombier format(char *mnemonic, Instr *i, char *f)
10617dd7cddfSDavid du Colombier {
10627dd7cddfSDavid du Colombier int n, s;
10637dd7cddfSDavid du Colombier ulong mask;
106447ad9175SDavid du Colombier uvlong vmask;
10657dd7cddfSDavid du Colombier
10667dd7cddfSDavid du Colombier if (mnemonic)
10677dd7cddfSDavid du Colombier format(0, i, mnemonic);
10687dd7cddfSDavid du Colombier if (f == 0)
10697dd7cddfSDavid du Colombier return;
10707dd7cddfSDavid du Colombier if (mnemonic)
10717dd7cddfSDavid du Colombier bprint(i, "\t");
10727dd7cddfSDavid du Colombier for ( ; *f; f++) {
10737dd7cddfSDavid du Colombier if (*f != '%') {
10747dd7cddfSDavid du Colombier bprint(i, "%c", *f);
10757dd7cddfSDavid du Colombier continue;
10767dd7cddfSDavid du Colombier }
10777dd7cddfSDavid du Colombier switch (*++f) {
10787dd7cddfSDavid du Colombier
10797dd7cddfSDavid du Colombier case 'a':
10807dd7cddfSDavid du Colombier bprint(i, "%d", i->ra);
10817dd7cddfSDavid du Colombier break;
10827dd7cddfSDavid du Colombier
10837dd7cddfSDavid du Colombier case 'b':
10847dd7cddfSDavid du Colombier bprint(i, "%d", i->rb);
10857dd7cddfSDavid du Colombier break;
10867dd7cddfSDavid du Colombier
10877dd7cddfSDavid du Colombier case 'c':
10887dd7cddfSDavid du Colombier bprint(i, "%d", i->frc);
10897dd7cddfSDavid du Colombier break;
10907dd7cddfSDavid du Colombier
10917dd7cddfSDavid du Colombier case 'd':
10927dd7cddfSDavid du Colombier case 's':
10937dd7cddfSDavid du Colombier bprint(i, "%d", i->rd);
10947dd7cddfSDavid du Colombier break;
10957dd7cddfSDavid du Colombier
109647ad9175SDavid du Colombier case 'C':
109747ad9175SDavid du Colombier if(i->rc)
109847ad9175SDavid du Colombier bprint(i, "CC");
10997dd7cddfSDavid du Colombier break;
11007dd7cddfSDavid du Colombier
11017dd7cddfSDavid du Colombier case 'D':
11027dd7cddfSDavid du Colombier if(i->rd & 3)
11037dd7cddfSDavid du Colombier bprint(i, "CR(INVAL:%d)", i->rd);
11047dd7cddfSDavid du Colombier else if(i->op == 63)
11057dd7cddfSDavid du Colombier bprint(i, "FPSCR(%d)", i->crfd);
11067dd7cddfSDavid du Colombier else
11077dd7cddfSDavid du Colombier bprint(i, "CR(%d)", i->crfd);
11087dd7cddfSDavid du Colombier break;
11097dd7cddfSDavid du Colombier
111047ad9175SDavid du Colombier case 'e':
111147ad9175SDavid du Colombier bprint(i, "%d", i->xsh);
111247ad9175SDavid du Colombier break;
111347ad9175SDavid du Colombier
111447ad9175SDavid du Colombier case 'E':
111547ad9175SDavid du Colombier switch(IBF(i->w0,27,30)){ /* low bit is top bit of shift in rldiX cases */
111647ad9175SDavid du Colombier case 8: i->mb = i->xmbe; i->me = 63; break; /* rldcl */
111747ad9175SDavid du Colombier case 9: i->mb = 0; i->me = i->xmbe; break; /* rldcr */
111847ad9175SDavid du Colombier case 4: case 5:
111947ad9175SDavid du Colombier i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldic */
112047ad9175SDavid du Colombier case 0: case 1:
112147ad9175SDavid du Colombier i->mb = i->xmbe; i->me = 63; break; /* rldicl */
112247ad9175SDavid du Colombier case 2: case 3:
112347ad9175SDavid du Colombier i->mb = 0; i->me = i->xmbe; break; /* rldicr */
112447ad9175SDavid du Colombier case 6: case 7:
112547ad9175SDavid du Colombier i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldimi */
112647ad9175SDavid du Colombier }
112747ad9175SDavid du Colombier vmask = (~(uvlong)0>>i->mb) & (~(uvlong)0<<(63-i->me));
112847ad9175SDavid du Colombier s = shmask(&vmask);
112947ad9175SDavid du Colombier if(s)
113047ad9175SDavid du Colombier bprint(i, "(%llux<<%d)", vmask, s);
11317dd7cddfSDavid du Colombier else
113247ad9175SDavid du Colombier bprint(i, "%llux", vmask);
11337dd7cddfSDavid du Colombier break;
11347dd7cddfSDavid du Colombier
11357dd7cddfSDavid du Colombier case 'i':
11361bd28109SDavid du Colombier bprint(i, "$%d", i->simm);
11377dd7cddfSDavid du Colombier break;
11387dd7cddfSDavid du Colombier
11397dd7cddfSDavid du Colombier case 'I':
11401bd28109SDavid du Colombier bprint(i, "$%ux", i->uimm);
11417dd7cddfSDavid du Colombier break;
11427dd7cddfSDavid du Colombier
114347ad9175SDavid du Colombier case 'j':
114447ad9175SDavid du Colombier if(i->aa)
114547ad9175SDavid du Colombier pglobal(i, i->li, 1, "(SB)");
114647ad9175SDavid du Colombier else
114747ad9175SDavid du Colombier pglobal(i, i->addr+i->li, 1, "");
114847ad9175SDavid du Colombier break;
114947ad9175SDavid du Colombier
115047ad9175SDavid du Colombier case 'J':
115147ad9175SDavid du Colombier if(i->aa)
115247ad9175SDavid du Colombier pglobal(i, i->bd, 1, "(SB)");
115347ad9175SDavid du Colombier else
115447ad9175SDavid du Colombier pglobal(i, i->addr+i->bd, 1, "");
115547ad9175SDavid du Colombier break;
115647ad9175SDavid du Colombier
115747ad9175SDavid du Colombier case 'k':
115847ad9175SDavid du Colombier bprint(i, "%d", i->sh);
115947ad9175SDavid du Colombier break;
116047ad9175SDavid du Colombier
116147ad9175SDavid du Colombier case 'K':
116247ad9175SDavid du Colombier bprint(i, "$%x", i->imm);
116347ad9175SDavid du Colombier break;
116447ad9175SDavid du Colombier
116547ad9175SDavid du Colombier case 'L':
116647ad9175SDavid du Colombier if(i->lk)
116747ad9175SDavid du Colombier bprint(i, "L");
116847ad9175SDavid du Colombier break;
116947ad9175SDavid du Colombier
117047ad9175SDavid du Colombier case 'l':
117147ad9175SDavid du Colombier if(i->simm < 0)
117247ad9175SDavid du Colombier bprint(i, "-%x(R%d)", -i->simm, i->ra);
117347ad9175SDavid du Colombier else
117447ad9175SDavid du Colombier bprint(i, "%x(R%d)", i->simm, i->ra);
117547ad9175SDavid du Colombier break;
117647ad9175SDavid du Colombier
117747ad9175SDavid du Colombier case 'm':
117847ad9175SDavid du Colombier bprint(i, "%ux", i->crm);
117947ad9175SDavid du Colombier break;
118047ad9175SDavid du Colombier
118147ad9175SDavid du Colombier case 'M':
118247ad9175SDavid du Colombier bprint(i, "%ux", i->fm);
118347ad9175SDavid du Colombier break;
118447ad9175SDavid du Colombier
118547ad9175SDavid du Colombier case 'n':
118647ad9175SDavid du Colombier bprint(i, "%d", i->nb==0? 32: i->nb); /* eg, pg 10-103 */
11877dd7cddfSDavid du Colombier break;
11887dd7cddfSDavid du Colombier
11897dd7cddfSDavid du Colombier case 'P':
11907dd7cddfSDavid du Colombier n = ((i->spr&0x1f)<<5)|((i->spr>>5)&0x1f);
11917dd7cddfSDavid du Colombier for(s=0; sprname[s].name; s++)
11927dd7cddfSDavid du Colombier if(sprname[s].n == n)
11937dd7cddfSDavid du Colombier break;
11947dd7cddfSDavid du Colombier if(sprname[s].name) {
11957dd7cddfSDavid du Colombier if(s < 10)
11967dd7cddfSDavid du Colombier bprint(i, sprname[s].name);
11977dd7cddfSDavid du Colombier else
11987dd7cddfSDavid du Colombier bprint(i, "SPR(%s)", sprname[s].name);
11997dd7cddfSDavid du Colombier } else
12007dd7cddfSDavid du Colombier bprint(i, "SPR(%d)", n);
12017dd7cddfSDavid du Colombier break;
12027dd7cddfSDavid du Colombier
1203b0dcc5a8SDavid du Colombier case 'Q':
1204b0dcc5a8SDavid du Colombier n = ((i->spr&0x1f)<<5)|((i->spr>>5)&0x1f);
1205b0dcc5a8SDavid du Colombier bprint(i, "%d", n);
1206b0dcc5a8SDavid du Colombier break;
1207b0dcc5a8SDavid du Colombier
120847ad9175SDavid du Colombier case 'S':
120947ad9175SDavid du Colombier if(i->ra & 3)
121047ad9175SDavid du Colombier bprint(i, "CR(INVAL:%d)", i->ra);
121147ad9175SDavid du Colombier else if(i->op == 63)
121247ad9175SDavid du Colombier bprint(i, "FPSCR(%d)", i->crfs);
121347ad9175SDavid du Colombier else
121447ad9175SDavid du Colombier bprint(i, "CR(%d)", i->crfs);
12157dd7cddfSDavid du Colombier break;
12167dd7cddfSDavid du Colombier
121747ad9175SDavid du Colombier case 'U':
121847ad9175SDavid du Colombier if(i->rc)
121947ad9175SDavid du Colombier bprint(i, "U");
12207dd7cddfSDavid du Colombier break;
12217dd7cddfSDavid du Colombier
122247ad9175SDavid du Colombier case 'V':
122347ad9175SDavid du Colombier if(i->oe)
122447ad9175SDavid du Colombier bprint(i, "V");
122547ad9175SDavid du Colombier break;
122647ad9175SDavid du Colombier
122747ad9175SDavid du Colombier case 'w':
122847ad9175SDavid du Colombier bprint(i, "[%lux]", i->w0);
122947ad9175SDavid du Colombier break;
123047ad9175SDavid du Colombier
123147ad9175SDavid du Colombier case 'W':
123247ad9175SDavid du Colombier if(i->m64)
123347ad9175SDavid du Colombier bprint(i, "W");
123447ad9175SDavid du Colombier break;
123547ad9175SDavid du Colombier
123647ad9175SDavid du Colombier case 'Z':
123747ad9175SDavid du Colombier if(i->m64)
123847ad9175SDavid du Colombier bprint(i, "Z");
12397dd7cddfSDavid du Colombier break;
12407dd7cddfSDavid du Colombier
12417dd7cddfSDavid du Colombier case 'z':
12427dd7cddfSDavid du Colombier if(i->mb <= i->me)
12437dd7cddfSDavid du Colombier mask = ((ulong)~0L>>i->mb) & (~0L<<(31-i->me));
12447dd7cddfSDavid du Colombier else
12457dd7cddfSDavid du Colombier mask = ~(((ulong)~0L>>(i->me+1)) & (~0L<<(31-(i->mb-1))));
12467dd7cddfSDavid du Colombier bprint(i, "%lux", mask);
12477dd7cddfSDavid du Colombier break;
12487dd7cddfSDavid du Colombier
12497dd7cddfSDavid du Colombier case '\0':
12507dd7cddfSDavid du Colombier bprint(i, "%%");
12517dd7cddfSDavid du Colombier return;
12527dd7cddfSDavid du Colombier
12537dd7cddfSDavid du Colombier default:
12547dd7cddfSDavid du Colombier bprint(i, "%%%c", *f);
12557dd7cddfSDavid du Colombier break;
12567dd7cddfSDavid du Colombier }
12577dd7cddfSDavid du Colombier }
12587dd7cddfSDavid du Colombier }
12597dd7cddfSDavid du Colombier
12607dd7cddfSDavid du Colombier static int
printins(Map * map,uvlong pc,char * buf,int n)12614de34a7eSDavid du Colombier printins(Map *map, uvlong pc, char *buf, int n)
12627dd7cddfSDavid du Colombier {
12637dd7cddfSDavid du Colombier Instr i;
12647dd7cddfSDavid du Colombier Opcode *o;
12657dd7cddfSDavid du Colombier
12667dd7cddfSDavid du Colombier mymap = map;
12677dd7cddfSDavid du Colombier memset(&i, 0, sizeof(i));
12687dd7cddfSDavid du Colombier i.curr = buf;
12697dd7cddfSDavid du Colombier i.end = buf+n-1;
12707dd7cddfSDavid du Colombier if(mkinstr(pc, &i) < 0)
12717dd7cddfSDavid du Colombier return -1;
12727dd7cddfSDavid du Colombier for(o = opcodes; o->mnemonic != 0; o++)
12737dd7cddfSDavid du Colombier if(i.op == o->op && (i.xo & o->xomask) == o->xo) {
12747dd7cddfSDavid du Colombier if (o->f)
12757dd7cddfSDavid du Colombier (*o->f)(o, &i);
12767dd7cddfSDavid du Colombier else
12777dd7cddfSDavid du Colombier format(o->mnemonic, &i, o->ken);
12787dd7cddfSDavid du Colombier return i.size*4;
12797dd7cddfSDavid du Colombier }
12807dd7cddfSDavid du Colombier bprint(&i, "unknown %lux", i.w0);
12817dd7cddfSDavid du Colombier return i.size*4;
12827dd7cddfSDavid du Colombier }
12837dd7cddfSDavid du Colombier
12847dd7cddfSDavid du Colombier static int
powerinst(Map * map,uvlong pc,char modifier,char * buf,int n)12854de34a7eSDavid du Colombier powerinst(Map *map, uvlong pc, char modifier, char *buf, int n)
12867dd7cddfSDavid du Colombier {
12877dd7cddfSDavid du Colombier USED(modifier);
12887dd7cddfSDavid du Colombier return printins(map, pc, buf, n);
12897dd7cddfSDavid du Colombier }
12907dd7cddfSDavid du Colombier
12917dd7cddfSDavid du Colombier static int
powerdas(Map * map,uvlong pc,char * buf,int n)12924de34a7eSDavid du Colombier powerdas(Map *map, uvlong pc, char *buf, int n)
12937dd7cddfSDavid du Colombier {
12947dd7cddfSDavid du Colombier Instr instr;
12957dd7cddfSDavid du Colombier
12967dd7cddfSDavid du Colombier mymap = map;
12977dd7cddfSDavid du Colombier memset(&instr, 0, sizeof(instr));
12987dd7cddfSDavid du Colombier instr.curr = buf;
12997dd7cddfSDavid du Colombier instr.end = buf+n-1;
13007dd7cddfSDavid du Colombier if (mkinstr(pc, &instr) < 0)
13017dd7cddfSDavid du Colombier return -1;
13027dd7cddfSDavid du Colombier if (instr.end-instr.curr > 8)
13037dd7cddfSDavid du Colombier instr.curr = _hexify(instr.curr, instr.w0, 7);
13047dd7cddfSDavid du Colombier if (instr.end-instr.curr > 9 && instr.size == 2) {
13057dd7cddfSDavid du Colombier *instr.curr++ = ' ';
13067dd7cddfSDavid du Colombier instr.curr = _hexify(instr.curr, instr.w1, 7);
13077dd7cddfSDavid du Colombier }
13087dd7cddfSDavid du Colombier *instr.curr = 0;
13097dd7cddfSDavid du Colombier return instr.size*4;
13107dd7cddfSDavid du Colombier }
13117dd7cddfSDavid du Colombier
13127dd7cddfSDavid du Colombier static int
powerinstlen(Map * map,uvlong pc)13134de34a7eSDavid du Colombier powerinstlen(Map *map, uvlong pc)
13147dd7cddfSDavid du Colombier {
13157dd7cddfSDavid du Colombier Instr i;
13167dd7cddfSDavid du Colombier
13177dd7cddfSDavid du Colombier mymap = map;
13187dd7cddfSDavid du Colombier if (mkinstr(pc, &i) < 0)
13197dd7cddfSDavid du Colombier return -1;
13207dd7cddfSDavid du Colombier return i.size*4;
13217dd7cddfSDavid du Colombier }
13227dd7cddfSDavid du Colombier
13237dd7cddfSDavid du Colombier static int
powerfoll(Map * map,uvlong pc,Rgetter rget,uvlong * foll)13244de34a7eSDavid du Colombier powerfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
13257dd7cddfSDavid du Colombier {
13267dd7cddfSDavid du Colombier char *reg;
13277dd7cddfSDavid du Colombier Instr i;
13287dd7cddfSDavid du Colombier
13297dd7cddfSDavid du Colombier mymap = map;
13307dd7cddfSDavid du Colombier if (mkinstr(pc, &i) < 0)
13317dd7cddfSDavid du Colombier return -1;
13327dd7cddfSDavid du Colombier foll[0] = pc+4;
13337dd7cddfSDavid du Colombier foll[1] = pc+4;
13347dd7cddfSDavid du Colombier switch(i.op) {
13357dd7cddfSDavid du Colombier default:
13367dd7cddfSDavid du Colombier return 1;
13377dd7cddfSDavid du Colombier
13387dd7cddfSDavid du Colombier case 18: /* branch */
13397dd7cddfSDavid du Colombier foll[0] = i.li;
13407dd7cddfSDavid du Colombier if(!i.aa)
13417dd7cddfSDavid du Colombier foll[0] += pc;
13427dd7cddfSDavid du Colombier break;
13437dd7cddfSDavid du Colombier
13447dd7cddfSDavid du Colombier case 16: /* conditional branch */
13457dd7cddfSDavid du Colombier foll[0] = i.bd;
13467dd7cddfSDavid du Colombier if(!i.aa)
13477dd7cddfSDavid du Colombier foll[0] += pc;
13487dd7cddfSDavid du Colombier break;
13497dd7cddfSDavid du Colombier
13507dd7cddfSDavid du Colombier case 19: /* conditional branch to register */
13517dd7cddfSDavid du Colombier if(i.xo == 528)
13527dd7cddfSDavid du Colombier reg = "CTR";
13537dd7cddfSDavid du Colombier else if(i.xo == 16)
13547dd7cddfSDavid du Colombier reg = "LR";
13557dd7cddfSDavid du Colombier else
13567dd7cddfSDavid du Colombier return 1; /* not a branch */
13577dd7cddfSDavid du Colombier foll[0] = (*rget)(map, reg);
13587dd7cddfSDavid du Colombier break;
13597dd7cddfSDavid du Colombier }
13607dd7cddfSDavid du Colombier if(i.lk)
13617dd7cddfSDavid du Colombier return 2;
13627dd7cddfSDavid du Colombier return 1;
13637dd7cddfSDavid du Colombier }
1364