Repository: bytecodealliance/wasmtime
Pull request #7439 (2023-11-01 15:04:39)

egraphs: Remove extends and reduces from the shift amount
👋 Hey,

This PR adds a few egraph rules that remove extends from the inputs of shift and rotate instructions. These instructions support a different shift amount type than the instruction type, so we should be able to remove them.

Additionally it also removes ireduce and iconcat for the same reasons. This works for all types except for `i128` so we restrict those.

github-actions[bot]: #### Subscribe to Label Action

cc @cfallin, @fitzgen

<details>
This issue or pull request has been labeled: "cranelift", "isle"

Thus the following users have been cc'd because of the following labels:

* cfallin: isle
* fitzgen: isle

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

[Learn more.](https://github.com/bytecodealliance/subscribe-to-label-action)
</details>

Patch:
diff --git a/cranelift/codegen/src/opts/shifts.isle b/cranelift/codegen/src/opts/shifts.isle
index 8dcf153d1..1b33d89d8 100644
--- a/cranelift/codegen/src/opts/shifts.isle
+++ b/cranelift/codegen/src/opts/shifts.isle
@@ -102,3 +102,45 @@
 (rule (simplify (ineg ty (ushr ty x sconst @ (iconst ty (u64_from_imm64 shift_amt)))))
       (if-let $true (u64_eq shift_amt (u64_sub (ty_bits ty) 1)))
       (sshr ty x sconst))
+
+;; Shifts and rotates allow a different type for the shift amount, so we
+;; can remove any extend/reduce operations on the shift amount.
+;;
+;; (op x (ireduce y)) == (op x y)
+;; (op x (uextend y)) == (op x y)
+;; (op x (sextend y)) == (op x y)
+;;
+;; where `op` is one of ishl, ushr, sshr, rotl, rotr
+;;
+;; TODO: This rule is restricted to <=64 bits for ireduce since the x86
+;; backend doesn't support SIMD shifts with 128-bit shift amounts.
+
+(rule (simplify (ishl ty x (ireduce _ y @ (value_type (fits_in_64 _))))) (ishl ty x y))
+(rule (simplify (ishl ty x (uextend _ y))) (ishl ty x y))
+(rule (simplify (ishl ty x (sextend _ y))) (ishl ty x y))
+(rule (simplify (ushr ty x (ireduce _ y @ (value_type (fits_in_64 _))))) (ushr ty x y))
+(rule (simplify (ushr ty x (uextend _ y))) (ushr ty x y))
+(rule (simplify (ushr ty x (sextend _ y))) (ushr ty x y))
+(rule (simplify (sshr ty x (ireduce _ y @ (value_type (fits_in_64 _))))) (sshr ty x y))
+(rule (simplify (sshr ty x (uextend _ y))) (sshr ty x y))
+(rule (simplify (sshr ty x (sextend _ y))) (sshr ty x y))
+(rule (simplify (rotr ty x (ireduce _ y @ (value_type (fits_in_64 _))))) (rotr ty x y))
+(rule (simplify (rotr ty x (uextend _ y))) (rotr ty x y))
+(rule (simplify (rotr ty x (sextend _ y))) (rotr ty x y))
+(rule (simplify (rotl ty x (ireduce _ y @ (value_type (fits_in_64 _))))) (rotl ty x y))
+(rule (simplify (rotl ty x (uextend _ y))) (rotl ty x y))
+(rule (simplify (rotl ty x (sextend _ y))) (rotl ty x y))
+
+;; Remove iconcat from the shift amount input. This is correct even if the
+;; the iconcat is i8 type, since it can represent the largest shift amount
+;; for i128 types.
+;;
+;; (op x (iconcat y1 y2)) == (op x y1)
+;;
+;; where `op` is one of ishl, ushr, sshr, rotl, rotr
+
+(rule (simplify (ishl ty x (iconcat _ y _))) (ishl ty x y))
+(rule (simplify (ushr ty x (iconcat _ y _))) (ushr ty x y))
+(rule (simplify (sshr ty x (iconcat _ y _))) (sshr ty x y))
+(rule (simplify (rotr ty x (iconcat _ y _))) (rotr ty x y))
+(rule (simplify (rotl ty x (iconcat _ y _))) (rotl ty x y))
diff --git a/crates/cli-flags/src/lib.rs b/crates/cli-flags/src/lib.rs
index 0a496257c..03900707a 100644
--- a/crates/cli-flags/src/lib.rs
+++ b/crates/cli-flags/src/lib.rs
@@ -362,12 +362,10 @@ impl CommonOptions {
         } else {
             use std::io::IsTerminal;
             use tracing_subscriber::{EnvFilter, FmtSubscriber};
-            let mut b = FmtSubscriber::builder()
+            let b = FmtSubscriber::builder()
                 .with_writer(std::io::stderr)
-                .with_env_filter(EnvFilter::from_env("WASMTIME_LOG"));
-            if std::io::stderr().is_terminal() {
-                b = b.with_ansi(true);
-            }
+                .with_env_filter(EnvFilter::from_env("WASMTIME_LOG"))
+                .with_ansi(std::io::stderr().is_terminal());
             b.init();
         }
         #[cfg(not(feature = "logging"))]
diff --git a/crates/runtime/src/mpk/pkru.rs b/crates/runtime/src/mpk/pkru.rs
index 99dee74fa..9e36dd35a 100644
--- a/crates/runtime/src/mpk/pkru.rs
+++ b/crates/runtime/src/mpk/pkru.rs
@@ -56,6 +56,11 @@ pub fn write(pkru: u32) {
 /// Check the `ECX.PKU` flag (bit 3) of the `07h` `CPUID` leaf; see the
 /// Intel Software Development Manual, vol 3a, section 2.7.
 pub fn has_cpuid_bit_set() -> bool {
+    // TODO: disable MPK support until the following issue is resolved:
+    // https://github.com/bytecodealliance/wasmtime/issues/7445
+    if true {
+        return false;
+    }
     let result = unsafe { std::arch::x86_64::__cpuid(0x07) };
     (result.ecx & 0b100) != 0
 }
diff --git a/crates/wasi-common/cap-std-sync/src/stdio.rs b/crates/wasi-common/cap-std-sync/src/stdio.rs
index b2723d076..af4d52faa 100644
--- a/crates/wasi-common/cap-std-sync/src/stdio.rs
+++ b/crates/wasi-common/cap-std-sync/src/stdio.rs
@@ -127,7 +127,12 @@ macro_rules! wasi_file_write_impl {
                 Ok(FdFlags::APPEND)
             }
             async fn write_vectored<'a>(&self, bufs: &[io::IoSlice<'a>]) -> Result<u64, Error> {
-                let n = self.0.lock().write_vectored(bufs)?;
+                let mut io = self.0.lock();
+                let n = io.write_vectored(bufs)?;
+                // On a successful write additionally flush out the bytes to
+                // handle stdio buffering done by libstd since WASI interfaces
+                // here aren't buffered.
+                io.flush()?;
                 Ok(n.try_into().map_err(|_| {
                     Error::range().context("converting write_vectored total length")
                 })?)
diff --git a/crates/wasi-http/src/types.rs b/crates/wasi-http/src/types.rs
index dc41a30c6..e962ff47c 100644
--- a/crates/wasi-http/src/types.rs
+++ b/crates/wasi-http/src/types.rs
@@ -289,7 +289,7 @@ pub struct HostIncomingResponse {
 }
 
 pub struct HostOutgoingResponse {
-    pub status: u16,
+    pub status: http::StatusCode,
     pub headers: FieldMap,
     pub body: Option<HyperOutgoingBody>,
 }
diff --git a/crates/wasi-http/src/types_impl.rs b/crates/wasi-http/src/types_impl.rs
index 2f7612af1..bce0384ab 100644
--- a/crates/wasi-http/src/types_impl.rs
+++ b/crates/wasi-http/src/types_impl.rs
@@ -632,13 +632,12 @@ impl<T: WasiHttpView> crate::bindings::http::types::HostIncomingBody for T {
 impl<T: WasiHttpView> crate::bindings::http::types::HostOutgoingResponse for T {
     fn new(
         &mut self,
-        status: StatusCode,
         headers: Resource<Headers>,
     ) -> wasmtime::Result<Resource<HostOutgoingResponse>> {
         let fields = move_fields(self.table(), headers)?;
 
         let id = self.table().push(HostOutgoingResponse {
-            status,
+            status: http::StatusCode::OK,
             headers: fields,
             body: None,
         })?;
@@ -669,16 +668,26 @@ impl<T: WasiHttpView> crate::bindings::http::types::HostOutgoingResponse for T {
         &mut self,
         id: Resource<HostOutgoingResponse>,
     ) -> wasmtime::Result<types::StatusCode> {
-        Ok(self.table().get(&id)?.status)
+        Ok(self.table().get(&id)?.status.into())
     }
 
     fn set_status_code(
         &mut self,
         id: Resource<HostOutgoingResponse>,
         status: types::StatusCode,
-    ) -> wasmtime::Result<()> {
-        self.table().get_mut(&id)?.status = status;
-        Ok(())
+    ) -> wasmtime::Result<Result<(), Error>> {
+        let resp = self.table().get_mut(&id)?;
+
+        match http::StatusCode::from_u16(status) {
+            Ok(status) => resp.status = status,
+            Err(_) => {
+                return Ok(Err(Error::UnexpectedError(
+                    "Invalid status code".to_string(),
+                )))
+            }
+        };
+
+        Ok(Ok(()))
     }
 
     fn headers(
diff --git a/crates/wasi-http/wit/deps/http/types.wit b/crates/wasi-http/wit/deps/http/types.wit
index 9a0c8956b..81166b011 100644
--- a/crates/wasi-http/wit/deps/http/types.wit
+++ b/crates/wasi-http/wit/deps/http/types.wit
@@ -351,16 +351,18 @@ interface types {
   /// Represents an outgoing HTTP Response.
   resource outgoing-response {
 
-    /// Construct an `outgoing-response`.
+    /// Construct an `outgoing-response`, with a default `status-code` of `200`.
+    /// If a different `status-code` is needed, it must be set via the
+    /// `set-status-code` method.
     ///
-    /// * `status-code` is the HTTP Status Code for the Response.
     /// * `headers` is the HTTP Headers for the Response.
-    constructor(status-code: status-code, headers: headers);
+    constructor(headers: headers);
 
     /// Get the HTTP Status Code for the Response.
     status-code: func() -> status-code;
+
     /// Set the HTTP Status Code for the Response.
-    set-status-code: func(status-code: status-code);
+    set-status-code: func(status-code: status-code) -> result<_, error>;
 
     /// Get the headers associated with the Request.
     ///
diff --git a/crates/wasi/wit/deps/http/types.wit b/crates/wasi/wit/deps/http/types.wit
index 9a0c8956b..81166b011 100644
--- a/crates/wasi/wit/deps/http/types.wit
+++ b/crates/wasi/wit/deps/http/types.wit
@@ -351,16 +351,18 @@ interface types {
   /// Represents an outgoing HTTP Response.
   resource outgoing-response {
 
-    /// Construct an `outgoing-response`.
+    /// Construct an `outgoing-response`, with a default `status-code` of `200`.
+    /// If a different `status-code` is needed, it must be set via the
+    /// `set-status-code` method.
     ///
-    /// * `status-code` is the HTTP Status Code for the Response.
     /// * `headers` is the HTTP Headers for the Response.
-    constructor(status-code: status-code, headers: headers);
+    constructor(headers: headers);
 
     /// Get the HTTP Status Code for the Response.
     status-code: func() -> status-code;
+
     /// Set the HTTP Status Code for the Response.
-    set-status-code: func(status-code: status-code);
+    set-status-code: func(status-code: status-code) -> result<_, error>;
 
     /// Get the headers associated with the Request.
     ///
diff --git a/src/commands/run.rs b/src/commands/run.rs
index 89fe35e85..6ca015ddd 100644
--- a/src/commands/run.rs
+++ b/src/commands/run.rs
@@ -504,8 +504,8 @@ impl RunCommand {
                 // parses base-10 representations.
                 ValType::I32 => Val::I32(val.parse()?),
                 ValType::I64 => Val::I64(val.parse()?),
-                ValType::F32 => Val::F32(val.parse()?),
-                ValType::F64 => Val::F64(val.parse()?),
+                ValType::F32 => Val::F32(val.parse::<f32>()?.to_bits()),
+                ValType::F64 => Val::F64(val.parse::<f64>()?.to_bits()),
                 t => bail!("unsupported argument type {:?}", t),
             });
         }
diff --git a/winch/codegen/src/frame/mod.rs b/winch/codegen/src/frame/mod.rs
index 9a0329856..3e555a912 100644
--- a/winch/codegen/src/frame/mod.rs
+++ b/winch/codegen/src/frame/mod.rs
@@ -108,7 +108,7 @@ impl Frame {
             locals_size,
             vmctx_slot: LocalSlot::i64(vmctx_offset),
             defined_locals_range: DefinedLocalsRange(
-                defined_locals_start..defined_locals.stack_size,
+                defined_locals_start..(defined_locals_start + defined_locals.stack_size),
             ),
         })
     }
diff --git a/winch/codegen/src/isa/x64/asm.rs b/winch/codegen/src/isa/x64/asm.rs
index e44bdc4fc..98f7723c6 100644
--- a/winch/codegen/src/isa/x64/asm.rs
+++ b/winch/codegen/src/isa/x64/asm.rs
@@ -773,7 +773,10 @@ impl Assembler {
     }
 
     pub fn popcnt(&mut self, src: Reg, size: OperandSize) {
-        assert!(self.isa_flags.has_popcnt(), "Requires has_popcnt flag");
+        assert!(
+            self.isa_flags.has_popcnt() && self.isa_flags.has_sse42(),
+            "Requires has_popcnt and has_sse42 flags"
+        );
         self.emit(Inst::UnaryRmR {
             size: size.into(),
             op: args::UnaryRmROpcode::Popcnt,
diff --git a/winch/codegen/src/isa/x64/masm.rs b/winch/codegen/src/isa/x64/masm.rs
index f28ab3196..e534b040a 100644
--- a/winch/codegen/src/isa/x64/masm.rs
+++ b/winch/codegen/src/isa/x64/masm.rs
@@ -799,7 +799,7 @@ impl Masm for MacroAssembler {
 
     fn popcnt(&mut self, context: &mut CodeGenContext, size: OperandSize) {
         let src = context.pop_to_reg(self, None);
-        if self.flags.has_popcnt() {
+        if self.flags.has_popcnt() && self.flags.has_sse42() {
             self.asm.popcnt(src.into(), size);
             context.stack.push(src.into());
         } else {


Test patch:
diff --git a/cranelift/filetests/filetests/egraph/shifts.clif b/cranelift/filetests/filetests/egraph/shifts.clif
index b8028c50e..7852ada12 100644
--- a/cranelift/filetests/filetests/egraph/shifts.clif
+++ b/cranelift/filetests/filetests/egraph/shifts.clif
@@ -315,3 +315,212 @@ block0(v0: i64):
     ; check: v8 = uextend.i64 v7
     ; check: return v8
 }
+
+function %ishl_amt_type_ireduce(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = ireduce.i8 v1
+    v3 = ishl.i8 v0, v2
+    return v3
+}
+
+; check: v4 = ishl v0, v1
+; check: return v4
+
+function %ishl_amt_type_sextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = sextend.i32 v1
+    v3 = ishl.i8 v0, v2
+    return v3
+}
+
+; check: v4 = ishl v0, v1
+; check: return v4
+
+function %ishl_amt_type_uextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = uextend.i32 v1
+    v3 = ishl.i8 v0, v2
+    return v3
+}
+
+; check: v4 = ishl v0, v1
+; check: return v4
+
+
+function %ushr_amt_type_ireduce(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = ireduce.i8 v1
+    v3 = ushr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = ushr v0, v1
+; check: return v4
+
+function %ushr_amt_type_sextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = sextend.i32 v1
+    v3 = ushr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = ushr v0, v1
+; check: return v4
+
+function %ushr_amt_type_uextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = uextend.i32 v1
+    v3 = ushr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = ushr v0, v1
+; check: return v4
+
+
+function %sshr_amt_type_ireduce(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = ireduce.i8 v1
+    v3 = sshr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = sshr v0, v1
+; check: return v4
+
+function %sshr_amt_type_sextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = sextend.i32 v1
+    v3 = sshr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = sshr v0, v1
+; check: return v4
+
+function %sshr_amt_type_uextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = uextend.i32 v1
+    v3 = sshr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = sshr v0, v1
+; check: return v4
+
+
+function %rotr_amt_type_ireduce(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = ireduce.i8 v1
+    v3 = rotr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = rotr v0, v1
+; check: return v4
+
+function %rotr_amt_type_sextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = sextend.i32 v1
+    v3 = rotr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = rotr v0, v1
+; check: return v4
+
+function %rotr_amt_type_uextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = uextend.i32 v1
+    v3 = rotr.i8 v0, v2
+    return v3
+}
+
+; check: v4 = rotr v0, v1
+; check: return v4
+
+
+function %rotl_amt_type_ireduce(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = ireduce.i8 v1
+    v3 = rotl.i8 v0, v2
+    return v3
+}
+
+; check: v4 = rotl v0, v1
+; check: return v4
+
+function %rotl_amt_type_sextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = sextend.i32 v1
+    v3 = rotl.i8 v0, v2
+    return v3
+}
+
+; check: v4 = rotl v0, v1
+; check: return v4
+
+function %rotl_amt_type_uextend(i8, i16) -> i8 {
+block0(v0: i8, v1: i16):
+    v2 = uextend.i32 v1
+    v3 = rotl.i8 v0, v2
+    return v3
+}
+
+; check: v4 = rotl v0, v1
+; check: return v4
+
+
+function %ishl_amt_type_iconcat(i8, i16, i16) -> i8 {
+block0(v0: i8, v1: i16, v2: i16):
+    v3 = iconcat.i16 v1, v2
+    v4 = ishl.i8 v0, v3
+    return v4
+}
+
+; check: v5 = ishl v0, v1
+; check: return v5
+
+
+function %ushr_amt_type_iconcat(i8, i16, i16) -> i8 {
+block0(v0: i8, v1: i16, v2: i16):
+    v3 = iconcat.i16 v1, v2
+    v4 = ushr.i8 v0, v3
+    return v4
+}
+
+; check: v5 = ushr v0, v1
+; check: return v5
+
+
+function %sshr_amt_type_iconcat(i8, i16, i16) -> i8 {
+block0(v0: i8, v1: i16, v2: i16):
+    v3 = iconcat.i16 v1, v2
+    v4 = sshr.i8 v0, v3
+    return v4
+}
+
+; check: v5 = sshr v0, v1
+; check: return v5
+
+
+function %rotr_amt_type_iconcat(i8, i16, i16) -> i8 {
+block0(v0: i8, v1: i16, v2: i16):
+    v3 = iconcat.i16 v1, v2
+    v4 = rotr.i8 v0, v3
+    return v4
+}
+
+; check: v5 = rotr v0, v1
+; check: return v5
+
+
+function %rotl_amt_type_iconcat(i8, i16, i16) -> i8 {
+block0(v0: i8, v1: i16, v2: i16):
+    v3 = iconcat.i16 v1, v2
+    v4 = rotl.i8 v0, v3
+    return v4
+}
+
+; check: v5 = rotl v0, v1
+; check: return v5
diff --git a/crates/test-programs/src/bin/api_proxy.rs b/crates/test-programs/src/bin/api_proxy.rs
index 1bcdc783d..2170bdbbc 100644
--- a/crates/test-programs/src/bin/api_proxy.rs
+++ b/crates/test-programs/src/bin/api_proxy.rs
@@ -17,7 +17,7 @@ struct T;
 impl bindings::exports::wasi::http::incoming_handler::Guest for T {
     fn handle(_request: IncomingRequest, outparam: ResponseOutparam) {
         let hdrs = bindings::wasi::http::types::Headers::new();
-        let resp = bindings::wasi::http::types::OutgoingResponse::new(200, hdrs);
+        let resp = bindings::wasi::http::types::OutgoingResponse::new(hdrs);
         let body = resp.body().expect("outgoing response");
 
         bindings::wasi::http::types::ResponseOutparam::set(outparam, Ok(resp));
diff --git a/crates/test-programs/src/bin/api_proxy_streaming.rs b/crates/test-programs/src/bin/api_proxy_streaming.rs
index 5f1c0560c..730bef938 100644
--- a/crates/test-programs/src/bin/api_proxy_streaming.rs
+++ b/crates/test-programs/src/bin/api_proxy_streaming.rs
@@ -53,7 +53,6 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam
             let mut results = stream::iter(results).buffer_unordered(MAX_CONCURRENCY);
 
             let response = OutgoingResponse::new(
-                200,
                 Fields::from_list(&[("content-type".to_string(), b"text/plain".to_vec())]).unwrap(),
             );
 
@@ -79,7 +78,6 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam
             // Echo the request body without buffering it.
 
             let response = OutgoingResponse::new(
-                200,
                 Fields::from_list(
                     &headers
                         .into_iter()
@@ -129,7 +127,6 @@ async fn handle_request(request: IncomingRequest, response_out: ResponseOutparam
                         );
 
                         let response = OutgoingResponse::new(
-                            200,
                             Fields::from_list(
                                 &headers
                                     .into_iter()
@@ -242,7 +239,10 @@ fn method_not_allowed(response_out: ResponseOutparam) {
 }
 
 fn respond(status: u16, response_out: ResponseOutparam) {
-    let response = OutgoingResponse::new(status, Fields::new());
+    let response = OutgoingResponse::new(Fields::new());
+    response
+        .set_status_code(status)
+        .expect("setting status code");
 
     let body = response.body().expect("response should be writable");
 
diff --git a/crates/test-programs/src/bin/cli_stdio_write_flushes.rs b/crates/test-programs/src/bin/cli_stdio_write_flushes.rs
new file mode 100644
index 000000000..64d0ccdc6
--- /dev/null
+++ b/crates/test-programs/src/bin/cli_stdio_write_flushes.rs
@@ -0,0 +1,10 @@
+use std::io::Write;
+
+fn main() {
+    print!("> ");
+    std::io::stdout().flush().unwrap();
+
+    let mut s = String::new();
+    std::io::stdin().read_line(&mut s).unwrap();
+    assert!(s.is_empty());
+}
diff --git a/crates/test-programs/src/bin/http_outbound_request_response_build.rs b/crates/test-programs/src/bin/http_outbound_request_response_build.rs
index 8a50ff6fa..c2360d299 100644
--- a/crates/test-programs/src/bin/http_outbound_request_response_build.rs
+++ b/crates/test-programs/src/bin/http_outbound_request_response_build.rs
@@ -27,7 +27,7 @@ fn main() {
             "application/text".to_string().into_bytes(),
         )])
         .unwrap();
-        let response = http_types::OutgoingResponse::new(200, headers);
+        let response = http_types::OutgoingResponse::new(headers);
         let outgoing_body = response.body().unwrap();
         let response_body = outgoing_body.write().unwrap();
         response_body
diff --git a/crates/test-programs/src/bin/preview2_tcp_bind.rs b/crates/test-programs/src/bin/preview2_tcp_bind.rs
index 0dadd114b..faea346a1 100644
--- a/crates/test-programs/src/bin/preview2_tcp_bind.rs
+++ b/crates/test-programs/src/bin/preview2_tcp_bind.rs
@@ -30,7 +30,9 @@ fn test_tcp_bind_specific_port(net: &Network, ip: IpAddress) {
             assert_eq!(bind_addr.ip(), bound_addr.ip());
             assert_eq!(bind_addr.port(), bound_addr.port());
         }
-        Err(ErrorCode::AddressInUse) => {}
+        // Concurrent invocations of this test can yield `AddressInUse` and that
+        // same error can show up on Windows as `AccessDenied`.
+        Err(ErrorCode::AddressInUse | ErrorCode::AccessDenied) => {}
         Err(e) => panic!("error: {e}"),
     }
 }
diff --git a/tests/all/cli_tests.rs b/tests/all/cli_tests.rs
index b4bc8c86c..ff336feb8 100644
--- a/tests/all/cli_tests.rs
+++ b/tests/all/cli_tests.rs
@@ -1176,10 +1176,29 @@ warning: this CLI invocation of Wasmtime is going to break in the future -- for
     Ok(())
 }
 
+#[test]
+fn float_args() -> Result<()> {
+    let result = run_wasmtime(&[
+        "--invoke",
+        "echo_f32",
+        "tests/all/cli_tests/simple.wat",
+        "1.0",
+    ])?;
+    assert_eq!(result, "1\n");
+    let result = run_wasmtime(&[
+        "--invoke",
+        "echo_f64",
+        "tests/all/cli_tests/simple.wat",
+        "1.1",
+    ])?;
+    assert_eq!(result, "1.1\n");
+    Ok(())
+}
+
 mod test_programs {
     use super::{get_wasmtime_command, run_wasmtime};
     use anyhow::Result;
-    use std::io::Write;
+    use std::io::{Read, Write};
     use std::process::Stdio;
     use test_programs_artifacts::*;
 
@@ -1430,4 +1449,40 @@ mod test_programs {
         assert!(output.status.success());
         Ok(())
     }
+
+    // Test to ensure that prints in the guest aren't buffered on the host by
+    // accident. The test here will print something without a newline and then
+    // wait for input on stdin, and the test here is to ensure that the
+    // character shows up here even as the guest is waiting on input via stdin.
+    #[test]
+    fn cli_stdio_write_flushes() -> Result<()> {
+        fn run(args: &[&str]) -> Result<()> {
+            println!("running {args:?}");
+            let mut child = get_wasmtime_command()?
+                .args(args)
+                .stdin(Stdio::piped())
+                .stdout(Stdio::piped())
+                .spawn()?;
+            let mut stdout = child.stdout.take().unwrap();
+            let mut buf = [0; 10];
+            match stdout.read(&mut buf) {
+                Ok(2) => assert_eq!(&buf[..2], b"> "),
+                e => panic!("unexpected read result {e:?}"),
+            }
+            drop(stdout);
+            drop(child.stdin.take().unwrap());
+            let status = child.wait()?;
+            assert!(status.success());
+            Ok(())
+        }
+
+        run(&["run", "-Spreview2=n", CLI_STDIO_WRITE_FLUSHES])?;
+        run(&["run", "-Spreview2=y", CLI_STDIO_WRITE_FLUSHES])?;
+        run(&[
+            "run",
+            "-Wcomponent-model",
+            CLI_STDIO_WRITE_FLUSHES_COMPONENT,
+        ])?;
+        Ok(())
+    }
 }
diff --git a/tests/all/cli_tests/simple.wat b/tests/all/cli_tests/simple.wat
index a851dfa00..a62319c5e 100644
--- a/tests/all/cli_tests/simple.wat
+++ b/tests/all/cli_tests/simple.wat
@@ -4,4 +4,6 @@
     )
     (func (export "get_f32") (result f32) f32.const 100)
     (func (export "get_f64") (result f64) f64.const 100)
+    (func (export "echo_f32") (param f32) (result f32) local.get 0)
+    (func (export "echo_f64") (param f64) (result f64) local.get 0)
 )
diff --git a/winch/filetests/filetests/x64/br_if/as_local_set_value.wat b/winch/filetests/filetests/x64/br_if/as_local_set_value.wat
index 054e6a8b3..ee5f0ac87 100644
--- a/winch/filetests/filetests/x64/br_if/as_local_set_value.wat
+++ b/winch/filetests/filetests/x64/br_if/as_local_set_value.wat
@@ -12,13 +12,15 @@
 ;;    1:	 4889e5               	mov	rbp, rsp
 ;;    4:	 4883ec10             	sub	rsp, 0x10
 ;;    8:	 897c240c             	mov	dword ptr [rsp + 0xc], edi
-;;    c:	 4c893424             	mov	qword ptr [rsp], r14
-;;   10:	 8b4c240c             	mov	ecx, dword ptr [rsp + 0xc]
-;;   14:	 b811000000           	mov	eax, 0x11
-;;   19:	 85c9                 	test	ecx, ecx
-;;   1b:	 0f8509000000         	jne	0x2a
-;;   21:	 8944240c             	mov	dword ptr [rsp + 0xc], eax
-;;   25:	 b8ffffffff           	mov	eax, 0xffffffff
-;;   2a:	 4883c410             	add	rsp, 0x10
-;;   2e:	 5d                   	pop	rbp
-;;   2f:	 c3                   	ret	
+;;    c:	 c744240800000000     	mov	dword ptr [rsp + 8], 0
+;;   14:	 4531db               	xor	r11d, r11d
+;;   17:	 4c893424             	mov	qword ptr [rsp], r14
+;;   1b:	 8b4c240c             	mov	ecx, dword ptr [rsp + 0xc]
+;;   1f:	 b811000000           	mov	eax, 0x11
+;;   24:	 85c9                 	test	ecx, ecx
+;;   26:	 0f8509000000         	jne	0x35
+;;   2c:	 8944240c             	mov	dword ptr [rsp + 0xc], eax
+;;   30:	 b8ffffffff           	mov	eax, 0xffffffff
+;;   35:	 4883c410             	add	rsp, 0x10
+;;   39:	 5d                   	pop	rbp
+;;   3a:	 c3                   	ret	
diff --git a/winch/filetests/filetests/x64/i32_popcnt/no_sse42.wat b/winch/filetests/filetests/x64/i32_popcnt/no_sse42.wat
new file mode 100644
index 000000000..dc3567e84
--- /dev/null
+++ b/winch/filetests/filetests/x64/i32_popcnt/no_sse42.wat
@@ -0,0 +1,33 @@
+;;! target = "x86_64"
+;;! flags = ["has_popcnt"]
+
+(module
+    (func (result i32)
+      i32.const 3
+      i32.popcnt
+    )
+)
+;;    0:	 55                   	push	rbp
+;;    1:	 4889e5               	mov	rbp, rsp
+;;    4:	 4883ec08             	sub	rsp, 8
+;;    8:	 4c893424             	mov	qword ptr [rsp], r14
+;;    c:	 b803000000           	mov	eax, 3
+;;   11:	 89c1                 	mov	ecx, eax
+;;   13:	 c1e801               	shr	eax, 1
+;;   16:	 81e055555555         	and	eax, 0x55555555
+;;   1c:	 29c1                 	sub	ecx, eax
+;;   1e:	 89c8                 	mov	eax, ecx
+;;   20:	 41bb33333333         	mov	r11d, 0x33333333
+;;   26:	 4421d8               	and	eax, r11d
+;;   29:	 c1e902               	shr	ecx, 2
+;;   2c:	 4421d9               	and	ecx, r11d
+;;   2f:	 01c1                 	add	ecx, eax
+;;   31:	 89c8                 	mov	eax, ecx
+;;   33:	 c1e804               	shr	eax, 4
+;;   36:	 01c8                 	add	eax, ecx
+;;   38:	 81e00f0f0f0f         	and	eax, 0xf0f0f0f
+;;   3e:	 69c001010101         	imul	eax, eax, 0x1010101
+;;   44:	 c1e818               	shr	eax, 0x18
+;;   47:	 4883c408             	add	rsp, 8
+;;   4b:	 5d                   	pop	rbp
+;;   4c:	 c3                   	ret	
diff --git a/winch/filetests/filetests/x64/i64_popcnt/no_sse42.wat b/winch/filetests/filetests/x64/i64_popcnt/no_sse42.wat
new file mode 100644
index 000000000..7430a14ff
--- /dev/null
+++ b/winch/filetests/filetests/x64/i64_popcnt/no_sse42.wat
@@ -0,0 +1,40 @@
+;;! target = "x86_64"
+;;! flags = ["has_popcnt"]
+
+(module
+    (func (result i64)
+      i64.const 3
+      i64.popcnt
+    )
+)
+;;    0:	 55                   	push	rbp
+;;    1:	 4889e5               	mov	rbp, rsp
+;;    4:	 4883ec08             	sub	rsp, 8
+;;    8:	 4c893424             	mov	qword ptr [rsp], r14
+;;    c:	 48c7c003000000       	mov	rax, 3
+;;   13:	 4889c1               	mov	rcx, rax
+;;   16:	 48c1e801             	shr	rax, 1
+;;   1a:	 49bb5555555555555555 	
+;; 				movabs	r11, 0x5555555555555555
+;;   24:	 4c21d8               	and	rax, r11
+;;   27:	 4829c1               	sub	rcx, rax
+;;   2a:	 4889c8               	mov	rax, rcx
+;;   2d:	 49bb3333333333333333 	
+;; 				movabs	r11, 0x3333333333333333
+;;   37:	 4c21d8               	and	rax, r11
+;;   3a:	 48c1e902             	shr	rcx, 2
+;;   3e:	 4c21d9               	and	rcx, r11
+;;   41:	 4801c1               	add	rcx, rax
+;;   44:	 4889c8               	mov	rax, rcx
+;;   47:	 48c1e804             	shr	rax, 4
+;;   4b:	 4801c8               	add	rax, rcx
+;;   4e:	 49bb0f0f0f0f0f0f0f0f 	
+;; 				movabs	r11, 0xf0f0f0f0f0f0f0f
+;;   58:	 4c21d8               	and	rax, r11
+;;   5b:	 49bb0101010101010101 	
+;; 				movabs	r11, 0x101010101010101
+;;   65:	 490fafc3             	imul	rax, r11
+;;   69:	 48c1e838             	shr	rax, 0x38
+;;   6d:	 4883c408             	add	rsp, 8
+;;   71:	 5d                   	pop	rbp
+;;   72:	 c3                   	ret	
diff --git a/winch/filetests/filetests/x64/loop/for.wat b/winch/filetests/filetests/x64/loop/for.wat
index cbeb993b6..2db94dd07 100644
--- a/winch/filetests/filetests/x64/loop/for.wat
+++ b/winch/filetests/filetests/x64/loop/for.wat
@@ -19,29 +19,30 @@
 ;;    1:	 4889e5               	mov	rbp, rsp
 ;;    4:	 4883ec20             	sub	rsp, 0x20
 ;;    8:	 48897c2418           	mov	qword ptr [rsp + 0x18], rdi
-;;    d:	 48c744241000000000   	
-;; 				mov	qword ptr [rsp + 0x10], 0
-;;   16:	 4c893424             	mov	qword ptr [rsp], r14
-;;   1a:	 48c7c001000000       	mov	rax, 1
-;;   21:	 4889442410           	mov	qword ptr [rsp + 0x10], rax
-;;   26:	 48c7c002000000       	mov	rax, 2
-;;   2d:	 4889442408           	mov	qword ptr [rsp + 8], rax
-;;   32:	 488b442418           	mov	rax, qword ptr [rsp + 0x18]
-;;   37:	 488b4c2408           	mov	rcx, qword ptr [rsp + 8]
-;;   3c:	 4839c1               	cmp	rcx, rax
-;;   3f:	 b900000000           	mov	ecx, 0
-;;   44:	 400f97c1             	seta	cl
-;;   48:	 85c9                 	test	ecx, ecx
-;;   4a:	 0f8526000000         	jne	0x76
-;;   50:	 488b442408           	mov	rax, qword ptr [rsp + 8]
-;;   55:	 488b4c2410           	mov	rcx, qword ptr [rsp + 0x10]
-;;   5a:	 480fafc8             	imul	rcx, rax
-;;   5e:	 48894c2410           	mov	qword ptr [rsp + 0x10], rcx
-;;   63:	 488b442408           	mov	rax, qword ptr [rsp + 8]
-;;   68:	 4883c001             	add	rax, 1
-;;   6c:	 4889442408           	mov	qword ptr [rsp + 8], rax
-;;   71:	 e9bcffffff           	jmp	0x32
-;;   76:	 488b442410           	mov	rax, qword ptr [rsp + 0x10]
-;;   7b:	 4883c420             	add	rsp, 0x20
-;;   7f:	 5d                   	pop	rbp
-;;   80:	 c3                   	ret	
+;;    d:	 4531db               	xor	r11d, r11d
+;;   10:	 4c895c2410           	mov	qword ptr [rsp + 0x10], r11
+;;   15:	 4c895c2408           	mov	qword ptr [rsp + 8], r11
+;;   1a:	 4c893424             	mov	qword ptr [rsp], r14
+;;   1e:	 48c7c001000000       	mov	rax, 1
+;;   25:	 4889442410           	mov	qword ptr [rsp + 0x10], rax
+;;   2a:	 48c7c002000000       	mov	rax, 2
+;;   31:	 4889442408           	mov	qword ptr [rsp + 8], rax
+;;   36:	 488b442418           	mov	rax, qword ptr [rsp + 0x18]
+;;   3b:	 488b4c2408           	mov	rcx, qword ptr [rsp + 8]
+;;   40:	 4839c1               	cmp	rcx, rax
+;;   43:	 b900000000           	mov	ecx, 0
+;;   48:	 400f97c1             	seta	cl
+;;   4c:	 85c9                 	test	ecx, ecx
+;;   4e:	 0f8526000000         	jne	0x7a
+;;   54:	 488b442408           	mov	rax, qword ptr [rsp + 8]
+;;   59:	 488b4c2410           	mov	rcx, qword ptr [rsp + 0x10]
+;;   5e:	 480fafc8             	imul	rcx, rax
+;;   62:	 48894c2410           	mov	qword ptr [rsp + 0x10], rcx
+;;   67:	 488b442408           	mov	rax, qword ptr [rsp + 8]
+;;   6c:	 4883c001             	add	rax, 1
+;;   70:	 4889442408           	mov	qword ptr [rsp + 8], rax
+;;   75:	 e9bcffffff           	jmp	0x36
+;;   7a:	 488b442410           	mov	rax, qword ptr [rsp + 0x10]
+;;   7f:	 4883c420             	add	rsp, 0x20
+;;   83:	 5d                   	pop	rbp
+;;   84:	 c3                   	ret	
diff --git a/winch/filetests/filetests/x64/loop/while.wat b/winch/filetests/filetests/x64/loop/while.wat
index e9773ab92..adef2ad06 100644
--- a/winch/filetests/filetests/x64/loop/while.wat
+++ b/winch/filetests/filetests/x64/loop/while.wat
@@ -18,24 +18,26 @@
 ;;    1:	 4889e5               	mov	rbp, rsp
 ;;    4:	 4883ec18             	sub	rsp, 0x18
 ;;    8:	 48897c2410           	mov	qword ptr [rsp + 0x10], rdi
-;;    d:	 4c893424             	mov	qword ptr [rsp], r14
-;;   11:	 48c7c001000000       	mov	rax, 1
-;;   18:	 4889442408           	mov	qword ptr [rsp + 8], rax
-;;   1d:	 488b442410           	mov	rax, qword ptr [rsp + 0x10]
-;;   22:	 4883f800             	cmp	rax, 0
-;;   26:	 b800000000           	mov	eax, 0
-;;   2b:	 400f94c0             	sete	al
-;;   2f:	 85c0                 	test	eax, eax
-;;   31:	 0f8526000000         	jne	0x5d
-;;   37:	 488b442408           	mov	rax, qword ptr [rsp + 8]
-;;   3c:	 488b4c2410           	mov	rcx, qword ptr [rsp + 0x10]
-;;   41:	 480fafc8             	imul	rcx, rax
-;;   45:	 48894c2408           	mov	qword ptr [rsp + 8], rcx
-;;   4a:	 488b442410           	mov	rax, qword ptr [rsp + 0x10]
-;;   4f:	 4883e801             	sub	rax, 1
-;;   53:	 4889442410           	mov	qword ptr [rsp + 0x10], rax
-;;   58:	 e9c0ffffff           	jmp	0x1d
-;;   5d:	 488b442408           	mov	rax, qword ptr [rsp + 8]
-;;   62:	 4883c418             	add	rsp, 0x18
-;;   66:	 5d                   	pop	rbp
-;;   67:	 c3                   	ret	
+;;    d:	 48c744240800000000   	
+;; 				mov	qword ptr [rsp + 8], 0
+;;   16:	 4c893424             	mov	qword ptr [rsp], r14
+;;   1a:	 48c7c001000000       	mov	rax, 1
+;;   21:	 4889442408           	mov	qword ptr [rsp + 8], rax
+;;   26:	 488b442410           	mov	rax, qword ptr [rsp + 0x10]
+;;   2b:	 4883f800             	cmp	rax, 0
+;;   2f:	 b800000000           	mov	eax, 0
+;;   34:	 400f94c0             	sete	al
+;;   38:	 85c0                 	test	eax, eax
+;;   3a:	 0f8526000000         	jne	0x66
+;;   40:	 488b442408           	mov	rax, qword ptr [rsp + 8]
+;;   45:	 488b4c2410           	mov	rcx, qword ptr [rsp + 0x10]
+;;   4a:	 480fafc8             	imul	rcx, rax
+;;   4e:	 48894c2408           	mov	qword ptr [rsp + 8], rcx
+;;   53:	 488b442410           	mov	rax, qword ptr [rsp + 0x10]
+;;   58:	 4883e801             	sub	rax, 1
+;;   5c:	 4889442410           	mov	qword ptr [rsp + 0x10], rax
+;;   61:	 e9c0ffffff           	jmp	0x26
+;;   66:	 488b442408           	mov	rax, qword ptr [rsp + 8]
+;;   6b:	 4883c418             	add	rsp, 0x18
+;;   6f:	 5d                   	pop	rbp
+;;   70:	 c3                   	ret	
diff --git a/winch/filetests/filetests/x64/table/fill.wat b/winch/filetests/filetests/x64/table/fill.wat
index 2a6121295..d811a646f 100644
--- a/winch/filetests/filetests/x64/table/fill.wat
+++ b/winch/filetests/filetests/x64/table/fill.wat
@@ -49,46 +49,49 @@
 ;;    8:	 897c241c             	mov	dword ptr [rsp + 0x1c], edi
 ;;    c:	 89742418             	mov	dword ptr [rsp + 0x18], esi
 ;;   10:	 89542414             	mov	dword ptr [rsp + 0x14], edx
-;;   14:	 4c89742404           	mov	qword ptr [rsp + 4], r14
-;;   19:	 8b4c2418             	mov	ecx, dword ptr [rsp + 0x18]
-;;   1d:	 4c89f2               	mov	rdx, r14
-;;   20:	 8b5a50               	mov	ebx, dword ptr [rdx + 0x50]
-;;   23:	 39d9                 	cmp	ecx, ebx
-;;   25:	 0f8381000000         	jae	0xac
-;;   2b:	 4189cb               	mov	r11d, ecx
-;;   2e:	 4d6bdb08             	imul	r11, r11, 8
-;;   32:	 488b5248             	mov	rdx, qword ptr [rdx + 0x48]
-;;   36:	 4889d6               	mov	rsi, rdx
-;;   39:	 4c01da               	add	rdx, r11
-;;   3c:	 39d9                 	cmp	ecx, ebx
-;;   3e:	 480f43d6             	cmovae	rdx, rsi
-;;   42:	 488b02               	mov	rax, qword ptr [rdx]
-;;   45:	 4885c0               	test	rax, rax
-;;   48:	 0f8523000000         	jne	0x71
-;;   4e:	 4d8b5e38             	mov	r11, qword ptr [r14 + 0x38]
-;;   52:	 498b5b48             	mov	rbx, qword ptr [r11 + 0x48]
-;;   56:	 4156                 	push	r14
-;;   58:	 51                   	push	rcx
-;;   59:	 488b7c2408           	mov	rdi, qword ptr [rsp + 8]
-;;   5e:	 be00000000           	mov	esi, 0
-;;   63:	 8b1424               	mov	edx, dword ptr [rsp]
-;;   66:	 ffd3                 	call	rbx
-;;   68:	 4883c410             	add	rsp, 0x10
-;;   6c:	 e904000000           	jmp	0x75
-;;   71:	 4883e0fe             	and	rax, 0xfffffffffffffffe
-;;   75:	 488944240c           	mov	qword ptr [rsp + 0xc], rax
-;;   7a:	 4d8b5e38             	mov	r11, qword ptr [r14 + 0x38]
-;;   7e:	 498b4368             	mov	rax, qword ptr [r11 + 0x68]
-;;   82:	 4156                 	push	r14
-;;   84:	 4883ec08             	sub	rsp, 8
-;;   88:	 488b7c2408           	mov	rdi, qword ptr [rsp + 8]
-;;   8d:	 be01000000           	mov	esi, 1
-;;   92:	 8b54242c             	mov	edx, dword ptr [rsp + 0x2c]
-;;   96:	 488b4c241c           	mov	rcx, qword ptr [rsp + 0x1c]
-;;   9b:	 448b442424           	mov	r8d, dword ptr [rsp + 0x24]
-;;   a0:	 ffd0                 	call	rax
-;;   a2:	 4883c410             	add	rsp, 0x10
-;;   a6:	 4883c420             	add	rsp, 0x20
-;;   aa:	 5d                   	pop	rbp
-;;   ab:	 c3                   	ret	
-;;   ac:	 0f0b                 	ud2	
+;;   14:	 c744241000000000     	mov	dword ptr [rsp + 0x10], 0
+;;   1c:	 48c744240800000000   	
+;; 				mov	qword ptr [rsp + 8], 0
+;;   25:	 4c89742404           	mov	qword ptr [rsp + 4], r14
+;;   2a:	 8b4c2418             	mov	ecx, dword ptr [rsp + 0x18]
+;;   2e:	 4c89f2               	mov	rdx, r14
+;;   31:	 8b5a50               	mov	ebx, dword ptr [rdx + 0x50]
+;;   34:	 39d9                 	cmp	ecx, ebx
+;;   36:	 0f8381000000         	jae	0xbd
+;;   3c:	 4189cb               	mov	r11d, ecx
+;;   3f:	 4d6bdb08             	imul	r11, r11, 8
+;;   43:	 488b5248             	mov	rdx, qword ptr [rdx + 0x48]
+;;   47:	 4889d6               	mov	rsi, rdx
+;;   4a:	 4c01da               	add	rdx, r11
+;;   4d:	 39d9                 	cmp	ecx, ebx
+;;   4f:	 480f43d6             	cmovae	rdx, rsi
+;;   53:	 488b02               	mov	rax, qword ptr [rdx]
+;;   56:	 4885c0               	test	rax, rax
+;;   59:	 0f8523000000         	jne	0x82
+;;   5f:	 4d8b5e38             	mov	r11, qword ptr [r14 + 0x38]
+;;   63:	 498b5b48             	mov	rbx, qword ptr [r11 + 0x48]
+;;   67:	 4156                 	push	r14
+;;   69:	 51                   	push	rcx
+;;   6a:	 488b7c2408           	mov	rdi, qword ptr [rsp + 8]
+;;   6f:	 be00000000           	mov	esi, 0
+;;   74:	 8b1424               	mov	edx, dword ptr [rsp]
+;;   77:	 ffd3                 	call	rbx
+;;   79:	 4883c410             	add	rsp, 0x10
+;;   7d:	 e904000000           	jmp	0x86
+;;   82:	 4883e0fe             	and	rax, 0xfffffffffffffffe
+;;   86:	 488944240c           	mov	qword ptr [rsp + 0xc], rax
+;;   8b:	 4d8b5e38             	mov	r11, qword ptr [r14 + 0x38]
+;;   8f:	 498b4368             	mov	rax, qword ptr [r11 + 0x68]
+;;   93:	 4156                 	push	r14
+;;   95:	 4883ec08             	sub	rsp, 8
+;;   99:	 488b7c2408           	mov	rdi, qword ptr [rsp + 8]
+;;   9e:	 be01000000           	mov	esi, 1
+;;   a3:	 8b54242c             	mov	edx, dword ptr [rsp + 0x2c]
+;;   a7:	 488b4c241c           	mov	rcx, qword ptr [rsp + 0x1c]
+;;   ac:	 448b442424           	mov	r8d, dword ptr [rsp + 0x24]
+;;   b1:	 ffd0                 	call	rax
+;;   b3:	 4883c410             	add	rsp, 0x10
+;;   b7:	 4883c420             	add	rsp, 0x20
+;;   bb:	 5d                   	pop	rbp
+;;   bc:	 c3                   	ret	
+;;   bd:	 0f0b                 	ud2