forked from GitHub/haskell-wasm
implement min and max ops
This commit is contained in:
@@ -1528,6 +1528,45 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct
|
|||||||
_ -> error "impossible due to validation"
|
_ -> error "impossible due to validation"
|
||||||
in
|
in
|
||||||
return $ Done ctx { stack = VV128 r : rest }
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 shape) IAvgrU) =
|
||||||
|
let r = case shape of
|
||||||
|
I8x16 -> lanewise @Word8 shape v1 v2 $ \a b -> fromIntegral $ (fromIntegral a + fromIntegral b + 1) `div` 2
|
||||||
|
I16x8 -> lanewise @Word16 shape v1 v2 $ \a b -> fromIntegral $ (fromIntegral a + fromIntegral b + 1) `div` 2
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 shape) IMinU) =
|
||||||
|
let r = case shape of
|
||||||
|
I8x16 -> lanewise @Word8 shape v1 v2 min
|
||||||
|
I16x8 -> lanewise @Word16 shape v1 v2 min
|
||||||
|
I32x4 -> lanewise @Word32 shape v1 v2 min
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 shape) IMinS) =
|
||||||
|
let r = case shape of
|
||||||
|
I8x16 -> lanewise @Word8 shape v1 v2 $ \a b -> asWord8 $ min (asInt8 a) (asInt8 b)
|
||||||
|
I16x8 -> lanewise @Word16 shape v1 v2 $ \a b -> asWord16 $ min (asInt16 a) (asInt16 b)
|
||||||
|
I32x4 -> lanewise @Word32 shape v1 v2 $ \a b -> asWord32 $ min (asInt32 a) (asInt32 b)
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 shape) IMaxU) =
|
||||||
|
let r = case shape of
|
||||||
|
I8x16 -> lanewise @Word8 shape v1 v2 max
|
||||||
|
I16x8 -> lanewise @Word16 shape v1 v2 max
|
||||||
|
I32x4 -> lanewise @Word32 shape v1 v2 max
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 shape) IMaxS) =
|
||||||
|
let r = case shape of
|
||||||
|
I8x16 -> lanewise @Word8 shape v1 v2 $ \a b -> asWord8 $ max (asInt8 a) (asInt8 b)
|
||||||
|
I16x8 -> lanewise @Word16 shape v1 v2 $ \a b -> asWord16 $ max (asInt16 a) (asInt16 b)
|
||||||
|
I32x4 -> lanewise @Word32 shape v1 v2 $ \a b -> asWord32 $ max (asInt32 a) (asInt32 b)
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 _) IAnd) =
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (IBinOp (BS128 _) IAnd) =
|
||||||
let r = lanewise @Word64 I64x2 v1 v2 (.&.) in
|
let r = lanewise @Word64 I64x2 v1 v2 (.&.) in
|
||||||
return $ Done ctx { stack = VV128 r : rest }
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
@@ -1682,6 +1721,17 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct
|
|||||||
return $ Done ctx { stack = VF64 (nearest v) : rest }
|
return $ Done ctx { stack = VF64 (nearest v) : rest }
|
||||||
step ctx@EvalCtx{ stack = (VF64 v:rest) } (FUnOp BS64 FSqrt) =
|
step ctx@EvalCtx{ stack = (VF64 v:rest) } (FUnOp BS64 FSqrt) =
|
||||||
return $ Done ctx { stack = VF64 (sqrt v) : rest }
|
return $ Done ctx { stack = VF64 (sqrt v) : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v:rest) } (FUnOp (BS128 shape) FAbs) =
|
||||||
|
let r = case shape of
|
||||||
|
F32x4 -> ByteArray.byteArrayFromList
|
||||||
|
$ floatToWord . abs . wordToFloat . ByteArray.indexByteArray @Word32 v
|
||||||
|
<$> [0..3]
|
||||||
|
F64x2 -> ByteArray.byteArrayFromList
|
||||||
|
$ doubleToWord . abs . wordToDouble . ByteArray.indexByteArray @Word64 v
|
||||||
|
<$> [0..1]
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
step ctx@EvalCtx{ stack = (VV128 v:rest) } (FUnOp (BS128 shape) FNeg) =
|
step ctx@EvalCtx{ stack = (VV128 v:rest) } (FUnOp (BS128 shape) FNeg) =
|
||||||
let r = case shape of
|
let r = case shape of
|
||||||
F32x4 -> ByteArray.byteArrayFromList
|
F32x4 -> ByteArray.byteArrayFromList
|
||||||
@@ -1760,6 +1810,20 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct
|
|||||||
_ -> error "impossible due to validation"
|
_ -> error "impossible due to validation"
|
||||||
in
|
in
|
||||||
return $ Done ctx { stack = VV128 r : rest }
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (FBinOp (BS128 shape) FMin) =
|
||||||
|
let r = case shape of
|
||||||
|
F32x4 -> lanewise @Word32 shape v1 v2 $ \a b -> floatToWord $ zeroAwareMin (wordToFloat a) (wordToFloat b)
|
||||||
|
F64x2 -> lanewise @Word64 shape v1 v2 $ \a b -> doubleToWord $ zeroAwareMin (wordToDouble a) (wordToDouble b)
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
|
step ctx@EvalCtx{ stack = (VV128 v2:VV128 v1:rest) } (FBinOp (BS128 shape) FMax) =
|
||||||
|
let r = case shape of
|
||||||
|
F32x4 -> lanewise @Word32 shape v1 v2 $ \a b -> floatToWord $ zeroAwareMax (wordToFloat a) (wordToFloat b)
|
||||||
|
F64x2 -> lanewise @Word64 shape v1 v2 $ \a b -> doubleToWord $ zeroAwareMax (wordToDouble a) (wordToDouble b)
|
||||||
|
_ -> error "impossible due to validation"
|
||||||
|
in
|
||||||
|
return $ Done ctx { stack = VV128 r : rest }
|
||||||
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FRelOp BS32 FEq) =
|
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FRelOp BS32 FEq) =
|
||||||
return $ Done ctx { stack = VI32 (if v1 == v2 then 1 else 0) : rest }
|
return $ Done ctx { stack = VI32 (if v1 == v2 then 1 else 0) : rest }
|
||||||
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FRelOp BS32 FNe) =
|
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FRelOp BS32 FNe) =
|
||||||
|
|||||||
@@ -422,6 +422,20 @@ import Language.Wasm.Lexer (
|
|||||||
'i16x8.add_sat_u' { Lexeme _ (TKeyword "i16x8.add_sat_u") }
|
'i16x8.add_sat_u' { Lexeme _ (TKeyword "i16x8.add_sat_u") }
|
||||||
'i8x16.sub_sat_u' { Lexeme _ (TKeyword "i8x16.sub_sat_u") }
|
'i8x16.sub_sat_u' { Lexeme _ (TKeyword "i8x16.sub_sat_u") }
|
||||||
'i16x8.sub_sat_u' { Lexeme _ (TKeyword "i16x8.sub_sat_u") }
|
'i16x8.sub_sat_u' { Lexeme _ (TKeyword "i16x8.sub_sat_u") }
|
||||||
|
'i8x16.avgr_u' { Lexeme _ (TKeyword "i8x16.avgr_u") }
|
||||||
|
'i16x8.avgr_u' { Lexeme _ (TKeyword "i16x8.avgr_u") }
|
||||||
|
'i8x16.min_s' { Lexeme _ (TKeyword "i8x16.min_s") }
|
||||||
|
'i16x8.min_s' { Lexeme _ (TKeyword "i16x8.min_s") }
|
||||||
|
'i32x4.min_s' { Lexeme _ (TKeyword "i32x4.min_s") }
|
||||||
|
'i8x16.min_u' { Lexeme _ (TKeyword "i8x16.min_u") }
|
||||||
|
'i16x8.min_u' { Lexeme _ (TKeyword "i16x8.min_u") }
|
||||||
|
'i32x4.min_u' { Lexeme _ (TKeyword "i32x4.min_u") }
|
||||||
|
'i8x16.max_s' { Lexeme _ (TKeyword "i8x16.max_s") }
|
||||||
|
'i16x8.max_s' { Lexeme _ (TKeyword "i16x8.max_s") }
|
||||||
|
'i32x4.max_s' { Lexeme _ (TKeyword "i32x4.max_s") }
|
||||||
|
'i8x16.max_u' { Lexeme _ (TKeyword "i8x16.max_u") }
|
||||||
|
'i16x8.max_u' { Lexeme _ (TKeyword "i16x8.max_u") }
|
||||||
|
'i32x4.max_u' { Lexeme _ (TKeyword "i32x4.max_u") }
|
||||||
'i16x8.mul' { Lexeme _ (TKeyword "i16x8.mul") }
|
'i16x8.mul' { Lexeme _ (TKeyword "i16x8.mul") }
|
||||||
'i32x4.mul' { Lexeme _ (TKeyword "i32x4.mul") }
|
'i32x4.mul' { Lexeme _ (TKeyword "i32x4.mul") }
|
||||||
'i64x2.mul' { Lexeme _ (TKeyword "i64x2.mul") }
|
'i64x2.mul' { Lexeme _ (TKeyword "i64x2.mul") }
|
||||||
@@ -497,6 +511,12 @@ import Language.Wasm.Lexer (
|
|||||||
'f64x2.mul' { Lexeme _ (TKeyword "f64x2.mul") }
|
'f64x2.mul' { Lexeme _ (TKeyword "f64x2.mul") }
|
||||||
'f32x4.div' { Lexeme _ (TKeyword "f32x4.div") }
|
'f32x4.div' { Lexeme _ (TKeyword "f32x4.div") }
|
||||||
'f64x2.div' { Lexeme _ (TKeyword "f64x2.div") }
|
'f64x2.div' { Lexeme _ (TKeyword "f64x2.div") }
|
||||||
|
'f32x4.min' { Lexeme _ (TKeyword "f32x4.min") }
|
||||||
|
'f64x2.min' { Lexeme _ (TKeyword "f64x2.min") }
|
||||||
|
'f32x4.max' { Lexeme _ (TKeyword "f32x4.max") }
|
||||||
|
'f64x2.max' { Lexeme _ (TKeyword "f64x2.max") }
|
||||||
|
'f32x4.abs' { Lexeme _ (TKeyword "f32x4.abs") }
|
||||||
|
'f64x2.abs' { Lexeme _ (TKeyword "f64x2.abs") }
|
||||||
'f32x4.neg' { Lexeme _ (TKeyword "f32x4.neg") }
|
'f32x4.neg' { Lexeme _ (TKeyword "f32x4.neg") }
|
||||||
'f64x2.neg' { Lexeme _ (TKeyword "f64x2.neg") }
|
'f64x2.neg' { Lexeme _ (TKeyword "f64x2.neg") }
|
||||||
'f32x4.sqrt' { Lexeme _ (TKeyword "f32x4.sqrt") }
|
'f32x4.sqrt' { Lexeme _ (TKeyword "f32x4.sqrt") }
|
||||||
@@ -967,6 +987,20 @@ plaininstr :: { PlainInstr }
|
|||||||
| 'i16x8.add_sat_u' { IBinOp (BS128 I16x8) IAddSatU }
|
| 'i16x8.add_sat_u' { IBinOp (BS128 I16x8) IAddSatU }
|
||||||
| 'i8x16.sub_sat_u' { IBinOp (BS128 I8x16) ISubSatU }
|
| 'i8x16.sub_sat_u' { IBinOp (BS128 I8x16) ISubSatU }
|
||||||
| 'i16x8.sub_sat_u' { IBinOp (BS128 I16x8) ISubSatU }
|
| 'i16x8.sub_sat_u' { IBinOp (BS128 I16x8) ISubSatU }
|
||||||
|
| 'i8x16.avgr_u' { IBinOp (BS128 I8x16) IAvgrU }
|
||||||
|
| 'i16x8.avgr_u' { IBinOp (BS128 I16x8) IAvgrU }
|
||||||
|
| 'i8x16.min_s' { IBinOp (BS128 I8x16) IMinS }
|
||||||
|
| 'i16x8.min_s' { IBinOp (BS128 I16x8) IMinS }
|
||||||
|
| 'i32x4.min_s' { IBinOp (BS128 I32x4) IMinS }
|
||||||
|
| 'i8x16.min_u' { IBinOp (BS128 I8x16) IMinU }
|
||||||
|
| 'i16x8.min_u' { IBinOp (BS128 I16x8) IMinU }
|
||||||
|
| 'i32x4.min_u' { IBinOp (BS128 I32x4) IMinU }
|
||||||
|
| 'i8x16.max_s' { IBinOp (BS128 I8x16) IMaxS }
|
||||||
|
| 'i16x8.max_s' { IBinOp (BS128 I16x8) IMaxS }
|
||||||
|
| 'i32x4.max_s' { IBinOp (BS128 I32x4) IMaxS }
|
||||||
|
| 'i8x16.max_u' { IBinOp (BS128 I8x16) IMaxU }
|
||||||
|
| 'i16x8.max_u' { IBinOp (BS128 I16x8) IMaxU }
|
||||||
|
| 'i32x4.max_u' { IBinOp (BS128 I32x4) IMaxU }
|
||||||
| 'i16x8.mul' { IBinOp (BS128 I16x8) IMul }
|
| 'i16x8.mul' { IBinOp (BS128 I16x8) IMul }
|
||||||
| 'i32x4.mul' { IBinOp (BS128 I32x4) IMul }
|
| 'i32x4.mul' { IBinOp (BS128 I32x4) IMul }
|
||||||
| 'i64x2.mul' { IBinOp (BS128 I64x2) IMul }
|
| 'i64x2.mul' { IBinOp (BS128 I64x2) IMul }
|
||||||
@@ -1042,6 +1076,12 @@ plaininstr :: { PlainInstr }
|
|||||||
| 'f64x2.mul' { FBinOp (BS128 F64x2) FMul }
|
| 'f64x2.mul' { FBinOp (BS128 F64x2) FMul }
|
||||||
| 'f32x4.div' { FBinOp (BS128 F32x4) FDiv }
|
| 'f32x4.div' { FBinOp (BS128 F32x4) FDiv }
|
||||||
| 'f64x2.div' { FBinOp (BS128 F64x2) FDiv }
|
| 'f64x2.div' { FBinOp (BS128 F64x2) FDiv }
|
||||||
|
| 'f32x4.min' { FBinOp (BS128 F32x4) FMin }
|
||||||
|
| 'f64x2.min' { FBinOp (BS128 F64x2) FMin }
|
||||||
|
| 'f32x4.max' { FBinOp (BS128 F32x4) FMax }
|
||||||
|
| 'f64x2.max' { FBinOp (BS128 F64x2) FMax }
|
||||||
|
| 'f32x4.abs' { FUnOp (BS128 F32x4) FAbs }
|
||||||
|
| 'f64x2.abs' { FUnOp (BS128 F64x2) FAbs }
|
||||||
| 'f32x4.neg' { FUnOp (BS128 F32x4) FNeg }
|
| 'f32x4.neg' { FUnOp (BS128 F32x4) FNeg }
|
||||||
| 'f64x2.neg' { FUnOp (BS128 F64x2) FNeg }
|
| 'f64x2.neg' { FUnOp (BS128 F64x2) FNeg }
|
||||||
| 'f32x4.sqrt' { FUnOp (BS128 F32x4) FSqrt }
|
| 'f32x4.sqrt' { FUnOp (BS128 F32x4) FSqrt }
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ data IBinOp =
|
|||||||
| ISubSatS
|
| ISubSatS
|
||||||
| IAddSatU
|
| IAddSatU
|
||||||
| ISubSatU
|
| ISubSatU
|
||||||
|
| IAvgrU
|
||||||
| IMul
|
| IMul
|
||||||
| IDivU
|
| IDivU
|
||||||
| IDivS
|
| IDivS
|
||||||
@@ -97,6 +98,10 @@ data IBinOp =
|
|||||||
| IShrS
|
| IShrS
|
||||||
| IRotl
|
| IRotl
|
||||||
| IRotr
|
| IRotr
|
||||||
|
| IMinU
|
||||||
|
| IMinS
|
||||||
|
| IMaxU
|
||||||
|
| IMaxS
|
||||||
deriving (Show, Eq, Generic, NFData)
|
deriving (Show, Eq, Generic, NFData)
|
||||||
|
|
||||||
data IRelOp = IEq | INe | ILtU | ILtS | IGtU | IGtS | ILeU | ILeS | IGeU | IGeS deriving (Show, Eq, Generic, NFData)
|
data IRelOp = IEq | INe | ILtU | ILtS | IGtU | IGtS | ILeU | ILeS | IGeU | IGeS deriving (Show, Eq, Generic, NFData)
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ main = do
|
|||||||
filter (List.isPrefixOf "simd") .
|
filter (List.isPrefixOf "simd") .
|
||||||
filter (List.isSuffixOf ".wast")
|
filter (List.isSuffixOf ".wast")
|
||||||
<$> Directory.listDirectory "tests/spec"
|
<$> Directory.listDirectory "tests/spec"
|
||||||
-- let files = ["simd_f64x2_cmp.wast"]
|
-- let files = ["simd_i16x8_arith2.wast"]
|
||||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||||
test <- LBS.readFile ("tests/spec/" ++ file)
|
test <- LBS.readFile ("tests/spec/" ++ file)
|
||||||
return $ testCase file $ do
|
return $ testCase file $ do
|
||||||
|
|||||||
Reference in New Issue
Block a user