def _fptrunc(term, smt): v = smt.eval(term.arg) tgt = smt.type(term) e = 2**(tgt.exp - 1) # max exponent + 1 m = 2**e rm = z3.get_default_rounding_mode() return smt._conditional_conv_value([v > -m, v < m], z3.fpTpFP(rm, v, _ty_sort(tgt)), term.name)
def _fptrunc(term, smt): v = smt.eval(term.arg) tgt = smt.type(term) e = 2**(tgt.exp-1) # max exponent + 1 m = 2**e rm = z3.get_default_rounding_mode() return smt._conditional_conv_value( [v > -m, v < m], z3.fpTpFP(rm, v, _ty_sort(tgt)), term.name)
def pp_fp(self, a, d, xs): _z3_assert(isinstance(a, z3.FPRef), "type mismatch") k = a.decl().kind() op = '?' if (self.fpa_pretty and k in _z3_op_to_fpa_pretty_str): op = _z3_op_to_fpa_pretty_str[k] elif k in _z3_op_to_fpa_normal_str: op = _z3_op_to_fpa_normal_str[k] elif k in _z3_op_to_str: op = _z3_op_to_str[k] n = a.num_args() if self.fpa_pretty: if self.is_infix(k) and n >= 3: rm = a.arg(0) if z3.is_fprm_value(rm) and z3.get_default_rounding_mode( a.ctx).eq(rm): arg1 = to_format(self.pp_expr(a.arg(1), d + 1, xs)) arg2 = to_format(self.pp_expr(a.arg(2), d + 1, xs)) r = [] r.append(arg1) r.append(to_format(' ')) r.append(to_format(op)) r.append(to_format(' ')) r.append(arg2) return compose(r) elif k == Z3_OP_FPA_NEG: return compose([ to_format('-'), to_format(self.pp_expr(a.arg(0), d + 1, xs)) ]) if k in _z3_op_to_fpa_normal_str: op = _z3_op_to_fpa_normal_str[k] r = [] r.append(to_format(op)) if not z3.is_const(a): r.append(to_format('(')) first = True for c in a.children(): if first: first = False else: r.append(to_format(', ')) r.append(self.pp_expr(c, d + 1, xs)) r.append(to_format(')')) return compose(r) else: return to_format(a.as_string())
def _uitofp(term, smt): v = smt.eval(term.arg) src = smt.type(term.arg) tgt = smt.type(term) w = 2**(tgt.exp-1) if src.width >= w: m = 2**w conds = [z3.ULE(v, m)] else: conds = [] return smt._conditional_conv_value(conds, z3.fpToFPUnsigned(z3.get_default_rounding_mode(), v, _ty_sort(tgt)), term.name)
def _sitofp(term, smt): v = smt.eval(term.arg) src = smt.type(term.arg) tgt = smt.type(term) w = 2**(tgt.exp-1) # 1 + maximum value of the exponent if src.width - 1 > w: m = 2**w conds = [-m < v, v < m] else: conds = [] return smt._conditional_conv_value(conds, z3.fpToFP(z3.get_default_rounding_mode(), v, _ty_sort(tgt)), term.name)
def _sitofp(term, smt): v = smt.eval(term.arg) src = smt.type(term.arg) tgt = smt.type(term) w = 2**(tgt.exp - 1) # 1 + maximum value of the exponent if src.width - 1 > w: m = 2**w conds = [-m < v, v < m] else: conds = [] return smt._conditional_conv_value( conds, z3.fpToFP(z3.get_default_rounding_mode(), v, _ty_sort(tgt)), term.name)
def pp_fp(self, a, d, xs): _z3_assert(isinstance(a, z3.FPRef), "type mismatch") k = a.decl().kind() op = '?' if (self.fpa_pretty and k in _z3_op_to_fpa_pretty_str): op = _z3_op_to_fpa_pretty_str[k] elif k in _z3_op_to_fpa_normal_str: op = _z3_op_to_fpa_normal_str[k] elif k in _z3_op_to_str: op = _z3_op_to_str[k] n = a.num_args() if self.fpa_pretty: if self.is_infix(k) and n >= 3: rm = a.arg(0) if z3.is_fprm_value(rm) and z3.get_default_rounding_mode(a.ctx).eq(rm): arg1 = to_format(self.pp_expr(a.arg(1), d+1, xs)) arg2 = to_format(self.pp_expr(a.arg(2), d+1, xs)) r = [] r.append(arg1) r.append(to_format(' ')) r.append(to_format(op)) r.append(to_format(' ')) r.append(arg2) return compose(r) elif k == Z3_OP_FPA_NEG: return compose([to_format('-') , to_format(self.pp_expr(a.arg(0), d+1, xs))]) if k in _z3_op_to_fpa_normal_str: op = _z3_op_to_fpa_normal_str[k] r = [] r.append(to_format(op)) if not z3.is_const(a): r.append(to_format('(')) first = True for c in a.children(): if first: first = False else: r.append(to_format(', ')) r.append(self.pp_expr(c, d+1, xs)) r.append(to_format(')')) return compose(r) else: return to_format(a.as_string())
defined = lambda x,y: [z3.ULT(y, y.size())], poisons = {'exact': lambda x,y: z3.LShR(x, y) << y == x})) eval.register(AndInst, BaseSMTTranslator, binop(operator.and_)) eval.register(OrInst, BaseSMTTranslator, binop(operator.or_)) eval.register(XorInst, BaseSMTTranslator, binop(operator.xor)) def fbinop(op): return lambda term,smt: smt._float_binary_operator(term, op) eval.register(FAddInst, BaseSMTTranslator, fbinop(operator.add)) eval.register(FSubInst, BaseSMTTranslator, fbinop(operator.sub)) eval.register(FMulInst, BaseSMTTranslator, fbinop(operator.mul)) eval.register(FDivInst, BaseSMTTranslator, fbinop( lambda x,y: z3.fpDiv(z3.get_default_rounding_mode(), x, y))) eval.register(FRemInst, BaseSMTTranslator, fbinop(z3.fpRem)) @doubledispatch def _eval_bitcast(src, tgt, v): """ Return SMT expression converting v from src to tgt. Assumes src and tgt have the same bit width. """ raise NotImplementedError @_eval_bitcast.register(IntType, IntType) @_eval_bitcast.register(IntType, PtrType) @_eval_bitcast.register(PtrType, IntType)
eval.register(AndInst, BaseSMTTranslator, binop(operator.and_)) eval.register(OrInst, BaseSMTTranslator, binop(operator.or_)) eval.register(XorInst, BaseSMTTranslator, binop(operator.xor)) def fbinop(op): return lambda term, smt: smt._float_binary_operator(term, op) eval.register(FAddInst, BaseSMTTranslator, fbinop(operator.add)) eval.register(FSubInst, BaseSMTTranslator, fbinop(operator.sub)) eval.register(FMulInst, BaseSMTTranslator, fbinop(operator.mul)) eval.register( FDivInst, BaseSMTTranslator, fbinop(lambda x, y: z3.fpDiv(z3.get_default_rounding_mode(), x, y))) eval.register(FRemInst, BaseSMTTranslator, fbinop(z3.fpRem)) @doubledispatch def _eval_bitcast(src, tgt, v): """ Return SMT expression converting v from src to tgt. Assumes src and tgt have the same bit width. """ raise NotImplementedError @_eval_bitcast.register(IntType, IntType) @_eval_bitcast.register(IntType, PtrType)
poisons = {'exact': lambda x,y: z3.LShR(x,y) << y == x})) eval.register(AndInst, BaseSMTEncoder, binop(operator.and_)) eval.register(OrInst, BaseSMTEncoder, binop(operator.or_)) eval.register(XorInst, BaseSMTEncoder, binop(operator.xor)) def fbinop(op): return lambda term,smt: smt._float_binary_operator(term, op) eval.register(FAddInst, BaseSMTEncoder, fbinop(operator.add)) eval.register(FSubInst, BaseSMTEncoder, fbinop(operator.sub)) eval.register(FMulInst, BaseSMTEncoder, fbinop(operator.mul)) eval.register(FDivInst, BaseSMTEncoder, fbinop( lambda x,y: z3.fpDiv(z3.get_default_rounding_mode(), x, y))) eval.register(FRemInst, BaseSMTEncoder, fbinop(fpMod)) @doubledispatch def _eval_bitcast(src, tgt, v): """ Return SMT expression converting v from src to tgt. Assumes src and tgt have the same bit width. """ raise NotImplementedError('Unexpected bitcast: {} -> {}'.format(src, tgt)) @_eval_bitcast.register(IntType, IntType) @_eval_bitcast.register(IntType, PtrType) @_eval_bitcast.register(PtrType, IntType)