implement extract_lane and replace_lane
This commit is contained in:
@@ -1574,6 +1574,21 @@ eval budget store inst FunctionInstance { funcType, moduleInstance, code = Funct
|
||||
ByteArray.unsafeFreezeByteArray arr
|
||||
_ -> error "impossible due to validation"
|
||||
return $ Done ctx { stack = VV128 val : rest }
|
||||
step ctx@EvalCtx{ stack = (VV128 v:rest) } V128AnyTrue =
|
||||
let w0 = ByteArray.indexByteArray @Word64 v 0 in
|
||||
let w1 = ByteArray.indexByteArray @Word64 v 1 in
|
||||
let r = if w0 == 0 && w1 == 0 then 0 else 1 in
|
||||
return $ Done ctx { stack = VI32 r : rest }
|
||||
step ctx@EvalCtx{ stack = (VV128 v:rest) } (V128AllTrue shape) =
|
||||
let r = case shape of
|
||||
I8x16 -> all (/= 0) $ ByteArray.indexByteArray @Word8 v <$> [0..15]
|
||||
I16x8 -> all (/= 0) $ ByteArray.indexByteArray @Word16 v <$> [0..8]
|
||||
I32x4 -> all (/= 0) $ ByteArray.indexByteArray @Word32 v <$> [0..4]
|
||||
I64x2 -> all (/= 0) $ ByteArray.indexByteArray @Word64 v <$> [0..2]
|
||||
F32x4 -> all (/= 0) $ wordToFloat . ByteArray.indexByteArray @Word32 v <$> [0..4]
|
||||
F64x2 -> all (/= 0) $ wordToDouble . ByteArray.indexByteArray @Word64 v <$> [0..2]
|
||||
in
|
||||
return $ Done ctx { stack = VI32 (if r then 1 else 0) : rest }
|
||||
step EvalCtx{ stack } instr = error $ "Error during evaluation of instruction: " ++ show instr ++ ". Stack " ++ show stack
|
||||
eval _ _ _ HostInstance { funcType, hostCode } args = Just <$> hostCode args
|
||||
|
||||
|
||||
@@ -80,8 +80,10 @@ tokens :-
|
||||
<0> @id { tokenStr TId }
|
||||
<0> "(" { constToken TOpenBracket }
|
||||
<0> ")" { constToken TCloseBracket }
|
||||
<0> $sign? @num { parseDecimalSignedInt }
|
||||
<0> $sign? "0x" @hexnum { parseHexalSignedInt }
|
||||
<0> @num { parseDecimalSignedInt True }
|
||||
<0> "0x" @hexnum { parseHexalSignedInt True }
|
||||
<0> $sign @num { parseDecimalSignedInt False }
|
||||
<0> $sign "0x" @hexnum { parseHexalSignedInt False }
|
||||
<0> $sign? @float { parseDecFloat }
|
||||
<0> $sign? @hexfloat { parseHexFloat }
|
||||
<0, blockComment> @startblockcomment { startBlockComment }
|
||||
@@ -130,11 +132,11 @@ parseSign str =
|
||||
{-# SPECIALIZE parseSign :: LBS.ByteString -> ((Integer -> Integer), Int64) #-}
|
||||
{-# SPECIALIZE parseSign :: LBS.ByteString -> ((Double -> Double), Int64) #-}
|
||||
|
||||
parseHexalSignedInt :: AlexAction Lexeme
|
||||
parseHexalSignedInt = token $ \(pos, _, s, _) len ->
|
||||
parseHexalSignedInt :: Bool -> AlexAction Lexeme
|
||||
parseHexalSignedInt nat = token $ \(pos, _, s, _) len ->
|
||||
let (sign, slen) = parseSign s in
|
||||
let num = readHexFromPrefix (len - 2 - slen) $ LBSUtf8.drop (2 + slen) s in
|
||||
Lexeme (Just pos) $ TIntLit $ sign num
|
||||
Lexeme (Just pos) $ TIntLit nat $ sign num
|
||||
|
||||
parseNanSigned :: AlexAction Lexeme
|
||||
parseNanSigned = token $ \(pos, _, s, _) len ->
|
||||
@@ -146,11 +148,11 @@ parseNanSigned = token $ \(pos, _, s, _) len ->
|
||||
let num = readHexFromPrefix (len - 6 - slen) $ LBSUtf8.drop (6 + slen) s in
|
||||
Lexeme (Just pos) $ TFloatLit $ NanRep $ NanHex sign $ fromIntegral num
|
||||
|
||||
parseDecimalSignedInt :: AlexAction Lexeme
|
||||
parseDecimalSignedInt = token $ \(pos, _, s, _) len ->
|
||||
parseDecimalSignedInt :: Bool -> AlexAction Lexeme
|
||||
parseDecimalSignedInt nat = token $ \(pos, _, s, _) len ->
|
||||
let (sign, slen) = parseSign s in
|
||||
let num = readDecFromPrefix (len - slen) $ LBSUtf8.drop slen s in
|
||||
Lexeme (Just pos) $ TIntLit $ sign num
|
||||
Lexeme (Just pos) $ TIntLit nat $ sign num
|
||||
|
||||
parseDecFloat :: AlexAction Lexeme
|
||||
parseDecFloat = token $ \(pos, _, s, _) len ->
|
||||
@@ -364,7 +366,7 @@ data NaN
|
||||
deriving (Show, Eq)
|
||||
|
||||
data Token = TKeyword LBS.ByteString
|
||||
| TIntLit Integer
|
||||
| TIntLit {- Natural -} Bool Integer
|
||||
| TFloatLit FloatRep
|
||||
| TStringLit LBS.ByteString
|
||||
| TId LBS.ByteString
|
||||
|
||||
+198
-188
@@ -408,7 +408,8 @@ import Language.Wasm.Lexer (
|
||||
'output' { Lexeme _ (TKeyword "output") }
|
||||
-- script extension end
|
||||
id { Lexeme _ (TId $$) }
|
||||
int { Lexeme _ (TIntLit $$) }
|
||||
signed { Lexeme _ (TIntLit False $$) }
|
||||
nat { Lexeme _ (TIntLit True $$) }
|
||||
f64 { Lexeme _ (TFloatLit $$) }
|
||||
offset { Lexeme _ (TKeyword (asOffset -> Just $$)) }
|
||||
align { Lexeme _ (TKeyword (asAlign -> Just $$)) }
|
||||
@@ -439,6 +440,10 @@ valtype :: { ValueType }
|
||||
| 'funcref' { Func }
|
||||
| 'externref' { Extern }
|
||||
|
||||
int :: {Integer}
|
||||
: signed { $1 }
|
||||
| nat { $1 }
|
||||
|
||||
index :: { Index }
|
||||
: u32 { Index $1 }
|
||||
| ident { Named $1 }
|
||||
@@ -524,6 +529,9 @@ v128_const :: { V128Rep }
|
||||
F64x2Const [$2, $3]
|
||||
}
|
||||
|
||||
lane_index :: { Natural }
|
||||
: nat {% if $1 < 256 then Right $ fromIntegral $1 else Left "malformed lane index"}
|
||||
|
||||
plaininstr :: { PlainInstr }
|
||||
-- control instructions
|
||||
: 'unreachable' { Unreachable }
|
||||
@@ -583,196 +591,198 @@ plaininstr :: { PlainInstr }
|
||||
Nothing -> TableInit (Index 0) $2
|
||||
Just elemIdx -> TableInit $2 elemIdx
|
||||
}
|
||||
| 'table.get' opt(index) { TableGet (fromMaybe (Index 0) $2) }
|
||||
| 'table.set' opt(index) { TableSet (fromMaybe (Index 0) $2) }
|
||||
| 'table.get' opt(index) { TableGet (fromMaybe (Index 0) $2) }
|
||||
| 'table.set' opt(index) { TableSet (fromMaybe (Index 0) $2) }
|
||||
| 'table.copy' opt(index) opt(index) { TableCopy (fromMaybe (Index 0) $2) (fromMaybe (Index 0) $3) }
|
||||
| 'table.fill' opt(index) { TableFill (fromMaybe (Index 0) $2) }
|
||||
| 'table.size' opt(index) { TableSize (fromMaybe (Index 0) $2) }
|
||||
| 'table.grow' opt(index) { TableGrow (fromMaybe (Index 0) $2) }
|
||||
| 'elem.drop' index { ElemDrop $2 }
|
||||
-- numeric instructions
|
||||
| 'i32.const' int32 { I32Const $2 }
|
||||
| 'i64.const' int64 { I64Const $2 }
|
||||
| 'f32.const' float32 { F32Const $2 }
|
||||
| 'f64.const' float64 { F64Const $2 }
|
||||
| 'v128.const' v128_const { V128Const $2 }
|
||||
| 'i32.clz' { IUnOp BS32 IClz }
|
||||
| 'i32.ctz' { IUnOp BS32 ICtz }
|
||||
| 'i32.popcnt' { IUnOp BS32 IPopcnt }
|
||||
| 'i32.extend8_s' { IUnOp BS32 IExtend8S }
|
||||
| 'i32.extend16_s' { IUnOp BS32 IExtend16S }
|
||||
| 'i32.add' { IBinOp BS32 IAdd }
|
||||
| 'i32.sub' { IBinOp BS32 ISub }
|
||||
| 'i32.mul' { IBinOp BS32 IMul }
|
||||
| 'i32.div_s' { IBinOp BS32 IDivS }
|
||||
| 'i32.div_u' { IBinOp BS32 IDivU }
|
||||
| 'i32.rem_s' { IBinOp BS32 IRemS }
|
||||
| 'i32.rem_u' { IBinOp BS32 IRemU }
|
||||
| 'i32.and' { IBinOp BS32 IAnd }
|
||||
| 'i32.or' { IBinOp BS32 IOr }
|
||||
| 'i32.xor' { IBinOp BS32 IXor }
|
||||
| 'i32.shl' { IBinOp BS32 IShl }
|
||||
| 'i32.shr_s' { IBinOp BS32 IShrS }
|
||||
| 'i32.shr_u' { IBinOp BS32 IShrU }
|
||||
| 'i32.rotl' { IBinOp BS32 IRotl }
|
||||
| 'i32.rotr' { IBinOp BS32 IRotr }
|
||||
| 'i64.clz' { IUnOp BS64 IClz }
|
||||
| 'i64.ctz' { IUnOp BS64 ICtz }
|
||||
| 'i64.popcnt' { IUnOp BS64 IPopcnt }
|
||||
| 'i64.extend8_s' { IUnOp BS64 IExtend8S }
|
||||
| 'i64.extend16_s' { IUnOp BS64 IExtend16S }
|
||||
| 'i64.extend32_s' { IUnOp BS64 IExtend32S }
|
||||
| 'i64.add' { IBinOp BS64 IAdd }
|
||||
| 'i64.sub' { IBinOp BS64 ISub }
|
||||
| 'i64.mul' { IBinOp BS64 IMul }
|
||||
| 'i64.div_s' { IBinOp BS64 IDivS }
|
||||
| 'i64.div_u' { IBinOp BS64 IDivU }
|
||||
| 'i64.rem_s' { IBinOp BS64 IRemS }
|
||||
| 'i64.rem_u' { IBinOp BS64 IRemU }
|
||||
| 'i64.and' { IBinOp BS64 IAnd }
|
||||
| 'i64.or' { IBinOp BS64 IOr }
|
||||
| 'i64.xor' { IBinOp BS64 IXor }
|
||||
| 'i64.shl' { IBinOp BS64 IShl }
|
||||
| 'i64.shr_s' { IBinOp BS64 IShrS }
|
||||
| 'i64.shr_u' { IBinOp BS64 IShrU }
|
||||
| 'i64.rotl' { IBinOp BS64 IRotl }
|
||||
| 'i64.rotr' { IBinOp BS64 IRotr }
|
||||
| 'f32.abs' { FUnOp BS32 FAbs }
|
||||
| 'f32.neg' { FUnOp BS32 FNeg }
|
||||
| 'f32.ceil' { FUnOp BS32 FCeil }
|
||||
| 'f32.floor' { FUnOp BS32 FFloor }
|
||||
| 'f32.trunc' { FUnOp BS32 FTrunc }
|
||||
| 'f32.nearest' { FUnOp BS32 FNearest }
|
||||
| 'f32.sqrt' { FUnOp BS32 FSqrt }
|
||||
| 'f32.add' { FBinOp BS32 FAdd }
|
||||
| 'f32.sub' { FBinOp BS32 FSub }
|
||||
| 'f32.mul' { FBinOp BS32 FMul }
|
||||
| 'f32.div' { FBinOp BS32 FDiv }
|
||||
| 'f32.min' { FBinOp BS32 FMin }
|
||||
| 'f32.max' { FBinOp BS32 FMax }
|
||||
| 'f32.copysign' { FBinOp BS32 FCopySign }
|
||||
| 'f64.abs' { FUnOp BS64 FAbs }
|
||||
| 'f64.neg' { FUnOp BS64 FNeg }
|
||||
| 'f64.ceil' { FUnOp BS64 FCeil }
|
||||
| 'f64.floor' { FUnOp BS64 FFloor }
|
||||
| 'f64.trunc' { FUnOp BS64 FTrunc }
|
||||
| 'f64.nearest' { FUnOp BS64 FNearest }
|
||||
| 'f64.sqrt' { FUnOp BS64 FSqrt }
|
||||
| 'f64.add' { FBinOp BS64 FAdd }
|
||||
| 'f64.sub' { FBinOp BS64 FSub }
|
||||
| 'f64.mul' { FBinOp BS64 FMul }
|
||||
| 'f64.div' { FBinOp BS64 FDiv }
|
||||
| 'f64.min' { FBinOp BS64 FMin }
|
||||
| 'f64.max' { FBinOp BS64 FMax }
|
||||
| 'f64.copysign' { FBinOp BS64 FCopySign }
|
||||
| 'i32.eqz' { I32Eqz }
|
||||
| 'i32.eq' { IRelOp BS32 IEq }
|
||||
| 'i32.ne' { IRelOp BS32 INe }
|
||||
| 'i32.lt_s' { IRelOp BS32 ILtS }
|
||||
| 'i32.lt_u' { IRelOp BS32 ILtU }
|
||||
| 'i32.gt_s' { IRelOp BS32 IGtS }
|
||||
| 'i32.gt_u' { IRelOp BS32 IGtU }
|
||||
| 'i32.le_s' { IRelOp BS32 ILeS }
|
||||
| 'i32.le_u' { IRelOp BS32 ILeU }
|
||||
| 'i32.ge_s' { IRelOp BS32 IGeS }
|
||||
| 'i32.ge_u' { IRelOp BS32 IGeU }
|
||||
| 'i64.eqz' { I64Eqz }
|
||||
| 'i64.eq' { IRelOp BS64 IEq }
|
||||
| 'i64.ne' { IRelOp BS64 INe }
|
||||
| 'i64.lt_s' { IRelOp BS64 ILtS }
|
||||
| 'i64.lt_u' { IRelOp BS64 ILtU }
|
||||
| 'i64.gt_s' { IRelOp BS64 IGtS }
|
||||
| 'i64.gt_u' { IRelOp BS64 IGtU }
|
||||
| 'i64.le_s' { IRelOp BS64 ILeS }
|
||||
| 'i64.le_u' { IRelOp BS64 ILeU }
|
||||
| 'i64.ge_s' { IRelOp BS64 IGeS }
|
||||
| 'i64.ge_u' { IRelOp BS64 IGeU }
|
||||
| 'f32.eq' { FRelOp BS32 FEq }
|
||||
| 'f32.ne' { FRelOp BS32 FNe }
|
||||
| 'f32.lt' { FRelOp BS32 FLt }
|
||||
| 'f32.gt' { FRelOp BS32 FGt }
|
||||
| 'f32.le' { FRelOp BS32 FLe }
|
||||
| 'f32.ge' { FRelOp BS32 FGe }
|
||||
| 'f64.eq' { FRelOp BS64 FEq }
|
||||
| 'f64.ne' { FRelOp BS64 FNe }
|
||||
| 'f64.lt' { FRelOp BS64 FLt }
|
||||
| 'f64.gt' { FRelOp BS64 FGt }
|
||||
| 'f64.le' { FRelOp BS64 FLe }
|
||||
| 'f64.ge' { FRelOp BS64 FGe }
|
||||
| 'i32.wrap_i64' { I32WrapI64 }
|
||||
| 'i32.trunc_f32_s' { ITruncFS BS32 BS32 }
|
||||
| 'i32.trunc_f32_u' { ITruncFU BS32 BS32 }
|
||||
| 'i32.trunc_f64_s' { ITruncFS BS32 BS64 }
|
||||
| 'i32.trunc_f64_u' { ITruncFU BS32 BS64 }
|
||||
| 'i32.trunc_sat_f32_s' { ITruncSatFS BS32 BS32 }
|
||||
| 'i32.trunc_sat_f32_u' { ITruncSatFU BS32 BS32 }
|
||||
| 'i32.trunc_sat_f64_s' { ITruncSatFS BS32 BS64 }
|
||||
| 'i32.trunc_sat_f64_u' { ITruncSatFU BS32 BS64 }
|
||||
| 'i64.extend_i32_s' { I64ExtendSI32 }
|
||||
| 'i64.extend_i32_u' { I64ExtendUI32 }
|
||||
| 'i64.trunc_f32_s' { ITruncFS BS64 BS32 }
|
||||
| 'i64.trunc_f32_u' { ITruncFU BS64 BS32 }
|
||||
| 'i64.trunc_f64_s' { ITruncFS BS64 BS64 }
|
||||
| 'i64.trunc_f64_u' { ITruncFU BS64 BS64 }
|
||||
| 'i64.trunc_sat_f32_s' { ITruncSatFS BS64 BS32 }
|
||||
| 'i64.trunc_sat_f32_u' { ITruncSatFU BS64 BS32 }
|
||||
| 'i64.trunc_sat_f64_s' { ITruncSatFS BS64 BS64 }
|
||||
| 'i64.trunc_sat_f64_u' { ITruncSatFU BS64 BS64 }
|
||||
| 'f32.convert_i32_s' { FConvertIS BS32 BS32 }
|
||||
| 'f32.convert_i32_u' { FConvertIU BS32 BS32 }
|
||||
| 'f32.convert_i64_s' { FConvertIS BS32 BS64 }
|
||||
| 'f32.convert_i64_u' { FConvertIU BS32 BS64 }
|
||||
| 'f32.demote_f64' { F32DemoteF64 }
|
||||
| 'f64.convert_i32_s' { FConvertIS BS64 BS32 }
|
||||
| 'f64.convert_i32_u' { FConvertIU BS64 BS32 }
|
||||
| 'f64.convert_i64_s' { FConvertIS BS64 BS64 }
|
||||
| 'f64.convert_i64_u' { FConvertIU BS64 BS64 }
|
||||
| 'f64.promote_f32' { F64PromoteF32 }
|
||||
| 'i32.reinterpret_f32' { IReinterpretF BS32 }
|
||||
| 'i64.reinterpret_f64' { IReinterpretF BS64 }
|
||||
| 'f32.reinterpret_i32' { FReinterpretI BS32 }
|
||||
| 'f64.reinterpret_i64' { FReinterpretI BS64 }
|
||||
| 'table.fill' opt(index) { TableFill (fromMaybe (Index 0) $2) }
|
||||
| 'table.size' opt(index) { TableSize (fromMaybe (Index 0) $2) }
|
||||
| 'table.grow' opt(index) { TableGrow (fromMaybe (Index 0) $2) }
|
||||
| 'elem.drop' index { ElemDrop $2 }
|
||||
-- numeric instructions
|
||||
| 'i32.const' int32 { I32Const $2 }
|
||||
| 'i64.const' int64 { I64Const $2 }
|
||||
| 'f32.const' float32 { F32Const $2 }
|
||||
| 'f64.const' float64 { F64Const $2 }
|
||||
| 'v128.const' v128_const { V128Const $2 }
|
||||
| 'i32.clz' { IUnOp BS32 IClz }
|
||||
| 'i32.ctz' { IUnOp BS32 ICtz }
|
||||
| 'i32.popcnt' { IUnOp BS32 IPopcnt }
|
||||
| 'i32.extend8_s' { IUnOp BS32 IExtend8S }
|
||||
| 'i32.extend16_s' { IUnOp BS32 IExtend16S }
|
||||
| 'i32.add' { IBinOp BS32 IAdd }
|
||||
| 'i32.sub' { IBinOp BS32 ISub }
|
||||
| 'i32.mul' { IBinOp BS32 IMul }
|
||||
| 'i32.div_s' { IBinOp BS32 IDivS }
|
||||
| 'i32.div_u' { IBinOp BS32 IDivU }
|
||||
| 'i32.rem_s' { IBinOp BS32 IRemS }
|
||||
| 'i32.rem_u' { IBinOp BS32 IRemU }
|
||||
| 'i32.and' { IBinOp BS32 IAnd }
|
||||
| 'i32.or' { IBinOp BS32 IOr }
|
||||
| 'i32.xor' { IBinOp BS32 IXor }
|
||||
| 'i32.shl' { IBinOp BS32 IShl }
|
||||
| 'i32.shr_s' { IBinOp BS32 IShrS }
|
||||
| 'i32.shr_u' { IBinOp BS32 IShrU }
|
||||
| 'i32.rotl' { IBinOp BS32 IRotl }
|
||||
| 'i32.rotr' { IBinOp BS32 IRotr }
|
||||
| 'i64.clz' { IUnOp BS64 IClz }
|
||||
| 'i64.ctz' { IUnOp BS64 ICtz }
|
||||
| 'i64.popcnt' { IUnOp BS64 IPopcnt }
|
||||
| 'i64.extend8_s' { IUnOp BS64 IExtend8S }
|
||||
| 'i64.extend16_s' { IUnOp BS64 IExtend16S }
|
||||
| 'i64.extend32_s' { IUnOp BS64 IExtend32S }
|
||||
| 'i64.add' { IBinOp BS64 IAdd }
|
||||
| 'i64.sub' { IBinOp BS64 ISub }
|
||||
| 'i64.mul' { IBinOp BS64 IMul }
|
||||
| 'i64.div_s' { IBinOp BS64 IDivS }
|
||||
| 'i64.div_u' { IBinOp BS64 IDivU }
|
||||
| 'i64.rem_s' { IBinOp BS64 IRemS }
|
||||
| 'i64.rem_u' { IBinOp BS64 IRemU }
|
||||
| 'i64.and' { IBinOp BS64 IAnd }
|
||||
| 'i64.or' { IBinOp BS64 IOr }
|
||||
| 'i64.xor' { IBinOp BS64 IXor }
|
||||
| 'i64.shl' { IBinOp BS64 IShl }
|
||||
| 'i64.shr_s' { IBinOp BS64 IShrS }
|
||||
| 'i64.shr_u' { IBinOp BS64 IShrU }
|
||||
| 'i64.rotl' { IBinOp BS64 IRotl }
|
||||
| 'i64.rotr' { IBinOp BS64 IRotr }
|
||||
| 'f32.abs' { FUnOp BS32 FAbs }
|
||||
| 'f32.neg' { FUnOp BS32 FNeg }
|
||||
| 'f32.ceil' { FUnOp BS32 FCeil }
|
||||
| 'f32.floor' { FUnOp BS32 FFloor }
|
||||
| 'f32.trunc' { FUnOp BS32 FTrunc }
|
||||
| 'f32.nearest' { FUnOp BS32 FNearest }
|
||||
| 'f32.sqrt' { FUnOp BS32 FSqrt }
|
||||
| 'f32.add' { FBinOp BS32 FAdd }
|
||||
| 'f32.sub' { FBinOp BS32 FSub }
|
||||
| 'f32.mul' { FBinOp BS32 FMul }
|
||||
| 'f32.div' { FBinOp BS32 FDiv }
|
||||
| 'f32.min' { FBinOp BS32 FMin }
|
||||
| 'f32.max' { FBinOp BS32 FMax }
|
||||
| 'f32.copysign' { FBinOp BS32 FCopySign }
|
||||
| 'f64.abs' { FUnOp BS64 FAbs }
|
||||
| 'f64.neg' { FUnOp BS64 FNeg }
|
||||
| 'f64.ceil' { FUnOp BS64 FCeil }
|
||||
| 'f64.floor' { FUnOp BS64 FFloor }
|
||||
| 'f64.trunc' { FUnOp BS64 FTrunc }
|
||||
| 'f64.nearest' { FUnOp BS64 FNearest }
|
||||
| 'f64.sqrt' { FUnOp BS64 FSqrt }
|
||||
| 'f64.add' { FBinOp BS64 FAdd }
|
||||
| 'f64.sub' { FBinOp BS64 FSub }
|
||||
| 'f64.mul' { FBinOp BS64 FMul }
|
||||
| 'f64.div' { FBinOp BS64 FDiv }
|
||||
| 'f64.min' { FBinOp BS64 FMin }
|
||||
| 'f64.max' { FBinOp BS64 FMax }
|
||||
| 'f64.copysign' { FBinOp BS64 FCopySign }
|
||||
| 'i32.eqz' { I32Eqz }
|
||||
| 'i32.eq' { IRelOp BS32 IEq }
|
||||
| 'i32.ne' { IRelOp BS32 INe }
|
||||
| 'i32.lt_s' { IRelOp BS32 ILtS }
|
||||
| 'i32.lt_u' { IRelOp BS32 ILtU }
|
||||
| 'i32.gt_s' { IRelOp BS32 IGtS }
|
||||
| 'i32.gt_u' { IRelOp BS32 IGtU }
|
||||
| 'i32.le_s' { IRelOp BS32 ILeS }
|
||||
| 'i32.le_u' { IRelOp BS32 ILeU }
|
||||
| 'i32.ge_s' { IRelOp BS32 IGeS }
|
||||
| 'i32.ge_u' { IRelOp BS32 IGeU }
|
||||
| 'i64.eqz' { I64Eqz }
|
||||
| 'i64.eq' { IRelOp BS64 IEq }
|
||||
| 'i64.ne' { IRelOp BS64 INe }
|
||||
| 'i64.lt_s' { IRelOp BS64 ILtS }
|
||||
| 'i64.lt_u' { IRelOp BS64 ILtU }
|
||||
| 'i64.gt_s' { IRelOp BS64 IGtS }
|
||||
| 'i64.gt_u' { IRelOp BS64 IGtU }
|
||||
| 'i64.le_s' { IRelOp BS64 ILeS }
|
||||
| 'i64.le_u' { IRelOp BS64 ILeU }
|
||||
| 'i64.ge_s' { IRelOp BS64 IGeS }
|
||||
| 'i64.ge_u' { IRelOp BS64 IGeU }
|
||||
| 'f32.eq' { FRelOp BS32 FEq }
|
||||
| 'f32.ne' { FRelOp BS32 FNe }
|
||||
| 'f32.lt' { FRelOp BS32 FLt }
|
||||
| 'f32.gt' { FRelOp BS32 FGt }
|
||||
| 'f32.le' { FRelOp BS32 FLe }
|
||||
| 'f32.ge' { FRelOp BS32 FGe }
|
||||
| 'f64.eq' { FRelOp BS64 FEq }
|
||||
| 'f64.ne' { FRelOp BS64 FNe }
|
||||
| 'f64.lt' { FRelOp BS64 FLt }
|
||||
| 'f64.gt' { FRelOp BS64 FGt }
|
||||
| 'f64.le' { FRelOp BS64 FLe }
|
||||
| 'f64.ge' { FRelOp BS64 FGe }
|
||||
| 'i32.wrap_i64' { I32WrapI64 }
|
||||
| 'i32.trunc_f32_s' { ITruncFS BS32 BS32 }
|
||||
| 'i32.trunc_f32_u' { ITruncFU BS32 BS32 }
|
||||
| 'i32.trunc_f64_s' { ITruncFS BS32 BS64 }
|
||||
| 'i32.trunc_f64_u' { ITruncFU BS32 BS64 }
|
||||
| 'i32.trunc_sat_f32_s' { ITruncSatFS BS32 BS32 }
|
||||
| 'i32.trunc_sat_f32_u' { ITruncSatFU BS32 BS32 }
|
||||
| 'i32.trunc_sat_f64_s' { ITruncSatFS BS32 BS64 }
|
||||
| 'i32.trunc_sat_f64_u' { ITruncSatFU BS32 BS64 }
|
||||
| 'i64.extend_i32_s' { I64ExtendSI32 }
|
||||
| 'i64.extend_i32_u' { I64ExtendUI32 }
|
||||
| 'i64.trunc_f32_s' { ITruncFS BS64 BS32 }
|
||||
| 'i64.trunc_f32_u' { ITruncFU BS64 BS32 }
|
||||
| 'i64.trunc_f64_s' { ITruncFS BS64 BS64 }
|
||||
| 'i64.trunc_f64_u' { ITruncFU BS64 BS64 }
|
||||
| 'i64.trunc_sat_f32_s' { ITruncSatFS BS64 BS32 }
|
||||
| 'i64.trunc_sat_f32_u' { ITruncSatFU BS64 BS32 }
|
||||
| 'i64.trunc_sat_f64_s' { ITruncSatFS BS64 BS64 }
|
||||
| 'i64.trunc_sat_f64_u' { ITruncSatFU BS64 BS64 }
|
||||
| 'f32.convert_i32_s' { FConvertIS BS32 BS32 }
|
||||
| 'f32.convert_i32_u' { FConvertIU BS32 BS32 }
|
||||
| 'f32.convert_i64_s' { FConvertIS BS32 BS64 }
|
||||
| 'f32.convert_i64_u' { FConvertIU BS32 BS64 }
|
||||
| 'f32.demote_f64' { F32DemoteF64 }
|
||||
| 'f64.convert_i32_s' { FConvertIS BS64 BS32 }
|
||||
| 'f64.convert_i32_u' { FConvertIU BS64 BS32 }
|
||||
| 'f64.convert_i64_s' { FConvertIS BS64 BS64 }
|
||||
| 'f64.convert_i64_u' { FConvertIU BS64 BS64 }
|
||||
| 'f64.promote_f32' { F64PromoteF32 }
|
||||
| 'i32.reinterpret_f32' { IReinterpretF BS32 }
|
||||
| 'i64.reinterpret_f64' { IReinterpretF BS64 }
|
||||
| 'f32.reinterpret_i32' { FReinterpretI BS32 }
|
||||
| 'f64.reinterpret_i64' { FReinterpretI BS64 }
|
||||
-- simd
|
||||
| 'i8x16.shuffle' i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 i8 {
|
||||
I8x16Shuffle $ map fromIntegral
|
||||
[$2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17]
|
||||
| 'i8x16.shuffle' u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 u32 {%
|
||||
let idxs = [$2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17] in
|
||||
if any (\i -> i < 0 || i > 0xFF) idxs
|
||||
then Left "malformed lane index"
|
||||
else Right $ I8x16Shuffle $ map fromIntegral idxs
|
||||
}
|
||||
| 'i8x16.swizzle' { I8x16Swizzle }
|
||||
| 'v128.any_true' { V128AnyTrue }
|
||||
| 'i8x16.splat' { V128Splat I8x16 }
|
||||
| 'i16x8.splat' { V128Splat I16x8 }
|
||||
| 'i32x4.splat' { V128Splat I32x4 }
|
||||
| 'i64x2.splat' { V128Splat I64x2 }
|
||||
| 'f32x4.splat' { V128Splat F32x4 }
|
||||
| 'f64x2.splat' { V128Splat F64x2 }
|
||||
| 'i8x16.all_true' { V128AllTrue I8x16 }
|
||||
| 'i16x8.all_true' { V128AllTrue I16x8 }
|
||||
| 'i32x4.all_true' { V128AllTrue I32x4 }
|
||||
| 'i64x2.all_true' { V128AllTrue I64x2 }
|
||||
| 'f32x4.all_true' { V128AllTrue F32x4 }
|
||||
| 'f64x2.all_true' { V128AllTrue F64x2 }
|
||||
| 'i8x16.extract_lane_s' u32 { V128ExtractLane I8x16 $2 True }
|
||||
| 'i16x8.extract_lane_s' u32 { V128ExtractLane I16x8 $2 True }
|
||||
| 'i8x16.extract_lane_u' u32 { V128ExtractLane I8x16 $2 False }
|
||||
| 'i16x8.extract_lane_u' u32 { V128ExtractLane I16x8 $2 False }
|
||||
| 'i32x4.extract_lane' u32 { V128ExtractLane I32x4 $2 False }
|
||||
| 'i64x2.extract_lane' u32 { V128ExtractLane I64x2 $2 False }
|
||||
| 'f32x4.extract_lane' u32 { V128ExtractLane F32x4 $2 False }
|
||||
| 'f64x2.extract_lane' u32 { V128ExtractLane F64x2 $2 False }
|
||||
| 'i8x16.replace_lane' u32 { V128ReplaceLane I8x16 $2 }
|
||||
| 'i16x8.replace_lane' u32 { V128ReplaceLane I16x8 $2 }
|
||||
| 'i32x4.replace_lane' u32 { V128ReplaceLane I32x4 $2 }
|
||||
| 'i64x2.replace_lane' u32 { V128ReplaceLane I64x2 $2 }
|
||||
| 'f32x4.replace_lane' u32 { V128ReplaceLane F32x4 $2 }
|
||||
| 'f64x2.replace_lane' u32 { V128ReplaceLane F64x2 $2 }
|
||||
| 'i8x16.add' { IBinOp (BS128 I8x16) IAdd }
|
||||
| 'i16x8.add' { IBinOp (BS128 I16x8) IAdd }
|
||||
| 'i32x4.add' { IBinOp (BS128 I32x4) IAdd }
|
||||
| 'i64x2.add' { IBinOp (BS128 I64x2) IAdd }
|
||||
| 'i8x16.sub' { IBinOp (BS128 I8x16) ISub }
|
||||
| 'i16x8.sub' { IBinOp (BS128 I16x8) ISub }
|
||||
| 'i32x4.sub' { IBinOp (BS128 I32x4) ISub }
|
||||
| 'i64x2.sub' { IBinOp (BS128 I64x2) ISub }
|
||||
| 'i8x16.swizzle' { I8x16Swizzle }
|
||||
| 'v128.any_true' { V128AnyTrue }
|
||||
| 'i8x16.splat' { V128Splat I8x16 }
|
||||
| 'i16x8.splat' { V128Splat I16x8 }
|
||||
| 'i32x4.splat' { V128Splat I32x4 }
|
||||
| 'i64x2.splat' { V128Splat I64x2 }
|
||||
| 'f32x4.splat' { V128Splat F32x4 }
|
||||
| 'f64x2.splat' { V128Splat F64x2 }
|
||||
| 'i8x16.all_true' { V128AllTrue I8x16 }
|
||||
| 'i16x8.all_true' { V128AllTrue I16x8 }
|
||||
| 'i32x4.all_true' { V128AllTrue I32x4 }
|
||||
| 'i64x2.all_true' { V128AllTrue I64x2 }
|
||||
| 'f32x4.all_true' { V128AllTrue F32x4 }
|
||||
| 'f64x2.all_true' { V128AllTrue F64x2 }
|
||||
| 'i8x16.extract_lane_s' lane_index { V128ExtractLane I8x16 $2 True }
|
||||
| 'i16x8.extract_lane_s' lane_index { V128ExtractLane I16x8 $2 True }
|
||||
| 'i8x16.extract_lane_u' lane_index { V128ExtractLane I8x16 $2 False }
|
||||
| 'i16x8.extract_lane_u' lane_index { V128ExtractLane I16x8 $2 False }
|
||||
| 'i32x4.extract_lane' lane_index { V128ExtractLane I32x4 $2 False }
|
||||
| 'i64x2.extract_lane' lane_index { V128ExtractLane I64x2 $2 False }
|
||||
| 'f32x4.extract_lane' lane_index { V128ExtractLane F32x4 $2 False }
|
||||
| 'f64x2.extract_lane' lane_index { V128ExtractLane F64x2 $2 False }
|
||||
| 'i8x16.replace_lane' lane_index { V128ReplaceLane I8x16 $2 }
|
||||
| 'i16x8.replace_lane' lane_index { V128ReplaceLane I16x8 $2 }
|
||||
| 'i32x4.replace_lane' lane_index { V128ReplaceLane I32x4 $2 }
|
||||
| 'i64x2.replace_lane' lane_index { V128ReplaceLane I64x2 $2 }
|
||||
| 'f32x4.replace_lane' lane_index { V128ReplaceLane F32x4 $2 }
|
||||
| 'f64x2.replace_lane' lane_index { V128ReplaceLane F64x2 $2 }
|
||||
| 'i8x16.add' { IBinOp (BS128 I8x16) IAdd }
|
||||
| 'i16x8.add' { IBinOp (BS128 I16x8) IAdd }
|
||||
| 'i32x4.add' { IBinOp (BS128 I32x4) IAdd }
|
||||
| 'i64x2.add' { IBinOp (BS128 I64x2) IAdd }
|
||||
| 'i8x16.sub' { IBinOp (BS128 I8x16) ISub }
|
||||
| 'i16x8.sub' { IBinOp (BS128 I16x8) ISub }
|
||||
| 'i32x4.sub' { IBinOp (BS128 I32x4) ISub }
|
||||
| 'i64x2.sub' { IBinOp (BS128 I64x2) ISub }
|
||||
|
||||
typeuse(next)
|
||||
: '(' typeuse1(folded_instr_list(next), instruction_list(next)) {
|
||||
|
||||
@@ -188,6 +188,7 @@ runScript onAssertFail script = do
|
||||
getFailureString (Validate.FunctionIndexOutOfRange idx) = ["unknown function", "unknown function " <> TL.pack (show idx)]
|
||||
getFailureString (Validate.GlobalIndexOutOfRange idx) = ["unknown global", "unknown global " <> TL.pack (show idx)]
|
||||
getFailureString Validate.LabelIndexOutOfRange = ["unknown label"]
|
||||
getFailureString Validate.LaneIndexOutOfRange = ["invalid lane index"]
|
||||
getFailureString Validate.TypeIndexOutOfRange = ["unknown type"]
|
||||
getFailureString Validate.MinMoreThanMaxInMemoryLimit = ["size minimum must not be greater than maximum"]
|
||||
getFailureString Validate.MemoryLimitExceeded = ["memory size must be at most 65536 pages (4GiB)"]
|
||||
|
||||
@@ -40,6 +40,7 @@ data ValidationError =
|
||||
| ElemIndexOutOfRange Natural
|
||||
| DataIndexOutOfRange Natural
|
||||
| LabelIndexOutOfRange
|
||||
| LaneIndexOutOfRange
|
||||
| TypeIndexOutOfRange
|
||||
| ResultTypeDoesntMatch
|
||||
| TypeMismatch { actual :: Arrow, expected :: Arrow }
|
||||
@@ -524,13 +525,16 @@ getInstrType _ (FReinterpretI BS32) = return $ I32 ==> F32
|
||||
getInstrType _ (FReinterpretI BS64) = return $ I64 ==> F64
|
||||
getInstrType _ I8x16Swizzle =
|
||||
return $ [V128, V128] ==> V128
|
||||
getInstrType _ (I8x16Shuffle _) =
|
||||
getInstrType _ (I8x16Shuffle idxs) = do
|
||||
when (any (>= 32) idxs) $ throwError LaneIndexOutOfRange
|
||||
return $ [V128, V128] ==> V128
|
||||
getInstrType _ (V128Splat shape) =
|
||||
return $ getShapeElemType shape ==> V128
|
||||
getInstrType _ (V128ExtractLane shape _ _) =
|
||||
getInstrType _ (V128ExtractLane shape idx _) = do
|
||||
when (idx >= lanesCount shape) $ throwError LaneIndexOutOfRange
|
||||
return $ V128 ==> getShapeElemType shape
|
||||
getInstrType _ (V128ReplaceLane shape _) =
|
||||
getInstrType _ (V128ReplaceLane shape idx) = do
|
||||
when (idx >= lanesCount shape) $ throwError LaneIndexOutOfRange
|
||||
return $ [V128, getShapeElemType shape] ==> V128
|
||||
getInstrType _ (V128AllTrue _) =
|
||||
return $ V128 ==> I32
|
||||
@@ -545,6 +549,16 @@ getShapeElemType I64x2 = I64
|
||||
getShapeElemType F32x4 = F32
|
||||
getShapeElemType F64x2 = F64
|
||||
|
||||
lanesCount :: SimdShape -> Natural
|
||||
lanesCount shape = case shape of
|
||||
I8x16 -> 16
|
||||
I16x8 -> 8
|
||||
I32x4 -> 4
|
||||
I64x2 -> 2
|
||||
F32x4 -> 4
|
||||
F64x2 -> 2
|
||||
I128x1 -> 1
|
||||
|
||||
replace :: (Eq a) => a -> a -> [a] -> [a]
|
||||
replace _ _ [] = []
|
||||
replace x y (v:r) = (if x == v then y else v) : replace x y r
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ main = do
|
||||
filter (List.isPrefixOf "simd") .
|
||||
filter (List.isSuffixOf ".wast")
|
||||
<$> Directory.listDirectory "tests/spec"
|
||||
let files = ["simd_lane.wast"]
|
||||
-- let files = ["simd_lane.wast"]
|
||||
scriptTestCases <- (`mapM` files) $ \file -> do
|
||||
test <- LBS.readFile ("tests/spec/" ++ file)
|
||||
return $ testCase file $ do
|
||||
|
||||
Reference in New Issue
Block a user