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
4 changes: 4 additions & 0 deletions interpreter/binary/decode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ let simd_prefix s =
| 0xe7l -> f32x4_div
| 0xe8l -> f32x4_min
| 0xe9l -> f32x4_max
| 0xeal -> f32x4_pmin
| 0xebl -> f32x4_pmax
| 0xecl -> f64x2_abs
| 0xedl -> f64x2_neg
| 0xefl -> f64x2_sqrt
Expand All @@ -403,6 +405,8 @@ let simd_prefix s =
| 0xf3l -> f64x2_div
| 0xf4l -> f64x2_min
| 0xf5l -> f64x2_max
| 0xf6l -> f64x2_pmin
| 0xf7l -> f64x2_pmax
| 0xf8l -> i32x4_trunc_sat_f32x4_s
| 0xf9l -> i32x4_trunc_sat_f32x4_u
| 0xfal -> f32x4_convert_i32x4_s
Expand Down
4 changes: 4 additions & 0 deletions interpreter/binary/encode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ let encode m =
| Binary (V128 V128Op.(F32x4 Div)) -> simd_op 0xe7l
| Binary (V128 V128Op.(F32x4 Min)) -> simd_op 0xe8l
| Binary (V128 V128Op.(F32x4 Max)) -> simd_op 0xe9l
| Binary (V128 V128Op.(F32x4 Pmin)) -> simd_op 0xeal
| Binary (V128 V128Op.(F32x4 Pmax)) -> simd_op 0xebl
| Binary (V128 V128Op.(F64x2 Eq)) -> simd_op 0x47l
| Binary (V128 V128Op.(F64x2 Ne)) -> simd_op 0x48l
| Binary (V128 V128Op.(F64x2 Lt)) -> simd_op 0x49l
Expand All @@ -500,6 +502,8 @@ let encode m =
| Binary (V128 V128Op.(F64x2 Div)) -> simd_op 0xf3l
| Binary (V128 V128Op.(F64x2 Min)) -> simd_op 0xf4l
| Binary (V128 V128Op.(F64x2 Max)) -> simd_op 0xf5l
| Binary (V128 V128Op.(F64x2 Pmin)) -> simd_op 0xf6l
| Binary (V128 V128Op.(F64x2 Pmax)) -> simd_op 0xf7l
| Binary (V128 V128Op.(V128 And)) -> simd_op 0x4el
| Binary (V128 V128Op.(V128 AndNot)) -> simd_op 0x4fl
| Binary (V128 V128Op.(V128 Or)) -> simd_op 0x50l
Expand Down
4 changes: 4 additions & 0 deletions interpreter/exec/eval_numeric.ml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ struct
| F32x4 Div -> SXX.F32x4.div
| F32x4 Min -> SXX.F32x4.min
| F32x4 Max -> SXX.F32x4.max
| F32x4 Pmin -> SXX.F32x4.pmin
| F32x4 Pmax -> SXX.F32x4.pmax
| F64x2 Eq -> SXX.F64x2.eq
| F64x2 Ne -> SXX.F64x2.ne
| F64x2 Lt -> SXX.F64x2.lt
Expand All @@ -259,6 +261,8 @@ struct
| F64x2 Div -> SXX.F64x2.div
| F64x2 Min -> SXX.F64x2.min
| F64x2 Max -> SXX.F64x2.max
| F64x2 Pmin -> SXX.F64x2.pmin
| F64x2 Pmax -> SXX.F64x2.pmax
| V128 And -> SXX.V128.and_
| V128 Or -> SXX.V128.or_
| V128 Xor -> SXX.V128.xor
Expand Down
4 changes: 4 additions & 0 deletions interpreter/exec/simd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ sig
val div : t -> t -> t
val min : t -> t -> t
val max : t -> t -> t
val pmin : t -> t -> t
val pmax : t -> t -> t
end

module type Vec =
Expand Down Expand Up @@ -268,6 +270,8 @@ struct
let div = binop Float.div
let min = binop Float.min
let max = binop Float.max
let pmin = binop (fun x y -> if Float.lt y x then y else x)
let pmax = binop (fun x y -> if Float.lt x y then y else x)
end

