From 6ad6aa2cc4894fd2fa606db176aaf3650445962e Mon Sep 17 00:00:00 2001 From: Paul Dennis Date: Sun, 4 Jan 2026 18:41:42 +0100 Subject: [PATCH 1/2] niv pinned shell.nix for versioning working dependencies --- interpreter/nix/sources.json | 14 +++ interpreter/nix/sources.nix | 198 +++++++++++++++++++++++++++++++++++ interpreter/shell.nix | 17 +++ 3 files changed, 229 insertions(+) create mode 100644 interpreter/nix/sources.json create mode 100644 interpreter/nix/sources.nix create mode 100644 interpreter/shell.nix diff --git a/interpreter/nix/sources.json b/interpreter/nix/sources.json new file mode 100644 index 00000000..f4bfabd2 --- /dev/null +++ b/interpreter/nix/sources.json @@ -0,0 +1,14 @@ +{ + "nixpkgs": { + "branch": "nixos-unstable", + "description": "Nix Packages collection", + "homepage": null, + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9da7f1cf7f8a6e2a7cb3001b048546c92a8258b4", + "sha256": "04h7cq8rp8815xb4zglkah4w6p2r5lqp7xanv89yxzbmnv29np2a", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/9da7f1cf7f8a6e2a7cb3001b048546c92a8258b4.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + } +} diff --git a/interpreter/nix/sources.nix b/interpreter/nix/sources.nix new file mode 100644 index 00000000..fe3dadf7 --- /dev/null +++ b/interpreter/nix/sources.nix @@ -0,0 +1,198 @@ +# This file has been generated by Niv. + +let + + # + # The fetchers. fetch_ fetches specs of type . + # + + fetch_file = pkgs: name: spec: + let + name' = sanitizeName name + "-src"; + in + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; name = name'; } + else + pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; + + fetch_tarball = pkgs: name: spec: + let + name' = sanitizeName name + "-src"; + in + if spec.builtin or true then + builtins_fetchTarball { name = name'; inherit (spec) url sha256; } + else + pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; + + fetch_git = name: spec: + let + ref = + spec.ref or ( + if spec ? branch then "refs/heads/${spec.branch}" else + if spec ? tag then "refs/tags/${spec.tag}" else + abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!" + ); + submodules = spec.submodules or false; + submoduleArg = + let + nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0; + emptyArgWithWarning = + if submodules + then + builtins.trace + ( + "The niv input \"${name}\" uses submodules " + + "but your nix's (${builtins.nixVersion}) builtins.fetchGit " + + "does not support them" + ) + { } + else { }; + in + if nixSupportsSubmodules + then { inherit submodules; } + else emptyArgWithWarning; + in + builtins.fetchGit + ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg); + + fetch_local = spec: spec.path; + + fetch_builtin-tarball = name: throw + ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=tarball -a builtin=true''; + + fetch_builtin-url = name: throw + ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=file -a builtin=true''; + + # + # Various helpers + # + + # https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695 + sanitizeName = name: + ( + concatMapStrings (s: if builtins.isList s then "-" else s) + ( + builtins.split "[^[:alnum:]+._?=-]+" + ((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name) + ) + ); + + # The set of packages used when specs are fetched using non-builtins. + mkPkgs = sources: system: + let + sourcesNixpkgs = + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; }; + hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; + hasThisAsNixpkgsPath = == ./.; + in + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import { } + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # The actual fetching function. + fetch = pkgs: name: spec: + + if ! builtins.hasAttr "type" spec then + abort "ERROR: niv spec ${name} does not have a 'type' attribute" + else if spec.type == "file" then fetch_file pkgs name spec + else if spec.type == "tarball" then fetch_tarball pkgs name spec + else if spec.type == "git" then fetch_git name spec + else if spec.type == "local" then fetch_local spec + else if spec.type == "builtin-tarball" then fetch_builtin-tarball name + else if spec.type == "builtin-url" then fetch_builtin-url name + else + abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + + # If the environment variable NIV_OVERRIDE_${name} is set, then use + # the path directly as opposed to the fetched source. + replace = name: drv: + let + saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name; + ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; + in + if ersatz == "" then drv else + # this turns the string into an actual Nix path (for both absolute and + # relative paths) + if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; + + # Ports of functions for older nix versions + + # a Nix version of mapAttrs if the built-in doesn't exist + mapAttrs = builtins.mapAttrs or ( + f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) + ); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 + range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 + stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 + stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); + concatMapStrings = f: list: concatStrings (map f list); + concatStrings = builtins.concatStringsSep ""; + + # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 + optionalAttrs = cond: as: if cond then as else { }; + + # fetchTarball version that is compatible between all the versions of Nix + builtins_fetchTarball = { url, name ? null, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) + else + fetchTarball attrs; + + # fetchurl version that is compatible between all the versions of Nix + builtins_fetchurl = { url, name ? null, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) + else + fetchurl attrs; + + # Create the final "sources" from the config + mkSources = config: + mapAttrs + ( + name: spec: + if builtins.hasAttr "outPath" spec + then + abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = replace name (fetch config.pkgs name spec); } + ) + config.sources; + + # The "config" used by the fetchers + mkConfig = + { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null + , sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile) + , system ? builtins.currentSystem + , pkgs ? mkPkgs sources system + }: rec { + # The sources, i.e. the attribute set of spec name to spec + inherit sources; + + # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers + inherit pkgs; + }; + +in +mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/interpreter/shell.nix b/interpreter/shell.nix new file mode 100644 index 00000000..df249980 --- /dev/null +++ b/interpreter/shell.nix @@ -0,0 +1,17 @@ +{ sources ? import ./nix/sources.nix {} +, pkgs ? import sources.nixpkgs {} +}: + +pkgs.mkShell { + buildInputs = with pkgs; [ + dune_3 + ocaml + ocamlPackages.arg-complete + ocamlPackages.findlib + ocamlPackages.mopsa + python3 + ]; + + LC_ALL = "C.UTF-8"; + LANG = "C.UTF-8"; +} From 4282db6c529d2df40970f71ab7e2232d033cbad6 Mon Sep 17 00:00:00 2001 From: John Galt <3dcontentfanbo1@protonmail.com> Date: Sat, 10 Jan 2026 13:42:19 +0100 Subject: [PATCH 2/2] ref runtime feature for rounding variants --- interpreter/binary/decode.ml | 63 +++++++++ interpreter/binary/encode.ml | 70 ++++++++++ interpreter/dune | 1 + interpreter/exec/eval_num.ml | 232 ++++++++++++++++++++++++++++++++ interpreter/syntax/ast.ml | 8 +- interpreter/syntax/operators.ml | 60 +++++++++ interpreter/text/arrange.ml | 33 +++++ interpreter/text/lexer.mll | 60 +++++++++ interpreter/valid/valid.ml | 20 ++- 9 files changed, 539 insertions(+), 8 deletions(-) diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index fa3a0ef9..43cbf21c 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -507,6 +507,69 @@ let rec instr s = | 0x10l -> table_size (at var s) | 0x11l -> table_fill (at var s) + | 0x80l -> f32_sqrt_ceil + | 0x81l -> f32_add_ceil + | 0x82l -> f32_sub_ceil + | 0x83l -> f32_mul_ceil + | 0x84l -> f32_div_ceil + | 0x85l -> f64_sqrt_ceil + | 0x86l -> f64_add_ceil + | 0x87l -> f64_sub_ceil + | 0x88l -> f64_mul_ceil + | 0x89l -> f64_div_ceil + | 0x8al -> f32_convert_ceil_i32_s + | 0x8bl -> f32_convert_ceil_i32_u + | 0x8cl -> f32_convert_ceil_i64_s + | 0x8dl -> f32_convert_ceil_i64_u + | 0x8el -> f32_demote_ceil_f64 + | 0x8fl -> f64_convert_ceil_i32_s + | 0x90l -> f64_convert_ceil_i32_u + | 0x91l -> f64_convert_ceil_i64_s + | 0x92l -> f64_convert_ceil_i64_u + | 0x93l -> f64_promote_ceil_f32 + + | 0x94l -> f32_sqrt_floor + | 0x95l -> f32_add_floor + | 0x96l -> f32_sub_floor + | 0x97l -> f32_mul_floor + | 0x98l -> f32_div_floor + | 0x99l -> f64_sqrt_floor + | 0x9al -> f64_add_floor + | 0x9bl -> f64_sub_floor + | 0x9cl -> f64_mul_floor + | 0x9dl -> f64_div_floor + | 0x9el -> f32_convert_floor_i32_s + | 0x9fl -> f32_convert_floor_i32_u + | 0xa0l -> f32_convert_floor_i64_s + | 0xa1l -> f32_convert_floor_i64_u + | 0xa2l -> f32_demote_floor_f64 + | 0xa3l -> f64_convert_floor_i32_s + | 0xa4l -> f64_convert_floor_i32_u + | 0xa5l -> f64_convert_floor_i64_s + | 0xa6l -> f64_convert_floor_i64_u + | 0xa7l -> f64_promote_floor_f32 + + | 0xa8l -> f32_sqrt_trunc + | 0xa9l -> f32_add_trunc + | 0xaal -> f32_sub_trunc + | 0xabl -> f32_mul_trunc + | 0xacl -> f32_div_trunc + | 0xadl -> f64_sqrt_trunc + | 0xael -> f64_add_trunc + | 0xafl -> f64_sub_trunc + | 0xb0l -> f64_mul_trunc + | 0xb1l -> f64_div_trunc + | 0xb2l -> f32_convert_trunc_i32_s + | 0xb3l -> f32_convert_trunc_i32_u + | 0xb4l -> f32_convert_trunc_i64_s + | 0xb5l -> f32_convert_trunc_i64_u + | 0xb6l -> f32_demote_trunc_f64 + | 0xb7l -> f64_convert_trunc_i32_s + | 0xb8l -> f64_convert_trunc_i32_u + | 0xb9l -> f64_convert_trunc_i64_s + | 0xbal -> f64_convert_trunc_i64_u + | 0xbbl -> f64_promote_trunc_f32 + | n -> illegal2 s pos b n ) diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index f5665bb1..0a72151c 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -468,6 +468,76 @@ struct | Convert (F64 F64Op.ConvertUI32) -> op 0xb8 | Convert (F64 F64Op.ConvertSI64) -> op 0xb9 | Convert (F64 F64Op.ConvertUI64) -> op 0xba + + | Unary (F32 F32Op.SqrtCeil) -> op 0xfc; u32 0x80l + | Binary (F32 F32Op.AddCeil) -> op 0xfc; u32 0x81l + | Binary (F32 F32Op.SubCeil) -> op 0xfc; u32 0x82l + | Binary (F32 F32Op.MulCeil) -> op 0xfc; u32 0x83l + | Binary (F32 F32Op.DivCeil) -> op 0xfc; u32 0x84l + | Unary (F64 F64Op.SqrtCeil) -> op 0xfc; u32 0x85l + | Binary (F64 F64Op.AddCeil) -> op 0xfc; u32 0x86l + | Binary (F64 F64Op.SubCeil) -> op 0xfc; u32 0x87l + | Binary (F64 F64Op.MulCeil) -> op 0xfc; u32 0x88l + | Binary (F64 F64Op.DivCeil) -> op 0xfc; u32 0x89l + | Convert (F32 F32Op.ConvertCeilSI32) -> op 0xfc; u32 0x8al + | Convert (F32 F32Op.ConvertCeilUI32) -> op 0xfc; u32 0x8bl + | Convert (F32 F32Op.ConvertCeilSI64) -> op 0xfc; u32 0x8cl + | Convert (F32 F32Op.ConvertCeilUI64) -> op 0xfc; u32 0x8dl + | Convert (F32 F32Op.DemoteCeilF64) -> op 0xfc; u32 0x8el + | Convert (F64 F64Op.ConvertCeilSI32) -> op 0xfc; u32 0x8fl + | Convert (F64 F64Op.ConvertCeilUI32) -> op 0xfc; u32 0x90l + | Convert (F64 F64Op.ConvertCeilSI64) -> op 0xfc; u32 0x91l + | Convert (F64 F64Op.ConvertCeilUI64) -> op 0xfc; u32 0x92l + | Convert (F64 F64Op.PromoteCeilF32) -> op 0xfc; u32 0x93l + | Convert (F32 F32Op.PromoteCeilF32) -> error e.at "illegal instruction f32.promote_ceil_f32" + | Convert (F64 F64Op.DemoteCeilF64) -> error e.at "illegal instruction f64.demote_ceil_f64" + + | Unary (F32 F32Op.SqrtFloor) -> op 0xfc; u32 0x94l + | Binary (F32 F32Op.AddFloor) -> op 0xfc; u32 0x95l + | Binary (F32 F32Op.SubFloor) -> op 0xfc; u32 0x96l + | Binary (F32 F32Op.MulFloor) -> op 0xfc; u32 0x97l + | Binary (F32 F32Op.DivFloor) -> op 0xfc; u32 0x98l + | Unary (F64 F64Op.SqrtFloor) -> op 0xfc; u32 0x99l + | Binary (F64 F64Op.AddFloor) -> op 0xfc; u32 0x9al + | Binary (F64 F64Op.SubFloor) -> op 0xfc; u32 0x9bl + | Binary (F64 F64Op.MulFloor) -> op 0xfc; u32 0x9cl + | Binary (F64 F64Op.DivFloor) -> op 0xfc; u32 0x9dl + | Convert (F32 F32Op.ConvertFloorSI32) -> op 0xFc; u32 0x9el + | Convert (F32 F32Op.ConvertFloorUI32) -> op 0xFc; u32 0x9Fl + | Convert (F32 F32Op.ConvertFloorSI64) -> op 0xFc; u32 0xa0l + | Convert (F32 F32Op.ConvertFloorUI64) -> op 0xFc; u32 0xa1l + | Convert (F32 F32Op.DemoteFloorF64) -> op 0xFc; u32 0xa2l + | Convert (F64 F64Op.ConvertFloorSI32) -> op 0xFc; u32 0xa3l + | Convert (F64 F64Op.ConvertFloorUI32) -> op 0xFc; u32 0xa4l + | Convert (F64 F64Op.ConvertFloorSI64) -> op 0xFc; u32 0xa5l + | Convert (F64 F64Op.ConvertFloorUI64) -> op 0xFc; u32 0xa6l + | Convert (F64 F64Op.PromoteFloorF32) -> op 0xFc; u32 0xa7l + | Convert (F32 F32Op.PromoteFloorF32) -> error e.at "illegal instruction f32.promote_ceil_f32" + | Convert (F64 F64Op.DemoteFloorF64) -> error e.at "illegal instruction f64.demote_ceil_f64" + + | Unary (F32 F32Op.SqrtTrunc) -> op 0xfc; u32 0xa8l + | Binary (F32 F32Op.AddTrunc) -> op 0xfc; u32 0xa9l + | Binary (F32 F32Op.SubTrunc) -> op 0xfc; u32 0xaal + | Binary (F32 F32Op.MulTrunc) -> op 0xfc; u32 0xabl + | Binary (F32 F32Op.DivTrunc) -> op 0xfc; u32 0xacl + | Unary (F64 F64Op.SqrtTrunc) -> op 0xfc; u32 0xadl + | Binary (F64 F64Op.AddTrunc) -> op 0xfc; u32 0xael + | Binary (F64 F64Op.SubTrunc) -> op 0xfc; u32 0xafl + | Binary (F64 F64Op.MulTrunc) -> op 0xfc; u32 0xb0l + | Binary (F64 F64Op.DivTrunc) -> op 0xfc; u32 0xb1l + | Convert (F32 F32Op.ConvertTruncSI32) -> op 0xfc; u32 0xb2l + | Convert (F32 F32Op.ConvertTruncUI32) -> op 0xfc; u32 0xb3l + | Convert (F32 F32Op.ConvertTruncSI64) -> op 0xfc; u32 0xb4l + | Convert (F32 F32Op.ConvertTruncUI64) -> op 0xfc; u32 0xb5l + | Convert (F32 F32Op.DemoteTruncF64) -> op 0xfc; u32 0xb6l + | Convert (F64 F64Op.ConvertTruncSI32) -> op 0xfc; u32 0xb7l + | Convert (F64 F64Op.ConvertTruncUI32) -> op 0xfc; u32 0xb8l + | Convert (F64 F64Op.ConvertTruncSI64) -> op 0xfc; u32 0xb9l + | Convert (F64 F64Op.ConvertTruncUI64) -> op 0xfc; u32 0xbal + | Convert (F64 F64Op.PromoteTruncF32) -> op 0xfc; u32 0xbbl + | Convert (F32 F32Op.PromoteTruncF32) -> error e.at "illegal instruction f32.promote_trunc_f32" + | Convert (F64 F64Op.DemoteTruncF64) -> error e.at "illegal instruction f64.demote_trunc_f64" + | Convert (F64 F64Op.PromoteF32) -> op 0xbb | Convert (F64 F64Op.DemoteF64) -> error e.at "illegal instruction f64.demote_f64" diff --git a/interpreter/dune b/interpreter/dune index 9a853921..92aac3fb 100644 --- a/interpreter/dune +++ b/interpreter/dune @@ -2,6 +2,7 @@ (library (public_name wasm) + (libraries mopsa.mopsa_utils) ; The 'wasm' module shall not be part of the library, as it would start the ; Wasm REPL every time in all the dependencies. ; We exclude the 'wast' module as it is only used for the JS build. diff --git a/interpreter/exec/eval_num.ml b/interpreter/exec/eval_num.ml index 40dd1be0..1b199ea8 100644 --- a/interpreter/exec/eval_num.ml +++ b/interpreter/exec/eval_num.ml @@ -72,6 +72,21 @@ struct | Neg -> FXX.neg | Abs -> FXX.abs | Sqrt -> FXX.sqrt + | SqrtCeil -> (fun v1 -> + ItvUtils.Float.set_round_up (); + let result = FXX.sqrt v1 in + ItvUtils.Float.set_round_near (); + result) + | SqrtFloor -> (fun v1 -> + ItvUtils.Float.set_round_down (); + let result = FXX.sqrt v1 in + ItvUtils.Float.set_round_near (); + result) + | SqrtTrunc -> (fun v1 -> + ItvUtils.Float.set_round_zero (); + let result = FXX.sqrt v1 in + ItvUtils.Float.set_round_near (); + result) | Ceil -> FXX.ceil | Floor -> FXX.floor | Trunc -> FXX.trunc @@ -81,6 +96,67 @@ struct let binop op = let f = match op with | Add -> FXX.add + | AddCeil -> (fun v1 v2 -> + ItvUtils.Float.set_round_up (); + let result = FXX.add v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | AddFloor -> (fun v1 v2 -> + ItvUtils.Float.set_round_down (); + let result = FXX.add v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | AddTrunc -> (fun v1 v2 -> + ItvUtils.Float.set_round_zero (); + let result = FXX.add v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | SubCeil -> (fun v1 v2 -> + ItvUtils.Float.set_round_up (); + let result = FXX.sub v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | SubFloor -> (fun v1 v2 -> + ItvUtils.Float.set_round_down (); + let result = FXX.sub v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | SubTrunc -> (fun v1 v2 -> + ItvUtils.Float.set_round_zero (); + let result = FXX.sub v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | MulCeil -> (fun v1 v2 -> + ItvUtils.Float.set_round_up (); + let result = FXX.mul v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | MulFloor -> (fun v1 v2 -> + ItvUtils.Float.set_round_down (); + let result = FXX.mul v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | MulTrunc -> (fun v1 v2 -> + ItvUtils.Float.set_round_zero (); + let result = FXX.mul v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | DivCeil -> (fun v1 v2 -> + ItvUtils.Float.set_round_up (); + let result = FXX.div v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | DivFloor -> (fun v1 v2 -> + ItvUtils.Float.set_round_down (); + let result = FXX.div v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | DivTrunc -> (fun v1 v2 -> + ItvUtils.Float.set_round_zero (); + let result = FXX.div v1 v2 in + ItvUtils.Float.set_round_near (); + result) + | Sub -> FXX.sub | Mul -> FXX.mul | Div -> FXX.div @@ -157,12 +233,90 @@ struct let cvtop op v = let z = match op with | DemoteF64 -> F32_convert.demote_f64 (F64Num.of_num 1 v) + | DemoteCeilF64 -> + ItvUtils.Float.set_round_up (); + let result = F32_convert.demote_f64 (F64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | DemoteFloorF64 -> + ItvUtils.Float.set_round_down (); + let result = F32_convert.demote_f64 (F64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | DemoteTruncF64 -> + ItvUtils.Float.set_round_zero (); + let result = F32_convert.demote_f64 (F64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertSI32 -> F32_convert.convert_i32_s (I32Num.of_num 1 v) + | ConvertCeilSI32 -> + ItvUtils.Float.set_round_up (); + let result = F32_convert.convert_i32_s (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorSI32 -> + ItvUtils.Float.set_round_down (); + let result = F32_convert.convert_i32_s (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncSI32 -> + ItvUtils.Float.set_round_zero (); + let result = F32_convert.convert_i32_s (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertUI32 -> F32_convert.convert_i32_u (I32Num.of_num 1 v) + | ConvertCeilUI32 -> + ItvUtils.Float.set_round_up (); + let result = F32_convert.convert_i32_u (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorUI32 -> + ItvUtils.Float.set_round_down (); + let result = F32_convert.convert_i32_u (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncUI32 -> + ItvUtils.Float.set_round_zero (); + let result = F32_convert.convert_i32_u (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertSI64 -> F32_convert.convert_i64_s (I64Num.of_num 1 v) + | ConvertCeilSI64 -> + ItvUtils.Float.set_round_up (); + let result = F32_convert.convert_i64_s (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorSI64 -> + ItvUtils.Float.set_round_down (); + let result = F32_convert.convert_i64_s (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncSI64 -> + ItvUtils.Float.set_round_zero (); + let result = F32_convert.convert_i64_s (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertUI64 -> F32_convert.convert_i64_u (I64Num.of_num 1 v) + | ConvertCeilUI64 -> + ItvUtils.Float.set_round_up (); + let result = F32_convert.convert_i64_u (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorUI64 -> + ItvUtils.Float.set_round_down (); + let result = F32_convert.convert_i64_u (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncUI64 -> + ItvUtils.Float.set_round_zero (); + let result = F32_convert.convert_i64_u (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ReinterpretInt -> F32_convert.reinterpret_i32 (I32Num.of_num 1 v) | PromoteF32 -> raise (TypeError (1, v, F32Type)) + | PromoteCeilF32 -> raise (TypeError (1, v, F32Type)) + | PromoteFloorF32 -> raise (TypeError (1, v, F32Type)) + | PromoteTruncF32 -> raise (TypeError (1, v, F32Type)) in F32Num.to_num z end @@ -173,12 +327,90 @@ struct let cvtop op v = let z = match op with | PromoteF32 -> F64_convert.promote_f32 (F32Num.of_num 1 v) + | PromoteCeilF32 -> + ItvUtils.Float.set_round_up (); + let result = F64_convert.promote_f32 (F32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | PromoteFloorF32 -> + ItvUtils.Float.set_round_down (); + let result = F64_convert.promote_f32 (F32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | PromoteTruncF32 -> + ItvUtils.Float.set_round_zero (); + let result = F64_convert.promote_f32 (F32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertSI32 -> F64_convert.convert_i32_s (I32Num.of_num 1 v) + | ConvertCeilSI32 -> + ItvUtils.Float.set_round_up (); + let result = F64_convert.convert_i32_s (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorSI32 -> + ItvUtils.Float.set_round_down (); + let result = F64_convert.convert_i32_s (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncSI32 -> + ItvUtils.Float.set_round_zero (); + let result = F64_convert.convert_i32_s (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertUI32 -> F64_convert.convert_i32_u (I32Num.of_num 1 v) + | ConvertCeilUI32 -> + ItvUtils.Float.set_round_up (); + let result = F64_convert.convert_i32_u (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorUI32 -> + ItvUtils.Float.set_round_down (); + let result = F64_convert.convert_i32_u (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncUI32 -> + ItvUtils.Float.set_round_zero (); + let result = F64_convert.convert_i32_u (I32Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertSI64 -> F64_convert.convert_i64_s (I64Num.of_num 1 v) + | ConvertCeilSI64 -> + ItvUtils.Float.set_round_up (); + let result = F64_convert.convert_i64_s (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorSI64 -> + ItvUtils.Float.set_round_down (); + let result = F64_convert.convert_i64_s (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncSI64 -> + ItvUtils.Float.set_round_zero (); + let result = F64_convert.convert_i64_s (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ConvertUI64 -> F64_convert.convert_i64_u (I64Num.of_num 1 v) + | ConvertCeilUI64 -> + ItvUtils.Float.set_round_up (); + let result = F64_convert.convert_i64_u (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertFloorUI64 -> + ItvUtils.Float.set_round_down (); + let result = F64_convert.convert_i64_u (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result + | ConvertTruncUI64 -> + ItvUtils.Float.set_round_zero (); + let result = F64_convert.convert_i64_u (I64Num.of_num 1 v) in + ItvUtils.Float.set_round_near (); + result | ReinterpretInt -> F64_convert.reinterpret_i64 (I64Num.of_num 1 v) | DemoteF64 -> raise (TypeError (1, v, F64Type)) + | DemoteCeilF64 -> raise (TypeError (1, v, F64Type)) + | DemoteFloorF64 -> raise (TypeError (1, v, F64Type)) + | DemoteTruncF64 -> raise (TypeError (1, v, F64Type)) in F64Num.to_num z end diff --git a/interpreter/syntax/ast.ml b/interpreter/syntax/ast.ml index a6eb0d9c..5b77ab48 100644 --- a/interpreter/syntax/ast.ml +++ b/interpreter/syntax/ast.ml @@ -38,12 +38,12 @@ end module FloatOp = struct - type unop = Neg | Abs | Ceil | Floor | Trunc | Nearest | Sqrt - type binop = Add | Sub | Mul | Div | Min | Max | CopySign + type unop = Neg | Abs | Ceil | Floor | Trunc | Nearest | Sqrt | SqrtCeil | SqrtFloor | SqrtTrunc + type binop = Add | AddCeil | AddFloor | AddTrunc | Sub | SubCeil | SubTrunc | SubFloor | Mul | MulCeil | MulFloor | MulTrunc | Div | DivCeil | DivFloor | DivTrunc | Min | Max | CopySign type testop = | type relop = Eq | Ne | Lt | Gt | Le | Ge - type cvtop = ConvertSI32 | ConvertUI32 | ConvertSI64 | ConvertUI64 - | PromoteF32 | DemoteF64 + type cvtop = ConvertSI32 | ConvertUI32 | ConvertSI64 | ConvertUI64 | ConvertCeilSI32 | ConvertCeilUI32 | ConvertCeilSI64 | ConvertCeilUI64 | ConvertFloorSI32 | ConvertFloorUI32 | ConvertFloorSI64 | ConvertFloorUI64 | ConvertTruncSI32 | ConvertTruncUI32 | ConvertTruncSI64 | ConvertTruncUI64 + | PromoteF32 | PromoteCeilF32 | PromoteFloorF32 | PromoteTruncF32 | DemoteF64 | DemoteCeilF64 | DemoteFloorF64 | DemoteTruncF64 | ReinterpretInt end diff --git a/interpreter/syntax/operators.ml b/interpreter/syntax/operators.ml index 296bb1e7..4980e963 100644 --- a/interpreter/syntax/operators.ml +++ b/interpreter/syntax/operators.ml @@ -101,6 +101,9 @@ let i64_popcnt = Unary (I64 I64Op.Popcnt) let f32_neg = Unary (F32 F32Op.Neg) let f32_abs = Unary (F32 F32Op.Abs) let f32_sqrt = Unary (F32 F32Op.Sqrt) +let f32_sqrt_ceil = Unary (F32 F32Op.SqrtCeil) +let f32_sqrt_floor = Unary (F32 F32Op.SqrtFloor) +let f32_sqrt_trunc = Unary (F32 F32Op.SqrtTrunc) let f32_ceil = Unary (F32 F32Op.Ceil) let f32_floor = Unary (F32 F32Op.Floor) let f32_trunc = Unary (F32 F32Op.Trunc) @@ -108,6 +111,9 @@ let f32_nearest = Unary (F32 F32Op.Nearest) let f64_neg = Unary (F64 F64Op.Neg) let f64_abs = Unary (F64 F64Op.Abs) let f64_sqrt = Unary (F64 F64Op.Sqrt) +let f64_sqrt_ceil = Unary (F64 F64Op.SqrtCeil) +let f64_sqrt_floor = Unary (F64 F64Op.SqrtFloor) +let f64_sqrt_trunc = Unary (F64 F64Op.SqrtTrunc) let f64_ceil = Unary (F64 F64Op.Ceil) let f64_floor = Unary (F64 F64Op.Floor) let f64_trunc = Unary (F64 F64Op.Trunc) @@ -144,16 +150,40 @@ let i64_shr_u = Binary (I64 I64Op.ShrU) let i64_rotl = Binary (I64 I64Op.Rotl) let i64_rotr = Binary (I64 I64Op.Rotr) let f32_add = Binary (F32 F32Op.Add) +let f32_add_ceil = Binary (F32 F32Op.AddCeil) +let f32_add_floor = Binary (F32 F32Op.AddFloor) +let f32_add_trunc = Binary (F32 F32Op.AddTrunc) let f32_sub = Binary (F32 F32Op.Sub) +let f32_sub_ceil = Binary (F32 F32Op.SubCeil) +let f32_sub_floor = Binary (F32 F32Op.SubFloor) +let f32_sub_trunc = Binary (F32 F32Op.SubTrunc) let f32_mul = Binary (F32 F32Op.Mul) +let f32_mul_ceil = Binary (F32 F32Op.MulCeil) +let f32_mul_floor = Binary (F32 F32Op.MulFloor) +let f32_mul_trunc = Binary (F32 F32Op.MulTrunc) let f32_div = Binary (F32 F32Op.Div) +let f32_div_ceil = Binary (F32 F32Op.DivCeil) +let f32_div_floor = Binary (F32 F32Op.DivFloor) +let f32_div_trunc = Binary (F32 F32Op.DivTrunc) let f32_min = Binary (F32 F32Op.Min) let f32_max = Binary (F32 F32Op.Max) let f32_copysign = Binary (F32 F32Op.CopySign) let f64_add = Binary (F64 F64Op.Add) +let f64_add_ceil = Binary (F64 F64Op.AddCeil) +let f64_add_floor = Binary (F64 F64Op.AddFloor) +let f64_add_trunc = Binary (F64 F64Op.AddTrunc) let f64_sub = Binary (F64 F64Op.Sub) +let f64_sub_ceil = Binary (F64 F64Op.SubCeil) +let f64_sub_floor = Binary (F64 F64Op.SubFloor) +let f64_sub_trunc = Binary (F64 F64Op.SubTrunc) let f64_mul = Binary (F64 F64Op.Mul) +let f64_mul_ceil = Binary (F64 F64Op.MulCeil) +let f64_mul_floor = Binary (F64 F64Op.MulFloor) +let f64_mul_trunc = Binary (F64 F64Op.MulTrunc) let f64_div = Binary (F64 F64Op.Div) +let f64_div_ceil = Binary (F64 F64Op.DivCeil) +let f64_div_floor = Binary (F64 F64Op.DivFloor) +let f64_div_trunc = Binary (F64 F64Op.DivTrunc) let f64_min = Binary (F64 F64Op.Min) let f64_max = Binary (F64 F64Op.Max) let f64_copysign = Binary (F64 F64Op.CopySign) @@ -216,19 +246,49 @@ let i64_trunc_f32_u = Convert (I64 I64Op.TruncUF32) let i64_trunc_f64_s = Convert (I64 I64Op.TruncSF64) let i64_trunc_f64_u = Convert (I64 I64Op.TruncUF64) let f32_convert_i32_s = Convert (F32 F32Op.ConvertSI32) +let f32_convert_ceil_i32_s = Convert (F32 F32Op.ConvertCeilSI32) +let f32_convert_floor_i32_s = Convert (F32 F32Op.ConvertFloorSI32) +let f32_convert_trunc_i32_s = Convert (F32 F32Op.ConvertTruncSI32) let f32_convert_i32_u = Convert (F32 F32Op.ConvertUI32) +let f32_convert_ceil_i32_u = Convert (F32 F32Op.ConvertCeilUI32) +let f32_convert_floor_i32_u = Convert (F32 F32Op.ConvertFloorUI32) +let f32_convert_trunc_i32_u = Convert (F32 F32Op.ConvertTruncUI32) let f32_convert_i64_s = Convert (F32 F32Op.ConvertSI64) +let f32_convert_ceil_i64_s = Convert (F32 F32Op.ConvertCeilSI64) +let f32_convert_floor_i64_s = Convert (F32 F32Op.ConvertFloorSI64) +let f32_convert_trunc_i64_s = Convert (F32 F32Op.ConvertTruncSI64) let f32_convert_i64_u = Convert (F32 F32Op.ConvertUI64) +let f32_convert_ceil_i64_u = Convert (F32 F32Op.ConvertCeilUI64) +let f32_convert_floor_i64_u = Convert (F32 F32Op.ConvertFloorUI64) +let f32_convert_trunc_i64_u = Convert (F32 F32Op.ConvertTruncUI64) let i64_trunc_sat_f32_s = Convert (I64 I64Op.TruncSatSF32) let i64_trunc_sat_f32_u = Convert (I64 I64Op.TruncSatUF32) let i64_trunc_sat_f64_s = Convert (I64 I64Op.TruncSatSF64) let i64_trunc_sat_f64_u = Convert (I64 I64Op.TruncSatUF64) let f32_demote_f64 = Convert (F32 F32Op.DemoteF64) +let f32_demote_ceil_f64 = Convert (F32 F32Op.DemoteCeilF64) +let f32_demote_floor_f64 = Convert (F32 F32Op.DemoteFloorF64) +let f32_demote_trunc_f64 = Convert (F32 F32Op.DemoteTruncF64) let f64_convert_i32_s = Convert (F64 F64Op.ConvertSI32) +let f64_convert_ceil_i32_s = Convert (F64 F64Op.ConvertCeilSI32) +let f64_convert_floor_i32_s = Convert (F64 F64Op.ConvertFloorSI32) +let f64_convert_trunc_i32_s = Convert (F64 F64Op.ConvertTruncSI32) let f64_convert_i32_u = Convert (F64 F64Op.ConvertUI32) +let f64_convert_ceil_i32_u = Convert (F64 F64Op.ConvertCeilUI32) +let f64_convert_floor_i32_u = Convert (F64 F64Op.ConvertFloorUI32) +let f64_convert_trunc_i32_u = Convert (F64 F64Op.ConvertTruncUI32) let f64_convert_i64_s = Convert (F64 F64Op.ConvertSI64) +let f64_convert_ceil_i64_s = Convert (F64 F64Op.ConvertCeilSI64) +let f64_convert_floor_i64_s = Convert (F64 F64Op.ConvertFloorSI64) +let f64_convert_trunc_i64_s = Convert (F64 F64Op.ConvertTruncSI64) let f64_convert_i64_u = Convert (F64 F64Op.ConvertUI64) +let f64_convert_ceil_i64_u = Convert (F64 F64Op.ConvertCeilUI64) +let f64_convert_floor_i64_u = Convert (F64 F64Op.ConvertFloorUI64) +let f64_convert_trunc_i64_u = Convert (F64 F64Op.ConvertTruncUI64) let f64_promote_f32 = Convert (F64 F64Op.PromoteF32) +let f64_promote_ceil_f32 = Convert (F64 F64Op.PromoteCeilF32) +let f64_promote_floor_f32 = Convert (F64 F64Op.PromoteFloorF32) +let f64_promote_trunc_f32 = Convert (F64 F64Op.PromoteTruncF32) let i32_reinterpret_f32 = Convert (I32 I32Op.ReinterpretFloat) let i64_reinterpret_f64 = Convert (I64 I64Op.ReinterpretFloat) let f32_reinterpret_i32 = Convert (F32 F32Op.ReinterpretInt) diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index dc56743e..77331251 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -177,23 +177,56 @@ struct | Trunc -> "trunc" | Nearest -> "nearest" | Sqrt -> "sqrt" + | SqrtCeil -> "sqrt_ceil" + | SqrtFloor -> "sqrt_floor" + | SqrtTrunc -> "sqrt_trunc" let binop xx = function | Add -> "add" + | AddCeil -> "add_ceil" + | AddFloor -> "add_floor" + | AddTrunc -> "add_trunc" | Sub -> "sub" + | SubCeil -> "sub_ceil" + | SubFloor -> "sub_floor" + | SubTrunc -> "sub_trunc" | Mul -> "mul" + | MulCeil -> "mul_ceil" + | MulFloor -> "mul_floor" + | MulTrunc -> "mul_trunc" | Div -> "div" + | DivCeil -> "div_ceil" + | DivFloor -> "div_floor" + | DivTrunc -> "div_trunc" | Min -> "min" | Max -> "max" | CopySign -> "copysign" let cvtop xx = function | ConvertSI32 -> "convert_i32_s" + | ConvertCeilSI32 -> "convert_ceil_i32_s" + | ConvertFloorSI32 -> "convert_floor_i32_s" + | ConvertTruncSI32 -> "convert_trunc_i32_s" | ConvertUI32 -> "convert_i32_u" + | ConvertCeilUI32 -> "convert_ceil_i32_u" + | ConvertFloorUI32 -> "convert_floor_i32_u" + | ConvertTruncUI32 -> "convert_trunc_i32_u" | ConvertSI64 -> "convert_i64_s" + | ConvertCeilSI64 -> "convert_ceil_i64_s" + | ConvertFloorSI64 -> "convert_floor_i64_s" + | ConvertTruncSI64 -> "convert_trunc_i64_s" | ConvertUI64 -> "convert_i64_u" + | ConvertCeilUI64 -> "convert_ceil_i64_u" + | ConvertFloorUI64 -> "convert_floor_i64_u" + | ConvertTruncUI64 -> "convert_trunc_i64_u" | PromoteF32 -> "promote_f32" + | PromoteCeilF32 -> "promote_ceil_f32" + | PromoteFloorF32 -> "promote_floor_f32" + | PromoteTruncF32 -> "promote_trunc_f32" | DemoteF64 -> "demote_f64" + | DemoteCeilF64 -> "demote_ceil_f64" + | DemoteFloorF64 -> "demote_floor_f64" + | DemoteTruncF64 -> "demote_trunc_f64" | ReinterpretInt -> "reinterpret_i" ^ xx end diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index d9a12b5d..3ec1dc8a 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -292,6 +292,9 @@ rule token = parse | "f32.neg" -> UNARY f32_neg | "f32.abs" -> UNARY f32_abs | "f32.sqrt" -> UNARY f32_sqrt + | "f32.sqrt_ceil" -> UNARY f32_sqrt_ceil + | "f32.sqrt_floor" -> UNARY f32_sqrt_floor + | "f32.sqrt_trunc" -> UNARY f32_sqrt_trunc | "f32.ceil" -> UNARY f32_ceil | "f32.floor" -> UNARY f32_floor | "f32.trunc" -> UNARY f32_trunc @@ -299,6 +302,9 @@ rule token = parse | "f64.neg" -> UNARY f64_neg | "f64.abs" -> UNARY f64_abs | "f64.sqrt" -> UNARY f64_sqrt + | "f64.sqrt_ceil" -> UNARY f64_sqrt_ceil + | "f64.sqrt_floor" -> UNARY f64_sqrt_floor + | "f64.sqrt_trunc" -> UNARY f64_sqrt_trunc | "f64.ceil" -> UNARY f64_ceil | "f64.floor" -> UNARY f64_floor | "f64.trunc" -> UNARY f64_trunc @@ -336,16 +342,40 @@ rule token = parse | "i64.rotr" -> BINARY i64_rotr | "f32.add" -> BINARY f32_add + | "f32.add_ceil" -> BINARY f32_add_ceil + | "f32.add_floor" -> BINARY f32_add_floor + | "f32.add_trunc" -> BINARY f32_add_trunc | "f32.sub" -> BINARY f32_sub + | "f32.sub_ceil" -> BINARY f32_sub_ceil + | "f32.sub_floor" -> BINARY f32_sub_floor + | "f32.sub_trunc" -> BINARY f32_sub_trunc | "f32.mul" -> BINARY f32_mul + | "f32.mul_ceil" -> BINARY f32_mul_ceil + | "f32.mul_floor" -> BINARY f32_mul_floor + | "f32.mul_trunc" -> BINARY f32_mul_trunc | "f32.div" -> BINARY f32_div + | "f32.div_ceil" -> BINARY f32_div_ceil + | "f32.div_floor" -> BINARY f32_div_floor + | "f32.div_trunc" -> BINARY f32_div_trunc | "f32.min" -> BINARY f32_min | "f32.max" -> BINARY f32_max | "f32.copysign" -> BINARY f32_copysign | "f64.add" -> BINARY f64_add + | "f64.add_ceil" -> BINARY f64_add_ceil + | "f64.add_floor" -> BINARY f64_add_floor + | "f64.add_trunc" -> BINARY f64_add_trunc | "f64.sub" -> BINARY f64_sub + | "f64.sub_ceil" -> BINARY f64_sub_ceil + | "f64.sub_floor" -> BINARY f64_sub_floor + | "f64.sub_trunc" -> BINARY f64_sub_trunc | "f64.mul" -> BINARY f64_mul + | "f64.mul_ceil" -> BINARY f64_mul_ceil + | "f64.mul_floor" -> BINARY f64_mul_floor + | "f64.mul_trunc" -> BINARY f64_mul_trunc | "f64.div" -> BINARY f64_div + | "f64.div_ceil" -> BINARY f64_div_ceil + | "f64.div_floor" -> BINARY f64_div_floor + | "f64.div_trunc" -> BINARY f64_div_trunc | "f64.min" -> BINARY f64_min | "f64.max" -> BINARY f64_max | "f64.copysign" -> BINARY f64_copysign @@ -391,7 +421,13 @@ rule token = parse | "i64.extend_i32_s" -> CONVERT i64_extend_i32_s | "i64.extend_i32_u" -> CONVERT i64_extend_i32_u | "f32.demote_f64" -> CONVERT f32_demote_f64 + | "f32.demote_ceil_f64" -> CONVERT f32_demote_ceil_f64 + | "f32.demote_floor_f64" -> CONVERT f32_demote_floor_f64 + | "f32.demote_trunc_f64" -> CONVERT f32_demote_trunc_f64 | "f64.promote_f32" -> CONVERT f64_promote_f32 + | "f64.promote_ceil_f32" -> CONVERT f64_promote_ceil_f32 + | "f64.promote_floor_f32" -> CONVERT f64_promote_floor_f32 + | "f64.promote_trunc_f32" -> CONVERT f64_promote_trunc_f32 | "i32.trunc_f32_u" -> CONVERT i32_trunc_f32_u | "i32.trunc_f32_s" -> CONVERT i32_trunc_f32_s | "i64.trunc_f32_u" -> CONVERT i64_trunc_f32_u @@ -409,13 +445,37 @@ rule token = parse | "i64.trunc_sat_f64_u" -> CONVERT i64_trunc_sat_f64_u | "i64.trunc_sat_f64_s" -> CONVERT i64_trunc_sat_f64_s | "f32.convert_i32_u" -> CONVERT f32_convert_i32_u + | "f32.convert_ceil_i32_u" -> CONVERT f32_convert_ceil_i32_u + | "f32.convert_floor_i32_u" -> CONVERT f32_convert_floor_i32_u + | "f32.convert_trunc_i32_u" -> CONVERT f32_convert_trunc_i32_u | "f32.convert_i32_s" -> CONVERT f32_convert_i32_s + | "f32.convert_ceil_i32_s" -> CONVERT f32_convert_ceil_i32_s + | "f32.convert_floor_i32_s" -> CONVERT f32_convert_floor_i32_s + | "f32.convert_trunc_i32_s" -> CONVERT f32_convert_trunc_i32_s | "f64.convert_i32_u" -> CONVERT f64_convert_i32_u + | "f64.convert_ceil_i32_u" -> CONVERT f64_convert_ceil_i32_u + | "f64.convert_floor_i32_u" -> CONVERT f64_convert_floor_i32_u + | "f64.convert_trunc_i32_u" -> CONVERT f64_convert_trunc_i32_u | "f64.convert_i32_s" -> CONVERT f64_convert_i32_s + | "f64.convert_ceil_i32_s" -> CONVERT f64_convert_ceil_i32_s + | "f64.convert_floor_i32_s" -> CONVERT f64_convert_floor_i32_s + | "f64.convert_trunc_i32_s" -> CONVERT f64_convert_trunc_i32_s | "f32.convert_i64_u" -> CONVERT f32_convert_i64_u + | "f32.convert_ceil_i64_u" -> CONVERT f32_convert_ceil_i64_u + | "f32.convert_floor_i64_u" -> CONVERT f32_convert_floor_i64_u + | "f32.convert_trunc_i64_u" -> CONVERT f32_convert_trunc_i64_u | "f32.convert_i64_s" -> CONVERT f32_convert_i64_s + | "f32.convert_ceil_i64_s" -> CONVERT f32_convert_ceil_i64_s + | "f32.convert_floor_i64_s" -> CONVERT f32_convert_floor_i64_s + | "f32.convert_trunc_i64_s" -> CONVERT f32_convert_trunc_i64_s | "f64.convert_i64_u" -> CONVERT f64_convert_i64_u + | "f64.convert_ceil_i64_u" -> CONVERT f64_convert_ceil_i64_u + | "f64.convert_floor_i64_u" -> CONVERT f64_convert_floor_i64_u + | "f64.convert_trunc_i64_u" -> CONVERT f64_convert_trunc_i64_u | "f64.convert_i64_s" -> CONVERT f64_convert_i64_s + | "f64.convert_ceil_i64_s" -> CONVERT f64_convert_ceil_i64_s + | "f64.convert_floor_i64_s" -> CONVERT f64_convert_floor_i64_s + | "f64.convert_trunc_i64_s" -> CONVERT f64_convert_trunc_i64_s | "f32.reinterpret_i32" -> CONVERT f32_reinterpret_i32 | "f64.reinterpret_i64" -> CONVERT f64_reinterpret_i64 | "i32.reinterpret_f32" -> CONVERT i32_reinterpret_f32 diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index cfe7f310..0dece3d8 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -137,18 +137,30 @@ let type_cvtop at = function | Values.F32 cvtop -> let open F32Op in (match cvtop with - | ConvertSI32 | ConvertUI32 | ReinterpretInt -> I32Type - | ConvertSI64 | ConvertUI64 -> I64Type + | ConvertSI32 | ConvertCeilSI32 | ConvertFloorSI32 | ConvertTruncSI32 | ConvertUI32 | ConvertCeilUI32 | ConvertFloorUI32 | ConvertTruncUI32 | ReinterpretInt -> I32Type + | ConvertSI64 | ConvertCeilSI64 | ConvertFloorSI64 | ConvertTruncSI64 | ConvertUI64 | ConvertCeilUI64 | ConvertFloorUI64 | ConvertTruncUI64 -> I64Type | PromoteF32 -> error at "invalid conversion" + | PromoteCeilF32 -> error at "invalid conversion" + | PromoteFloorF32 -> error at "invalid conversion" + | PromoteTruncF32 -> error at "invalid conversion" | DemoteF64 -> F64Type + | DemoteCeilF64 -> F64Type + | DemoteFloorF64 -> F64Type + | DemoteTruncF64 -> F64Type ), F32Type | Values.F64 cvtop -> let open F64Op in (match cvtop with - | ConvertSI32 | ConvertUI32 -> I32Type - | ConvertSI64 | ConvertUI64 | ReinterpretInt -> I64Type + | ConvertSI32 | ConvertCeilSI32 | ConvertFloorSI32 | ConvertTruncSI32 | ConvertUI32 | ConvertCeilUI32 | ConvertFloorUI32 | ConvertTruncUI32 -> I32Type + | ConvertSI64 | ConvertCeilSI64 | ConvertFloorSI64 | ConvertTruncSI64 | ConvertUI64 | ConvertCeilUI64 | ConvertFloorUI64 | ConvertTruncUI64 | ReinterpretInt -> I64Type | PromoteF32 -> F32Type + | PromoteCeilF32 -> F32Type + | PromoteFloorF32 -> F32Type + | PromoteTruncF32 -> F32Type | DemoteF64 -> error at "invalid conversion" + | DemoteCeilF64 -> error at "invalid conversion" + | DemoteFloorF64 -> error at "invalid conversion" + | DemoteTruncF64 -> error at "invalid conversion" ), F64Type let num_lanes = function