/*++ Copyright (c) 2006 Microsoft Corporation Module Name: bit_blaster_tpl.h Abstract: Template for bit-blaster operations Author: Leonardo de Moura (leonardo) 2011-05-02. Revision History: --*/ #pragma once #include "util/rational.h" template class bit_blaster_tpl : public Cfg { public: typedef rational numeral; protected: template void mk_le(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); template void mk_sdiv_srem_smod(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); template void mk_ext_rotate_left_right(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); unsigned long long m_max_memory; bool m_use_wtm; /* Wallace Tree Multiplier */ bool m_use_bcm; /* Booth Multiplier for constants */ void checkpoint(); public: bit_blaster_tpl(Cfg const & cfg = Cfg(), unsigned long long max_memory = UINT64_MAX, bool use_wtm = false, bool use_bcm=false): Cfg(cfg), m_max_memory(max_memory), m_use_wtm(use_wtm), m_use_bcm(use_bcm) { } void set_max_memory(unsigned long long max_memory) { m_max_memory = max_memory; } // Cfg required API ast_manager & m() const { return Cfg::m(); } numeral power(unsigned n) const { return Cfg::power(n); } void mk_xor(expr * a, expr * b, expr_ref & r) { Cfg::mk_xor(a, b, r); } void mk_xor3(expr * a, expr * b, expr * c, expr_ref & r) { Cfg::mk_xor3(a, b, c, r); } void mk_carry(expr * a, expr * b, expr * c, expr_ref & r) { Cfg::mk_carry(a, b, c, r); } void mk_iff(expr * a, expr * b, expr_ref & r) { Cfg::mk_iff(a, b, r); } void mk_and(expr * a, expr * b, expr_ref & r) { Cfg::mk_and(a, b, r); } void mk_and(expr * a, expr * b, expr * c, expr_ref & r) { Cfg::mk_and(a, b, c, r); } void mk_and(unsigned sz, expr * const * args, expr_ref & r) { Cfg::mk_and(sz, args, r); } void mk_or(expr * a, expr * b, expr_ref & r) { Cfg::mk_or(a, b, r); } void mk_or(expr * a, expr * b, expr * c, expr_ref & r) { Cfg::mk_or(a, b, c, r); } void mk_or(unsigned sz, expr * const * args, expr_ref & r) { Cfg::mk_or(sz, args, r); } void mk_not(expr * a, expr_ref & r) { Cfg::mk_not(a, r); } void mk_ite(expr * c, expr * t, expr * e, expr_ref & r) { Cfg::mk_ite(c, t, e, r); } void mk_nand(expr * a, expr * b, expr_ref & r) { Cfg::mk_nand(a, b, r); } void mk_nor(expr * a, expr * b, expr_ref & r) { Cfg::mk_nor(a, b, r); } void mk_ge2(expr* a, expr* b, expr* c, expr_ref& r) { Cfg::mk_ge2(a, b, c, r); } // bool is_numeral(unsigned sz, expr * const * bits) const; bool is_numeral(unsigned sz, expr * const * bits, numeral & r) const; bool is_minus_one(unsigned sz, expr * const * bits) const; void num2bits(numeral const & v, unsigned sz, expr_ref_vector & out_bits) const; void mk_half_adder(expr * a, expr * b, expr_ref & out, expr_ref & cout); void mk_full_adder(expr * a, expr * b, expr * cin, expr_ref & out, expr_ref & cout); void mk_neg(unsigned sz, expr * const * a_bits, expr_ref_vector & out_bits); void mk_adder(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_subtracter(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits, expr_ref & cout); void mk_multiplier(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_udiv_urem(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & q_bits, expr_ref_vector & r_bits); void mk_udiv(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & q_bits); void mk_urem(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & r_bits); void mk_multiplexer(expr * c, unsigned sz, expr * const * t_bits, expr * const * e_bits, expr_ref_vector & out_bits); void mk_sdiv(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_srem(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_smod(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_rotate_left(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits); void mk_rotate_right(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits); void mk_ext_rotate_left(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_ext_rotate_right(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_sign_extend(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits); void mk_zero_extend(unsigned sz, expr * const * a_bits, unsigned n, expr_ref_vector & out_bits); void mk_eq(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); void mk_is_eq(unsigned sz, expr * const * a_bits, unsigned n, expr_ref & out); void mk_eqs(unsigned sz, expr * const * a_bits, expr_ref_vector & eqs); void mk_shl(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_lshr(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_ashr(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_sle(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); void mk_ule(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); void mk_not(unsigned sz, expr * const * a_bits, expr_ref_vector & out_bits); void mk_and(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_or(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_xor(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_xnor(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_nand(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_nor(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_redand(unsigned sz, expr * const * a_bits, expr_ref_vector & out_bits); void mk_redor(unsigned sz, expr * const * a_bits, expr_ref_vector & out_bits); void mk_umul_no_overflow(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); void mk_smul_no_overflow_core(unsigned sz, expr * const * a_bits, expr * const * b_bits, bool is_overflow, expr_ref & result); void mk_smul_no_overflow(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); void mk_smul_no_underflow(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out); void mk_comp(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_carry_save_adder(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr * const * c_bits, expr_ref_vector & sum_bits, expr_ref_vector & carry_bits); bool mk_const_multiplier(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); bool mk_const_case_multiplier(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref_vector & out_bits); void mk_const_case_multiplier(bool is_a, unsigned i, unsigned sz, ptr_buffer& a_bits, ptr_buffer& b_bits, expr_ref_vector & out_bits); bool is_bool_const(expr* e) const { return m().is_true(e) || m().is_false(e); } void mk_abs(unsigned sz, expr * const * a_bits, expr_ref_vector & out_bits); };