module MakeInt (Int : Int.S) (Convert : sig
Expand Down
2 changes: 1 addition & 1 deletion interpreter/syntax/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct
type funop = Abs | Neg | Sqrt
| Ceil | Floor | Trunc | Nearest
| ConvertI32x4S | ConvertI32x4U
type fbinop = Add | Sub | Mul | Div | Min | Max
type fbinop = Add | Sub | Mul | Div | Min | Max | Pmin | Pmax
| Eq | Ne | Lt | Le | Gt | Ge
type vunop = Not
type vbinop = And | Or | Xor | AndNot
Expand Down
4 changes: 4 additions & 0 deletions interpreter/syntax/operators.ml
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ let f32x4_min = Binary (V128 (V128Op.F32x4 V128Op.Min))
let f32x4_max = Binary (V128 (V128Op.F32x4 V128Op.Max))
let f32x4_convert_i32x4_s = Unary (V128 V128Op.(F32x4 ConvertI32x4S))
let f32x4_convert_i32x4_u = Unary (V128 V128Op.(F32x4 ConvertI32x4U))
let f32x4_pmin = Binary (V128 (V128Op.F32x4 V128Op.Pmin))
let f32x4_pmax = Binary (V128 (V128Op.F32x4 V128Op.Pmax))

let f64x2_splat = Convert (V128 (V128Op.F64x2 V128Op.Splat))
let f64x2_extract_lane imm = SimdExtract (V128Op.F64x2 (ZX, imm))
Expand All @@ -420,3 +422,5 @@ let f64x2_div = Binary (V128 (V128Op.F64x2 V128Op.Div))
let f64x2_min = Binary (V128 (V128Op.F64x2 V128Op.Min))
let f64x2_max = Binary (V128 (V128Op.F64x2 V128Op.Max))
let f64x2_abs = Unary (V128 (V128Op.F64x2 V128Op.Abs))
let f64x2_pmin = Binary (V128 (V128Op.F64x2 V128Op.Pmin))
let f64x2_pmax = Binary (V128 (V128Op.F64x2 V128Op.Pmax))
4 changes: 4 additions & 0 deletions interpreter/text/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ struct
| F32x4 Div -> "f32x4.div"
| F32x4 Min -> "f32x4.min"
| F32x4 Max -> "f32x4.max"
| F32x4 Pmin -> "f32x4.pmin"
| F32x4 Pmax -> "f32x4.pmax"
| F64x2 Eq -> "f64x2.eq"
| F64x2 Ne -> "f64x2.ne"
| F64x2 Lt -> "f64x2.lt"
Expand All @@ -332,6 +334,8 @@ struct
| F64x2 Div -> "f64x2.div"
| F64x2 Min -> "f64x2.min"
| F64x2 Max -> "f64x2.max"
| F64x2 Pmin -> "f64x2.pmin"
| F64x2 Pmax -> "f64x2.pmax"
| V128 And -> "v128.and"
| V128 AndNot -> "v128.andnot"
| V128 Or -> "v128.or"
Expand Down
2 changes: 2 additions & 0 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@ rule token = parse
| (simd_float_shape as s)".floor" { UNARY (simd_float_op s f32x4_floor f64x2_floor) }
| (simd_float_shape as s)".trunc" { UNARY (simd_float_op s f32x4_trunc f64x2_trunc) }
| (simd_float_shape as s)".nearest" { UNARY (simd_float_op s f32x4_nearest f64x2_nearest) }
| (simd_float_shape as s)".pmin" { BINARY (simd_float_op s f32x4_pmin f64x2_pmin) }
| (simd_float_shape as s)".pmax" { BINARY (simd_float_op s f32x4_pmax f64x2_pmax) }
| (simd_shape as s)".add"
{ BINARY (simdop s i8x16_add i16x8_add i32x4_add i64x2_add f32x4_add f64x2_add) }
| (simd_shape as s)".sub"
Expand Down
2 changes: 2 additions & 0 deletions test/core/simd/meta/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Currently it only support following simd test files generation.
- 'simd_f64x2.wast'
- 'simd_f32x4_rounding'
- 'simd_f64x2_rounding'
- 'simd_f32x4_pmin_pmax'
- 'simd_f64x2_pmin_pmax'


Usage:
Expand Down
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 @@ -28,6 +28,8 @@
'simd_int_arith2',
'simd_f32x4_rounding',
'simd_f64x2_rounding',
'simd_f32x4_pmin_pmax',
'simd_f64x2_pmin_pmax',
)


Expand Down
2 changes: 1 addition & 1 deletion test/core/simd/meta/simd_f32x4.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,4 @@ def gen_test_cases():


if __name__ == '__main__':
gen_test_cases()
gen_test_cases()
83 changes: 83 additions & 0 deletions test/core/simd/meta/simd_f32x4_pmin_pmax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3

"""
Generate f32x4 [pmin, pmax] cases.
"""

from simd_f32x4_arith import Simdf32x4ArithmeticCase
from simd_float_op import FloatingPointSimpleOp
from simd import SIMD
from test_assert import AssertReturn


class Simdf32x4PminPmaxCase(Simdf32x4ArithmeticCase):
UNARY_OPS = ()
BINARY_OPS = ('pmin', 'pmax',)
floatOp = FloatingPointSimpleOp()

def get_combine_cases(self):
return ''

def get_normal_case(self):
"""Normal test cases from WebAssembly core tests.
"""
cases = []
binary_test_data = []
unary_test_data = []

