Skip to content

Commit

Permalink
Fix bugs related to 64-bit int conversion, fix intel#212 (intel#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkorbel1 authored and quekyj committed Jan 9, 2023
1 parent afbaec9 commit 95c133f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
2 changes: 1 addition & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ linter:
- avoid_function_literals_in_foreach_calls
- avoid_implementing_value_types
- avoid_init_to_null
- avoid_js_rounded_ints
# - avoid_js_rounded_ints
- avoid_multiple_declarations_per_line
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
Expand Down
24 changes: 22 additions & 2 deletions lib/src/values/big_logic_value.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@
part of values;

/// Extends [BigInt] with utility functions that are useful for dealing with
/// large bit vectors and conversion between types.
extension BigLogicValueBigIntUtilities on BigInt {
/// Returns this [BigInt] as an [int].
///
/// Always interprets the number as unsigned, and thus never clamps to fit.
int toIntUnsigned(int width) {
if (width > LogicValue._INT_BITS) {
throw Exception('Cannot convert to BigInt when width $width'
' is greater than ${LogicValue._INT_BITS}');
} else if (width == LogicValue._INT_BITS) {
// With `0x` in front of a hex literal, will be interpreted as unsigned.
return int.parse('0x${toRadixString(16)}');
} else {
return toInt();
}
}
}

/// A [LogicValue] whose number of bits is greater than the size of an [int].
///
/// The implementation is similar to [_SmallLogicValue], except it uses
Expand Down Expand Up @@ -64,8 +83,9 @@ class _BigLogicValue extends LogicValue {
(_invalid >> start) & _maskOfWidth(newWidth), newWidth);
} else {
return _SmallLogicValue(
((_value >> start) & _maskOfWidth(newWidth)).toInt(),
((_invalid >> start) & _maskOfWidth(newWidth)).toInt(),
((_value >> start) & _maskOfWidth(newWidth)).toIntUnsigned(newWidth),
((_invalid >> start) & _maskOfWidth(newWidth))
.toIntUnsigned(newWidth),
newWidth);
}
}
Expand Down
7 changes: 2 additions & 5 deletions lib/src/values/logic_value.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ abstract class LogicValue {
/// [width] must be greater than or equal to 0.
static LogicValue ofBigInt(BigInt value, int width) => width > _INT_BITS
? _BigLogicValue(value, BigInt.zero, width)
: _SmallLogicValue(value.toInt(), 0, width);
: _SmallLogicValue(value.toIntUnsigned(width), 0, width);

/// Converts `BigInt` [value] to a valid [LogicValue] with [width]
/// number of bits.
Expand Down Expand Up @@ -803,10 +803,7 @@ int _unsignedBinaryParse(String source) {
if (val != null) {
return val;
} else {
final hex = BigInt.parse(source, radix: 2).toRadixString(16);

// With `0x` in front of a hex literal, it will be interpreted as unsigned.
return int.parse('0x$hex');
return BigInt.parse(source, radix: 2).toIntUnsigned(source.length);
}
}

Expand Down
23 changes: 23 additions & 0 deletions test/logic_value_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -838,4 +838,27 @@ void main() {
equals(LogicValue.x));
});
});

group('64-bit conversions', () {
test(
'64-bit LogicValues larger than maximum positive value on integer'
' are properly converted when converted from BigInt', () {
final extraWide = LogicValue.ofBigInt(
BigInt.parse('f' * 16 + 'f0' * 8, radix: 16),
128,
);
final smaller = extraWide.getRange(0, 64);
expect(smaller.toInt(), equals(0xf0f0f0f0f0f0f0f0));
});
test(
'64-bit BigInts larger than max pos int value constructing'
' a LogicValue is correct', () {
final bigInt64Lv =
LogicValue.ofBigInt(BigInt.parse('fa' * 8, radix: 16), 64);
expect(bigInt64Lv.toInt(), equals(0xfafafafafafafafa));
});
test('64-bit binary negatives are converted properly with bin', () {
expect(bin('1110' * 16), equals(0xeeeeeeeeeeeeeeee));
});
});
}

0 comments on commit 95c133f

Please sign in to comment.