Skip to content

Commit 898660b

Browse files
committed
SMV: convert typecasts to SMV
This adds conversion for a variety of typecast expressions into SMV syntax.
1 parent 59b4d9a commit 898660b

File tree

3 files changed

+117
-4
lines changed

3 files changed

+117
-4
lines changed

regression/ebmc/smv-word-level/verilog1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ verilog1.sv
66
^INIT main\.x = 0ud32_0$
77
^INVAR Verilog::main\.x_aux0 = main\.x \+ 0ud32_1$
88
^TRANS next\(main\.x\) = Verilog::main\.x_aux0$
9-
^LTLSPEC F main\.x = 0sd32_10$
9+
^LTLSPEC F main\.x = unsigned\(0sd32_10\)$
1010
^EXIT=0$
1111
^SIGNAL=0$
1212
--

src/smvlang/expr2smv.cpp

Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Author: Daniel Kroening, [email protected]
99
#include "expr2smv.h"
1010
#include "expr2smv_class.h"
1111

12+
#include <util/mathematical_types.h>
13+
14+
#include "smv_expr.h"
15+
1216
/*******************************************************************\
1317
1418
Function: expr2smvt::convert_nondet_choice
@@ -221,6 +225,115 @@ expr2smvt::resultt expr2smvt::convert_function_application(
221225

222226
/*******************************************************************\
223227
228+
Function: expr2smvt::convert_typecast
229+
230+
Inputs:
231+
232+
Outputs:
233+
234+
Purpose:
235+
236+
\*******************************************************************/
237+
238+
expr2smvt::resultt expr2smvt::convert_typecast(const typecast_exprt &expr)
239+
{
240+
// typecasts can repesent a variety of functions
241+
auto &src_type = expr.op().type();
242+
auto &dest_type = expr.type();
243+
244+
if(src_type.id() == ID_unsignedbv && dest_type.id() == ID_signedbv)
245+
{
246+
// unsigned to signed
247+
auto src_width = to_unsignedbv_type(src_type).get_width();
248+
auto dest_width = to_signedbv_type(dest_type).get_width();
249+
250+
if(src_width == dest_width)
251+
{
252+
// signess change only
253+
return convert_rec(smv_signed_cast_exprt{expr.op(), dest_type});
254+
}
255+
else if(dest_width > src_width)
256+
{
257+
// Signedness _and_ width change. First go to signed, then extend.
258+
return convert_rec(smv_extend_exprt{
259+
smv_signed_cast_exprt{expr.op(), signedbv_typet{src_width}},
260+
dest_width - src_width,
261+
dest_type});
262+
}
263+
else
264+
{
265+
// First shrink, then go signed.
266+
return convert_rec(smv_signed_cast_exprt{
267+
smv_resize_exprt{expr.op(), dest_width, unsignedbv_typet{dest_width}},
268+
dest_type});
269+
}
270+
}
271+
else if(src_type.id() == ID_signedbv && dest_type.id() == ID_unsignedbv)
272+
{
273+
// signed to unsigned
274+
auto src_width = to_signedbv_type(src_type).get_width();
275+
auto dest_width = to_unsignedbv_type(dest_type).get_width();
276+
277+
if(
278+
to_signedbv_type(src_type).get_width() ==
279+
to_unsignedbv_type(dest_type).get_width())
280+
{
281+
// signess change only
282+
return convert_rec(smv_unsigned_cast_exprt{expr.op(), dest_type});
283+
}
284+
else if(dest_width > src_width)
285+
{
286+
// Signedness _and_ width change.
287+
// First enlarge, then go unsigned.
288+
return convert_rec(smv_unsigned_cast_exprt{
289+
smv_extend_exprt{
290+
expr.op(), dest_width - src_width, signedbv_typet{dest_width}},
291+
dest_type});
292+
}
293+
else
294+
{
295+
// First go unsigned, then shrink
296+
return convert_rec(smv_resize_exprt{
297+
smv_unsigned_cast_exprt{expr.op(), unsignedbv_typet{src_width}},
298+
dest_width,
299+
dest_type});
300+
}
301+
}
302+
else if(src_type.id() == ID_signedbv && dest_type.id() == ID_signedbv)
303+
{
304+
// signed to signed, width change.
305+
// Note that resize(...) preserves the sign bit, unlike our typecast.
306+
auto src_width = to_signedbv_type(src_type).get_width();
307+
auto dest_width = to_signedbv_type(dest_type).get_width();
308+
if(dest_width > src_width)
309+
{
310+
return convert_rec(
311+
smv_extend_exprt{expr.op(), dest_width - src_width, dest_type});
312+
}
313+
else
314+
return convert_norep(expr);
315+
}
316+
else if(src_type.id() == ID_unsignedbv && dest_type.id() == ID_unsignedbv)
317+
{
318+
// Unsigned to unsigned, width change. Use extend when enlarging.
319+
auto src_width = to_unsignedbv_type(src_type).get_width();
320+
auto dest_width = to_unsignedbv_type(dest_type).get_width();
321+
if(dest_width > src_width)
322+
{
323+
return convert_rec(
324+
smv_extend_exprt{expr.op(), dest_width - src_width, dest_type});
325+
}
326+
else
327+
{
328+
return convert_rec(smv_resize_exprt{expr.op(), dest_width, dest_type});
329+
}
330+
}
331+
else
332+
return convert_norep(expr);
333+
}
334+
335+
/*******************************************************************\
336+
224337
Function: expr2smvt::convert_rtctl
225338
226339
Inputs:
@@ -713,9 +826,7 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
713826
return convert_function_application("unsigned", src);
714827

715828
else if(src.id() == ID_typecast)
716-
{
717-
return convert_rec(to_typecast_expr(src).op());
718-
}
829+
return convert_typecast(to_typecast_expr(src));
719830

720831
else // no SMV language expression for internal representation
721832
return convert_norep(src);

src/smvlang/expr2smv_class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ class expr2smvt
126126
resultt
127127
convert_function_application(const std::string &symbol, const exprt &);
128128

129+
resultt convert_typecast(const typecast_exprt &);
130+
129131
resultt convert_norep(const exprt &);
130132
};
131133

0 commit comments

Comments
 (0)