for op in self.BINARY_OPS:
op_name = self.full_op_name(op)
for operand1 in self.FLOAT_NUMBERS + self.LITERAL_NUMBERS:
for operand2 in self.FLOAT_NUMBERS + self.LITERAL_NUMBERS:
result = self.floatOp.binary_op(op, operand1, operand2)
binary_test_data.append([op_name, operand1, operand2, result])

# pmin and pmax always return operand1 if either operand is a nan
for operand1 in self.NAN_NUMBERS:
for operand2 in self.FLOAT_NUMBERS + self.LITERAL_NUMBERS + self.NAN_NUMBERS:
binary_test_data.append([op_name, operand1, operand2, operand1])
for operand2 in self.NAN_NUMBERS:
for operand1 in self.FLOAT_NUMBERS + self.LITERAL_NUMBERS:
binary_test_data.append([op_name, operand1, operand2, operand1])

for case in binary_test_data:
cases.append(str(AssertReturn(case[0],
[SIMD.v128_const(c, self.LANE_TYPE) for c in case[1:-1]],
SIMD.v128_const(case[-1], self.LANE_TYPE))))

self.get_unknown_operator_case(cases)

return '\n'.join(cases)

def get_unknown_operator_case(self, cases):
"""Unknown operator cases.
"""

tpl_assert = "(assert_malformed (module quote \"(memory 1) (func (result v128) " \
"({lane_type}.{op} {value}))\") \"unknown operator\")"

unknown_op_cases = ['\n\n;; Unknown operators\n']
cases.extend(unknown_op_cases)

for lane_type in ['i8x16', 'i16x8', 'i32x4', 'i64x2']:

for op in self.BINARY_OPS:
cases.append(tpl_assert.format(lane_type=lane_type, op=op, value=' '.join([self.v128_const('i32x4', '0')]*2)))

def gen_test_cases(self):
wast_filename = '../simd_{lane_type}_pmin_pmax.wast'.format(lane_type=self.LANE_TYPE)
with open(wast_filename, 'w') as fp:
txt_test_case = self.get_all_cases()
txt_test_case = txt_test_case.replace(
self.LANE_TYPE + ' arithmetic',
self.LANE_TYPE + ' [pmin, pmax]')
fp.write(txt_test_case)


def gen_test_cases():
simd_f32x4_pmin_pmax_case = Simdf32x4PminPmaxCase()
simd_f32x4_pmin_pmax_case.gen_test_cases()


if __name__ == '__main__':
gen_test_cases()
27 changes: 27 additions & 0 deletions test/core/simd/meta/simd_f64x2_pmin_pmax.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python3

"""
Generate f64x2 [pmin, pmax] cases.
"""

from simd_f32x4_pmin_pmax import Simdf32x4PminPmaxCase
from simd_f64x2_arith import Simdf64x2ArithmeticCase
from simd_float_op import FloatingPointSimpleOp
from simd import SIMD
from test_assert import AssertReturn


class Simdf64x2PminPmaxCase(Simdf32x4PminPmaxCase):
LANE_TYPE = 'f64x2'
FLOAT_NUMBERS = Simdf64x2ArithmeticCase.FLOAT_NUMBERS
LITERAL_NUMBERS = Simdf64x2ArithmeticCase.LITERAL_NUMBERS
NAN_NUMBERS = Simdf64x2ArithmeticCase.NAN_NUMBERS


def gen_test_cases():
simd_f64x2_pmin_pmax_case = Simdf64x2PminPmaxCase()
simd_f64x2_pmin_pmax_case.gen_test_cases()


if __name__ == '__main__':
gen_test_cases()
17 changes: 16 additions & 1 deletion test/core/simd/meta/simd_float_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def float_neg(self, p):


class FloatingPointSimpleOp(FloatingPointOp):
"""Common simple ops for both f32x4 and f64x2: abs, min, max"""
"""Common simple ops for both f32x4 and f64x2: abs, min, max, pmin, pmax"""

def binary_op(self, op: str, p1: str, p2: str, hex_form=True) -> str:
"""Binary operation on p1 and p2 with the operation specified by op
Expand Down Expand Up @@ -164,6 +164,21 @@ def binary_op(self, op: str, p1: str, p2: str, hex_form=True) -> str:
if '-nan' in [p1, p2]:
return '-nan'

# pmin and pmax semantics follow C++'s std::min std::max
if op == 'pmin':
r = f2 if f2 < f1 else f1
if hex_form:
return r.hex()
else:
return str(r)

if op == 'pmax':
r = f2 if f1 < f2 else f1
if hex_form:
return r.hex()
else:
return str(r)

if op == 'min':
if '-0x0p+0' in [p1, p2] and '0x0p+0' in [p1, p2]:
return '-0x0p+0'
Expand Down
Loading