-
Notifications
You must be signed in to change notification settings - Fork 42
[test] Add spec tests for integer min/max ops #163
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| #!/usr/bin/env python3 | ||
|
|
||
| """Common integer value operations""" | ||
|
|
||
| from simd_lane_value import LaneValue | ||
|
|
||
| class IntegerSimpleOp: | ||
| """Common integer simple ops: | ||
| min_s, min_u, max_s, max_u | ||
| """ | ||
|
|
||
| @staticmethod | ||
| def binary_op(op: str, p1: str, p2: str, lane_width: int) -> str: | ||
| """Binary operation on p1 and p2 with the operation specified by op | ||
|
|
||
| :param op: min_s, min_u, max_s, max_u | ||
| :param p1: a hex or decimal integer literal string | ||
| :param p2: a hex or decimal integer literal string | ||
| :lane_width: bit number of each lane in SIMD v128 | ||
| :return: | ||
| """ | ||
| if '0x' in p1: | ||
| base1 = 16 | ||
| else: | ||
| base1 = 10 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like the parameters are allowed to be base-10, but the doc comment specifies that they must be hex. One of these should be updated.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I will fix it soon. |
||
| v1 = int(p1, base1) | ||
|
|
||
| if '0x' in p2: | ||
| base2 = 16 | ||
| else: | ||
| base2 = 10 | ||
| v2 = int(p2, base2) | ||
|
|
||
| if op in ['min_s', 'max_s']: | ||
| i1 = IntegerSimpleOp.get_valid_value(v1, lane_width) | ||
| i2 = IntegerSimpleOp.get_valid_value(v2, lane_width) | ||
| if op == 'min_s': | ||
| return p1 if i1 <= i2 else p2 | ||
| else: | ||
| return p1 if i1 >= i2 else p2 | ||
|
|
||
| elif op in ['min_u', 'max_u']: | ||
| i1 = IntegerSimpleOp.get_valid_value(v1, lane_width, signed=False) | ||
| i2 = IntegerSimpleOp.get_valid_value(v2, lane_width, signed=False) | ||
| if op == 'min_u': | ||
| return p1 if i1 <= i2 else p2 | ||
| else: | ||
| return p1 if i1 >= i2 else p2 | ||
|
|
||
| else: | ||
| raise Exception('Unknown binary operation') | ||
|
|
||
| @staticmethod | ||
| def get_valid_value(value, lane_width, signed=True): | ||
| """Get the valid integer value of value in the specified lane size. | ||
| """ | ||
| lane = LaneValue(lane_width) | ||
| value &= lane.mask | ||
|
|
||
| if signed: | ||
| if value > lane.max: | ||
| return value - lane.mod | ||
| if value < lane.min: | ||
| return value + lane.mod | ||
|
|
||
| return value | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| #!/usr/bin/env python3 | ||
|
|
||
|
|
||
| class LaneValue: | ||
| """This class stands for the value of signed integer represented by a lane in v128. | ||
| Suppose a bit number of the lane is n, then: | ||
| For signed integer: | ||
| minimum = -pow(2, n - 1), maximum = pow(2, n - 1) - 1 | ||
| The bit number of the lane can be 8, 16, 32, 64""" | ||
| def __init__(self, lane_width): | ||
| """lane_width: bit number of each lane in SIMD v128""" | ||
| self.lane_width = lane_width | ||
|
|
||
| @property | ||
| def min(self): | ||
| return -pow(2, self.lane_width - 1) | ||
|
|
||
| @property | ||
| def max(self): | ||
| return pow(2, self.lane_width - 1) - 1 | ||
|
|
||
| @property | ||
| def mask(self): | ||
| return pow(2, self.lane_width) - 1 | ||
|
|
||
| @property | ||
| def mod(self): | ||
| return pow(2, self.lane_width) | ||
|
|
||
| @property | ||
| def quarter(self): | ||
| return pow(2, self.lane_width - 2) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm splitting this class from https://github.com/WebAssembly/simd/blob/master/test/core/simd/meta/simd_arithmetic.py#L20, which is used for set various test data per properties defined above. e.g. for an i8 value, its bit width is 255, its quarter is 64, for an i16 value, its quarter is 16384, thus we can have different test data for different lane width value. I just want to specific a test data between the boundary value. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems generally useful. Are you planning to extend this to more operations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's part of my ongoing plan.