Skip to content

Commit 05bc9ed

Browse files
committed
Implement bswap in SAT back-end
Previously only constants were supported via expression simplification.
1 parent 4f37035 commit 05bc9ed

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed

regression/cbmc/gcc_bswap1/main.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
4+
#ifndef __GNUC__
5+
uint16_t __builtin_bswap16(uint16_t);
6+
uint32_t __builtin_bswap32(uint32_t);
7+
uint64_t __builtin_bswap64(uint64_t);
8+
#endif
9+
10+
uint16_t __VERIFIER_nondet_u16();
11+
uint32_t __VERIFIER_nondet_u32();
12+
uint64_t __VERIFIER_nondet_u64();
13+
14+
int main()
15+
{
16+
uint16_t sa = 0xabcd;
17+
assert(__builtin_bswap16(sa) == 0xcdab);
18+
uint16_t sb = __VERIFIER_nondet_u16();
19+
sb &= 0xff00;
20+
// expected to fail, only MSB guaranteed to be 0
21+
assert(__builtin_bswap16(sb) == 0);
22+
assert((__builtin_bswap16(sb) & 0xff00) == 0);
23+
24+
uint32_t a = 0xabcdef00;
25+
assert(__builtin_bswap32(a) == 0x00efcdab);
26+
uint32_t b = __VERIFIER_nondet_u32();
27+
b &= 0xffffff00;
28+
// expected to fail, only MSB guaranteed to be 0
29+
assert(__builtin_bswap32(b) == 0);
30+
assert((__builtin_bswap32(b) & 0xff000000) == 0);
31+
32+
uint64_t al = 0xabcdef0001020304LL;
33+
assert(__builtin_bswap64(al) == 0x0403020100efcdabLL);
34+
uint64_t bl = __VERIFIER_nondet_u64();
35+
bl &= 0xffffffffffffff00LL;
36+
// expected to fail, only MSB guaranteed to be 0
37+
assert(__builtin_bswap64(bl) == 0);
38+
assert((__builtin_bswap64(bl) & 0xff00000000000000) == 0);
39+
40+
return 0;
41+
}

regression/cbmc/gcc_bswap1/test.desc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
\[main\.assertion\.[258]\] assertion __builtin_bswap(16|32|64)\((sb|b|bl)\) == 0: FAILURE$
8+
^\*\* 3 of 9 failed
9+
--
10+
^warning: ignoring
11+
\[main\.assertion\.[258]\] assertion __builtin_bswap(16|32|64)\((sb|b|bl)\) == 0: SUCCESS$

src/solvers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ SRC = $(BOOLEFORCE_SRC) \
106106
flattening/boolbv_array.cpp \
107107
flattening/boolbv_array_of.cpp \
108108
flattening/boolbv_bitwise.cpp \
109+
flattening/boolbv_bswap.cpp \
109110
flattening/boolbv_bv_rel.cpp \
110111
flattening/boolbv_byte_extract.cpp \
111112
flattening/boolbv_byte_update.cpp \

src/solvers/flattening/boolbv.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
245245
}
246246
else if(expr.id()==ID_abs)
247247
return convert_abs(expr);
248+
else if(expr.id() == ID_bswap)
249+
return convert_bswap(to_bswap_expr(expr));
248250
else if(expr.id()==ID_byte_extract_little_endian ||
249251
expr.id()==ID_byte_extract_big_endian)
250252
return convert_byte_extract(to_byte_extract_expr(expr));

src/solvers/flattening/boolbv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class boolbvt:public arrayst
133133

134134
virtual bvt convert_index(const exprt &array, const mp_integer &index);
135135
virtual bvt convert_index(const index_exprt &expr);
136+
virtual bvt convert_bswap(const bswap_exprt &expr);
136137
virtual bvt convert_byte_extract(const byte_extract_exprt &expr);
137138
virtual bvt convert_byte_update(const byte_update_exprt &expr);
138139
virtual bvt convert_constraint_select_one(const exprt &expr);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*******************************************************************\
2+
3+
Module: Bit-blasting of bswap
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
#include "boolbv.h"
10+
11+
#include <util/config.h>
12+
#include <util/invariant.h>
13+
14+
bvt boolbvt::convert_bswap(const bswap_exprt &expr)
15+
{
16+
const std::size_t width = boolbv_width(expr.type());
17+
18+
// width must be multiple of bytes
19+
const std::size_t byte_bits = config.ansi_c.char_width;
20+
if(width % byte_bits != 0)
21+
return conversion_failed(expr);
22+
23+
bvt result = convert_bv(expr.op());
24+
CHECK_RETURN(result.size() == width);
25+
26+
std::size_t dest_base = width;
27+
28+
for(std::size_t src = 0; src < width; ++src)
29+
{
30+
std::size_t bit_offset = src % byte_bits;
31+
if(bit_offset == 0)
32+
dest_base -= byte_bits;
33+
34+
if(src >= dest_base)
35+
break;
36+
37+
result[src].swap(result[dest_base + bit_offset]);
38+
}
39+
40+
return result;
41+
}

0 commit comments

Comments
 (0)