From 22198d8d767d2f3615aa81e0f698fa100f5cef69 Mon Sep 17 00:00:00 2001 From: Ilya Rezvov Date: Sun, 10 Sep 2023 17:28:37 -0600 Subject: [PATCH] implement rest of unary float operations for simd --- src/Language/Wasm/Interpreter.hs | 44 ++++++++++++++++++++++++++++++++ src/Language/Wasm/Parser.y | 16 ++++++++++++ tests/Test.hs | 2 +- 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/Language/Wasm/Interpreter.hs b/src/Language/Wasm/Interpreter.hs index 099a970..b21b467 100644 --- a/src/Language/Wasm/Interpreter.hs +++ b/src/Language/Wasm/Interpreter.hs @@ -1743,6 +1743,50 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct _ -> error "impossible due to validation" in return $ Done ctx { stack = VV128 r : rest } + step ctx@EvalCtx{ stack = (VV128 v:rest) } (FUnOp (BS128 shape) FCeil) = + let r = case shape of + F32x4 -> ByteArray.byteArrayFromList + $ floatToWord . floatCeil . wordToFloat . ByteArray.indexByteArray @Word32 v + <$> [0..3] + F64x2 -> ByteArray.byteArrayFromList + $ doubleToWord . doubleCeil . 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) FFloor) = + let r = case shape of + F32x4 -> ByteArray.byteArrayFromList + $ floatToWord . floatFloor . wordToFloat . ByteArray.indexByteArray @Word32 v + <$> [0..3] + F64x2 -> ByteArray.byteArrayFromList + $ doubleToWord . doubleFloor . 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) FTrunc) = + let r = case shape of + F32x4 -> ByteArray.byteArrayFromList + $ floatToWord . floatTrunc . wordToFloat . ByteArray.indexByteArray @Word32 v + <$> [0..3] + F64x2 -> ByteArray.byteArrayFromList + $ doubleToWord . doubleTrunc . 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) FNearest) = + let r = case shape of + F32x4 -> ByteArray.byteArrayFromList + $ floatToWord . nearest . wordToFloat . ByteArray.indexByteArray @Word32 v + <$> [0..3] + F64x2 -> ByteArray.byteArrayFromList + $ doubleToWord . nearest . 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) FSqrt) = let r = case shape of F32x4 -> ByteArray.byteArrayFromList diff --git a/src/Language/Wasm/Parser.y b/src/Language/Wasm/Parser.y index 9bab426..b5b0bc3 100644 --- a/src/Language/Wasm/Parser.y +++ b/src/Language/Wasm/Parser.y @@ -519,6 +519,14 @@ import Language.Wasm.Lexer ( 'f64x2.abs' { Lexeme _ (TKeyword "f64x2.abs") } 'f32x4.neg' { Lexeme _ (TKeyword "f32x4.neg") } 'f64x2.neg' { Lexeme _ (TKeyword "f64x2.neg") } +'f32x4.ceil' { Lexeme _ (TKeyword "f32x4.ceil") } +'f64x2.ceil' { Lexeme _ (TKeyword "f64x2.ceil") } +'f32x4.floor' { Lexeme _ (TKeyword "f32x4.floor") } +'f64x2.floor' { Lexeme _ (TKeyword "f64x2.floor") } +'f32x4.trunc' { Lexeme _ (TKeyword "f32x4.trunc") } +'f64x2.trunc' { Lexeme _ (TKeyword "f64x2.trunc") } +'f32x4.nearest' { Lexeme _ (TKeyword "f32x4.nearest") } +'f64x2.nearest' { Lexeme _ (TKeyword "f64x2.nearest") } 'f32x4.sqrt' { Lexeme _ (TKeyword "f32x4.sqrt") } 'f64x2.sqrt' { Lexeme _ (TKeyword "f64x2.sqrt") } 'f32x4.eq' { Lexeme _ (TKeyword "f32x4.eq") } @@ -1084,6 +1092,14 @@ plaininstr :: { PlainInstr } | 'f64x2.abs' { FUnOp (BS128 F64x2) FAbs } | 'f32x4.neg' { FUnOp (BS128 F32x4) FNeg } | 'f64x2.neg' { FUnOp (BS128 F64x2) FNeg } + | 'f32x4.ceil' { FUnOp (BS128 F32x4) FCeil } + | 'f64x2.ceil' { FUnOp (BS128 F64x2) FCeil } + | 'f32x4.floor' { FUnOp (BS128 F32x4) FFloor } + | 'f64x2.floor' { FUnOp (BS128 F64x2) FFloor } + | 'f32x4.trunc' { FUnOp (BS128 F32x4) FTrunc } + | 'f64x2.trunc' { FUnOp (BS128 F64x2) FTrunc } + | 'f32x4.nearest' { FUnOp (BS128 F32x4) FNearest } + | 'f64x2.nearest' { FUnOp (BS128 F64x2) FNearest } | 'f32x4.sqrt' { FUnOp (BS128 F32x4) FSqrt } | 'f64x2.sqrt' { FUnOp (BS128 F64x2) FSqrt } | 'f32x4.eq' { FRelOp (BS128 F32x4) FEq } diff --git a/tests/Test.hs b/tests/Test.hs index 98298e7..cb27f4b 100644 --- a/tests/Test.hs +++ b/tests/Test.hs @@ -20,7 +20,7 @@ main = do filter (List.isPrefixOf "simd") . filter (List.isSuffixOf ".wast") <$> Directory.listDirectory "tests/spec" - -- let files = ["simd_i16x8_arith2.wast"] + -- let files = ["simd_f64x2_rounding.wast"] scriptTestCases <- (`mapM` files) $ \file -> do test <- LBS.readFile ("tests/spec/" ++ file) return $ testCase file $ do