def adj (seq): (x_stack, y_stack) = seq[stack_idx] xsub = dict ([(v, xv) for (v, (xv, _)) in azip (inps, seq)]) ysub = dict ([(v, yv) for (v, (_, yv)) in azip (inps, seq)]) from logic import var_subst stk_eqs = [(syntax.mk_memacc (x_stack, var_subst (p, xsub), t), syntax.mk_memacc (y_stack, var_subst (p, ysub), t)) for (p, t) in addrs] return seq[:stack_idx] + seq[stack_idx + 1:] + stk_eqs
def adj(seq): (x_stack, y_stack) = seq[stack_idx] xsub = dict([(v, xv) for (v, (xv, _)) in azip(inps, seq)]) ysub = dict([(v, yv) for (v, (_, yv)) in azip(inps, seq)]) from logic import var_subst stk_eqs = [(syntax.mk_memacc(x_stack, var_subst(p, xsub), t), syntax.mk_memacc(y_stack, var_subst(p, ysub), t)) for (p, t) in addrs] return seq[:stack_idx] + seq[stack_idx + 1:] + stk_eqs
def get_asm_calling_convention_at_node (node): cc = get_asm_calling_convention (node.fname) if not cc: return None fun = functions[node.fname] arg_input_map = dict (azip (fun.inputs, node.args)) ret_output_map = dict (azip (fun.outputs, [mk_var (nm, typ) for (nm, typ) in node.rets])) args = [logic.var_subst (arg, arg_input_map) for arg in cc['args']] rets = [logic.var_subst (ret, ret_output_map) for ret in cc['rets']] # these are useful because they happen to map ret r0_input back to # the previous value r0, rather than the useless value r0_input_ignore. rets_inp = [logic.var_subst (ret, arg_input_map) for ret in cc['rets']] saved = [logic.var_subst (v, ret_output_map) for v in cc['callee_saved']] return {'args': args, 'rets': rets, 'rets_inp': rets_inp, 'callee_saved': saved}
def adjust_ret_ptr (ptr): """this is a bit of a hack. the return slots are named based on r0_input, which will be unchanged, which is handy, but we really want to be talking about r0, which will produce meaningful offsets against the pointers actually used in the program.""" return logic.var_subst (ptr, {('r0_input', syntax.word32T): syntax.mk_var ('r0', syntax.word32T)}, must_subst = False)
def adjust_ret_ptr(ptr): """this is a bit of a hack. the return slots are named based on r0_input, which will be unchanged, which is handy, but we really want to be talking about r0, which will produce meaningful offsets against the pointers actually used in the program.""" return logic.var_subst(ptr, { ('ret_addr_input', syntax.word32T): syntax.mk_var('r0', syntax.word32T) }, must_subst=False)
def get_asm_calling_convention_at_node(node): cc = get_asm_calling_convention(node.fname) if not cc: return None fun = functions[node.fname] arg_input_map = dict(azip(fun.inputs, node.args)) ret_output_map = dict( azip(fun.outputs, [mk_var(nm, typ) for (nm, typ) in node.rets])) args = [logic.var_subst(arg, arg_input_map) for arg in cc['args']] rets = [logic.var_subst(ret, ret_output_map) for ret in cc['rets']] # these are useful because they happen to map ret r0_input back to # the previous value r0, rather than the useless value r0_input_ignore. rets_inp = [logic.var_subst(ret, arg_input_map) for ret in cc['rets']] saved = [logic.var_subst(v, ret_output_map) for v in cc['callee_saved']] return { 'args': args, 'rets': rets, 'rets_inp': rets_inp, 'callee_saved': saved }
def subst_induct (expr, induct_var): substs = {('%n', word32T): induct_var} return logic.var_subst (expr, substs, must_subst = False)
def pretty_lambda(t): v = syntax.mk_var('#seq-visits', word32T) t = logic.var_subst(t, {('%i', word32T): v}, must_subst=False) return syntax.pretty_expr(t, print_type=True)
def mksub(v): return lambda exp: logic.var_subst(exp, {('%i', word32T): v}, must_subst=False)
def mksub(v): return lambda exp: logic.var_subst(exp, {("%i", word32T): v}, must_subst=False)
def pretty_lambda (t): v = syntax.mk_var ('#seq-visits', word32T) t = logic.var_subst (t, {('%i', word32T) : v}, must_subst = False) return syntax.pretty_expr (t, print_type = True)