condition_table_true = ["lt", "gt", "eq"] condition_table_false = ["ge", "le", "ne"] trap_condition_table = { 1: "lgt", 2: "llt", 4: "eq", 5: "lge", 8: "gt", 12: "ge", 16: "lt", 20: "le", 31: "u" } spr_table = { 8: "lr", 9: "ctr" } def decodeI(value): return (value >> 2) & 0xFFFFFF, (value >> 1) & 1, value & 1 def decodeB(value): return (value >> 21) & 0x1F, (value >> 16) & 0x1F, (value >> 2) & 0x3FFF, (value >> 1) & 1, value & 1 def decodeD(value): return (value >> 21) & 0x1F, (value >> 16) & 0x1F, value & 0xFFFF def decodeX(value): return (value >> 21) & 0x1F, (value >> 16) & 0x1F, (value >> 11) & 0x1F, (value >> 1) & 0x3FF, value & 1 def extend_sign(value, bits=16): if value & 1 << (bits - 1): value -= 1 << bits return value def ihex(value): return "-" * (value < 0) + "0x" + hex(value).lstrip("-0x").rstrip("L").zfill(1).upper() def decodeCond(BO, BI): #TODO: Better condition code if BO == 20: return "" if BO & 1: return "?" if BI > 2: return "?" if BO == 4: return condition_table_false[BI] if BO == 12: return condition_table_true[BI] return "?" def loadStore(value, regtype="r"): D, A, d = decodeD(value) d = extend_sign(d) return "%s%i, %s(r%i)" %(regtype, D, ihex(d), A) def loadStoreX(D, A, B, pad): if pad: return "" return "r%i, %s, r%i" %(D, ("r%i" %A) if A else "0", B) def add(D, A, B, Rc): return "add%s" %("." * Rc), "r%i, r%i, r%i" %(D, A, B) def addi(value, addr): D, A, SIMM = decodeD(value) SIMM = extend_sign(SIMM) if A == 0: return "li", "r%i, %s" %(D, ihex(SIMM)) return "addi", "r%i, r%i, %s" %(D, A, ihex(SIMM)) def addic(value, addr): D, A, SIMM = decodeD(value) SIMM = extend_sign(SIMM) return "addic", "r%i, r%i, %s" %(D, A, ihex(SIMM)) def addic_(value, addr): D, A, SIMM = decodeD(value) SIMM = extend_sign(SIMM) return "addic.", "r%i, r%i, %s" %(D, A, ihex(SIMM)) def addis(value, addr): D, A, SIMM = decodeD(value) SIMM = extend_sign(SIMM) if A == 0: return "lis", "r%i, %s" %(D, ihex(SIMM)) return "addis", "r%i, r%i, %s" %(D, A, ihex(SIMM)) def and_(S, A, B, Rc): return "and%s" % ("." * Rc), "r%i, r%i, r%i" % (A, S, B) def b(value, addr): LI, AA, LK = decodeI(value) LI = extend_sign(LI, 24) * 4 if AA: dst = LI else: dst = addr + LI return "b%s%s" %("l" * LK, "a" * AA), ihex(dst) def bc(value, addr): BO, BI, BD, AA, LK = decodeB(value) LI = extend_sign(LK, 14) * 4 instr = "b" + decodeCond(BO, BI) if LK: instr += "l" if AA: instr += "a" dst = LI else: dst = addr + LI return instr, ihex(dst) def bcctr(BO, BI, pad, LK): if pad: return "" instr = "b" + decodeCond(BO, BI) + "ctr" if LK: instr += "l" return instr def bclr(BO, BI, pad, LK): if pad: return "" instr = "b" + decodeCond(BO, BI) + "lr" if LK: instr += "l" return instr def cmp(cr, A, B, pad): if pad: return "" if cr & 3: return "" return "cmp", "cr%i, r%i, r%i" %(cr >> 2, A, B) def cmpi(value, addr): cr, A, SIMM = decodeD(value) SIMM = extend_sign(SIMM) if cr & 3: return "" return "cmpwi", "cr%i, r%i, %s" %(cr >> 2, A, ihex(SIMM)) def cmpl(cr, A, B, pad): if pad: return "" if cr & 3: return "" return "cmplw", "cr%i, r%i, r%i" %(cr >> 2, A, B) def cmpli(value, addr): cr, A, UIMM = decodeD(value) if cr & 3: return "" return "cmplwi", "cr%i, r%i, %s" %(cr >> 2, A, ihex(UIMM)) def cntlzw(S, A, pad, Rc): if pad: return "" return "cntlzw%s" %("." * Rc), "r%i, r%i" %(A, S) def dcbst(pad1, A, B, pad2): if pad1 or pad2: return "" return "dcbst", "r%i, r%i" %(A, B) def fmr(D, pad, B, Rc): if pad: return "" return "fmr%s" %("." * Rc), "f%i, f%i" %(D, B) def fneg(D, pad, B, Rc): if pad: return "" return "fneg%s" %("." * Rc), "f%i, f%i" %(D, B) def mfspr(D, sprLo, sprHi, pad): if pad: return "" sprnum = (sprHi << 5) | sprLo if sprnum not in spr_table: spr = "?" else: spr = spr_table[sprnum] return "mf%s" %spr, "r%i" %D def mtspr(S, sprLo, sprHi, pad): if pad: return "" sprnum = (sprHi << 5) | sprLo if sprnum not in spr_table: spr = ihex(sprnum) else: spr = spr_table[sprnum] return "mt%s" %spr, "r%i" %S def lbz(value, addr): return "lbz", loadStore(value) def lfd(value, addr): return "lfd", loadStore(value, "f") def lfs(value, addr): return "lfs", loadStore(value, "f") def lmw(value, addr): return "lmw", loadStore(value) def lwz(value, addr): return "lwz", loadStore(value) def lwzu(value, addr): return "lwzu", loadStore(value) def lwarx(D, A, B, pad): return "lwarx", loadStoreX(D, A, B, pad) def lwzx(D, A, B, pad): return "lwzx", loadStoreX(D, A, B, pad) def or_(S, A, B, Rc): if S == B: return "mr%s" %("." * Rc), "r%i, r%i" %(A, S) return "or%s" %("." * Rc), "r%i, r%i, r%i" %(A, S, B) def ori(value, addr): S, A, UIMM = decodeD(value) if UIMM == 0: return "nop" return "ori", "r%s, r%s, %s" %(A, S, ihex(UIMM)) def oris(value, addr): S, A, UIMM = decodeD(value) return "oris", "r%s, r%s, %s" %(A, S, ihex(UIMM)) def rlwinm(value, addr): S, A, SH, M, Rc = decodeX(value) MB = M >> 5 ME = M & 0x1F dot = "." * Rc if SH == 0 and MB == 0 and ME == 31: return "nop" if MB == 0 and ME == 31 - SH: return "slwi%s" %dot, "r%i, r%i, %i" %(A, S, SH) if ME == 31 and SH == 32 - MB: return "srwi%s" %dot, "r%i, r%i, %i" %(A, S, MB) if MB == 0 and ME < 31: return "extlwi%s" %dot, "r%i, r%i, %i,%i" %(A, S, ME + 1, SH) #extrwi if MB == 0 and ME == 31: if SH >= 16: return "rotlwi%s" %dot, "r%i, r%i, %i" %(A, S, SH) return "rotrwi%s" %dot, "r%i, r%i, %i" %(A, S, 32 - SH) if SH == 0 and ME == 31: return "clrlwi%s" %dot, "r%i, r%i, %i" %(A, S, MB) if SH == 0 and MB == 0: return "clrrwi%s" %dot, "r%i, r%i, %i" %(A, S, 31 - ME) #clrlslwi return "rlwinm%s" %dot, "r%i, r%i, r%i,r%i,r%i" %(A, S, SH, MB, ME) def sc(value, addr): if value & 0x3FFFFFF != 2: return "" return "sc" def stb(value, addr): return "stb", loadStore(value) def stfd(value, addr): return "stfd", loadStore(value, "f") def stfs(value, addr): return "stfs", loadStore(value, "f") def stfsu(value, addr): return "stfsu", loadStore(value, "f") def stmw(value, addr): return "stmw", loadStore(value) def stw(value, addr): return "stw", loadStore(value) def stwu(value, addr): return "stwu", loadStore(value) def stbx(S, A, B, pad): return "stbx", loadStoreX(S, A, B, pad) def stwx(S, A, B, pad): return "stwx", loadStoreX(S, A, B, pad) def stwcx(S, A, B, pad): return "stwcx", loadStoreX(S, A, B, pad ^ 1) def tw(TO, A, B, pad): if pad: return "" if TO == 31 and A == 0 and B == 0: return "trap" if TO not in trap_condition_table: condition = "?" else: condition = trap_condition_table[TO] return "tw%s" %condition, "r%i, r%i" %(A, B) opcode_table_ext1 = { 16: bclr, 528: bcctr } opcode_table_ext2 = { 0: cmp, 4: tw, 20: lwarx, 23: lwzx, 26: cntlzw, 28: and_, 32: cmpl, 54: dcbst, 150: stwcx, 151: stwx, 215: stbx, 266: add, 339: mfspr, 444: or_, 467: mtspr } opcode_table_float_ext1 = { 40: fneg, 72: fmr } def ext1(value, addr): DS, A, B, XO, Rc = decodeX(value) if not XO in opcode_table_ext1: return "ext1 - %s" %bin(XO) return opcode_table_ext1[XO](DS, A, B, Rc) def ext2(value, addr): DS, A, B, XO, Rc = decodeX(value) if not XO in opcode_table_ext2: return "ext2 - %s" %bin(XO) return opcode_table_ext2[XO](DS, A, B, Rc) def float_ext1(value, addr): D, A, B, XO, Rc = decodeX(value) if not XO in opcode_table_float_ext1: return "float_ext1 - %s" %bin(XO) return opcode_table_float_ext1[XO](D, A, B, Rc) opcode_table = { 10: cmpli, 11: cmpi, 12: addic, 13: addic_, 14: addi, 15: addis, 16: bc, 17: sc, 18: b, 19: ext1, 21: rlwinm, 24: ori, 25: oris, 31: ext2, 32: lwz, 33: lwzu, 34: lbz, 36: stw, 37: stwu, 38: stb, 46: lmw, 47: stmw, 48: lfs, 50: lfd, 52: stfs, 53: stfsu, 54: stfd, 63: float_ext1 } def disassemble(value, address): opcode = value >> 26 if opcode not in opcode_table: return "???" instr = opcode_table[opcode](value, address) if type(instr) == str: return instr return instr[0] + " " * (10 - len(instr[0])) + instr[1]