parse and implement simd_i32x4_trunc_sat_f64x2 instruction

This commit is contained in:
Ilya Rezvov
2025-01-13 10:22:06 -07:00
parent 662b57326c
commit 727fc8694b
5 changed files with 512 additions and 504 deletions
+7 -3
View File
@@ -2277,9 +2277,9 @@ 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 v:rest) } (I32x4TruncSatF32x4 signed) = step ctx@EvalCtx{ stack = (VV128 v:rest) } (I32x4TruncSatF signed sz) =
let let
floatTruncSat :: Bool -> Float -> Word32 floatTruncSat :: (RealFloat f) => Bool -> f -> Word32
floatTruncSat True v | isNaN v = 0 floatTruncSat True v | isNaN v = 0
floatTruncSat True v | v >= 2^31 = 0x7fffffff floatTruncSat True v | v >= 2^31 = 0x7fffffff
floatTruncSat True v | v < -2^31 - 1 = 0x80000000 floatTruncSat True v | v < -2^31 - 1 = 0x80000000
@@ -2288,7 +2288,11 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct
floatTruncSat False v | v >= 2^32 = 0xffffffff floatTruncSat False v | v >= 2^32 = 0xffffffff
floatTruncSat False v = truncate v floatTruncSat False v = truncate v
in in
let r = floatTruncSat signed . ByteArray.indexByteArray @Float v <$> [0..3] in let r = case sz of
BS32 -> floatTruncSat signed . ByteArray.indexByteArray @Float v <$> [0..3]
BS64 -> (floatTruncSat signed . ByteArray.indexByteArray @Double v <$> [0..1]) ++ [0, 0]
_ -> error "impossible due to validation"
in
return $ Done ctx { stack = VV128 (ByteArray.byteArrayFromList @Word32 r) : rest } 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 step EvalCtx{ stack } instr = error $ "Error during evaluation of instruction: " ++ show instr ++ ". Stack " ++ show stack
eval _ _ _ HostInstance { funcType, hostCode } args = Just <$> hostCode args eval _ _ _ HostInstance { funcType, hostCode } args = Just <$> hostCode args
+18 -14
View File
@@ -341,12 +341,12 @@ import Language.Wasm.Lexer (
'f32x4.convert_i32x4_u' { Lexeme _ (TKeyword "f32x4.convert_i32x4_u") } 'f32x4.convert_i32x4_u' { Lexeme _ (TKeyword "f32x4.convert_i32x4_u") }
'f64x2.convert_low_i32x4_s' { Lexeme _ (TKeyword "f64x2.convert_low_i32x4_s") } 'f64x2.convert_low_i32x4_s' { Lexeme _ (TKeyword "f64x2.convert_low_i32x4_s") }
'f64x2.convert_low_i32x4_u' { Lexeme _ (TKeyword "f64x2.convert_low_i32x4_u") } 'f64x2.convert_low_i32x4_u' { Lexeme _ (TKeyword "f64x2.convert_low_i32x4_u") }
'i8x16.narrow_i16x8_s'{ Lexeme _ (TKeyword "i8x16.narrow_i16x8_s") } 'i8x16.narrow_i16x8_s' { Lexeme _ (TKeyword "i8x16.narrow_i16x8_s") }
'i8x16.narrow_i16x8_u'{ Lexeme _ (TKeyword "i8x16.narrow_i16x8_u") } 'i8x16.narrow_i16x8_u' { Lexeme _ (TKeyword "i8x16.narrow_i16x8_u") }
'i16x8.narrow_i32x4_s'{ Lexeme _ (TKeyword "i16x8.narrow_i32x4_s") } 'i16x8.narrow_i32x4_s' { Lexeme _ (TKeyword "i16x8.narrow_i32x4_s") }
'i16x8.narrow_i32x4_u'{ Lexeme _ (TKeyword "i16x8.narrow_i32x4_u") } 'i16x8.narrow_i32x4_u' { Lexeme _ (TKeyword "i16x8.narrow_i32x4_u") }
'f64x2.promote_low_f32x4'{ Lexeme _ (TKeyword "f64x2.promote_low_f32x4") } 'f64x2.promote_low_f32x4' { Lexeme _ (TKeyword "f64x2.promote_low_f32x4") }
'f32x4.demote_f64x2_zero'{ Lexeme _ (TKeyword "f32x4.demote_f64x2_zero") } 'f32x4.demote_f64x2_zero' { Lexeme _ (TKeyword "f32x4.demote_f64x2_zero") }
'f32.demote_f64' { Lexeme _ (TKeyword "f32.demote_f64") } 'f32.demote_f64' { Lexeme _ (TKeyword "f32.demote_f64") }
'f64.convert_i32_s' { Lexeme _ (TKeyword "f64.convert_i32_s") } 'f64.convert_i32_s' { Lexeme _ (TKeyword "f64.convert_i32_s") }
'f64.convert_i32_u' { Lexeme _ (TKeyword "f64.convert_i32_u") } 'f64.convert_i32_u' { Lexeme _ (TKeyword "f64.convert_i32_u") }
@@ -391,10 +391,10 @@ import Language.Wasm.Lexer (
'i64x2.splat' { Lexeme _ (TKeyword "i64x2.splat") } 'i64x2.splat' { Lexeme _ (TKeyword "i64x2.splat") }
'f32x4.splat' { Lexeme _ (TKeyword "f32x4.splat") } 'f32x4.splat' { Lexeme _ (TKeyword "f32x4.splat") }
'f64x2.splat' { Lexeme _ (TKeyword "f64x2.splat") } 'f64x2.splat' { Lexeme _ (TKeyword "f64x2.splat") }
'i8x16.extract_lane_u'{ Lexeme _ (TKeyword "i8x16.extract_lane_u") } 'i8x16.extract_lane_u' { Lexeme _ (TKeyword "i8x16.extract_lane_u") }
'i16x8.extract_lane_u'{ Lexeme _ (TKeyword "i16x8.extract_lane_u") } 'i16x8.extract_lane_u' { Lexeme _ (TKeyword "i16x8.extract_lane_u") }
'i8x16.extract_lane_s'{ Lexeme _ (TKeyword "i8x16.extract_lane_s") } 'i8x16.extract_lane_s' { Lexeme _ (TKeyword "i8x16.extract_lane_s") }
'i16x8.extract_lane_s'{ Lexeme _ (TKeyword "i16x8.extract_lane_s") } 'i16x8.extract_lane_s' { Lexeme _ (TKeyword "i16x8.extract_lane_s") }
'i32x4.extract_lane' { Lexeme _ (TKeyword "i32x4.extract_lane") } 'i32x4.extract_lane' { Lexeme _ (TKeyword "i32x4.extract_lane") }
'i64x2.extract_lane' { Lexeme _ (TKeyword "i64x2.extract_lane") } 'i64x2.extract_lane' { Lexeme _ (TKeyword "i64x2.extract_lane") }
'f32x4.extract_lane' { Lexeme _ (TKeyword "f32x4.extract_lane") } 'f32x4.extract_lane' { Lexeme _ (TKeyword "f32x4.extract_lane") }
@@ -586,6 +586,8 @@ import Language.Wasm.Lexer (
'i64x2.extend_low_i32x4_u' { Lexeme _ (TKeyword "i64x2.extend_low_i32x4_u") } '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_s' { Lexeme _ (TKeyword "i32x4.trunc_sat_f32x4_s") }
'i32x4.trunc_sat_f32x4_u' { Lexeme _ (TKeyword "i32x4.trunc_sat_f32x4_u") } 'i32x4.trunc_sat_f32x4_u' { Lexeme _ (TKeyword "i32x4.trunc_sat_f32x4_u") }
'i32x4.trunc_sat_f64x2_s_zero' { Lexeme _ (TKeyword "i32x4.trunc_sat_f64x2_s_zero") }
'i32x4.trunc_sat_f64x2_u_zero' { Lexeme _ (TKeyword "i32x4.trunc_sat_f64x2_u_zero") }
-- script extension -- script extension
'binary' { Lexeme _ (TKeyword "binary") } 'binary' { Lexeme _ (TKeyword "binary") }
'quote' { Lexeme _ (TKeyword "quote") } 'quote' { Lexeme _ (TKeyword "quote") }
@@ -1202,8 +1204,10 @@ plaininstr :: { PlainInstr }
| 'i64x2.extend_high_i32x4_u' { V128IExtend I64x2 I32x4 True False } | 'i64x2.extend_high_i32x4_u' { V128IExtend I64x2 I32x4 True False }
| 'i64x2.extend_low_i32x4_s' { V128IExtend I64x2 I32x4 False True } | 'i64x2.extend_low_i32x4_s' { V128IExtend I64x2 I32x4 False True }
| 'i64x2.extend_low_i32x4_u' { V128IExtend I64x2 I32x4 False False } | 'i64x2.extend_low_i32x4_u' { V128IExtend I64x2 I32x4 False False }
| 'i32x4.trunc_sat_f32x4_s' { I32x4TruncSatF32x4 True } | 'i32x4.trunc_sat_f32x4_s' { I32x4TruncSatF True BS32 }
| 'i32x4.trunc_sat_f32x4_u' { I32x4TruncSatF32x4 False } | 'i32x4.trunc_sat_f32x4_u' { I32x4TruncSatF False BS32 }
| 'i32x4.trunc_sat_f64x2_s_zero' { I32x4TruncSatF True BS64 }
| 'i32x4.trunc_sat_f64x2_u_zero' { I32x4TruncSatF False BS64 }
typeuse(next) typeuse(next)
: '(' typeuse1(folded_instr_list(next), instruction_list(next)) { : '(' typeuse1(folded_instr_list(next), instruction_list(next)) {
@@ -1938,7 +1942,7 @@ data PlainInstr =
| F64x2PromoteLowF32x4 | F64x2PromoteLowF32x4
| F32x4DemoteF64x2Zero | F32x4DemoteF64x2Zero
| V128IExtend SimdShape SimdShape {- high -} Bool {- signed -} Bool | V128IExtend SimdShape SimdShape {- high -} Bool {- signed -} Bool
| I32x4TruncSatF32x4 {- signed -} Bool | I32x4TruncSatF {- signed -} Bool {- Float Size -} BitSize
deriving (Show, Eq) deriving (Show, Eq)
data TypeDef = TypeDef (Maybe Ident) FuncType deriving (Show, Eq) data TypeDef = TypeDef (Maybe Ident) FuncType deriving (Show, Eq)
@@ -2545,7 +2549,7 @@ desugarize fields = do
synInstrToStruct _ (PlainInstr F32x4DemoteF64x2Zero) = return $ S.F32x4DemoteF64x2Zero synInstrToStruct _ (PlainInstr F32x4DemoteF64x2Zero) = return $ S.F32x4DemoteF64x2Zero
synInstrToStruct _ (PlainInstr (V128Narrow t f s)) = return $ S.V128Narrow t f s 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 (V128IExtend t f h s)) = return $ S.V128IExtend t f h s
synInstrToStruct _ (PlainInstr (I32x4TruncSatF32x4 s)) = return $ S.I32x4TruncSatF32x4 s synInstrToStruct _ (PlainInstr (I32x4TruncSatF s sz)) = return $ S.I32x4TruncSatF s sz
synInstrToStruct ctx@FunCtx { ctxMod = Module { types } } BlockInstr {label, blockType, body} = do synInstrToStruct ctx@FunCtx { ctxMod = Module { types } } BlockInstr {label, blockType, body} = do
let ctx' = ctx { ctxLabels = label : ctxLabels ctx } let ctx' = ctx { ctxLabels = label : ctxLabels ctx }
bt <- case blockType of bt <- case blockType of
+1 -1
View File
@@ -276,7 +276,7 @@ data Instruction index =
| F64x2PromoteLowF32x4 | F64x2PromoteLowF32x4
| F32x4DemoteF64x2Zero | F32x4DemoteF64x2Zero
| V128IExtend SimdShape SimdShape {- high -} Bool {- signed -} Bool | V128IExtend SimdShape SimdShape {- high -} Bool {- signed -} Bool
| I32x4TruncSatF32x4 {- signed -} Bool | I32x4TruncSatF {- signed -} Bool {- Float Size -} BitSize
deriving (Show, Eq, Generic, NFData) deriving (Show, Eq, Generic, NFData)
type Expression = [Instruction Natural] type Expression = [Instruction Natural]
+1 -1
View File
@@ -629,7 +629,7 @@ getInstrType _ F32x4DemoteF64x2Zero =
return $ V128 ==> V128 return $ V128 ==> V128
getInstrType _ (V128IExtend _ _ _ _) = getInstrType _ (V128IExtend _ _ _ _) =
return $ V128 ==> V128 return $ V128 ==> V128
getInstrType _ (I32x4TruncSatF32x4 _) = getInstrType _ (I32x4TruncSatF _ _) =
return $ V128 ==> V128 return $ V128 ==> V128
getShapeElemType :: SimdShape -> ValueType getShapeElemType :: SimdShape -> ValueType
+1 -1
View File
@@ -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_i32x4_trunc_sat_f32x4.wast"] -- let files = ["simd_i32x4_trunc_sat_f64x2.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