def stack_virtualise_expr (expr, sp_offs): if expr.is_op ('MemAcc') and is_stack (expr.vals[0]): [m, p] = expr.vals if expr.typ == syntax.word8T: ps = [(syntax.mk_minus (p, syntax.mk_word32 (n)), n) for n in [0, 1, 2, 3]] elif expr.typ == syntax.word32T: ps = [(p, 0)] else: assert expr.typ == syntax.word32T, expr ptrs = [(p, 'MemAcc') for (p, _) in ps] if sp_offs == None: return (ptrs, None) # FIXME: very 32-bit specific ps = [(p, n) for (p, n) in ps if p in sp_offs if sp_offs[p][1] % 4 == 0] if not ps: return (ptrs, expr) [(p, n)] = ps (k, offs) = sp_offs[p] v = mk_var (('Fake', k, offs), syntax.word32T) if n != 0: v = syntax.mk_shiftr (v, n * 8) v = syntax.mk_cast (v, expr.typ) return (ptrs, v) elif expr.kind == 'Op': vs = [stack_virtualise_expr (v, sp_offs) for v in expr.vals] return ([p for (ptrs, _) in vs for p in ptrs], syntax.Expr ('Op', expr.typ, name = expr.name, vals = [v for (_, v) in vs])) else: return ([], expr)
def stack_virtualise_expr(expr, sp_offs): if expr.is_op('MemAcc') and is_stack(expr.vals[0]): [m, p] = expr.vals if expr.typ == syntax.word8T: ps = [(syntax.mk_minus(p, syntax.mk_word32(n)), n) for n in [0, 1, 2, 3]] elif expr.typ == syntax.word32T: ps = [(p, 0)] else: assert expr.typ == syntax.word32T, expr ptrs = [(p, 'MemAcc') for (p, _) in ps] if sp_offs == None: return (ptrs, None) # FIXME: very 32-bit specific ps = [(p, n) for (p, n) in ps if p in sp_offs if sp_offs[p][1] % 4 == 0] if not ps: return (ptrs, expr) [(p, n)] = ps if p not in sp_offs: raise StackOffsMissing() (k, offs) = sp_offs[p] v = mk_var(('Fake', k, offs), syntax.word32T) if n != 0: v = syntax.mk_shiftr(v, n * 8) v = syntax.mk_cast(v, expr.typ) return (ptrs, v) elif expr.kind == 'Op': vs = [stack_virtualise_expr(v, sp_offs) for v in expr.vals] return ([p for (ptrs, _) in vs for p in ptrs], syntax.adjust_op_vals(expr, [v for (_, v) in vs])) else: return ([], expr)
def v_eqs_to_split (p, pair, v_eqs, restrs, hyps, tags = None): trace ('v_eqs_to_split: (%s, %s)' % pair) ((l_n, l_init, l_step), (r_n, r_init, r_step)) = pair l_details = (l_n, (l_init, l_step), mk_seq_eqs (p, l_n, l_step, True) + [v_i[0] for (v_i, v_j) in v_eqs if v_j == 'Const']) r_details = (r_n, (r_init, r_step), mk_seq_eqs (p, r_n, r_step, False) + c_memory_loop_invariant (p, r_n, l_n)) eqs = [(v_i[0], mk_cast (v_j[0], v_i[0].typ)) for (v_i, v_j) in v_eqs if v_j != 'Const'] n = 2 split = (l_details, r_details, eqs, n, (n * r_step) - 1) trace ('Split: %s' % (split, )) if tags == None: tags = p.pairing.tags hyps = hyps + check.split_loop_hyps (tags, split, restrs, exit = True) r_max = find_split_limit (p, r_n, restrs, hyps, 'Offset', bound = (n + 2) * r_step, must_find = False, hints = [n * r_step, n * r_step + 1]) if r_max == None: trace ('v_eqs_to_split: no RHS limit') return None if r_max > n * r_step: trace ('v_eqs_to_split: RHS limit not %d' % (n * r_step)) return None trace ('v_eqs_to_split: split %s' % (split,)) return split