Skip to content

Commit eefb340

Browse files
author
kroening
committed
byte_extract_big_endian now works for non-constant offset
git-svn-id: svn+ssh://svn.cprover.org/srv/svn/cbmc/trunk@3907 6afb6bc1-c8e4-404c-8f48-9ae832c5b171
1 parent 4f4cdbb commit eefb340

File tree

1 file changed

+92
-72
lines changed

1 file changed

+92
-72
lines changed

src/solvers/flattening/boolbv_byte_extract.cpp

Lines changed: 92 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,31 @@ Author: Daniel Kroening, [email protected]
1717

1818
/*******************************************************************\
1919
20+
Function: map_bv
21+
22+
Inputs:
23+
24+
Outputs:
25+
26+
Purpose:
27+
28+
\*******************************************************************/
29+
30+
bvt map_bv(const endianness_mapt &map, const bvt &src)
31+
{
32+
assert(map.size()*8==src.size());
33+
34+
bvt result;
35+
result.resize(src.size(), const_literal(false));
36+
37+
for(unsigned i=0; i<src.size(); i++)
38+
result[i]=src[map.map_bit(i)];
39+
40+
return result;
41+
}
42+
43+
/*******************************************************************\
44+
2045
Function: boolbvt::convert_byte_extract
2146
2247
Inputs:
@@ -59,104 +84,99 @@ void boolbvt::convert_byte_extract(const exprt &expr, bvt &bv)
5984

6085
// first do op0
6186

62-
const bvt &op0_bv=convert_bv(op0);
63-
87+
endianness_mapt op0_map(op0.type(), little_endian, ns);
88+
const bvt op0_bv=map_bv(op0_map, convert_bv(op0));
89+
90+
// do result
91+
endianness_mapt result_map(expr.type(), little_endian, ns);
92+
bv.resize(width);
93+
6494
// see if the byte number is constant
95+
unsigned byte_width=8;
6596

6697
mp_integer index;
6798
if(!to_integer(op1, index))
6899
{
69-
bv.resize(width);
70-
71-
unsigned byte_width=8;
72100
mp_integer offset=index*byte_width;
73101

74-
endianness_mapt op0_map(op0.type(), little_endian, ns);
75-
endianness_mapt bv_map(expr.type(), little_endian, ns);
76-
77-
assert(width==byte_width*bv_map.size());
78-
79102
unsigned offset_i=integer2unsigned(offset);
80103

81104
for(unsigned i=0; i<width; i++)
82-
// out of bounds
105+
// out of bounds?
83106
if(offset<0 || offset_i+i>=op0_bv.size())
84107
bv[i]=prop.new_variable();
85108
else
86-
bv[bv_map.map_bit(i)]=
87-
op0_bv[op0_map.map_bit(offset_i+i)];
88-
89-
return;
109+
bv[i]=op0_bv[offset_i+i];
90110
}
91-
92-
unsigned byte_width=8;
93-
unsigned bytes=op0_bv.size()/byte_width;
94-
95-
if(prop.has_set_to())
111+
else
96112
{
97-
// free variables
98-
99-
bv.resize(width);
100-
for(unsigned i=0; i<width; i++)
101-
bv[i]=prop.new_variable();
113+
unsigned bytes=op0_bv.size()/byte_width;
114+
115+
if(prop.has_set_to())
116+
{
117+
// free variables
118+
for(unsigned i=0; i<width; i++)
119+
bv[i]=prop.new_variable();
102120

103-
// add implications
121+
// add implications
104122

105-
equal_exprt equality;
106-
equality.lhs()=op1; // index operand
123+
equal_exprt equality;
124+
equality.lhs()=op1; // index operand
107125

108-
typet constant_type=op1.type(); // type of index operand
126+
typet constant_type=op1.type(); // type of index operand
109127

110-
bvt equal_bv;
111-
equal_bv.resize(width);
128+
bvt equal_bv;
129+
equal_bv.resize(width);
112130

113-
for(unsigned i=0; i<bytes; i++)
114-
{
115-
equality.rhs()=from_integer(i, constant_type);
131+
for(unsigned i=0; i<bytes; i++)
132+
{
133+
equality.rhs()=from_integer(i, constant_type);
116134

117-
unsigned offset=i*byte_width;
135+
unsigned offset=i*byte_width;
118136

119-
for(unsigned j=0; j<width; j++)
120-
if(offset+j<op0_bv.size())
121-
equal_bv[j]=prop.lequal(bv[j], op0_bv[offset+j]);
122-
else
123-
equal_bv[j]=const_literal(true);
137+
for(unsigned j=0; j<width; j++)
138+
if(offset+j<op0_bv.size())
139+
equal_bv[j]=prop.lequal(bv[j], op0_bv[offset+j]);
140+
else
141+
equal_bv[j]=const_literal(true);
124142

125-
prop.l_set_to_true(
126-
prop.limplies(convert(equality), prop.land(equal_bv)));
143+
prop.l_set_to_true(
144+
prop.limplies(convert(equality), prop.land(equal_bv)));
145+
}
127146
}
128-
}
129-
else
130-
{
131-
bv.resize(width);
132-
133-
equal_exprt equality;
134-
equality.lhs()=op1; // index operand
135-
136-
typet constant_type(op1.type()); // type of index operand
137-
138-
for(unsigned i=0; i<bytes; i++)
147+
else
139148
{
140-
equality.rhs()=from_integer(i, constant_type);
141-
142-
literalt e=convert(equality);
143-
144-
unsigned offset=i*byte_width;
149+
equal_exprt equality;
150+
equality.lhs()=op1; // index operand
145151

146-
for(unsigned j=0; j<width; j++)
152+
typet constant_type(op1.type()); // type of index operand
153+
154+
for(unsigned i=0; i<bytes; i++)
147155
{
148-
literalt l;
149-
150-
if(offset+j<op0_bv.size())
151-
l=op0_bv[offset+j];
152-
else
153-
l=const_literal(false);
154-
155-
if(i==0)
156-
bv[j]=l;
157-
else
158-
bv[j]=prop.lselect(e, l, bv[j]);
159-
}
160-
}
156+
equality.rhs()=from_integer(i, constant_type);
157+
158+
literalt e=convert(equality);
159+
160+
unsigned offset=i*byte_width;
161+
162+
for(unsigned j=0; j<width; j++)
163+
{
164+
literalt l;
165+
166+
if(offset+j<op0_bv.size())
167+
l=op0_bv[offset+j];
168+
else
169+
l=const_literal(false);
170+
171+
if(i==0)
172+
bv[j]=l;
173+
else
174+
bv[j]=prop.lselect(e, l, bv[j]);
175+
}
176+
}
177+
}
161178
}
179+
180+
// shuffle the result
181+
bv=map_bv(result_map, bv);
162182
}

0 commit comments

Comments
 (0)