@@ -289,36 +289,14 @@ bool get_bvrep_bit(
289
289
{
290
290
PRECONDITION (bit_index < width);
291
291
292
- // The representation is hex, i.e., four bits per letter,
293
- // most significant nibble first, using uppercase letters.
294
- // No lowercase, no leading zeros (other than for 'zero'),
295
- // to ensure canonicity.
296
- const auto nibble_index = bit_index / 4 ;
292
+ const auto byte_index = bit_index >> 3 ;
297
293
298
- if (nibble_index >= src.size ())
294
+ if (byte_index >= src.size ())
299
295
return false ;
300
296
301
- const char nibble = src[src.size () - 1 - nibble_index ];
297
+ unsigned char byte = src[src.size () - 1 - byte_index ];
302
298
303
- DATA_INVARIANT (
304
- isdigit (nibble) || (nibble >= ' A' && nibble <= ' F' ),
305
- " bvrep is hexadecimal, upper-case" );
306
-
307
- const unsigned char nibble_value =
308
- isdigit (nibble) ? nibble - ' 0' : nibble - ' A' + 10 ;
309
-
310
- return ((nibble_value >> (bit_index % 4 )) & 1 ) != 0 ;
311
- }
312
-
313
- // / turn a value 0...15 into '0'-'9', 'A'-'Z'
314
- static char nibble2hex (unsigned char nibble)
315
- {
316
- PRECONDITION (nibble <= 0xf );
317
-
318
- if (nibble >= 10 )
319
- return ' A' + nibble - 10 ;
320
- else
321
- return ' 0' + nibble;
299
+ return ((byte >> (bit_index & 7 )) & 1 ) != 0 ;
322
300
}
323
301
324
302
// / construct a bit-vector representation from a functor
@@ -329,38 +307,32 @@ irep_idt
329
307
make_bvrep (const std::size_t width, const std::function<bool (std::size_t )> f)
330
308
{
331
309
std::string result;
332
- result.reserve (( width + 3 ) / 4 );
333
- unsigned char nibble = 0 ;
310
+ result.reserve (width / 8 + 1 );
311
+ unsigned byte = 0 ;
334
312
335
313
for (std::size_t i = 0 ; i < width; i++)
336
314
{
337
- const auto bit_in_nibble = i % 4 ;
315
+ const auto bit_in_byte = i % 8 ;
338
316
339
- nibble |= ((unsigned char )f (i)) << bit_in_nibble ;
317
+ byte |= ((unsigned )f (i)) << bit_in_byte ;
340
318
341
- if (bit_in_nibble == 3 )
319
+ if (bit_in_byte == 7 )
342
320
{
343
- result += nibble2hex (nibble) ;
344
- nibble = 0 ;
321
+ result += ( char )byte ;
322
+ byte = 0 ;
345
323
}
346
324
}
347
325
348
- if (nibble != 0 )
349
- result += nibble2hex (nibble) ;
326
+ if (byte != 0 )
327
+ result += ( char )byte ;
350
328
351
329
// drop leading zeros
352
- const std::size_t pos = result.find_last_not_of (' 0' );
353
-
354
- if (pos == std::string::npos)
355
- return ID_0;
356
- else
357
- {
358
- result.resize (pos + 1 );
330
+ while (!result.empty () && result.back () == 0 )
331
+ result.resize (result.size () - 1 );
359
332
360
- std::reverse (result.begin (), result.end ());
333
+ std::reverse (result.begin (), result.end ());
361
334
362
- return result;
363
- }
335
+ return result;
364
336
}
365
337
366
338
// / perform a binary bit-wise operation, given as a functor,
@@ -397,6 +369,19 @@ irep_idt bvrep_bitwise_op(
397
369
});
398
370
}
399
371
372
+ std::string dump_integer (mp_integer src)
373
+ {
374
+ std::size_t d = src.digits (256 ) + 1 ;
375
+ unsigned char *buf = new unsigned char [d], *p = buf;
376
+ src.dump (buf, d);
377
+ while (d > 0 && *p == 0 )
378
+ {
379
+ d--;
380
+ p++;
381
+ }
382
+ return std::string ((char *)p, d);
383
+ }
384
+
400
385
// / convert an integer to bit-vector representation with given width
401
386
// / This uses two's complement for negative numbers.
402
387
// / If the value is out of range, it is 'wrapped around'.
@@ -412,22 +397,24 @@ irep_idt integer2bvrep(const mp_integer &src, std::size_t width)
412
397
tmp %= p;
413
398
if (tmp != 0 )
414
399
tmp = p - tmp;
415
- return integer2string (tmp, 16 );
400
+ return dump_integer (tmp);
416
401
}
417
402
else
418
403
{
419
404
// we 'wrap around' if 'src' is too large
420
- return integer2string (src % p, 16 );
405
+ return dump_integer (src % p);
421
406
}
422
407
}
423
408
424
409
// / convert a bit-vector representation (possibly signed) to integer
425
410
mp_integer bvrep2integer (const irep_idt &src, std::size_t width, bool is_signed)
426
411
{
412
+ mp_integer tmp;
413
+ tmp.load ((const unsigned char *)id2string (src).data (), src.size ());
414
+
427
415
if (is_signed)
428
416
{
429
417
PRECONDITION (width >= 1 );
430
- const auto tmp = string2integer (id2string (src), 16 );
431
418
const auto p = power (2 , width - 1 );
432
419
if (tmp >= p)
433
420
{
@@ -440,8 +427,7 @@ mp_integer bvrep2integer(const irep_idt &src, std::size_t width, bool is_signed)
440
427
}
441
428
else
442
429
{
443
- const auto result = string2integer (id2string (src), 16 );
444
- PRECONDITION (result < power (2 , width));
445
- return result;
430
+ PRECONDITION (tmp < power (2 , width));
431
+ return tmp;
446
432
}
447
433
}
0 commit comments