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)
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 _op_raw_fpToFP(self, a1, a2=None, a3=None): # TODO: lots of mandatory checks are performed by the high level API here. we shouldn't use low level APIs here return z3.fpToFP(a1, a2=a2, a3=a3, ctx=self._context)
def _sitofp(term, smt): x = smt.eval(term._args[0]) tgt = smt.type(term) return z3.fpToFP(z3.RTZ(), x, _ty_sort(tgt))
def _(term, smt): v = smt.eval(term._args[0]) return z3.fpToFP(z3.RNE(), v, _ty_sort(smt.type(term)))
def _(src, tgt, v): return z3.fpToFP(v, _ty_sort(tgt))
eval.register(TruncInst, BaseSMTTranslator, _convert( lambda s,t,v: z3.Extract(t.width-1, 0, v))) eval.register(ZExtOrTruncInst, BaseSMTTranslator, _convert( lambda s,t,v: zext_or_trunc(v, s.width, t.width))) # FIXME: don't assume 64-bit pointers eval.register(PtrtointInst, BaseSMTTranslator, _convert( lambda s,t,v: zext_or_trunc(v, 64, t.width))) eval.register(InttoptrInst, BaseSMTTranslator, _convert( lambda s,t,v: zext_or_trunc(v, s.width, 64))) eval.register(FPExtInst, BaseSMTTranslator, _convert( lambda s,t,v: z3.fpToFP(z3.get_default_rounding_mode(), v, _ty_sort(t)))) @eval.register(FPTruncInst, BaseSMTTranslator) 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) @eval.register(FPtoSIInst, BaseSMTTranslator)
def _op_raw_fpToFP(self, a1, a2=None, a3=None): return z3.fpToFP(a1, a2=a2, a3=a3, ctx=self._context)