def _convert(self, obj): if isinstance(obj, FSort): return z3.FPSort(obj.exp, obj.mantissa, ctx=self._context) elif isinstance(obj, RM): if obj == RM_RNE: return z3.RNE(ctx=self._context) elif obj == RM_RNA: return z3.RNA(ctx=self._context) elif obj == RM_RTP: return z3.RTP(ctx=self._context) elif obj == RM_RTN: return z3.RTN(ctx=self._context) elif obj == RM_RTZ: return z3.RTZ(ctx=self._context) else: raise BackendError("unrecognized rounding mode") elif obj is True: return z3.BoolVal(True, ctx=self._context) elif obj is False: return z3.BoolVal(False, ctx=self._context) elif isinstance(obj, (numbers.Number, str)): return obj elif hasattr(obj, '__module__') and obj.__module__ in ('z3', 'z3.z3'): return obj else: l.debug("BackendZ3 encountered unexpected type %s", type(obj)) raise BackendError("unexpected type %s encountered in BackendZ3" % type(obj))
def _convert(self, obj, result=None): if type(obj) is NativeBVV: return z3.BitVecVal(obj.value, obj.bits) elif isinstance(obj, FSort): return z3.FPSort(obj.exp, obj.mantissa) elif isinstance(obj, RM): if obj == RM_RNE: return z3.RNE() elif obj == RM_RNA: return z3.RNA() elif obj == RM_RTP: return z3.RTP() elif obj == RM_RTN: return z3.RTN() elif obj == RM_RTZ: return z3.RTZ() else: raise BackendError("unrecognized rounding mode") elif isinstance(obj, NativeFPV): val = str(obj.value) sort = self._convert(obj.sort) if val == 'inf': return z3.fpPlusInfinity(sort) elif val == '-inf': return z3.fpMinusInfinity(sort) elif val == '0.0': return z3.fpPlusZero(sort) elif val == '-0.0': return z3.fpMinusZero(sort) elif val == 'nan': return z3.fpNaN(sort) else: better_val = str(Decimal(obj.value)) return z3.FPVal(better_val, sort) elif obj is True: return z3.BoolVal(True) elif obj is False: return z3.BoolVal(False) elif type(obj) in (int, long, float, str): return obj elif hasattr(obj, '__module__') and obj.__module__ == 'z3': return obj else: l.debug("BackendZ3 encountered unexpected type %s", type(obj)) raise BackendError("unexpected type %s encountered in BackendZ3" % type(obj))
def _(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**tgt.frac - 1) << (w - tgt.frac) conds = [v >= -m, v <= m] else: conds = [] b = smt.fresh_bool() smt.add_qvar(b) sort = _ty_sort(tgt) return smt._conditional_conv_value( conds, z3.If(b, z3.fpToFP(z3.RTN(), v, sort), z3.fpToFP(z3.RTP(), v, sort)), term.name)
from .esilclasses import * import z3 z3.set_param('rewriter.hi_fp_unspecified', 'true') SIZE = 64 FSIZE = z3.Float64() FONE = z3.FPVal(1.0, FSIZE) FZERO = z3.FPVal(0.0, FSIZE) FNEGONE = z3.FPVal(-1.0, FSIZE) INT = 1 FLOAT = 2 FPM = z3.RTN() import logging logger = logging.getLogger("esilsolve") def pop_values(stack, state, num: int=1, signext=False) -> List[z3.BitVecRef]: size = state.esil["size"] val_type = state.esil["type"] return [ get_value(stack.pop(), state, signext, size, val_type) for i in range(num) ] def get_value(val, state, signext=False, size=SIZE, val_type=INT) \ -> z3.BitVecRef: if isinstance(val, str): val = state.registers[val]