Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion test/core/simd/meta/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Currently it only support following simd test files generation.
- 'simd_i16x8_sat_arith.wast'
- 'simd_f32x4.wast'
- 'simd_f64x2.wast'
- 'simd_i8x16.wast'
- 'simd_i16x8.wast'
- 'simd_i32x4.wast'


Usage:
Expand All @@ -27,4 +30,4 @@ Usage:
$ python gen_tests.py -a
```

More details documented in `gen_tests.py`.
This script requires Python 3.6+, more details are documented in `gen_tests.py`.
2 changes: 2 additions & 0 deletions test/core/simd/meta/gen_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""
This script is used for generating WebAssembly SIMD test cases.
It requires Python 3.6+.
"""
import sys
import argparse
Expand All @@ -24,6 +25,7 @@
'simd_bitwise',
'simd_f32x4',
'simd_f64x2',
'simd_lanewise_integer',
)


Expand Down
17 changes: 9 additions & 8 deletions test/core/simd/meta/simd.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,34 @@
"""


class SIMD(object):
class SIMD:

# Constant template
CONST = '({value_type}.const {value})'

# v128 Constant template
V128_CONST = '(v128.const {lane_type} {value})'

def const(self, value, value_type):
@staticmethod
def const(value, value_type):
"""
generation constant data, [e.g. i32, i64, f32, f64]
Params:
value: constant data, string or list,
lane_type: lane type, [i32, i64, f32, f64]
"""
return self.CONST.format(value_type=value_type, value=''.join(value))
return SIMD.CONST.format(value_type=value_type, value=''.join(value))

def v128_const(self, value, lane_type):
@staticmethod
def v128_const(value, lane_type):
"""
generation v128 constant data, [e.g. i8x16, i16x8, i32x4, f32x4]
Params:
value: constant data, string or list,
lane_type: lane type, [e.g. i8x16, i16x8, i32x4, f32x4]
"""

if lane_type.lower().find('x') == -1:
return self.const(value, lane_type)
return SIMD.const(value, lane_type)

lane_cnt = int(lane_type[1:].split('x')[1])

Expand All @@ -47,7 +48,7 @@ def v128_const(self, value, lane_type):

# If it is an empty list, generate all constant data with 0x00
if len(value) == 0:
return self.v128_const('0x00', lane_type)
return SIMD.v128_const('0x00', lane_type)

data_elem = []

Expand Down Expand Up @@ -80,4 +81,4 @@ def v128_const(self, value, lane_type):
data_elem = ' '.join(data_elem)

# Returns v128 constant text
return self.V128_CONST.format(lane_type=lane_type, value=data_elem)
return SIMD.V128_CONST.format(lane_type=lane_type, value=data_elem)
66 changes: 66 additions & 0 deletions test/core/simd/meta/simd_integer_op.py
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
Copy link
Member

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?

Copy link
Contributor Author

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.

: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
Copy link
Member

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
32 changes: 32 additions & 0 deletions test/core/simd/meta/simd_lane_value.py
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is quarter used for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Loading