@@ -9,6 +9,10 @@ Author: Daniel Kroening, kroening@kroening.com
9
9
#include " expr2smv.h"
10
10
#include " expr2smv_class.h"
11
11
12
+ #include < util/mathematical_types.h>
13
+
14
+ #include " smv_expr.h"
15
+
12
16
/* ******************************************************************\
13
17
14
18
Function: expr2smvt::convert_nondet_choice
@@ -221,6 +225,124 @@ expr2smvt::resultt expr2smvt::convert_function_application(
221
225
222
226
/* ******************************************************************\
223
227
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
+ // signedness 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
+ // signedness 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
+ auto src_width = to_signedbv_type (src_type).get_width ();
306
+ auto dest_width = to_signedbv_type (dest_type).get_width ();
307
+ if (dest_width > src_width)
308
+ {
309
+ // enlarge using extend
310
+ return convert_rec (
311
+ smv_extend_exprt{expr.op (), dest_width - src_width, dest_type});
312
+ }
313
+ else
314
+ {
315
+ // Note that SMV's resize(...) preserves the sign bit, unlike our typecast.
316
+ // We therefore first go unsigned, then resize, then go signed again.
317
+ return convert_rec (smv_signed_cast_exprt{
318
+ smv_resize_exprt{
319
+ smv_unsigned_cast_exprt{expr.op (), unsignedbv_typet{src_width}},
320
+ dest_width,
321
+ unsignedbv_typet{dest_width}},
322
+ dest_type});
323
+ }
324
+ }
325
+ else if (src_type.id () == ID_unsignedbv && dest_type.id () == ID_unsignedbv)
326
+ {
327
+ // Unsigned to unsigned, width change. Use extend when enlarging.
328
+ auto src_width = to_unsignedbv_type (src_type).get_width ();
329
+ auto dest_width = to_unsignedbv_type (dest_type).get_width ();
330
+ if (dest_width > src_width)
331
+ {
332
+ return convert_rec (
333
+ smv_extend_exprt{expr.op (), dest_width - src_width, dest_type});
334
+ }
335
+ else
336
+ {
337
+ return convert_rec (smv_resize_exprt{expr.op (), dest_width, dest_type});
338
+ }
339
+ }
340
+ else
341
+ return convert_norep (expr);
342
+ }
343
+
344
+ /* ******************************************************************\
345
+
224
346
Function: expr2smvt::convert_rtctl
225
347
226
348
Inputs:
@@ -714,7 +836,7 @@ expr2smvt::resultt expr2smvt::convert_rec(const exprt &src)
714
836
715
837
else if (src.id () == ID_typecast)
716
838
{
717
- return convert_rec (to_typecast_expr (src). op ( ));
839
+ return convert_typecast (to_typecast_expr (src));
718
840
}
719
841
720
842
else // no SMV language expression for internal representation
0 commit comments