|
29 | 29 | #include <util/string_constant.h>
|
30 | 30 |
|
31 | 31 | #include <solvers/flattening/boolbv_width.h>
|
32 |
| -#include <solvers/flattening/flatten_byte_operators.h> |
33 | 32 | #include <solvers/flattening/c_bit_field_replacement_type.h>
|
| 33 | +#include <solvers/flattening/flatten_byte_operators.h> |
34 | 34 | #include <solvers/floatbv/float_bv.h>
|
| 35 | +#include <solvers/lowering/expr_lowering.h> |
35 | 36 |
|
36 | 37 | // Mark different kinds of error condition
|
37 | 38 | // General
|
@@ -1809,6 +1810,68 @@ void smt2_convt::convert_expr(const exprt &expr)
|
1809 | 1810 | "smt2_convt::convert_expr: `"+expr.id_string()+
|
1810 | 1811 | "' is not yet supported");
|
1811 | 1812 | }
|
| 1813 | + else if(expr.id() == ID_bswap) |
| 1814 | + { |
| 1815 | + if(expr.operands().size() != 1) |
| 1816 | + INVALIDEXPR("bswap gets one operand"); |
| 1817 | + |
| 1818 | + if(expr.op0().type() != expr.type()) |
| 1819 | + INVALIDEXPR("bswap gets one operand with same type"); |
| 1820 | + |
| 1821 | + // first 'let' the operand |
| 1822 | + out << "(let ((bswap_op "; |
| 1823 | + convert_expr(expr.op0()); |
| 1824 | + out << ")) "; |
| 1825 | + |
| 1826 | + if(expr.type().id() == ID_signedbv || expr.type().id() == ID_unsignedbv) |
| 1827 | + { |
| 1828 | + const std::size_t width = to_bitvector_type(expr.type()).get_width(); |
| 1829 | + |
| 1830 | + // width must be multiple of bytes |
| 1831 | + if(width % 8 != 0) |
| 1832 | + INVALIDEXPR("bswap must get bytes"); |
| 1833 | + |
| 1834 | + const std::size_t bytes = width / 8; |
| 1835 | + |
| 1836 | + if(bytes <= 1) |
| 1837 | + out << "bswap_op"; |
| 1838 | + else |
| 1839 | + { |
| 1840 | + // do a parallel 'let' for each byte |
| 1841 | + out << "(let ("; |
| 1842 | + |
| 1843 | + for(std::size_t byte = 0; byte < bytes; byte++) |
| 1844 | + { |
| 1845 | + if(byte != 0) |
| 1846 | + out << ' '; |
| 1847 | + out << "(bswap_byte_" << byte << ' '; |
| 1848 | + out << "((_ extract " << (byte * 8 + 7) << " " << (byte * 8) |
| 1849 | + << ") bswap_op)"; |
| 1850 | + out << ')'; |
| 1851 | + } |
| 1852 | + |
| 1853 | + out << ") "; |
| 1854 | + |
| 1855 | + // now stitch back together with 'concat' |
| 1856 | + out << "(concat"; |
| 1857 | + |
| 1858 | + for(std::size_t byte = 0; byte < bytes; byte++) |
| 1859 | + out << " bswap_byte_" << byte; |
| 1860 | + |
| 1861 | + out << ')'; // concat |
| 1862 | + out << ')'; // let bswap_byte_* |
| 1863 | + } |
| 1864 | + } |
| 1865 | + else |
| 1866 | + UNEXPECTEDCASE("bswap must get bitvector operand"); |
| 1867 | + |
| 1868 | + out << ')'; // let bswap_op |
| 1869 | + } |
| 1870 | + else if(expr.id() == ID_popcount) |
| 1871 | + { |
| 1872 | + exprt lowered = lower_popcount(to_popcount_expr(expr), ns); |
| 1873 | + convert_expr(lowered); |
| 1874 | + } |
1812 | 1875 | else
|
1813 | 1876 | UNEXPECTEDCASE(
|
1814 | 1877 | "smt2_convt::convert_expr: `"+expr.id_string()+"' is unsupported");
|
|
0 commit comments