diff options
| author | forsyth <forsyth@vitanuova.com> | 2010-04-27 12:51:13 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2010-04-27 12:51:13 +0100 |
| commit | d67b7dad77bb8aa973dad1f7c3ab0c309b114278 (patch) | |
| tree | 6794120fb327d6de19cf05eed53f80d877781a3e /utils/libmach/qdb.c | |
| parent | 09da2e137d5eb0c940df35d989e4c31ec0654fc4 (diff) | |
20100427-1251
Diffstat (limited to 'utils/libmach/qdb.c')
| -rw-r--r-- | utils/libmach/qdb.c | 497 |
1 files changed, 294 insertions, 203 deletions
diff --git a/utils/libmach/qdb.c b/utils/libmach/qdb.c index 890408b1..36bc3436 100644 --- a/utils/libmach/qdb.c +++ b/utils/libmach/qdb.c @@ -3,15 +3,16 @@ #include "mach.h" /* - * PowerPC-specific debugger interface + * PowerPC-specific debugger interface, + * including 64-bit modes * forsyth@terzarima.net */ static char *powerexcep(Map*, Rgetter); -static int powerfoll(Map*, ulong, Rgetter, ulong*); -static int powerinst(Map*, ulong, char, char*, int); -static int powerinstlen(Map*, ulong); -static int powerdas(Map*, ulong, char*, int); +static int powerfoll(Map*, uvlong, Rgetter, uvlong*); +static int powerinst(Map*, uvlong, char, char*, int); +static int powerinstlen(Map*, uvlong); +static int powerdas(Map*, uvlong, char*, int); /* * Machine description @@ -21,8 +22,8 @@ Machdata powermach = {0x07f, 0xe0, 0x00, 0x08}, /* breakpoint (tw 31,r0,r0) */ 4, /* break point size */ - beswab, /* convert short to local byte order */ - beswal, /* convert long to local byte order */ + beswab, /* short to local byte order */ + beswal, /* long to local byte order */ beswav, /* vlong to local byte order */ risctrace, /* print C traceback */ riscframe, /* frame finder */ @@ -66,11 +67,11 @@ static char *excname[] = "reserved 19", "reserved 1A", /* the following are made up on a program exception */ - "floating point exception", /* 1B: FPEXC */ - "illegal instruction", /* 1C */ - "privileged instruction", /* 1D */ - "trap", /* 1E */ - "illegal operation", /* 1F */ + "floating point exception", /* FPEXC */ + "illegal instruction", + "privileged instruction", + "trap", + "illegal operation", "breakpoint", /* 20 */ }; @@ -112,11 +113,11 @@ typedef struct { uchar bi; /* bits 11-15 */ uchar bo; /* bits 6-10 */ uchar crbd; /* bits 6-10 */ - /*union {*/ + /* union { */ short d; /* bits 16-31 */ short simm; ushort uimm; - /*};*/ + /*}; */ uchar fm; /* bits 7-14 */ uchar fra; /* bits 11-15 */ uchar frb; /* bits 16-20 */ @@ -128,13 +129,15 @@ typedef struct { uchar lk; /* bit 31 */ uchar mb; /* bits 21-25 */ uchar me; /* bits 26-30 */ + uchar xmbe; /* bits 26,21-25: mb[5] || mb[0:4], also xme */ + uchar xsh; /* bits 30,16-20: sh[5] || sh[0:4] */ uchar nb; /* bits 16-20 */ uchar op; /* bits 0-5 */ uchar oe; /* bit 21 */ uchar ra; /* bits 11-15 */ uchar rb; /* bits 16-20 */ uchar rc; /* bit 31 */ - /* union {*/ + /* union { */ uchar rs; /* bits 6-10 */ uchar rd; /*};*/ @@ -143,11 +146,12 @@ typedef struct { uchar to; /* bits 6-10 */ uchar imm; /* bits 16-19 */ ushort xo; /* bits 21-30, 22-30, 26-30, or 30 (beware) */ - long immediate; + uvlong imm64; long w0; long w1; - ulong addr; /* pc of instruction */ + uvlong addr; /* pc of instruction */ short target; + short m64; /* 64-bit mode */ char *curr; /* current fill level in output buffer */ char *end; /* end of buffer */ int size; /* number of longs in instr */ @@ -157,6 +161,8 @@ typedef struct { #define IBF(v,a,b) (((ulong)(v)>>(32-(b)-1)) & ~(~0L<<(((b)-(a)+1)))) #define IB(v,b) IBF((v),(b),(b)) +#pragma varargck argpos bprint 2 + static void bprint(Instr *i, char *fmt, ...) { @@ -168,14 +174,15 @@ bprint(Instr *i, char *fmt, ...) } static int -decode(ulong pc, Instr *i) +decode(uvlong pc, Instr *i) { - long w; + ulong w; if (get4(mymap, pc, &w) < 0) { werrstr("can't read instruction: %r"); return -1; } + i->m64 = asstype == APOWER64; i->aa = IB(w, 30); i->crba = IBF(w, 11, 15); i->crbb = IBF(w, 16, 20); @@ -188,8 +195,6 @@ decode(ulong pc, Instr *i) i->bo = IBF(w, 6, 10); i->crbd = IBF(w, 6, 10); i->uimm = IBF(w, 16, 31); /* also d, simm */ - i->simm = i->uimm; - i->d = i->uimm; i->fm = IBF(w, 7, 14); i->fra = IBF(w, 11, 15); i->frb = IBF(w, 16, 20); @@ -203,6 +208,7 @@ decode(ulong pc, Instr *i) i->lk = IB(w, 31); i->mb = IBF(w, 21, 25); i->me = IBF(w, 26, 30); + i->xmbe = (IB(w,26)<<5) | i->mb; i->nb = IBF(w, 16, 20); i->op = IBF(w, 0, 5); i->oe = IB(w, 21); @@ -210,15 +216,21 @@ decode(ulong pc, Instr *i) i->rb = IBF(w, 16, 20); i->rc = IB(w, 31); i->rs = IBF(w, 6, 10); /* also rd */ - i->rd = i->rs; i->sh = IBF(w, 16, 20); + i->xsh = (IB(w, 30)<<5) | i->sh; i->spr = IBF(w, 11, 20); i->to = IBF(w, 6, 10); i->imm = IBF(w, 16, 19); i->xo = IBF(w, 21, 30); /* bits 21-30, 22-30, 26-30, or 30 (beware) */ - i->immediate = i->simm; + if(i->op == 58){ /* class of 64-bit loads */ + i->xo = i->simm & 3; + i->simm &= ~3; + } + i->imm64 = i->simm; if(i->op == 15) - i->immediate <<= 16; + i->imm64 <<= 16; + else if(i->op == 25 || i->op == 27 || i->op == 29) + i->imm64 = (uvlong)(i->uimm<<16); i->w0 = w; i->target = -1; i->addr = pc; @@ -227,7 +239,7 @@ decode(ulong pc, Instr *i) } static int -mkinstr(ulong pc, Instr *i) +mkinstr(uvlong pc, Instr *i) { Instr x; @@ -235,26 +247,15 @@ mkinstr(ulong pc, Instr *i) return -1; /* * combine ADDIS/ORI (CAU/ORIL) into MOVW + * also ORIS/ORIL for unsigned in 64-bit mode */ - if (i->op == 15 && i->ra==0) { + if ((i->op == 15 || i->op == 25) && i->ra==0) { if(decode(pc+4, &x) < 0) return -1; if (x.op == 24 && x.rs == x.ra && x.ra == i->rd) { - i->immediate |= (x.immediate & 0xFFFF); - i->w1 = x.w0; - i->target = x.rd; - i->size++; - return 1; - } - } - if (i->op == 15 && i->ra==REGSB && mach->sb) { - if(decode(pc+4, &x) < 0) - return -1; - if (x.op >= 32 && x.op < 54 && i->rd == x.ra) { - i->op = x.op; - i->ra = REGSB; - i->rs = i->rd = x.rd; - i->immediate += x.simm; + i->imm64 |= (x.imm64 & 0xFFFF); + if(i->op != 15) + i->imm64 &= 0xFFFFFFFFUL; i->w1 = x.w0; i->target = x.rd; i->size++; @@ -267,20 +268,20 @@ mkinstr(ulong pc, Instr *i) static int plocal(Instr *i) { - int offset; + long offset; Symbol s; if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s)) return -1; - offset = s.value - i->immediate; + offset = s.value - i->imm64; if (offset > 0) { if(getauto(&s, offset, CAUTO, &s)) { - bprint(i, "%s+%d(SP)", s.name, s.value); + bprint(i, "%s+%lld(SP)", s.name, s.value); return 1; } } else { if (getauto(&s, -offset-4, CPARAM, &s)) { - bprint(i, "%s+%d(FP)", s.name, -offset); + bprint(i, "%s+%ld(FP)", s.name, -offset); return 1; } } @@ -288,18 +289,17 @@ plocal(Instr *i) } static int -pglobal(Instr *i, long off, int anyoff, char *reg) +pglobal(Instr *i, uvlong off, int anyoff, char *reg) { Symbol s, s2; - long off1; + uvlong off1; if(findsym(off, CANY, &s) && - strcmp(s.name, ".string") != 0 && - (ulong)(off-s.value) < 4096 && + s.value-off < 4096 && (s.class == CDATA || s.class == CTEXT)) { if(off==s.value && s.name[0]=='$'){ off1 = 0; - get4(mymap, s.value, &off1); + geta(mymap, s.value, &off1); if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){ bprint(i, "$%s%s", s2.name, reg); return 1; @@ -307,13 +307,13 @@ pglobal(Instr *i, long off, int anyoff, char *reg) } bprint(i, "%s", s.name); if (s.value != off) - bprint(i, "+%lux", off-s.value); + bprint(i, "+%llux", off-s.value); bprint(i, reg); return 1; } if(!anyoff) return 0; - bprint(i, "%lux%s", off, reg); + bprint(i, "%llux%s", off, reg); return 1; } @@ -322,16 +322,12 @@ address(Instr *i) { if (i->ra == REGSP && plocal(i) >= 0) return; - if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->immediate, 0, "(SB)") > 0) + if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->imm64, 0, "(SB)") >= 0) return; - if(i->immediate < 0) - bprint(i, "-%lx", -i->immediate); - else - bprint(i, "%lux", i->immediate); - if (i->ra == REGSB && mach->sb) - bprint(i, "(SB)"); + if(i->simm < 0) + bprint(i, "-%x(R%d)", -i->simm, i->ra); else - bprint(i, "(R%d)", i->ra); + bprint(i, "%llux(R%d)", i->imm64, i->ra); } static char *tcrbits[] = {"LT", "GT", "EQ", "VS"}; @@ -362,12 +358,12 @@ branch(Opcode *o, Instr *i) if(bo != 20) { bi = i->bi&3; sprint(buf, "B%s%%L", bo==12? tcrbits[bi]: fcrbits[bi]); - format(buf, i, 0); + format(buf, i, nil); bprint(i, "\t"); if(i->bi > 4) bprint(i, "CR(%d),", i->bi/4); } else - format("BR%L\t", i, 0); + format("BR%L\t", i, nil); if(i->op == 16) format(0, i, "%J"); else if(i->op == 19 && i->xo == 528) @@ -383,7 +379,7 @@ addi(Opcode *o, Instr *i) { if (i->op==14 && i->ra == 0) format("MOVW", i, "%i,R%d"); - else if (i->ra == REGSP || i->ra == REGSB) { + else if (i->ra == REGSB) { bprint(i, "MOVW\t$"); address(i); bprint(i, ",R%d", i->rd); @@ -403,23 +399,19 @@ addis(Opcode *o, Instr *i) { long v; - v = i->immediate; - if (i->op==15 && i->ra == 0) { - bprint(i, "MOVW\t$"); - pglobal(i, i->immediate, 1, ""); - bprint(i, ",R%d", i->rd); - } - else if (i->op==15 && i->ra == REGSB && mach->sb) { + v = i->imm64; + if (i->op==15 && i->ra == 0) + bprint(i, "MOVW\t$%lux,R%d", v, i->rd); + else if (i->op==15 && i->ra == REGSB) { bprint(i, "MOVW\t$"); address(i); bprint(i, ",R%d", i->rd); -/* how about auto/param addresses? */ } else if(i->op==15 && v < 0) { - bprint(i, "SUB\t$%d,R%d", -v, i->ra); + bprint(i, "SUB\t$%ld,R%d", -v, i->ra); if(i->rd != i->ra) bprint(i, ",R%d", i->rd); } else { - format(o->mnemonic, i, 0); + format(o->mnemonic, i, nil); bprint(i, "\t$%ld,R%d", v, i->ra); if(i->rd != i->ra) bprint(i, ",R%d", i->rd); @@ -509,7 +501,8 @@ dcb(Opcode *o, Instr *i) static void lw(Opcode *o, Instr *i, char r) { - bprint(i, "%s\t", o->mnemonic); + format(o->mnemonic, i, nil); + bprint(i, "\t"); address(i); bprint(i, ",%c%d", r, i->rd); } @@ -530,29 +523,28 @@ static void sw(Opcode *o, Instr *i, char r) { int offset; - char *m; Symbol s; - m = o->mnemonic; - if (i->ra == REGSP) { + if (i->rs == REGSP) { if (findsym(i->addr, CTEXT, &s) && findlocal(&s, FRAMENAME, &s)) { - offset = s.value-i->immediate; + offset = s.value-i->imm64; if (offset > 0 && getauto(&s, offset, CAUTO, &s)) { - bprint(i, "%s\t%c%d,%s-%d(SP)", m, r, i->rs, - s.name, offset); + format(o->mnemonic, i, nil); + bprint(i, "\t%c%d,%s-%d(SP)", r, i->rd, s.name, offset); return; } } } - if (i->ra == REGSP || i->ra == REGSB && mach->sb) { - bprint(i, "%s\t%c%d,", m, r, i->rs); + if (i->rs == REGSB && mach->sb) { + format(o->mnemonic, i, nil); + bprint(i, "\t%c%d,", r, i->rd); address(i); return; } if (r == 'F') - format(m, i, "F%d,%l"); + format(o->mnemonic, i, "F%d,%l"); else - format(m, i, o->ken); + format(o->mnemonic, i, o->ken); } static void @@ -599,7 +591,8 @@ add(Opcode *o, Instr *i) static void sub(Opcode *o, Instr *i) { - format(o->mnemonic, i, 0); + format(o->mnemonic, i, nil); + bprint(i, "\t"); if(i->op == 31) { bprint(i, "\tR%d,R%d", i->ra, i->rb); /* subtract Ra from Rb */ if(i->rd != i->rb) @@ -609,9 +602,9 @@ sub(Opcode *o, Instr *i) } static void -qmuldiv(Opcode *o, Instr *i) +qdiv(Opcode *o, Instr *i) { - format(o->mnemonic, i, 0); + format(o->mnemonic, i, nil); if(i->op == 31) bprint(i, "\tR%d,R%d", i->rb, i->ra); else @@ -646,7 +639,7 @@ or(Opcode *o, Instr *i) if (i->op == 31) { /* Rb,Rs,Ra */ if (i->rs == 0 && i->ra == 0 && i->rb == 0) - format("NOP", i, 0); + format("NOP", i, nil); else if (i->rs == i->rb) format("MOVW", i, "R%b,R%a"); else @@ -658,7 +651,7 @@ or(Opcode *o, Instr *i) static void shifted(Opcode *o, Instr *i) { - format(o->mnemonic, i, 0); + format(o->mnemonic, i, nil); bprint(i, "\t$%lux,", (ulong)i->uimm<<16); if (i->rs == i->ra) bprint(i, "R%d", i->ra); @@ -679,7 +672,7 @@ static char ir2[] = "R%a,R%d"; /* reverse of IBM order */ static char ir3[] = "R%b,R%a,R%d"; static char ir3r[] = "R%a,R%b,R%d"; static char il3[] = "R%b,R%s,R%a"; -static char il2u[] = "%I,R%s,R%a"; +static char il2u[] = "%I,R%a,R%d"; static char il3s[] = "$%k,R%s,R%a"; static char il2[] = "R%s,R%a"; static char icmp3[] = "R%a,R%b,%D"; @@ -694,12 +687,16 @@ static char ldop[] = "%l,R%d"; static char stop[] = "R%d,%l"; static char fldop[] = "%l,F%d"; static char fstop[] = "F%d,%l"; +static char rldc[] = "R%b,R%s,$%E,R%a"; static char rlim[] = "R%b,R%s,$%z,R%a"; static char rlimi[] = "$%k,R%s,$%z,R%a"; +static char rldi[] = "$%e,R%s,$%E,R%a"; #define OEM IBF(~0,22,30) #define FP4 IBF(~0,26,30) -#define ALL ((ushort)~0) +#define ALL (~0) +#define RLDC 0xF +#define RLDI 0xE /* notes: 10-26: crfD = rD>>2; rD&3 mbz @@ -707,8 +704,6 @@ notes: */ static Opcode opcodes[] = { - {31, 360, OEM, "ABS%V%C", 0, ir2}, /* POWER */ - {31, 266, OEM, "ADD%V%C", add, ir3}, {31, 10, OEM, "ADDC%V%C", add, ir3}, {31, 138, OEM, "ADDE%V%C", add, ir3}, @@ -721,22 +716,21 @@ static Opcode opcodes[] = { {31, 28, ALL, "AND%C", and, il3}, {31, 60, ALL, "ANDN%C", and, il3}, - {28, 0, 0, "ANDCC", andi, il2u}, - {29, 0, 0, "ANDCC", shifted, 0}, + {28, 0, 0, "ANDCC", andi, il2u}, + {29, 0, 0, "ANDCC", shifted, 0}, {18, 0, 0, "B%L", gencc, "%j"}, {16, 0, 0, "BC%L", branch, "%d,%a,%J"}, {19, 528, ALL, "BC%L", branch, "%d,%a,(CTR)"}, {19, 16, ALL, "BC%L", branch, "%d,%a,(LR)"}, - {31, 531, ALL, "CLCS", gen, ir2}, /* POWER */ - {31, 0, ALL, "CMP", 0, icmp3}, {11, 0, 0, "CMP", 0, "R%a,%i,%D"}, {31, 32, ALL, "CMPU", 0, icmp3}, {10, 0, 0, "CMPU", 0, "R%a,%I,%D"}, - {31, 26, ALL, "CNTLZ%C", gencc, ir2}, + {31, 58, ALL, "CNTLZD%C", gencc, ir2}, /* 64 */ + {31, 26, ALL, "CNTLZ%W%C", gencc, ir2}, {19, 257, ALL, "CRAND", gen, cr3op}, {19, 129, ALL, "CRANDN", gen, cr3op}, @@ -753,14 +747,13 @@ static Opcode opcodes[] = { {31, 278, ALL, "DCBT", dcb, 0}, {31, 246, ALL, "DCBTST", dcb, 0}, {31, 1014, ALL, "DCBZ", dcb, 0}, + {31, 454, ALL, "DCCCI", dcb, 0}, + {31, 966, ALL, "ICCCI", dcb, 0}, - {31, 331, OEM, "DIV%V%C", qmuldiv, ir3}, /* POWER */ - {31, 363, OEM, "DIVS%V%C", qmuldiv, ir3}, /* POWER */ - {31, 491, OEM, "DIVW%V%C", qmuldiv, ir3}, - {31, 459, OEM, "DIVWU%V%C", qmuldiv, ir3}, - - {31, 264, OEM, "DOZ%V%C", gencc, ir3r}, /* POWER */ - {9, 0, 0, "DOZ", gen, ir2i}, /* POWER */ + {31, 489, OEM, "DIVD%V%C", qdiv, ir3}, /* 64 */ + {31, 457, OEM, "DIVDU%V%C", qdiv, ir3}, /* 64 */ + {31, 491, OEM, "DIVW%V%C", qdiv, ir3}, + {31, 459, OEM, "DIVWU%V%C", qdiv, ir3}, {31, 310, ALL, "ECIWX", ldx, 0}, {31, 438, ALL, "ECOWX", stx, 0}, @@ -770,12 +763,16 @@ static Opcode opcodes[] = { {31, 954, ALL, "EXTSB%C", gencc, il2}, {31, 922, ALL, "EXTSH%C", gencc, il2}, + {31, 986, ALL, "EXTSW%C", gencc, il2}, /* 64 */ {63, 264, ALL, "FABS%C", gencc, fp2}, {63, 21, ALL, "FADD%C", gencc, fp3}, {59, 21, ALL, "FADDS%C", gencc, fp3}, {63, 32, ALL, "FCMPO", gen, fpcmp}, {63, 0, ALL, "FCMPU", gen, fpcmp}, + {63, 846, ALL, "FCFID%C", gencc, fp2}, /* 64 */ + {63, 814, ALL, "FCTID%C", gencc, fp2}, /* 64 */ + {63, 815, ALL, "FCTIDZ%C", gencc, fp2}, /* 64 */ {63, 14, ALL, "FCTIW%C", gencc, fp2}, {63, 15, ALL, "FCTIWZ%C", gencc, fp2}, {63, 18, ALL, "FDIV%C", gencc, fp3}, @@ -793,11 +790,16 @@ static Opcode opcodes[] = { {59, 31, FP4, "FNMADDS%C", gencc, fp4}, {63, 30, FP4, "FNMSUB%C", gencc, fp4}, {59, 30, FP4, "FNMSUBS%C", gencc, fp4}, + {59, 24, ALL, "FRES%C", gencc, fp2}, /* optional */ {63, 12, ALL, "FRSP%C", gencc, fp2}, + {63, 26, ALL, "FRSQRTE%C", gencc, fp2}, /* optional */ + {63, 23, FP4, "FSEL%CC", gencc, fp4}, /* optional */ + {63, 22, ALL, "FSQRT%C", gencc, fp2}, /* optional */ + {59, 22, ALL, "FSQRTS%C", gencc, fp2}, /* optional */ {63, 20, FP4, "FSUB%C", gencc, fp3}, {59, 20, FP4, "FSUBS%C", gencc, fp3}, - {31, 982, ALL, "ICBI", dcb, 0}, + {31, 982, ALL, "ICBI", dcb, 0}, /* optional */ {19, 150, ALL, "ISYNC", gen, 0}, {34, 0, 0, "MOVBZ", load, ldop}, @@ -822,18 +824,26 @@ static Opcode opcodes[] = { {31, 311, ALL, "MOVHZU", ldx, 0}, {31, 279, ALL, "MOVHZ", ldx, 0}, {46, 0, 0, "MOVMW", load, ldop}, - {31, 277, ALL, "LSCBX%C", ldx, 0}, /* POWER */ {31, 597, ALL, "LSW", gen, "(R%a),$%n,R%d"}, {31, 533, ALL, "LSW", ldx, 0}, {31, 20, ALL, "LWAR", ldx, 0}, + {31, 84, ALL, "LWARD", ldx, 0}, /* 64 */ + + {58, 0, ALL, "MOVD", load, ldop}, /* 64 */ + {58, 1, ALL, "MOVDU", load, ldop}, /* 64 */ + {31, 53, ALL, "MOVDU", ldx, 0}, /* 64 */ + {31, 21, ALL, "MOVD", ldx, 0}, /* 64 */ + {31, 534, ALL, "MOVWBR", ldx, 0}, - {32, 0, 0, "MOVW", load, ldop}, - {33, 0, 0, "MOVWU", load, ldop}, - {31, 55, ALL, "MOVWU", ldx, 0}, - {31, 23, ALL, "MOVW", ldx, 0}, - {31, 29, ALL, "MASKG%C", gencc, "R%s:R%b,R%d"}, /* POWER */ - {31, 541, ALL, "MASKIR%C", gencc, "R%s,R%b,R%a"}, /* POWER */ + {58, 2, ALL, "MOVW", load, ldop}, /* 64 (lwa) */ + {31, 373, ALL, "MOVWU", ldx, 0}, /* 64 */ + {31, 341, ALL, "MOVW", ldx, 0}, /* 64 */ + + {32, 0, 0, "MOVW%Z", load, ldop}, + {33, 0, 0, "MOVW%ZU", load, ldop}, + {31, 55, ALL, "MOVW%ZU", ldx, 0}, + {31, 23, ALL, "MOVW%Z", ldx, 0}, {19, 0, ALL, "MOVFL", gen, "%S,%D"}, {63, 64, ALL, "MOVCRFS", gen, "%S,%D"}, @@ -845,67 +855,63 @@ static Opcode opcodes[] = { {31, 339, ALL, "MOVW", gen, "%P,R%d"}, {31, 595, ALL, "MOVW", gen, "SEG(%a),R%d"}, {31, 659, ALL, "MOVW", gen, "SEG(R%b),R%d"}, + {31, 323, ALL, "MOVW", gen, "DCR(%Q),R%d"}, + {31, 451, ALL, "MOVW", gen, "R%s,DCR(%Q)"}, {31, 144, ALL, "MOVFL", gen, "R%s,%m,CR"}, {63, 70, ALL, "MTFSB0%C", gencc, "%D"}, {63, 38, ALL, "MTFSB1%C", gencc, "%D"}, {63, 711, ALL, "MOVFL%C", gencc, "F%b,%M,FPSCR"}, /* mtfsf */ {63, 134, ALL, "MOVFL%C", gencc, "%K,%D"}, {31, 146, ALL, "MOVW", gen, "R%s,MSR"}, + {31, 178, ALL, "MOVD", gen, "R%s,MSR"}, {31, 467, ALL, "MOVW", gen, "R%s,%P"}, {31, 210, ALL, "MOVW", gen, "R%s,SEG(%a)"}, {31, 242, ALL, "MOVW", gen, "R%s,SEG(R%b)"}, - {31, 107, OEM, "MUL%V%C", gencc, ir3}, /* POWER */ - {31, 75, ALL, "MULHW%C", gencc, ir3}, /* POWER */ - {31, 11, ALL, "MULHWU%C", gencc, ir3}, /* POWER */ + {31, 73, ALL, "MULHD%C", gencc, ir3}, + {31, 9, ALL, "MULHDU%C", gencc, ir3}, + {31, 233, OEM, "MULLD%V%C", gencc, ir3}, + {31, 75, ALL, "MULHW%C", gencc, ir3}, + {31, 11, ALL, "MULHWU%C", gencc, ir3}, {31, 235, OEM, "MULLW%V%C", gencc, ir3}, - {7, 0, 0, "MULLW", qmuldiv, "%i,R%a,R%d"}, - {31, 488, OEM, "NABS%V%C", neg, ir2}, /* POWER */ + {7, 0, 0, "MULLW", qdiv, "%i,R%a,R%d"}, {31, 476, ALL, "NAND%C", gencc, il3}, {31, 104, OEM, "NEG%V%C", neg, ir2}, {31, 124, ALL, "NOR%C", gencc, il3}, - {31, 444, ALL, "OR%C", or, il3}, + {31, 444, ALL, "OR%C", or, il3}, {31, 412, ALL, "ORN%C", or, il3}, {24, 0, 0, "OR", and, "%I,R%d,R%a"}, {25, 0, 0, "OR", shifted, 0}, {19, 50, ALL, "RFI", gen, 0}, + {19, 51, ALL, "RFCI", gen, 0}, + + {30, 8, RLDC, "RLDCL%C", gencc, rldc}, /* 64 */ + {30, 9, RLDC, "RLDCR%C", gencc, rldc}, /* 64 */ + {30, 0, RLDI, "RLDCL%C", gencc, rldi}, /* 64 */ + {30, 1<<1, RLDI, "RLDCR%C", gencc, rldi}, /* 64 */ + {30, 2<<1, RLDI, "RLDC%C", gencc, rldi}, /* 64 */ + {30, 3<<1, RLDI, "RLDMI%C", gencc, rldi}, /* 64 */ - {22, 0, 0, "RLMI%C", gencc, rlim}, /* POWER */ {20, 0, 0, "RLWMI%C", gencc, rlimi}, {21, 0, 0, "RLWNM%C", gencc, rlimi}, {23, 0, 0, "RLWNM%C", gencc, rlim}, - {31, 537, ALL, "RRIB%C", gencc, il3}, /* POWER */ - {17, 1, ALL, "SYSCALL", gen, 0}, - {31, 153, ALL, "SLE%C", shift, il3}, /* POWER */ - {31, 217, ALL, "SLEQ%C", shift, il3}, /* POWER */ - {31, 184, ALL, "SLQ%C", shifti, il3s}, /* POWER */ - {31, 248, ALL, "SLLQ%C", shifti, il3s}, /* POWER */ - {31, 216, ALL, "SLLQ%C", shift, il3}, /* POWER */ - {31, 152, ALL, "SLQ%C", shift, il3}, /* POWER */ - + {31, 27, ALL, "SLD%C", shift, il3}, /* 64 */ {31, 24, ALL, "SLW%C", shift, il3}, - {31, 920, ALL, "SRAQ%C", shift, il3}, /* POWER */ - {31, 952, ALL, "SRAQ%C", shifti, il3s}, /* POWER */ - + {31, 794, ALL, "SRAD%C", shift, il3}, /* 64 */ + {31, (413<<1)|0, ALL, "SRAD%C", shifti, il3s}, /* 64 */ + {31, (413<<1)|1, ALL, "SRAD%C", shifti, il3s}, /* 64 */ {31, 792, ALL, "SRAW%C", shift, il3}, {31, 824, ALL, "SRAW%C", shifti, il3s}, - {31, 665, ALL, "SRE%C", shift, il3}, /* POWER */ - {31, 921, ALL, "SREA%C", shift, il3}, /* POWER */ - {31, 729, ALL, "SREQ%C", shift, il3}, /* POWER */ - {31, 696, ALL, "SRQ%C", shifti, il3s}, /* POWER */ - {31, 760, ALL, "SRLQ%C", shifti, il3s}, /* POWER */ - {31, 728, ALL, "SRLQ%C", shift, il3}, /* POWER */ - {31, 664, ALL, "SRQ%C", shift, il3}, /* POWER */ - + {31, 539, ALL, "SRD%C", shift, il3}, /* 64 */ {31, 536, ALL, "SRW%C", shift, il3}, {38, 0, 0, "MOVB", store, stop}, @@ -931,10 +937,22 @@ static Opcode opcodes[] = { {36, 0, 0, "MOVW", store, stop}, {31, 662, ALL, "MOVWBR", stx, 0}, {31, 150, ALL, "STWCCC", stx, 0}, + {31, 214, ALL, "STDCCC", stx, 0}, /* 64 */ {37, 0, 0, "MOVWU", store, stop}, {31, 183, ALL, "MOVWU", stx, 0}, {31, 151, ALL, "MOVW", stx, 0}, + {62, 0, 0, "MOVD%U", store, stop}, /* 64 */ + {31, 149, ALL, "MOVD", stx, 0,}, /* 64 */ + {31, 181, ALL, "MOVDU", stx, 0}, /* 64 */ + + {31, 498, ALL, "SLBIA", gen, 0}, /* 64 */ + {31, 434, ALL, "SLBIE", gen, "R%b"}, /* 64 */ + {31, 466, ALL, "SLBIEX", gen, "R%b"}, /* 64 */ + {31, 915, ALL, "SLBMFEE", gen, "R%b,R%d"}, /* 64 */ + {31, 851, ALL, "SLBMFEV", gen, "R%b,R%d"}, /* 64 */ + {31, 402, ALL, "SLBMTE", gen, "R%s,R%b"}, /* 64 */ + {31, 40, OEM, "SUB%V%C", sub, ir3}, {31, 8, OEM, "SUBC%V%C", sub, ir3}, {31, 136, OEM, "SUBE%V%C", sub, ir3}, @@ -942,11 +960,15 @@ static Opcode opcodes[] = { {31, 232, OEM, "SUBME%V%C", sub, ir2}, {31, 200, OEM, "SUBZE%V%C", sub, ir2}, - {31, 598, ALL, "SYNC", gen, 0}, - {31, 306, ALL, "TLBIE", gen, "R%b"}, - {31, 370, ALL, "TLBIA", gen, 0}, - {31, 1010, ALL, "TLBLI", gen, "R%b"}, - {31, 978, ALL, "TLBLD", gen, "R%b"}, + {31, 598, ALL, "SYNC", gen, 0}, /* TO DO: there's a parameter buried in there */ + {2, 0, 0, "TD", gen, "%d,R%a,%i"}, /* 64 */ + {31, 370, ALL, "TLBIA", gen, 0}, /* optional */ + {31, 306, ALL, "TLBIE", gen, "R%b"}, /* optional */ + {31, 274, ALL, "TLBIEL", gen, "R%b"}, /* optional */ + {31, 1010, ALL, "TLBLI", gen, "R%b"}, /* optional */ + {31, 978, ALL, "TLBLD", gen, "R%b"}, /* optional */ + {31, 566, ALL, "TLBSYNC", gen, 0}, /* optional */ + {31, 68, ALL, "TD", gen, "%d,R%a,R%b"}, /* 64 */ {31, 4, ALL, "TW", gen, "%d,R%a,R%b"}, {3, 0, 0, "TW", gen, "%d,R%a,%i"}, @@ -1013,11 +1035,31 @@ static Spr sprname[] = { {0,0}, }; +static int +shmask(uvlong *m) +{ + int i; + + for(i=0; i<63; i++) + if(*m & ((uvlong)1<<i)) + break; + if(i > 63) + return 0; + if(*m & ~((uvlong)1<<i)){ /* more than one bit: do multiples of bytes */ + i = (i/8)*8; + if(i == 0) + return 0; + } + *m >>= i; + return i; +} + static void format(char *mnemonic, Instr *i, char *f) { int n, s; ulong mask; + uvlong vmask; if (mnemonic) format(0, i, mnemonic); @@ -1031,15 +1073,6 @@ format(char *mnemonic, Instr *i, char *f) continue; } switch (*++f) { - case 'V': - if(i->oe) - bprint(i, "V"); - break; - - case 'C': - if(i->rc) - bprint(i, "CC"); - break; case 'a': bprint(i, "%d", i->ra); @@ -1058,13 +1091,9 @@ format(char *mnemonic, Instr *i, char *f) bprint(i, "%d", i->rd); break; - case 'S': - if(i->ra & 3) - bprint(i, "CR(INVAL:%d)", i->ra); - else if(i->op == 63) - bprint(i, "FPSCR(%d)", i->crfs); - else - bprint(i, "CR(%d)", i->crfs); + case 'C': + if(i->rc) + bprint(i, "CC"); break; case 'D': @@ -1076,20 +1105,83 @@ format(char *mnemonic, Instr *i, char *f) bprint(i, "CR(%d)", i->crfd); break; - case 'l': - address(i); + case 'e': + bprint(i, "%d", i->xsh); + break; + + case 'E': + switch(IBF(i->w0,27,30)){ /* low bit is top bit of shift in rldiX cases */ + case 8: i->mb = i->xmbe; i->me = 63; break; /* rldcl */ + case 9: i->mb = 0; i->me = i->xmbe; break; /* rldcr */ + case 4: case 5: + i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldic */ + case 0: case 1: + i->mb = i->xmbe; i->me = 63; break; /* rldicl */ + case 2: case 3: + i->mb = 0; i->me = i->xmbe; break; /* rldicr */ + case 6: case 7: + i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldimi */ + } + vmask = (~(uvlong)0>>i->mb) & (~(uvlong)0<<(63-i->me)); + s = shmask(&vmask); + if(s) + bprint(i, "(%llux<<%d)", vmask, s); + else + bprint(i, "%llux", vmask); break; case 'i': - bprint(i, "$%ld", i->simm); + bprint(i, "$%d", i->simm); break; case 'I': - bprint(i, "$%lx", i->uimm); + bprint(i, "$%ux", i->uimm); break; - case 'w': - bprint(i, "[%lux]", i->w0); + case 'j': + if(i->aa) + pglobal(i, i->li, 1, "(SB)"); + else + pglobal(i, i->addr+i->li, 1, ""); + break; + + case 'J': + if(i->aa) + pglobal(i, i->bd, 1, "(SB)"); + else + pglobal(i, i->addr+i->bd, 1, ""); + break; + + case 'k': + bprint(i, "%d", i->sh); + break; + + case 'K': + bprint(i, "$%x", i->imm); + break; + + case 'L': + if(i->lk) + bprint(i, "L"); + break; + + case 'l': + if(i->simm < 0) + bprint(i, "-%x(R%d)", -i->simm, i->ra); + else + bprint(i, "%x(R%d)", i->simm, i->ra); + break; + + case 'm': + bprint(i, "%ux", i->crm); + break; + + case 'M': + bprint(i, "%ux", i->fm); + break; + + case 'n': + bprint(i, "%d", i->nb==0? 32: i->nb); /* eg, pg 10-103 */ break; case 'P': @@ -1098,7 +1190,7 @@ format(char *mnemonic, Instr *i, char *f) if(sprname[s].n == n) break; if(sprname[s].name) { - if(n < 10) + if(s < 10) bprint(i, sprname[s].name); else bprint(i, "SPR(%s)", sprname[s].name); @@ -1106,51 +1198,50 @@ format(char *mnemonic, Instr *i, char *f) bprint(i, "SPR(%d)", n); break; - case 'n': - bprint(i, "%d", i->nb==0? 32: i->nb); /* eg, pg 10-103 */ - break; - - case 'm': - bprint(i, "%lx", i->crm); + case 'Q': + n = ((i->spr&0x1f)<<5)|((i->spr>>5)&0x1f); + bprint(i, "%d", n); break; - case 'M': - bprint(i, "%lx", i->fm); + case 'S': + if(i->ra & 3) + bprint(i, "CR(INVAL:%d)", i->ra); + else if(i->op == 63) + bprint(i, "FPSCR(%d)", i->crfs); + else + bprint(i, "CR(%d)", i->crfs); break; - case 'z': - if(i->mb <= i->me) - mask = ((ulong)~0L>>i->mb) & (~0L<<(31-i->me)); - else - mask = ~(((ulong)~0L>>(i->me+1)) & (~0L<<(31-(i->mb-1)))); - bprint(i, "%lux", mask); + case 'U': + if(i->rc) + bprint(i, "U"); break; - case 'k': - bprint(i, "%d", i->sh); + case 'V': + if(i->oe) + bprint(i, "V"); break; - case 'K': - bprint(i, "$%x", i->imm); + case 'w': + bprint(i, "[%lux]", i->w0); break; - case 'L': - if(i->lk) - bprint(i, "L"); + case 'W': + if(i->m64) + bprint(i, "W"); break; - case 'j': - if(i->aa) - pglobal(i, i->li, 1, "(SB)"); - else - pglobal(i, i->addr+i->li, 1, ""); + case 'Z': + if(i->m64) + bprint(i, "Z"); break; - case 'J': - if(i->aa) - pglobal(i, i->bd, 1, "(SB)"); + case 'z': + if(i->mb <= i->me) + mask = ((ulong)~0L>>i->mb) & (~0L<<(31-i->me)); else - pglobal(i, i->addr+i->bd, 1, ""); + mask = ~(((ulong)~0L>>(i->me+1)) & (~0L<<(31-(i->mb-1)))); + bprint(i, "%lux", mask); break; case '\0': @@ -1165,7 +1256,7 @@ format(char *mnemonic, Instr *i, char *f) } static int -printins(Map *map, ulong pc, char *buf, int n) +printins(Map *map, uvlong pc, char *buf, int n) { Instr i; Opcode *o; @@ -1189,14 +1280,14 @@ printins(Map *map, ulong pc, char *buf, int n) } static int -powerinst(Map *map, ulong pc, char modifier, char *buf, int n) +powerinst(Map *map, uvlong pc, char modifier, char *buf, int n) { USED(modifier); return printins(map, pc, buf, n); } static int -powerdas(Map *map, ulong pc, char *buf, int n) +powerdas(Map *map, uvlong pc, char *buf, int n) { Instr instr; @@ -1217,7 +1308,7 @@ powerdas(Map *map, ulong pc, char *buf, int n) } static int -powerinstlen(Map *map, ulong pc) +powerinstlen(Map *map, uvlong pc) { Instr i; @@ -1228,7 +1319,7 @@ powerinstlen(Map *map, ulong pc) } static int -powerfoll(Map *map, ulong pc, Rgetter rget, ulong *foll) +powerfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll) { char *reg; Instr i; |
