diff options
Diffstat (limited to 'miasm/arch/ppc')
| -rw-r--r-- | miasm/arch/ppc/__init__.py | 1 | ||||
| -rw-r--r-- | miasm/arch/ppc/arch.py | 826 | ||||
| -rw-r--r-- | miasm/arch/ppc/disasm.py | 7 | ||||
| -rw-r--r-- | miasm/arch/ppc/jit.py | 70 | ||||
| -rw-r--r-- | miasm/arch/ppc/lifter_model_call.py | 87 | ||||
| -rw-r--r-- | miasm/arch/ppc/regs.py | 77 | ||||
| -rw-r--r-- | miasm/arch/ppc/sem.py | 981 |
7 files changed, 0 insertions, 2049 deletions
diff --git a/miasm/arch/ppc/__init__.py b/miasm/arch/ppc/__init__.py deleted file mode 100644 index bbad893b..00000000 --- a/miasm/arch/ppc/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["arch", "disasm", "regs", "sem"] diff --git a/miasm/arch/ppc/arch.py b/miasm/arch/ppc/arch.py deleted file mode 100644 index a1bde2a6..00000000 --- a/miasm/arch/ppc/arch.py +++ /dev/null @@ -1,826 +0,0 @@ -from builtins import range - -import logging -from pyparsing import * -from miasm.expression.expression import * -from miasm.core.cpu import * -from collections import defaultdict -from miasm.core.bin_stream import bin_stream -import miasm.arch.ppc.regs as regs_module -from miasm.arch.ppc.regs import * -from miasm.core.asm_ast import AstInt, AstId, AstMem, AstOp -from miasm.ir.ir import color_expr_html - -log = logging.getLogger("ppcdis") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.DEBUG) - -LPARENTHESIS = Suppress(Literal("(")) -RPARENTHESIS = Suppress(Literal(")")) - -def cb_deref_imm_reg(tokens): - if len(tokens) == 1: - return AstMem(tokens[0], 32) - elif len(tokens) == 2: - return AstMem(tokens[1] + tokens[0], 32) - else: - raise NotImplementedError('len(tokens) > 2') - - -deref_reg_disp = (Optional(base_expr) + LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(cb_deref_imm_reg) -deref_reg = (LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(cb_deref_imm_reg) - -deref = deref_reg | deref_reg_disp - - -class ppc_arg(m_arg): - def asm_ast_to_expr(self, arg, loc_db): - if isinstance(arg, AstId): - if isinstance(arg.name, ExprId): - return arg.name - if arg.name in gpregs.str: - return None - loc_key = loc_db.get_or_create_name_location(arg.name) - return ExprLoc(loc_key, 32) - if isinstance(arg, AstOp): - args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] - if None in args: - return None - return ExprOp(arg.op, *args) - if isinstance(arg, AstInt): - return ExprInt(arg.value, 32) - if isinstance(arg, AstMem): - ptr = self.asm_ast_to_expr(arg.ptr, loc_db) - if ptr is None: - return None - return ExprMem(ptr, arg.size) - return None - - -class additional_info(object): - - def __init__(self): - self.except_on_instr = False - self.bo_bi_are_defined = False - self.bi = 0 - self.bo = 0 - - -class instruction_ppc(instruction): - - def __init__(self, *args, **kargs): - super(instruction_ppc, self).__init__(*args, **kargs) - - @staticmethod - def arg2str(e, pos = None, loc_db=None): - if isinstance(e, ExprId) or isinstance(e, ExprInt): - return str(e) - elif isinstance(e, ExprMem): - addr = e.ptr - if isinstance(addr, ExprInt) or isinstance(addr, ExprId): - out = '(%s)'%addr - elif isinstance(addr, ExprOp): - if len(addr.args) == 1: - out = '(%s)'%addr - elif len(addr.args) == 2: - out = '%s(%s)'%(addr.args[1], addr.args[0]) - else: - raise NotImplementedError('More than two args to ExprOp of address') - else: - raise NotImplementedError('Invalid memory expression') - return out - - return str(e) - - - @staticmethod - def arg2html(e, pos = None, loc_db=None): - if isinstance(e, ExprId) or isinstance(e, ExprInt) or isinstance(e, ExprLoc): - return color_expr_html(e, loc_db) - elif isinstance(e, ExprMem): - addr = e.ptr - if isinstance(addr, ExprInt) or isinstance(addr, ExprId): - out = '(%s)'%color_expr_html(addr, loc_db) - elif isinstance(addr, ExprOp): - if len(addr.args) == 1: - out = '(%s)'%color_expr_html(addr, loc_db) - elif len(addr.args) == 2: - out = '%s(%s)'%(color_expr_html(addr.args[1], loc_db), color_expr_html(addr.args[0], loc_db)) - else: - raise NotImplementedError('More than two args to ExprOp of address') - else: - raise NotImplementedError('Invalid memory expression') - return out - - return color_expr_html(e, loc_db) - - @staticmethod - def is_conditional_jump(s): - return (s[0] == 'B' and - s[1:3] in { 'DN', 'DZ', 'LT', 'GT', 'EQ', 'SO', - 'GE', 'LE', 'NE', 'NS' }) - - def dstflow(self): - name = self.name - if name[-1] == '+' or name[-1] == '-': - name = name[:-1] - return (name[0] == 'B' and - name[-2:] != 'LR' and - name[-3:] != 'LRL' and - name[-3:] != 'CTR' and - name[-4:] != 'CTRL') - - def dstflow2label(self, loc_db): - name = self.name - if name[-1] == '+' or name[-1] == '-': - name = name[:-1] - - if name[-1] == 'L': - name = name[:-1] - elif name[-2:] == 'LA': - name = name[:-2] + 'A' - - if name[-2:] != 'LR' and name[-3:] != 'CTR': - if len(self.args) == 2: - address_index = 1 - else: - address_index = 0 - e = self.args[address_index] - if not isinstance(e, ExprInt): - return - if name[-1] != 'A': - ad = (int(e) + self.offset) & 0xFFFFFFFF - else: - ad = int(e) - loc_key = loc_db.get_or_create_offset_location(ad) - s = ExprLoc(loc_key, e.size) - self.args[address_index] = s - - def breakflow(self): - return self.name[0] == 'B' - - def is_subcall(self): - name = self.name - if name[-1] == '+' or name[-1] == '-': - name = name[0:-1] - return name[0] == 'B' and (name[-1] == 'L' or name[-2:-1] == 'LA') - - def getdstflow(self, loc_db): - if 'LR' in self.name: - return [ LR ] - elif 'CTR' in self.name: - return [ CTR ] - elif len(self.args) == 2: - address_index = 1 - else: - address_index = 0 - return [ self.args[address_index] ] - - def splitflow(self): - ret = False - if self.is_conditional_jump(self.name): - if self.additional_info.bo & 0b10100 != 0b10100: - ret = True - ret = ret or self.is_subcall() - return ret - - def get_symbol_size(self, symbol, loc_db): - return 32 - - def fixDstOffset(self): - e = self.args[0] - if not isinstance(e, ExprInt): - log.debug('Dynamic destination offset %r' % e) - return - if self.name[-1] != 'A': - if self.offset is None: - raise ValueError('symbol not resolved %s' % self.l) - off = (int(e) + 0x100000000 - (self.offset + self.l)) & 0xFFFFFFFF - if int(off % 4): - raise ValueError('Offset %r must be a multiple of four' % off) - else: - off = int(e) - self.args[0] = ExprInt(off, 32) - - def get_args_expr(self): - args = [a for a in self.args] - return args - - def get_asm_offset(self, x): - return ExprInt_from(x, self.offset) - - -class mn_ppc(cls_mn): - delayslot = 0 - name = "ppc32" - regs = regs_module - bintree = {} - num = 0 - all_mn = [] - all_mn_mode = defaultdict(list) - all_mn_name = defaultdict(list) - all_mn_inst = defaultdict(list) - instruction = instruction_ppc - max_instruction_len = 4 - - @classmethod - def getpc(cls, attrib = None): - return PC - - @classmethod - def getsp(cls, attrib = None): - return R1 - - def additional_info(self): - info = additional_info() - info.bo_bi_are_defined = False - if hasattr(self, "bo"): - info.bo_bi_are_defined = True - info.bi = int(self.bi.strbits, 2) - info.bo = int(self.bo.strbits, 2) - return info - - @classmethod - def getbits(cls, bs, attrib, start, n): - if not n: - return 0 - o = 0 - if n > bs.getlen() * 8: - raise ValueError('not enough bits %r %r' % (n, len(bs.bin) * 8)) - while n: - offset = start // 8 - n_offset = cls.endian_offset(attrib, offset) - c = cls.getbytes(bs, n_offset, 1) - if not c: - raise IOError - c = ord(c) - r = 8 - start % 8 - c &= (1 << r) - 1 - l = min(r, n) - c >>= (r - l) - o <<= l - o |= c - n -= l - start += l - return o - - @classmethod - def endian_offset(cls, attrib, offset): - if attrib == "b": - return offset - else: - raise NotImplementedError("bad attrib") - - @classmethod - def check_mnemo(cls, fields): - l = sum([x.l for x in fields]) - assert l == 32, "len %r" % l - - @classmethod - def getmn(cls, name): - return name.upper() - - @classmethod - def mod_fields(cls, fields): - l = sum([x.l for x in fields]) - return fields - - @classmethod - def gen_modes(cls, subcls, name, bases, dct, fields): - dct['mode'] = None - return [(subcls, name, bases, dct, fields)] - - def post_dis(self): - return self - - def value(self, mode): - v = super(mn_ppc, self).value(mode) - if mode == 'b': - return [x for x in v] - else: - raise NotImplementedError("bad attrib") - - def get_symbol_size(self, symbol, loc_db, mode): - return 32 - - -class ppc_reg(reg_noarg, ppc_arg): - pass - - -class ppc_gpreg_noarg(reg_noarg): - reg_info = gpregs - parser = reg_info.parser - -class ppc_gpreg_or_0_noarg(reg_noarg): - reg_info = gpregs - parser = reg_info.parser - - def decode(self, v): - ret = super(ppc_gpreg_or_0_noarg, self).decode(v) - if ret == False: - return False - reg = self.expr - if reg == R0: - self.expr = ExprInt(0, 32) - return ret - -class ppc_gpreg(ppc_reg): - reg_info = gpregs - parser = reg_info.parser - -class ppc_gpreg_or_0(ppc_reg): - reg_info = gpregs - parser = reg_info.parser - - def decode(self, v): - ret = super(ppc_gpreg_or_0, self).decode(v) - if ret == False: - return False - reg = self.expr - if reg == R0: - self.expr = ExprInt(0, 32) - return ret - -class ppc_crfreg_noarg(reg_noarg): - reg_info = crfregs - parser = reg_info.parser - -class ppc_crfreg(ppc_reg): - reg_info = crfregs - parser = reg_info.parser - -class ppc_imm(imm_noarg, ppc_arg): - parser = base_expr - -class ppc_s14imm_branch(ppc_imm): - - def decode(self, v): - v = sign_ext(v << 2, 16, 32) - self.expr = ExprInt(v, 32) - return True - - def encode(self): - if not isinstance(self.expr, ExprInt): - return False - v = int(self.expr) - if v & 0x3: - return False - v = v >> 2 - if sign_ext(v & self.lmask, 14, 32) != v: - return False - self.value = v & self.lmask - return True - -class ppc_s24imm_branch(ppc_imm): - - def decode(self, v): - v = sign_ext(v << 2, 26, 32) - self.expr = ExprInt(v, 32) - return True - - def encode(self): - if not isinstance(self.expr, ExprInt): - return False - v = int(self.expr) - if v & 0x3: - return False - v = v >> 2 - if sign_ext(v & self.lmask, 24, 32) != v: - return False - self.value = v & self.lmask - return True - -class ppc_s16imm(ppc_imm): - - def decode(self, v): - v = sign_ext(v, 16, 32) - self.expr = ExprInt(v, 32) - return True - - def encode(self): - if not isinstance(self.expr, ExprInt): - return False - v = int(self.expr) - if sign_ext(v & self.lmask, 16, 32) != v: - return False - self.value = v & self.lmask - return True - -class ppc_u16imm(ppc_imm): - - def decode(self, v): - if v & self.lmask != v: - return False - self.expr = ExprInt(v, 32) - return True - - def encode(self): - if not isinstance(self.expr, ExprInt): - return False - v = int(self.expr) - if v & self.lmask != v: - return False - self.value = v & self.lmask - return True - -def ppc_swap_10(v): - return ((v & 0b11111) << 5) | ((v & 0b1111100000) >> 5) - -class ppc_spr(ppc_imm): - - def decode(self, v): - self.expr = ExprInt(ppc_swap_10(v), 32) - return True - - def encode(self, e): - if not isinstance(e, ExprInt): - return False - self.value = ppc_swap_10(int(e)) - return True - -class ppc_tbr(ppc_imm): - - def decode(self, v): - self.expr = ExprInt(ppc_swap_10(v), 32) - return True - - def encode(self, e): - if not isinstance(e, ExprInt): - return False - self.value = ppc_swap_10(int(e)) - return True - -class ppc_u08imm(ppc_u16imm): - pass - -class ppc_u05imm(ppc_u16imm): - pass - -class ppc_u04imm(ppc_u16imm): - pass - -class ppc_u02imm_noarg(imm_noarg): - pass - -class ppc_float(ppc_reg): - reg_info = floatregs - parser = reg_info.parser - -class ppc_vex(ppc_reg): - reg_info = vexregs - parser = reg_info.parser - -def ppc_bo_bi_to_mnemo(bo, bi, prefer_taken=True, default_taken=True): - bo2mnemo = { 0: 'DNZF', 2: 'DZF', 4: 'F', 8: 'DNZT', - 10: 'DZT', 12: 'T', 16: 'DNZ', 18: 'DZ', - 20: '' } - bi2cond = { 0b00: 'LT', 0b01: 'GT', 0b10: 'EQ', 0b11: 'SO' } - bi2ncond = { 0b00: 'GE', 0b01: 'LE', 0b10: 'NE', 0b11: 'NS' } - n = bo & 0b11110 - if not n in bo2mnemo: - raise NotImplementedError("Unknown BO field") - mnem = 'B' + bo2mnemo[n] - if mnem[-1] == 'T': - mnem = mnem[:-1] + bi2cond[bi & 0b11] - if mnem[-1] == 'F': - mnem = mnem[:-1] + bi2ncond[bi & 0b11] - - if prefer_taken != default_taken: - if prefer_taken: - mnem += '+' - else: - mnem += '-' - - return mnem - -def ppc_all_bo_bi(): - for bo in [0, 2, 4, 8, 10, 12, 16, 18, 20]: - for bi in range(4): - yield bo, bi - -class ppc_divert_conditional_branch(bs_divert): - prio=3 - def divert(self, i, candidates): - out = [] - for cls, _, bases, dct, fields in candidates: - bi_i = getfieldindexby_name(fields, 'bi')[1] - bo_i = getfieldindexby_name(fields, 'bo')[1] - - for bo, bi in ppc_all_bo_bi(): - nfields = fields[:] - nfields[bi_i] = bs(int2bin(bi, 2), fname="bi") - nfields[bo_i] = bs(int2bin(bo, 5), fname="bo") - ndct = dict(dct) - ndct['name'] = ppc_bo_bi_to_mnemo(bo, bi) - out.append((cls, ndct['name'], bases, ndct, nfields)) - - nfields = fields[:] - nfields[bi_i] = bs(int2bin(bi, 2), fname="bi") - nfields[bo_i] = bs(int2bin(bo+1, 5), fname="bo") - ndct = dict(dct) - ndct['name'] = ppc_bo_bi_to_mnemo(bo, bi) - out.append((cls, ndct['name'], bases, ndct, nfields)) - - return out - -class ppc_deref32(ppc_arg): - parser = deref - - def decode(self, v): - v = sign_ext(v, 16, 32) - e = self.parent.ra.expr + ExprInt(v, 32) - self.expr = ExprMem(e, size=32) - return True - - def encode(self): - e = self.expr - if not isinstance(e, ExprMem): - return False - addr = e.ptr - if isinstance(addr, ExprId) or isinstance(addr, ExprInt): - addr = addr + ExprInt(0, 32) - elif not isinstance(addr, ExprOp): - return False - if addr.op != '+': - return False - if len(addr.args) != 2: - return False - reg, disp = addr.args[0], addr.args[1] - v = int(disp) - if sign_ext(v & 0xFFFF, 16, 32) != v: - return False - v &= 0xFFFF - self.value = v - self.parent.ra.expr = reg - return True - - -def ppcop(name, fields, args=None, alias=False): - dct = {"fields": fields} - dct["alias"] = alias - if args is not None: - dct['args'] = args - type(name, (mn_ppc,), dct) - -rd = bs(l=5, cls=(ppc_gpreg,)) -ra = bs(l=5, cls=(ppc_gpreg,)) -ra_or_0 = bs(l=5, cls=(ppc_gpreg_or_0,)) -rb = bs(l=5, cls=(ppc_gpreg,)) -rs = bs(l=5, cls=(ppc_gpreg,)) -crfd = bs(l=3, cls=(ppc_crfreg,)) -crfs = bs(l=3, cls=(ppc_crfreg,)) -sh = bs(l=5, cls=(ppc_u05imm,)) -mb = bs(l=5, cls=(ppc_u05imm,)) -me = bs(l=5, cls=(ppc_u05imm,)) -nb = bs(l=5, cls=(ppc_u05imm,)) -crm = bs(l=8, cls=(ppc_u08imm,)) -sr = bs(l=4, cls=(ppc_u04imm,)) -spr = bs(l=10, cls=(ppc_spr,)) -tbr = bs(l=10, cls=(ppc_tbr,)) -u05imm = bs(l=5, cls=(ppc_u05imm,)) - -s24imm_branch = bs(l=24, cls=(ppc_s24imm_branch,), fname="imm") -s14imm_branch = bs(l=14, cls=(ppc_s14imm_branch,), fname="imm") -s16imm = bs(l=16, cls=(ppc_s16imm,), fname="imm") -u16imm = bs(l=16, cls=(ppc_u16imm,), fname="imm") -u08imm = bs(l=5, cls=(ppc_u08imm,), fname="imm") -u02imm_noarg = bs(l=2, cls=(ppc_u02imm_noarg,), fname="imm") - -ra_noarg = bs(l=5, cls=(ppc_gpreg_noarg,), fname="ra") -ra_or_0_noarg = bs(l=5, cls=(ppc_gpreg_or_0_noarg,), fname="ra") -dregimm = bs(l=16, cls=(ppc_deref32,)) - -rc_mod = bs_mod_name(l=1, mn_mod=['', '.'], fname='rc') - -frd = bs(l=5, cls=(ppc_float,)) -frb = bs(l=5, cls=(ppc_float,)) -frs = bs(l=5, cls=(ppc_float,)) -fm = bs(l=8, cls=(ppc_u08imm,)) - -va = bs(l=5, cls=(ppc_vex,)) -vb = bs(l=5, cls=(ppc_vex,)) -vd = bs(l=5, cls=(ppc_vex,)) -rb_noarg = bs(l=5, cls=(ppc_gpreg_noarg,), fname="rb") - -arith1_name = {"MULLI": 0b000111, "SUBFIC": 0b001000, "ADDIC": 0b001100, - "ADDIC.": 0b001101 } - -logic2_name = {"ORI": 0b011000, "XORI": 0b011010, "ANDI.": 0b011100 } -slogic2_name = {"ORIS": 0b011001, "XORIS": 0b011011, "ANDIS.": 0b011101 } - -arith3_name = {"SUBFC": 0b0000001000, "ADDC": 0b0000001010, - "MULHWU": 0b0000001011, "SUBF": 0b0000101000, - "MULHW": 0b0001001011, "SUBFE": 0b0010001000, - "ADDE": 0b0010001010, "MULLW": 0b0011101011, - "ADD": 0b0100001010, "DIVWU": 0b0111001011, - "DIVW": 0b0111101011, "SUBFCO": 0b1000001000, - "ADDCO": 0b1000001010, "SUBFO": 0b1000101000, - "SUBFEO": 0b1010001000, "ADDEO": 0b1010001010, - "MULLWO": 0b1011101011, "ADDO": 0b1100001010, - "DIVWUO": 0b1111001011, "DIVWO": 0b1111101011 } - -xor_name = { "EQV": 0b0100011100, "XOR": 0b0100111100 } - -arith4_name = {"NEG": 0b0001101000, "SUBFZE": 0b0011001000, - "ADDZE": 0b0011001010, "SUBFME": 0b0011101000, - "ADDME": 0b0011101010, "NEGO": 0b1001101000, - "SUBFZEO": 0b1011001000, "ADDZEO": 0b1011001010, - "SUBFMEO": 0b1011101000, "ADDMEO": 0b1011101010 } - -arith5_name = {"CNTLZW": 0b00000, "EXTSH": 0b11100, "EXTSB": 0b11101 } - -crlogic_name = {"CRAND": 0b1000, "CRANDC": 0b0100, "CREQV": 0b1001, - "CRNAND": 0b0111, "CRNOR": 0b0001, "CROR": 0b1110, - "CRORC": 0b1101, "CRXOR": 0b0110 } - -rotins_name = {"RLWIMI": 0b010100, "RLWINM": 0b010101 } - -bs_arith1_name = bs_name(l=6, name=arith1_name) - -load1_name = {"LWARX": 0b0000010100, "LWZX": 0b0000010111, - "LBZX": 0b0001010111, "LHZX": 0b0100010111, - "ECIWX": 0b0100110110, "LHAX": 0b0101010111, - "LSWX": 0b1000010101, "LWBRX": 0b1000010110, - "LHBRX": 0b1100010110 } - -load1_name_u = {"LWZUX": 0b0000110111, "LBZUX": 0b0001110111, - "LHZUX": 0b0100110111, "LHAUX": 0b0101110111 } - -load2_name = {"LWZ": 0b0000, "LBZ": 0b0010, "LHZ": 0b1000, "LHA": 0b1010, - "LMW": 0b1110 } - -load2_name_u = {"LWZU": 0b0001, "LBZU": 0b0011, "LHZU": 0b1001, "LHAU": 0b1011} - -store1_name = { "STWCX.": 0b00100101101, "STWX": 0b00100101110, - "STBX": 0b00110101110, "STHX": 0b01100101110, - "ECOWX": 0b01101101100, "STSWX": 0b10100101010, - "STWBRX": 0b10100101100, "STHBRX": 0b11100101100 } -store1_name_u = { "STWUX": 0b00101101110, "STBUX": 0b00111101110, - "STHUX": 0b01101101110 } - -store2_name = { "STW": 0b0100, "STB": 0b0110, "STH": 0b1100, "STMW": 0b1111 } -store2_name_u = { "STWU": 0b0101, "STBU": 0b0111, "STHU": 0b1101 } - -logic1_name = {"SLW": 0b0000011000, "AND": 0b0000011100, - "ANDC": 0b0000111100, "NOR": 0b0001111100, - "ORC": 0b0110011100, "OR": 0b0110111100, - "NAND": 0b0111011100, "SRW": 0b1000011000, - "SRAW": 0b1100011000 } - -dcb_name = {"DCBST": 0b00001, "DCBF": 0b00010, - "DCBTST": 0b00111, "DCBT": 0b01000, - "DCBI": 0b01110, "DCBA": 0b10111, - "ICBI": 0b11110, "DCBZ": 0b11111 } - - -load1_name_float = {"LFS": 0b110000, "LFD": 0b110010 } -load1_name_float_u = {"LFSU": 0b110001, "LFDU": 0b110011 } -store1_name_float = {"STFS": 0b110100, "STFD": 0b110110 } -store1_name_float_u = {"STFSU": 0b110101, "STFDU": 0b110111 } - -load1_name_vex = {"LVEBX": 0b0000000111, "LVEHX": 0b0000100111, - "LVEWX": 0b0001000111, "LVSL": 0b0000000110, - "LVSR": 0b0000100110, "LVX": 0b0001100111, - "LVXL": 0b0101100111 } - -class bs_mod_name_prio4(bs_mod_name): - prio = 4 - -class bs_mod_name_prio5(bs_mod_name): - prio = 5 - -class bs_mod_name_prio6(bs_mod_name): - prio = 6 - -branch_to_reg = bs_mod_name_prio4(l=1, mn_mod=['LR', 'CTR'], fname='btoreg') -branch_lk = bs_mod_name_prio5(l=1, mn_mod=['', 'L'], fname='lk') -branch_aa = bs_mod_name_prio6(l=1, mn_mod=['', 'A'], fname='aa') - -ppcop("arith1", [bs_arith1_name, rd, ra, s16imm]) -ppcop("ADDIS", [bs('001111'), rd, ra_or_0, u16imm]) -ppcop("ADDI", [bs('001110'), rd, ra_or_0, s16imm]) - -ppcop("logic2", [bs_name(l=6, name=logic2_name), rs, ra, u16imm], - [ra, rs, u16imm]) -ppcop("slogic2", [bs_name(l=6, name=slogic2_name), rs, ra, u16imm], - [ra, rs, u16imm]) - -ppcop("store1", [bs('011111'), rs, ra_or_0, rb, - bs_name(l=11, name=store1_name)]) -ppcop("store1u", [bs('011111'), rs, ra, rb, - bs_name(l=11, name=store1_name_u)]) - -ppcop("store2", [bs('10'), bs_name(l=4, name=store2_name), rs, - ra_noarg, dregimm]) -ppcop("store2u", [bs('10'), bs_name(l=4, name=store2_name_u), rs, - ra_or_0_noarg, dregimm]) - -ppcop("arith3", [bs('011111'), rd, ra, rb, bs_name(l=10, name=arith3_name), - rc_mod]) - -ppcop("xor", [bs('011111'), rs, ra, rb, bs_name(l=10, name=xor_name), - rc_mod], [ra, rs, rb]) - -ppcop("arith4", [bs('011111'), rd, ra, bs('00000'), - bs_name(l=10, name=arith4_name), rc_mod]) - -ppcop("arith5", [bs('011111'), rs, ra, bs('00000'), - bs_name(l=5, name=arith5_name), - bs('11010'), rc_mod], [ra, rs]) - -ppcop("load1", [bs('011111'), rd, ra_or_0, rb, - bs_name(l=10, name=load1_name), bs('0')]) -ppcop("load1u", [bs('011111'), rd, ra, rb, - bs_name(l=10, name=load1_name_u), bs('0')]) -ppcop("load2", [bs('10'), bs_name(l=4, name=load2_name), - rd, ra_or_0_noarg, dregimm]) -ppcop("load2u", [bs('10'), bs_name(l=4, name=load2_name_u), - rd, ra_noarg, dregimm]) - -ppcop("logic1", [bs('011111'), rs, ra, rb, bs_name(l=10, name=logic1_name), - rc_mod], - [ra, rs, rb]) - -ppcop("TWI", [bs('000011'), u05imm, ra, s16imm]) -ppcop("TW", [bs('011111'), u05imm, ra, rb, bs('00000001000')]) - -ppcop("CMPW", [bs('011111'), crfd, bs('00'), ra, rb, bs('00000000000')]) -ppcop("CMPLW", [bs('011111'), crfd, bs('00'), ra, rb, bs('00001000000')]) -ppcop("CMPLWI", [bs('001010'), crfd, bs('00'), ra, u16imm]) -ppcop("CMPWI", [bs('001011'), crfd, bs('00'), ra, s16imm]) - -ppcop("BC", [bs('010000'), bs(l=5, cls=(ppc_u05imm,), fname='bo'), - crfs, - ppc_divert_conditional_branch(l=2, fname='bi'), - s14imm_branch, branch_aa, branch_lk]) -ppcop("SC", [bs('01000100000000000000000000000010')]) -ppcop("B", [bs('010010'), s24imm_branch, branch_aa, branch_lk]) -ppcop("MCRF", [bs('010011'), crfd, bs('00'), crfs, bs('000000000000000000')]) - -ppcop("BCXXX", [bs('010011'), bs(l=5, cls=(ppc_u05imm,), fname='bo'), - crfs, - ppc_divert_conditional_branch(l=2, fname='bi'), - bs('00000'), branch_to_reg, - bs('000010000'), branch_lk]) - -ppcop("crlogic", [bs('010011'), - bs(l=5, cls=(ppc_u05imm,), fname='crbd'), - bs(l=5, cls=(ppc_u05imm,), fname='crba'), - bs(l=5, cls=(ppc_u05imm,), fname='crbb'), - bs('0'), - bs_name(l=4, name=crlogic_name), - bs('000010')]) - -ppcop("rotins", [bs_name(l=6, name=rotins_name), - rs, ra, sh, mb, me, rc_mod], - [ ra, rs, sh, mb, me ]) -ppcop("RLWNM", [bs('010111'), rs, ra, rb, mb, me, rc_mod], - [ ra, rs, rb, mb, me ]) -ppcop("MFXXX", [bs('011111'), rd, bs('0000000000'), - bs('000'), - bs_name(l=1, name={'MFCR':0, 'MFMSR':1}), - bs('0100110')]) - -ppcop("dcb", [bs('01111100000'), ra, rb, bs_name(l=5, name=dcb_name), - bs('101100')]) - -ppcop("MTCRF", [bs('011111'), rs, bs('0'), crm, bs('000100100000')], [crm, rs]) -ppcop("MTMSR", [bs('011111'), rs, bs('0000000000'), bs('00100100100')]) -ppcop("MTSR", [bs('011111'), rs, bs('0'), sr, bs('0000000110100100')], [sr, rs]) -ppcop("MTSRIN", [bs('011111'), rs, bs('00000'), rb, bs('00111100100')]) - -ppcop("TLBIE", [bs('011111'), bs('0000000000'), rb, bs('01001100100')]) -ppcop("MFSPR", [bs('011111'), rd, spr, bs('01010100110')]) -ppcop("TLBIA", [bs('01111100000000000000001011100100')]) -ppcop("MFTB", [bs('011111'), rd, tbr, bs('01011100110')]) -ppcop("RFI", [bs('01001100000000000000000001100100')]) -ppcop("ISYNC", [bs('01001100000000000000000100101100')]) -ppcop("MTSPR", [bs('011111'), rs, spr, bs('01110100110')], [spr, rs]) -ppcop("MCRXR", [bs('011111'), crfd, bs('000000000000'), - bs('10000000000')]) -ppcop("TLBSYNC", [bs('01111100000000000000010001101100')]) -ppcop("MFSR", [bs('011111'), rd, bs('0'), sr, bs('00000'), bs('10010100110')]) -ppcop("LSWI", [bs('011111'), rd, ra, nb, bs('10010101010')]) -ppcop("STSWI", [bs('011111'), rs, ra, nb, bs('10110101010')]) -ppcop("SYNC", [bs('011111'), bs('000000000000000'), bs('10010101100')]) -ppcop("MFSRIN", [bs('011111'), rd, bs('00000'), rb, bs('10100100110')]) - -ppcop("SRAWI", [bs('011111'), rs, ra, sh, bs('1100111000'), rc_mod], - [ra, rs, sh]) - -ppcop("EIEIO", [bs('011111'), bs('000000000000000'), bs('11010101100')]) - -ppcop("load1f", [bs_name(l=6, name=load1_name_float), frd, ra_noarg, dregimm]) -ppcop("load1fu", [bs_name(l=6, name=load1_name_float_u), frd, ra_noarg, dregimm]) -ppcop("store1f", [bs_name(l=6, name=store1_name_float), frd, ra_noarg, dregimm]) -ppcop("store1fu", [bs_name(l=6, name=store1_name_float_u), frd, ra_noarg, dregimm]) -ppcop("MTFSF", [bs('111111'), bs('0'), fm, bs('0'), frb, bs('10110001110')]) -ppcop("MTFSF.", [bs('111111'), bs('0'), fm, bs('0'), frb, bs('10110001111')]) -ppcop("MFFS", [bs('111111'), frd, bs('00000000001001000111'), bs('0')]) -ppcop("MFFS.", [bs('111111'), frd, bs('00000000001001000111'), bs('1')]) - -ppcop("load1vex", [bs('011111'), vd, ra, rb, bs_name(l=10, name=load1_name_vex), bs('0')]) -ppcop("mtvscr", [bs('0001000000000000'), vb, bs('11001000100')]) diff --git a/miasm/arch/ppc/disasm.py b/miasm/arch/ppc/disasm.py deleted file mode 100644 index b91d96bf..00000000 --- a/miasm/arch/ppc/disasm.py +++ /dev/null @@ -1,7 +0,0 @@ -from miasm.arch.ppc.arch import mn_ppc -from miasm.core.asmblock import disasmEngine - -class dis_ppc32b(disasmEngine): - def __init__(self, bs=None, **kwargs): - super(dis_ppc32b, self).__init__(mn_ppc, None, bs, **kwargs) - self.attrib = 'b' diff --git a/miasm/arch/ppc/jit.py b/miasm/arch/ppc/jit.py deleted file mode 100644 index dcaff82c..00000000 --- a/miasm/arch/ppc/jit.py +++ /dev/null @@ -1,70 +0,0 @@ -from builtins import range -from miasm.jitter.jitload import Jitter, named_arguments -from miasm.arch.ppc.sem import Lifter_PPC32b -import struct - -import logging - -log = logging.getLogger('jit_ppc') -hnd = logging.StreamHandler() -hnd.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(hnd) -log.setLevel(logging.CRITICAL) - -class jitter_ppc32b(Jitter): - max_reg_arg = 8 - - def __init__(self, loc_db, *args, **kwargs): - super(jitter_ppc32b, self).__init__(Lifter_PPC32b(loc_db), - *args, **kwargs) - self.vm.set_big_endian() - - def push_uint32_t(self, v): - self.cpu.R1 -= 4 - self.vm.set_mem(self.cpu.R1, struct.pack(">I", v)) - - def pop_uint32_t(self): - x = struct.unpack(">I", self.vm.get_mem(self.cpu.R1, 4))[0] - self.cpu.R1 += 4 - return x - - def get_stack_arg(self, n): - x = struct.unpack(">I", self.vm.get_mem(self.cpu.R1 + 8 + 4 * n, 4))[0] - return x - - @named_arguments - def func_args_systemv(self, n_args): - args = [self.get_arg_n_systemv(i) for i in range(n_args)] - ret_ad = self.cpu.LR - return ret_ad, args - - def func_ret_systemv(self, ret_addr, ret_value1=None, ret_value2=None): - self.pc = self.cpu.PC = ret_addr - if ret_value1 is not None: - self.cpu.R3 = ret_value1 - if ret_value2 is not None: - self.cpu.R4 = ret_value2 - return True - - def func_prepare_systemv(self, ret_addr, *args): - for index in range(min(len(args), self.max_reg_arg)): - setattr(self.cpu, 'R%d' % (index + 3), args[index]) - for index in range(len(args) - 1, self.max_reg_arg - 1, -1): - self.push_uint32_t(args[index]) - - # reserve room for LR save word and backchain - self.cpu.R1 -= 8 - - self.cpu.LR = ret_addr - - def get_arg_n_systemv(self, index): - if index < self.max_reg_arg: - arg = getattr(self.cpu, 'R%d' % (index + 3)) - else: - arg = self.get_stack_arg(index - self.max_reg_arg) - return arg - - - def init_run(self, *args, **kwargs): - Jitter.init_run(self, *args, **kwargs) - self.cpu.PC = self.pc diff --git a/miasm/arch/ppc/lifter_model_call.py b/miasm/arch/ppc/lifter_model_call.py deleted file mode 100644 index 06691190..00000000 --- a/miasm/arch/ppc/lifter_model_call.py +++ /dev/null @@ -1,87 +0,0 @@ -from miasm.expression.expression import ExprAssign, ExprOp -from miasm.ir.ir import AssignBlock -from miasm.ir.analysis import LifterModelCall -from miasm.arch.ppc.sem import Lifter_PPC32b - - -class LifterModelCallPpc32b(Lifter_PPC32b, LifterModelCall): - - def __init__(self, loc_db, *args): - super(LifterModelCallPpc32b, self).__init__(loc_db, *args) - self.ret_reg = self.arch.regs.R3 - - # for test XXX TODO - def set_dead_regs(self, irblock): - pass - - def get_out_regs(self, _): - return set([self.ret_reg, self.sp]) - - def add_unused_regs(self): - leaves = [self.blocks[label] for label in self.g.leafs()] - for irblock in leaves: - self.set_dead_regs(irblock) - - def call_effects(self, ad, instr): - call_assignblks = AssignBlock( - [ - ExprAssign( - self.ret_reg, - ExprOp( - 'call_func_ret', - ad, - self.sp, - self.arch.regs.R3, - self.arch.regs.R4, - self.arch.regs.R5, - ) - ), - ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)), - ], - instr - ) - return [call_assignblks], [] - - def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): - """ - Add the IR effects of an instruction to the current state. - - @instr: native instruction - @block: native block source - @assignments: list of current AssignBlocks - @ir_blocks_all: list of additional effects - @gen_pc_updt: insert PC update effects between instructions - """ - if instr.is_subcall(): - call_assignblks, extra_irblocks = self.call_effects( - instr.getdstflow(None)[0], - instr - ) - assignments += call_assignblks - ir_blocks_all += extra_irblocks - return True - - if gen_pc_updt is not False: - self.gen_pc_update(assignments, instr) - - assignblk, ir_blocks_extra = self.instr2ir(instr) - assignments.append(assignblk) - ir_blocks_all += ir_blocks_extra - if ir_blocks_extra: - return True - return False - - def sizeof_char(self): - return 8 - - def sizeof_short(self): - return 16 - - def sizeof_int(self): - return 32 - - def sizeof_long(self): - return 32 - - def sizeof_pointer(self): - return 32 diff --git a/miasm/arch/ppc/regs.py b/miasm/arch/ppc/regs.py deleted file mode 100644 index 00781d6a..00000000 --- a/miasm/arch/ppc/regs.py +++ /dev/null @@ -1,77 +0,0 @@ - -from builtins import range -from miasm.expression.expression import * -from miasm.core.cpu import gen_reg, gen_regs - -exception_flags = ExprId('exception_flags', 32) -spr_access = ExprId('spr_access', 32) - -reserve = ExprId('reserve', 1) -reserve_address = ExprId('reserve_address', 32) - -SPR_ACCESS_IS_WRITE = 0x80000000 -SPR_ACCESS_SPR_MASK = 0x000003FF -SPR_ACCESS_SPR_OFF = 0 -SPR_ACCESS_GPR_MASK = 0x0001F000 -SPR_ACCESS_GPR_OFF = 12 - -gpregs_str = ["R%d" % i for i in range(32)] -gpregs_expr, gpregs_init, gpregs = gen_regs(gpregs_str, globals(), 32) - -crfregs_str = ["CR%d" % i for i in range(8)] -crfregs_expr, crfregs_init, crfregs = gen_regs(crfregs_str, globals(), 4) - -crfbitregs_str = ["CR%d_%s" % (i, flag) for i in range(8) - for flag in ['LT', 'GT', 'EQ', 'SO'] ] -crfbitregs_expr, crfbitregs_init, crfbitregs = gen_regs(crfbitregs_str, - globals(), 1) - -xerbitregs_str = ["XER_%s" % field for field in ['SO', 'OV', 'CA'] ] -xerbitregs_expr, xerbitregs_init, xerbitregs = gen_regs(xerbitregs_str, - globals(), 1) - -xerbcreg_str = ["XER_BC"] -xerbcreg_expr, xerbcreg_init, xerbcreg = gen_regs(xerbcreg_str, - globals(), 7) - - -otherregs_str = ["PC", "CTR", "LR", "FPSCR", "VRSAVE", "VSCR" ] -otherregs_expr, otherregs_init, otherregs = gen_regs(otherregs_str, - globals(), 32) - -superregs_str = (["SPRG%d" % i for i in range(4)] + - ["SRR%d" % i for i in range(2)] + - ["DAR", "DSISR", "MSR", "PIR", "PVR", - "DEC", "TBL", "TBU"]) -superregs_expr, superregs_init, superregs = gen_regs(superregs_str, - globals(), 32) - -mmuregs_str = (["SR%d" % i for i in range(16)] + - ["IBAT%dU" % i for i in range(4)] + - ["IBAT%dL" % i for i in range(4)] + - ["DBAT%dU" % i for i in range(4)] + - ["DBAT%dL" % i for i in range(4)] + - ["SDR1"]) -mmuregs_expr, mmuregs_init, mmuregs = gen_regs(mmuregs_str, - globals(), 32) - -floatregs_str = (["FPR%d" % i for i in range(32)]) -floatregs_expr, floatregs_init, floatregs = gen_regs(floatregs_str, - globals(), 64) - -vexregs_str = (["VR%d" % i for i in range(32)]) -vexregs_expr, vexregs_init, vexregs = gen_regs(vexregs_str, - globals(), 128) - -regs_flt_expr = [] - -all_regs_ids = (gpregs_expr + crfbitregs_expr + xerbitregs_expr + - xerbcreg_expr + otherregs_expr + superregs_expr + mmuregs_expr + floatregs_expr + vexregs_expr + - [ exception_flags, spr_access, reserve, reserve_address ]) -all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids]) -all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids] -all_regs_ids_no_alias = all_regs_ids[:] - -regs_init = {} -for i, r in enumerate(all_regs_ids): - regs_init[r] = all_regs_ids_init[i] diff --git a/miasm/arch/ppc/sem.py b/miasm/arch/ppc/sem.py deleted file mode 100644 index 7fbf61e6..00000000 --- a/miasm/arch/ppc/sem.py +++ /dev/null @@ -1,981 +0,0 @@ -from __future__ import print_function -from builtins import range - -import miasm.expression.expression as expr -from miasm.ir.ir import AssignBlock, Lifter, IRBlock -from miasm.arch.ppc.arch import mn_ppc -from miasm.arch.ppc.regs import * -from miasm.core.sembuilder import SemBuilder -from miasm.jitter.csts import * - -spr_dict = { - 8: LR, 9: CTR, 18: DSISR, 19: DAR, - 22: DEC, 25: SDR1, 26: SRR0, 27: SRR1, - 272: SPRG0, 273: SPRG0, 274: SPRG1, 275: SPRG2, 276: SPRG3, - 284: TBL, 285: TBU, 287: PVR, - 528: IBAT0U, 529: IBAT0L, 530: IBAT1U, 531: IBAT1L, 532: IBAT2U, 533: IBAT2L, 534: IBAT3U, 535: IBAT3L, - 536: DBAT0U, 537: DBAT0L, 538: DBAT1U, 539: DBAT1L, 540: DBAT2U, 541: DBAT2L, 542: DBAT3U, 543: DBAT3L, - 1023: PIR -} - -sr_dict = { - 0: SR0, 1: SR1, 2: SR2, 3: SR3, - 4: SR4, 5: SR5, 6: SR6, 7: SR7, - 8: SR8, 9: SR9, 10: SR10, 11: SR11, - 12: SR12, 13: SR13, 14: SR14, 15: SR15 -} - -float_dict = { - 0: FPR0, 1: FPR1, 2: FPR2, 3: FPR3, 4: FPR4, 5: FPR5, 6: FPR6, 7: FPR7, 8: FPR8, - 9: FPR9, 10: FPR10, 11: FPR11, 12: FPR12, 13: FPR13, 14: FPR14, 15: FPR15, 16: FPR16, - 17: FPR17, 18: FPR18, 19: FPR19, 20: FPR20, 21: FPR21, 22: FPR22, 23: FPR23, 24: FPR24, - 25: FPR25, 26: FPR26, 27: FPR27, 28: FPR28, 29: FPR29, 30: FPR30, 31: FPR31 -} - -vex_dict = { - 0: VR0, 1: VR1, 2: VR2, 3: VR3, 4: VR4, 5: VR5, 6: VR6, 7: VR7, 8: VR8, - 9: VR9, 10: VR10, 11: VR11, 12: VR12, 13: VR13, 14: VR14, 15: VR15, 16: VR16, - 17: VR17, 18: VR18, 19: VR19, 20: VR20, 21: VR21, 22: VR22, 23: VR23, 24: VR24, - 25: VR25, 26: VR26, 27: VR27, 28: VR28, 29: VR29, 30: VR30, 31: VR31, -} - -crf_dict = dict((ExprId("CR%d" % i, 4), - dict( (bit, ExprId("CR%d_%s" % (i, bit), 1)) - for bit in ['LT', 'GT', 'EQ', 'SO' ] )) - for i in range(8) ) - -ctx = { - 'crf_dict': crf_dict, - 'spr_dict': spr_dict, - 'sr_dict': sr_dict, - 'float_dict': float_dict, - 'vex_dict': vex_dict, - 'expr': expr, -} - -ctx.update(all_regs_ids_byname) -sbuild = SemBuilder(ctx) - -def mn_compute_flags(rvalue, overflow_expr=None): - ret = [] - ret.append(ExprAssign(CR0_LT, rvalue.msb())) - ret.append(ExprAssign(CR0_GT, (ExprCond(rvalue, ExprInt(1, 1), - ExprInt(0, 1)) & ~rvalue.msb()))) - ret.append(ExprAssign(CR0_EQ, ExprCond(rvalue, ExprInt(0, 1), - ExprInt(1, 1)))) - if overflow_expr != None: - ret.append(ExprAssign(CR0_SO, XER_SO | overflow_expr)) - else: - ret.append(ExprAssign(CR0_SO, XER_SO)) - - return ret - -def mn_do_add(ir, instr, arg1, arg2, arg3): - assert instr.name[0:3] == 'ADD' - - flags_update = [] - - has_dot = False - has_c = False - has_e = False - has_o = False - - for l in instr.name[3:]: - if l == '.': - has_dot = True - elif l == 'C': - has_c = True - elif l == 'E': - has_e = True - elif l == 'O': - has_o = True - elif l == 'I' or l == 'M' or l == 'S' or l == 'Z': - pass # Taken care of earlier - else: - assert False - - rvalue = arg2 + arg3 - - if has_e: - rvalue = rvalue + XER_CA.zeroExtend(32) - - over_expr = None - if has_o: - msb1 = arg2.msb() - msb2 = arg3.msb() - msba = rvalue.msb() - over_expr = ~(msb1 ^ msb2) & (msb1 ^ msba) - flags_update.append(ExprAssign(XER_OV, over_expr)) - flags_update.append(ExprAssign(XER_SO, XER_SO | over_expr)) - - if has_dot: - flags_update += mn_compute_flags(rvalue, over_expr) - - if has_c or has_e: - carry_expr = (((arg2 ^ arg3) ^ rvalue) ^ - ((arg2 ^ rvalue) & (~(arg2 ^ arg3)))).msb() - flags_update.append(ExprAssign(XER_CA, carry_expr)) - - return ([ ExprAssign(arg1, rvalue) ] + flags_update), [] - -def mn_do_and(ir, instr, ra, rs, arg2): - if len(instr.name) > 3 and instr.name[3] == 'C': - oarg = ~arg2 - else: - oarg = arg2 - - rvalue = rs & oarg - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_cntlzw(ir, instr, ra, rs): - ret = [ ExprAssign(ra, ExprOp('cntleadzeros', rs)) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def crbit_to_reg(bit): - bit = int(bit) - crid = bit // 4 - bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4] - return all_regs_ids_byname["CR%d_%s" % (crid, bitname)] - -def mn_do_cr(ir, instr, crd, cra, crb): - a = crbit_to_reg(cra) - b = crbit_to_reg(crb) - d = crbit_to_reg(crd) - - op = instr.name[2:] - - if op == 'AND': - r = a & b - elif op == 'ANDC': - r = a & ~b - elif op == 'EQV': - r = ~(a ^ b) - elif op == 'NAND': - r = ~(a & b) - elif op == 'NOR': - r = ~(a | b) - elif op == 'OR': - r = a | b - elif op == 'ORC': - r = a | ~b - elif op == 'XOR': - r = a ^ b - else: - raise RuntimeError("Unknown operation on CR") - return [ ExprAssign(d, r) ], [] - -def mn_do_div(ir, instr, rd, ra, rb): - assert instr.name[0:4] == 'DIVW' - - flags_update = [] - - has_dot = False - has_c = False - has_o = False - has_u = False - - for l in instr.name[3:]: - if l == '.': - has_dot = True - elif l == 'C': - has_c = True - elif l == 'O': - has_o = True - elif l == 'U': - has_u = True - elif l == 'W': - pass - else: - assert False - - if has_u: - op = 'udiv' - else: - op = 'sdiv' - - rvalue = ExprOp(op, ra, rb) - - over_expr = None - if has_o: - over_expr = ExprCond(rb, ExprInt(0, 1), ExprInt(1, 1)) - if not has_u: - over_expr = over_expr | (ExprCond(ra ^ 0x80000000, ExprInt(0, 1), - ExprInt(1, 1)) & - ExprCond(rb ^ 0xFFFFFFFF, ExprInt(0, 1), - ExprInt(1, 1))) - flags_update.append(ExprAssign(XER_OV, over_expr)) - flags_update.append(ExprAssign(XER_SO, XER_SO | over_expr)) - - if has_dot: - flags_update += mn_compute_flags(rvalue, over_expr) - - return ([ ExprAssign(rd, rvalue) ] + flags_update), [] - - -def mn_do_eqv(ir, instr, ra, rs, rb): - rvalue = ~(rs ^ rb) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_exts(ir, instr, ra, rs): - if instr.name[4] == 'B': - size = 8 - elif instr.name[4] == 'H': - size = 16 - else: - assert False - - rvalue = rs[0:size].signExtend(32) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def byte_swap(expr): - nbytes = expr.size // 8 - lbytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ] - return ExprCompose(*lbytes) - -def mn_do_load(ir, instr, arg1, arg2, arg3=None): - assert instr.name[0] == 'L' - - ret = [] - - if instr.name[1] == 'M': - return mn_do_lmw(ir, instr, arg1, arg2) - elif instr.name[1] == 'S': - raise RuntimeError("LSWI, and LSWX need implementing") - elif instr.name[1] == 'F': - print("Warning, instruction %s implemented as NOP" % instr) - return [], [] - elif instr.name[1] == 'V': - print("Warning, instruction %s implemented as NOP" % instr) - return [], [] - - size = {'B': 8, 'H': 16, 'W': 32}[instr.name[1]] - - has_a = False - has_b = False - has_u = False - is_lwarx = False - - for l in instr.name[2:]: - if l == 'A': - has_a = True - elif l == 'B': - has_b = True - elif l == 'U': - has_u = True - elif l == 'X' or l == 'Z': - pass # Taken care of earlier - elif l == 'R' and not has_b: - is_lwarx = True - else: - assert False - - if arg3 is None: - assert isinstance(arg2, ExprMem) - - address = arg2.ptr - else: - address = arg2 + arg3 - - src = ExprMem(address, size) - - if has_b: - src = byte_swap(src) - - if has_a: - src = src.signExtend(32) - else: - src = src.zeroExtend(32) - - ret.append(ExprAssign(arg1, src)) - if has_u: - if arg3 is None: - ret.append(ExprAssign(arg2.ptr.args[0], address)) - else: - ret.append(ExprAssign(arg2, address)) - - if is_lwarx: - ret.append(ExprAssign(reserve, ExprInt(1, 1))) - ret.append(ExprAssign(reserve_address, address)) # XXX should be the PA - - return ret, [] - -def mn_do_lmw(ir, instr, rd, src): - ret = [] - address = src.ptr - ri = int(rd.name[1:],10) - i = 0 - while ri <= 31: - ret.append(ExprAssign(all_regs_ids_byname["R%d" % ri], - ExprMem(address + ExprInt(i, 32), 32))) - ri += 1 - i += 4 - - return ret, [] - -def mn_do_lswi(ir, instr, rd, ra, nb): - if nb == 0: - nb = 32 - i = 32 - raise RuntimeError("%r not implemented" % instr) - -def mn_do_lswx(ir, instr, rd, ra, nb): - raise RuntimeError("%r not implemented" % instr) - -def mn_do_mcrf(ir, instr, crfd, crfs): - ret = [] - - for bit in [ 'LT', 'GT', 'EQ', 'SO' ]: - d = all_regs_ids_byname["%s_%s" % (crfd, bit)] - s = all_regs_ids_byname["%s_%s" % (crfs, bit)] - ret.append(ExprAssign(d, s)) - - return ret, [] - -def mn_do_mcrxr(ir, instr, crfd): - ret = [] - - for (bit, val) in [ ('LT', XER_SO), ('GT', XER_OV), ('EQ', XER_CA), - ('SO', ExprInt(0, 1)) ]: - ret.append(ExprAssign(all_regs_ids_byname["%s_%s" % (crfd, bit)], val)) - - return ret, [] - -def mn_do_mfcr(ir, instr, rd): - return ([ ExprAssign(rd, ExprCompose(*[ all_regs_ids_byname["CR%d_%s" % (i, b)] - for i in range(7, -1, -1) - for b in ['SO', 'EQ', 'GT', 'LT']]))], - []) - -@sbuild.parse -def mn_mfmsr(rd): - rd = MSR - -def mn_mfspr(ir, instr, arg1, arg2): - sprid = int(arg2) - gprid = int(arg1.name[1:]) - if sprid in spr_dict: - return [ ExprAssign(arg1, spr_dict[sprid]) ], [] - elif sprid == 1: # XER - return [ ExprAssign(arg1, ExprCompose(XER_BC, ExprInt(0, 22), - XER_CA, XER_OV, XER_SO)) ], [] - else: - return [ ExprAssign(spr_access, - ExprInt(((sprid << SPR_ACCESS_SPR_OFF) | - (gprid << SPR_ACCESS_GPR_OFF)), 32)), - ExprAssign(exception_flags, ExprInt(EXCEPT_SPR_ACCESS, 32)) ], [] - -def mn_mtcrf(ir, instr, crm, rs): - ret = [] - - for i in range(8): - if int(crm) & (1 << (7 - i)): - j = (28 - 4 * i) + 3 - for b in ['LT', 'GT', 'EQ', 'SO']: - ret.append(ExprAssign(all_regs_ids_byname["CR%d_%s" % (i, b)], - rs[j:j+1])) - j -= 1 - - return ret, [] - -def mn_mtmsr(ir, instr, rs): - print("%08x: MSR assigned" % instr.offset) - return [ ExprAssign(MSR, rs) ], [] - -def mn_mtspr(ir, instr, arg1, arg2): - sprid = int(arg1) - gprid = int(arg2.name[1:]) - if sprid in spr_dict: - return [ ExprAssign(spr_dict[sprid], arg2) ], [] - elif sprid == 1: # XER - return [ ExprAssign(XER_SO, arg2[31:32]), - ExprAssign(XER_OV, arg2[30:31]), - ExprAssign(XER_CA, arg2[29:30]), - ExprAssign(XER_BC, arg2[0:7]) ], [] - else: - return [ ExprAssign(spr_access, - ExprInt(((sprid << SPR_ACCESS_SPR_OFF) | - (gprid << SPR_ACCESS_GPR_OFF) | - SPR_ACCESS_IS_WRITE), 32)), - ExprAssign(exception_flags, ExprInt(EXCEPT_SPR_ACCESS, 32)) ], [] - -def mn_mtsr(ir, instr, sr, rs): - srid = sr.arg - return [ ExprAssign(sr_dict[srid], rs) ], [] - -# TODO -#def mn_mtsrin(ir, instr, rs, rb): -# return [ ExprAssign(sr_dict[rb[0:3]], rs) ], [] - -def mn_mfsr(ir, instr, rd, sr): - srid = sr.arg - return [ ExprAssign(rd, sr_dict[srid]) ], [] - -# TODO -#def mn_mfsrin(ir, instr, rd, rb): -# return [ ExprAssign(rd, sr_dict[rb[0:3]]) ], [] - -def mn_do_mul(ir, instr, rd, ra, arg2): - variant = instr.name[3:] - if variant[-1] == '.': - variant = variant[:-2] - - if variant == 'HW': - v1 = ra.signExtend(64) - v2 = arg2.signExtend(64) - shift = 32 - elif variant == 'HWU': - v1 = ra.zeroExtend(64) - v2 = arg2.zeroExtend(64) - shift = 32 - else: - v1 = ra - v2 = arg2 - shift = 0 - - rvalue = ExprOp('*', v1, v2) - if shift != 0: - rvalue = rvalue[shift : shift + 32] - - ret = [ ExprAssign(rd, rvalue) ] - - over_expr = None - if variant[-1] == 'O': - over_expr = ExprCond((rvalue.signExtend(64) ^ - ExprOp('*', v1.signExtend(64), - v2.signExtend(64))), - ExprInt(1, 1), ExprInt(0, 1)) - ret.append(ExprAssign(XER_OV, over_expr)) - ret.append(ExprAssign(XER_SO, XER_SO | over_expr)) - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue, over_expr) - - return ret, [] - -def mn_do_nand(ir, instr, ra, rs, rb): - rvalue = ~(rs & rb) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_neg(ir, instr, rd, ra): - rvalue = -ra - ret = [ ExprAssign(rd, rvalue) ] - has_o = False - - over_expr = None - if instr.name[-1] == 'O' or instr.name[-2] == 'O': - has_o = True - over_expr = ExprCond(ra ^ ExprInt(0x80000000, 32), - ExprInt(0, 1), ExprInt(1, 1)) - ret.append(ExprAssign(XER_OV, over_expr)) - ret.append(ExprAssign(XER_SO, XER_SO | over_expr)) - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue, over_expr) - - return ret, [] - -def mn_do_nor(ir, instr, ra, rs, rb): - - rvalue = ~(rs | rb) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_or(ir, instr, ra, rs, arg2): - if len(instr.name) > 2 and instr.name[2] == 'C': - oarg = ~arg2 - else: - oarg = arg2 - - rvalue = rs | oarg - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_rfi(ir, instr): - dest = ExprCompose(ExprInt(0, 2), SRR0[2:32]) - ret = [ ExprAssign(MSR, (MSR & - ~ExprInt(0b1111111101110011, 32) | - ExprCompose(SRR1[0:2], ExprInt(0, 2), - SRR1[4:7], ExprInt(0, 1), - SRR1[8:16], ExprInt(0, 16)))), - ExprAssign(PC, dest), - ExprAssign(ir.IRDst, dest) ] - return ret, [] - -def mn_do_rotate(ir, instr, ra, rs, shift, mb, me): - r = ExprOp('<<<', rs, shift) - if mb <= me: - m = ExprInt(((1 << (32 - mb)) - 1) & ~((1 << (32 - me - 1)) - 1), 32) - else: - m = ExprInt(((1 << (32 - mb)) - 1) | ~((1 << (32 - me - 1)) - 1), 32) - rvalue = r & m - if instr.name[0:6] == 'RLWIMI': - rvalue = rvalue | (ra & ~m) - - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_slw(ir, instr, ra, rs, rb): - - rvalue = ExprCond(rb[5:6], ExprInt(0, 32), - ExprOp('<<', rs, rb & ExprInt(0b11111, 32))) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_sraw(ir, instr, ra, rs, rb): - rvalue = ExprCond(rb[5:6], ExprInt(0xFFFFFFFF, 32), - ExprOp('a>>', rs, rb & ExprInt(0b11111, 32))) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - mask = ExprCond(rb[5:6], ExprInt(0xFFFFFFFF, 32), - (ExprInt(0xFFFFFFFF, 32) >> - (ExprInt(32, 32) - (rb & ExprInt(0b11111, 32))))) - ret.append(ExprAssign(XER_CA, rs.msb() & - ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1)))) - - return ret, [] - -def mn_do_srawi(ir, instr, ra, rs, imm): - rvalue = ExprOp('a>>', rs, imm) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - mask = ExprInt(0xFFFFFFFF >> (32 - int(imm)), 32) - - ret.append(ExprAssign(XER_CA, rs.msb() & - ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1)))) - - return ret, [] - -def mn_do_srw(ir, instr, ra, rs, rb): - rvalue = rs >> (rb & ExprInt(0b11111, 32)) - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_do_stmw(ir, instr, rs, dest): - ret = [] - address = dest.ptr - ri = int(rs.name[1:],10) - i = 0 - while ri <= 31: - ret.append(ExprAssign(ExprMem(address + ExprInt(i,32), 32), - all_regs_ids_byname["R%d" % ri])) - ri += 1 - i += 4 - - return ret, [] - -def mn_do_store(ir, instr, arg1, arg2, arg3=None): - assert instr.name[0:2] == 'ST' - - ret = [] - additional_ir = [] - - if instr.name[2] == 'S': - raise RuntimeError("STSWI, and STSWX need implementing") - elif instr.name[2] == 'F': - print("Warning, instruction %s implemented as NOP" % instr) - return [], [] - - size = {'B': 8, 'H': 16, 'W': 32}[instr.name[2]] - - has_b = False - has_u = False - is_stwcx = False - - for l in instr.name[3:]: - if l == 'B' or l == 'R': - has_b = True - elif l == 'U': - has_u = True - elif l == 'X' or l == 'Z': - pass # Taken care of earlier - elif l == 'C' or l == '.': - is_stwcx = True - else: - assert False - - if arg3 is None: - assert isinstance(arg2, ExprMem) - - address = arg2.ptr - else: - address = arg2 + arg3 - - dest = ExprMem(address, size) - - src = arg1[0:size] - if has_b: - src = byte_swap(src) - - ret.append(ExprAssign(dest, src)) - if has_u: - if arg3 is None: - ret.append(ExprAssign(arg2.ptr.args[0], address)) - else: - ret.append(ExprAssign(arg2, address)) - - if is_stwcx: - loc_do = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) - loc_dont = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) - loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) - flags = [ ExprAssign(CR0_LT, ExprInt(0,1)), - ExprAssign(CR0_GT, ExprInt(0,1)), - ExprAssign(CR0_SO, XER_SO)] - ret += flags - ret.append(ExprAssign(CR0_EQ, ExprInt(1,1))) - ret.append(ExprAssign(ir.IRDst, loc_next)) - dont = flags + [ ExprAssign(CR0_EQ, ExprInt(0,1)), - ExprAssign(ir.IRDst, loc_next) ] - additional_ir = [ IRBlock(ir.loc_db, loc_do.loc_key, [ AssignBlock(ret) ]), - IRBlock(ir.loc_db, loc_dont.loc_key, [ AssignBlock(dont) ]) ] - ret = [ ExprAssign(reserve, ExprInt(0, 1)), - ExprAssign(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ] - - return ret, additional_ir - -def mn_do_sub(ir, instr, arg1, arg2, arg3): - assert instr.name[0:4] == 'SUBF' - - flags_update = [] - - has_dot = False - has_c = False - has_e = False - has_o = False - - for l in instr.name[4:]: - if l == '.': - has_dot = True - elif l == 'C': - has_c = True - elif l == 'E': - has_e = True - elif l == 'O': - has_o = True - elif l == 'I' or l == 'M' or l == 'S' or l == 'Z': - pass # Taken care of earlier - else: - assert False - - if has_e: - arg3 = arg3 + XER_CA.zeroExtend(32) - arg2 = arg2 + ExprInt(1, 32) - - rvalue = arg3 - arg2 - - over_expr = None - if has_o: - msb1 = arg2.msb() - msb2 = arg3.msb() - msba = rvalue.msb() - over_expr = (msb1 ^ msb2) & (msb1 ^ msba) - flags_update.append(ExprAssign(XER_OV, over_expr)) - flags_update.append(ExprAssign(XER_SO, XER_SO | over_expr)) - - if has_dot: - flags_update += mn_compute_flags(rvalue, over_expr) - - if has_c or has_e: - carry_expr = ((((arg3 ^ arg2) ^ rvalue) ^ - ((arg3 ^ rvalue) & (arg3 ^ arg2))).msb()) - flags_update.append(ExprAssign(XER_CA, ~carry_expr)) - - return ([ ExprAssign(arg1, rvalue) ] + flags_update), [] - -def mn_do_xor(ir, instr, ra, rs, rb): - rvalue = rs ^ rb - ret = [ ExprAssign(ra, rvalue) ] - - if instr.name[-1] == '.': - ret += mn_compute_flags(rvalue) - - return ret, [] - -def mn_b(ir, instr, arg1, arg2 = None): - if arg2 is not None: - arg1 = arg2 - return [ ExprAssign(PC, arg1), ExprAssign(ir.IRDst, arg1) ], [] - -def mn_bl(ir, instr, arg1, arg2 = None): - if arg2 is not None: - arg1 = arg2 - dst = ir.get_next_instr(instr) - return [ ExprAssign(LR, ExprLoc(dst, 32)), - ExprAssign(PC, arg1), - ExprAssign(ir.IRDst, arg1) ], [] - -def mn_get_condition(instr): - bit = instr.additional_info.bi & 0b11 - cr = instr.args[0].name - return all_regs_ids_byname[cr + '_' + ['LT', 'GT', 'EQ', 'SO'][bit]] - -def mn_do_cond_branch(ir, instr, dest): - bo = instr.additional_info.bo - bi = instr.additional_info.bi - ret = [] - - if bo & 0b00100: - ctr_cond = True - else: - ret.append(ExprAssign(CTR, CTR - ExprInt(1, 32))) - ctr_cond = ExprCond(CTR ^ ExprInt(1, 32), ExprInt(1, 1), ExprInt(0, 1)) - if bo & 0b00010: - ctr_cond = ~ctr_cond - - if (bo & 0b10000): - cond_cond = True - else: - cond_cond = mn_get_condition(instr) - if not (bo & 0b01000): - cond_cond = ~cond_cond - - if ctr_cond != True or cond_cond != True: - if ctr_cond != True: - condition = ctr_cond - if cond_cond != True: - condition = condition & cond_cond - else: - condition = cond_cond - dst = ir.get_next_instr(instr) - dest_expr = ExprCond(condition, dest, - ExprLoc(dst, 32)) - else: - dest_expr = dest - - if instr.name[-1] == 'L' or instr.name[-2:-1] == 'LA': - dst = ir.get_next_instr(instr) - ret.append(ExprAssign(LR, ExprLoc(dst, 32))) - - ret.append(ExprAssign(PC, dest_expr)) - ret.append(ExprAssign(ir.IRDst, dest_expr)) - - return ret, [] - -def mn_do_nop_warn(ir, instr, *args): - print("Warning, instruction %s implemented as NOP" % instr) - return [], [] - -@sbuild.parse -def mn_cmp_signed(arg1, arg2, arg3): - crf_dict[arg1]['LT'] = expr.ExprOp(expr.TOK_INF_SIGNED, arg2, arg3) - crf_dict[arg1]['GT'] = expr.ExprOp(expr.TOK_INF_SIGNED, arg3, arg2) - crf_dict[arg1]['EQ'] = expr.ExprOp(expr.TOK_EQUAL, arg2, arg3) - crf_dict[arg1]['SO'] = XER_SO - -@sbuild.parse -def mn_cmp_unsigned(arg1, arg2, arg3): - crf_dict[arg1]['LT'] = expr.ExprOp(expr.TOK_INF_UNSIGNED, arg2, arg3) - crf_dict[arg1]['GT'] = expr.ExprOp(expr.TOK_INF_UNSIGNED, arg3, arg2) - crf_dict[arg1]['EQ'] = expr.ExprOp(expr.TOK_EQUAL, arg2, arg3) - crf_dict[arg1]['SO'] = XER_SO - -def mn_nop(ir, instr, *args): - return [], [] - -@sbuild.parse -def mn_or(arg1, arg2, arg3): - arg1 = arg2 | arg3 - -@sbuild.parse -def mn_assign(arg1, arg2): - arg2 = arg1 - -def mn_stb(ir, instr, arg1, arg2): - dest = ExprMem(arg2.arg, 8) - return [ExprAssign(dest, ExprSlice(arg1, 0, 8))], [] - -@sbuild.parse -def mn_stwu(arg1, arg2): - arg2 = arg1 - arg1 = arg2.arg - -sem_dir = { - 'B': mn_b, - 'BA': mn_b, - 'BL': mn_bl, - 'BLA': mn_bl, - 'CMPLW': mn_cmp_unsigned, - 'CMPLWI': mn_cmp_unsigned, - 'CMPW': mn_cmp_signed, - 'CMPWI': mn_cmp_signed, - 'CNTLZW': mn_do_cntlzw, - 'CNTLZW.': mn_do_cntlzw, - 'ECIWX': mn_do_nop_warn, - 'ECOWX': mn_do_nop_warn, - 'EIEIO': mn_do_nop_warn, - 'EQV': mn_do_eqv, - 'EQV.': mn_do_eqv, - 'ICBI': mn_do_nop_warn, - 'ISYNC': mn_do_nop_warn, - 'MCRF': mn_do_mcrf, - 'MCRXR': mn_do_mcrxr, - 'MFCR': mn_do_mfcr, - 'MFFS': mn_do_nop_warn, - 'MFFS.': mn_do_nop_warn, - 'MFMSR': mn_mfmsr, - 'MFSPR': mn_mfspr, - 'MFSR': mn_mfsr, - 'MFSRIN': mn_do_nop_warn, - 'MTFSF': mn_do_nop_warn, - 'MTFSF.': mn_do_nop_warn, - 'MFTB': mn_mfspr, - 'MTCRF': mn_mtcrf, - 'MTMSR': mn_mtmsr, - 'MTSPR': mn_mtspr, - 'MTSR': mn_mtsr, - 'MTSRIN': mn_do_nop_warn, - 'MTVSCR': mn_do_nop_warn, - 'NAND': mn_do_nand, - 'NAND.': mn_do_nand, - 'NOR': mn_do_nor, - 'NOR.': mn_do_nor, - 'RFI': mn_do_rfi, - 'SC': mn_do_nop_warn, - 'SLW': mn_do_slw, - 'SLW.': mn_do_slw, - 'SRAW': mn_do_sraw, - 'SRAW.': mn_do_sraw, - 'SRAWI': mn_do_srawi, - 'SRAWI.': mn_do_srawi, - 'SRW': mn_do_srw, - 'SRW.': mn_do_srw, - 'SYNC': mn_do_nop_warn, - 'TLBIA': mn_do_nop_warn, - 'TLBIE': mn_do_nop_warn, - 'TLBSYNC': mn_do_nop_warn, - 'TW': mn_do_nop_warn, - 'TWI': mn_do_nop_warn, -} - - -class Lifter_PPC32b(Lifter): - - def __init__(self, loc_db): - super(Lifter_PPC32b, self).__init__(mn_ppc, 'b', loc_db) - self.pc = mn_ppc.getpc() - self.sp = mn_ppc.getsp() - self.IRDst = expr.ExprId('IRDst', 32) - self.addrsize = 32 - - def get_ir(self, instr): - args = instr.args[:] - if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]: - args[2] = ExprInt(int(args[2]) << 16, 32) - if instr.name[0:3] == 'ADD': - if instr.name[0:4] == 'ADDZ': - last_arg = ExprInt(0, 32) - elif instr.name[0:4] == 'ADDM': - last_arg = ExprInt(0xFFFFFFFF, 32) - else: - last_arg = args[2] - instr_ir, extra_ir = mn_do_add(self, instr, args[0], args[1], - last_arg) - elif instr.name[0:3] == 'AND': - instr_ir, extra_ir = mn_do_and(self, instr, *args) - elif instr.additional_info.bo_bi_are_defined: - name = instr.name - if name[-1] == '+' or name[-1] == '-': - name = name[0:-1] - if name[-3:] == 'CTR' or name[-4:] == 'CTRL': - arg1 = ExprCompose(ExprInt(0, 2), CTR[2:32]) - elif name[-2:] == 'LR' or name[-3:] == 'LRL': - arg1 = ExprCompose(ExprInt(0, 2), LR[2:32]) - else: - arg1 = args[1] - instr_ir, extra_ir = mn_do_cond_branch(self, instr, arg1) - elif instr.name[0:2] == 'CR': - instr_ir, extra_ir = mn_do_cr(self, instr, *args) - elif instr.name[0:3] == 'DCB': - instr_ir, extra_ir = mn_do_nop_warn(self, instr, *args) - elif instr.name[0:3] == 'DIV': - instr_ir, extra_ir = mn_do_div(self, instr, *args) - elif instr.name[0:4] == 'EXTS': - instr_ir, extra_ir = mn_do_exts(self, instr, *args) - elif instr.name[0] == 'L': - instr_ir, extra_ir = mn_do_load(self, instr, *args) - elif instr.name[0:3] == 'MUL': - instr_ir, extra_ir = mn_do_mul(self, instr, *args) - elif instr.name[0:3] == 'NEG': - instr_ir, extra_ir = mn_do_neg(self, instr, *args) - elif instr.name[0:2] == 'OR': - instr_ir, extra_ir = mn_do_or(self, instr, *args) - elif instr.name[0:2] == 'RL': - instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1], - args[2], int(args[3]), - int(args[4])) - elif instr.name == 'STMW': - instr_ir, extra_ir = mn_do_stmw(self, instr, *args) - elif instr.name[0:2] == 'ST': - instr_ir, extra_ir = mn_do_store(self, instr, *args) - elif instr.name[0:4] == 'SUBF': - if instr.name[0:5] == 'SUBFZ': - last_arg = ExprInt(0, 32) - elif instr.name[0:5] == 'SUBFM': - last_arg = ExprInt(0xFFFFFFFF, 32) - else: - last_arg = args[2] - instr_ir, extra_ir = mn_do_sub(self, instr, args[0], args[1], - last_arg) - elif instr.name[0:3] == 'XOR': - instr_ir, extra_ir = mn_do_xor(self, instr, *args) - else: - instr_ir, extra_ir = sem_dir[instr.name](self, instr, *args) - - return instr_ir, extra_ir - - def get_next_instr(self, instr): - l = self.loc_db.get_or_create_offset_location(instr.offset + 4) - return l - - def get_next_break_loc_key(self, instr): - l = self.loc_db.get_or_create_offset_location(instr.offset + 4) - return l |