implement unary float operations for simd

This commit is contained in:
Ilya Rezvov
2023-09-10 14:27:28 -06:00
parent 0d8159e553
commit a4a96af6aa
4 changed files with 33 additions and 10 deletions
+22
View File
@@ -1682,6 +1682,28 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct
return $ Done ctx { stack = VF64 (nearest v) : rest }
step ctx@EvalCtx{ stack = (VF64 v:rest) } (FUnOp BS64 FSqrt) =
return $ Done ctx { stack = VF64 (sqrt v) : rest }
step ctx@EvalCtx{ stack = (VV128 v:rest) } (FUnOp (BS128 shape) FNeg) =
let r = case shape of
F32x4 -> ByteArray.byteArrayFromList
$ floatToWord . negate . wordToFloat . ByteArray.indexByteArray @Word32 v
<$> [0..3]
F64x2 -> ByteArray.byteArrayFromList
$ doubleToWord . negate . 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
$ floatToWord . sqrt . wordToFloat . ByteArray.indexByteArray @Word32 v
<$> [0..3]
F64x2 -> ByteArray.byteArrayFromList
$ doubleToWord . sqrt . wordToDouble . ByteArray.indexByteArray @Word64 v
<$> [0..1]
_ -> error "impossible due to validation"
in
return $ Done ctx { stack = VV128 r : rest }
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FBinOp BS32 FAdd) =
return $ Done ctx { stack = VF32 (v1 + v2) : rest }
step ctx@EvalCtx{ stack = (VF32 v2:VF32 v1:rest) } (FBinOp BS32 FSub) =
+6 -4
View File
@@ -226,11 +226,13 @@ readHexFloat toFloat sz expLimit manitisaSize str = do
then ([True], 0, exp' + 1)
else (rounded, 1, exp')
else (rounded, 0, exp')
if exp'' > expLimit || exp'' < (negate $ expLimit + manitisaSize) then Left "constant out of range" else return ()
if exp'' >= (negate $ expLimit - 1)
then return $ toFloat $ sign .|. ((fromIntegral $ exp'' + expLimit) `shiftL` manitisaSize) .|. ((fromBits (tail bits') + a) `shiftL` (manitisaSize + 1 - length bits'))
e <- if exp'' > expLimit then Left "const out of range"
else if exp'' < (negate $ expLimit + manitisaSize) then return $ negate $ expLimit + manitisaSize + 1
else return exp''
if e >= (negate $ expLimit - 1)
then return $ toFloat $ sign .|. ((fromIntegral $ e + expLimit) `shiftL` manitisaSize) .|. ((fromBits (tail bits') + a) `shiftL` (manitisaSize + 1 - length bits'))
else do
let shift = expLimit + manitisaSize - length bits' - abs exp''
let shift = expLimit + manitisaSize - length bits' - abs e
if shift < 0
then return $ toFloat sign
else return $ toFloat $ sign .|. ((fromBits bits' + a) `shiftL` shift)
+4 -5
View File
@@ -164,13 +164,12 @@ runScript onAssertFail script = do
isValueMatch val v@(Parser.ExactValue _) = isValueEqual val $ asArg v
isValueMatch (Interpreter.VF32 v) Parser.CanonicalNan = identicalIEEE v nan || identicalIEEE v (abs nan)
isValueMatch (Interpreter.VF32 v) Parser.ArithmeticNan =
-- floatToWord v .&. floatToWord (abs nan) == floatToWord (abs nan)
isNaN v
let posNan = 0x7F800000 in
floatToWord v .&. posNan == posNan
isValueMatch (Interpreter.VF64 v) Parser.CanonicalNan = identicalIEEE v nan || identicalIEEE v (abs nan)
isValueMatch (Interpreter.VF64 v) Parser.ArithmeticNan =
-- let posNan = doubleToWord (abs nan) in
-- doubleToWord v .&. posNan == posNan
isNaN v
let posNan = 0x7FF0000000000000 in
doubleToWord v .&. posNan == posNan
isValueMatch (Interpreter.VV128 v) (Parser.VectorPat Struct.F32x4 pat) =
let vals = Interpreter.VF32 . wordToFloat . ByteArray.indexByteArray v <$> [0..3] in
and $ zipWith isValueMatch vals pat
+1 -1
View File
@@ -20,7 +20,7 @@ main = do
filter (List.isPrefixOf "simd") .
filter (List.isSuffixOf ".wast")
<$> Directory.listDirectory "tests/spec"
let files = ["simd_f32x4_arith.wast"]
-- let files = ["simd_f64x2_arith.wast"]
scriptTestCases <- (`mapM` files) $ \file -> do
test <- LBS.readFile ("tests/spec/" ++ file)
return $ testCase file $ do