parse and implement I32x4TruncSatF32x4 instruction
This commit is contained in:
@@ -2277,6 +2277,19 @@ 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) } (I32x4TruncSatF32x4 signed) =
|
||||
let
|
||||
floatTruncSat :: Bool -> Float -> Word32
|
||||
floatTruncSat True v | isNaN v = 0
|
||||
floatTruncSat True v | v >= 2^31 = 0x7fffffff
|
||||
floatTruncSat True v | v < -2^31 - 1 = 0x80000000
|
||||
floatTruncSat True v = asWord32 $ truncate v
|
||||
floatTruncSat False v | v <= -1 || isNaN v = 0
|
||||
floatTruncSat False v | v >= 2^32 = 0xffffffff
|
||||
floatTruncSat False v = truncate v
|
||||
in
|
||||
let r = floatTruncSat signed . ByteArray.indexByteArray @Float v <$> [0..3] in
|
||||
return $ Done ctx { stack = VV128 (ByteArray.byteArrayFromList @Word32 r) : rest }
|
||||
step EvalCtx{ stack } instr = error $ "Error during evaluation of instruction: " ++ show instr ++ ". Stack " ++ show stack
|
||||
eval _ _ _ HostInstance { funcType, hostCode } args = Just <$> hostCode args
|
||||
|
||||
|
||||
@@ -584,6 +584,8 @@ import Language.Wasm.Lexer (
|
||||
'i64x2.extend_high_i32x4_u' { Lexeme _ (TKeyword "i64x2.extend_high_i32x4_u") }
|
||||
'i64x2.extend_low_i32x4_s' { Lexeme _ (TKeyword "i64x2.extend_low_i32x4_s") }
|
||||
'i64x2.extend_low_i32x4_u' { Lexeme _ (TKeyword "i64x2.extend_low_i32x4_u") }
|
||||
'i32x4.trunc_sat_f32x4_s' { Lexeme _ (TKeyword "i32x4.trunc_sat_f32x4_s") }
|
||||
'i32x4.trunc_sat_f32x4_u' { Lexeme _ (TKeyword "i32x4.trunc_sat_f32x4_u") }
|
||||
-- script extension
|
||||
'binary' { Lexeme _ (TKeyword "binary") }
|
||||
'quote' { Lexeme _ (TKeyword "quote") }
|
||||
@@ -1200,6 +1202,8 @@ plaininstr :: { PlainInstr }
|
||||
| 'i64x2.extend_high_i32x4_u' { V128IExtend I64x2 I32x4 True False }
|
||||
| 'i64x2.extend_low_i32x4_s' { V128IExtend I64x2 I32x4 False True }
|
||||
| 'i64x2.extend_low_i32x4_u' { V128IExtend I64x2 I32x4 False False }
|
||||
| 'i32x4.trunc_sat_f32x4_s' { I32x4TruncSatF32x4 True }
|
||||
| 'i32x4.trunc_sat_f32x4_u' { I32x4TruncSatF32x4 False }
|
||||
|
||||
typeuse(next)
|
||||
: '(' typeuse1(folded_instr_list(next), instruction_list(next)) {
|
||||
@@ -1934,6 +1938,7 @@ data PlainInstr =
|
||||
| F64x2PromoteLowF32x4
|
||||
| F32x4DemoteF64x2Zero
|
||||
| V128IExtend SimdShape SimdShape {- high -} Bool {- signed -} Bool
|
||||
| I32x4TruncSatF32x4 {- signed -} Bool
|
||||
deriving (Show, Eq)
|
||||
|
||||
data TypeDef = TypeDef (Maybe Ident) FuncType deriving (Show, Eq)
|
||||
@@ -2540,6 +2545,7 @@ desugarize fields = do
|
||||
synInstrToStruct _ (PlainInstr F32x4DemoteF64x2Zero) = return $ S.F32x4DemoteF64x2Zero
|
||||
synInstrToStruct _ (PlainInstr (V128Narrow t f s)) = return $ S.V128Narrow t f s
|
||||
synInstrToStruct _ (PlainInstr (V128IExtend t f h s)) = return $ S.V128IExtend t f h s
|
||||
synInstrToStruct _ (PlainInstr (I32x4TruncSatF32x4 s)) = return $ S.I32x4TruncSatF32x4 s
|
||||
synInstrToStruct ctx@FunCtx { ctxMod = Module { types } } BlockInstr {label, blockType, body} = do
|
||||
let ctx' = ctx { ctxLabels = label : ctxLabels ctx }
|
||||
bt <- case blockType of
|
||||
|
||||
@@ -276,6 +276,7 @@ data Instruction index =
|
||||
| F64x2PromoteLowF32x4
|
||||
| F32x4DemoteF64x2Zero
|
||||
| V128IExtend SimdShape SimdShape {- high -} Bool {- signed -} Bool
|
||||
| I32x4TruncSatF32x4 {- signed -} Bool
|
||||
deriving (Show, Eq, Generic, NFData)
|
||||
|
||||
type Expression = [Instruction Natural]
|
||||
|
||||
@@ -629,6 +629,8 @@ getInstrType _ F32x4DemoteF64x2Zero =
|
||||
return $ V128 ==> V128
|
||||
getInstrType _ (V128IExtend _ _ _ _) =
|
||||
return $ V128 ==> V128
|
||||
getInstrType _ (I32x4TruncSatF32x4 _) =
|
||||
return $ V128 ==> V128
|
||||
|
||||
getShapeElemType :: SimdShape -> ValueType
|
||||
getShapeElemType I8x16 = I32
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ main = do
|
||||
filter (List.isPrefixOf "simd") .
|
||||
filter (List.isSuffixOf ".wast")
|
||||
<$> Directory.listDirectory "tests/spec"
|
||||
-- let files = ["simd_int_to_int_extend.wast"]
|
||||
-- let files = ["simd_i32x4_trunc_sat_f32x4.wast"]
|
||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||
test <- LBS.readFile ("tests/spec/" ++ file)
|
||||
return $ testCase file $ do
|
||||
|
||||
Reference in New Issue
Block a user