def _size2mask(self, size): """Return a C string corresponding to the size2mask operation, with support for @size <= 128""" mask = size2mask(size) if size > 64: # Avoid "integer constant is too large for its type" error return "(0x%x | ((uint128_t) 0x%x << 64))" % ( mask & 0xFFFFFFFFFFFFFFFF, (mask >> 64) & 0xFFFFFFFFFFFFFFFF, ) return "0x%x" % mask
def signExtend(self, size): """Sign extend to size @size: int """ # assert self.size <= size if self.size == size: return self ad_size = size - self.size return ExprCompose( self, ExprCond(self.msb(), ExprInt(size2mask(ad_size), ad_size), ExprInt(0, ad_size)))
def signExtend(self, size): """Sign extend to size @size: int """ assert self.size <= size if self.size == size: return self ad_size = size - self.size return ExprCompose(self, ExprCond(self.msb(), ExprInt(size2mask(ad_size), ad_size), ExprInt(0, ad_size)))
def simp_ext(_, expr): if expr.op.startswith('zeroExt_'): arg = expr.args[0] if expr.size == arg.size: return arg return ExprCompose(arg, ExprInt(0, expr.size - arg.size)) if expr.op.startswith("signExt_"): arg = expr.args[0] add_size = expr.size - arg.size new_expr = ExprCompose( arg, ExprCond(arg.msb(), ExprInt(size2mask(add_size), add_size), ExprInt(0, add_size))) return new_expr return expr
def simp_ext(_, expr): if expr.op.startswith('zeroExt_'): arg = expr.args[0] if expr.size == arg.size: return arg return ExprCompose(arg, ExprInt(0, expr.size - arg.size)) if expr.op.startswith("signExt_"): arg = expr.args[0] add_size = expr.size - arg.size new_expr = ExprCompose( arg, ExprCond( arg.msb(), ExprInt(size2mask(add_size), add_size), ExprInt(0, add_size) ) ) return new_expr return expr
def _size2mask(self, size): """Return a C string corresponding to the size2mask operation, with support for @size <= 64""" assert size <= 64 mask = size2mask(size) return "0x%x" % mask
def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == 'parity': arg = expr.args[0] out = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: out = "(%s&%s)" % (out, self._size2mask(arg.size)) else: out = 'bignum_mask(%s, 8)' % (out, 8) out = 'bignum_to_uint64(%s)' % out out = 'parity(%s)' % out return out elif expr.op.startswith("zeroExt_"): arg = expr.args[0] if expr.size == arg.size: return arg return self.from_expr( ExprCompose(arg, ExprInt(0, expr.size - arg.size))) elif expr.op.startswith("signExt_"): arg = expr.args[0] if expr.size == arg.size: return arg add_size = expr.size - arg.size new_expr = ExprCompose( arg, ExprCond(arg.msb(), ExprInt(size2mask(add_size), add_size), ExprInt(0, add_size))) return self.from_expr(new_expr) elif expr.op in ['cntleadzeros', 'cnttrailzeros']: arg = expr.args[0] out = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: out = "%s(0x%x, %s)" % (expr.op, expr.args[0].size, out) else: out = "bignum_%s(%s, %d)" % (expr.op, out, arg.size) return out elif expr.op == '!': arg = expr.args[0] out = self.from_expr(arg) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = "(~ %s)&%s" % (out, self._size2mask(arg.size)) else: out = "bignum_not(%s)" % out out = "bignum_mask(%s, expr.size)" % out return out elif expr.op in [ "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos", "fchs", ]: return "fpu_%s%d(%s)" % ( expr.op, expr.size, self.from_expr(expr.args[0]), ) elif (expr.op.startswith("access_") or expr.op.startswith("load_") or expr.op.startswith("fxam_c")): arg = expr.args[0] out = self.from_expr(arg) out = "%s(%s)" % (expr.op, out) return out elif expr.op == "-": arg = expr.args[0] out = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: out = "(%s(%s))" % (expr.op, out) out = "(%s&%s)" % (out, self._size2mask(arg.size)) else: out = "bignum_sub(bignum_from_uint64(0), %s)" % out out = "bignum_mask(%s, %d)" % (out, expr.size) return out elif expr.op.startswith("fpround_"): return "%s_fp%d(%s)" % ( expr.op, expr.size, self.from_expr(expr.args[0]), ) elif expr.op == "sint_to_fp": size = expr.size arg = expr.args[0] if size not in [32, 64]: raise RuntimeError("Unsupported size for sint_to_fp: %r" % size) return "%s_%d(%s)" % (expr.op, size, self.from_expr(arg)) elif expr.op.startswith("fp_to_sint"): dest_size = expr.size arg_size = expr.args[0].size if (arg_size, dest_size) in [ (32, 32), (64, 64), (64, 32), ]: func = "fp%d_to_sint%d" % (arg_size, dest_size) else: raise RuntimeError( "Unsupported size for fp_to_sint: %r to %r" % (arg_size, dest_size)) return "%s(%s)" % (func, self.from_expr(expr.args[0])) elif expr.op.startswith("fpconvert_fp"): dest_size = expr.size arg_size = expr.args[0].size if (arg_size, dest_size) in [(32, 64), (64, 32)]: func = "fp%d_to_fp%d" % (arg_size, dest_size) else: raise RuntimeError( "Unsupported size for fpconvert: %r to %r" % (arg_size, dest_size)) return "%s(%s)" % (func, self.from_expr(expr.args[0])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 2: if expr.op == TOK_EQUAL: return '(((%s&%s) == (%s&%s))?1:0)' % ( self.from_expr(expr.args[0]), self._size2mask(expr.args[0].size), self.from_expr(expr.args[1]), self._size2mask(expr.args[1].size), ) elif expr.op in self.dct_shift: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = 'SHIFT_%s(%d, %s, %s)' % (self.dct_shift[ expr.op].upper(), expr.args[0].size, arg0, arg1) else: op = {"<<": "lshift", ">>": "rshift", "a>>": "a_rshift"} out = "bignum_%s(%s, bignum_to_uint64(%s))" % (op[expr.op], arg0, arg1) out = "bignum_mask(%s, %d)" % (out, expr.size) return out elif expr.is_associative(): args = [self.from_expr(arg) for arg in expr.args] if expr.size <= self.NATIVE_INT_MAX_SIZE: out = (" %s " % expr.op).join(args) out = "((%s)&%s)" % (out, self._size2mask(expr.size)) else: op_to_bn_func = { "+": "add", "*": "mul", "|": "or", "^": "xor", "&": "and", } args = list(expr.args) out = self.from_expr(args.pop()) while args: out = 'bignum_mask(bignum_%s(%s, %s), %d)' % ( op_to_bn_func[expr.op], out, self.from_expr(args.pop()), expr.size) return out elif expr.op in ['-']: return '(((%s&%s) %s (%s&%s))&%s)' % ( self.from_expr(expr.args[0]), self._size2mask(expr.args[0].size), str( expr.op), self.from_expr( expr.args[1]), self._size2mask(expr.args[1].size), self._size2mask(expr.args[0].size)) elif expr.op in self.dct_rot: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = '(%s(%s, %s, %s) &%s)' % ( self.dct_rot[expr.op], expr.args[0].size, arg0, arg1, self._size2mask(expr.args[0].size), ) else: op = {">>>": "ror", "<<<": "rol"} out = "bignum_%s(%s, %d, bignum_to_uint64(%s))" % ( op[expr.op], arg0, expr.size, arg1) out = "bignum_mask(%s, %d)" % (out, expr.size) return out elif expr.op == 'x86_cpuid': return "%s(%s, %s)" % (expr.op, self.from_expr( expr.args[0]), self.from_expr(expr.args[1])) elif expr.op.startswith("fcom"): arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE: raise ValueError( "Bad semantic: fpu do operations do not support such size" ) out = "fpu_%s(%s, %s)" % (expr.op, arg0, arg1) return out elif expr.op in [ "fadd", "fsub", "fdiv", 'fmul', "fscale", "fprem", "fyl2x", "fpatan" ]: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE: raise ValueError( "Bad semantic: fpu do operations do not support such size" ) out = "fpu_%s%d(%s, %s)" % (expr.op, expr.size, arg0, arg1) return out elif expr.op == "segm": return "segm2addr(jitcpu, %s, %s)" % (self.from_expr( expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ['udiv', 'umod']: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = '%s%d(%s, %s)' % (expr.op, expr.args[0].size, arg0, arg1) else: out = "bignum_%s(%s, %s)" % (expr.op, arg0, arg1) out = "bignum_mask(%s, %d)" % (out, expr.size) return out elif expr.op in ['sdiv', 'smod']: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = '%s%d(%s, %s)' % (expr.op, expr.args[0].size, arg0, arg1) else: out = "bignum_%s(%s, %s, %d)" % (expr.op, arg0, arg1, expr.size) out = "bignum_mask(%s, %d)" % (out, expr.size) return out elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) >= 3 and expr.is_associative(): # ????? oper = [ '(%s&%s)' % ( self.from_expr(arg), self._size2mask(arg.size), ) for arg in expr.args ] oper = str(expr.op).join(oper) return "((%s)&%s)" % (oper, self._size2mask(expr.args[0].size)) else: raise NotImplementedError('Unknown op: %s' % expr.op)
def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == 'parity': return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ['cntleadzeros', 'cnttrailzeros']: return "%s(0x%x, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0])) elif expr.op == '!': return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) elif (expr.op.startswith("double_to_") or expr.op.endswith("_to_double") or expr.op.startswith("access_") or expr.op.startswith("load_") or expr.op.startswith("fxam_c") or expr.op in ["-", "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos", "fchs"]): return "%s(%s)" % (expr.op, self.from_expr(expr.args[0])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 2: if expr.op == "==": return '(((%s&0x%x) == (%s&0x%x))?1:0)' % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), self.from_expr(expr.args[1]), size2mask(expr.args[1].size)) elif expr.op in self.dct_shift: return 'SHIFT_%s(%d, %s, %s)' % (self.dct_shift[expr.op].upper(), expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.is_associative() or expr.op in ["%", "/"]: oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) elif expr.op in ['-']: return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), str(expr.op), self.from_expr(expr.args[1]), size2mask(expr.args[1].size), size2mask(expr.args[0].size)) elif expr.op in self.dct_rot: return '(%s(%s, %s, %s) &0x%x)' % (self.dct_rot[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), size2mask(expr.args[0].size)) elif expr.op == 'x86_cpuid': return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif (expr.op.startswith("fcom") or expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale", "fprem", "fprem_lsb", "fyl2x", "fpatan"]): return "fpu_%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op == "segm": return "segm2addr(jitcpu, %s, %s)" % ( self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ['udiv', 'umod', 'idiv', 'imod']: return '%s%d(%s, %s)' % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) >= 3 and expr.is_associative(): # ????? oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) else: raise NotImplementedError('Unknown op: %s' % expr.op)
def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == 'parity': return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ['bsr', 'bsf']: return "x86_%s(%s, 0x%x)" % (expr.op, self.from_expr(expr.args[0]), expr.args[0].size) elif expr.op == '!': return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ["hex2bcd", "bcd2hex"]: return "%s_%d(%s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0])) elif (expr.op.startswith("double_to_") or expr.op.endswith("_to_double") or expr.op.startswith("access_") or expr.op.startswith("load_") or expr.op in ["-", "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos"]): return "%s(%s)" % (expr.op, self.from_expr(expr.args[0])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 2: if expr.op == "==": return '(((%s&0x%x) == (%s&0x%x))?1:0)' % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), self.from_expr(expr.args[1]), size2mask(expr.args[1].size)) elif expr.op in self.dct_shift: return 'shift_%s_%.2d(%s , %s)' % (self.dct_shift[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.is_associative() or expr.op in ["%", "/"]: oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) elif expr.op in ['-']: return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), str(expr.op), self.from_expr(expr.args[1]), size2mask(expr.args[1].size), size2mask(expr.args[0].size)) elif expr.op in self.dct_rot: return '(%s(%s, %s, %s) &0x%x)' % (self.dct_rot[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), size2mask(expr.args[0].size)) elif (expr.op.startswith('cpuid') or expr.op.startswith("fcom") or expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]): return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op == "segm": return "segm2addr(jitcpu, %s, %s)" % ( self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ['udiv', 'umod', 'idiv', 'imod']: return '%s%d((vm_cpu_t*)jitcpu->cpu, %s, %s)' % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 3 and expr.op in self.dct_div: return '(%s(%s, %s, %s, %s) &0x%x)' % (self.dct_div[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), self.from_expr(expr.args[2]), size2mask(expr.args[0].size)) elif len(expr.args) >= 3 and expr.is_associative(): # ????? oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) else: raise NotImplementedError('Unknown op: %s' % expr.op)
def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == 'parity': return "parity(%s&0x%x)" % (self.from_expr( expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ['bsr', 'bsf']: return "x86_%s(%s, 0x%x)" % ( expr.op, self.from_expr(expr.args[0]), expr.args[0].size) elif expr.op == '!': return "(~ %s)&0x%x" % (self.from_expr( expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ["hex2bcd", "bcd2hex"]: return "%s_%d(%s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0])) elif (expr.op.startswith("double_to_") or expr.op.endswith("_to_double") or expr.op.startswith("access_") or expr.op.startswith("load_") or expr.op in [ "-", "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos" ]): return "%s(%s)" % (expr.op, self.from_expr(expr.args[0])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 2: if expr.op == "==": return '(((%s&0x%x) == (%s&0x%x))?1:0)' % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), self.from_expr(expr.args[1]), size2mask(expr.args[1].size)) elif expr.op in self.dct_shift: return 'shift_%s_%.2d(%s , %s)' % ( self.dct_shift[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.is_associative() or expr.op in ["%", "/"]: oper = [ '(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args ] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) elif expr.op in ['-']: return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), str(expr.op), self.from_expr(expr.args[1]), size2mask(expr.args[1].size), size2mask(expr.args[0].size)) elif expr.op in self.dct_rot: return '(%s(%s, %s, %s) &0x%x)' % ( self.dct_rot[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr( expr.args[1]), size2mask(expr.args[0].size)) elif (expr.op.startswith('cpuid') or expr.op.startswith("fcom") or expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]): return "%s(%s, %s)" % (expr.op, self.from_expr( expr.args[0]), self.from_expr(expr.args[1])) elif expr.op == "segm": return "segm2addr(vmcpu, %s, %s)" % (self.from_expr( expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ['udiv', 'umod', 'idiv', 'imod']: return '%s%d(vmcpu, %s, %s)' % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 3 and expr.op in self.dct_div: return '(%s(%s, %s, %s, %s) &0x%x)' % ( self.dct_div[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), self.from_expr(expr.args[2]), size2mask(expr.args[0].size)) elif len(expr.args) >= 3 and expr.is_associative(): # ????? oper = [ '(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args ] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) else: raise NotImplementedError('Unknown op: %s' % expr.op)
def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == 'parity': arg = expr.args[0] out = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: out = "(%s&%s)" % (out, self._size2mask(arg.size)) else: out = 'bignum_mask(%s, 8)' % (out, 8) out = 'bignum_to_uint64(%s)' % out out = 'parity(%s)' % out return out elif expr.op.startswith("zeroExt_"): arg = expr.args[0] if expr.size == arg.size: return arg return self.from_expr(ExprCompose(arg, ExprInt(0, expr.size - arg.size))) elif expr.op.startswith("signExt_"): arg = expr.args[0] if expr.size == arg.size: return arg add_size = expr.size - arg.size new_expr = ExprCompose( arg, ExprCond( arg.msb(), ExprInt(size2mask(add_size), add_size), ExprInt(0, add_size) ) ) return self.from_expr(new_expr) elif expr.op in ['cntleadzeros', 'cnttrailzeros']: arg = expr.args[0] out = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: out = "%s(0x%x, %s)" % (expr.op, expr.args[0].size, out) else: out = "bignum_%s(%s, %d)" % (expr.op, out, arg.size) return out elif expr.op == '!': arg = expr.args[0] out = self.from_expr(arg) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = "(~ %s)&%s" % (out, self._size2mask(arg.size)) else: out = "bignum_not(%s)" % out out = "bignum_mask(%s, expr.size)" % out return out elif expr.op in [ "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos", "fchs", ]: return "fpu_%s%d(%s)" % ( expr.op, expr.size, self.from_expr(expr.args[0]), ) elif (expr.op.startswith("access_") or expr.op.startswith("load_") or expr.op.startswith("fxam_c")): arg = expr.args[0] out = self.from_expr(arg) out = "%s(%s)" % (expr.op, out) return out elif expr.op == "-": arg = expr.args[0] out = self.from_expr(arg) if arg.size <= self.NATIVE_INT_MAX_SIZE: out = "(%s(%s))" % (expr.op, out) out = "(%s&%s)" % (out, self._size2mask(arg.size)) else: out = "bignum_sub(bignum_from_uint64(0), %s)" % out out = "bignum_mask(%s, %d)"% (out, expr.size) return out elif expr.op.startswith("fpround_"): return "%s_fp%d(%s)" % ( expr.op, expr.size, self.from_expr(expr.args[0]), ) elif expr.op == "sint_to_fp": size = expr.size arg = expr.args[0] if size not in [32, 64]: raise RuntimeError( "Unsupported size for sint_to_fp: %r" % size ) return "%s_%d(%s)" % (expr.op, size, self.from_expr(arg)) elif expr.op.startswith("fp_to_sint"): dest_size = expr.size arg_size = expr.args[0].size if (arg_size, dest_size) in [ (32, 32), (64, 64), (64, 32), ]: func = "fp%d_to_sint%d" % (arg_size, dest_size) else: raise RuntimeError( "Unsupported size for fp_to_sint: %r to %r" % ( arg_size, dest_size )) return "%s(%s)" % (func, self.from_expr(expr.args[0])) elif expr.op.startswith("fpconvert_fp"): dest_size = expr.size arg_size = expr.args[0].size if (arg_size, dest_size) in [ (32, 64), (64, 32) ]: func = "fp%d_to_fp%d" % (arg_size, dest_size) else: raise RuntimeError( "Unsupported size for fpconvert: %r to %r" % (arg_size, dest_size) ) return "%s(%s)" % (func, self.from_expr(expr.args[0])) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) == 2: if expr.op == TOK_EQUAL: return '(((%s&%s) == (%s&%s))?1:0)' % ( self.from_expr(expr.args[0]), self._size2mask(expr.args[0].size), self.from_expr(expr.args[1]), self._size2mask(expr.args[1].size), ) elif expr.op in self.dct_shift: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = 'SHIFT_%s(%d, %s, %s)' % ( self.dct_shift[expr.op].upper(), expr.args[0].size, arg0, arg1 ) else: op = { "<<": "lshift", ">>": "rshift", "a>>": "a_rshift" } out = "bignum_%s(%s, bignum_to_uint64(%s))" % ( op[expr.op], arg0, arg1 ) out = "bignum_mask(%s, %d)"% (out, expr.size) return out elif expr.is_associative(): args = [self.from_expr(arg) for arg in expr.args] if expr.size <= self.NATIVE_INT_MAX_SIZE: out = (" %s " % expr.op).join(args) out = "((%s)&%s)" % (out, self._size2mask(expr.size)) else: op_to_bn_func = { "+": "add", "*": "mul", "|": "or", "^": "xor", "&": "and", } args = list(expr.args) out = self.from_expr(args.pop()) while args: out = 'bignum_mask(bignum_%s(%s, %s), %d)' % ( op_to_bn_func[expr.op], out, self.from_expr(args.pop()), expr.size ) return out elif expr.op in ['-']: return '(((%s&%s) %s (%s&%s))&%s)' % ( self.from_expr(expr.args[0]), self._size2mask(expr.args[0].size), str(expr.op), self.from_expr(expr.args[1]), self._size2mask(expr.args[1].size), self._size2mask(expr.args[0].size) ) elif expr.op in self.dct_rot: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = '(%s(%s, %s, %s) &%s)' % ( self.dct_rot[expr.op], expr.args[0].size, arg0, arg1, self._size2mask(expr.args[0].size), ) else: op = { ">>>": "ror", "<<<": "rol" } out = "bignum_%s(%s, %d, bignum_to_uint64(%s))" % ( op[expr.op], arg0, expr.size, arg1 ) out = "bignum_mask(%s, %d)"% (out, expr.size) return out elif expr.op == 'x86_cpuid': return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op.startswith("fcom"): arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE: raise ValueError("Bad semantic: fpu do operations do not support such size") out = "fpu_%s(%s, %s)" % (expr.op, arg0, arg1) return out elif expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale", "fprem", "fyl2x", "fpatan"]: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if not expr.args[0].size <= self.NATIVE_INT_MAX_SIZE: raise ValueError("Bad semantic: fpu do operations do not support such size") out = "fpu_%s%d(%s, %s)" % (expr.op, expr.size, arg0, arg1) return out elif expr.op == "segm": return "segm2addr(jitcpu, %s, %s)" % ( self.from_expr(expr.args[0]), self.from_expr(expr.args[1]) ) elif expr.op in ['udiv', 'umod']: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = '%s%d(%s, %s)' % ( expr.op, expr.args[0].size, arg0, arg1 ) else: out = "bignum_%s(%s, %s)" % ( expr.op, arg0, arg1 ) out = "bignum_mask(%s, %d)"% (out, expr.size) return out elif expr.op in ['idiv', 'imod']: arg0 = self.from_expr(expr.args[0]) arg1 = self.from_expr(expr.args[1]) if expr.size <= self.NATIVE_INT_MAX_SIZE: out = '%s%d(%s, %s)' % ( expr.op, expr.args[0].size, arg0, arg1 ) else: out = "bignum_%s(%s, %s, %d)" % ( expr.op, arg0, arg1, expr.size ) out = "bignum_mask(%s, %d)"% (out, expr.size) return out elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % ( expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]) ) else: raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) >= 3 and expr.is_associative(): # ????? oper = ['(%s&%s)' % ( self.from_expr(arg), self._size2mask(arg.size), ) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&%s)" % ( oper, self._size2mask(expr.args[0].size) ) else: raise NotImplementedError('Unknown op: %s' % expr.op)
def __get_int(self): "Return self integer representation" return int(self.__arg & size2mask(self.__size))
def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == "parity": return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ["bsr", "bsf"]: return "x86_%s(%s, 0x%x)" % (expr.op, self.from_expr(expr.args[0]), expr.args[0].size) elif expr.op == "!": return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]), size2mask(expr.args[0].size)) elif expr.op in ["hex2bcd", "bcd2hex"]: return "%s_%d(%s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0])) elif ( expr.op.startswith("double_to_") or expr.op.endswith("_to_double") or expr.op.startswith("access_") or expr.op.startswith("load_") or expr.op.startswith("fxam_c") or expr.op in ["-", "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos", "fchs"] ): return "%s(%s)" % (expr.op, self.from_expr(expr.args[0])) else: raise NotImplementedError("Unknown op: %r" % expr.op) elif len(expr.args) == 2: if expr.op == "==": return "(((%s&0x%x) == (%s&0x%x))?1:0)" % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), self.from_expr(expr.args[1]), size2mask(expr.args[1].size), ) elif expr.op in self.dct_shift: return "shift_%s_%.2d(%s , %s)" % ( self.dct_shift[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), ) elif expr.is_associative() or expr.op in ["%", "/"]: oper = ["(%s&0x%x)" % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) elif expr.op in ["-"]: return "(((%s&0x%x) %s (%s&0x%x))&0x%x)" % ( self.from_expr(expr.args[0]), size2mask(expr.args[0].size), str(expr.op), self.from_expr(expr.args[1]), size2mask(expr.args[1].size), size2mask(expr.args[0].size), ) elif expr.op in self.dct_rot: return "(%s(%s, %s, %s) &0x%x)" % ( self.dct_rot[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), size2mask(expr.args[0].size), ) elif ( expr.op.startswith("cpuid") or expr.op.startswith("fcom") or expr.op in ["fadd", "fsub", "fdiv", "fmul", "fscale", "fprem", "fprem_lsb", "fyl2x", "fpatan"] ): return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op == "segm": return "segm2addr(jitcpu, %s, %s)" % (self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ["udiv", "umod", "idiv", "imod"]: return "%s%d((vm_cpu_t*)jitcpu->cpu, %s, %s)" % ( expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), ) elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % ( expr.op, expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), ) else: raise NotImplementedError("Unknown op: %r" % expr.op) elif len(expr.args) == 3 and expr.op in self.dct_rotc: return "(%s(%s, %s, %s, %s) &0x%x)" % ( self.dct_rotc[expr.op], expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1]), self.from_expr(expr.args[2]), size2mask(expr.args[0].size), ) elif len(expr.args) >= 3 and expr.is_associative(): # ????? oper = ["(%s&0x%x)" % (self.from_expr(arg), size2mask(arg.size)) for arg in expr.args] oper = str(expr.op).join(oper) return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) else: raise NotImplementedError("Unknown op: %s" % expr.op)