wasmer_compiler_llvm/translator/
code.rs

1use std::collections::HashMap;
2
3use super::{
4    intrinsics::{
5        CtxType, FunctionCache, GlobalCache, Intrinsics, MemoryCache, tbaa_label, type_to_llvm,
6    },
7    // stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic},
8    state::{ControlFrame, ExtraInfo, IfElseState, State, TagCatchInfo},
9};
10use inkwell::{
11    AddressSpace, AtomicOrdering, AtomicRMWBinOp, DLLStorageClass, FloatPredicate, IntPredicate,
12    attributes::AttributeLoc,
13    builder::Builder,
14    context::Context,
15    module::{Linkage, Module},
16    passes::PassBuilderOptions,
17    targets::{FileType, TargetMachine},
18    types::{BasicType, BasicTypeEnum, FloatMathType, IntType, PointerType, VectorType},
19    values::{
20        BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue, FloatValue,
21        FunctionValue, InstructionOpcode, InstructionValue, IntValue, PhiValue, PointerValue,
22        VectorValue,
23    },
24};
25use itertools::Itertools;
26use smallvec::SmallVec;
27use target_lexicon::{BinaryFormat, OperatingSystem, Triple};
28
29use crate::{
30    abi::{Abi, G0M0FunctionKind, LocalFunctionG0M0params, get_abi},
31    config::LLVM,
32    error::{err, err_nt},
33    object_file::{CompiledFunction, load_object_file},
34};
35use wasmer_compiler::{
36    FunctionBinaryReader, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddlewareChain,
37    ModuleTranslationState, from_binaryreadererror_wasmerror,
38    misc::CompiledKind,
39    types::{
40        relocation::RelocationTarget,
41        symbols::{Symbol, SymbolRegistry},
42    },
43    wasmparser::{Catch, MemArg, Operator},
44    wpheaptype_to_type, wptype_to_type,
45};
46use wasmer_types::{
47    CompileError, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex,
48    ModuleInfo, SignatureIndex, TableIndex, Type,
49};
50use wasmer_types::{TagIndex, entity::PrimaryMap};
51use wasmer_vm::{MemoryStyle, TableStyle, VMOffsets};
52
53const FUNCTION_SECTION_ELF: &str = "__TEXT,wasmer_function";
54const FUNCTION_SECTION_MACHO: &str = "__TEXT";
55const FUNCTION_SEGMENT_MACHO: &str = "wasmer_function";
56
57// Since we want to use module-local tag numbers for landing pads,
58// the catch-all tag can't be zero; we instead use i32::MAX, which
59// is hopefully large enough to not conflict with any real tag.
60// If you have 2 billion tags in a single module, you deserve what you get.
61// ( Arshia: that comment above is AI-generated... AI is savage XD )
62const CATCH_ALL_TAG_VALUE: i32 = i32::MAX;
63
64pub struct FuncTranslator {
65    ctx: Context,
66    target_machine: TargetMachine,
67    abi: Box<dyn Abi>,
68    binary_fmt: BinaryFormat,
69    func_section: String,
70}
71
72impl FuncTranslator {
73    pub fn new(
74        target_machine: TargetMachine,
75        binary_fmt: BinaryFormat,
76    ) -> Result<Self, CompileError> {
77        let abi = get_abi(&target_machine);
78        Ok(Self {
79            ctx: Context::create(),
80            target_machine,
81            abi,
82            func_section: match binary_fmt {
83                BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
84                BinaryFormat::Macho => FUNCTION_SEGMENT_MACHO.to_string(),
85                _ => {
86                    return Err(CompileError::UnsupportedTarget(format!(
87                        "Unsupported binary format: {binary_fmt:?}"
88                    )));
89                }
90            },
91            binary_fmt,
92        })
93    }
94
95    #[allow(clippy::too_many_arguments)]
96    pub fn translate_to_module(
97        &self,
98        wasm_module: &ModuleInfo,
99        module_translation: &ModuleTranslationState,
100        local_func_index: &LocalFunctionIndex,
101        function_body: &FunctionBodyData,
102        config: &LLVM,
103        memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
104        _table_styles: &PrimaryMap<TableIndex, TableStyle>,
105        symbol_registry: &dyn SymbolRegistry,
106        target: &Triple,
107    ) -> Result<Module<'_>, CompileError> {
108        // The function type, used for the callbacks.
109        let func_index = wasm_module.func_index(*local_func_index);
110        let function =
111            CompiledKind::Local(*local_func_index, wasm_module.get_function_name(func_index));
112        let function_name =
113            symbol_registry.symbol_to_name(Symbol::LocalFunction(*local_func_index));
114
115        let g0m0_is_enabled = config.enable_g0m0_opt;
116        let func_kind = if g0m0_is_enabled {
117            Some(G0M0FunctionKind::Local)
118        } else {
119            None
120        };
121
122        let module_name = match wasm_module.name.as_ref() {
123            None => format!("<anonymous module> function {function_name}"),
124            Some(module_name) => format!("module {module_name} function {function_name}"),
125        };
126        let module = self.ctx.create_module(module_name.as_str());
127
128        let target_machine = &self.target_machine;
129        let target_triple = target_machine.get_triple();
130        let target_data = target_machine.get_target_data();
131        module.set_triple(&target_triple);
132        module.set_data_layout(&target_data.get_data_layout());
133        let wasm_fn_type = wasm_module
134            .signatures
135            .get(wasm_module.functions[func_index])
136            .unwrap();
137
138        // TODO: pointer width
139        let offsets = VMOffsets::new(8, wasm_module);
140        let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data, &self.binary_fmt);
141        let (func_type, func_attrs) = self.abi.func_type_to_llvm(
142            &self.ctx,
143            &intrinsics,
144            Some(&offsets),
145            wasm_fn_type,
146            func_kind,
147        )?;
148
149        let func = module.add_function(&function_name, func_type, Some(Linkage::External));
150        for (attr, attr_loc) in &func_attrs {
151            func.add_attribute(*attr_loc, *attr);
152        }
153
154        if !matches!(target.operating_system, OperatingSystem::Windows) {
155            func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe);
156        }
157
158        func.add_attribute(AttributeLoc::Function, intrinsics.uwtable);
159        func.add_attribute(AttributeLoc::Function, intrinsics.frame_pointer);
160
161        let section = match self.binary_fmt {
162            BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
163            BinaryFormat::Macho => {
164                format!("{FUNCTION_SECTION_MACHO},{FUNCTION_SEGMENT_MACHO}")
165            }
166            _ => {
167                return Err(CompileError::UnsupportedTarget(format!(
168                    "Unsupported binary format: {:?}",
169                    self.binary_fmt
170                )));
171            }
172        };
173
174        func.set_personality_function(intrinsics.personality);
175        func.as_global_value().set_section(Some(&section));
176
177        func.set_linkage(Linkage::DLLExport);
178        func.as_global_value()
179            .set_dll_storage_class(DLLStorageClass::Export);
180
181        let entry = self.ctx.append_basic_block(func, "entry");
182        let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
183        let return_ = self.ctx.append_basic_block(func, "return");
184        let alloca_builder = self.ctx.create_builder();
185        let cache_builder = self.ctx.create_builder();
186        let builder = self.ctx.create_builder();
187        cache_builder.position_at_end(entry);
188        let br = err!(cache_builder.build_unconditional_branch(start_of_code));
189        alloca_builder.position_before(&br);
190        cache_builder.position_before(&br);
191        builder.position_at_end(start_of_code);
192
193        let mut state = State::new();
194        builder.position_at_end(return_);
195        let phis: SmallVec<[PhiValue; 1]> = wasm_fn_type
196            .results()
197            .iter()
198            .map(|&wasm_ty| {
199                type_to_llvm(&intrinsics, wasm_ty).map(|ty| builder.build_phi(ty, "").unwrap())
200            })
201            .collect::<Result<_, _>>()?;
202        state.push_block(return_, phis, 0);
203        builder.position_at_end(start_of_code);
204
205        let mut reader = MiddlewareBinaryReader::new_with_offset(
206            function_body.data,
207            function_body.module_offset,
208        );
209        reader.set_middleware_chain(
210            config
211                .middlewares
212                .generate_function_middleware_chain(*local_func_index),
213        );
214
215        let mut params = vec![];
216        let first_param =
217            if func_type.get_return_type().is_none() && wasm_fn_type.results().len() > 1 {
218                if g0m0_is_enabled { 4 } else { 2 }
219            } else if g0m0_is_enabled {
220                3
221            } else {
222                1
223            };
224        let mut is_first_alloca = true;
225        let mut insert_alloca = |ty, name: String| -> Result<PointerValue, CompileError> {
226            let alloca = err!(alloca_builder.build_alloca(ty, &name));
227            if is_first_alloca {
228                alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
229                is_first_alloca = false;
230            }
231            Ok(alloca)
232        };
233
234        // Uncomment to print, at the start of the function, the function name.
235        // (poor man's debugger!)
236        //let func_name_str =
237        //    err!(alloca_builder.build_global_string_ptr(&function_name, "function_name"));
238        //
239        //_ = alloca_builder.build_call(
240        //    intrinsics.debug_str,
241        //    &[
242        //        func_name_str.as_pointer_value().into(),
243        //        intrinsics
244        //            .i32_ty
245        //            .const_int(function_name.len() as _, false)
246        //            .into(),
247        //    ],
248        //    "",
249        //);
250
251        for idx in 0..wasm_fn_type.params().len() {
252            let ty = wasm_fn_type.params()[idx];
253            let ty = type_to_llvm(&intrinsics, ty)?;
254            let value = func
255                .get_nth_param((idx as u32).checked_add(first_param).unwrap())
256                .unwrap();
257            let alloca = insert_alloca(ty, format!("param_{idx}"))?;
258            err!(cache_builder.build_store(alloca, value));
259            params.push((ty, alloca));
260        }
261
262        let mut locals = vec![];
263        let num_locals = reader.read_local_count()?;
264        for idx in 0..num_locals {
265            let (count, ty) = reader.read_local_decl()?;
266            let ty = err!(wptype_to_type(ty));
267            let ty = type_to_llvm(&intrinsics, ty)?;
268            for _ in 0..count {
269                let alloca = insert_alloca(ty, format!("local_{idx}"))?;
270                err!(cache_builder.build_store(alloca, ty.const_zero()));
271                locals.push((ty, alloca));
272            }
273        }
274
275        let mut params_locals = params.clone();
276        params_locals.extend(locals.iter().cloned());
277
278        let mut g0m0_params = None;
279
280        if g0m0_is_enabled {
281            let value = self.abi.get_g0_ptr_param(&func);
282            let g0 = insert_alloca(intrinsics.i32_ty.as_basic_type_enum(), "g0".to_string())?;
283            err!(cache_builder.build_store(g0, value));
284            g0.set_name("g0");
285            let m0 = self.abi.get_m0_ptr_param(&func);
286            m0.set_name("m0_base_ptr");
287
288            g0m0_params = Some((g0, m0));
289        }
290
291        let mut fcg = LLVMFunctionCodeGenerator {
292            g0m0: g0m0_params,
293            context: &self.ctx,
294            builder,
295            alloca_builder,
296            intrinsics: &intrinsics,
297            state,
298            function: func,
299            locals: params_locals,
300            ctx: CtxType::new(wasm_module, &func, &cache_builder, &*self.abi, config),
301            unreachable_depth: 0,
302            memory_styles,
303            _table_styles,
304            module: &module,
305            module_translation,
306            wasm_module,
307            symbol_registry,
308            abi: &*self.abi,
309            config,
310            tags_cache: HashMap::new(),
311            binary_fmt: self.binary_fmt,
312        };
313
314        fcg.ctx.add_func(
315            func_index,
316            func.as_global_value().as_pointer_value(),
317            func_type,
318            fcg.ctx.basic(),
319            &func_attrs,
320        );
321
322        while fcg.state.has_control_frames() {
323            let pos = reader.current_position() as u32;
324            let op = reader.read_operator()?;
325            fcg.translate_operator(op, pos)?;
326        }
327
328        fcg.finalize(wasm_fn_type)?;
329
330        if let Some(ref callbacks) = config.callbacks {
331            callbacks.preopt_ir(&function, &module);
332        }
333
334        let mut passes = vec![];
335
336        if config.enable_verifier {
337            passes.push("verify");
338        }
339
340        passes.push("sccp");
341        passes.push("early-cse");
342        //passes.push("deadargelim");
343        passes.push("adce");
344        passes.push("sroa");
345        passes.push("aggressive-instcombine");
346        passes.push("jump-threading");
347        //passes.push("ipsccp");
348        passes.push("simplifycfg");
349        passes.push("reassociate");
350        passes.push("loop-rotate");
351        passes.push("indvars");
352        //passes.push("lcssa");
353        //passes.push("licm");
354        //passes.push("instcombine");
355        passes.push("sccp");
356        passes.push("reassociate");
357        passes.push("simplifycfg");
358        passes.push("gvn");
359        passes.push("memcpyopt");
360        passes.push("dse");
361        passes.push("dce");
362        //passes.push("instcombine");
363        passes.push("reassociate");
364        passes.push("simplifycfg");
365        passes.push("mem2reg");
366
367        //let llvm_dump_path = std::env::var("WASMER_LLVM_DUMP_DIR");
368        //if let Ok(ref llvm_dump_path) = llvm_dump_path {
369        //    let path = std::path::Path::new(llvm_dump_path);
370        //    if !path.exists() {
371        //        std::fs::create_dir_all(path).unwrap()
372        //    }
373        //    let path = path.join(format!("{function_name}.ll"));
374        //    _ = module.print_to_file(path).unwrap();
375        //}
376
377        module
378            .run_passes(
379                passes.join(",").as_str(),
380                target_machine,
381                PassBuilderOptions::create(),
382            )
383            .unwrap();
384
385        //if let Ok(ref llvm_dump_path) = llvm_dump_path {
386        //    if !passes.is_empty() {
387        //        let path =
388        //            std::path::Path::new(llvm_dump_path).join(format!("{function_name}_opt.ll"));
389        //        _ = module.print_to_file(path).unwrap();
390        //    }
391        //}
392
393        if let Some(ref callbacks) = config.callbacks {
394            callbacks.postopt_ir(&function, &module);
395        }
396
397        Ok(module)
398    }
399
400    #[allow(clippy::too_many_arguments)]
401    pub fn translate(
402        &self,
403        wasm_module: &ModuleInfo,
404        module_translation: &ModuleTranslationState,
405        local_func_index: &LocalFunctionIndex,
406        function_body: &FunctionBodyData,
407        config: &LLVM,
408        memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
409        table_styles: &PrimaryMap<TableIndex, TableStyle>,
410        symbol_registry: &dyn SymbolRegistry,
411        target: &Triple,
412    ) -> Result<CompiledFunction, CompileError> {
413        let module = self.translate_to_module(
414            wasm_module,
415            module_translation,
416            local_func_index,
417            function_body,
418            config,
419            memory_styles,
420            table_styles,
421            symbol_registry,
422            target,
423        )?;
424        let function = CompiledKind::Local(
425            *local_func_index,
426            wasm_module.get_function_name(wasm_module.func_index(*local_func_index)),
427        );
428        let target_machine = &self.target_machine;
429        let memory_buffer = target_machine
430            .write_to_memory_buffer(&module, FileType::Object)
431            .unwrap();
432
433        if let Some(ref callbacks) = config.callbacks {
434            callbacks.obj_memory_buffer(&function, &memory_buffer);
435            let asm_buffer = target_machine
436                .write_to_memory_buffer(&module, FileType::Assembly)
437                .unwrap();
438            callbacks.asm_memory_buffer(&function, &asm_buffer)
439        }
440
441        let mem_buf_slice = memory_buffer.as_slice();
442
443        load_object_file(
444            mem_buf_slice,
445            &self.func_section,
446            RelocationTarget::LocalFunc(*local_func_index),
447            |name: &str| {
448                Ok({
449                    let name = if matches!(self.binary_fmt, BinaryFormat::Macho) {
450                        if name.starts_with("_") {
451                            name.replacen("_", "", 1)
452                        } else {
453                            name.to_string()
454                        }
455                    } else {
456                        name.to_string()
457                    };
458                    if let Some(Symbol::LocalFunction(local_func_index)) =
459                        symbol_registry.name_to_symbol(&name)
460                    {
461                        Some(RelocationTarget::LocalFunc(local_func_index))
462                    } else {
463                        None
464                    }
465                })
466            },
467            self.binary_fmt,
468        )
469    }
470}
471
472impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
473    // Create a vector where each lane contains the same value.
474    fn splat_vector(
475        &self,
476        value: BasicValueEnum<'ctx>,
477        vec_ty: VectorType<'ctx>,
478    ) -> Result<VectorValue<'ctx>, CompileError> {
479        // Use insert_element to insert the element into an undef vector, then use
480        // shuffle vector to copy that lane to all lanes.
481        err_nt!(
482            self.builder.build_shuffle_vector(
483                err!(self.builder.build_insert_element(
484                    vec_ty.get_undef(),
485                    value,
486                    self.intrinsics.i32_zero,
487                    "",
488                )),
489                vec_ty.get_undef(),
490                self.intrinsics
491                    .i32_ty
492                    .vec_type(vec_ty.get_size())
493                    .const_zero(),
494                "",
495            )
496        )
497    }
498
499    // Convert floating point vector to integer and saturate when out of range.
500    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
501    #[allow(clippy::too_many_arguments)]
502    fn trunc_sat<T: FloatMathType<'ctx>>(
503        &self,
504        fvec_ty: T,
505        ivec_ty: T::MathConvType,
506        lower_bound: u64, // Exclusive (least representable value)
507        upper_bound: u64, // Exclusive (greatest representable value)
508        int_min_value: u64,
509        int_max_value: u64,
510        value: IntValue<'ctx>,
511    ) -> Result<VectorValue<'ctx>, CompileError> {
512        // a) Compare vector with itself to identify NaN lanes.
513        // b) Compare vector with splat of inttofp(upper_bound) to identify
514        //    lanes that need to saturate to max.
515        // c) Compare vector with splat of inttofp(lower_bound) to identify
516        //    lanes that need to saturate to min.
517        // d) Use vector select (not shuffle) to pick from either the
518        //    splat vector or the input vector depending on whether the
519        //    comparison indicates that we have an unrepresentable value. Replace
520        //    unrepresentable values with zero.
521        // e) Now that the value is safe, fpto[su]i it.
522        // f) Use our previous comparison results to replace certain zeros with
523        //    int_min or int_max.
524
525        let fvec_ty = fvec_ty.as_basic_type_enum().into_vector_type();
526        let ivec_ty = ivec_ty.as_basic_type_enum().into_vector_type();
527        let fvec_element_ty = fvec_ty.get_element_type().into_float_type();
528        let ivec_element_ty = ivec_ty.get_element_type().into_int_type();
529
530        let is_signed = int_min_value != 0;
531        let int_min_value = self.splat_vector(
532            ivec_element_ty
533                .const_int(int_min_value, is_signed)
534                .as_basic_value_enum(),
535            ivec_ty,
536        )?;
537        let int_max_value = self.splat_vector(
538            ivec_element_ty
539                .const_int(int_max_value, is_signed)
540                .as_basic_value_enum(),
541            ivec_ty,
542        )?;
543        let lower_bound = if is_signed {
544            err!(self.builder.build_signed_int_to_float(
545                ivec_element_ty.const_int(lower_bound, is_signed),
546                fvec_element_ty,
547                "",
548            ))
549        } else {
550            err!(self.builder.build_unsigned_int_to_float(
551                ivec_element_ty.const_int(lower_bound, is_signed),
552                fvec_element_ty,
553                "",
554            ))
555        };
556        let upper_bound = if is_signed {
557            err!(self.builder.build_signed_int_to_float(
558                ivec_element_ty.const_int(upper_bound, is_signed),
559                fvec_element_ty,
560                "",
561            ))
562        } else {
563            err!(self.builder.build_unsigned_int_to_float(
564                ivec_element_ty.const_int(upper_bound, is_signed),
565                fvec_element_ty,
566                "",
567            ))
568        };
569
570        let value = err!(self.builder.build_bit_cast(value, fvec_ty, "")).into_vector_value();
571        let zero = fvec_ty.const_zero();
572        let lower_bound = self.splat_vector(lower_bound.as_basic_value_enum(), fvec_ty)?;
573        let upper_bound = self.splat_vector(upper_bound.as_basic_value_enum(), fvec_ty)?;
574        let nan_cmp =
575            err!(
576                self.builder
577                    .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
578            );
579        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
580            FloatPredicate::OGT,
581            value,
582            upper_bound,
583            "above_upper_bound",
584        ));
585        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
586            FloatPredicate::OLT,
587            value,
588            lower_bound,
589            "below_lower_bound",
590        ));
591        let not_representable = err!(self.builder.build_or(
592            err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
593            below_lower_bound_cmp,
594            "not_representable_as_int",
595        ));
596        let value =
597            err!(
598                self.builder
599                    .build_select(not_representable, zero, value, "safe_to_convert")
600            )
601            .into_vector_value();
602        let value = if is_signed {
603            self.builder
604                .build_float_to_signed_int(value, ivec_ty, "as_int")
605        } else {
606            self.builder
607                .build_float_to_unsigned_int(value, ivec_ty, "as_int")
608        };
609
610        let value = err!(value);
611        let value =
612            err!(
613                self.builder
614                    .build_select(above_upper_bound_cmp, int_max_value, value, "")
615            )
616            .into_vector_value();
617        err_nt!(
618            self.builder
619                .build_select(below_lower_bound_cmp, int_min_value, value, "")
620                .map(|v| v.into_vector_value())
621        )
622    }
623
624    // Convert floating point vector to integer and saturate when out of range.
625    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
626    #[allow(clippy::too_many_arguments)]
627    fn trunc_sat_into_int<T: FloatMathType<'ctx>>(
628        &self,
629        fvec_ty: T,
630        ivec_ty: T::MathConvType,
631        lower_bound: u64, // Exclusive (least representable value)
632        upper_bound: u64, // Exclusive (greatest representable value)
633        int_min_value: u64,
634        int_max_value: u64,
635        value: IntValue<'ctx>,
636    ) -> Result<IntValue<'ctx>, CompileError> {
637        let res = self.trunc_sat(
638            fvec_ty,
639            ivec_ty,
640            lower_bound,
641            upper_bound,
642            int_min_value,
643            int_max_value,
644            value,
645        )?;
646        err_nt!(
647            self.builder
648                .build_bit_cast(res, self.intrinsics.i128_ty, "")
649                .map(|v| v.into_int_value())
650        )
651    }
652
653    // Convert floating point vector to integer and saturate when out of range.
654    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
655    fn trunc_sat_scalar(
656        &self,
657        int_ty: IntType<'ctx>,
658        lower_bound: u64, // Exclusive (least representable value)
659        upper_bound: u64, // Exclusive (greatest representable value)
660        int_min_value: u64,
661        int_max_value: u64,
662        value: FloatValue<'ctx>,
663    ) -> Result<IntValue<'ctx>, CompileError> {
664        // TODO: this is a scalarized version of the process in trunc_sat. Either
665        // we should merge with trunc_sat, or we should simplify this function.
666
667        // a) Compare value with itself to identify NaN.
668        // b) Compare value inttofp(upper_bound) to identify values that need to
669        //    saturate to max.
670        // c) Compare value with inttofp(lower_bound) to identify values that need
671        //    to saturate to min.
672        // d) Use select to pick from either zero or the input vector depending on
673        //    whether the comparison indicates that we have an unrepresentable
674        //    value.
675        // e) Now that the value is safe, fpto[su]i it.
676        // f) Use our previous comparison results to replace certain zeros with
677        //    int_min or int_max.
678
679        let is_signed = int_min_value != 0;
680        let int_min_value = int_ty.const_int(int_min_value, is_signed);
681        let int_max_value = int_ty.const_int(int_max_value, is_signed);
682
683        let lower_bound = if is_signed {
684            err!(self.builder.build_signed_int_to_float(
685                int_ty.const_int(lower_bound, is_signed),
686                value.get_type(),
687                "",
688            ))
689        } else {
690            err!(self.builder.build_unsigned_int_to_float(
691                int_ty.const_int(lower_bound, is_signed),
692                value.get_type(),
693                "",
694            ))
695        };
696        let upper_bound = if is_signed {
697            err!(self.builder.build_signed_int_to_float(
698                int_ty.const_int(upper_bound, is_signed),
699                value.get_type(),
700                "",
701            ))
702        } else {
703            err!(self.builder.build_unsigned_int_to_float(
704                int_ty.const_int(upper_bound, is_signed),
705                value.get_type(),
706                "",
707            ))
708        };
709
710        let zero = value.get_type().const_zero();
711
712        let nan_cmp =
713            err!(
714                self.builder
715                    .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
716            );
717        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
718            FloatPredicate::OGT,
719            value,
720            upper_bound,
721            "above_upper_bound",
722        ));
723        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
724            FloatPredicate::OLT,
725            value,
726            lower_bound,
727            "below_lower_bound",
728        ));
729        let not_representable = err!(self.builder.build_or(
730            err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
731            below_lower_bound_cmp,
732            "not_representable_as_int",
733        ));
734        let value =
735            err!(
736                self.builder
737                    .build_select(not_representable, zero, value, "safe_to_convert")
738            )
739            .into_float_value();
740        let value = if is_signed {
741            err!(
742                self.builder
743                    .build_float_to_signed_int(value, int_ty, "as_int")
744            )
745        } else {
746            err!(
747                self.builder
748                    .build_float_to_unsigned_int(value, int_ty, "as_int")
749            )
750        };
751        let value =
752            err!(
753                self.builder
754                    .build_select(above_upper_bound_cmp, int_max_value, value, "")
755            )
756            .into_int_value();
757        let value =
758            err!(
759                self.builder
760                    .build_select(below_lower_bound_cmp, int_min_value, value, "")
761            )
762            .into_int_value();
763
764        err_nt!(
765            self.builder
766                .build_bit_cast(value, int_ty, "")
767                .map(|v| v.into_int_value())
768        )
769    }
770
771    fn trap_if_not_representable_as_int(
772        &self,
773        lower_bound: u64, // Inclusive (not a trapping value)
774        upper_bound: u64, // Inclusive (not a trapping value)
775        value: FloatValue,
776    ) -> Result<(), CompileError> {
777        let float_ty = value.get_type();
778        let int_ty = if float_ty == self.intrinsics.f32_ty {
779            self.intrinsics.i32_ty
780        } else {
781            self.intrinsics.i64_ty
782        };
783
784        let lower_bound = err!(self.builder.build_bit_cast(
785            int_ty.const_int(lower_bound, false),
786            float_ty,
787            ""
788        ))
789        .into_float_value();
790        let upper_bound = err!(self.builder.build_bit_cast(
791            int_ty.const_int(upper_bound, false),
792            float_ty,
793            ""
794        ))
795        .into_float_value();
796
797        // The 'U' in the float predicate is short for "unordered" which means that
798        // the comparison will compare true if either operand is a NaN. Thus, NaNs
799        // are out of bounds.
800        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
801            FloatPredicate::UGT,
802            value,
803            upper_bound,
804            "above_upper_bound",
805        ));
806        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
807            FloatPredicate::ULT,
808            value,
809            lower_bound,
810            "below_lower_bound",
811        ));
812        let out_of_bounds = err!(self.builder.build_or(
813            above_upper_bound_cmp,
814            below_lower_bound_cmp,
815            "out_of_bounds",
816        ));
817
818        let failure_block = self
819            .context
820            .append_basic_block(self.function, "conversion_failure_block");
821        let continue_block = self
822            .context
823            .append_basic_block(self.function, "conversion_success_block");
824
825        err!(
826            self.builder
827                .build_conditional_branch(out_of_bounds, failure_block, continue_block)
828        );
829        self.builder.position_at_end(failure_block);
830        let is_nan =
831            err!(
832                self.builder
833                    .build_float_compare(FloatPredicate::UNO, value, value, "is_nan")
834            );
835        let trap_code = err!(self.builder.build_select(
836            is_nan,
837            self.intrinsics.trap_bad_conversion_to_integer,
838            self.intrinsics.trap_illegal_arithmetic,
839            "",
840        ));
841        err!(
842            self.builder
843                .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
844        );
845        err!(self.builder.build_unreachable());
846        self.builder.position_at_end(continue_block);
847
848        Ok(())
849    }
850
851    fn trap_if_zero_or_overflow(
852        &self,
853        left: IntValue,
854        right: IntValue,
855    ) -> Result<(), CompileError> {
856        let int_type = left.get_type();
857
858        let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
859            let min_value = int_type.const_int(i32::MIN as u64, false);
860            let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
861            (min_value, neg_one_value)
862        } else if int_type == self.intrinsics.i64_ty {
863            let min_value = int_type.const_int(i64::MIN as u64, false);
864            let neg_one_value = int_type.const_int(-1i64 as u64, false);
865            (min_value, neg_one_value)
866        } else {
867            unreachable!()
868        };
869
870        let divisor_is_zero = err!(self.builder.build_int_compare(
871            IntPredicate::EQ,
872            right,
873            int_type.const_zero(),
874            "divisor_is_zero",
875        ));
876        let should_trap = err!(self.builder.build_or(
877            divisor_is_zero,
878            err!(self.builder.build_and(
879                err!(self.builder.build_int_compare(
880                    IntPredicate::EQ,
881                    left,
882                    min_value,
883                    "left_is_min"
884                )),
885                err!(self.builder.build_int_compare(
886                    IntPredicate::EQ,
887                    right,
888                    neg_one_value,
889                    "right_is_neg_one",
890                )),
891                "div_will_overflow",
892            )),
893            "div_should_trap",
894        ));
895
896        let should_trap = err!(self.builder.build_call(
897            self.intrinsics.expect_i1,
898            &[
899                should_trap.into(),
900                self.intrinsics.i1_ty.const_zero().into(),
901            ],
902            "should_trap_expect",
903        ))
904        .try_as_basic_value()
905        .unwrap_basic()
906        .into_int_value();
907
908        let shouldnt_trap_block = self
909            .context
910            .append_basic_block(self.function, "shouldnt_trap_block");
911        let should_trap_block = self
912            .context
913            .append_basic_block(self.function, "should_trap_block");
914        err!(self.builder.build_conditional_branch(
915            should_trap,
916            should_trap_block,
917            shouldnt_trap_block
918        ));
919        self.builder.position_at_end(should_trap_block);
920        let trap_code = err!(self.builder.build_select(
921            divisor_is_zero,
922            self.intrinsics.trap_integer_division_by_zero,
923            self.intrinsics.trap_illegal_arithmetic,
924            "",
925        ));
926        err!(
927            self.builder
928                .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
929        );
930        err!(self.builder.build_unreachable());
931        self.builder.position_at_end(shouldnt_trap_block);
932
933        Ok(())
934    }
935
936    fn trap_if_zero(&self, value: IntValue) -> Result<(), CompileError> {
937        let int_type = value.get_type();
938        let should_trap = err!(self.builder.build_int_compare(
939            IntPredicate::EQ,
940            value,
941            int_type.const_zero(),
942            "divisor_is_zero",
943        ));
944
945        let should_trap = err!(self.builder.build_call(
946            self.intrinsics.expect_i1,
947            &[
948                should_trap.into(),
949                self.intrinsics.i1_ty.const_zero().into(),
950            ],
951            "should_trap_expect",
952        ))
953        .try_as_basic_value()
954        .unwrap_basic()
955        .into_int_value();
956
957        let shouldnt_trap_block = self
958            .context
959            .append_basic_block(self.function, "shouldnt_trap_block");
960        let should_trap_block = self
961            .context
962            .append_basic_block(self.function, "should_trap_block");
963        err!(self.builder.build_conditional_branch(
964            should_trap,
965            should_trap_block,
966            shouldnt_trap_block
967        ));
968        self.builder.position_at_end(should_trap_block);
969        err!(self.builder.build_call(
970            self.intrinsics.throw_trap,
971            &[self.intrinsics.trap_integer_division_by_zero.into()],
972            "throw",
973        ));
974        err!(self.builder.build_unreachable());
975        self.builder.position_at_end(shouldnt_trap_block);
976
977        Ok(())
978    }
979
980    fn v128_into_int_vec(
981        &self,
982        value: BasicValueEnum<'ctx>,
983        info: ExtraInfo,
984        int_vec_ty: VectorType<'ctx>,
985    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
986        let (value, info) = if self.config.enable_nan_canonicalization {
987            if info.has_pending_f32_nan() {
988                let value = err!(
989                    self.builder
990                        .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
991                );
992                (self.canonicalize_nans(value)?, info.strip_pending())
993            } else if info.has_pending_f64_nan() {
994                let value = err!(
995                    self.builder
996                        .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
997                );
998                (self.canonicalize_nans(value)?, info.strip_pending())
999            } else {
1000                (value, info)
1001            }
1002        } else {
1003            (value, info)
1004        };
1005        Ok((
1006            err!(self.builder.build_bit_cast(value, int_vec_ty, "")).into_vector_value(),
1007            info,
1008        ))
1009    }
1010
1011    fn v128_into_i8x16(
1012        &self,
1013        value: BasicValueEnum<'ctx>,
1014        info: ExtraInfo,
1015    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1016        self.v128_into_int_vec(value, info, self.intrinsics.i8x16_ty)
1017    }
1018
1019    fn v128_into_i16x8(
1020        &self,
1021        value: BasicValueEnum<'ctx>,
1022        info: ExtraInfo,
1023    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1024        self.v128_into_int_vec(value, info, self.intrinsics.i16x8_ty)
1025    }
1026
1027    fn v128_into_i32x4(
1028        &self,
1029        value: BasicValueEnum<'ctx>,
1030        info: ExtraInfo,
1031    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1032        self.v128_into_int_vec(value, info, self.intrinsics.i32x4_ty)
1033    }
1034
1035    fn v128_into_i64x2(
1036        &self,
1037        value: BasicValueEnum<'ctx>,
1038        info: ExtraInfo,
1039    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1040        self.v128_into_int_vec(value, info, self.intrinsics.i64x2_ty)
1041    }
1042
1043    // If the value is pending a 64-bit canonicalization, do it now.
1044    // Return a f32x4 vector.
1045    fn v128_into_f32x4(
1046        &self,
1047        value: BasicValueEnum<'ctx>,
1048        info: ExtraInfo,
1049    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1050        let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f64_nan()
1051        {
1052            let value = err!(
1053                self.builder
1054                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1055            );
1056            (self.canonicalize_nans(value)?, info.strip_pending())
1057        } else {
1058            (value, info)
1059        };
1060        Ok((
1061            err!(
1062                self.builder
1063                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1064            )
1065            .into_vector_value(),
1066            info,
1067        ))
1068    }
1069
1070    // If the value is pending a 32-bit canonicalization, do it now.
1071    // Return a f64x2 vector.
1072    fn v128_into_f64x2(
1073        &self,
1074        value: BasicValueEnum<'ctx>,
1075        info: ExtraInfo,
1076    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1077        let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f32_nan()
1078        {
1079            let value = err!(
1080                self.builder
1081                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1082            );
1083            (self.canonicalize_nans(value)?, info.strip_pending())
1084        } else {
1085            (value, info)
1086        };
1087        Ok((
1088            err!(
1089                self.builder
1090                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1091            )
1092            .into_vector_value(),
1093            info,
1094        ))
1095    }
1096
1097    fn apply_pending_canonicalization(
1098        &self,
1099        value: BasicValueEnum<'ctx>,
1100        info: ExtraInfo,
1101    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1102        if !self.config.enable_nan_canonicalization {
1103            return Ok(value);
1104        }
1105
1106        if info.has_pending_f32_nan() {
1107            if value.get_type().is_vector_type()
1108                || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1109            {
1110                let ty = value.get_type();
1111                let value = err!(
1112                    self.builder
1113                        .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1114                );
1115                let value = self.canonicalize_nans(value)?;
1116                err_nt!(self.builder.build_bit_cast(value, ty, ""))
1117            } else {
1118                self.canonicalize_nans(value)
1119            }
1120        } else if info.has_pending_f64_nan() {
1121            if value.get_type().is_vector_type()
1122                || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1123            {
1124                let ty = value.get_type();
1125                let value = err!(
1126                    self.builder
1127                        .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1128                );
1129                let value = self.canonicalize_nans(value)?;
1130                err_nt!(self.builder.build_bit_cast(value, ty, ""))
1131            } else {
1132                self.canonicalize_nans(value)
1133            }
1134        } else {
1135            Ok(value)
1136        }
1137    }
1138
1139    // Replaces any NaN with the canonical QNaN, otherwise leaves the value alone.
1140    fn canonicalize_nans(
1141        &self,
1142        value: BasicValueEnum<'ctx>,
1143    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1144        if !self.config.enable_nan_canonicalization {
1145            return Ok(value);
1146        }
1147
1148        let f_ty = value.get_type();
1149        if f_ty.is_vector_type() {
1150            let value = value.into_vector_value();
1151            let f_ty = f_ty.into_vector_type();
1152            let zero = f_ty.const_zero();
1153            let nan_cmp =
1154                err!(
1155                    self.builder
1156                        .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1157                );
1158            let canonical_qnan = f_ty
1159                .get_element_type()
1160                .into_float_type()
1161                .const_float(f64::NAN);
1162            let canonical_qnan = self.splat_vector(canonical_qnan.as_basic_value_enum(), f_ty)?;
1163            err_nt!(
1164                self.builder
1165                    .build_select(nan_cmp, canonical_qnan, value, "")
1166                    .map(|v| v.as_basic_value_enum())
1167            )
1168        } else {
1169            let value = value.into_float_value();
1170            let f_ty = f_ty.into_float_type();
1171            let zero = f_ty.const_zero();
1172            let nan_cmp =
1173                err!(
1174                    self.builder
1175                        .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1176                );
1177            let canonical_qnan = f_ty.const_float(f64::NAN);
1178            err_nt!(
1179                self.builder
1180                    .build_select(nan_cmp, canonical_qnan, value, "")
1181                    .map(|v| v.as_basic_value_enum())
1182            )
1183        }
1184    }
1185
1186    // If this memory access must trap when out of bounds (i.e. it is a memory
1187    // access written in the user program as opposed to one used by our VM)
1188    // then mark that it can't be delete.
1189    fn mark_memaccess_nodelete(
1190        &mut self,
1191        memory_index: MemoryIndex,
1192        memaccess: InstructionValue<'ctx>,
1193    ) -> Result<(), CompileError> {
1194        if let MemoryCache::Static { base_ptr: _ } = self.ctx.memory(
1195            memory_index,
1196            self.intrinsics,
1197            self.module,
1198            self.memory_styles,
1199        )? {
1200            // The best we've got is `volatile`.
1201            // TODO: convert unwrap fail to CompileError
1202            memaccess.set_volatile(true).unwrap();
1203        }
1204        Ok(())
1205    }
1206
1207    fn annotate_user_memaccess(
1208        &mut self,
1209        memory_index: MemoryIndex,
1210        _memarg: &MemArg,
1211        alignment: u32,
1212        memaccess: InstructionValue<'ctx>,
1213    ) -> Result<(), CompileError> {
1214        match memaccess.get_opcode() {
1215            InstructionOpcode::Load | InstructionOpcode::Store => {
1216                memaccess.set_alignment(alignment).unwrap();
1217            }
1218            _ => {}
1219        };
1220        self.mark_memaccess_nodelete(memory_index, memaccess)?;
1221        tbaa_label(
1222            self.module,
1223            self.intrinsics,
1224            format!("memory {}", memory_index.as_u32()),
1225            memaccess,
1226        );
1227        Ok(())
1228    }
1229
1230    fn resolve_memory_ptr(
1231        &mut self,
1232        memory_index: MemoryIndex,
1233        memarg: &MemArg,
1234        ptr_ty: PointerType<'ctx>,
1235        var_offset: IntValue<'ctx>,
1236        value_size: usize,
1237    ) -> Result<PointerValue<'ctx>, CompileError> {
1238        let builder = &self.builder;
1239        let intrinsics = &self.intrinsics;
1240        let context = &self.context;
1241        let function = &self.function;
1242
1243        // Compute the offset into the storage.
1244        let imm_offset = intrinsics.i64_ty.const_int(memarg.offset, false);
1245        let var_offset = err!(builder.build_int_z_extend(var_offset, intrinsics.i64_ty, ""));
1246        let offset = err!(builder.build_int_add(var_offset, imm_offset, ""));
1247
1248        // Look up the memory base (as pointer) and bounds (as unsigned integer).
1249        let base_ptr = if let Some((_, ref m0)) = self.g0m0 {
1250            *m0
1251        } else {
1252            match self
1253                .ctx
1254                .memory(memory_index, intrinsics, self.module, self.memory_styles)?
1255            {
1256                MemoryCache::Dynamic {
1257                    ptr_to_base_ptr,
1258                    ptr_to_current_length,
1259                } => {
1260                    // Bounds check it.
1261                    let minimum = self.wasm_module.memories[memory_index].minimum;
1262                    let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
1263                    let ptr_in_bounds = if offset.is_const() {
1264                        // When the offset is constant, if it's below the minimum
1265                        // memory size, we've statically shown that it's safe.
1266                        let load_offset_end =
1267                            offset.const_add(value_size_v).get_zero_extended_constant();
1268                        if load_offset_end.is_some_and(|load_offset_end| {
1269                            load_offset_end <= minimum.bytes().0 as u64
1270                        }) {
1271                            Some(intrinsics.i64_ty.const_int(1, false))
1272                        } else {
1273                            None
1274                        }
1275                    } else {
1276                        None
1277                    };
1278
1279                    let ptr_in_bounds = match ptr_in_bounds {
1280                        Some(ptr) => ptr,
1281                        None => {
1282                            let load_offset_end = err!(builder.build_int_add(
1283                                offset,
1284                                value_size_v,
1285                                "load_offset_end"
1286                            ));
1287
1288                            let current_length = err!(builder.build_load(
1289                                self.intrinsics.i32_ty,
1290                                ptr_to_current_length,
1291                                "current_length"
1292                            ))
1293                            .into_int_value();
1294                            tbaa_label(
1295                                self.module,
1296                                self.intrinsics,
1297                                format!("memory {} length", memory_index.as_u32()),
1298                                current_length.as_instruction_value().unwrap(),
1299                            );
1300                            let current_length = err!(builder.build_int_z_extend(
1301                                current_length,
1302                                intrinsics.i64_ty,
1303                                "current_length_zextd"
1304                            ));
1305
1306                            err!(builder.build_int_compare(
1307                                IntPredicate::ULE,
1308                                load_offset_end,
1309                                current_length,
1310                                "ptr_in_bounds",
1311                            ))
1312                        }
1313                    };
1314
1315                    if !ptr_in_bounds.is_constant_int()
1316                        || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
1317                    {
1318                        // LLVM may have folded this into 'i1 true' in which case we know
1319                        // the pointer is in bounds. LLVM may also have folded it into a
1320                        // constant expression, not known to be either true or false yet.
1321                        // If it's false, unknown-but-constant, or not-a-constant, emit a
1322                        // runtime bounds check. LLVM may yet succeed at optimizing it away.
1323                        let ptr_in_bounds = err!(builder.build_call(
1324                            intrinsics.expect_i1,
1325                            &[
1326                                ptr_in_bounds.into(),
1327                                intrinsics.i1_ty.const_int(1, true).into(),
1328                            ],
1329                            "ptr_in_bounds_expect",
1330                        ))
1331                        .try_as_basic_value()
1332                        .unwrap_basic()
1333                        .into_int_value();
1334
1335                        let in_bounds_continue_block =
1336                            context.append_basic_block(*function, "in_bounds_continue_block");
1337                        let not_in_bounds_block =
1338                            context.append_basic_block(*function, "not_in_bounds_block");
1339                        err!(builder.build_conditional_branch(
1340                            ptr_in_bounds,
1341                            in_bounds_continue_block,
1342                            not_in_bounds_block,
1343                        ));
1344                        builder.position_at_end(not_in_bounds_block);
1345                        err!(builder.build_call(
1346                            intrinsics.throw_trap,
1347                            &[intrinsics.trap_memory_oob.into()],
1348                            "throw",
1349                        ));
1350                        err!(builder.build_unreachable());
1351                        builder.position_at_end(in_bounds_continue_block);
1352                    }
1353                    let ptr_to_base =
1354                        err!(builder.build_load(intrinsics.ptr_ty, ptr_to_base_ptr, "ptr_to_base"))
1355                            .into_pointer_value();
1356                    tbaa_label(
1357                        self.module,
1358                        self.intrinsics,
1359                        format!("memory base_ptr {}", memory_index.as_u32()),
1360                        ptr_to_base.as_instruction_value().unwrap(),
1361                    );
1362                    ptr_to_base
1363                }
1364                MemoryCache::Static { base_ptr } => base_ptr,
1365            }
1366        };
1367        let value_ptr = unsafe {
1368            err!(builder.build_gep(self.intrinsics.i8_ty, base_ptr, &[offset], "mem_value_ptr"))
1369        };
1370        err_nt!(
1371            builder
1372                .build_bit_cast(value_ptr, ptr_ty, "mem_value")
1373                .map(|v| v.into_pointer_value())
1374        )
1375    }
1376
1377    fn trap_if_misaligned(
1378        &self,
1379        _memarg: &MemArg,
1380        ptr: PointerValue<'ctx>,
1381        align: u8,
1382    ) -> Result<(), CompileError> {
1383        if align <= 1 {
1384            return Ok(());
1385        }
1386        let value = err!(self.builder.build_ptr_to_int(
1387            ptr,
1388            self.intrinsics.i64_ty,
1389            "mischeck_value"
1390        ));
1391        let and = err!(self.builder.build_and(
1392            value,
1393            self.intrinsics.i64_ty.const_int((align - 1).into(), false),
1394            "misaligncheck",
1395        ));
1396        let aligned = err!(self.builder.build_int_compare(
1397            IntPredicate::EQ,
1398            and,
1399            self.intrinsics.i64_zero,
1400            "is_aligned"
1401        ));
1402        let aligned = err!(self.builder.build_call(
1403            self.intrinsics.expect_i1,
1404            &[
1405                aligned.into(),
1406                self.intrinsics.i1_ty.const_int(1, false).into(),
1407            ],
1408            "is_aligned_expect",
1409        ))
1410        .try_as_basic_value()
1411        .unwrap_basic()
1412        .into_int_value();
1413
1414        let continue_block = self
1415            .context
1416            .append_basic_block(self.function, "aligned_access_continue_block");
1417        let not_aligned_block = self
1418            .context
1419            .append_basic_block(self.function, "misaligned_trap_block");
1420        err!(
1421            self.builder
1422                .build_conditional_branch(aligned, continue_block, not_aligned_block)
1423        );
1424
1425        self.builder.position_at_end(not_aligned_block);
1426        err!(self.builder.build_call(
1427            self.intrinsics.throw_trap,
1428            &[self.intrinsics.trap_unaligned_atomic.into()],
1429            "throw",
1430        ));
1431        err!(self.builder.build_unreachable());
1432
1433        self.builder.position_at_end(continue_block);
1434        Ok(())
1435    }
1436
1437    fn finalize(&mut self, wasm_fn_type: &FunctionType) -> Result<(), CompileError> {
1438        let func_type = self.function.get_type();
1439
1440        let results = self.state.popn_save_extra(wasm_fn_type.results().len())?;
1441        let results = err!(
1442            results
1443                .into_iter()
1444                .map(|(v, i)| self.apply_pending_canonicalization(v, i))
1445                .collect::<Result<Vec<_>, _>>()
1446        );
1447
1448        if wasm_fn_type.results().is_empty() {
1449            err!(self.builder.build_return(None));
1450        } else if self.abi.is_sret(wasm_fn_type)? {
1451            let sret = self
1452                .function
1453                .get_first_param()
1454                .unwrap()
1455                .into_pointer_value();
1456            let llvm_params: Vec<_> = wasm_fn_type
1457                .results()
1458                .iter()
1459                .map(|x| type_to_llvm(self.intrinsics, *x).unwrap())
1460                .collect();
1461            let mut struct_value = self
1462                .context
1463                .struct_type(llvm_params.as_slice(), false)
1464                .get_undef();
1465            for (idx, value) in results.into_iter().enumerate() {
1466                let value = err!(self.builder.build_bit_cast(
1467                    value,
1468                    type_to_llvm(self.intrinsics, wasm_fn_type.results()[idx])?,
1469                    "",
1470                ));
1471                struct_value =
1472                    err!(
1473                        self.builder
1474                            .build_insert_value(struct_value, value, idx as u32, "")
1475                    )
1476                    .into_struct_value();
1477            }
1478            err!(self.builder.build_store(sret, struct_value));
1479            err!(self.builder.build_return(None));
1480        } else {
1481            err!(
1482                self.builder
1483                    .build_return(Some(&self.abi.pack_values_for_register_return(
1484                        self.intrinsics,
1485                        &self.builder,
1486                        &results,
1487                        &func_type,
1488                    )?))
1489            );
1490        }
1491        Ok(())
1492    }
1493
1494    // Generates a global constant with the tag's module-local index, which can be used
1495    // as the "type info" of a catch clause.
1496    fn get_or_insert_tag_type_info_global(&mut self, tag: i32) -> BasicValueEnum<'ctx> {
1497        if let Some(tag) = self.tags_cache.get(&tag) {
1498            return *tag;
1499        }
1500
1501        let tag_ty = self
1502            .context
1503            .struct_type(&[self.intrinsics.i32_ty.into()], false);
1504        let tag_glbl = self.module.add_global(
1505            tag_ty,
1506            Some(AddressSpace::default()),
1507            &format!("__wasmer_eh_type_info_{tag}"),
1508        );
1509        tag_glbl.set_initializer(
1510            &tag_ty
1511                .const_named_struct(&[self.intrinsics.i32_ty.const_int(tag as _, false).into()])
1512                .as_basic_value_enum(),
1513        );
1514
1515        tag_glbl.set_linkage(Linkage::External);
1516        tag_glbl.set_constant(true);
1517        // Why set this to a specific section? On macOS it would land on a specifc read only data
1518        // section. GOT-based relocations will probably be generated with a non-zero addend, making
1519        // some EH-related intricacies not working.
1520        //
1521        // The general idea is that each tag has its own section, so the GOT-based relocation can
1522        // have a zero addend, i.e. the data of the tag is the first (and only) value in a specific
1523        // section we can target in relocations.
1524        if matches!(self.binary_fmt, target_lexicon::BinaryFormat::Macho) {
1525            tag_glbl.set_section(Some(&format!("{FUNCTION_SECTION_MACHO},_eh_ti_{tag}")));
1526        }
1527
1528        let tag_glbl = tag_glbl.as_basic_value_enum();
1529
1530        self.tags_cache.insert(tag, tag_glbl);
1531        tag_glbl
1532    }
1533
1534    fn build_g0m0_indirect_call(
1535        &mut self,
1536        table_index: u32,
1537        ctx_ptr: PointerValue<'ctx>,
1538        func_type: &FunctionType,
1539        func_ptr: PointerValue<'ctx>,
1540        func_index: IntValue<'ctx>,
1541    ) -> Result<(), CompileError> {
1542        let Some((g0, m0)) = self.g0m0 else {
1543            return Err(CompileError::Codegen(
1544                "Call to build_g0m0_indirect_call without g0m0 parameters!".to_string(),
1545            ));
1546        };
1547
1548        let mut local_func_indices = vec![];
1549        let mut foreign_func_indices = vec![];
1550
1551        for t in &self.wasm_module.table_initializers {
1552            if t.table_index.as_u32() == table_index {
1553                for (func_in_table_idx, func_idx) in t.elements.iter().enumerate() {
1554                    if self.wasm_module.local_func_index(*func_idx).is_some() {
1555                        local_func_indices.push(func_in_table_idx)
1556                    } else {
1557                        foreign_func_indices.push(func_in_table_idx)
1558                    }
1559                }
1560                break;
1561            }
1562        }
1563
1564        // removed with mem2reg.
1565        //
1566        let g0_value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, "g0"));
1567
1568        let needs_switch = self.g0m0.is_some()
1569            && !local_func_indices.is_empty()
1570            && !foreign_func_indices.is_empty();
1571
1572        if needs_switch {
1573            let foreign_idx_block = self
1574                .context
1575                .append_basic_block(self.function, "foreign_call_block");
1576            let local_idx_block = self
1577                .context
1578                .append_basic_block(self.function, "local_call_block");
1579            let unreachable_indirect_call_branch_block = self
1580                .context
1581                .append_basic_block(self.function, "unreachable_indirect_call_branch");
1582
1583            let cont = self.context.append_basic_block(self.function, "cont");
1584
1585            err!(
1586                self.builder.build_switch(
1587                    func_index,
1588                    unreachable_indirect_call_branch_block,
1589                    &local_func_indices
1590                        .into_iter()
1591                        .map(|v| (
1592                            self.intrinsics.i32_ty.const_int(v as _, false),
1593                            local_idx_block
1594                        ))
1595                        .chain(foreign_func_indices.into_iter().map(|v| (
1596                            self.intrinsics.i32_ty.const_int(v as _, false),
1597                            foreign_idx_block
1598                        )))
1599                        .collect::<Vec<_>>()
1600                )
1601            );
1602
1603            self.builder
1604                .position_at_end(unreachable_indirect_call_branch_block);
1605            err!(self.builder.build_unreachable());
1606
1607            //let current_block = self.builder.get_insert_block().unwrap();
1608            self.builder.position_at_end(local_idx_block);
1609            let local_call_site = self.build_indirect_call(
1610                ctx_ptr,
1611                func_type,
1612                func_ptr,
1613                Some(G0M0FunctionKind::Local),
1614                Some((g0_value.into_int_value(), m0)),
1615            )?;
1616
1617            let local_rets = self.abi.rets_from_call(
1618                &self.builder,
1619                self.intrinsics,
1620                local_call_site,
1621                func_type,
1622            )?;
1623
1624            err!(self.builder.build_unconditional_branch(cont));
1625
1626            self.builder.position_at_end(foreign_idx_block);
1627            let foreign_call_site = self.build_indirect_call(
1628                ctx_ptr,
1629                func_type,
1630                func_ptr,
1631                Some(G0M0FunctionKind::Imported),
1632                None,
1633            )?;
1634
1635            let foreign_rets = self.abi.rets_from_call(
1636                &self.builder,
1637                self.intrinsics,
1638                foreign_call_site,
1639                func_type,
1640            )?;
1641
1642            err!(self.builder.build_unconditional_branch(cont));
1643
1644            self.builder.position_at_end(cont);
1645
1646            for i in 0..foreign_rets.len() {
1647                let f_i = foreign_rets[i];
1648                let l_i = local_rets[i];
1649                let ty = f_i.get_type();
1650                let v = err!(self.builder.build_phi(ty, ""));
1651                v.add_incoming(&[(&f_i, foreign_idx_block), (&l_i, local_idx_block)]);
1652                self.state.push1(v.as_basic_value());
1653            }
1654        } else if foreign_func_indices.is_empty() {
1655            let call_site = self.build_indirect_call(
1656                ctx_ptr,
1657                func_type,
1658                func_ptr,
1659                Some(G0M0FunctionKind::Local),
1660                Some((g0_value.into_int_value(), m0)),
1661            )?;
1662
1663            self.abi
1664                .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1665                .iter()
1666                .for_each(|ret| self.state.push1(*ret));
1667        } else {
1668            let call_site = self.build_indirect_call(
1669                ctx_ptr,
1670                func_type,
1671                func_ptr,
1672                Some(G0M0FunctionKind::Imported),
1673                Some((g0_value.into_int_value(), m0)),
1674            )?;
1675            self.abi
1676                .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1677                .iter()
1678                .for_each(|ret| self.state.push1(*ret));
1679        }
1680
1681        Ok(())
1682    }
1683
1684    fn build_indirect_call(
1685        &mut self,
1686        ctx_ptr: PointerValue<'ctx>,
1687        func_type: &FunctionType,
1688        func_ptr: PointerValue<'ctx>,
1689        func_kind: Option<G0M0FunctionKind>,
1690        g0m0_params: LocalFunctionG0M0params<'ctx>,
1691    ) -> Result<CallSiteValue<'ctx>, CompileError> {
1692        let (llvm_func_type, llvm_func_attrs) = self.abi.func_type_to_llvm(
1693            self.context,
1694            self.intrinsics,
1695            Some(self.ctx.get_offsets()),
1696            func_type,
1697            func_kind,
1698        )?;
1699
1700        let params = self.state.popn_save_extra(func_type.params().len())?;
1701
1702        // Apply pending canonicalizations.
1703        let params = params
1704            .iter()
1705            .zip(func_type.params().iter())
1706            .map(|((v, info), wasm_ty)| match wasm_ty {
1707                Type::F32 => err_nt!(self.builder.build_bit_cast(
1708                    self.apply_pending_canonicalization(*v, *info)?,
1709                    self.intrinsics.f32_ty,
1710                    "",
1711                )),
1712                Type::F64 => err_nt!(self.builder.build_bit_cast(
1713                    self.apply_pending_canonicalization(*v, *info)?,
1714                    self.intrinsics.f64_ty,
1715                    "",
1716                )),
1717                Type::V128 => self.apply_pending_canonicalization(*v, *info),
1718                _ => Ok(*v),
1719            })
1720            .collect::<Result<Vec<_>, _>>()?;
1721
1722        let params = self.abi.args_to_call(
1723            &self.alloca_builder,
1724            func_type,
1725            &llvm_func_type,
1726            ctx_ptr,
1727            params.as_slice(),
1728            self.intrinsics,
1729            g0m0_params,
1730        )?;
1731
1732        let typed_func_ptr = err!(self.builder.build_pointer_cast(
1733            func_ptr,
1734            self.context.ptr_type(AddressSpace::default()),
1735            "typed_func_ptr",
1736        ));
1737
1738        /*
1739        if self.track_state {
1740            if let Some(offset) = opcode_offset {
1741                let mut stackmaps = self.stackmaps.borrow_mut();
1742                emit_stack_map(
1743                    &info,
1744                    self.intrinsics,
1745                    self.builder,
1746                    self.index,
1747                    &mut *stackmaps,
1748                    StackmapEntryKind::Call,
1749                    &self.locals,
1750                    state,
1751                    ctx,
1752                    offset,
1753                )
1754            }
1755        }
1756        */
1757
1758        let call_site_local = if let Some(lpad) = self.state.get_innermost_landingpad() {
1759            let then_block = self.context.append_basic_block(self.function, "then_block");
1760
1761            let ret = err!(self.builder.build_indirect_invoke(
1762                llvm_func_type,
1763                typed_func_ptr,
1764                params.as_slice(),
1765                then_block,
1766                lpad,
1767                "",
1768            ));
1769
1770            self.builder.position_at_end(then_block);
1771            ret
1772        } else {
1773            err!(
1774                self.builder.build_indirect_call(
1775                    llvm_func_type,
1776                    typed_func_ptr,
1777                    params
1778                        .iter()
1779                        .copied()
1780                        .map(Into::into)
1781                        .collect::<Vec<BasicMetadataValueEnum>>()
1782                        .as_slice(),
1783                    "indirect_call",
1784                )
1785            )
1786        };
1787        for (attr, attr_loc) in llvm_func_attrs {
1788            call_site_local.add_attribute(attr_loc, attr);
1789        }
1790
1791        Ok(call_site_local)
1792    }
1793}
1794
1795/*
1796fn emit_stack_map<'ctx>(
1797    intrinsics: &Intrinsics<'ctx>,
1798    builder: &Builder<'ctx>,
1799    local_function_id: usize,
1800    target: &mut StackmapRegistry,
1801    kind: StackmapEntryKind,
1802    locals: &[PointerValue],
1803    state: &State<'ctx>,
1804    _ctx: &mut CtxType<'ctx>,
1805    opcode_offset: usize,
1806) {
1807    let stackmap_id = target.entries.len();
1808
1809    let mut params = Vec::with_capacity(2 + locals.len() + state.stack.len());
1810
1811    params.push(
1812        intrinsics
1813            .i64_ty
1814            .const_int(stackmap_id as u64, false)
1815            .as_basic_value_enum(),
1816    );
1817    params.push(intrinsics.i32_ty.const_zero().as_basic_value_enum());
1818
1819    let locals: Vec<_> = locals.iter().map(|x| x.as_basic_value_enum()).collect();
1820    let mut value_semantics: Vec<ValueSemantic> =
1821        Vec::with_capacity(locals.len() + state.stack.len());
1822
1823    params.extend_from_slice(&locals);
1824    value_semantics.extend((0..locals.len()).map(ValueSemantic::WasmLocal));
1825
1826    params.extend(state.stack.iter().map(|x| x.0));
1827    value_semantics.extend((0..state.stack.len()).map(ValueSemantic::WasmStack));
1828
1829    // FIXME: Information needed for Abstract -> Runtime state transform is not fully preserved
1830    // to accelerate compilation and reduce memory usage. Check this again when we try to support
1831    // "full" LLVM OSR.
1832
1833    assert_eq!(params.len(), value_semantics.len() + 2);
1834
1835    builder.build_call(intrinsics.experimental_stackmap, &params, "");
1836
1837    target.entries.push(StackmapEntry {
1838        kind,
1839        local_function_id,
1840        local_count: locals.len(),
1841        stack_count: state.stack.len(),
1842        opcode_offset,
1843        value_semantics,
1844        is_start: true,
1845    });
1846}
1847
1848fn finalize_opcode_stack_map<'ctx>(
1849    intrinsics: &Intrinsics<'ctx>,
1850    builder: &Builder<'ctx>,
1851    local_function_id: usize,
1852    target: &mut StackmapRegistry,
1853    kind: StackmapEntryKind,
1854    opcode_offset: usize,
1855) {
1856    let stackmap_id = target.entries.len();
1857    builder.build_call(
1858        intrinsics.experimental_stackmap,
1859        &[
1860            intrinsics
1861                .i64_ty
1862                .const_int(stackmap_id as u64, false)
1863                .as_basic_value_enum(),
1864            intrinsics.i32_ty.const_zero().as_basic_value_enum(),
1865        ],
1866        "opcode_stack_map_end",
1867    );
1868    target.entries.push(StackmapEntry {
1869        kind,
1870        local_function_id,
1871        local_count: 0,
1872        stack_count: 0,
1873        opcode_offset,
1874        value_semantics: vec![],
1875        is_start: false,
1876    });
1877}
1878 */
1879
1880pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
1881    g0m0: Option<(PointerValue<'ctx>, PointerValue<'ctx>)>,
1882    context: &'ctx Context,
1883    builder: Builder<'ctx>,
1884    alloca_builder: Builder<'ctx>,
1885    intrinsics: &'a Intrinsics<'ctx>,
1886    state: State<'ctx>,
1887    function: FunctionValue<'ctx>,
1888    locals: Vec<(BasicTypeEnum<'ctx>, PointerValue<'ctx>)>, // Contains params and locals
1889    ctx: CtxType<'ctx, 'a>,
1890    unreachable_depth: usize,
1891    memory_styles: &'a PrimaryMap<MemoryIndex, MemoryStyle>,
1892    _table_styles: &'a PrimaryMap<TableIndex, TableStyle>,
1893
1894    // This is support for stackmaps:
1895    /*
1896    stackmaps: Rc<RefCell<StackmapRegistry>>,
1897    index: usize,
1898    opcode_offset: usize,
1899    track_state: bool,
1900    */
1901    module: &'a Module<'ctx>,
1902    module_translation: &'a ModuleTranslationState,
1903    wasm_module: &'a ModuleInfo,
1904    symbol_registry: &'a dyn SymbolRegistry,
1905    abi: &'a dyn Abi,
1906    config: &'a LLVM,
1907    tags_cache: HashMap<i32, BasicValueEnum<'ctx>>,
1908    binary_fmt: target_lexicon::BinaryFormat,
1909}
1910
1911impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
1912    fn quiet_nan(&self, value: BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, CompileError> {
1913        let intrinsic = if value
1914            .get_type()
1915            .eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1916        {
1917            Some(self.intrinsics.add_f32)
1918        } else if value
1919            .get_type()
1920            .eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1921        {
1922            Some(self.intrinsics.add_f64)
1923        } else if value
1924            .get_type()
1925            .eq(&self.intrinsics.f32x4_ty.as_basic_type_enum())
1926        {
1927            Some(self.intrinsics.add_f32x4)
1928        } else if value
1929            .get_type()
1930            .eq(&self.intrinsics.f64x2_ty.as_basic_type_enum())
1931        {
1932            Some(self.intrinsics.add_f64x2)
1933        } else {
1934            None
1935        };
1936
1937        match intrinsic {
1938            Some(intrinsic) => err_nt!(
1939                self.builder
1940                    .build_call(
1941                        intrinsic,
1942                        &[
1943                            value.into(),
1944                            value.get_type().const_zero().into(),
1945                            self.intrinsics.fp_rounding_md,
1946                            self.intrinsics.fp_exception_md,
1947                        ],
1948                        "",
1949                    )
1950                    .map(|v| v.try_as_basic_value().unwrap_basic())
1951            ),
1952            None => Ok(value),
1953        }
1954    }
1955
1956    fn finalize_minmax_result(
1957        &self,
1958        value: BasicValueEnum<'ctx>,
1959    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1960        let ty = value.get_type();
1961        if ty.eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1962            || ty.eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1963        {
1964            let value = value.into_float_value();
1965            let is_nan = err!(self.builder.build_float_compare(
1966                FloatPredicate::UNO,
1967                value,
1968                value,
1969                "res_is_nan"
1970            ));
1971            let quiet = self.quiet_nan(value.as_basic_value_enum())?;
1972            let result =
1973                err!(
1974                    self.builder
1975                        .build_select(is_nan, quiet, value.as_basic_value_enum(), "")
1976                );
1977            Ok(result.as_basic_value_enum())
1978        } else if ty.eq(&self.intrinsics.f32x4_ty.as_basic_type_enum()) {
1979            let value = value.into_vector_value();
1980            let is_nan = err!(self.builder.build_call(
1981                self.intrinsics.cmp_f32x4,
1982                &[
1983                    value.into(),
1984                    value.into(),
1985                    self.intrinsics.fp_uno_md,
1986                    self.intrinsics.fp_exception_md,
1987                ],
1988                "",
1989            ))
1990            .try_as_basic_value()
1991            .unwrap_basic()
1992            .into_vector_value();
1993            let quiet = self
1994                .quiet_nan(value.as_basic_value_enum())?
1995                .into_vector_value();
1996            let result = err!(self.builder.build_select(
1997                is_nan,
1998                quiet.as_basic_value_enum(),
1999                value.as_basic_value_enum(),
2000                "",
2001            ));
2002            Ok(result.as_basic_value_enum())
2003        } else if ty.eq(&self.intrinsics.f64x2_ty.as_basic_type_enum()) {
2004            let value = value.into_vector_value();
2005            let is_nan = err!(self.builder.build_call(
2006                self.intrinsics.cmp_f64x2,
2007                &[
2008                    value.into(),
2009                    value.into(),
2010                    self.intrinsics.fp_uno_md,
2011                    self.intrinsics.fp_exception_md,
2012                ],
2013                "",
2014            ))
2015            .try_as_basic_value()
2016            .unwrap_basic()
2017            .into_vector_value();
2018            let quiet = self
2019                .quiet_nan(value.as_basic_value_enum())?
2020                .into_vector_value();
2021            let result = err!(self.builder.build_select(
2022                is_nan,
2023                quiet.as_basic_value_enum(),
2024                value.as_basic_value_enum(),
2025                "",
2026            ));
2027            Ok(result.as_basic_value_enum())
2028        } else {
2029            Ok(value)
2030        }
2031    }
2032
2033    fn translate_operator(&mut self, op: Operator, _source_loc: u32) -> Result<(), CompileError> {
2034        // TODO: remove this vmctx by moving everything into CtxType. Values
2035        // computed off vmctx usually benefit from caching.
2036        let vmctx = &self.ctx.basic().into_pointer_value();
2037
2038        //let opcode_offset: Option<usize> = None;
2039
2040        if !self.state.reachable {
2041            match op {
2042                Operator::Block { blockty: _ }
2043                | Operator::Loop { blockty: _ }
2044                | Operator::If { blockty: _ } => {
2045                    self.unreachable_depth += 1;
2046                    return Ok(());
2047                }
2048                Operator::Else => {
2049                    if self.unreachable_depth != 0 {
2050                        return Ok(());
2051                    }
2052                }
2053                Operator::End => {
2054                    if self.unreachable_depth != 0 {
2055                        self.unreachable_depth -= 1;
2056                        return Ok(());
2057                    }
2058                }
2059                _ => {
2060                    return Ok(());
2061                }
2062            }
2063        }
2064
2065        match op {
2066            /***************************
2067             * Control Flow instructions.
2068             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions
2069             ***************************/
2070            Operator::Block { blockty } => {
2071                let current_block = self
2072                    .builder
2073                    .get_insert_block()
2074                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2075
2076                let end_block = self.context.append_basic_block(self.function, "end");
2077                self.builder.position_at_end(end_block);
2078
2079                let phis: SmallVec<[PhiValue<'ctx>; 1]> = self
2080                    .module_translation
2081                    .blocktype_params_results(&blockty)?
2082                    .1
2083                    .iter()
2084                    .map(|&wp_ty| {
2085                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2086                            type_to_llvm(self.intrinsics, wasm_ty)
2087                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2088                        })
2089                    })
2090                    .collect::<Result<_, _>>()?;
2091
2092                self.state.push_block(
2093                    end_block,
2094                    phis,
2095                    self.module_translation
2096                        .blocktype_params_results(&blockty)?
2097                        .0
2098                        .len(),
2099                );
2100                self.builder.position_at_end(current_block);
2101            }
2102            Operator::Loop { blockty } => {
2103                let loop_body = self.context.append_basic_block(self.function, "loop_body");
2104                let loop_next = self.context.append_basic_block(self.function, "loop_outer");
2105                let pre_loop_block = self.builder.get_insert_block().unwrap();
2106
2107                err!(self.builder.build_unconditional_branch(loop_body));
2108
2109                self.builder.position_at_end(loop_next);
2110                let blocktypes = self.module_translation.blocktype_params_results(&blockty)?;
2111                let phis = blocktypes
2112                    .1
2113                    .iter()
2114                    .map(|&wp_ty| {
2115                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2116                            type_to_llvm(self.intrinsics, wasm_ty)
2117                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2118                        })
2119                    })
2120                    .collect::<Result<_, _>>()?;
2121                self.builder.position_at_end(loop_body);
2122                let loop_phis: SmallVec<[PhiValue<'ctx>; 1]> = blocktypes
2123                    .0
2124                    .iter()
2125                    .map(|&wp_ty| {
2126                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2127                            type_to_llvm(self.intrinsics, wasm_ty)
2128                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2129                        })
2130                    })
2131                    .collect::<Result<_, _>>()?;
2132                for phi in loop_phis.iter().rev() {
2133                    let (value, info) = self.state.pop1_extra()?;
2134                    let value = self.apply_pending_canonicalization(value, info)?;
2135                    phi.add_incoming(&[(&value, pre_loop_block)]);
2136                }
2137                for phi in &loop_phis {
2138                    self.state.push1(phi.as_basic_value());
2139                }
2140
2141                let num_inputs = loop_phis.len();
2142                self.state
2143                    .push_loop(loop_body, loop_next, loop_phis, phis, num_inputs);
2144            }
2145            Operator::Br { relative_depth } => {
2146                let frame = self.state.frame_at_depth(relative_depth)?;
2147
2148                let current_block = self
2149                    .builder
2150                    .get_insert_block()
2151                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2152
2153                let phis = if frame.is_loop() {
2154                    frame.loop_body_phis()
2155                } else {
2156                    frame.phis()
2157                };
2158
2159                let len = phis.len();
2160                let values = self.state.peekn_extra(len)?;
2161                let values = values
2162                    .iter()
2163                    .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2164                    .collect::<Result<Vec<_>, _>>()?;
2165
2166                // For each result of the block we're branching to,
2167                // pop a value off the value stack and load it into
2168                // the corresponding phi.
2169                for (phi, value) in phis.iter().zip(values.into_iter()) {
2170                    phi.add_incoming(&[(&value, current_block)]);
2171                }
2172
2173                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2174
2175                self.state.popn(len)?;
2176                self.state.reachable = false;
2177            }
2178            Operator::BrIf { relative_depth } => {
2179                let cond = self.state.pop1()?;
2180                let frame = self.state.frame_at_depth(relative_depth)?;
2181
2182                let current_block = self
2183                    .builder
2184                    .get_insert_block()
2185                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2186
2187                let phis = if frame.is_loop() {
2188                    frame.loop_body_phis()
2189                } else {
2190                    frame.phis()
2191                };
2192
2193                let param_stack = self.state.peekn_extra(phis.len())?;
2194                let param_stack = param_stack
2195                    .iter()
2196                    .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2197                    .collect::<Result<Vec<_>, _>>()?;
2198
2199                for (phi, value) in phis.iter().zip(param_stack) {
2200                    phi.add_incoming(&[(&value, current_block)]);
2201                }
2202
2203                let else_block = self.context.append_basic_block(self.function, "else");
2204
2205                let cond_value = err!(self.builder.build_int_compare(
2206                    IntPredicate::NE,
2207                    cond.into_int_value(),
2208                    self.intrinsics.i32_zero,
2209                    "",
2210                ));
2211                err!(self.builder.build_conditional_branch(
2212                    cond_value,
2213                    *frame.br_dest(),
2214                    else_block
2215                ));
2216                self.builder.position_at_end(else_block);
2217            }
2218            Operator::BrTable { ref targets } => {
2219                let current_block = self
2220                    .builder
2221                    .get_insert_block()
2222                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2223
2224                let index = self.state.pop1()?;
2225
2226                let default_frame = self.state.frame_at_depth(targets.default())?;
2227
2228                let phis = if default_frame.is_loop() {
2229                    default_frame.loop_body_phis()
2230                } else {
2231                    default_frame.phis()
2232                };
2233                let args = self.state.peekn(phis.len())?;
2234
2235                for (phi, value) in phis.iter().zip(args.iter()) {
2236                    phi.add_incoming(&[(value, current_block)]);
2237                }
2238
2239                let cases: Vec<_> = targets
2240                    .targets()
2241                    .enumerate()
2242                    .map(|(case_index, depth)| {
2243                        let depth = depth.map_err(from_binaryreadererror_wasmerror)?;
2244                        let frame_result: Result<&ControlFrame, CompileError> =
2245                            self.state.frame_at_depth(depth);
2246                        let frame = match frame_result {
2247                            Ok(v) => v,
2248                            Err(e) => return Err(e),
2249                        };
2250                        let case_index_literal =
2251                            self.context.i32_type().const_int(case_index as u64, false);
2252                        let phis = if frame.is_loop() {
2253                            frame.loop_body_phis()
2254                        } else {
2255                            frame.phis()
2256                        };
2257                        for (phi, value) in phis.iter().zip(args.iter()) {
2258                            phi.add_incoming(&[(value, current_block)]);
2259                        }
2260
2261                        Ok((case_index_literal, *frame.br_dest()))
2262                    })
2263                    .collect::<Result<_, _>>()?;
2264
2265                err!(self.builder.build_switch(
2266                    index.into_int_value(),
2267                    *default_frame.br_dest(),
2268                    &cases[..],
2269                ));
2270
2271                let args_len = args.len();
2272                self.state.popn(args_len)?;
2273                self.state.reachable = false;
2274            }
2275            Operator::If { blockty } => {
2276                let current_block = self
2277                    .builder
2278                    .get_insert_block()
2279                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2280                let if_then_block = self.context.append_basic_block(self.function, "if_then");
2281                let if_else_block = self.context.append_basic_block(self.function, "if_else");
2282                let end_block = self.context.append_basic_block(self.function, "if_end");
2283
2284                let end_phis = {
2285                    self.builder.position_at_end(end_block);
2286
2287                    let phis = self
2288                        .module_translation
2289                        .blocktype_params_results(&blockty)?
2290                        .1
2291                        .iter()
2292                        .map(|&wp_ty| {
2293                            err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2294                                type_to_llvm(self.intrinsics, wasm_ty)
2295                                    .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2296                            })
2297                        })
2298                        .collect::<Result<_, _>>()?;
2299
2300                    self.builder.position_at_end(current_block);
2301                    phis
2302                };
2303
2304                let cond = self.state.pop1()?;
2305
2306                let cond_value = err!(self.builder.build_int_compare(
2307                    IntPredicate::NE,
2308                    cond.into_int_value(),
2309                    self.intrinsics.i32_zero,
2310                    "",
2311                ));
2312
2313                err!(self.builder.build_conditional_branch(
2314                    cond_value,
2315                    if_then_block,
2316                    if_else_block
2317                ));
2318                self.builder.position_at_end(if_else_block);
2319                let block_param_types = self
2320                    .module_translation
2321                    .blocktype_params_results(&blockty)?
2322                    .0
2323                    .iter()
2324                    .map(|&wp_ty| {
2325                        err_nt!(wptype_to_type(wp_ty))
2326                            .and_then(|wasm_ty| type_to_llvm(self.intrinsics, wasm_ty))
2327                    })
2328                    .collect::<Result<Vec<_>, _>>()?;
2329                let else_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2330                    .iter()
2331                    .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2332                    .collect::<Result<SmallVec<_>, _>>()?;
2333                self.builder.position_at_end(if_then_block);
2334                let then_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2335                    .iter()
2336                    .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2337                    .collect::<Result<SmallVec<_>, _>>()?;
2338                for (else_phi, then_phi) in else_phis.iter().rev().zip(then_phis.iter().rev()) {
2339                    let (value, info) = self.state.pop1_extra()?;
2340                    let value = self.apply_pending_canonicalization(value, info)?;
2341                    else_phi.add_incoming(&[(&value, current_block)]);
2342                    then_phi.add_incoming(&[(&value, current_block)]);
2343                }
2344                for phi in then_phis.iter() {
2345                    self.state.push1(phi.as_basic_value());
2346                }
2347
2348                self.state.push_if(
2349                    if_then_block,
2350                    if_else_block,
2351                    end_block,
2352                    then_phis,
2353                    else_phis,
2354                    end_phis,
2355                    block_param_types.len(),
2356                );
2357            }
2358            Operator::Else => {
2359                if self.state.reachable {
2360                    let frame = self.state.frame_at_depth(0)?;
2361                    let current_block = self.builder.get_insert_block().ok_or_else(|| {
2362                        CompileError::Codegen("not currently in a block".to_string())
2363                    })?;
2364
2365                    for phi in frame.phis().to_vec().iter().rev() {
2366                        let (value, info) = self.state.pop1_extra()?;
2367                        let value = self.apply_pending_canonicalization(value, info)?;
2368                        phi.add_incoming(&[(&value, current_block)])
2369                    }
2370
2371                    let frame = self.state.frame_at_depth(0)?;
2372                    err!(self.builder.build_unconditional_branch(*frame.code_after()));
2373                }
2374
2375                let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
2376                    if_else,
2377                    if_else_state,
2378                    ..
2379                } = self.state.frame_at_depth_mut(0)?
2380                {
2381                    (if_else, if_else_state)
2382                } else {
2383                    unreachable!()
2384                };
2385
2386                *if_else_state = IfElseState::Else;
2387
2388                self.builder.position_at_end(*if_else_block);
2389                self.state.reachable = true;
2390
2391                if let ControlFrame::IfElse { else_phis, .. } = self.state.frame_at_depth(0)? {
2392                    // Push our own 'else' phi nodes to the stack.
2393                    for phi in else_phis.clone().iter() {
2394                        self.state.push1(phi.as_basic_value());
2395                    }
2396                };
2397            }
2398
2399            Operator::End => {
2400                let frame = self.state.pop_frame()?;
2401                let current_block = self
2402                    .builder
2403                    .get_insert_block()
2404                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2405
2406                if self.state.reachable {
2407                    for phi in frame.phis().iter().rev() {
2408                        let (value, info) = self.state.pop1_extra()?;
2409                        let value = self.apply_pending_canonicalization(value, info)?;
2410                        phi.add_incoming(&[(&value, current_block)]);
2411                    }
2412
2413                    err!(self.builder.build_unconditional_branch(*frame.code_after()));
2414                }
2415
2416                if let ControlFrame::IfElse {
2417                    if_else,
2418                    next,
2419                    if_else_state: IfElseState::If,
2420                    else_phis,
2421                    ..
2422                } = &frame
2423                {
2424                    for (phi, else_phi) in frame.phis().iter().zip(else_phis.iter()) {
2425                        phi.add_incoming(&[(&else_phi.as_basic_value(), *if_else)]);
2426                    }
2427                    self.builder.position_at_end(*if_else);
2428                    err!(self.builder.build_unconditional_branch(*next));
2429                } else if let ControlFrame::Landingpad { .. } = &frame {
2430                    self.state.pop_landingpad();
2431                };
2432
2433                self.builder.position_at_end(*frame.code_after());
2434                self.state.reset_stack(&frame);
2435
2436                self.state.reachable = true;
2437
2438                // Push each phi value to the value stack.
2439                for phi in frame.phis() {
2440                    if phi.count_incoming() != 0 {
2441                        self.state.push1(phi.as_basic_value());
2442                    } else {
2443                        // TODO if there are no incoming phi values, it means
2444                        // this block has no predecessors, and we can skip it
2445                        // altogether. However, fixing this is non-trivial as
2446                        // some places in the code rely on code getting generated
2447                        // for unreachable end blocks. For now, we let LLVM remove
2448                        // the block during dead code elimination instead.
2449                        let basic_ty = phi.as_basic_value().get_type();
2450                        let placeholder_value = basic_ty.const_zero();
2451                        self.state.push1(placeholder_value);
2452                        phi.as_instruction().erase_from_basic_block();
2453                    }
2454                }
2455            }
2456            Operator::Return => {
2457                let current_block = self
2458                    .builder
2459                    .get_insert_block()
2460                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2461
2462                let frame = self.state.outermost_frame()?;
2463                for phi in frame.phis().to_vec().iter().rev() {
2464                    let (arg, info) = self.state.pop1_extra()?;
2465                    let arg = self.apply_pending_canonicalization(arg, info)?;
2466                    phi.add_incoming(&[(&arg, current_block)]);
2467                }
2468                let frame = self.state.outermost_frame()?;
2469                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2470
2471                self.state.reachable = false;
2472            }
2473
2474            Operator::Unreachable => {
2475                err!(self.builder.build_call(
2476                    self.intrinsics.throw_trap,
2477                    &[self.intrinsics.trap_unreachable.into()],
2478                    "throw",
2479                ));
2480                err!(self.builder.build_unreachable());
2481
2482                self.state.reachable = false;
2483            }
2484
2485            /***************************
2486             * Basic instructions.
2487             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#basic-instructions
2488             ***************************/
2489            Operator::Nop => {
2490                // Do nothing.
2491            }
2492            Operator::Drop => {
2493                self.state.pop1()?;
2494            }
2495
2496            // Generate const values.
2497            Operator::I32Const { value } => {
2498                let i = self.intrinsics.i32_ty.const_int(value as u64, false);
2499                let info = if is_f32_arithmetic(value as u32) {
2500                    ExtraInfo::arithmetic_f32()
2501                } else {
2502                    Default::default()
2503                };
2504                self.state.push1_extra(i, info);
2505            }
2506            Operator::I64Const { value } => {
2507                let i = self.intrinsics.i64_ty.const_int(value as u64, false);
2508                let info = if is_f64_arithmetic(value as u64) {
2509                    ExtraInfo::arithmetic_f64()
2510                } else {
2511                    Default::default()
2512                };
2513                self.state.push1_extra(i, info);
2514            }
2515            Operator::F32Const { value } => {
2516                let bits = self.intrinsics.i32_ty.const_int(value.bits() as u64, false);
2517                let info = if is_f32_arithmetic(value.bits()) {
2518                    ExtraInfo::arithmetic_f32()
2519                } else {
2520                    Default::default()
2521                };
2522                let f = err!(
2523                    self.builder
2524                        .build_bit_cast(bits, self.intrinsics.f32_ty, "f")
2525                );
2526                self.state.push1_extra(f, info);
2527            }
2528            Operator::F64Const { value } => {
2529                let bits = self.intrinsics.i64_ty.const_int(value.bits(), false);
2530                let info = if is_f64_arithmetic(value.bits()) {
2531                    ExtraInfo::arithmetic_f64()
2532                } else {
2533                    Default::default()
2534                };
2535                let f = err!(
2536                    self.builder
2537                        .build_bit_cast(bits, self.intrinsics.f64_ty, "f")
2538                );
2539                self.state.push1_extra(f, info);
2540            }
2541            Operator::V128Const { value } => {
2542                let mut hi: [u8; 8] = Default::default();
2543                let mut lo: [u8; 8] = Default::default();
2544                hi.copy_from_slice(&value.bytes()[0..8]);
2545                lo.copy_from_slice(&value.bytes()[8..16]);
2546                let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
2547                let i = self
2548                    .intrinsics
2549                    .i128_ty
2550                    .const_int_arbitrary_precision(&packed);
2551                let mut quad1: [u8; 4] = Default::default();
2552                let mut quad2: [u8; 4] = Default::default();
2553                let mut quad3: [u8; 4] = Default::default();
2554                let mut quad4: [u8; 4] = Default::default();
2555                quad1.copy_from_slice(&value.bytes()[0..4]);
2556                quad2.copy_from_slice(&value.bytes()[4..8]);
2557                quad3.copy_from_slice(&value.bytes()[8..12]);
2558                quad4.copy_from_slice(&value.bytes()[12..16]);
2559                let mut info: ExtraInfo = Default::default();
2560                if is_f32_arithmetic(u32::from_le_bytes(quad1))
2561                    && is_f32_arithmetic(u32::from_le_bytes(quad2))
2562                    && is_f32_arithmetic(u32::from_le_bytes(quad3))
2563                    && is_f32_arithmetic(u32::from_le_bytes(quad4))
2564                {
2565                    info |= ExtraInfo::arithmetic_f32();
2566                }
2567                if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
2568                    info |= ExtraInfo::arithmetic_f64();
2569                }
2570                self.state.push1_extra(i, info);
2571            }
2572
2573            Operator::I8x16Splat => {
2574                let (v, i) = self.state.pop1_extra()?;
2575                let v = v.into_int_value();
2576                let v = err!(
2577                    self.builder
2578                        .build_int_truncate(v, self.intrinsics.i8_ty, "")
2579                );
2580                let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
2581                let res = err!(
2582                    self.builder
2583                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2584                );
2585                self.state.push1_extra(res, i);
2586            }
2587            Operator::I16x8Splat => {
2588                let (v, i) = self.state.pop1_extra()?;
2589                let v = v.into_int_value();
2590                let v = err!(
2591                    self.builder
2592                        .build_int_truncate(v, self.intrinsics.i16_ty, "")
2593                );
2594                let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
2595                let res = err!(
2596                    self.builder
2597                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2598                );
2599                self.state.push1_extra(res, i);
2600            }
2601            Operator::I32x4Splat => {
2602                let (v, i) = self.state.pop1_extra()?;
2603                let res = self.splat_vector(v, self.intrinsics.i32x4_ty)?;
2604                let res = err!(
2605                    self.builder
2606                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2607                );
2608                self.state.push1_extra(res, i);
2609            }
2610            Operator::I64x2Splat => {
2611                let (v, i) = self.state.pop1_extra()?;
2612                let res = self.splat_vector(v, self.intrinsics.i64x2_ty)?;
2613                let res = err!(
2614                    self.builder
2615                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2616                );
2617                self.state.push1_extra(res, i);
2618            }
2619            Operator::F32x4Splat => {
2620                let (v, i) = self.state.pop1_extra()?;
2621                let res = self.splat_vector(v, self.intrinsics.f32x4_ty)?;
2622                let res = err!(
2623                    self.builder
2624                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2625                );
2626                // The spec is unclear, we interpret splat as preserving NaN
2627                // payload bits.
2628                self.state.push1_extra(res, i);
2629            }
2630            Operator::F64x2Splat => {
2631                let (v, i) = self.state.pop1_extra()?;
2632                let res = self.splat_vector(v, self.intrinsics.f64x2_ty)?;
2633                let res = err!(
2634                    self.builder
2635                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2636                );
2637                // The spec is unclear, we interpret splat as preserving NaN
2638                // payload bits.
2639                self.state.push1_extra(res, i);
2640            }
2641
2642            // Operate on self.locals.
2643            Operator::LocalGet { local_index } => {
2644                let (type_value, pointer_value) = self.locals[local_index as usize];
2645                let v = err!(self.builder.build_load(
2646                    type_value,
2647                    pointer_value,
2648                    &format!("local_{local_index}_get")
2649                ));
2650                tbaa_label(
2651                    self.module,
2652                    self.intrinsics,
2653                    format!("local {local_index}"),
2654                    v.as_instruction_value().unwrap(),
2655                );
2656                self.state.push1(v);
2657            }
2658            Operator::LocalSet { local_index } => {
2659                let pointer_value = self.locals[local_index as usize].1;
2660                let (v, i) = self.state.pop1_extra()?;
2661                let v = self.apply_pending_canonicalization(v, i)?;
2662                let store = err!(self.builder.build_store(pointer_value, v));
2663                tbaa_label(
2664                    self.module,
2665                    self.intrinsics,
2666                    format!("local {local_index}"),
2667                    store,
2668                );
2669            }
2670            Operator::LocalTee { local_index } => {
2671                let pointer_value = self.locals[local_index as usize].1;
2672                let (v, i) = self.state.peek1_extra()?;
2673                let v = self.apply_pending_canonicalization(v, i)?;
2674                let store = err!(self.builder.build_store(pointer_value, v));
2675                tbaa_label(
2676                    self.module,
2677                    self.intrinsics,
2678                    format!("local {local_index}"),
2679                    store,
2680                );
2681            }
2682
2683            Operator::GlobalGet { global_index } => {
2684                if self.g0m0.is_some() && global_index == 0 {
2685                    let Some((g0, _)) = self.g0m0 else {
2686                        unreachable!()
2687                    };
2688
2689                    // Removed with mem2reg.
2690                    let value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, ""));
2691
2692                    self.state.push1(value);
2693                } else {
2694                    let global_index = GlobalIndex::from_u32(global_index);
2695                    match self
2696                        .ctx
2697                        .global(global_index, self.intrinsics, self.module)?
2698                    {
2699                        GlobalCache::Const { value } => {
2700                            self.state.push1(*value);
2701                        }
2702                        GlobalCache::Mut {
2703                            ptr_to_value,
2704                            value_type,
2705                        } => {
2706                            let value =
2707                                err!(self.builder.build_load(*value_type, *ptr_to_value, ""));
2708                            tbaa_label(
2709                                self.module,
2710                                self.intrinsics,
2711                                format!("global {}", global_index.as_u32()),
2712                                value.as_instruction_value().unwrap(),
2713                            );
2714                            self.state.push1(value);
2715                        }
2716                    }
2717                }
2718            }
2719            Operator::GlobalSet { global_index } => {
2720                if self.g0m0.is_some() && global_index == 0 {
2721                    let Some((g0, _)) = self.g0m0 else {
2722                        unreachable!()
2723                    };
2724                    let ptr_to_value = g0;
2725                    let (value, info) = self.state.pop1_extra()?;
2726                    let value = self.apply_pending_canonicalization(value, info)?;
2727                    let store = err!(self.builder.build_store(ptr_to_value, value));
2728                    tbaa_label(self.module, self.intrinsics, "global 0".to_string(), store);
2729                } else {
2730                    let global_index = GlobalIndex::from_u32(global_index);
2731                    match self
2732                        .ctx
2733                        .global(global_index, self.intrinsics, self.module)?
2734                    {
2735                        GlobalCache::Const { value: _ } => {
2736                            return Err(CompileError::Codegen(format!(
2737                                "global.set on immutable global index {}",
2738                                global_index.as_u32()
2739                            )));
2740                        }
2741                        GlobalCache::Mut { ptr_to_value, .. } => {
2742                            let ptr_to_value = *ptr_to_value;
2743                            let (value, info) = self.state.pop1_extra()?;
2744                            let value = self.apply_pending_canonicalization(value, info)?;
2745                            let store = err!(self.builder.build_store(ptr_to_value, value));
2746                            tbaa_label(
2747                                self.module,
2748                                self.intrinsics,
2749                                format!("global {}", global_index.as_u32()),
2750                                store,
2751                            );
2752                        }
2753                    }
2754                }
2755            }
2756
2757            // `TypedSelect` must be used for extern refs so ref counting should
2758            // be done with TypedSelect. But otherwise they're the same.
2759            Operator::TypedSelect { .. } | Operator::Select => {
2760                let ((v1, i1), (v2, i2), (cond, _)) = self.state.pop3_extra()?;
2761                // We don't bother canonicalizing 'cond' here because we only
2762                // compare it to zero, and that's invariant under
2763                // canonicalization.
2764
2765                // If the pending bits of v1 and v2 are the same, we can pass
2766                // them along to the result. Otherwise, apply pending
2767                // canonicalizations now.
2768                let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
2769                    || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
2770                {
2771                    (
2772                        self.apply_pending_canonicalization(v1, i1)?,
2773                        i1.strip_pending(),
2774                        self.apply_pending_canonicalization(v2, i2)?,
2775                        i2.strip_pending(),
2776                    )
2777                } else {
2778                    (v1, i1, v2, i2)
2779                };
2780                let cond_value = err!(self.builder.build_int_compare(
2781                    IntPredicate::NE,
2782                    cond.into_int_value(),
2783                    self.intrinsics.i32_zero,
2784                    "",
2785                ));
2786                let res = err!(self.builder.build_select(cond_value, v1, v2, ""));
2787                let info = {
2788                    let mut info = (i1.strip_pending() & i2.strip_pending())?;
2789                    if i1.has_pending_f32_nan() {
2790                        debug_assert!(i2.has_pending_f32_nan());
2791                        info = (info | ExtraInfo::pending_f32_nan())?;
2792                    }
2793                    if i1.has_pending_f64_nan() {
2794                        debug_assert!(i2.has_pending_f64_nan());
2795                        info = (info | ExtraInfo::pending_f64_nan())?;
2796                    }
2797                    info
2798                };
2799                self.state.push1_extra(res, info);
2800            }
2801            Operator::Call { function_index } => {
2802                let func_index = FunctionIndex::from_u32(function_index);
2803                let sigindex = &self.wasm_module.functions[func_index];
2804                let func_type = &self.wasm_module.signatures[*sigindex];
2805
2806                let mut g0m0_params = None;
2807
2808                let FunctionCache {
2809                    func,
2810                    llvm_func_type,
2811                    vmctx: callee_vmctx,
2812                    attrs,
2813                } = if let Some(local_func_index) = self.wasm_module.local_func_index(func_index) {
2814                    if let Some((g0, m0)) = &self.g0m0 {
2815                        // removed with mem2reg.
2816                        let value = err!(self.builder.build_load(self.intrinsics.i32_ty, *g0, ""));
2817
2818                        g0m0_params = Some((value.into_int_value(), *m0));
2819                    }
2820
2821                    let function_name = self
2822                        .symbol_registry
2823                        .symbol_to_name(Symbol::LocalFunction(local_func_index));
2824
2825                    self.ctx.local_func(
2826                        local_func_index,
2827                        func_index,
2828                        self.intrinsics,
2829                        self.module,
2830                        self.context,
2831                        func_type,
2832                        &function_name,
2833                    )?
2834                } else {
2835                    self.ctx
2836                        .func(func_index, self.intrinsics, self.context, func_type)?
2837                };
2838                let llvm_func_type = *llvm_func_type;
2839                let func = *func;
2840                let callee_vmctx = *callee_vmctx;
2841                let attrs = attrs.clone();
2842
2843                /*
2844                let func_ptr = self.llvm.functions.borrow_mut()[&func_index];
2845
2846                (params, func_ptr.as_global_value().as_pointer_value())
2847                */
2848                let params = self.state.popn_save_extra(func_type.params().len())?;
2849
2850                // Apply pending canonicalizations.
2851                let params = params
2852                    .iter()
2853                    .zip(func_type.params().iter())
2854                    .map(|((v, info), wasm_ty)| match wasm_ty {
2855                        Type::F32 => err_nt!(self.builder.build_bit_cast(
2856                            self.apply_pending_canonicalization(*v, *info)?,
2857                            self.intrinsics.f32_ty,
2858                            "",
2859                        )),
2860                        Type::F64 => err_nt!(self.builder.build_bit_cast(
2861                            self.apply_pending_canonicalization(*v, *info)?,
2862                            self.intrinsics.f64_ty,
2863                            "",
2864                        )),
2865                        Type::V128 => self.apply_pending_canonicalization(*v, *info),
2866                        _ => Ok(*v),
2867                    })
2868                    .collect::<Result<Vec<_>, _>>()?;
2869
2870                let params = self.abi.args_to_call(
2871                    &self.alloca_builder,
2872                    func_type,
2873                    &llvm_func_type,
2874                    callee_vmctx.into_pointer_value(),
2875                    params.as_slice(),
2876                    self.intrinsics,
2877                    g0m0_params,
2878                )?;
2879
2880                /*
2881                if self.track_state {
2882                    if let Some(offset) = opcode_offset {
2883                        let mut stackmaps = self.stackmaps.borrow_mut();
2884                        emit_stack_map(
2885                            &info,
2886                            self.intrinsics,
2887                            self.builder,
2888                            self.index,
2889                            &mut *stackmaps,
2890                            StackmapEntryKind::Call,
2891                            &self.locals,
2892                            state,
2893                            ctx,
2894                            offset,
2895                        )
2896                    }
2897                }
2898                */
2899                let call_site = if let Some(lpad) = self.state.get_innermost_landingpad() {
2900                    let then_block = self.context.append_basic_block(self.function, "then_block");
2901
2902                    let ret = err!(self.builder.build_indirect_invoke(
2903                        llvm_func_type,
2904                        func,
2905                        params.as_slice(),
2906                        then_block,
2907                        lpad,
2908                        "",
2909                    ));
2910
2911                    self.builder.position_at_end(then_block);
2912                    ret
2913                } else {
2914                    err!(
2915                        self.builder.build_indirect_call(
2916                            llvm_func_type,
2917                            func,
2918                            params
2919                                .iter()
2920                                .copied()
2921                                .map(Into::into)
2922                                .collect::<Vec<BasicMetadataValueEnum>>()
2923                                .as_slice(),
2924                            "",
2925                        )
2926                    )
2927                };
2928                for (attr, attr_loc) in attrs {
2929                    call_site.add_attribute(attr_loc, attr);
2930                }
2931                /*
2932                if self.track_state {
2933                    if let Some(offset) = opcode_offset {
2934                        let mut stackmaps = self.stackmaps.borrow_mut();
2935                        finalize_opcode_stack_map(
2936                            self.intrinsics,
2937                            self.builder,
2938                            self.index,
2939                            &mut *stackmaps,
2940                            StackmapEntryKind::Call,
2941                            offset,
2942                        )
2943                    }
2944                }
2945                */
2946
2947                self.abi
2948                    .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
2949                    .iter()
2950                    .for_each(|ret| self.state.push1(*ret));
2951            }
2952            Operator::CallIndirect {
2953                type_index,
2954                table_index,
2955            } => {
2956                let sigindex = SignatureIndex::from_u32(type_index);
2957                let func_type = &self.wasm_module.signatures[sigindex];
2958                let expected_dynamic_sigindex =
2959                    self.ctx
2960                        .dynamic_sigindex(sigindex, self.intrinsics, self.module)?;
2961                let (table_base, table_bound) = self.ctx.table(
2962                    TableIndex::from_u32(table_index),
2963                    self.intrinsics,
2964                    self.module,
2965                    &self.builder,
2966                )?;
2967                let func_index = self.state.pop1()?.into_int_value();
2968
2969                let truncated_table_bounds = err!(self.builder.build_int_truncate(
2970                    table_bound,
2971                    self.intrinsics.i32_ty,
2972                    "truncated_table_bounds",
2973                ));
2974
2975                // First, check if the index is outside of the table bounds.
2976                let index_in_bounds = err!(self.builder.build_int_compare(
2977                    IntPredicate::ULT,
2978                    func_index,
2979                    truncated_table_bounds,
2980                    "index_in_bounds",
2981                ));
2982
2983                let index_in_bounds = err!(self.builder.build_call(
2984                    self.intrinsics.expect_i1,
2985                    &[
2986                        index_in_bounds.into(),
2987                        self.intrinsics.i1_ty.const_int(1, false).into(),
2988                    ],
2989                    "index_in_bounds_expect",
2990                ))
2991                .try_as_basic_value()
2992                .unwrap_basic()
2993                .into_int_value();
2994
2995                let in_bounds_continue_block = self
2996                    .context
2997                    .append_basic_block(self.function, "in_bounds_continue_block");
2998                let not_in_bounds_block = self
2999                    .context
3000                    .append_basic_block(self.function, "not_in_bounds_block");
3001                err!(self.builder.build_conditional_branch(
3002                    index_in_bounds,
3003                    in_bounds_continue_block,
3004                    not_in_bounds_block,
3005                ));
3006                self.builder.position_at_end(not_in_bounds_block);
3007                err!(self.builder.build_call(
3008                    self.intrinsics.throw_trap,
3009                    &[self.intrinsics.trap_table_access_oob.into()],
3010                    "throw",
3011                ));
3012                err!(self.builder.build_unreachable());
3013                self.builder.position_at_end(in_bounds_continue_block);
3014
3015                // We assume the table has the `funcref` (pointer to `anyfunc`)
3016                // element type.
3017                let casted_table_base = err!(self.builder.build_pointer_cast(
3018                    table_base,
3019                    self.context.ptr_type(AddressSpace::default()),
3020                    "casted_table_base",
3021                ));
3022
3023                let funcref_ptr = unsafe {
3024                    err!(self.builder.build_in_bounds_gep(
3025                        self.intrinsics.ptr_ty,
3026                        casted_table_base,
3027                        &[func_index],
3028                        "funcref_ptr",
3029                    ))
3030                };
3031
3032                // a funcref (pointer to `anyfunc`)
3033                let anyfunc_struct_ptr = err!(self.builder.build_load(
3034                    self.intrinsics.ptr_ty,
3035                    funcref_ptr,
3036                    "anyfunc_struct_ptr",
3037                ))
3038                .into_pointer_value();
3039
3040                // trap if we're trying to call a null funcref
3041                {
3042                    let funcref_not_null = err!(
3043                        self.builder
3044                            .build_is_not_null(anyfunc_struct_ptr, "null funcref check")
3045                    );
3046
3047                    let funcref_continue_deref_block = self
3048                        .context
3049                        .append_basic_block(self.function, "funcref_continue deref_block");
3050
3051                    let funcref_is_null_block = self
3052                        .context
3053                        .append_basic_block(self.function, "funcref_is_null_block");
3054                    err!(self.builder.build_conditional_branch(
3055                        funcref_not_null,
3056                        funcref_continue_deref_block,
3057                        funcref_is_null_block,
3058                    ));
3059                    self.builder.position_at_end(funcref_is_null_block);
3060                    err!(self.builder.build_call(
3061                        self.intrinsics.throw_trap,
3062                        &[self.intrinsics.trap_call_indirect_null.into()],
3063                        "throw",
3064                    ));
3065                    err!(self.builder.build_unreachable());
3066                    self.builder.position_at_end(funcref_continue_deref_block);
3067                }
3068
3069                // Load things from the anyfunc data structure.
3070                let func_ptr_ptr = self
3071                    .builder
3072                    .build_struct_gep(
3073                        self.intrinsics.anyfunc_ty,
3074                        anyfunc_struct_ptr,
3075                        0,
3076                        "func_ptr_ptr",
3077                    )
3078                    .unwrap();
3079                let sigindex_ptr = self
3080                    .builder
3081                    .build_struct_gep(
3082                        self.intrinsics.anyfunc_ty,
3083                        anyfunc_struct_ptr,
3084                        1,
3085                        "sigindex_ptr",
3086                    )
3087                    .unwrap();
3088                let ctx_ptr_ptr = self
3089                    .builder
3090                    .build_struct_gep(
3091                        self.intrinsics.anyfunc_ty,
3092                        anyfunc_struct_ptr,
3093                        2,
3094                        "ctx_ptr_ptr",
3095                    )
3096                    .unwrap();
3097                let (func_ptr, found_dynamic_sigindex, ctx_ptr) = (
3098                    err!(
3099                        self.builder
3100                            .build_load(self.intrinsics.ptr_ty, func_ptr_ptr, "func_ptr")
3101                    )
3102                    .into_pointer_value(),
3103                    err!(
3104                        self.builder
3105                            .build_load(self.intrinsics.i32_ty, sigindex_ptr, "sigindex")
3106                    )
3107                    .into_int_value(),
3108                    err!(
3109                        self.builder
3110                            .build_load(self.intrinsics.ptr_ty, ctx_ptr_ptr, "ctx_ptr")
3111                    ),
3112                );
3113
3114                // Next, check if the table element is initialized.
3115
3116                // TODO: we may not need this check anymore
3117                let elem_initialized = err!(self.builder.build_is_not_null(func_ptr, ""));
3118
3119                // Next, check if the signature id is correct.
3120
3121                let sigindices_equal = err!(self.builder.build_int_compare(
3122                    IntPredicate::EQ,
3123                    expected_dynamic_sigindex,
3124                    found_dynamic_sigindex,
3125                    "sigindices_equal",
3126                ));
3127
3128                let initialized_and_sigindices_match = err!(self.builder.build_and(
3129                    elem_initialized,
3130                    sigindices_equal,
3131                    ""
3132                ));
3133
3134                // Tell llvm that `expected_dynamic_sigindex` should equal `found_dynamic_sigindex`.
3135                let initialized_and_sigindices_match = err!(self.builder.build_call(
3136                    self.intrinsics.expect_i1,
3137                    &[
3138                        initialized_and_sigindices_match.into(),
3139                        self.intrinsics.i1_ty.const_int(1, false).into(),
3140                    ],
3141                    "initialized_and_sigindices_match_expect",
3142                ))
3143                .try_as_basic_value()
3144                .unwrap_basic()
3145                .into_int_value();
3146
3147                let continue_block = self
3148                    .context
3149                    .append_basic_block(self.function, "continue_block");
3150                let sigindices_notequal_block = self
3151                    .context
3152                    .append_basic_block(self.function, "sigindices_notequal_block");
3153                err!(self.builder.build_conditional_branch(
3154                    initialized_and_sigindices_match,
3155                    continue_block,
3156                    sigindices_notequal_block,
3157                ));
3158
3159                self.builder.position_at_end(sigindices_notequal_block);
3160                let trap_code = err!(self.builder.build_select(
3161                    elem_initialized,
3162                    self.intrinsics.trap_call_indirect_sig,
3163                    self.intrinsics.trap_call_indirect_null,
3164                    "",
3165                ));
3166                err!(self.builder.build_call(
3167                    self.intrinsics.throw_trap,
3168                    &[trap_code.into()],
3169                    "throw"
3170                ));
3171                err!(self.builder.build_unreachable());
3172                self.builder.position_at_end(continue_block);
3173
3174                if self.g0m0.is_some() {
3175                    self.build_g0m0_indirect_call(
3176                        table_index,
3177                        ctx_ptr.into_pointer_value(),
3178                        func_type,
3179                        func_ptr,
3180                        func_index,
3181                    )?;
3182                } else {
3183                    let call_site = self.build_indirect_call(
3184                        ctx_ptr.into_pointer_value(),
3185                        func_type,
3186                        func_ptr,
3187                        None,
3188                        None,
3189                    )?;
3190
3191                    self.abi
3192                        .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
3193                        .iter()
3194                        .for_each(|ret| self.state.push1(*ret));
3195                }
3196            }
3197
3198            /***************************
3199             * Integer Arithmetic instructions.
3200             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-arithmetic-instructions
3201             ***************************/
3202            Operator::I32Add | Operator::I64Add => {
3203                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3204                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3205                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3206                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3207                let res = err!(self.builder.build_int_add(v1, v2, ""));
3208                self.state.push1(res);
3209            }
3210            Operator::I8x16Add => {
3211                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3212                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3213                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3214                let res = err!(self.builder.build_int_add(v1, v2, ""));
3215                let res = err!(
3216                    self.builder
3217                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3218                );
3219                self.state.push1(res);
3220            }
3221            Operator::I16x8Add => {
3222                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3223                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3224                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3225                let res = err!(self.builder.build_int_add(v1, v2, ""));
3226                let res = err!(
3227                    self.builder
3228                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3229                );
3230                self.state.push1(res);
3231            }
3232            Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U => {
3233                let extend_op = match op {
3234                    Operator::I16x8ExtAddPairwiseI8x16S => {
3235                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, "")
3236                    }
3237                    Operator::I16x8ExtAddPairwiseI8x16U => {
3238                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, "")
3239                    }
3240                    _ => unreachable!("Unhandled internal variant"),
3241                };
3242                let (v, i) = self.state.pop1_extra()?;
3243                let (v, _) = self.v128_into_i8x16(v, i)?;
3244
3245                let left = err!(self.builder.build_shuffle_vector(
3246                    v,
3247                    v.get_type().get_undef(),
3248                    VectorType::const_vector(&[
3249                        self.intrinsics.i32_consts[0],
3250                        self.intrinsics.i32_consts[2],
3251                        self.intrinsics.i32_consts[4],
3252                        self.intrinsics.i32_consts[6],
3253                        self.intrinsics.i32_consts[8],
3254                        self.intrinsics.i32_consts[10],
3255                        self.intrinsics.i32_consts[12],
3256                        self.intrinsics.i32_consts[14],
3257                    ]),
3258                    "",
3259                ));
3260                let left = err!(extend_op(self, left));
3261                let right = err!(self.builder.build_shuffle_vector(
3262                    v,
3263                    v.get_type().get_undef(),
3264                    VectorType::const_vector(&[
3265                        self.intrinsics.i32_consts[1],
3266                        self.intrinsics.i32_consts[3],
3267                        self.intrinsics.i32_consts[5],
3268                        self.intrinsics.i32_consts[7],
3269                        self.intrinsics.i32_consts[9],
3270                        self.intrinsics.i32_consts[11],
3271                        self.intrinsics.i32_consts[13],
3272                        self.intrinsics.i32_consts[15],
3273                    ]),
3274                    "",
3275                ));
3276                let right = err!(extend_op(self, right));
3277
3278                let res = err!(self.builder.build_int_add(left, right, ""));
3279                let res = err!(
3280                    self.builder
3281                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3282                );
3283                self.state.push1(res);
3284            }
3285            Operator::I32x4Add => {
3286                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3287                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3288                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3289                let res = err!(self.builder.build_int_add(v1, v2, ""));
3290                let res = err!(
3291                    self.builder
3292                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3293                );
3294                self.state.push1(res);
3295            }
3296            Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
3297                let extend_op = match op {
3298                    Operator::I32x4ExtAddPairwiseI16x8S => {
3299                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3300                    }
3301                    Operator::I32x4ExtAddPairwiseI16x8U => {
3302                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3303                    }
3304                    _ => unreachable!("Unhandled internal variant"),
3305                };
3306                let (v, i) = self.state.pop1_extra()?;
3307                let (v, _) = self.v128_into_i16x8(v, i)?;
3308
3309                let left = err!(self.builder.build_shuffle_vector(
3310                    v,
3311                    v.get_type().get_undef(),
3312                    VectorType::const_vector(&[
3313                        self.intrinsics.i32_consts[0],
3314                        self.intrinsics.i32_consts[2],
3315                        self.intrinsics.i32_consts[4],
3316                        self.intrinsics.i32_consts[6],
3317                    ]),
3318                    "",
3319                ));
3320                let left = err!(extend_op(self, left));
3321                let right = err!(self.builder.build_shuffle_vector(
3322                    v,
3323                    v.get_type().get_undef(),
3324                    VectorType::const_vector(&[
3325                        self.intrinsics.i32_consts[1],
3326                        self.intrinsics.i32_consts[3],
3327                        self.intrinsics.i32_consts[5],
3328                        self.intrinsics.i32_consts[7],
3329                    ]),
3330                    "",
3331                ));
3332                let right = err!(extend_op(self, right));
3333
3334                let res = err!(self.builder.build_int_add(left, right, ""));
3335                let res = err!(
3336                    self.builder
3337                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3338                );
3339                self.state.push1(res);
3340            }
3341            Operator::I64x2Add => {
3342                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3343                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3344                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3345                let res = err!(self.builder.build_int_add(v1, v2, ""));
3346                let res = err!(
3347                    self.builder
3348                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3349                );
3350                self.state.push1(res);
3351            }
3352            Operator::I8x16AddSatS => {
3353                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3354                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3355                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3356                let res = err!(self.builder.build_call(
3357                    self.intrinsics.sadd_sat_i8x16,
3358                    &[v1.into(), v2.into()],
3359                    ""
3360                ))
3361                .try_as_basic_value()
3362                .unwrap_basic();
3363                let res = err!(
3364                    self.builder
3365                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3366                );
3367                self.state.push1(res);
3368            }
3369            Operator::I16x8AddSatS => {
3370                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3371                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3372                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3373                let res = err!(self.builder.build_call(
3374                    self.intrinsics.sadd_sat_i16x8,
3375                    &[v1.into(), v2.into()],
3376                    ""
3377                ))
3378                .try_as_basic_value()
3379                .unwrap_basic();
3380                let res = err!(
3381                    self.builder
3382                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3383                );
3384                self.state.push1(res);
3385            }
3386            Operator::I8x16AddSatU => {
3387                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3388                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3389                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3390                let res = err!(self.builder.build_call(
3391                    self.intrinsics.uadd_sat_i8x16,
3392                    &[v1.into(), v2.into()],
3393                    ""
3394                ))
3395                .try_as_basic_value()
3396                .unwrap_basic();
3397                let res = err!(
3398                    self.builder
3399                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3400                );
3401                self.state.push1(res);
3402            }
3403            Operator::I16x8AddSatU => {
3404                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3405                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3406                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3407                let res = err!(self.builder.build_call(
3408                    self.intrinsics.uadd_sat_i16x8,
3409                    &[v1.into(), v2.into()],
3410                    ""
3411                ))
3412                .try_as_basic_value()
3413                .unwrap_basic();
3414                let res = err!(
3415                    self.builder
3416                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3417                );
3418                self.state.push1(res);
3419            }
3420            Operator::I32Sub | Operator::I64Sub => {
3421                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3422                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3423                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3424                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3425                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3426                self.state.push1(res);
3427            }
3428            Operator::I8x16Sub => {
3429                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3430                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3431                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3432                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3433                let res = err!(
3434                    self.builder
3435                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3436                );
3437                self.state.push1(res);
3438            }
3439            Operator::I16x8Sub => {
3440                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3441                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3442                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3443                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3444                let res = err!(
3445                    self.builder
3446                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3447                );
3448                self.state.push1(res);
3449            }
3450            Operator::I32x4Sub => {
3451                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3452                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3453                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3454                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3455                let res = err!(
3456                    self.builder
3457                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3458                );
3459                self.state.push1(res);
3460            }
3461            Operator::I64x2Sub => {
3462                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3463                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3464                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3465                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3466                let res = err!(
3467                    self.builder
3468                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3469                );
3470                self.state.push1(res);
3471            }
3472            Operator::I8x16SubSatS => {
3473                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3474                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3475                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3476                let res = err!(self.builder.build_call(
3477                    self.intrinsics.ssub_sat_i8x16,
3478                    &[v1.into(), v2.into()],
3479                    ""
3480                ))
3481                .try_as_basic_value()
3482                .unwrap_basic();
3483                let res = err!(
3484                    self.builder
3485                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3486                );
3487                self.state.push1(res);
3488            }
3489            Operator::I16x8SubSatS => {
3490                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3491                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3492                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3493                let res = err!(self.builder.build_call(
3494                    self.intrinsics.ssub_sat_i16x8,
3495                    &[v1.into(), v2.into()],
3496                    ""
3497                ))
3498                .try_as_basic_value()
3499                .unwrap_basic();
3500                let res = err!(
3501                    self.builder
3502                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3503                );
3504                self.state.push1(res);
3505            }
3506            Operator::I8x16SubSatU => {
3507                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3508                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3509                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3510                let res = err!(self.builder.build_call(
3511                    self.intrinsics.usub_sat_i8x16,
3512                    &[v1.into(), v2.into()],
3513                    ""
3514                ))
3515                .try_as_basic_value()
3516                .unwrap_basic();
3517                let res = err!(
3518                    self.builder
3519                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3520                );
3521                self.state.push1(res);
3522            }
3523            Operator::I16x8SubSatU => {
3524                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3525                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3526                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3527                let res = err!(self.builder.build_call(
3528                    self.intrinsics.usub_sat_i16x8,
3529                    &[v1.into(), v2.into()],
3530                    ""
3531                ))
3532                .try_as_basic_value()
3533                .unwrap_basic();
3534                let res = err!(
3535                    self.builder
3536                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3537                );
3538                self.state.push1(res);
3539            }
3540            Operator::I32Mul | Operator::I64Mul => {
3541                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3542                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3543                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3544                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3545                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3546                self.state.push1(res);
3547            }
3548            Operator::I16x8Mul => {
3549                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3550                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3551                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3552                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3553                let res = err!(
3554                    self.builder
3555                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3556                );
3557                self.state.push1(res);
3558            }
3559            Operator::I32x4Mul => {
3560                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3561                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3562                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3563                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3564                let res = err!(
3565                    self.builder
3566                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3567                );
3568                self.state.push1(res);
3569            }
3570            Operator::I64x2Mul => {
3571                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3572                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3573                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3574                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3575                let res = err!(
3576                    self.builder
3577                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3578                );
3579                self.state.push1(res);
3580            }
3581            Operator::I16x8Q15MulrSatS => {
3582                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3583                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3584                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3585
3586                let max_value = self.intrinsics.i16_ty.const_int(i16::MAX as u64, false);
3587                let max_values = VectorType::const_vector(&[max_value; 8]);
3588
3589                let v1 = err!(
3590                    self.builder
3591                        .build_int_s_extend(v1, self.intrinsics.i32x8_ty, "")
3592                );
3593                let v2 = err!(
3594                    self.builder
3595                        .build_int_s_extend(v2, self.intrinsics.i32x8_ty, "")
3596                );
3597                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3598
3599                // magic number specified by the spec
3600                let bit = self.intrinsics.i32_ty.const_int(0x4000, false);
3601                let bits = VectorType::const_vector(&[bit; 8]);
3602
3603                let res = err!(self.builder.build_int_add(res, bits, ""));
3604
3605                let fifteen = self.intrinsics.i32_consts[15];
3606                let fifteens = VectorType::const_vector(&[fifteen; 8]);
3607
3608                let res = err!(self.builder.build_right_shift(res, fifteens, true, ""));
3609                let saturate_up = {
3610                    let max_values = err!(self.builder.build_int_s_extend(
3611                        max_values,
3612                        self.intrinsics.i32x8_ty,
3613                        ""
3614                    ));
3615                    err!(
3616                        self.builder
3617                            .build_int_compare(IntPredicate::SGT, res, max_values, "")
3618                    )
3619                };
3620
3621                let res = err!(
3622                    self.builder
3623                        .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
3624                );
3625
3626                let res = err!(self.builder.build_select(saturate_up, max_values, res, ""))
3627                    .into_vector_value();
3628                let res = err!(
3629                    self.builder
3630                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3631                );
3632                self.state.push1(res);
3633            }
3634            Operator::I16x8ExtMulLowI8x16S
3635            | Operator::I16x8ExtMulLowI8x16U
3636            | Operator::I16x8ExtMulHighI8x16S
3637            | Operator::I16x8ExtMulHighI8x16U => {
3638                let extend_op = match op {
3639                    Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulHighI8x16S => {
3640                        |s: &Self, v| -> Result<VectorValue, CompileError> {
3641                            err_nt!(s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, ""))
3642                        }
3643                    }
3644                    Operator::I16x8ExtMulLowI8x16U | Operator::I16x8ExtMulHighI8x16U => {
3645                        |s: &Self, v| -> Result<VectorValue, CompileError> {
3646                            err_nt!(s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, ""))
3647                        }
3648                    }
3649                    _ => unreachable!("Unhandled internal variant"),
3650                };
3651                let shuffle_array = match op {
3652                    Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulLowI8x16U => [
3653                        self.intrinsics.i32_consts[0],
3654                        self.intrinsics.i32_consts[2],
3655                        self.intrinsics.i32_consts[4],
3656                        self.intrinsics.i32_consts[6],
3657                        self.intrinsics.i32_consts[8],
3658                        self.intrinsics.i32_consts[10],
3659                        self.intrinsics.i32_consts[12],
3660                        self.intrinsics.i32_consts[14],
3661                    ],
3662                    Operator::I16x8ExtMulHighI8x16S | Operator::I16x8ExtMulHighI8x16U => [
3663                        self.intrinsics.i32_consts[1],
3664                        self.intrinsics.i32_consts[3],
3665                        self.intrinsics.i32_consts[5],
3666                        self.intrinsics.i32_consts[7],
3667                        self.intrinsics.i32_consts[9],
3668                        self.intrinsics.i32_consts[11],
3669                        self.intrinsics.i32_consts[13],
3670                        self.intrinsics.i32_consts[15],
3671                    ],
3672                    _ => unreachable!("Unhandled internal variant"),
3673                };
3674                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3675                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3676                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3677                let val1 = err!(self.builder.build_shuffle_vector(
3678                    v1,
3679                    v1.get_type().get_undef(),
3680                    VectorType::const_vector(&shuffle_array),
3681                    "",
3682                ));
3683                let val1 = err!(extend_op(self, val1));
3684                let val2 = err!(self.builder.build_shuffle_vector(
3685                    v2,
3686                    v2.get_type().get_undef(),
3687                    VectorType::const_vector(&shuffle_array),
3688                    "",
3689                ));
3690                let val2 = err!(extend_op(self, val2));
3691                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3692                let res = err!(
3693                    self.builder
3694                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3695                );
3696                self.state.push1(res);
3697            }
3698            Operator::I32x4ExtMulLowI16x8S
3699            | Operator::I32x4ExtMulLowI16x8U
3700            | Operator::I32x4ExtMulHighI16x8S
3701            | Operator::I32x4ExtMulHighI16x8U => {
3702                let extend_op = match op {
3703                    Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulHighI16x8S => {
3704                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3705                    }
3706                    Operator::I32x4ExtMulLowI16x8U | Operator::I32x4ExtMulHighI16x8U => {
3707                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3708                    }
3709                    _ => unreachable!("Unhandled internal variant"),
3710                };
3711                let shuffle_array = match op {
3712                    Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulLowI16x8U => [
3713                        self.intrinsics.i32_consts[0],
3714                        self.intrinsics.i32_consts[2],
3715                        self.intrinsics.i32_consts[4],
3716                        self.intrinsics.i32_consts[6],
3717                    ],
3718                    Operator::I32x4ExtMulHighI16x8S | Operator::I32x4ExtMulHighI16x8U => [
3719                        self.intrinsics.i32_consts[1],
3720                        self.intrinsics.i32_consts[3],
3721                        self.intrinsics.i32_consts[5],
3722                        self.intrinsics.i32_consts[7],
3723                    ],
3724                    _ => unreachable!("Unhandled internal variant"),
3725                };
3726                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3727                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3728                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3729                let val1 = err!(self.builder.build_shuffle_vector(
3730                    v1,
3731                    v1.get_type().get_undef(),
3732                    VectorType::const_vector(&shuffle_array),
3733                    "",
3734                ));
3735                let val1 = err!(extend_op(self, val1));
3736                let val2 = err!(self.builder.build_shuffle_vector(
3737                    v2,
3738                    v2.get_type().get_undef(),
3739                    VectorType::const_vector(&shuffle_array),
3740                    "",
3741                ));
3742                let val2 = err!(extend_op(self, val2));
3743                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3744                let res = err!(
3745                    self.builder
3746                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3747                );
3748                self.state.push1(res);
3749            }
3750            Operator::I64x2ExtMulLowI32x4S
3751            | Operator::I64x2ExtMulLowI32x4U
3752            | Operator::I64x2ExtMulHighI32x4S
3753            | Operator::I64x2ExtMulHighI32x4U => {
3754                let extend_op = match op {
3755                    Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulHighI32x4S => {
3756                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
3757                    }
3758                    Operator::I64x2ExtMulLowI32x4U | Operator::I64x2ExtMulHighI32x4U => {
3759                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
3760                    }
3761                    _ => unreachable!("Unhandled internal variant"),
3762                };
3763                let shuffle_array = match op {
3764                    Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulLowI32x4U => {
3765                        [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[2]]
3766                    }
3767                    Operator::I64x2ExtMulHighI32x4S | Operator::I64x2ExtMulHighI32x4U => {
3768                        [self.intrinsics.i32_consts[1], self.intrinsics.i32_consts[3]]
3769                    }
3770                    _ => unreachable!("Unhandled internal variant"),
3771                };
3772                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3773                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3774                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3775                let val1 = err!(self.builder.build_shuffle_vector(
3776                    v1,
3777                    v1.get_type().get_undef(),
3778                    VectorType::const_vector(&shuffle_array),
3779                    "",
3780                ));
3781                let val1 = err!(extend_op(self, val1));
3782                let val2 = err!(self.builder.build_shuffle_vector(
3783                    v2,
3784                    v2.get_type().get_undef(),
3785                    VectorType::const_vector(&shuffle_array),
3786                    "",
3787                ));
3788                let val2 = err!(extend_op(self, val2));
3789                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3790                let res = err!(
3791                    self.builder
3792                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3793                );
3794                self.state.push1(res);
3795            }
3796            Operator::I32x4DotI16x8S => {
3797                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3798                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3799                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3800                let low_i16 = [
3801                    self.intrinsics.i32_consts[0],
3802                    self.intrinsics.i32_consts[2],
3803                    self.intrinsics.i32_consts[4],
3804                    self.intrinsics.i32_consts[6],
3805                ];
3806                let high_i16 = [
3807                    self.intrinsics.i32_consts[1],
3808                    self.intrinsics.i32_consts[3],
3809                    self.intrinsics.i32_consts[5],
3810                    self.intrinsics.i32_consts[7],
3811                ];
3812                let v1_low = err!(self.builder.build_shuffle_vector(
3813                    v1,
3814                    v1.get_type().get_undef(),
3815                    VectorType::const_vector(&low_i16),
3816                    "",
3817                ));
3818                let v1_low = err!(self.builder.build_int_s_extend(
3819                    v1_low,
3820                    self.intrinsics.i32x4_ty,
3821                    ""
3822                ));
3823                let v1_high = err!(self.builder.build_shuffle_vector(
3824                    v1,
3825                    v1.get_type().get_undef(),
3826                    VectorType::const_vector(&high_i16),
3827                    "",
3828                ));
3829                let v1_high = err!(self.builder.build_int_s_extend(
3830                    v1_high,
3831                    self.intrinsics.i32x4_ty,
3832                    ""
3833                ));
3834                let v2_low = err!(self.builder.build_shuffle_vector(
3835                    v2,
3836                    v2.get_type().get_undef(),
3837                    VectorType::const_vector(&low_i16),
3838                    "",
3839                ));
3840                let v2_low = err!(self.builder.build_int_s_extend(
3841                    v2_low,
3842                    self.intrinsics.i32x4_ty,
3843                    ""
3844                ));
3845                let v2_high = err!(self.builder.build_shuffle_vector(
3846                    v2,
3847                    v2.get_type().get_undef(),
3848                    VectorType::const_vector(&high_i16),
3849                    "",
3850                ));
3851                let v2_high = err!(self.builder.build_int_s_extend(
3852                    v2_high,
3853                    self.intrinsics.i32x4_ty,
3854                    ""
3855                ));
3856                let low_product = err!(self.builder.build_int_mul(v1_low, v2_low, ""));
3857                let high_product = err!(self.builder.build_int_mul(v1_high, v2_high, ""));
3858
3859                let res = err!(self.builder.build_int_add(low_product, high_product, ""));
3860                let res = err!(
3861                    self.builder
3862                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3863                );
3864                self.state.push1(res);
3865            }
3866            Operator::I32DivS | Operator::I64DivS => {
3867                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3868                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3869                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3870                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3871
3872                self.trap_if_zero_or_overflow(v1, v2)?;
3873
3874                let res = err!(self.builder.build_int_signed_div(v1, v2, ""));
3875                self.state.push1(res);
3876            }
3877            Operator::I32DivU | Operator::I64DivU => {
3878                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3879                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3880                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3881                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3882
3883                self.trap_if_zero(v2)?;
3884
3885                let res = err!(self.builder.build_int_unsigned_div(v1, v2, ""));
3886                self.state.push1(res);
3887            }
3888            Operator::I32RemS | Operator::I64RemS => {
3889                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3890                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3891                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3892                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3893                let int_type = v1.get_type();
3894                let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
3895                    let min_value = int_type.const_int(i32::MIN as u64, false);
3896                    let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
3897                    (min_value, neg_one_value)
3898                } else if int_type == self.intrinsics.i64_ty {
3899                    let min_value = int_type.const_int(i64::MIN as u64, false);
3900                    let neg_one_value = int_type.const_int(-1i64 as u64, false);
3901                    (min_value, neg_one_value)
3902                } else {
3903                    unreachable!()
3904                };
3905
3906                self.trap_if_zero(v2)?;
3907
3908                // "Overflow also leads to undefined behavior; this is a rare
3909                // case, but can occur, for example, by taking the remainder of
3910                // a 32-bit division of -2147483648 by -1. (The remainder
3911                // doesn’t actually overflow, but this rule lets srem be
3912                // implemented using instructions that return both the result
3913                // of the division and the remainder.)"
3914                //   -- https://llvm.org/docs/LangRef.html#srem-instruction
3915                //
3916                // In Wasm, the i32.rem_s i32.const -2147483648 i32.const -1 is
3917                // i32.const 0. We implement this by swapping out the left value
3918                // for 0 in this case.
3919                let will_overflow = err!(self.builder.build_and(
3920                    err!(self.builder.build_int_compare(
3921                        IntPredicate::EQ,
3922                        v1,
3923                        min_value,
3924                        "left_is_min"
3925                    )),
3926                    err!(self.builder.build_int_compare(
3927                        IntPredicate::EQ,
3928                        v2,
3929                        neg_one_value,
3930                        "right_is_neg_one",
3931                    )),
3932                    "srem_will_overflow",
3933                ));
3934                let v1 =
3935                    err!(
3936                        self.builder
3937                            .build_select(will_overflow, int_type.const_zero(), v1, "")
3938                    )
3939                    .into_int_value();
3940                let res = err!(self.builder.build_int_signed_rem(v1, v2, ""));
3941                self.state.push1(res);
3942            }
3943            Operator::I32RemU | Operator::I64RemU => {
3944                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3945                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3946                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3947                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3948
3949                self.trap_if_zero(v2)?;
3950
3951                let res = err!(self.builder.build_int_unsigned_rem(v1, v2, ""));
3952                self.state.push1(res);
3953            }
3954            Operator::I32And | Operator::I64And | Operator::V128And => {
3955                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3956                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3957                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3958                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3959                let res = err!(self.builder.build_and(v1, v2, ""));
3960                self.state.push1(res);
3961            }
3962            Operator::I32Or | Operator::I64Or | Operator::V128Or => {
3963                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3964                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3965                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3966                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3967                let res = err!(self.builder.build_or(v1, v2, ""));
3968                self.state.push1(res);
3969            }
3970            Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
3971                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3972                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3973                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3974                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3975                let res = err!(self.builder.build_xor(v1, v2, ""));
3976                self.state.push1(res);
3977            }
3978            Operator::V128AndNot => {
3979                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3980                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3981                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3982                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3983                let v2 = err!(self.builder.build_not(v2, ""));
3984                let res = err!(self.builder.build_and(v1, v2, ""));
3985                self.state.push1(res);
3986            }
3987            Operator::V128Bitselect => {
3988                let ((v1, i1), (v2, i2), (cond, cond_info)) = self.state.pop3_extra()?;
3989                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3990                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3991                let cond = self.apply_pending_canonicalization(cond, cond_info)?;
3992                let v1 = err!(
3993                    self.builder
3994                        .build_bit_cast(v1, self.intrinsics.i1x128_ty, "")
3995                )
3996                .into_vector_value();
3997                let v2 = err!(
3998                    self.builder
3999                        .build_bit_cast(v2, self.intrinsics.i1x128_ty, "")
4000                )
4001                .into_vector_value();
4002                let cond = err!(
4003                    self.builder
4004                        .build_bit_cast(cond, self.intrinsics.i1x128_ty, "")
4005                )
4006                .into_vector_value();
4007                let res = err!(self.builder.build_select(cond, v1, v2, ""));
4008                let res = err!(
4009                    self.builder
4010                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4011                );
4012                self.state.push1(res);
4013            }
4014            Operator::I8x16Bitmask => {
4015                let (v, i) = self.state.pop1_extra()?;
4016                let (v, _) = self.v128_into_i8x16(v, i)?;
4017
4018                let zeros = self.intrinsics.i8x16_ty.const_zero();
4019                let res = err!(
4020                    self.builder
4021                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4022                );
4023                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i16_ty, ""))
4024                    .into_int_value();
4025                let res = err!(
4026                    self.builder
4027                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4028                );
4029                self.state.push1(res);
4030            }
4031            Operator::I16x8Bitmask => {
4032                let (v, i) = self.state.pop1_extra()?;
4033                let (v, _) = self.v128_into_i16x8(v, i)?;
4034
4035                let zeros = self.intrinsics.i16x8_ty.const_zero();
4036                let res = err!(
4037                    self.builder
4038                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4039                );
4040                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i8_ty, ""))
4041                    .into_int_value();
4042                let res = err!(
4043                    self.builder
4044                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4045                );
4046                self.state.push1(res);
4047            }
4048            Operator::I32x4Bitmask => {
4049                let (v, i) = self.state.pop1_extra()?;
4050                let (v, _) = self.v128_into_i32x4(v, i)?;
4051
4052                let zeros = self.intrinsics.i32x4_ty.const_zero();
4053                let res = err!(
4054                    self.builder
4055                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4056                );
4057                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i4_ty, ""))
4058                    .into_int_value();
4059                let res = err!(
4060                    self.builder
4061                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4062                );
4063                self.state.push1(res);
4064            }
4065            Operator::I64x2Bitmask => {
4066                let (v, i) = self.state.pop1_extra()?;
4067                let (v, _) = self.v128_into_i64x2(v, i)?;
4068
4069                let zeros = self.intrinsics.i64x2_ty.const_zero();
4070                let res = err!(
4071                    self.builder
4072                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4073                );
4074                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i2_ty, ""))
4075                    .into_int_value();
4076                let res = err!(
4077                    self.builder
4078                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4079                );
4080                self.state.push1(res);
4081            }
4082            Operator::I32Shl => {
4083                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4084                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4085                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4086                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4087                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4088                let v2 = err!(self.builder.build_and(v2, mask, ""));
4089                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4090                self.state.push1(res);
4091            }
4092            Operator::I64Shl => {
4093                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4094                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4095                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4096                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4097                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4098                let v2 = err!(self.builder.build_and(v2, mask, ""));
4099                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4100                self.state.push1(res);
4101            }
4102            Operator::I8x16Shl => {
4103                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4104                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4105                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4106                let v2 = v2.into_int_value();
4107                let v2 = err!(
4108                    self.builder
4109                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4110                );
4111                let v2 = err!(
4112                    self.builder
4113                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4114                );
4115                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4116                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4117                let res = err!(
4118                    self.builder
4119                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4120                );
4121                self.state.push1(res);
4122            }
4123            Operator::I16x8Shl => {
4124                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4125                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4126                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4127                let v2 = v2.into_int_value();
4128                let v2 = err!(
4129                    self.builder
4130                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4131                );
4132                let v2 = err!(
4133                    self.builder
4134                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4135                );
4136                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4137                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4138                let res = err!(
4139                    self.builder
4140                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4141                );
4142                self.state.push1(res);
4143            }
4144            Operator::I32x4Shl => {
4145                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4146                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4147                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4148                let v2 = v2.into_int_value();
4149                let v2 = err!(self.builder.build_and(
4150                    v2,
4151                    self.intrinsics.i32_ty.const_int(31, false),
4152                    ""
4153                ));
4154                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4155                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4156                let res = err!(
4157                    self.builder
4158                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4159                );
4160                self.state.push1(res);
4161            }
4162            Operator::I64x2Shl => {
4163                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4164                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4165                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4166                let v2 = v2.into_int_value();
4167                let v2 = err!(self.builder.build_and(
4168                    v2,
4169                    self.intrinsics.i32_ty.const_int(63, false),
4170                    ""
4171                ));
4172                let v2 = err!(
4173                    self.builder
4174                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4175                );
4176                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4177                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4178                let res = err!(
4179                    self.builder
4180                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4181                );
4182                self.state.push1(res);
4183            }
4184            Operator::I32ShrS => {
4185                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4186                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4187                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4188                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4189                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4190                let v2 = err!(self.builder.build_and(v2, mask, ""));
4191                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4192                self.state.push1(res);
4193            }
4194            Operator::I64ShrS => {
4195                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4196                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4197                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4198                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4199                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4200                let v2 = err!(self.builder.build_and(v2, mask, ""));
4201                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4202                self.state.push1(res);
4203            }
4204            Operator::I8x16ShrS => {
4205                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4206                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4207                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4208                let v2 = v2.into_int_value();
4209                let v2 = err!(
4210                    self.builder
4211                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4212                );
4213                let v2 = err!(
4214                    self.builder
4215                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4216                );
4217                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4218                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4219                let res = err!(
4220                    self.builder
4221                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4222                );
4223                self.state.push1(res);
4224            }
4225            Operator::I16x8ShrS => {
4226                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4227                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4228                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4229                let v2 = v2.into_int_value();
4230                let v2 = err!(
4231                    self.builder
4232                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4233                );
4234                let v2 = err!(
4235                    self.builder
4236                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4237                );
4238                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4239                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4240                let res = err!(
4241                    self.builder
4242                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4243                );
4244                self.state.push1(res);
4245            }
4246            Operator::I32x4ShrS => {
4247                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4248                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4249                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4250                let v2 = v2.into_int_value();
4251                let v2 = err!(self.builder.build_and(
4252                    v2,
4253                    self.intrinsics.i32_ty.const_int(31, false),
4254                    ""
4255                ));
4256                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4257                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4258                let res = err!(
4259                    self.builder
4260                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4261                );
4262                self.state.push1(res);
4263            }
4264            Operator::I64x2ShrS => {
4265                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4266                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4267                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4268                let v2 = v2.into_int_value();
4269                let v2 = err!(self.builder.build_and(
4270                    v2,
4271                    self.intrinsics.i32_ty.const_int(63, false),
4272                    ""
4273                ));
4274                let v2 = err!(
4275                    self.builder
4276                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4277                );
4278                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4279                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4280                let res = err!(
4281                    self.builder
4282                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4283                );
4284                self.state.push1(res);
4285            }
4286            Operator::I32ShrU => {
4287                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4288                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4289                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4290                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4291                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4292                let v2 = err!(self.builder.build_and(v2, mask, ""));
4293                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4294                self.state.push1(res);
4295            }
4296            Operator::I64ShrU => {
4297                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4298                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4299                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4300                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4301                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4302                let v2 = err!(self.builder.build_and(v2, mask, ""));
4303                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4304                self.state.push1(res);
4305            }
4306            Operator::I8x16ShrU => {
4307                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4308                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4309                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4310                let v2 = v2.into_int_value();
4311                let v2 = err!(
4312                    self.builder
4313                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4314                );
4315                let v2 = err!(
4316                    self.builder
4317                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4318                );
4319                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4320                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4321                let res = err!(
4322                    self.builder
4323                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4324                );
4325                self.state.push1(res);
4326            }
4327            Operator::I16x8ShrU => {
4328                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4329                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4330                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4331                let v2 = v2.into_int_value();
4332                let v2 = err!(
4333                    self.builder
4334                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4335                );
4336                let v2 = err!(
4337                    self.builder
4338                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4339                );
4340                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4341                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4342                let res = err!(
4343                    self.builder
4344                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4345                );
4346                self.state.push1(res);
4347            }
4348            Operator::I32x4ShrU => {
4349                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4350                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4351                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4352                let v2 = v2.into_int_value();
4353                let v2 = err!(self.builder.build_and(
4354                    v2,
4355                    self.intrinsics.i32_ty.const_int(31, false),
4356                    ""
4357                ));
4358                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4359                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4360                let res = err!(
4361                    self.builder
4362                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4363                );
4364                self.state.push1(res);
4365            }
4366            Operator::I64x2ShrU => {
4367                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4368                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4369                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4370                let v2 = v2.into_int_value();
4371                let v2 = err!(self.builder.build_and(
4372                    v2,
4373                    self.intrinsics.i32_ty.const_int(63, false),
4374                    ""
4375                ));
4376                let v2 = err!(
4377                    self.builder
4378                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4379                );
4380                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4381                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4382                let res = err!(
4383                    self.builder
4384                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4385                );
4386                self.state.push1(res);
4387            }
4388            Operator::I32Rotl => {
4389                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4390                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4391                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4392                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4393                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4394                let v2 = err!(self.builder.build_and(v2, mask, ""));
4395                let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4396                let rhs = {
4397                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4398                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4399                    err!(self.builder.build_right_shift(v1, rhs, false, ""))
4400                };
4401                let res = err!(self.builder.build_or(lhs, rhs, ""));
4402                self.state.push1(res);
4403            }
4404            Operator::I64Rotl => {
4405                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4406                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4407                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4408                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4409                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4410                let v2 = err!(self.builder.build_and(v2, mask, ""));
4411                let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4412                let rhs = {
4413                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4414                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4415                    err!(self.builder.build_right_shift(v1, rhs, false, ""))
4416                };
4417                let res = err!(self.builder.build_or(lhs, rhs, ""));
4418                self.state.push1(res);
4419            }
4420            Operator::I32Rotr => {
4421                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4422                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4423                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4424                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4425                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4426                let v2 = err!(self.builder.build_and(v2, mask, ""));
4427                let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4428                let rhs = {
4429                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4430                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4431                    err!(self.builder.build_left_shift(v1, rhs, ""))
4432                };
4433                let res = err!(self.builder.build_or(lhs, rhs, ""));
4434                self.state.push1(res);
4435            }
4436            Operator::I64Rotr => {
4437                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4438                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4439                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4440                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4441                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4442                let v2 = err!(self.builder.build_and(v2, mask, ""));
4443                let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4444                let rhs = {
4445                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4446                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4447                    err!(self.builder.build_left_shift(v1, rhs, ""))
4448                };
4449                let res = err!(self.builder.build_or(lhs, rhs, ""));
4450                self.state.push1(res);
4451            }
4452            Operator::I32Clz => {
4453                let (input, info) = self.state.pop1_extra()?;
4454                let input = self.apply_pending_canonicalization(input, info)?;
4455                let is_zero_undef = self.intrinsics.i1_zero;
4456                let res = err!(self.builder.build_call(
4457                    self.intrinsics.ctlz_i32,
4458                    &[input.into(), is_zero_undef.into()],
4459                    "",
4460                ))
4461                .try_as_basic_value()
4462                .unwrap_basic();
4463                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4464            }
4465            Operator::I64Clz => {
4466                let (input, info) = self.state.pop1_extra()?;
4467                let input = self.apply_pending_canonicalization(input, info)?;
4468                let is_zero_undef = self.intrinsics.i1_zero;
4469                let res = err!(self.builder.build_call(
4470                    self.intrinsics.ctlz_i64,
4471                    &[input.into(), is_zero_undef.into()],
4472                    "",
4473                ))
4474                .try_as_basic_value()
4475                .unwrap_basic();
4476                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4477            }
4478            Operator::I32Ctz => {
4479                let (input, info) = self.state.pop1_extra()?;
4480                let input = self.apply_pending_canonicalization(input, info)?;
4481                let is_zero_undef = self.intrinsics.i1_zero;
4482                let res = err!(self.builder.build_call(
4483                    self.intrinsics.cttz_i32,
4484                    &[input.into(), is_zero_undef.into()],
4485                    "",
4486                ))
4487                .try_as_basic_value()
4488                .unwrap_basic();
4489                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4490            }
4491            Operator::I64Ctz => {
4492                let (input, info) = self.state.pop1_extra()?;
4493                let input = self.apply_pending_canonicalization(input, info)?;
4494                let is_zero_undef = self.intrinsics.i1_zero;
4495                let res = err!(self.builder.build_call(
4496                    self.intrinsics.cttz_i64,
4497                    &[input.into(), is_zero_undef.into()],
4498                    "",
4499                ))
4500                .try_as_basic_value()
4501                .unwrap_basic();
4502                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4503            }
4504            Operator::I8x16Popcnt => {
4505                let (v, i) = self.state.pop1_extra()?;
4506                let (v, _) = self.v128_into_i8x16(v, i)?;
4507                let res = err!(self.builder.build_call(
4508                    self.intrinsics.ctpop_i8x16,
4509                    &[v.into()],
4510                    ""
4511                ))
4512                .try_as_basic_value()
4513                .unwrap_basic();
4514                let res = err!(
4515                    self.builder
4516                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4517                );
4518                self.state.push1(res);
4519            }
4520            Operator::I32Popcnt => {
4521                let (input, info) = self.state.pop1_extra()?;
4522                let input = self.apply_pending_canonicalization(input, info)?;
4523                let res = err!(self.builder.build_call(
4524                    self.intrinsics.ctpop_i32,
4525                    &[input.into()],
4526                    ""
4527                ))
4528                .try_as_basic_value()
4529                .unwrap_basic();
4530                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4531            }
4532            Operator::I64Popcnt => {
4533                let (input, info) = self.state.pop1_extra()?;
4534                let input = self.apply_pending_canonicalization(input, info)?;
4535                let res = err!(self.builder.build_call(
4536                    self.intrinsics.ctpop_i64,
4537                    &[input.into()],
4538                    ""
4539                ))
4540                .try_as_basic_value()
4541                .unwrap_basic();
4542                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4543            }
4544            Operator::I32Eqz => {
4545                let input = self.state.pop1()?.into_int_value();
4546                let cond = err!(self.builder.build_int_compare(
4547                    IntPredicate::EQ,
4548                    input,
4549                    self.intrinsics.i32_zero,
4550                    "",
4551                ));
4552                let res = err!(
4553                    self.builder
4554                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4555                );
4556                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4557            }
4558            Operator::I64Eqz => {
4559                let input = self.state.pop1()?.into_int_value();
4560                let cond = err!(self.builder.build_int_compare(
4561                    IntPredicate::EQ,
4562                    input,
4563                    self.intrinsics.i64_zero,
4564                    "",
4565                ));
4566                let res = err!(
4567                    self.builder
4568                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4569                );
4570                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4571            }
4572            Operator::I8x16Abs => {
4573                let (v, i) = self.state.pop1_extra()?;
4574                let (v, _) = self.v128_into_i8x16(v, i)?;
4575
4576                let seven = self.intrinsics.i8_ty.const_int(7, false);
4577                let seven = VectorType::const_vector(&[seven; 16]);
4578                let all_sign_bits = err!(self.builder.build_right_shift(v, seven, true, ""));
4579                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4580                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4581                let res = err!(
4582                    self.builder
4583                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4584                );
4585                self.state.push1(res);
4586            }
4587            Operator::I16x8Abs => {
4588                let (v, i) = self.state.pop1_extra()?;
4589                let (v, _) = self.v128_into_i16x8(v, i)?;
4590
4591                let fifteen = self.intrinsics.i16_ty.const_int(15, false);
4592                let fifteen = VectorType::const_vector(&[fifteen; 8]);
4593                let all_sign_bits = err!(self.builder.build_right_shift(v, fifteen, true, ""));
4594                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4595                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4596                let res = err!(
4597                    self.builder
4598                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4599                );
4600                self.state.push1(res);
4601            }
4602            Operator::I32x4Abs => {
4603                let (v, i) = self.state.pop1_extra()?;
4604                let (v, _) = self.v128_into_i32x4(v, i)?;
4605
4606                let thirtyone = self.intrinsics.i32_ty.const_int(31, false);
4607                let thirtyone = VectorType::const_vector(&[thirtyone; 4]);
4608                let all_sign_bits = err!(self.builder.build_right_shift(v, thirtyone, true, ""));
4609                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4610                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4611                let res = err!(
4612                    self.builder
4613                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4614                );
4615                self.state.push1(res);
4616            }
4617            Operator::I64x2Abs => {
4618                let (v, i) = self.state.pop1_extra()?;
4619                let (v, _) = self.v128_into_i64x2(v, i)?;
4620
4621                let sixtythree = self.intrinsics.i64_ty.const_int(63, false);
4622                let sixtythree = VectorType::const_vector(&[sixtythree; 2]);
4623                let all_sign_bits = err!(self.builder.build_right_shift(v, sixtythree, true, ""));
4624                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4625                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4626                let res = err!(
4627                    self.builder
4628                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4629                );
4630                self.state.push1(res);
4631            }
4632            Operator::I8x16MinS => {
4633                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4634                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4635                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4636                let cmp = err!(
4637                    self.builder
4638                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4639                );
4640                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4641                let res = err!(
4642                    self.builder
4643                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4644                );
4645                self.state.push1(res);
4646            }
4647            Operator::I8x16MinU => {
4648                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4649                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4650                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4651                let cmp = err!(
4652                    self.builder
4653                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4654                );
4655                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4656                let res = err!(
4657                    self.builder
4658                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4659                );
4660                self.state.push1(res);
4661            }
4662            Operator::I8x16MaxS => {
4663                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4664                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4665                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4666                let cmp = err!(
4667                    self.builder
4668                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4669                );
4670                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4671                let res = err!(
4672                    self.builder
4673                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4674                );
4675                self.state.push1(res);
4676            }
4677            Operator::I8x16MaxU => {
4678                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4679                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4680                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4681                let cmp = err!(
4682                    self.builder
4683                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4684                );
4685                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4686                let res = err!(
4687                    self.builder
4688                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4689                );
4690                self.state.push1(res);
4691            }
4692            Operator::I16x8MinS => {
4693                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4694                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4695                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4696                let cmp = err!(
4697                    self.builder
4698                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4699                );
4700                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4701                let res = err!(
4702                    self.builder
4703                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4704                );
4705                self.state.push1(res);
4706            }
4707            Operator::I16x8MinU => {
4708                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4709                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4710                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4711                let cmp = err!(
4712                    self.builder
4713                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4714                );
4715                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4716                let res = err!(
4717                    self.builder
4718                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4719                );
4720                self.state.push1(res);
4721            }
4722            Operator::I16x8MaxS => {
4723                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4724                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4725                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4726                let cmp = err!(
4727                    self.builder
4728                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4729                );
4730                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4731                let res = err!(
4732                    self.builder
4733                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4734                );
4735                self.state.push1(res);
4736            }
4737            Operator::I16x8MaxU => {
4738                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4739                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4740                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4741                let cmp = err!(
4742                    self.builder
4743                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4744                );
4745                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4746                let res = err!(
4747                    self.builder
4748                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4749                );
4750                self.state.push1(res);
4751            }
4752            Operator::I32x4MinS => {
4753                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4754                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4755                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4756                let cmp = err!(
4757                    self.builder
4758                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4759                );
4760                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4761                let res = err!(
4762                    self.builder
4763                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4764                );
4765                self.state.push1(res);
4766            }
4767            Operator::I32x4MinU => {
4768                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4769                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4770                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4771                let cmp = err!(
4772                    self.builder
4773                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4774                );
4775                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4776                let res = err!(
4777                    self.builder
4778                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4779                );
4780                self.state.push1(res);
4781            }
4782            Operator::I32x4MaxS => {
4783                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4784                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4785                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4786                let cmp = err!(
4787                    self.builder
4788                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4789                );
4790                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4791                let res = err!(
4792                    self.builder
4793                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4794                );
4795                self.state.push1(res);
4796            }
4797            Operator::I32x4MaxU => {
4798                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4799                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4800                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4801                let cmp = err!(
4802                    self.builder
4803                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4804                );
4805                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4806                let res = err!(
4807                    self.builder
4808                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4809                );
4810                self.state.push1(res);
4811            }
4812            Operator::I8x16AvgrU => {
4813                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4814                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4815                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4816
4817                // This approach is faster on x86-64 when the PAVG[BW]
4818                // instructions are available. On other platforms, an alternative
4819                // implementation appears likely to outperform, described here:
4820                //   %a = or %v1, %v2
4821                //   %b = and %a, 1
4822                //   %v1 = lshr %v1, 1
4823                //   %v2 = lshr %v2, 1
4824                //   %sum = add %v1, %v2
4825                //   %res = add %sum, %b
4826
4827                let ext_ty = self.intrinsics.i16_ty.vec_type(16);
4828                let one = self.intrinsics.i16_ty.const_int(1, false);
4829                let one = VectorType::const_vector(&[one; 16]);
4830
4831                let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4832                let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4833                let res = err!(self.builder.build_int_add(
4834                    err!(self.builder.build_int_add(one, v1, "")),
4835                    v2,
4836                    ""
4837                ));
4838                let res = err!(self.builder.build_right_shift(res, one, false, ""));
4839                let res = err!(
4840                    self.builder
4841                        .build_int_truncate(res, self.intrinsics.i8x16_ty, "")
4842                );
4843                let res = err!(
4844                    self.builder
4845                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4846                );
4847                self.state.push1(res);
4848            }
4849            Operator::I16x8AvgrU => {
4850                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4851                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4852                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4853
4854                // This approach is faster on x86-64 when the PAVG[BW]
4855                // instructions are available. On other platforms, an alternative
4856                // implementation appears likely to outperform, described here:
4857                //   %a = or %v1, %v2
4858                //   %b = and %a, 1
4859                //   %v1 = lshr %v1, 1
4860                //   %v2 = lshr %v2, 1
4861                //   %sum = add %v1, %v2
4862                //   %res = add %sum, %b
4863
4864                let ext_ty = self.intrinsics.i32_ty.vec_type(8);
4865                let one = self.intrinsics.i32_consts[1];
4866                let one = VectorType::const_vector(&[one; 8]);
4867
4868                let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4869                let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4870                let res = err!(self.builder.build_int_add(
4871                    err!(self.builder.build_int_add(one, v1, "")),
4872                    v2,
4873                    ""
4874                ));
4875                let res = err!(self.builder.build_right_shift(res, one, false, ""));
4876                let res = err!(
4877                    self.builder
4878                        .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
4879                );
4880                let res = err!(
4881                    self.builder
4882                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4883                );
4884                self.state.push1(res);
4885            }
4886
4887            /***************************
4888             * Floating-Point Arithmetic instructions.
4889             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-arithmetic-instructions
4890             ***************************/
4891            Operator::F32Add => {
4892                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4893                let res = err!(self.builder.build_call(
4894                    self.intrinsics.add_f32,
4895                    &[
4896                        v1.into(),
4897                        v2.into(),
4898                        self.intrinsics.fp_rounding_md,
4899                        self.intrinsics.fp_exception_md,
4900                    ],
4901                    "",
4902                ))
4903                .try_as_basic_value()
4904                .unwrap_basic();
4905                self.state.push1_extra(
4906                    res,
4907                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4908                );
4909            }
4910            Operator::F64Add => {
4911                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4912                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4913                let res = err!(self.builder.build_call(
4914                    self.intrinsics.add_f64,
4915                    &[
4916                        v1.into(),
4917                        v2.into(),
4918                        self.intrinsics.fp_rounding_md,
4919                        self.intrinsics.fp_exception_md,
4920                    ],
4921                    "",
4922                ))
4923                .try_as_basic_value()
4924                .unwrap_basic();
4925                self.state.push1_extra(
4926                    res,
4927                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4928                );
4929            }
4930            Operator::F32x4Add => {
4931                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4932                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4933                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4934                let res = err!(self.builder.build_call(
4935                    self.intrinsics.add_f32x4,
4936                    &[
4937                        v1.into(),
4938                        v2.into(),
4939                        self.intrinsics.fp_rounding_md,
4940                        self.intrinsics.fp_exception_md,
4941                    ],
4942                    "",
4943                ))
4944                .try_as_basic_value()
4945                .unwrap_basic();
4946                let res = err!(
4947                    self.builder
4948                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4949                );
4950                self.state.push1_extra(
4951                    res,
4952                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4953                );
4954            }
4955            Operator::F64x2Add => {
4956                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4957                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
4958                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
4959                let res = err!(self.builder.build_call(
4960                    self.intrinsics.add_f64x2,
4961                    &[
4962                        v1.into(),
4963                        v2.into(),
4964                        self.intrinsics.fp_rounding_md,
4965                        self.intrinsics.fp_exception_md,
4966                    ],
4967                    "",
4968                ))
4969                .try_as_basic_value()
4970                .unwrap_basic();
4971                let res = err!(
4972                    self.builder
4973                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4974                );
4975                self.state.push1_extra(
4976                    res,
4977                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4978                );
4979            }
4980            Operator::F32Sub => {
4981                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4982                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4983                let res = err!(self.builder.build_call(
4984                    self.intrinsics.sub_f32,
4985                    &[
4986                        v1.into(),
4987                        v2.into(),
4988                        self.intrinsics.fp_rounding_md,
4989                        self.intrinsics.fp_exception_md,
4990                    ],
4991                    "",
4992                ))
4993                .try_as_basic_value()
4994                .unwrap_basic();
4995                self.state.push1_extra(
4996                    res,
4997                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4998                );
4999            }
5000            Operator::F64Sub => {
5001                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5002                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5003                let res = err!(self.builder.build_call(
5004                    self.intrinsics.sub_f64,
5005                    &[
5006                        v1.into(),
5007                        v2.into(),
5008                        self.intrinsics.fp_rounding_md,
5009                        self.intrinsics.fp_exception_md,
5010                    ],
5011                    "",
5012                ))
5013                .try_as_basic_value()
5014                .unwrap_basic();
5015                self.state.push1_extra(
5016                    res,
5017                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5018                );
5019            }
5020            Operator::F32x4Sub => {
5021                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5022                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5023                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5024                let res = err!(self.builder.build_call(
5025                    self.intrinsics.sub_f32x4,
5026                    &[
5027                        v1.into(),
5028                        v2.into(),
5029                        self.intrinsics.fp_rounding_md,
5030                        self.intrinsics.fp_exception_md,
5031                    ],
5032                    "",
5033                ))
5034                .try_as_basic_value()
5035                .unwrap_basic();
5036                let res = err!(
5037                    self.builder
5038                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5039                );
5040                self.state.push1_extra(
5041                    res,
5042                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5043                );
5044            }
5045            Operator::F64x2Sub => {
5046                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5047                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5048                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5049                let res = err!(self.builder.build_call(
5050                    self.intrinsics.sub_f64x2,
5051                    &[
5052                        v1.into(),
5053                        v2.into(),
5054                        self.intrinsics.fp_rounding_md,
5055                        self.intrinsics.fp_exception_md,
5056                    ],
5057                    "",
5058                ))
5059                .try_as_basic_value()
5060                .unwrap_basic();
5061                let res = err!(
5062                    self.builder
5063                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5064                );
5065                self.state.push1_extra(
5066                    res,
5067                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5068                );
5069            }
5070            Operator::F32Mul => {
5071                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5072                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5073                let res = err!(self.builder.build_call(
5074                    self.intrinsics.mul_f32,
5075                    &[
5076                        v1.into(),
5077                        v2.into(),
5078                        self.intrinsics.fp_rounding_md,
5079                        self.intrinsics.fp_exception_md,
5080                    ],
5081                    "",
5082                ))
5083                .try_as_basic_value()
5084                .unwrap_basic();
5085                self.state.push1_extra(
5086                    res,
5087                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5088                );
5089            }
5090            Operator::F64Mul => {
5091                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5092                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5093                let res = err!(self.builder.build_call(
5094                    self.intrinsics.mul_f64,
5095                    &[
5096                        v1.into(),
5097                        v2.into(),
5098                        self.intrinsics.fp_rounding_md,
5099                        self.intrinsics.fp_exception_md,
5100                    ],
5101                    "",
5102                ))
5103                .try_as_basic_value()
5104                .unwrap_basic();
5105                self.state.push1_extra(
5106                    res,
5107                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5108                );
5109            }
5110            Operator::F32x4Mul => {
5111                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5112                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5113                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5114                let res = err!(self.builder.build_call(
5115                    self.intrinsics.mul_f32x4,
5116                    &[
5117                        v1.into(),
5118                        v2.into(),
5119                        self.intrinsics.fp_rounding_md,
5120                        self.intrinsics.fp_exception_md,
5121                    ],
5122                    "",
5123                ))
5124                .try_as_basic_value()
5125                .unwrap_basic();
5126                let res = err!(
5127                    self.builder
5128                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5129                );
5130                self.state.push1_extra(
5131                    res,
5132                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5133                );
5134            }
5135            Operator::F64x2Mul => {
5136                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5137                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5138                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5139                let res = err!(self.builder.build_call(
5140                    self.intrinsics.mul_f64x2,
5141                    &[
5142                        v1.into(),
5143                        v2.into(),
5144                        self.intrinsics.fp_rounding_md,
5145                        self.intrinsics.fp_exception_md,
5146                    ],
5147                    "",
5148                ))
5149                .try_as_basic_value()
5150                .unwrap_basic();
5151                let res = err!(
5152                    self.builder
5153                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5154                );
5155                self.state.push1_extra(
5156                    res,
5157                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5158                );
5159            }
5160            Operator::F32Div => {
5161                let (v1, v2) = self.state.pop2()?;
5162                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5163                let res = err!(self.builder.build_call(
5164                    self.intrinsics.div_f32,
5165                    &[
5166                        v1.into(),
5167                        v2.into(),
5168                        self.intrinsics.fp_rounding_md,
5169                        self.intrinsics.fp_exception_md,
5170                    ],
5171                    "",
5172                ))
5173                .try_as_basic_value()
5174                .unwrap_basic();
5175                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5176            }
5177            Operator::F64Div => {
5178                let (v1, v2) = self.state.pop2()?;
5179                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5180                let res = err!(self.builder.build_call(
5181                    self.intrinsics.div_f64,
5182                    &[
5183                        v1.into(),
5184                        v2.into(),
5185                        self.intrinsics.fp_rounding_md,
5186                        self.intrinsics.fp_exception_md,
5187                    ],
5188                    "",
5189                ))
5190                .try_as_basic_value()
5191                .unwrap_basic();
5192                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5193            }
5194            Operator::F32x4Div => {
5195                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5196                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5197                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5198                let res = err!(self.builder.build_call(
5199                    self.intrinsics.div_f32x4,
5200                    &[
5201                        v1.into(),
5202                        v2.into(),
5203                        self.intrinsics.fp_rounding_md,
5204                        self.intrinsics.fp_exception_md,
5205                    ],
5206                    "",
5207                ))
5208                .try_as_basic_value()
5209                .unwrap_basic();
5210                let res = err!(
5211                    self.builder
5212                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5213                );
5214                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5215            }
5216            Operator::F64x2Div => {
5217                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5218                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5219                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5220                let res = err!(self.builder.build_call(
5221                    self.intrinsics.div_f64x2,
5222                    &[
5223                        v1.into(),
5224                        v2.into(),
5225                        self.intrinsics.fp_rounding_md,
5226                        self.intrinsics.fp_exception_md,
5227                    ],
5228                    "",
5229                ))
5230                .try_as_basic_value()
5231                .unwrap_basic();
5232                let res = err!(
5233                    self.builder
5234                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5235                );
5236                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5237            }
5238            Operator::F32Sqrt => {
5239                let input = self.state.pop1()?;
5240                let res = err!(self.builder.build_call(
5241                    self.intrinsics.sqrt_f32,
5242                    &[input.into()],
5243                    ""
5244                ))
5245                .try_as_basic_value()
5246                .unwrap_basic();
5247                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5248            }
5249            Operator::F64Sqrt => {
5250                let input = self.state.pop1()?;
5251                let res = err!(self.builder.build_call(
5252                    self.intrinsics.sqrt_f64,
5253                    &[input.into()],
5254                    ""
5255                ))
5256                .try_as_basic_value()
5257                .unwrap_basic();
5258                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5259            }
5260            Operator::F32x4Sqrt => {
5261                let (v, i) = self.state.pop1_extra()?;
5262                let (v, _) = self.v128_into_f32x4(v, i)?;
5263                let res = err!(self.builder.build_call(
5264                    self.intrinsics.sqrt_f32x4,
5265                    &[v.into()],
5266                    ""
5267                ))
5268                .try_as_basic_value()
5269                .unwrap_basic();
5270                let bits = err!(
5271                    self.builder
5272                        .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5273                );
5274                self.state.push1_extra(bits, ExtraInfo::pending_f32_nan());
5275            }
5276            Operator::F64x2Sqrt => {
5277                let (v, i) = self.state.pop1_extra()?;
5278                let (v, _) = self.v128_into_f64x2(v, i)?;
5279                let res = err!(self.builder.build_call(
5280                    self.intrinsics.sqrt_f64x2,
5281                    &[v.into()],
5282                    ""
5283                ))
5284                .try_as_basic_value()
5285                .unwrap_basic();
5286                let bits = err!(
5287                    self.builder
5288                        .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5289                );
5290                self.state.push1(bits);
5291            }
5292            Operator::F32Min => {
5293                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5294                let lhs = self
5295                    .apply_pending_canonicalization(lhs, lhs_info)?
5296                    .into_float_value();
5297                let rhs = self
5298                    .apply_pending_canonicalization(rhs, rhs_info)?
5299                    .into_float_value();
5300
5301                let res = err!(self.builder.build_call(
5302                    self.intrinsics.minimum_f32,
5303                    &[lhs.into(), rhs.into()],
5304                    "",
5305                ))
5306                .try_as_basic_value()
5307                .unwrap_basic();
5308
5309                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5310                let res = res.into_float_value();
5311
5312                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5313            }
5314            Operator::F64Min => {
5315                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5316                let lhs = self
5317                    .apply_pending_canonicalization(lhs, lhs_info)?
5318                    .into_float_value();
5319                let rhs = self
5320                    .apply_pending_canonicalization(rhs, rhs_info)?
5321                    .into_float_value();
5322
5323                let res = err!(self.builder.build_call(
5324                    self.intrinsics.minimum_f64,
5325                    &[lhs.into(), rhs.into()],
5326                    "",
5327                ))
5328                .try_as_basic_value()
5329                .unwrap_basic();
5330
5331                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5332                let res = res.into_float_value();
5333
5334                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5335            }
5336            Operator::F32x4Min => {
5337                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5338                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5339                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5340                let res = err!(self.builder.build_call(
5341                    self.intrinsics.minimum_f32x4,
5342                    &[v1.into(), v2.into()],
5343                    "",
5344                ))
5345                .try_as_basic_value()
5346                .unwrap_basic();
5347
5348                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5349                let res = res.into_vector_value();
5350
5351                let res = err!(
5352                    self.builder
5353                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5354                );
5355                self.state.push1_extra(
5356                    res,
5357                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5358                );
5359            }
5360            Operator::F32x4PMin => {
5361                // Pseudo-min: b < a ? b : a
5362                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5363                let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5364                let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5365                let cmp = err!(
5366                    self.builder
5367                        .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5368                );
5369                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5370                let res = err!(
5371                    self.builder
5372                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5373                );
5374                self.state.push1(res);
5375            }
5376            Operator::F64x2Min => {
5377                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5378                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5379                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5380                let res = err!(self.builder.build_call(
5381                    self.intrinsics.minimum_f64x2,
5382                    &[v1.into(), v2.into()],
5383                    "",
5384                ))
5385                .try_as_basic_value()
5386                .unwrap_basic();
5387
5388                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5389                let res = res.into_vector_value();
5390
5391                let res = err!(
5392                    self.builder
5393                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5394                );
5395                self.state.push1_extra(
5396                    res,
5397                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5398                );
5399            }
5400            Operator::F64x2PMin => {
5401                // Pseudo-min: b < a ? b : a
5402                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5403                let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5404                let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5405                let cmp = err!(
5406                    self.builder
5407                        .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5408                );
5409                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5410                let res = err!(
5411                    self.builder
5412                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5413                );
5414                self.state.push1(res);
5415            }
5416            Operator::F32Max => {
5417                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5418                let lhs = self
5419                    .apply_pending_canonicalization(lhs, lhs_info)?
5420                    .into_float_value();
5421                let rhs = self
5422                    .apply_pending_canonicalization(rhs, rhs_info)?
5423                    .into_float_value();
5424
5425                let res = err!(self.builder.build_call(
5426                    self.intrinsics.maximum_f32,
5427                    &[lhs.into(), rhs.into()],
5428                    "",
5429                ))
5430                .try_as_basic_value()
5431                .unwrap_basic();
5432
5433                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5434                let res = res.into_float_value();
5435
5436                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5437            }
5438            Operator::F64Max => {
5439                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5440                let lhs = self
5441                    .apply_pending_canonicalization(lhs, lhs_info)?
5442                    .into_float_value();
5443                let rhs = self
5444                    .apply_pending_canonicalization(rhs, rhs_info)?
5445                    .into_float_value();
5446
5447                let res = err!(self.builder.build_call(
5448                    self.intrinsics.maximum_f64,
5449                    &[lhs.into(), rhs.into()],
5450                    "",
5451                ))
5452                .try_as_basic_value()
5453                .unwrap_basic();
5454
5455                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5456                let res = res.into_float_value();
5457
5458                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5459            }
5460            Operator::F32x4Max => {
5461                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5462                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5463                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5464                let res = err!(self.builder.build_call(
5465                    self.intrinsics.maximum_f32x4,
5466                    &[v1.into(), v2.into()],
5467                    "",
5468                ))
5469                .try_as_basic_value()
5470                .unwrap_basic();
5471
5472                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5473                let res = res.into_vector_value();
5474
5475                let res = err!(
5476                    self.builder
5477                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5478                );
5479                self.state.push1_extra(
5480                    res,
5481                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5482                );
5483            }
5484            Operator::F32x4PMax => {
5485                // Pseudo-max: a < b ? b : a
5486                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5487                let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5488                let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5489                let cmp = err!(
5490                    self.builder
5491                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5492                );
5493                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5494
5495                let res = err!(
5496                    self.builder
5497                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5498                );
5499                self.state.push1(res);
5500            }
5501            Operator::F64x2Max => {
5502                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5503                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5504                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5505                let res = err!(self.builder.build_call(
5506                    self.intrinsics.maximum_f64x2,
5507                    &[v1.into(), v2.into()],
5508                    "",
5509                ))
5510                .try_as_basic_value()
5511                .unwrap_basic();
5512
5513                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5514                let res = res.into_vector_value();
5515
5516                let res = err!(
5517                    self.builder
5518                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5519                );
5520                self.state.push1_extra(
5521                    res,
5522                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5523                );
5524            }
5525            Operator::F64x2PMax => {
5526                // Pseudo-max: a < b ? b : a
5527                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5528                let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5529                let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5530                let cmp = err!(
5531                    self.builder
5532                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5533                );
5534                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5535                let res = err!(
5536                    self.builder
5537                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5538                );
5539                self.state.push1(res);
5540            }
5541            Operator::F32Ceil => {
5542                let (input, info) = self.state.pop1_extra()?;
5543                let res = err!(self.builder.build_call(
5544                    self.intrinsics.ceil_f32,
5545                    &[input.into()],
5546                    ""
5547                ))
5548                .try_as_basic_value()
5549                .unwrap_basic();
5550                self.state
5551                    .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5552            }
5553            Operator::F32x4Ceil => {
5554                let (v, i) = self.state.pop1_extra()?;
5555                let (v, _) = self.v128_into_f32x4(v, i)?;
5556                let res = err!(self.builder.build_call(
5557                    self.intrinsics.ceil_f32x4,
5558                    &[v.into()],
5559                    ""
5560                ))
5561                .try_as_basic_value()
5562                .unwrap_basic();
5563                let res = err!(
5564                    self.builder
5565                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5566                );
5567                self.state
5568                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5569            }
5570            Operator::F64Ceil => {
5571                let (input, info) = self.state.pop1_extra()?;
5572                let res = err!(self.builder.build_call(
5573                    self.intrinsics.ceil_f64,
5574                    &[input.into()],
5575                    ""
5576                ))
5577                .try_as_basic_value()
5578                .unwrap_basic();
5579                self.state
5580                    .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5581            }
5582            Operator::F64x2Ceil => {
5583                let (v, i) = self.state.pop1_extra()?;
5584                let (v, _) = self.v128_into_f64x2(v, i)?;
5585                let res = err!(self.builder.build_call(
5586                    self.intrinsics.ceil_f64x2,
5587                    &[v.into()],
5588                    ""
5589                ))
5590                .try_as_basic_value()
5591                .unwrap_basic();
5592                let res = err!(
5593                    self.builder
5594                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5595                );
5596                self.state
5597                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5598            }
5599            Operator::F32Floor => {
5600                let (input, info) = self.state.pop1_extra()?;
5601                let res = err!(self.builder.build_call(
5602                    self.intrinsics.floor_f32,
5603                    &[input.into()],
5604                    ""
5605                ))
5606                .try_as_basic_value()
5607                .unwrap_basic();
5608                self.state
5609                    .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5610            }
5611            Operator::F32x4Floor => {
5612                let (v, i) = self.state.pop1_extra()?;
5613                let (v, _) = self.v128_into_f32x4(v, i)?;
5614                let res = err!(self.builder.build_call(
5615                    self.intrinsics.floor_f32x4,
5616                    &[v.into()],
5617                    ""
5618                ))
5619                .try_as_basic_value()
5620                .unwrap_basic();
5621                let res = err!(
5622                    self.builder
5623                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5624                );
5625                self.state
5626                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5627            }
5628            Operator::F64Floor => {
5629                let (input, info) = self.state.pop1_extra()?;
5630                let res = err!(self.builder.build_call(
5631                    self.intrinsics.floor_f64,
5632                    &[input.into()],
5633                    ""
5634                ))
5635                .try_as_basic_value()
5636                .unwrap_basic();
5637                self.state
5638                    .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5639            }
5640            Operator::F64x2Floor => {
5641                let (v, i) = self.state.pop1_extra()?;
5642                let (v, _) = self.v128_into_f64x2(v, i)?;
5643                let res = err!(self.builder.build_call(
5644                    self.intrinsics.floor_f64x2,
5645                    &[v.into()],
5646                    ""
5647                ))
5648                .try_as_basic_value()
5649                .unwrap_basic();
5650                let res = err!(
5651                    self.builder
5652                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5653                );
5654                self.state
5655                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5656            }
5657            Operator::F32Trunc => {
5658                let (v, i) = self.state.pop1_extra()?;
5659                let res = err!(
5660                    self.builder
5661                        .build_call(self.intrinsics.trunc_f32, &[v.into()], "")
5662                )
5663                .try_as_basic_value()
5664                .unwrap_basic();
5665                self.state
5666                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5667            }
5668            Operator::F32x4Trunc => {
5669                let (v, i) = self.state.pop1_extra()?;
5670                let (v, _) = self.v128_into_f32x4(v, i)?;
5671                let res = err!(self.builder.build_call(
5672                    self.intrinsics.trunc_f32x4,
5673                    &[v.into()],
5674                    ""
5675                ))
5676                .try_as_basic_value()
5677                .unwrap_basic();
5678                let res = err!(
5679                    self.builder
5680                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5681                );
5682                self.state
5683                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5684            }
5685            Operator::F64Trunc => {
5686                let (v, i) = self.state.pop1_extra()?;
5687                let res = err!(
5688                    self.builder
5689                        .build_call(self.intrinsics.trunc_f64, &[v.into()], "")
5690                )
5691                .try_as_basic_value()
5692                .unwrap_basic();
5693                self.state
5694                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5695            }
5696            Operator::F64x2Trunc => {
5697                let (v, i) = self.state.pop1_extra()?;
5698                let (v, _) = self.v128_into_f64x2(v, i)?;
5699                let res = err!(self.builder.build_call(
5700                    self.intrinsics.trunc_f64x2,
5701                    &[v.into()],
5702                    ""
5703                ))
5704                .try_as_basic_value()
5705                .unwrap_basic();
5706                let res = err!(
5707                    self.builder
5708                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5709                );
5710                self.state
5711                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5712            }
5713            Operator::F32Nearest => {
5714                let (v, i) = self.state.pop1_extra()?;
5715                let res = err!(self.builder.build_call(
5716                    self.intrinsics.nearbyint_f32,
5717                    &[v.into()],
5718                    ""
5719                ))
5720                .try_as_basic_value()
5721                .unwrap_basic();
5722                self.state
5723                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5724            }
5725            Operator::F32x4Nearest => {
5726                let (v, i) = self.state.pop1_extra()?;
5727                let (v, _) = self.v128_into_f32x4(v, i)?;
5728                let res = err!(self.builder.build_call(
5729                    self.intrinsics.nearbyint_f32x4,
5730                    &[v.into()],
5731                    ""
5732                ))
5733                .try_as_basic_value()
5734                .unwrap_basic();
5735                let res = err!(
5736                    self.builder
5737                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5738                );
5739                self.state
5740                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5741            }
5742            Operator::F64Nearest => {
5743                let (v, i) = self.state.pop1_extra()?;
5744                let res = err!(self.builder.build_call(
5745                    self.intrinsics.nearbyint_f64,
5746                    &[v.into()],
5747                    ""
5748                ))
5749                .try_as_basic_value()
5750                .unwrap_basic();
5751                self.state
5752                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5753            }
5754            Operator::F64x2Nearest => {
5755                let (v, i) = self.state.pop1_extra()?;
5756                let (v, _) = self.v128_into_f64x2(v, i)?;
5757                let res = err!(self.builder.build_call(
5758                    self.intrinsics.nearbyint_f64x2,
5759                    &[v.into()],
5760                    ""
5761                ))
5762                .try_as_basic_value()
5763                .unwrap_basic();
5764                let res = err!(
5765                    self.builder
5766                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5767                );
5768                self.state
5769                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5770            }
5771            Operator::F32Abs => {
5772                let (v, i) = self.state.pop1_extra()?;
5773                let v = self.apply_pending_canonicalization(v, i)?;
5774                let res = err!(
5775                    self.builder
5776                        .build_call(self.intrinsics.fabs_f32, &[v.into()], "")
5777                )
5778                .try_as_basic_value()
5779                .unwrap_basic();
5780                // The exact NaN returned by F32Abs is fully defined. Do not
5781                // adjust.
5782                self.state.push1_extra(res, i.strip_pending());
5783            }
5784            Operator::F64Abs => {
5785                let (v, i) = self.state.pop1_extra()?;
5786                let v = self.apply_pending_canonicalization(v, i)?;
5787                let res = err!(
5788                    self.builder
5789                        .build_call(self.intrinsics.fabs_f64, &[v.into()], "")
5790                )
5791                .try_as_basic_value()
5792                .unwrap_basic();
5793                // The exact NaN returned by F64Abs is fully defined. Do not
5794                // adjust.
5795                self.state.push1_extra(res, i.strip_pending());
5796            }
5797            Operator::F32x4Abs => {
5798                let (v, i) = self.state.pop1_extra()?;
5799                let v = err!(self.builder.build_bit_cast(
5800                    v.into_int_value(),
5801                    self.intrinsics.f32x4_ty,
5802                    ""
5803                ));
5804                let v = self.apply_pending_canonicalization(v, i)?;
5805                let res = err!(self.builder.build_call(
5806                    self.intrinsics.fabs_f32x4,
5807                    &[v.into()],
5808                    ""
5809                ))
5810                .try_as_basic_value()
5811                .unwrap_basic();
5812                let res = err!(
5813                    self.builder
5814                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5815                );
5816                // The exact NaN returned by F32x4Abs is fully defined. Do not
5817                // adjust.
5818                self.state.push1_extra(res, i.strip_pending());
5819            }
5820            Operator::F64x2Abs => {
5821                let (v, i) = self.state.pop1_extra()?;
5822                let v = err!(self.builder.build_bit_cast(
5823                    v.into_int_value(),
5824                    self.intrinsics.f64x2_ty,
5825                    ""
5826                ));
5827                let v = self.apply_pending_canonicalization(v, i)?;
5828                let res = err!(self.builder.build_call(
5829                    self.intrinsics.fabs_f64x2,
5830                    &[v.into()],
5831                    ""
5832                ))
5833                .try_as_basic_value()
5834                .unwrap_basic();
5835                let res = err!(
5836                    self.builder
5837                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5838                );
5839                // The exact NaN returned by F32x4Abs is fully defined. Do not
5840                // adjust.
5841                self.state.push1_extra(res, i.strip_pending());
5842            }
5843            Operator::F32x4Neg => {
5844                let (v, i) = self.state.pop1_extra()?;
5845                let v = err!(self.builder.build_bit_cast(
5846                    v.into_int_value(),
5847                    self.intrinsics.f32x4_ty,
5848                    ""
5849                ));
5850                let v = self
5851                    .apply_pending_canonicalization(v, i)?
5852                    .into_vector_value();
5853                let res = err!(self.builder.build_float_neg(v, ""));
5854                let res = err!(
5855                    self.builder
5856                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5857                );
5858                // The exact NaN returned by F32x4Neg is fully defined. Do not
5859                // adjust.
5860                self.state.push1_extra(res, i.strip_pending());
5861            }
5862            Operator::F64x2Neg => {
5863                let (v, i) = self.state.pop1_extra()?;
5864                let v = err!(self.builder.build_bit_cast(
5865                    v.into_int_value(),
5866                    self.intrinsics.f64x2_ty,
5867                    ""
5868                ));
5869                let v = self
5870                    .apply_pending_canonicalization(v, i)?
5871                    .into_vector_value();
5872                let res = err!(self.builder.build_float_neg(v, ""));
5873                let res = err!(
5874                    self.builder
5875                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5876                );
5877                // The exact NaN returned by F64x2Neg is fully defined. Do not
5878                // adjust.
5879                self.state.push1_extra(res, i.strip_pending());
5880            }
5881            Operator::F32Neg | Operator::F64Neg => {
5882                let (v, i) = self.state.pop1_extra()?;
5883                let v = self
5884                    .apply_pending_canonicalization(v, i)?
5885                    .into_float_value();
5886                let res = err!(self.builder.build_float_neg(v, ""));
5887                // The exact NaN returned by F32Neg and F64Neg are fully defined.
5888                // Do not adjust.
5889                self.state.push1_extra(res, i.strip_pending());
5890            }
5891            Operator::F32Copysign => {
5892                let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5893                let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5894                let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5895                let res = err!(self.builder.build_call(
5896                    self.intrinsics.copysign_f32,
5897                    &[mag.into(), sgn.into()],
5898                    ""
5899                ))
5900                .try_as_basic_value()
5901                .unwrap_basic();
5902                // The exact NaN returned by F32Copysign is fully defined.
5903                // Do not adjust.
5904                self.state.push1_extra(res, mag_info.strip_pending());
5905            }
5906            Operator::F64Copysign => {
5907                let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5908                let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5909                let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5910                let res = err!(self.builder.build_call(
5911                    self.intrinsics.copysign_f64,
5912                    &[mag.into(), sgn.into()],
5913                    ""
5914                ))
5915                .try_as_basic_value()
5916                .unwrap_basic();
5917                // The exact NaN returned by F32Copysign is fully defined.
5918                // Do not adjust.
5919                self.state.push1_extra(res, mag_info.strip_pending());
5920            }
5921
5922            /***************************
5923             * Integer Comparison instructions.
5924             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-comparison-instructions
5925             ***************************/
5926            Operator::I32Eq | Operator::I64Eq => {
5927                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5928                let v1 = self.apply_pending_canonicalization(v1, i1)?;
5929                let v2 = self.apply_pending_canonicalization(v2, i2)?;
5930                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
5931                let cond = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5932                let res = err!(
5933                    self.builder
5934                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
5935                );
5936                self.state.push1_extra(
5937                    res,
5938                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
5939                );
5940            }
5941            Operator::I8x16Eq => {
5942                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5943                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
5944                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
5945                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5946                let res = err!(
5947                    self.builder
5948                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
5949                );
5950                let res = err!(
5951                    self.builder
5952                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5953                );
5954                self.state.push1(res);
5955            }
5956            Operator::I16x8Eq => {
5957                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5958                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
5959                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
5960                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5961                let res = err!(
5962                    self.builder
5963                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
5964                );
5965                let res = err!(
5966                    self.builder
5967                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5968                );
5969                self.state.push1(res);
5970            }
5971            Operator::I32x4Eq => {
5972                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5973                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
5974                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
5975                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5976                let res = err!(
5977                    self.builder
5978                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
5979                );
5980                let res = err!(
5981                    self.builder
5982                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5983                );
5984                self.state.push1(res);
5985            }
5986            Operator::I64x2Eq => {
5987                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5988                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
5989                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
5990                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5991                let res = err!(
5992                    self.builder
5993                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
5994                );
5995                let res = err!(
5996                    self.builder
5997                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5998                );
5999                self.state.push1(res);
6000            }
6001            Operator::I32Ne | Operator::I64Ne => {
6002                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6003                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6004                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6005                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6006                let cond = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6007                let res = err!(
6008                    self.builder
6009                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6010                );
6011                self.state.push1_extra(
6012                    res,
6013                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6014                );
6015            }
6016            Operator::I8x16Ne => {
6017                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6018                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6019                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6020                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6021                let res = err!(
6022                    self.builder
6023                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6024                );
6025                let res = err!(
6026                    self.builder
6027                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6028                );
6029                self.state.push1(res);
6030            }
6031            Operator::I16x8Ne => {
6032                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6033                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6034                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6035                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6036                let res = err!(
6037                    self.builder
6038                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6039                );
6040                let res = err!(
6041                    self.builder
6042                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6043                );
6044                self.state.push1(res);
6045            }
6046            Operator::I32x4Ne => {
6047                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6048                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6049                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6050                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6051                let res = err!(
6052                    self.builder
6053                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6054                );
6055                let res = err!(
6056                    self.builder
6057                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6058                );
6059                self.state.push1(res);
6060            }
6061            Operator::I64x2Ne => {
6062                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6063                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6064                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6065                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6066                let res = err!(
6067                    self.builder
6068                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6069                );
6070                let res = err!(
6071                    self.builder
6072                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6073                );
6074                self.state.push1(res);
6075            }
6076            Operator::I32LtS | Operator::I64LtS => {
6077                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6078                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6079                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6080                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6081                let cond = err!(
6082                    self.builder
6083                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6084                );
6085                let res = err!(
6086                    self.builder
6087                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6088                );
6089                self.state.push1_extra(
6090                    res,
6091                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6092                );
6093            }
6094            Operator::I8x16LtS => {
6095                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6096                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6097                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6098                let res = err!(
6099                    self.builder
6100                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6101                );
6102                let res = err!(
6103                    self.builder
6104                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6105                );
6106                let res = err!(
6107                    self.builder
6108                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6109                );
6110                self.state.push1(res);
6111            }
6112            Operator::I16x8LtS => {
6113                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6114                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6115                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6116                let res = err!(
6117                    self.builder
6118                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6119                );
6120                let res = err!(
6121                    self.builder
6122                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6123                );
6124                let res = err!(
6125                    self.builder
6126                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6127                );
6128                self.state.push1(res);
6129            }
6130            Operator::I32x4LtS => {
6131                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6132                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6133                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6134                let res = err!(
6135                    self.builder
6136                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6137                );
6138                let res = err!(
6139                    self.builder
6140                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6141                );
6142                let res = err!(
6143                    self.builder
6144                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6145                );
6146                self.state.push1(res);
6147            }
6148            Operator::I64x2LtS => {
6149                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6150                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6151                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6152                let res = err!(
6153                    self.builder
6154                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6155                );
6156                let res = err!(
6157                    self.builder
6158                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6159                );
6160                let res = err!(
6161                    self.builder
6162                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6163                );
6164                self.state.push1(res);
6165            }
6166            Operator::I32LtU | Operator::I64LtU => {
6167                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6168                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6169                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6170                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6171                let cond = err!(
6172                    self.builder
6173                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6174                );
6175                let res = err!(
6176                    self.builder
6177                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6178                );
6179                self.state.push1(res);
6180            }
6181            Operator::I8x16LtU => {
6182                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6183                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6184                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6185                let res = err!(
6186                    self.builder
6187                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6188                );
6189                let res = err!(
6190                    self.builder
6191                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6192                );
6193                let res = err!(
6194                    self.builder
6195                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6196                );
6197                self.state.push1(res);
6198            }
6199            Operator::I16x8LtU => {
6200                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6201                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6202                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6203                let res = err!(
6204                    self.builder
6205                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6206                );
6207                let res = err!(
6208                    self.builder
6209                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6210                );
6211                let res = err!(
6212                    self.builder
6213                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6214                );
6215                self.state.push1(res);
6216            }
6217            Operator::I32x4LtU => {
6218                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6219                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6220                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6221                let res = err!(
6222                    self.builder
6223                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6224                );
6225                let res = err!(
6226                    self.builder
6227                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6228                );
6229                let res = err!(
6230                    self.builder
6231                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6232                );
6233                self.state.push1(res);
6234            }
6235            Operator::I32LeS | Operator::I64LeS => {
6236                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6237                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6238                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6239                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6240                let cond = err!(
6241                    self.builder
6242                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6243                );
6244                let res = err!(
6245                    self.builder
6246                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6247                );
6248                self.state.push1_extra(
6249                    res,
6250                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6251                );
6252            }
6253            Operator::I8x16LeS => {
6254                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6255                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6256                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6257                let res = err!(
6258                    self.builder
6259                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6260                );
6261                let res = err!(
6262                    self.builder
6263                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6264                );
6265                let res = err!(
6266                    self.builder
6267                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6268                );
6269                self.state.push1(res);
6270            }
6271            Operator::I16x8LeS => {
6272                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6273                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6274                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6275                let res = err!(
6276                    self.builder
6277                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6278                );
6279                let res = err!(
6280                    self.builder
6281                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6282                );
6283                let res = err!(
6284                    self.builder
6285                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6286                );
6287                self.state.push1(res);
6288            }
6289            Operator::I32x4LeS => {
6290                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6291                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6292                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6293                let res = err!(
6294                    self.builder
6295                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6296                );
6297                let res = err!(
6298                    self.builder
6299                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6300                );
6301                let res = err!(
6302                    self.builder
6303                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6304                );
6305                self.state.push1(res);
6306            }
6307            Operator::I64x2LeS => {
6308                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6309                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6310                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6311                let res = err!(
6312                    self.builder
6313                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6314                );
6315                let res = err!(
6316                    self.builder
6317                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6318                );
6319                let res = err!(
6320                    self.builder
6321                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6322                );
6323                self.state.push1(res);
6324            }
6325            Operator::I32LeU | Operator::I64LeU => {
6326                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6327                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6328                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6329                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6330                let cond = err!(
6331                    self.builder
6332                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6333                );
6334                let res = err!(
6335                    self.builder
6336                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6337                );
6338                self.state.push1_extra(
6339                    res,
6340                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6341                );
6342            }
6343            Operator::I8x16LeU => {
6344                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6345                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6346                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6347                let res = err!(
6348                    self.builder
6349                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6350                );
6351                let res = err!(
6352                    self.builder
6353                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6354                );
6355                let res = err!(
6356                    self.builder
6357                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6358                );
6359                self.state.push1(res);
6360            }
6361            Operator::I16x8LeU => {
6362                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6363                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6364                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6365                let res = err!(
6366                    self.builder
6367                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6368                );
6369                let res = err!(
6370                    self.builder
6371                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6372                );
6373                let res = err!(
6374                    self.builder
6375                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6376                );
6377                self.state.push1(res);
6378            }
6379            Operator::I32x4LeU => {
6380                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6381                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6382                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6383                let res = err!(
6384                    self.builder
6385                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6386                );
6387                let res = err!(
6388                    self.builder
6389                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6390                );
6391                let res = err!(
6392                    self.builder
6393                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6394                );
6395                self.state.push1(res);
6396            }
6397            Operator::I32GtS | Operator::I64GtS => {
6398                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6399                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6400                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6401                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6402                let cond = err!(
6403                    self.builder
6404                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6405                );
6406                let res = err!(
6407                    self.builder
6408                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6409                );
6410                self.state.push1_extra(
6411                    res,
6412                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6413                );
6414            }
6415            Operator::I8x16GtS => {
6416                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6417                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6418                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6419                let res = err!(
6420                    self.builder
6421                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6422                );
6423                let res = err!(
6424                    self.builder
6425                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6426                );
6427                let res = err!(
6428                    self.builder
6429                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6430                );
6431                self.state.push1(res);
6432            }
6433            Operator::I16x8GtS => {
6434                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6435                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6436                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6437                let res = err!(
6438                    self.builder
6439                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6440                );
6441                let res = err!(
6442                    self.builder
6443                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6444                );
6445                let res = err!(
6446                    self.builder
6447                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6448                );
6449                self.state.push1(res);
6450            }
6451            Operator::I32x4GtS => {
6452                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6453                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6454                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6455                let res = err!(
6456                    self.builder
6457                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6458                );
6459                let res = err!(
6460                    self.builder
6461                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6462                );
6463                let res = err!(
6464                    self.builder
6465                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6466                );
6467                self.state.push1(res);
6468            }
6469            Operator::I64x2GtS => {
6470                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6471                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6472                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6473                let res = err!(
6474                    self.builder
6475                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6476                );
6477                let res = err!(
6478                    self.builder
6479                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6480                );
6481                let res = err!(
6482                    self.builder
6483                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6484                );
6485                self.state.push1(res);
6486            }
6487            Operator::I32GtU | Operator::I64GtU => {
6488                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6489                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6490                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6491                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6492                let cond = err!(
6493                    self.builder
6494                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6495                );
6496                let res = err!(
6497                    self.builder
6498                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6499                );
6500                self.state.push1_extra(
6501                    res,
6502                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6503                );
6504            }
6505            Operator::I8x16GtU => {
6506                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6507                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6508                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6509                let res = err!(
6510                    self.builder
6511                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6512                );
6513                let res = err!(
6514                    self.builder
6515                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6516                );
6517                let res = err!(
6518                    self.builder
6519                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6520                );
6521                self.state.push1(res);
6522            }
6523            Operator::I16x8GtU => {
6524                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6525                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6526                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6527                let res = err!(
6528                    self.builder
6529                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6530                );
6531                let res = err!(
6532                    self.builder
6533                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6534                );
6535                let res = err!(
6536                    self.builder
6537                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6538                );
6539                self.state.push1(res);
6540            }
6541            Operator::I32x4GtU => {
6542                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6543                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6544                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6545                let res = err!(
6546                    self.builder
6547                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6548                );
6549                let res = err!(
6550                    self.builder
6551                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6552                );
6553                let res = err!(
6554                    self.builder
6555                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6556                );
6557                self.state.push1(res);
6558            }
6559            Operator::I32GeS | Operator::I64GeS => {
6560                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6561                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6562                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6563                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6564                let cond = err!(
6565                    self.builder
6566                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6567                );
6568                let res = err!(
6569                    self.builder
6570                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6571                );
6572                self.state.push1(res);
6573            }
6574            Operator::I8x16GeS => {
6575                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6576                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6577                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6578                let res = err!(
6579                    self.builder
6580                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6581                );
6582                let res = err!(
6583                    self.builder
6584                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6585                );
6586                let res = err!(
6587                    self.builder
6588                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6589                );
6590                self.state.push1(res);
6591            }
6592            Operator::I16x8GeS => {
6593                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6594                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6595                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6596                let res = err!(
6597                    self.builder
6598                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6599                );
6600                let res = err!(
6601                    self.builder
6602                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6603                );
6604                let res = err!(
6605                    self.builder
6606                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6607                );
6608                self.state.push1(res);
6609            }
6610            Operator::I32x4GeS => {
6611                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6612                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6613                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6614                let res = err!(
6615                    self.builder
6616                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6617                );
6618                let res = err!(
6619                    self.builder
6620                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6621                );
6622                let res = err!(
6623                    self.builder
6624                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6625                );
6626                self.state.push1(res);
6627            }
6628            Operator::I64x2GeS => {
6629                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6630                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6631                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6632                let res = err!(
6633                    self.builder
6634                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6635                );
6636                let res = err!(
6637                    self.builder
6638                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6639                );
6640                let res = err!(
6641                    self.builder
6642                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6643                );
6644                self.state.push1(res);
6645            }
6646            Operator::I32GeU | Operator::I64GeU => {
6647                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6648                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6649                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6650                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6651                let cond = err!(
6652                    self.builder
6653                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6654                );
6655                let res = err!(
6656                    self.builder
6657                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6658                );
6659                self.state.push1_extra(
6660                    res,
6661                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6662                );
6663            }
6664            Operator::I8x16GeU => {
6665                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6666                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6667                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6668                let res = err!(
6669                    self.builder
6670                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6671                );
6672                let res = err!(
6673                    self.builder
6674                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6675                );
6676                let res = err!(
6677                    self.builder
6678                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6679                );
6680                self.state.push1(res);
6681            }
6682            Operator::I16x8GeU => {
6683                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6684                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6685                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6686                let res = err!(
6687                    self.builder
6688                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6689                );
6690                let res = err!(
6691                    self.builder
6692                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6693                );
6694                let res = err!(
6695                    self.builder
6696                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6697                );
6698                self.state.push1(res);
6699            }
6700            Operator::I32x4GeU => {
6701                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6702                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6703                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6704                let res = err!(
6705                    self.builder
6706                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6707                );
6708                let res = err!(
6709                    self.builder
6710                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6711                );
6712                let res = err!(
6713                    self.builder
6714                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6715                );
6716                self.state.push1(res);
6717            }
6718
6719            /***************************
6720             * Floating-Point Comparison instructions.
6721             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-comparison-instructions
6722             ***************************/
6723            Operator::F32Eq | Operator::F64Eq => {
6724                let (v1, v2) = self.state.pop2()?;
6725                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6726                let cond = err!(
6727                    self.builder
6728                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6729                );
6730                let res = err!(
6731                    self.builder
6732                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6733                );
6734                self.state.push1_extra(
6735                    res,
6736                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6737                );
6738            }
6739            Operator::F32x4Eq => {
6740                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6741                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6742                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6743                let res = err!(
6744                    self.builder
6745                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6746                );
6747                let res = err!(
6748                    self.builder
6749                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6750                );
6751                let res = err!(
6752                    self.builder
6753                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6754                );
6755                self.state.push1(res);
6756            }
6757            Operator::F64x2Eq => {
6758                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6759                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6760                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6761                let res = err!(
6762                    self.builder
6763                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6764                );
6765                let res = err!(
6766                    self.builder
6767                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6768                );
6769                let res = err!(
6770                    self.builder
6771                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6772                );
6773                self.state.push1(res);
6774            }
6775            Operator::F32Ne | Operator::F64Ne => {
6776                let (v1, v2) = self.state.pop2()?;
6777                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6778                let cond = err!(
6779                    self.builder
6780                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6781                );
6782                let res = err!(
6783                    self.builder
6784                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6785                );
6786                self.state.push1_extra(
6787                    res,
6788                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6789                );
6790            }
6791            Operator::F32x4Ne => {
6792                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6793                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6794                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6795                let res = err!(
6796                    self.builder
6797                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6798                );
6799                let res = err!(
6800                    self.builder
6801                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6802                );
6803                let res = err!(
6804                    self.builder
6805                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6806                );
6807                self.state.push1(res);
6808            }
6809            Operator::F64x2Ne => {
6810                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6811                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6812                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6813                let res = err!(
6814                    self.builder
6815                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6816                );
6817                let res = err!(
6818                    self.builder
6819                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6820                );
6821                let res = err!(
6822                    self.builder
6823                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6824                );
6825                self.state.push1(res);
6826            }
6827            Operator::F32Lt | Operator::F64Lt => {
6828                let (v1, v2) = self.state.pop2()?;
6829                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6830                let cond = err!(
6831                    self.builder
6832                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6833                );
6834                let res = err!(
6835                    self.builder
6836                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6837                );
6838                self.state.push1_extra(
6839                    res,
6840                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6841                );
6842            }
6843            Operator::F32x4Lt => {
6844                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6845                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6846                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6847                let res = err!(
6848                    self.builder
6849                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6850                );
6851                let res = err!(
6852                    self.builder
6853                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6854                );
6855                let res = err!(
6856                    self.builder
6857                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6858                );
6859                self.state.push1(res);
6860            }
6861            Operator::F64x2Lt => {
6862                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6863                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6864                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6865                let res = err!(
6866                    self.builder
6867                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6868                );
6869                let res = err!(
6870                    self.builder
6871                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6872                );
6873                let res = err!(
6874                    self.builder
6875                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6876                );
6877                self.state.push1(res);
6878            }
6879            Operator::F32Le | Operator::F64Le => {
6880                let (v1, v2) = self.state.pop2()?;
6881                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6882                let cond = err!(
6883                    self.builder
6884                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6885                );
6886                let res = err!(
6887                    self.builder
6888                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6889                );
6890                self.state.push1_extra(
6891                    res,
6892                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6893                );
6894            }
6895            Operator::F32x4Le => {
6896                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6897                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6898                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6899                let res = err!(
6900                    self.builder
6901                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6902                );
6903                let res = err!(
6904                    self.builder
6905                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6906                );
6907                let res = err!(
6908                    self.builder
6909                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6910                );
6911                self.state.push1(res);
6912            }
6913            Operator::F64x2Le => {
6914                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6915                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6916                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6917                let res = err!(
6918                    self.builder
6919                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6920                );
6921                let res = err!(
6922                    self.builder
6923                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6924                );
6925                let res = err!(
6926                    self.builder
6927                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6928                );
6929                self.state.push1(res);
6930            }
6931            Operator::F32Gt | Operator::F64Gt => {
6932                let (v1, v2) = self.state.pop2()?;
6933                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6934                let cond = err!(
6935                    self.builder
6936                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6937                );
6938                let res = err!(
6939                    self.builder
6940                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6941                );
6942                self.state.push1_extra(
6943                    res,
6944                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6945                );
6946            }
6947            Operator::F32x4Gt => {
6948                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6949                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6950                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6951                let res = err!(
6952                    self.builder
6953                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6954                );
6955                let res = err!(
6956                    self.builder
6957                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6958                );
6959                let res = err!(
6960                    self.builder
6961                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6962                );
6963                self.state.push1(res);
6964            }
6965            Operator::F64x2Gt => {
6966                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6967                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6968                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6969                let res = err!(
6970                    self.builder
6971                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6972                );
6973                let res = err!(
6974                    self.builder
6975                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6976                );
6977                let res = err!(
6978                    self.builder
6979                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6980                );
6981                self.state.push1(res);
6982            }
6983            Operator::F32Ge | Operator::F64Ge => {
6984                let (v1, v2) = self.state.pop2()?;
6985                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6986                let cond = err!(
6987                    self.builder
6988                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
6989                );
6990                let res = err!(
6991                    self.builder
6992                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6993                );
6994                self.state.push1_extra(
6995                    res,
6996                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6997                );
6998            }
6999            Operator::F32x4Ge => {
7000                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7001                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7002                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7003                let res = err!(
7004                    self.builder
7005                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7006                );
7007                let res = err!(
7008                    self.builder
7009                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7010                );
7011                let res = err!(
7012                    self.builder
7013                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7014                );
7015                self.state.push1(res);
7016            }
7017            Operator::F64x2Ge => {
7018                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7019                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7020                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7021                let res = err!(
7022                    self.builder
7023                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7024                );
7025                let res = err!(
7026                    self.builder
7027                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7028                );
7029                let res = err!(
7030                    self.builder
7031                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7032                );
7033                self.state.push1(res);
7034            }
7035
7036            /***************************
7037             * Conversion instructions.
7038             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#conversion-instructions
7039             ***************************/
7040            Operator::I32WrapI64 => {
7041                let (v, i) = self.state.pop1_extra()?;
7042                let v = self.apply_pending_canonicalization(v, i)?;
7043                let v = v.into_int_value();
7044                let res = err!(
7045                    self.builder
7046                        .build_int_truncate(v, self.intrinsics.i32_ty, "")
7047                );
7048                self.state.push1(res);
7049            }
7050            Operator::I64ExtendI32S => {
7051                let (v, i) = self.state.pop1_extra()?;
7052                let v = self.apply_pending_canonicalization(v, i)?;
7053                let v = v.into_int_value();
7054                let res = err!(
7055                    self.builder
7056                        .build_int_s_extend(v, self.intrinsics.i64_ty, "")
7057                );
7058                self.state.push1(res);
7059            }
7060            Operator::I64ExtendI32U => {
7061                let (v, i) = self.state.pop1_extra()?;
7062                let v = self.apply_pending_canonicalization(v, i)?;
7063                let v = v.into_int_value();
7064                let res = err!(
7065                    self.builder
7066                        .build_int_z_extend(v, self.intrinsics.i64_ty, "")
7067                );
7068                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
7069            }
7070            Operator::I16x8ExtendLowI8x16S => {
7071                let (v, i) = self.state.pop1_extra()?;
7072                let (v, _) = self.v128_into_i8x16(v, i)?;
7073                let low = err!(self.builder.build_shuffle_vector(
7074                    v,
7075                    v.get_type().get_undef(),
7076                    VectorType::const_vector(&[
7077                        self.intrinsics.i32_consts[0],
7078                        self.intrinsics.i32_consts[1],
7079                        self.intrinsics.i32_consts[2],
7080                        self.intrinsics.i32_consts[3],
7081                        self.intrinsics.i32_consts[4],
7082                        self.intrinsics.i32_consts[5],
7083                        self.intrinsics.i32_consts[6],
7084                        self.intrinsics.i32_consts[7],
7085                    ]),
7086                    "",
7087                ));
7088                let res = err!(
7089                    self.builder
7090                        .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7091                );
7092                let res = err!(
7093                    self.builder
7094                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7095                );
7096                self.state.push1(res);
7097            }
7098            Operator::I16x8ExtendHighI8x16S => {
7099                let (v, i) = self.state.pop1_extra()?;
7100                let (v, _) = self.v128_into_i8x16(v, i)?;
7101                let low = err!(self.builder.build_shuffle_vector(
7102                    v,
7103                    v.get_type().get_undef(),
7104                    VectorType::const_vector(&[
7105                        self.intrinsics.i32_consts[8],
7106                        self.intrinsics.i32_consts[9],
7107                        self.intrinsics.i32_consts[10],
7108                        self.intrinsics.i32_consts[11],
7109                        self.intrinsics.i32_consts[12],
7110                        self.intrinsics.i32_consts[13],
7111                        self.intrinsics.i32_consts[14],
7112                        self.intrinsics.i32_consts[15],
7113                    ]),
7114                    "",
7115                ));
7116                let res = err!(
7117                    self.builder
7118                        .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7119                );
7120                let res = err!(
7121                    self.builder
7122                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7123                );
7124                self.state.push1(res);
7125            }
7126            Operator::I16x8ExtendLowI8x16U => {
7127                let (v, i) = self.state.pop1_extra()?;
7128                let (v, _) = self.v128_into_i8x16(v, i)?;
7129                let low = err!(self.builder.build_shuffle_vector(
7130                    v,
7131                    v.get_type().get_undef(),
7132                    VectorType::const_vector(&[
7133                        self.intrinsics.i32_consts[0],
7134                        self.intrinsics.i32_consts[1],
7135                        self.intrinsics.i32_consts[2],
7136                        self.intrinsics.i32_consts[3],
7137                        self.intrinsics.i32_consts[4],
7138                        self.intrinsics.i32_consts[5],
7139                        self.intrinsics.i32_consts[6],
7140                        self.intrinsics.i32_consts[7],
7141                    ]),
7142                    "",
7143                ));
7144                let res = err!(
7145                    self.builder
7146                        .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7147                );
7148                let res = err!(
7149                    self.builder
7150                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7151                );
7152                self.state.push1(res);
7153            }
7154            Operator::I16x8ExtendHighI8x16U => {
7155                let (v, i) = self.state.pop1_extra()?;
7156                let (v, _) = self.v128_into_i8x16(v, i)?;
7157                let low = err!(self.builder.build_shuffle_vector(
7158                    v,
7159                    v.get_type().get_undef(),
7160                    VectorType::const_vector(&[
7161                        self.intrinsics.i32_consts[8],
7162                        self.intrinsics.i32_consts[9],
7163                        self.intrinsics.i32_consts[10],
7164                        self.intrinsics.i32_consts[11],
7165                        self.intrinsics.i32_consts[12],
7166                        self.intrinsics.i32_consts[13],
7167                        self.intrinsics.i32_consts[14],
7168                        self.intrinsics.i32_consts[15],
7169                    ]),
7170                    "",
7171                ));
7172                let res = err!(
7173                    self.builder
7174                        .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7175                );
7176                let res = err!(
7177                    self.builder
7178                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7179                );
7180                self.state.push1(res);
7181            }
7182            Operator::I32x4ExtendLowI16x8S => {
7183                let (v, i) = self.state.pop1_extra()?;
7184                let (v, _) = self.v128_into_i16x8(v, i)?;
7185                let low = err!(self.builder.build_shuffle_vector(
7186                    v,
7187                    v.get_type().get_undef(),
7188                    VectorType::const_vector(&[
7189                        self.intrinsics.i32_consts[0],
7190                        self.intrinsics.i32_consts[1],
7191                        self.intrinsics.i32_consts[2],
7192                        self.intrinsics.i32_consts[3],
7193                    ]),
7194                    "",
7195                ));
7196                let res = err!(
7197                    self.builder
7198                        .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7199                );
7200                let res = err!(
7201                    self.builder
7202                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7203                );
7204                self.state.push1(res);
7205            }
7206            Operator::I32x4ExtendHighI16x8S => {
7207                let (v, i) = self.state.pop1_extra()?;
7208                let (v, _) = self.v128_into_i16x8(v, i)?;
7209                let low = err!(self.builder.build_shuffle_vector(
7210                    v,
7211                    v.get_type().get_undef(),
7212                    VectorType::const_vector(&[
7213                        self.intrinsics.i32_consts[4],
7214                        self.intrinsics.i32_consts[5],
7215                        self.intrinsics.i32_consts[6],
7216                        self.intrinsics.i32_consts[7],
7217                    ]),
7218                    "",
7219                ));
7220                let res = err!(
7221                    self.builder
7222                        .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7223                );
7224                let res = err!(
7225                    self.builder
7226                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7227                );
7228                self.state.push1(res);
7229            }
7230            Operator::I32x4ExtendLowI16x8U => {
7231                let (v, i) = self.state.pop1_extra()?;
7232                let (v, _) = self.v128_into_i16x8(v, i)?;
7233                let low = err!(self.builder.build_shuffle_vector(
7234                    v,
7235                    v.get_type().get_undef(),
7236                    VectorType::const_vector(&[
7237                        self.intrinsics.i32_consts[0],
7238                        self.intrinsics.i32_consts[1],
7239                        self.intrinsics.i32_consts[2],
7240                        self.intrinsics.i32_consts[3],
7241                    ]),
7242                    "",
7243                ));
7244                let res = err!(
7245                    self.builder
7246                        .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7247                );
7248                let res = err!(
7249                    self.builder
7250                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7251                );
7252                self.state.push1(res);
7253            }
7254            Operator::I32x4ExtendHighI16x8U => {
7255                let (v, i) = self.state.pop1_extra()?;
7256                let (v, _) = self.v128_into_i16x8(v, i)?;
7257                let low = err!(self.builder.build_shuffle_vector(
7258                    v,
7259                    v.get_type().get_undef(),
7260                    VectorType::const_vector(&[
7261                        self.intrinsics.i32_consts[4],
7262                        self.intrinsics.i32_consts[5],
7263                        self.intrinsics.i32_consts[6],
7264                        self.intrinsics.i32_consts[7],
7265                    ]),
7266                    "",
7267                ));
7268                let res = err!(
7269                    self.builder
7270                        .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7271                );
7272                let res = err!(
7273                    self.builder
7274                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7275                );
7276                self.state.push1(res);
7277            }
7278            Operator::I64x2ExtendLowI32x4U
7279            | Operator::I64x2ExtendLowI32x4S
7280            | Operator::I64x2ExtendHighI32x4U
7281            | Operator::I64x2ExtendHighI32x4S => {
7282                let extend = match op {
7283                    Operator::I64x2ExtendLowI32x4U | Operator::I64x2ExtendHighI32x4U => {
7284                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
7285                    }
7286                    Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendHighI32x4S => {
7287                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
7288                    }
7289                    _ => unreachable!("Unhandled inner case"),
7290                };
7291                let indices = match op {
7292                    Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendLowI32x4U => {
7293                        [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[1]]
7294                    }
7295                    Operator::I64x2ExtendHighI32x4S | Operator::I64x2ExtendHighI32x4U => {
7296                        [self.intrinsics.i32_consts[2], self.intrinsics.i32_consts[3]]
7297                    }
7298                    _ => unreachable!("Unhandled inner case"),
7299                };
7300                let (v, i) = self.state.pop1_extra()?;
7301                let (v, _) = self.v128_into_i32x4(v, i)?;
7302                let low = err!(self.builder.build_shuffle_vector(
7303                    v,
7304                    v.get_type().get_undef(),
7305                    VectorType::const_vector(&indices),
7306                    "",
7307                ));
7308                let res = err!(extend(self, low));
7309                let res = err!(
7310                    self.builder
7311                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7312                );
7313                self.state.push1(res);
7314            }
7315            Operator::I8x16NarrowI16x8S => {
7316                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7317                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7318                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7319                let min = self.intrinsics.i16_ty.const_int(0xff80, false);
7320                let max = self.intrinsics.i16_ty.const_int(0x007f, false);
7321                let min = VectorType::const_vector(&[min; 8]);
7322                let max = VectorType::const_vector(&[max; 8]);
7323                let apply_min_clamp_v1 =
7324                    err!(
7325                        self.builder
7326                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7327                    );
7328                let apply_max_clamp_v1 =
7329                    err!(
7330                        self.builder
7331                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7332                    );
7333                let apply_min_clamp_v2 =
7334                    err!(
7335                        self.builder
7336                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7337                    );
7338                let apply_max_clamp_v2 =
7339                    err!(
7340                        self.builder
7341                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7342                    );
7343                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7344                    .into_vector_value();
7345                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7346                    .into_vector_value();
7347                let v1 = err!(self.builder.build_int_truncate(
7348                    v1,
7349                    self.intrinsics.i8_ty.vec_type(8),
7350                    ""
7351                ));
7352                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7353                    .into_vector_value();
7354                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7355                    .into_vector_value();
7356                let v2 = err!(self.builder.build_int_truncate(
7357                    v2,
7358                    self.intrinsics.i8_ty.vec_type(8),
7359                    ""
7360                ));
7361                let res = err!(self.builder.build_shuffle_vector(
7362                    v1,
7363                    v2,
7364                    VectorType::const_vector(&[
7365                        self.intrinsics.i32_consts[0],
7366                        self.intrinsics.i32_consts[1],
7367                        self.intrinsics.i32_consts[2],
7368                        self.intrinsics.i32_consts[3],
7369                        self.intrinsics.i32_consts[4],
7370                        self.intrinsics.i32_consts[5],
7371                        self.intrinsics.i32_consts[6],
7372                        self.intrinsics.i32_consts[7],
7373                        self.intrinsics.i32_consts[8],
7374                        self.intrinsics.i32_consts[9],
7375                        self.intrinsics.i32_consts[10],
7376                        self.intrinsics.i32_consts[11],
7377                        self.intrinsics.i32_consts[12],
7378                        self.intrinsics.i32_consts[13],
7379                        self.intrinsics.i32_consts[14],
7380                        self.intrinsics.i32_consts[15],
7381                    ]),
7382                    "",
7383                ));
7384                let res = err!(
7385                    self.builder
7386                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7387                );
7388                self.state.push1(res);
7389            }
7390            Operator::I8x16NarrowI16x8U => {
7391                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7392                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7393                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7394                let min = self.intrinsics.i16x8_ty.const_zero();
7395                let max = self.intrinsics.i16_ty.const_int(0x00ff, false);
7396                let max = VectorType::const_vector(&[max; 8]);
7397                let apply_min_clamp_v1 =
7398                    err!(
7399                        self.builder
7400                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7401                    );
7402                let apply_max_clamp_v1 =
7403                    err!(
7404                        self.builder
7405                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7406                    );
7407                let apply_min_clamp_v2 =
7408                    err!(
7409                        self.builder
7410                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7411                    );
7412                let apply_max_clamp_v2 =
7413                    err!(
7414                        self.builder
7415                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7416                    );
7417                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7418                    .into_vector_value();
7419                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7420                    .into_vector_value();
7421                let v1 = err!(self.builder.build_int_truncate(
7422                    v1,
7423                    self.intrinsics.i8_ty.vec_type(8),
7424                    ""
7425                ));
7426                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7427                    .into_vector_value();
7428                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7429                    .into_vector_value();
7430                let v2 = err!(self.builder.build_int_truncate(
7431                    v2,
7432                    self.intrinsics.i8_ty.vec_type(8),
7433                    ""
7434                ));
7435                let res = err!(self.builder.build_shuffle_vector(
7436                    v1,
7437                    v2,
7438                    VectorType::const_vector(&[
7439                        self.intrinsics.i32_consts[0],
7440                        self.intrinsics.i32_consts[1],
7441                        self.intrinsics.i32_consts[2],
7442                        self.intrinsics.i32_consts[3],
7443                        self.intrinsics.i32_consts[4],
7444                        self.intrinsics.i32_consts[5],
7445                        self.intrinsics.i32_consts[6],
7446                        self.intrinsics.i32_consts[7],
7447                        self.intrinsics.i32_consts[8],
7448                        self.intrinsics.i32_consts[9],
7449                        self.intrinsics.i32_consts[10],
7450                        self.intrinsics.i32_consts[11],
7451                        self.intrinsics.i32_consts[12],
7452                        self.intrinsics.i32_consts[13],
7453                        self.intrinsics.i32_consts[14],
7454                        self.intrinsics.i32_consts[15],
7455                    ]),
7456                    "",
7457                ));
7458                let res = err!(
7459                    self.builder
7460                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7461                );
7462                self.state.push1(res);
7463            }
7464            Operator::I16x8NarrowI32x4S => {
7465                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7466                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7467                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7468                let min = self.intrinsics.i32_ty.const_int(0xffff8000, false);
7469                let max = self.intrinsics.i32_ty.const_int(0x00007fff, false);
7470                let min = VectorType::const_vector(&[min; 4]);
7471                let max = VectorType::const_vector(&[max; 4]);
7472                let apply_min_clamp_v1 =
7473                    err!(
7474                        self.builder
7475                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7476                    );
7477                let apply_max_clamp_v1 =
7478                    err!(
7479                        self.builder
7480                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7481                    );
7482                let apply_min_clamp_v2 =
7483                    err!(
7484                        self.builder
7485                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7486                    );
7487                let apply_max_clamp_v2 =
7488                    err!(
7489                        self.builder
7490                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7491                    );
7492                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7493                    .into_vector_value();
7494                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7495                    .into_vector_value();
7496                let v1 = err!(self.builder.build_int_truncate(
7497                    v1,
7498                    self.intrinsics.i16_ty.vec_type(4),
7499                    ""
7500                ));
7501                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7502                    .into_vector_value();
7503                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7504                    .into_vector_value();
7505                let v2 = err!(self.builder.build_int_truncate(
7506                    v2,
7507                    self.intrinsics.i16_ty.vec_type(4),
7508                    ""
7509                ));
7510                let res = err!(self.builder.build_shuffle_vector(
7511                    v1,
7512                    v2,
7513                    VectorType::const_vector(&[
7514                        self.intrinsics.i32_consts[0],
7515                        self.intrinsics.i32_consts[1],
7516                        self.intrinsics.i32_consts[2],
7517                        self.intrinsics.i32_consts[3],
7518                        self.intrinsics.i32_consts[4],
7519                        self.intrinsics.i32_consts[5],
7520                        self.intrinsics.i32_consts[6],
7521                        self.intrinsics.i32_consts[7],
7522                    ]),
7523                    "",
7524                ));
7525                let res = err!(
7526                    self.builder
7527                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7528                );
7529                self.state.push1(res);
7530            }
7531            Operator::I16x8NarrowI32x4U => {
7532                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7533                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7534                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7535                let min = self.intrinsics.i32x4_ty.const_zero();
7536                let max = self.intrinsics.i32_ty.const_int(0xffff, false);
7537                let max = VectorType::const_vector(&[max; 4]);
7538                let apply_min_clamp_v1 =
7539                    err!(
7540                        self.builder
7541                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7542                    );
7543                let apply_max_clamp_v1 =
7544                    err!(
7545                        self.builder
7546                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7547                    );
7548                let apply_min_clamp_v2 =
7549                    err!(
7550                        self.builder
7551                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7552                    );
7553                let apply_max_clamp_v2 =
7554                    err!(
7555                        self.builder
7556                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7557                    );
7558                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7559                    .into_vector_value();
7560                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7561                    .into_vector_value();
7562                let v1 = err!(self.builder.build_int_truncate(
7563                    v1,
7564                    self.intrinsics.i16_ty.vec_type(4),
7565                    ""
7566                ));
7567                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7568                    .into_vector_value();
7569                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7570                    .into_vector_value();
7571                let v2 = err!(self.builder.build_int_truncate(
7572                    v2,
7573                    self.intrinsics.i16_ty.vec_type(4),
7574                    ""
7575                ));
7576                let res = err!(self.builder.build_shuffle_vector(
7577                    v1,
7578                    v2,
7579                    VectorType::const_vector(&[
7580                        self.intrinsics.i32_consts[0],
7581                        self.intrinsics.i32_consts[1],
7582                        self.intrinsics.i32_consts[2],
7583                        self.intrinsics.i32_consts[3],
7584                        self.intrinsics.i32_consts[4],
7585                        self.intrinsics.i32_consts[5],
7586                        self.intrinsics.i32_consts[6],
7587                        self.intrinsics.i32_consts[7],
7588                    ]),
7589                    "",
7590                ));
7591                let res = err!(
7592                    self.builder
7593                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7594                );
7595                self.state.push1(res);
7596            }
7597            Operator::I32x4TruncSatF32x4S => {
7598                let (v, i) = self.state.pop1_extra()?;
7599                let v = self.apply_pending_canonicalization(v, i)?;
7600                let v = v.into_int_value();
7601                let res = self.trunc_sat_into_int(
7602                    self.intrinsics.f32x4_ty,
7603                    self.intrinsics.i32x4_ty,
7604                    LEF32_GEQ_I32_MIN,
7605                    GEF32_LEQ_I32_MAX,
7606                    i32::MIN as u64,
7607                    i32::MAX as u64,
7608                    v,
7609                )?;
7610                self.state.push1(res);
7611            }
7612            Operator::I32x4TruncSatF32x4U => {
7613                let (v, i) = self.state.pop1_extra()?;
7614                let v = self.apply_pending_canonicalization(v, i)?;
7615                let v = v.into_int_value();
7616                let res = self.trunc_sat_into_int(
7617                    self.intrinsics.f32x4_ty,
7618                    self.intrinsics.i32x4_ty,
7619                    LEF32_GEQ_U32_MIN,
7620                    GEF32_LEQ_U32_MAX,
7621                    u32::MIN as u64,
7622                    u32::MAX as u64,
7623                    v,
7624                )?;
7625                self.state.push1(res);
7626            }
7627            Operator::I32x4TruncSatF64x2SZero | Operator::I32x4TruncSatF64x2UZero => {
7628                let ((min, max), (cmp_min, cmp_max)) = match op {
7629                    Operator::I32x4TruncSatF64x2SZero => (
7630                        (i32::MIN as u64, i32::MAX as u64),
7631                        (LEF64_GEQ_I32_MIN, GEF64_LEQ_I32_MAX),
7632                    ),
7633                    Operator::I32x4TruncSatF64x2UZero => (
7634                        (u32::MIN as u64, u32::MAX as u64),
7635                        (LEF64_GEQ_U32_MIN, GEF64_LEQ_U32_MAX),
7636                    ),
7637                    _ => unreachable!("Unhandled internal variant"),
7638                };
7639                let (v, i) = self.state.pop1_extra()?;
7640                let v = self.apply_pending_canonicalization(v, i)?;
7641                let v = v.into_int_value();
7642                let res = self.trunc_sat(
7643                    self.intrinsics.f64x2_ty,
7644                    self.intrinsics.i32_ty.vec_type(2),
7645                    cmp_min,
7646                    cmp_max,
7647                    min,
7648                    max,
7649                    v,
7650                )?;
7651
7652                let zero = self.intrinsics.i32_consts[0];
7653                let zeros = VectorType::const_vector(&[zero; 2]);
7654                let res = err!(self.builder.build_shuffle_vector(
7655                    res,
7656                    zeros,
7657                    VectorType::const_vector(&[
7658                        self.intrinsics.i32_consts[0],
7659                        self.intrinsics.i32_consts[1],
7660                        self.intrinsics.i32_consts[2],
7661                        self.intrinsics.i32_consts[3],
7662                    ]),
7663                    "",
7664                ));
7665                let res = err!(
7666                    self.builder
7667                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7668                );
7669                self.state.push1(res);
7670            }
7671            // Operator::I64x2TruncSatF64x2S => {
7672            //     let (v, i) = self.state.pop1_extra()?;
7673            //     let v = self.apply_pending_canonicalization(v, i)?;
7674            //     let v = v.into_int_value();
7675            //     let res = self.trunc_sat_into_int(
7676            //         self.intrinsics.f64x2_ty,
7677            //         self.intrinsics.i64x2_ty,
7678            //         i64::MIN as u64,
7679            //         i64::MAX as u64,
7680            //         i64::MIN as u64,
7681            //         i64::MAX as u64,
7682            //         v,
7683            //     )?;
7684            //     self.state.push1(res);
7685            // }
7686            // Operator::I64x2TruncSatF64x2U => {
7687            //     let (v, i) = self.state.pop1_extra()?;
7688            //     let v = self.apply_pending_canonicalization(v, i)?;
7689            //     let v = v.into_int_value();
7690            //     let res = self.trunc_sat_into_int(
7691            //         self.intrinsics.f64x2_ty,
7692            //         self.intrinsics.i64x2_ty,
7693            //         u64::MIN,
7694            //         u64::MAX,
7695            //         u64::MIN,
7696            //         u64::MAX,
7697            //         v,
7698            //     )?;
7699            //     self.state.push1(res);
7700            // }
7701            Operator::I32TruncF32S => {
7702                let v1 = self.state.pop1()?.into_float_value();
7703                self.trap_if_not_representable_as_int(
7704                    0xcf000000, // -2147483600.0
7705                    0x4effffff, // 2147483500.0
7706                    v1,
7707                )?;
7708                let res = err!(self.builder.build_float_to_signed_int(
7709                    v1,
7710                    self.intrinsics.i32_ty,
7711                    ""
7712                ));
7713                self.state.push1(res);
7714            }
7715            Operator::I32TruncF64S => {
7716                let v1 = self.state.pop1()?.into_float_value();
7717                self.trap_if_not_representable_as_int(
7718                    0xc1e00000001fffff, // -2147483648.9999995
7719                    0x41dfffffffffffff, // 2147483647.9999998
7720                    v1,
7721                )?;
7722                let res = err!(self.builder.build_float_to_signed_int(
7723                    v1,
7724                    self.intrinsics.i32_ty,
7725                    ""
7726                ));
7727                self.state.push1(res);
7728            }
7729            Operator::I32TruncSatF32S => {
7730                let (v, i) = self.state.pop1_extra()?;
7731                let v = self.apply_pending_canonicalization(v, i)?;
7732                let v = v.into_float_value();
7733                let res = self.trunc_sat_scalar(
7734                    self.intrinsics.i32_ty,
7735                    LEF32_GEQ_I32_MIN,
7736                    GEF32_LEQ_I32_MAX,
7737                    i32::MIN as u32 as u64,
7738                    i32::MAX as u32 as u64,
7739                    v,
7740                )?;
7741                self.state.push1(res);
7742            }
7743            Operator::I32TruncSatF64S => {
7744                let (v, i) = self.state.pop1_extra()?;
7745                let v = self.apply_pending_canonicalization(v, i)?;
7746                let v = v.into_float_value();
7747                let res = self.trunc_sat_scalar(
7748                    self.intrinsics.i32_ty,
7749                    LEF64_GEQ_I32_MIN,
7750                    GEF64_LEQ_I32_MAX,
7751                    i32::MIN as u64,
7752                    i32::MAX as u64,
7753                    v,
7754                )?;
7755                self.state.push1(res);
7756            }
7757            Operator::I64TruncF32S => {
7758                let v1 = self.state.pop1()?.into_float_value();
7759                self.trap_if_not_representable_as_int(
7760                    0xdf000000, // -9223372000000000000.0
7761                    0x5effffff, // 9223371500000000000.0
7762                    v1,
7763                )?;
7764                let res = err!(self.builder.build_float_to_signed_int(
7765                    v1,
7766                    self.intrinsics.i64_ty,
7767                    ""
7768                ));
7769                self.state.push1(res);
7770            }
7771            Operator::I64TruncF64S => {
7772                let v1 = self.state.pop1()?.into_float_value();
7773                self.trap_if_not_representable_as_int(
7774                    0xc3e0000000000000, // -9223372036854776000.0
7775                    0x43dfffffffffffff, // 9223372036854775000.0
7776                    v1,
7777                )?;
7778                let res = err!(self.builder.build_float_to_signed_int(
7779                    v1,
7780                    self.intrinsics.i64_ty,
7781                    ""
7782                ));
7783                self.state.push1(res);
7784            }
7785            Operator::I64TruncSatF32S => {
7786                let (v, i) = self.state.pop1_extra()?;
7787                let v = self.apply_pending_canonicalization(v, i)?;
7788                let v = v.into_float_value();
7789                let res = self.trunc_sat_scalar(
7790                    self.intrinsics.i64_ty,
7791                    LEF32_GEQ_I64_MIN,
7792                    GEF32_LEQ_I64_MAX,
7793                    i64::MIN as u64,
7794                    i64::MAX as u64,
7795                    v,
7796                )?;
7797                self.state.push1(res);
7798            }
7799            Operator::I64TruncSatF64S => {
7800                let (v, i) = self.state.pop1_extra()?;
7801                let v = self.apply_pending_canonicalization(v, i)?;
7802                let v = v.into_float_value();
7803                let res = self.trunc_sat_scalar(
7804                    self.intrinsics.i64_ty,
7805                    LEF64_GEQ_I64_MIN,
7806                    GEF64_LEQ_I64_MAX,
7807                    i64::MIN as u64,
7808                    i64::MAX as u64,
7809                    v,
7810                )?;
7811                self.state.push1(res);
7812            }
7813            Operator::I32TruncF32U => {
7814                let v1 = self.state.pop1()?.into_float_value();
7815                self.trap_if_not_representable_as_int(
7816                    0xbf7fffff, // -0.99999994
7817                    0x4f7fffff, // 4294967000.0
7818                    v1,
7819                )?;
7820                let res = err!(self.builder.build_float_to_unsigned_int(
7821                    v1,
7822                    self.intrinsics.i32_ty,
7823                    ""
7824                ));
7825                self.state.push1(res);
7826            }
7827            Operator::I32TruncF64U => {
7828                let v1 = self.state.pop1()?.into_float_value();
7829                self.trap_if_not_representable_as_int(
7830                    0xbfefffffffffffff, // -0.9999999999999999
7831                    0x41efffffffffffff, // 4294967295.9999995
7832                    v1,
7833                )?;
7834                let res = err!(self.builder.build_float_to_unsigned_int(
7835                    v1,
7836                    self.intrinsics.i32_ty,
7837                    ""
7838                ));
7839                self.state.push1(res);
7840            }
7841            Operator::I32TruncSatF32U => {
7842                let (v, i) = self.state.pop1_extra()?;
7843                let v = self.apply_pending_canonicalization(v, i)?;
7844                let v = v.into_float_value();
7845                let res = self.trunc_sat_scalar(
7846                    self.intrinsics.i32_ty,
7847                    LEF32_GEQ_U32_MIN,
7848                    GEF32_LEQ_U32_MAX,
7849                    u32::MIN as u64,
7850                    u32::MAX as u64,
7851                    v,
7852                )?;
7853                self.state.push1(res);
7854            }
7855            Operator::I32TruncSatF64U => {
7856                let (v, i) = self.state.pop1_extra()?;
7857                let v = self.apply_pending_canonicalization(v, i)?;
7858                let v = v.into_float_value();
7859                let res = self.trunc_sat_scalar(
7860                    self.intrinsics.i32_ty,
7861                    LEF64_GEQ_U32_MIN,
7862                    GEF64_LEQ_U32_MAX,
7863                    u32::MIN as u64,
7864                    u32::MAX as u64,
7865                    v,
7866                )?;
7867                self.state.push1(res);
7868            }
7869            Operator::I64TruncF32U => {
7870                let v1 = self.state.pop1()?.into_float_value();
7871                self.trap_if_not_representable_as_int(
7872                    0xbf7fffff, // -0.99999994
7873                    0x5f7fffff, // 18446743000000000000.0
7874                    v1,
7875                )?;
7876                let res = err!(self.builder.build_float_to_unsigned_int(
7877                    v1,
7878                    self.intrinsics.i64_ty,
7879                    ""
7880                ));
7881                self.state.push1(res);
7882            }
7883            Operator::I64TruncF64U => {
7884                let v1 = self.state.pop1()?.into_float_value();
7885                self.trap_if_not_representable_as_int(
7886                    0xbfefffffffffffff, // -0.9999999999999999
7887                    0x43efffffffffffff, // 18446744073709550000.0
7888                    v1,
7889                )?;
7890                let res = err!(self.builder.build_float_to_unsigned_int(
7891                    v1,
7892                    self.intrinsics.i64_ty,
7893                    ""
7894                ));
7895                self.state.push1(res);
7896            }
7897            Operator::I64TruncSatF32U => {
7898                let (v, i) = self.state.pop1_extra()?;
7899                let v = self.apply_pending_canonicalization(v, i)?;
7900                let v = v.into_float_value();
7901                let res = self.trunc_sat_scalar(
7902                    self.intrinsics.i64_ty,
7903                    LEF32_GEQ_U64_MIN,
7904                    GEF32_LEQ_U64_MAX,
7905                    u64::MIN,
7906                    u64::MAX,
7907                    v,
7908                )?;
7909                self.state.push1(res);
7910            }
7911            Operator::I64TruncSatF64U => {
7912                let (v, i) = self.state.pop1_extra()?;
7913                let v = self.apply_pending_canonicalization(v, i)?;
7914                let v = v.into_float_value();
7915                let res = self.trunc_sat_scalar(
7916                    self.intrinsics.i64_ty,
7917                    LEF64_GEQ_U64_MIN,
7918                    GEF64_LEQ_U64_MAX,
7919                    u64::MIN,
7920                    u64::MAX,
7921                    v,
7922                )?;
7923                self.state.push1(res);
7924            }
7925            Operator::F32DemoteF64 => {
7926                let v = self.state.pop1()?;
7927                let v = v.into_float_value();
7928                let res = err!(self.builder.build_call(
7929                    self.intrinsics.fptrunc_f64,
7930                    &[
7931                        v.into(),
7932                        self.intrinsics.fp_rounding_md,
7933                        self.intrinsics.fp_exception_md,
7934                    ],
7935                    "",
7936                ))
7937                .try_as_basic_value()
7938                .unwrap_basic();
7939                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
7940            }
7941            Operator::F64PromoteF32 => {
7942                let v = self.state.pop1()?;
7943                let v = v.into_float_value();
7944                let res = err!(self.builder.build_call(
7945                    self.intrinsics.fpext_f32,
7946                    &[v.into(), self.intrinsics.fp_exception_md],
7947                    "",
7948                ))
7949                .try_as_basic_value()
7950                .unwrap_basic();
7951                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
7952            }
7953            Operator::F32ConvertI32S | Operator::F32ConvertI64S => {
7954                let (v, i) = self.state.pop1_extra()?;
7955                let v = self.apply_pending_canonicalization(v, i)?;
7956                let v = v.into_int_value();
7957                let res = err!(self.builder.build_signed_int_to_float(
7958                    v,
7959                    self.intrinsics.f32_ty,
7960                    ""
7961                ));
7962                self.state.push1(res);
7963            }
7964            Operator::F64ConvertI32S | Operator::F64ConvertI64S => {
7965                let (v, i) = self.state.pop1_extra()?;
7966                let v = self.apply_pending_canonicalization(v, i)?;
7967                let v = v.into_int_value();
7968                let res = err!(self.builder.build_signed_int_to_float(
7969                    v,
7970                    self.intrinsics.f64_ty,
7971                    ""
7972                ));
7973                self.state.push1(res);
7974            }
7975            Operator::F32ConvertI32U | Operator::F32ConvertI64U => {
7976                let (v, i) = self.state.pop1_extra()?;
7977                let v = self.apply_pending_canonicalization(v, i)?;
7978                let v = v.into_int_value();
7979                let res = err!(self.builder.build_unsigned_int_to_float(
7980                    v,
7981                    self.intrinsics.f32_ty,
7982                    ""
7983                ));
7984                self.state.push1(res);
7985            }
7986            Operator::F64ConvertI32U | Operator::F64ConvertI64U => {
7987                let (v, i) = self.state.pop1_extra()?;
7988                let v = self.apply_pending_canonicalization(v, i)?;
7989                let v = v.into_int_value();
7990                let res = err!(self.builder.build_unsigned_int_to_float(
7991                    v,
7992                    self.intrinsics.f64_ty,
7993                    ""
7994                ));
7995                self.state.push1(res);
7996            }
7997            Operator::F32x4ConvertI32x4S => {
7998                let v = self.state.pop1()?;
7999                let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8000                    .into_vector_value();
8001                let res = err!(self.builder.build_signed_int_to_float(
8002                    v,
8003                    self.intrinsics.f32x4_ty,
8004                    ""
8005                ));
8006                let res = err!(
8007                    self.builder
8008                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8009                );
8010                self.state.push1(res);
8011            }
8012            Operator::F32x4ConvertI32x4U => {
8013                let v = self.state.pop1()?;
8014                let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8015                    .into_vector_value();
8016                let res = err!(self.builder.build_unsigned_int_to_float(
8017                    v,
8018                    self.intrinsics.f32x4_ty,
8019                    ""
8020                ));
8021                let res = err!(
8022                    self.builder
8023                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8024                );
8025                self.state.push1(res);
8026            }
8027            Operator::F64x2ConvertLowI32x4S | Operator::F64x2ConvertLowI32x4U => {
8028                let extend = match op {
8029                    Operator::F64x2ConvertLowI32x4U => {
8030                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8031                    }
8032                    Operator::F64x2ConvertLowI32x4S => {
8033                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8034                    }
8035                    _ => unreachable!("Unhandled inner case"),
8036                };
8037                let (v, i) = self.state.pop1_extra()?;
8038                let (v, _) = self.v128_into_i32x4(v, i)?;
8039                let low = err!(self.builder.build_shuffle_vector(
8040                    v,
8041                    v.get_type().get_undef(),
8042                    VectorType::const_vector(&[
8043                        self.intrinsics.i32_consts[0],
8044                        self.intrinsics.i32_consts[1],
8045                    ]),
8046                    "",
8047                ));
8048                let res = err!(extend(self, low));
8049                let res = err!(self.builder.build_signed_int_to_float(
8050                    res,
8051                    self.intrinsics.f64x2_ty,
8052                    ""
8053                ));
8054                let res = err!(
8055                    self.builder
8056                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8057                );
8058                self.state.push1(res);
8059            }
8060            Operator::F64x2PromoteLowF32x4 => {
8061                let (v, i) = self.state.pop1_extra()?;
8062                let (v, _) = self.v128_into_f32x4(v, i)?;
8063                let low = err!(self.builder.build_shuffle_vector(
8064                    v,
8065                    v.get_type().get_undef(),
8066                    VectorType::const_vector(&[
8067                        self.intrinsics.i32_consts[0],
8068                        self.intrinsics.i32_consts[1],
8069                    ]),
8070                    "",
8071                ));
8072                let res = err!(
8073                    self.builder
8074                        .build_float_ext(low, self.intrinsics.f64x2_ty, "")
8075                );
8076                let res = err!(
8077                    self.builder
8078                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8079                );
8080                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8081            }
8082            Operator::F32x4DemoteF64x2Zero => {
8083                let (v, i) = self.state.pop1_extra()?;
8084                let (v, _) = self.v128_into_f64x2(v, i)?;
8085                let f32x2_ty = self.intrinsics.f32_ty.vec_type(2);
8086                let res = err!(self.builder.build_float_trunc(v, f32x2_ty, ""));
8087                let zeros = f32x2_ty.const_zero();
8088                let res = err!(self.builder.build_shuffle_vector(
8089                    res,
8090                    zeros,
8091                    VectorType::const_vector(&[
8092                        self.intrinsics.i32_consts[0],
8093                        self.intrinsics.i32_consts[1],
8094                        self.intrinsics.i32_consts[2],
8095                        self.intrinsics.i32_consts[3],
8096                    ]),
8097                    "",
8098                ));
8099                let res = err!(
8100                    self.builder
8101                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8102                );
8103                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8104            }
8105            // Operator::F64x2ConvertI64x2S => {
8106            //     let v = self.state.pop1()?;
8107            //     let v = self
8108            //         .builder
8109            //         .build_bit_cast(v, self.intrinsics.i64x2_ty, "")
8110            //         .into_vector_value();
8111            //     let res = self
8112            //         .builder
8113            //         .build_signed_int_to_float(v, self.intrinsics.f64x2_ty, "");
8114            //     let res = chck_err!(self.builder.build_bit_cast(res, self.intrinsics.i128_ty, ""));
8115            //     self.state.push1(res);
8116            // }
8117            // Operator::F64x2ConvertI64x2U => {
8118            //     let v = self.state.pop1()?;
8119            //     let v = self
8120            //         .builder
8121            //         .build_bit_cast(v, self.intrinsics.i64x2_ty, "")
8122            //         .into_vector_value();
8123            //     let res = self
8124            //         .builder
8125            //         .build_unsigned_int_to_float(v, self.intrinsics.f64x2_ty, "");
8126            //     let res = chck_err!(self.builder.build_bit_cast(res, self.intrinsics.i128_ty, ""));
8127            //     self.state.push1(res);
8128            // }
8129            Operator::I32ReinterpretF32 => {
8130                let (v, i) = self.state.pop1_extra()?;
8131                let v = self.apply_pending_canonicalization(v, i)?;
8132                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i32_ty, ""));
8133                self.state.push1_extra(ret, ExtraInfo::arithmetic_f32());
8134            }
8135            Operator::I64ReinterpretF64 => {
8136                let (v, i) = self.state.pop1_extra()?;
8137                let v = self.apply_pending_canonicalization(v, i)?;
8138                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i64_ty, ""));
8139                self.state.push1_extra(ret, ExtraInfo::arithmetic_f64());
8140            }
8141            Operator::F32ReinterpretI32 => {
8142                let (v, i) = self.state.pop1_extra()?;
8143                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f32_ty, ""));
8144                self.state.push1_extra(ret, i);
8145            }
8146            Operator::F64ReinterpretI64 => {
8147                let (v, i) = self.state.pop1_extra()?;
8148                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f64_ty, ""));
8149                self.state.push1_extra(ret, i);
8150            }
8151
8152            /***************************
8153             * Sign-extension operators.
8154             * https://github.com/WebAssembly/sign-extension-ops/blob/master/proposals/sign-extension-ops/Overview.md
8155             ***************************/
8156            Operator::I32Extend8S => {
8157                let value = self.state.pop1()?.into_int_value();
8158                let narrow_value = err!(self.builder.build_int_truncate(
8159                    value,
8160                    self.intrinsics.i8_ty,
8161                    ""
8162                ));
8163                let extended_value = err!(self.builder.build_int_s_extend(
8164                    narrow_value,
8165                    self.intrinsics.i32_ty,
8166                    ""
8167                ));
8168                self.state.push1(extended_value);
8169            }
8170            Operator::I32Extend16S => {
8171                let value = self.state.pop1()?.into_int_value();
8172                let narrow_value = err!(self.builder.build_int_truncate(
8173                    value,
8174                    self.intrinsics.i16_ty,
8175                    ""
8176                ));
8177                let extended_value = err!(self.builder.build_int_s_extend(
8178                    narrow_value,
8179                    self.intrinsics.i32_ty,
8180                    ""
8181                ));
8182                self.state.push1(extended_value);
8183            }
8184            Operator::I64Extend8S => {
8185                let value = self.state.pop1()?.into_int_value();
8186                let narrow_value = err!(self.builder.build_int_truncate(
8187                    value,
8188                    self.intrinsics.i8_ty,
8189                    ""
8190                ));
8191                let extended_value = err!(self.builder.build_int_s_extend(
8192                    narrow_value,
8193                    self.intrinsics.i64_ty,
8194                    ""
8195                ));
8196                self.state.push1(extended_value);
8197            }
8198            Operator::I64Extend16S => {
8199                let value = self.state.pop1()?.into_int_value();
8200                let narrow_value = err!(self.builder.build_int_truncate(
8201                    value,
8202                    self.intrinsics.i16_ty,
8203                    ""
8204                ));
8205                let extended_value = err!(self.builder.build_int_s_extend(
8206                    narrow_value,
8207                    self.intrinsics.i64_ty,
8208                    ""
8209                ));
8210                self.state.push1(extended_value);
8211            }
8212            Operator::I64Extend32S => {
8213                let value = self.state.pop1()?.into_int_value();
8214                let narrow_value = err!(self.builder.build_int_truncate(
8215                    value,
8216                    self.intrinsics.i32_ty,
8217                    ""
8218                ));
8219                let extended_value = err!(self.builder.build_int_s_extend(
8220                    narrow_value,
8221                    self.intrinsics.i64_ty,
8222                    ""
8223                ));
8224                self.state.push1(extended_value);
8225            }
8226
8227            /***************************
8228             * Load and Store instructions.
8229             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#load-and-store-instructions
8230             ***************************/
8231            Operator::I32Load { ref memarg } => {
8232                let offset = self.state.pop1()?.into_int_value();
8233                let memory_index = MemoryIndex::from_u32(0);
8234                let effective_address = self.resolve_memory_ptr(
8235                    memory_index,
8236                    memarg,
8237                    self.intrinsics.ptr_ty,
8238                    offset,
8239                    4,
8240                )?;
8241                let result = err!(self.builder.build_load(
8242                    self.intrinsics.i32_ty,
8243                    effective_address,
8244                    ""
8245                ));
8246                self.annotate_user_memaccess(
8247                    memory_index,
8248                    memarg,
8249                    1,
8250                    result.as_instruction_value().unwrap(),
8251                )?;
8252                self.state.push1(result);
8253            }
8254            Operator::I64Load { ref memarg } => {
8255                let offset = self.state.pop1()?.into_int_value();
8256                let memory_index = MemoryIndex::from_u32(0);
8257                let effective_address = self.resolve_memory_ptr(
8258                    memory_index,
8259                    memarg,
8260                    self.intrinsics.ptr_ty,
8261                    offset,
8262                    8,
8263                )?;
8264                let result = err!(self.builder.build_load(
8265                    self.intrinsics.i64_ty,
8266                    effective_address,
8267                    ""
8268                ));
8269                self.annotate_user_memaccess(
8270                    memory_index,
8271                    memarg,
8272                    1,
8273                    result.as_instruction_value().unwrap(),
8274                )?;
8275                self.state.push1(result);
8276            }
8277            Operator::F32Load { ref memarg } => {
8278                let offset = self.state.pop1()?.into_int_value();
8279                let memory_index = MemoryIndex::from_u32(0);
8280                let effective_address = self.resolve_memory_ptr(
8281                    memory_index,
8282                    memarg,
8283                    self.intrinsics.ptr_ty,
8284                    offset,
8285                    4,
8286                )?;
8287                let result = err!(self.builder.build_load(
8288                    self.intrinsics.f32_ty,
8289                    effective_address,
8290                    ""
8291                ));
8292                self.annotate_user_memaccess(
8293                    memory_index,
8294                    memarg,
8295                    1,
8296                    result.as_instruction_value().unwrap(),
8297                )?;
8298                self.state.push1(result);
8299            }
8300            Operator::F64Load { ref memarg } => {
8301                let offset = self.state.pop1()?.into_int_value();
8302                let memory_index = MemoryIndex::from_u32(0);
8303                let effective_address = self.resolve_memory_ptr(
8304                    memory_index,
8305                    memarg,
8306                    self.intrinsics.ptr_ty,
8307                    offset,
8308                    8,
8309                )?;
8310                let result = err!(self.builder.build_load(
8311                    self.intrinsics.f64_ty,
8312                    effective_address,
8313                    ""
8314                ));
8315                self.annotate_user_memaccess(
8316                    memory_index,
8317                    memarg,
8318                    1,
8319                    result.as_instruction_value().unwrap(),
8320                )?;
8321                self.state.push1(result);
8322            }
8323            Operator::V128Load { ref memarg } => {
8324                let offset = self.state.pop1()?.into_int_value();
8325                let memory_index = MemoryIndex::from_u32(0);
8326                let effective_address = self.resolve_memory_ptr(
8327                    memory_index,
8328                    memarg,
8329                    self.intrinsics.ptr_ty,
8330                    offset,
8331                    16,
8332                )?;
8333                let result = err!(self.builder.build_load(
8334                    self.intrinsics.i128_ty,
8335                    effective_address,
8336                    ""
8337                ));
8338                self.annotate_user_memaccess(
8339                    memory_index,
8340                    memarg,
8341                    1,
8342                    result.as_instruction_value().unwrap(),
8343                )?;
8344                self.state.push1(result);
8345            }
8346            Operator::V128Load8Lane { ref memarg, lane } => {
8347                let (v, i) = self.state.pop1_extra()?;
8348                let (v, _i) = self.v128_into_i8x16(v, i)?;
8349                let offset = self.state.pop1()?.into_int_value();
8350                let memory_index = MemoryIndex::from_u32(memarg.memory);
8351                let effective_address = self.resolve_memory_ptr(
8352                    memory_index,
8353                    memarg,
8354                    self.intrinsics.ptr_ty,
8355                    offset,
8356                    1,
8357                )?;
8358                let element = err!(self.builder.build_load(
8359                    self.intrinsics.i8_ty,
8360                    effective_address,
8361                    ""
8362                ));
8363                self.annotate_user_memaccess(
8364                    memory_index,
8365                    memarg,
8366                    1,
8367                    element.as_instruction_value().unwrap(),
8368                )?;
8369                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8370                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8371                let res = err!(
8372                    self.builder
8373                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8374                );
8375                self.state.push1(res);
8376            }
8377            Operator::V128Load16Lane { ref memarg, lane } => {
8378                let (v, i) = self.state.pop1_extra()?;
8379                let (v, i) = self.v128_into_i16x8(v, i)?;
8380                let offset = self.state.pop1()?.into_int_value();
8381                let memory_index = MemoryIndex::from_u32(memarg.memory);
8382                let effective_address = self.resolve_memory_ptr(
8383                    memory_index,
8384                    memarg,
8385                    self.intrinsics.ptr_ty,
8386                    offset,
8387                    2,
8388                )?;
8389                let element = err!(self.builder.build_load(
8390                    self.intrinsics.i16_ty,
8391                    effective_address,
8392                    ""
8393                ));
8394                self.annotate_user_memaccess(
8395                    memory_index,
8396                    memarg,
8397                    1,
8398                    element.as_instruction_value().unwrap(),
8399                )?;
8400                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8401                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8402                let res = err!(
8403                    self.builder
8404                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8405                );
8406                self.state.push1_extra(res, i);
8407            }
8408            Operator::V128Load32Lane { ref memarg, lane } => {
8409                let (v, i) = self.state.pop1_extra()?;
8410                let (v, i) = self.v128_into_i32x4(v, i)?;
8411                let offset = self.state.pop1()?.into_int_value();
8412                let memory_index = MemoryIndex::from_u32(memarg.memory);
8413                let effective_address = self.resolve_memory_ptr(
8414                    memory_index,
8415                    memarg,
8416                    self.intrinsics.ptr_ty,
8417                    offset,
8418                    4,
8419                )?;
8420                let element = err!(self.builder.build_load(
8421                    self.intrinsics.i32_ty,
8422                    effective_address,
8423                    ""
8424                ));
8425                self.annotate_user_memaccess(
8426                    memory_index,
8427                    memarg,
8428                    1,
8429                    element.as_instruction_value().unwrap(),
8430                )?;
8431                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8432                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8433                let res = err!(
8434                    self.builder
8435                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8436                );
8437                self.state.push1_extra(res, i);
8438            }
8439            Operator::V128Load64Lane { ref memarg, lane } => {
8440                let (v, i) = self.state.pop1_extra()?;
8441                let (v, i) = self.v128_into_i64x2(v, i)?;
8442                let offset = self.state.pop1()?.into_int_value();
8443                let memory_index = MemoryIndex::from_u32(memarg.memory);
8444                let effective_address = self.resolve_memory_ptr(
8445                    memory_index,
8446                    memarg,
8447                    self.intrinsics.ptr_ty,
8448                    offset,
8449                    8,
8450                )?;
8451                let element = err!(self.builder.build_load(
8452                    self.intrinsics.i64_ty,
8453                    effective_address,
8454                    ""
8455                ));
8456                self.annotate_user_memaccess(
8457                    memory_index,
8458                    memarg,
8459                    1,
8460                    element.as_instruction_value().unwrap(),
8461                )?;
8462                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8463                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8464                let res = err!(
8465                    self.builder
8466                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8467                );
8468                self.state.push1_extra(res, i);
8469            }
8470
8471            Operator::I32Store { ref memarg } => {
8472                let value = self.state.pop1()?;
8473                let offset = self.state.pop1()?.into_int_value();
8474                let memory_index = MemoryIndex::from_u32(0);
8475                let effective_address = self.resolve_memory_ptr(
8476                    memory_index,
8477                    memarg,
8478                    self.intrinsics.ptr_ty,
8479                    offset,
8480                    4,
8481                )?;
8482                let dead_load = err!(self.builder.build_load(
8483                    self.intrinsics.i32_ty,
8484                    effective_address,
8485                    ""
8486                ));
8487                self.annotate_user_memaccess(
8488                    memory_index,
8489                    memarg,
8490                    1,
8491                    dead_load.as_instruction_value().unwrap(),
8492                )?;
8493                let store = err!(self.builder.build_store(effective_address, value));
8494                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8495            }
8496            Operator::I64Store { ref memarg } => {
8497                let value = self.state.pop1()?;
8498                let offset = self.state.pop1()?.into_int_value();
8499                let memory_index = MemoryIndex::from_u32(0);
8500                let effective_address = self.resolve_memory_ptr(
8501                    memory_index,
8502                    memarg,
8503                    self.intrinsics.ptr_ty,
8504                    offset,
8505                    8,
8506                )?;
8507                let dead_load = err!(self.builder.build_load(
8508                    self.intrinsics.i64_ty,
8509                    effective_address,
8510                    ""
8511                ));
8512                self.annotate_user_memaccess(
8513                    memory_index,
8514                    memarg,
8515                    1,
8516                    dead_load.as_instruction_value().unwrap(),
8517                )?;
8518                let store = err!(self.builder.build_store(effective_address, value));
8519                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8520            }
8521            Operator::F32Store { ref memarg } => {
8522                let (v, i) = self.state.pop1_extra()?;
8523                let v = self.apply_pending_canonicalization(v, i)?;
8524                let offset = self.state.pop1()?.into_int_value();
8525                let memory_index = MemoryIndex::from_u32(0);
8526                let effective_address = self.resolve_memory_ptr(
8527                    memory_index,
8528                    memarg,
8529                    self.intrinsics.ptr_ty,
8530                    offset,
8531                    4,
8532                )?;
8533                let dead_load = err!(self.builder.build_load(
8534                    self.intrinsics.f32_ty,
8535                    effective_address,
8536                    ""
8537                ));
8538                self.annotate_user_memaccess(
8539                    memory_index,
8540                    memarg,
8541                    1,
8542                    dead_load.as_instruction_value().unwrap(),
8543                )?;
8544                let store = err!(self.builder.build_store(effective_address, v));
8545                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8546            }
8547            Operator::F64Store { ref memarg } => {
8548                let (v, i) = self.state.pop1_extra()?;
8549                let v = self.apply_pending_canonicalization(v, i)?;
8550                let offset = self.state.pop1()?.into_int_value();
8551                let memory_index = MemoryIndex::from_u32(0);
8552                let effective_address = self.resolve_memory_ptr(
8553                    memory_index,
8554                    memarg,
8555                    self.intrinsics.ptr_ty,
8556                    offset,
8557                    8,
8558                )?;
8559                let dead_load = err!(self.builder.build_load(
8560                    self.intrinsics.f64_ty,
8561                    effective_address,
8562                    ""
8563                ));
8564                self.annotate_user_memaccess(
8565                    memory_index,
8566                    memarg,
8567                    1,
8568                    dead_load.as_instruction_value().unwrap(),
8569                )?;
8570                let store = err!(self.builder.build_store(effective_address, v));
8571                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8572            }
8573            Operator::V128Store { ref memarg } => {
8574                let (v, i) = self.state.pop1_extra()?;
8575                let v = self.apply_pending_canonicalization(v, i)?;
8576                let offset = self.state.pop1()?.into_int_value();
8577                let memory_index = MemoryIndex::from_u32(0);
8578                let effective_address = self.resolve_memory_ptr(
8579                    memory_index,
8580                    memarg,
8581                    self.intrinsics.ptr_ty,
8582                    offset,
8583                    16,
8584                )?;
8585                let dead_load = err!(self.builder.build_load(
8586                    self.intrinsics.i128_ty,
8587                    effective_address,
8588                    ""
8589                ));
8590                self.annotate_user_memaccess(
8591                    memory_index,
8592                    memarg,
8593                    1,
8594                    dead_load.as_instruction_value().unwrap(),
8595                )?;
8596                let store = err!(self.builder.build_store(effective_address, v));
8597                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8598            }
8599            Operator::V128Store8Lane { ref memarg, lane } => {
8600                let (v, i) = self.state.pop1_extra()?;
8601                let (v, _i) = self.v128_into_i8x16(v, i)?;
8602                let offset = self.state.pop1()?.into_int_value();
8603                let memory_index = MemoryIndex::from_u32(memarg.memory);
8604
8605                let effective_address = self.resolve_memory_ptr(
8606                    memory_index,
8607                    memarg,
8608                    self.intrinsics.ptr_ty,
8609                    offset,
8610                    1,
8611                )?;
8612                let dead_load = err!(self.builder.build_load(
8613                    self.intrinsics.i8_ty,
8614                    effective_address,
8615                    ""
8616                ));
8617                self.annotate_user_memaccess(
8618                    memory_index,
8619                    memarg,
8620                    1,
8621                    dead_load.as_instruction_value().unwrap(),
8622                )?;
8623                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8624                let val = err!(self.builder.build_extract_element(v, idx, ""));
8625                let store = err!(self.builder.build_store(effective_address, val));
8626                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8627            }
8628            Operator::V128Store16Lane { ref memarg, lane } => {
8629                let (v, i) = self.state.pop1_extra()?;
8630                let (v, _i) = self.v128_into_i16x8(v, i)?;
8631                let offset = self.state.pop1()?.into_int_value();
8632                let memory_index = MemoryIndex::from_u32(memarg.memory);
8633
8634                let effective_address = self.resolve_memory_ptr(
8635                    memory_index,
8636                    memarg,
8637                    self.intrinsics.ptr_ty,
8638                    offset,
8639                    2,
8640                )?;
8641                let dead_load = err!(self.builder.build_load(
8642                    self.intrinsics.i16_ty,
8643                    effective_address,
8644                    ""
8645                ));
8646                self.annotate_user_memaccess(
8647                    memory_index,
8648                    memarg,
8649                    1,
8650                    dead_load.as_instruction_value().unwrap(),
8651                )?;
8652                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8653                let val = err!(self.builder.build_extract_element(v, idx, ""));
8654                let store = err!(self.builder.build_store(effective_address, val));
8655                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8656            }
8657            Operator::V128Store32Lane { ref memarg, lane } => {
8658                let (v, i) = self.state.pop1_extra()?;
8659                let (v, _i) = self.v128_into_i32x4(v, i)?;
8660                let offset = self.state.pop1()?.into_int_value();
8661                let memory_index = MemoryIndex::from_u32(memarg.memory);
8662
8663                let effective_address = self.resolve_memory_ptr(
8664                    memory_index,
8665                    memarg,
8666                    self.intrinsics.ptr_ty,
8667                    offset,
8668                    4,
8669                )?;
8670                let dead_load = err!(self.builder.build_load(
8671                    self.intrinsics.i32_ty,
8672                    effective_address,
8673                    ""
8674                ));
8675                self.annotate_user_memaccess(
8676                    memory_index,
8677                    memarg,
8678                    1,
8679                    dead_load.as_instruction_value().unwrap(),
8680                )?;
8681                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8682                let val = err!(self.builder.build_extract_element(v, idx, ""));
8683                let store = err!(self.builder.build_store(effective_address, val));
8684                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8685            }
8686            Operator::V128Store64Lane { ref memarg, lane } => {
8687                let (v, i) = self.state.pop1_extra()?;
8688                let (v, _i) = self.v128_into_i64x2(v, i)?;
8689                let offset = self.state.pop1()?.into_int_value();
8690                let memory_index = MemoryIndex::from_u32(memarg.memory);
8691
8692                let effective_address = self.resolve_memory_ptr(
8693                    memory_index,
8694                    memarg,
8695                    self.intrinsics.ptr_ty,
8696                    offset,
8697                    8,
8698                )?;
8699                let dead_load = err!(self.builder.build_load(
8700                    self.intrinsics.i64_ty,
8701                    effective_address,
8702                    ""
8703                ));
8704                self.annotate_user_memaccess(
8705                    memory_index,
8706                    memarg,
8707                    1,
8708                    dead_load.as_instruction_value().unwrap(),
8709                )?;
8710                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8711                let val = err!(self.builder.build_extract_element(v, idx, ""));
8712                let store = err!(self.builder.build_store(effective_address, val));
8713                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8714            }
8715            Operator::I32Load8S { ref memarg } => {
8716                let offset = self.state.pop1()?.into_int_value();
8717                let memory_index = MemoryIndex::from_u32(0);
8718                let effective_address = self.resolve_memory_ptr(
8719                    memory_index,
8720                    memarg,
8721                    self.intrinsics.ptr_ty,
8722                    offset,
8723                    1,
8724                )?;
8725                let narrow_result = err!(self.builder.build_load(
8726                    self.intrinsics.i8_ty,
8727                    effective_address,
8728                    ""
8729                ));
8730                self.annotate_user_memaccess(
8731                    memory_index,
8732                    memarg,
8733                    1,
8734                    narrow_result.as_instruction_value().unwrap(),
8735                )?;
8736                let result = err!(self.builder.build_int_s_extend(
8737                    narrow_result.into_int_value(),
8738                    self.intrinsics.i32_ty,
8739                    "",
8740                ));
8741                self.state.push1(result);
8742            }
8743            Operator::I32Load16S { ref memarg } => {
8744                let offset = self.state.pop1()?.into_int_value();
8745                let memory_index = MemoryIndex::from_u32(0);
8746                let effective_address = self.resolve_memory_ptr(
8747                    memory_index,
8748                    memarg,
8749                    self.intrinsics.ptr_ty,
8750                    offset,
8751                    2,
8752                )?;
8753                let narrow_result = err!(self.builder.build_load(
8754                    self.intrinsics.i16_ty,
8755                    effective_address,
8756                    ""
8757                ));
8758                self.annotate_user_memaccess(
8759                    memory_index,
8760                    memarg,
8761                    1,
8762                    narrow_result.as_instruction_value().unwrap(),
8763                )?;
8764                let result = err!(self.builder.build_int_s_extend(
8765                    narrow_result.into_int_value(),
8766                    self.intrinsics.i32_ty,
8767                    "",
8768                ));
8769                self.state.push1(result);
8770            }
8771            Operator::I64Load8S { ref memarg } => {
8772                let offset = self.state.pop1()?.into_int_value();
8773                let memory_index = MemoryIndex::from_u32(0);
8774                let effective_address = self.resolve_memory_ptr(
8775                    memory_index,
8776                    memarg,
8777                    self.intrinsics.ptr_ty,
8778                    offset,
8779                    1,
8780                )?;
8781                let narrow_result = err!(self.builder.build_load(
8782                    self.intrinsics.i8_ty,
8783                    effective_address,
8784                    ""
8785                ))
8786                .into_int_value();
8787                self.annotate_user_memaccess(
8788                    memory_index,
8789                    memarg,
8790                    1,
8791                    narrow_result.as_instruction_value().unwrap(),
8792                )?;
8793                let result = err!(self.builder.build_int_s_extend(
8794                    narrow_result,
8795                    self.intrinsics.i64_ty,
8796                    ""
8797                ));
8798                self.state.push1(result);
8799            }
8800            Operator::I64Load16S { ref memarg } => {
8801                let offset = self.state.pop1()?.into_int_value();
8802                let memory_index = MemoryIndex::from_u32(0);
8803                let effective_address = self.resolve_memory_ptr(
8804                    memory_index,
8805                    memarg,
8806                    self.intrinsics.ptr_ty,
8807                    offset,
8808                    2,
8809                )?;
8810                let narrow_result = err!(self.builder.build_load(
8811                    self.intrinsics.i16_ty,
8812                    effective_address,
8813                    ""
8814                ))
8815                .into_int_value();
8816                self.annotate_user_memaccess(
8817                    memory_index,
8818                    memarg,
8819                    1,
8820                    narrow_result.as_instruction_value().unwrap(),
8821                )?;
8822                let result = err!(self.builder.build_int_s_extend(
8823                    narrow_result,
8824                    self.intrinsics.i64_ty,
8825                    ""
8826                ));
8827                self.state.push1(result);
8828            }
8829            Operator::I64Load32S { ref memarg } => {
8830                let offset = self.state.pop1()?.into_int_value();
8831                let memory_index = MemoryIndex::from_u32(0);
8832                let effective_address = self.resolve_memory_ptr(
8833                    memory_index,
8834                    memarg,
8835                    self.intrinsics.ptr_ty,
8836                    offset,
8837                    4,
8838                )?;
8839                let narrow_result = err!(self.builder.build_load(
8840                    self.intrinsics.i32_ty,
8841                    effective_address,
8842                    ""
8843                ));
8844                self.annotate_user_memaccess(
8845                    memory_index,
8846                    memarg,
8847                    1,
8848                    narrow_result.as_instruction_value().unwrap(),
8849                )?;
8850                let result = err!(self.builder.build_int_s_extend(
8851                    narrow_result.into_int_value(),
8852                    self.intrinsics.i64_ty,
8853                    "",
8854                ));
8855                self.state.push1(result);
8856            }
8857
8858            Operator::I32Load8U { ref memarg } => {
8859                let offset = self.state.pop1()?.into_int_value();
8860                let memory_index = MemoryIndex::from_u32(0);
8861                let effective_address = self.resolve_memory_ptr(
8862                    memory_index,
8863                    memarg,
8864                    self.intrinsics.ptr_ty,
8865                    offset,
8866                    1,
8867                )?;
8868                let narrow_result = err!(self.builder.build_load(
8869                    self.intrinsics.i8_ty,
8870                    effective_address,
8871                    ""
8872                ));
8873                self.annotate_user_memaccess(
8874                    memory_index,
8875                    memarg,
8876                    1,
8877                    narrow_result.as_instruction_value().unwrap(),
8878                )?;
8879                let result = err!(self.builder.build_int_z_extend(
8880                    narrow_result.into_int_value(),
8881                    self.intrinsics.i32_ty,
8882                    "",
8883                ));
8884                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8885            }
8886            Operator::I32Load16U { ref memarg } => {
8887                let offset = self.state.pop1()?.into_int_value();
8888                let memory_index = MemoryIndex::from_u32(0);
8889                let effective_address = self.resolve_memory_ptr(
8890                    memory_index,
8891                    memarg,
8892                    self.intrinsics.ptr_ty,
8893                    offset,
8894                    2,
8895                )?;
8896                let narrow_result = err!(self.builder.build_load(
8897                    self.intrinsics.i16_ty,
8898                    effective_address,
8899                    ""
8900                ));
8901                self.annotate_user_memaccess(
8902                    memory_index,
8903                    memarg,
8904                    1,
8905                    narrow_result.as_instruction_value().unwrap(),
8906                )?;
8907                let result = err!(self.builder.build_int_z_extend(
8908                    narrow_result.into_int_value(),
8909                    self.intrinsics.i32_ty,
8910                    "",
8911                ));
8912                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8913            }
8914            Operator::I64Load8U { ref memarg } => {
8915                let offset = self.state.pop1()?.into_int_value();
8916                let memory_index = MemoryIndex::from_u32(0);
8917                let effective_address = self.resolve_memory_ptr(
8918                    memory_index,
8919                    memarg,
8920                    self.intrinsics.ptr_ty,
8921                    offset,
8922                    1,
8923                )?;
8924                let narrow_result = err!(self.builder.build_load(
8925                    self.intrinsics.i8_ty,
8926                    effective_address,
8927                    ""
8928                ));
8929                self.annotate_user_memaccess(
8930                    memory_index,
8931                    memarg,
8932                    1,
8933                    narrow_result.as_instruction_value().unwrap(),
8934                )?;
8935                let result = err!(self.builder.build_int_z_extend(
8936                    narrow_result.into_int_value(),
8937                    self.intrinsics.i64_ty,
8938                    "",
8939                ));
8940                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8941            }
8942            Operator::I64Load16U { ref memarg } => {
8943                let offset = self.state.pop1()?.into_int_value();
8944                let memory_index = MemoryIndex::from_u32(0);
8945                let effective_address = self.resolve_memory_ptr(
8946                    memory_index,
8947                    memarg,
8948                    self.intrinsics.ptr_ty,
8949                    offset,
8950                    2,
8951                )?;
8952                let narrow_result = err!(self.builder.build_load(
8953                    self.intrinsics.i16_ty,
8954                    effective_address,
8955                    ""
8956                ));
8957                self.annotate_user_memaccess(
8958                    memory_index,
8959                    memarg,
8960                    1,
8961                    narrow_result.as_instruction_value().unwrap(),
8962                )?;
8963                let result = err!(self.builder.build_int_z_extend(
8964                    narrow_result.into_int_value(),
8965                    self.intrinsics.i64_ty,
8966                    "",
8967                ));
8968                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8969            }
8970            Operator::I64Load32U { ref memarg } => {
8971                let offset = self.state.pop1()?.into_int_value();
8972                let memory_index = MemoryIndex::from_u32(0);
8973                let effective_address = self.resolve_memory_ptr(
8974                    memory_index,
8975                    memarg,
8976                    self.intrinsics.ptr_ty,
8977                    offset,
8978                    4,
8979                )?;
8980                let narrow_result = err!(self.builder.build_load(
8981                    self.intrinsics.i32_ty,
8982                    effective_address,
8983                    ""
8984                ));
8985                self.annotate_user_memaccess(
8986                    memory_index,
8987                    memarg,
8988                    1,
8989                    narrow_result.as_instruction_value().unwrap(),
8990                )?;
8991                let result = err!(self.builder.build_int_z_extend(
8992                    narrow_result.into_int_value(),
8993                    self.intrinsics.i64_ty,
8994                    "",
8995                ));
8996                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8997            }
8998
8999            Operator::I32Store8 { ref memarg } | Operator::I64Store8 { ref memarg } => {
9000                let value = self.state.pop1()?.into_int_value();
9001                let offset = self.state.pop1()?.into_int_value();
9002                let memory_index = MemoryIndex::from_u32(0);
9003                let effective_address = self.resolve_memory_ptr(
9004                    memory_index,
9005                    memarg,
9006                    self.intrinsics.ptr_ty,
9007                    offset,
9008                    1,
9009                )?;
9010                let dead_load = err!(self.builder.build_load(
9011                    self.intrinsics.i8_ty,
9012                    effective_address,
9013                    ""
9014                ));
9015                self.annotate_user_memaccess(
9016                    memory_index,
9017                    memarg,
9018                    1,
9019                    dead_load.as_instruction_value().unwrap(),
9020                )?;
9021                let narrow_value = err!(self.builder.build_int_truncate(
9022                    value,
9023                    self.intrinsics.i8_ty,
9024                    ""
9025                ));
9026                let store = err!(self.builder.build_store(effective_address, narrow_value));
9027                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9028            }
9029            Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
9030                let value = self.state.pop1()?.into_int_value();
9031                let offset = self.state.pop1()?.into_int_value();
9032                let memory_index = MemoryIndex::from_u32(0);
9033                let effective_address = self.resolve_memory_ptr(
9034                    memory_index,
9035                    memarg,
9036                    self.intrinsics.ptr_ty,
9037                    offset,
9038                    2,
9039                )?;
9040                let dead_load = err!(self.builder.build_load(
9041                    self.intrinsics.i16_ty,
9042                    effective_address,
9043                    ""
9044                ));
9045                self.annotate_user_memaccess(
9046                    memory_index,
9047                    memarg,
9048                    1,
9049                    dead_load.as_instruction_value().unwrap(),
9050                )?;
9051                let narrow_value = err!(self.builder.build_int_truncate(
9052                    value,
9053                    self.intrinsics.i16_ty,
9054                    ""
9055                ));
9056                let store = err!(self.builder.build_store(effective_address, narrow_value));
9057                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9058            }
9059            Operator::I64Store32 { ref memarg } => {
9060                let value = self.state.pop1()?.into_int_value();
9061                let offset = self.state.pop1()?.into_int_value();
9062                let memory_index = MemoryIndex::from_u32(0);
9063                let effective_address = self.resolve_memory_ptr(
9064                    memory_index,
9065                    memarg,
9066                    self.intrinsics.ptr_ty,
9067                    offset,
9068                    4,
9069                )?;
9070                let dead_load = err!(self.builder.build_load(
9071                    self.intrinsics.i32_ty,
9072                    effective_address,
9073                    ""
9074                ));
9075                self.annotate_user_memaccess(
9076                    memory_index,
9077                    memarg,
9078                    1,
9079                    dead_load.as_instruction_value().unwrap(),
9080                )?;
9081                let narrow_value = err!(self.builder.build_int_truncate(
9082                    value,
9083                    self.intrinsics.i32_ty,
9084                    ""
9085                ));
9086                let store = err!(self.builder.build_store(effective_address, narrow_value));
9087                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9088            }
9089            Operator::I8x16Neg => {
9090                let (v, i) = self.state.pop1_extra()?;
9091                let (v, _) = self.v128_into_i8x16(v, i)?;
9092                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9093                let res = err!(
9094                    self.builder
9095                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9096                );
9097                self.state.push1(res);
9098            }
9099            Operator::I16x8Neg => {
9100                let (v, i) = self.state.pop1_extra()?;
9101                let (v, _) = self.v128_into_i16x8(v, i)?;
9102                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9103                let res = err!(
9104                    self.builder
9105                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9106                );
9107                self.state.push1(res);
9108            }
9109            Operator::I32x4Neg => {
9110                let (v, i) = self.state.pop1_extra()?;
9111                let (v, _) = self.v128_into_i32x4(v, i)?;
9112                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9113                let res = err!(
9114                    self.builder
9115                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9116                );
9117                self.state.push1(res);
9118            }
9119            Operator::I64x2Neg => {
9120                let (v, i) = self.state.pop1_extra()?;
9121                let (v, _) = self.v128_into_i64x2(v, i)?;
9122                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9123                let res = err!(
9124                    self.builder
9125                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9126                );
9127                self.state.push1(res);
9128            }
9129            Operator::V128Not => {
9130                let (v, i) = self.state.pop1_extra()?;
9131                let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9132                let res = err!(self.builder.build_not(v, ""));
9133                self.state.push1(res);
9134            }
9135            Operator::V128AnyTrue => {
9136                // | Operator::I64x2AnyTrue
9137                // Skip canonicalization, it never changes non-zero values to zero or vice versa.
9138                let v = self.state.pop1()?.into_int_value();
9139                let res = err!(self.builder.build_int_compare(
9140                    IntPredicate::NE,
9141                    v,
9142                    v.get_type().const_zero(),
9143                    "",
9144                ));
9145                let res = err!(
9146                    self.builder
9147                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9148                );
9149                self.state.push1_extra(
9150                    res,
9151                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9152                );
9153            }
9154            Operator::I8x16AllTrue
9155            | Operator::I16x8AllTrue
9156            | Operator::I32x4AllTrue
9157            | Operator::I64x2AllTrue => {
9158                let vec_ty = match op {
9159                    Operator::I8x16AllTrue => self.intrinsics.i8x16_ty,
9160                    Operator::I16x8AllTrue => self.intrinsics.i16x8_ty,
9161                    Operator::I32x4AllTrue => self.intrinsics.i32x4_ty,
9162                    Operator::I64x2AllTrue => self.intrinsics.i64x2_ty,
9163                    _ => unreachable!(),
9164                };
9165                let (v, i) = self.state.pop1_extra()?;
9166                let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9167                let lane_int_ty = self.context.custom_width_int_type(vec_ty.get_size());
9168                let vec = err!(self.builder.build_bit_cast(v, vec_ty, "vec")).into_vector_value();
9169                let mask = err!(self.builder.build_int_compare(
9170                    IntPredicate::NE,
9171                    vec,
9172                    vec_ty.const_zero(),
9173                    "mask",
9174                ));
9175                let cmask =
9176                    err!(self.builder.build_bit_cast(mask, lane_int_ty, "cmask")).into_int_value();
9177                let res = err!(self.builder.build_int_compare(
9178                    IntPredicate::EQ,
9179                    cmask,
9180                    lane_int_ty.const_int(u64::MAX, true),
9181                    "",
9182                ));
9183                let res = err!(
9184                    self.builder
9185                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9186                );
9187                self.state.push1_extra(
9188                    res,
9189                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9190                );
9191            }
9192            Operator::I8x16ExtractLaneS { lane } => {
9193                let (v, i) = self.state.pop1_extra()?;
9194                let (v, _) = self.v128_into_i8x16(v, i)?;
9195                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9196                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9197                let res = err!(
9198                    self.builder
9199                        .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9200                );
9201                self.state.push1(res);
9202            }
9203            Operator::I8x16ExtractLaneU { lane } => {
9204                let (v, i) = self.state.pop1_extra()?;
9205                let (v, _) = self.v128_into_i8x16(v, i)?;
9206                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9207                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9208                let res = err!(
9209                    self.builder
9210                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9211                );
9212                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9213            }
9214            Operator::I16x8ExtractLaneS { lane } => {
9215                let (v, i) = self.state.pop1_extra()?;
9216                let (v, _) = self.v128_into_i16x8(v, i)?;
9217                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9218                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9219                let res = err!(
9220                    self.builder
9221                        .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9222                );
9223                self.state.push1(res);
9224            }
9225            Operator::I16x8ExtractLaneU { lane } => {
9226                let (v, i) = self.state.pop1_extra()?;
9227                let (v, _) = self.v128_into_i16x8(v, i)?;
9228                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9229                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9230                let res = err!(
9231                    self.builder
9232                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9233                );
9234                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9235            }
9236            Operator::I32x4ExtractLane { lane } => {
9237                let (v, i) = self.state.pop1_extra()?;
9238                let (v, i) = self.v128_into_i32x4(v, i)?;
9239                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9240                let res = err!(self.builder.build_extract_element(v, idx, ""));
9241                self.state.push1_extra(res, i);
9242            }
9243            Operator::I64x2ExtractLane { lane } => {
9244                let (v, i) = self.state.pop1_extra()?;
9245                let (v, i) = self.v128_into_i64x2(v, i)?;
9246                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9247                let res = err!(self.builder.build_extract_element(v, idx, ""));
9248                self.state.push1_extra(res, i);
9249            }
9250            Operator::F32x4ExtractLane { lane } => {
9251                let (v, i) = self.state.pop1_extra()?;
9252                let (v, i) = self.v128_into_f32x4(v, i)?;
9253                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9254                let res = err!(self.builder.build_extract_element(v, idx, ""));
9255                self.state.push1_extra(res, i);
9256            }
9257            Operator::F64x2ExtractLane { lane } => {
9258                let (v, i) = self.state.pop1_extra()?;
9259                let (v, i) = self.v128_into_f64x2(v, i)?;
9260                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9261                let res = err!(self.builder.build_extract_element(v, idx, ""));
9262                self.state.push1_extra(res, i);
9263            }
9264            Operator::I8x16ReplaceLane { lane } => {
9265                let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9266                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
9267                let v2 = v2.into_int_value();
9268                let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i8_ty, ""));
9269                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9270                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9271                let res = err!(
9272                    self.builder
9273                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9274                );
9275                self.state.push1(res);
9276            }
9277            Operator::I16x8ReplaceLane { lane } => {
9278                let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9279                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
9280                let v2 = v2.into_int_value();
9281                let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i16_ty, ""));
9282                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9283                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9284                let res = err!(
9285                    self.builder
9286                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9287                );
9288                self.state.push1(res);
9289            }
9290            Operator::I32x4ReplaceLane { lane } => {
9291                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9292                let (v1, i1) = self.v128_into_i32x4(v1, i1)?;
9293                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9294                let v2 = v2.into_int_value();
9295                let i2 = i2.strip_pending();
9296                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9297                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9298                let res = err!(
9299                    self.builder
9300                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9301                );
9302                self.state
9303                    .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f32())?);
9304            }
9305            Operator::I64x2ReplaceLane { lane } => {
9306                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9307                let (v1, i1) = self.v128_into_i64x2(v1, i1)?;
9308                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9309                let v2 = v2.into_int_value();
9310                let i2 = i2.strip_pending();
9311                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9312                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9313                let res = err!(
9314                    self.builder
9315                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9316                );
9317                self.state
9318                    .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f64())?);
9319            }
9320            Operator::F32x4ReplaceLane { lane } => {
9321                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9322                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
9323                let push_pending_f32_nan_to_result =
9324                    i1.has_pending_f32_nan() && i2.has_pending_f32_nan();
9325                let (v1, v2) = if !push_pending_f32_nan_to_result {
9326                    (
9327                        self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9328                            .into_vector_value(),
9329                        self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9330                            .into_float_value(),
9331                    )
9332                } else {
9333                    (v1, v2.into_float_value())
9334                };
9335                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9336                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9337                let res = err!(
9338                    self.builder
9339                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9340                );
9341                let info = if push_pending_f32_nan_to_result {
9342                    ExtraInfo::pending_f32_nan()
9343                } else {
9344                    (i1.strip_pending() & i2.strip_pending())?
9345                };
9346                self.state.push1_extra(res, info);
9347            }
9348            Operator::F64x2ReplaceLane { lane } => {
9349                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9350                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
9351                let push_pending_f64_nan_to_result =
9352                    i1.has_pending_f64_nan() && i2.has_pending_f64_nan();
9353                let (v1, v2) = if !push_pending_f64_nan_to_result {
9354                    (
9355                        self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9356                            .into_vector_value(),
9357                        self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9358                            .into_float_value(),
9359                    )
9360                } else {
9361                    (v1, v2.into_float_value())
9362                };
9363                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9364                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9365                let res = err!(
9366                    self.builder
9367                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9368                );
9369                let info = if push_pending_f64_nan_to_result {
9370                    ExtraInfo::pending_f64_nan()
9371                } else {
9372                    (i1.strip_pending() & i2.strip_pending())?
9373                };
9374                self.state.push1_extra(res, info);
9375            }
9376            Operator::I8x16Swizzle => {
9377                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9378                let v1 = self.apply_pending_canonicalization(v1, i1)?;
9379                let v1 = err!(
9380                    self.builder
9381                        .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9382                )
9383                .into_vector_value();
9384                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9385                let v2 = err!(
9386                    self.builder
9387                        .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9388                )
9389                .into_vector_value();
9390                let lanes = self.intrinsics.i8_ty.const_int(16, false);
9391                let lanes =
9392                    self.splat_vector(lanes.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
9393                let mut res = self.intrinsics.i8x16_ty.get_undef();
9394                let idx_out_of_range = err!(self.builder.build_int_compare(
9395                    IntPredicate::UGE,
9396                    v2,
9397                    lanes,
9398                    "idx_out_of_range",
9399                ));
9400                let idx_clamped = err!(self.builder.build_select(
9401                    idx_out_of_range,
9402                    self.intrinsics.i8x16_ty.const_zero(),
9403                    v2,
9404                    "idx_clamped",
9405                ))
9406                .into_vector_value();
9407                for i in 0..16 {
9408                    let idx = err!(self.builder.build_extract_element(
9409                        idx_clamped,
9410                        self.intrinsics.i32_ty.const_int(i, false),
9411                        "idx",
9412                    ))
9413                    .into_int_value();
9414                    let replace_with_zero = err!(self.builder.build_extract_element(
9415                        idx_out_of_range,
9416                        self.intrinsics.i32_ty.const_int(i, false),
9417                        "replace_with_zero",
9418                    ))
9419                    .into_int_value();
9420                    let elem =
9421                        err!(self.builder.build_extract_element(v1, idx, "elem")).into_int_value();
9422                    let elem_or_zero = err!(self.builder.build_select(
9423                        replace_with_zero,
9424                        self.intrinsics.i8_zero,
9425                        elem,
9426                        "elem_or_zero",
9427                    ));
9428                    res = err!(self.builder.build_insert_element(
9429                        res,
9430                        elem_or_zero,
9431                        self.intrinsics.i32_ty.const_int(i, false),
9432                        "",
9433                    ));
9434                }
9435                let res = err!(
9436                    self.builder
9437                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9438                );
9439                self.state.push1(res);
9440            }
9441            Operator::I8x16Shuffle { lanes } => {
9442                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9443                let v1 = self.apply_pending_canonicalization(v1, i1)?;
9444                let v1 = err!(
9445                    self.builder
9446                        .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9447                )
9448                .into_vector_value();
9449                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9450                let v2 = err!(
9451                    self.builder
9452                        .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9453                )
9454                .into_vector_value();
9455                let mask = VectorType::const_vector(
9456                    lanes
9457                        .iter()
9458                        .map(|l| self.intrinsics.i32_ty.const_int((*l).into(), false))
9459                        .collect::<Vec<IntValue>>()
9460                        .as_slice(),
9461                );
9462                let res = err!(self.builder.build_shuffle_vector(v1, v2, mask, ""));
9463                let res = err!(
9464                    self.builder
9465                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9466                );
9467                self.state.push1(res);
9468            }
9469            Operator::V128Load8x8S { ref memarg } => {
9470                let offset = self.state.pop1()?.into_int_value();
9471                let memory_index = MemoryIndex::from_u32(0);
9472                let effective_address = self.resolve_memory_ptr(
9473                    memory_index,
9474                    memarg,
9475                    self.intrinsics.ptr_ty,
9476                    offset,
9477                    8,
9478                )?;
9479                let v = err!(self.builder.build_load(
9480                    self.intrinsics.i64_ty,
9481                    effective_address,
9482                    ""
9483                ));
9484                let v = err!(
9485                    self.builder
9486                        .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9487                )
9488                .into_vector_value();
9489                let res = err!(
9490                    self.builder
9491                        .build_int_s_extend(v, self.intrinsics.i16x8_ty, "")
9492                );
9493                let res = err!(
9494                    self.builder
9495                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9496                );
9497                self.state.push1(res);
9498            }
9499            Operator::V128Load8x8U { ref memarg } => {
9500                let offset = self.state.pop1()?.into_int_value();
9501                let memory_index = MemoryIndex::from_u32(0);
9502                let effective_address = self.resolve_memory_ptr(
9503                    memory_index,
9504                    memarg,
9505                    self.intrinsics.ptr_ty,
9506                    offset,
9507                    8,
9508                )?;
9509                let v = err!(self.builder.build_load(
9510                    self.intrinsics.i64_ty,
9511                    effective_address,
9512                    ""
9513                ));
9514                let v = err!(
9515                    self.builder
9516                        .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9517                )
9518                .into_vector_value();
9519                let res = err!(
9520                    self.builder
9521                        .build_int_z_extend(v, self.intrinsics.i16x8_ty, "")
9522                );
9523                let res = err!(
9524                    self.builder
9525                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9526                );
9527                self.state.push1(res);
9528            }
9529            Operator::V128Load16x4S { ref memarg } => {
9530                let offset = self.state.pop1()?.into_int_value();
9531                let memory_index = MemoryIndex::from_u32(0);
9532                let effective_address = self.resolve_memory_ptr(
9533                    memory_index,
9534                    memarg,
9535                    self.intrinsics.ptr_ty,
9536                    offset,
9537                    8,
9538                )?;
9539                let v = err!(self.builder.build_load(
9540                    self.intrinsics.i64_ty,
9541                    effective_address,
9542                    ""
9543                ));
9544                let v = err!(self.builder.build_bit_cast(
9545                    v,
9546                    self.intrinsics.i16_ty.vec_type(4),
9547                    ""
9548                ))
9549                .into_vector_value();
9550                let res = err!(
9551                    self.builder
9552                        .build_int_s_extend(v, self.intrinsics.i32x4_ty, "")
9553                );
9554                let res = err!(
9555                    self.builder
9556                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9557                );
9558                self.state.push1(res);
9559            }
9560            Operator::V128Load16x4U { ref memarg } => {
9561                let offset = self.state.pop1()?.into_int_value();
9562                let memory_index = MemoryIndex::from_u32(0);
9563                let effective_address = self.resolve_memory_ptr(
9564                    memory_index,
9565                    memarg,
9566                    self.intrinsics.ptr_ty,
9567                    offset,
9568                    8,
9569                )?;
9570                let v = err!(self.builder.build_load(
9571                    self.intrinsics.i64_ty,
9572                    effective_address,
9573                    ""
9574                ));
9575                let v = err!(self.builder.build_bit_cast(
9576                    v,
9577                    self.intrinsics.i16_ty.vec_type(4),
9578                    ""
9579                ))
9580                .into_vector_value();
9581                let res = err!(
9582                    self.builder
9583                        .build_int_z_extend(v, self.intrinsics.i32x4_ty, "")
9584                );
9585                let res = err!(
9586                    self.builder
9587                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9588                );
9589                self.state.push1(res);
9590            }
9591            Operator::V128Load32x2S { ref memarg } => {
9592                let offset = self.state.pop1()?.into_int_value();
9593                let memory_index = MemoryIndex::from_u32(0);
9594                let effective_address = self.resolve_memory_ptr(
9595                    memory_index,
9596                    memarg,
9597                    self.intrinsics.ptr_ty,
9598                    offset,
9599                    8,
9600                )?;
9601                let v = err!(self.builder.build_load(
9602                    self.intrinsics.i64_ty,
9603                    effective_address,
9604                    ""
9605                ));
9606                let v = err!(self.builder.build_bit_cast(
9607                    v,
9608                    self.intrinsics.i32_ty.vec_type(2),
9609                    ""
9610                ))
9611                .into_vector_value();
9612                let res = err!(
9613                    self.builder
9614                        .build_int_s_extend(v, self.intrinsics.i64x2_ty, "")
9615                );
9616                let res = err!(
9617                    self.builder
9618                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9619                );
9620                self.state.push1(res);
9621            }
9622            Operator::V128Load32x2U { ref memarg } => {
9623                let offset = self.state.pop1()?.into_int_value();
9624                let memory_index = MemoryIndex::from_u32(0);
9625                let effective_address = self.resolve_memory_ptr(
9626                    memory_index,
9627                    memarg,
9628                    self.intrinsics.ptr_ty,
9629                    offset,
9630                    8,
9631                )?;
9632                let v = err!(self.builder.build_load(
9633                    self.intrinsics.i64_ty,
9634                    effective_address,
9635                    ""
9636                ));
9637                let v = err!(self.builder.build_bit_cast(
9638                    v,
9639                    self.intrinsics.i32_ty.vec_type(2),
9640                    ""
9641                ))
9642                .into_vector_value();
9643                let res = err!(
9644                    self.builder
9645                        .build_int_z_extend(v, self.intrinsics.i64x2_ty, "")
9646                );
9647                let res = err!(
9648                    self.builder
9649                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9650                );
9651                self.state.push1(res);
9652            }
9653            Operator::V128Load32Zero { ref memarg } => {
9654                let offset = self.state.pop1()?.into_int_value();
9655                let memory_index = MemoryIndex::from_u32(0);
9656                let effective_address = self.resolve_memory_ptr(
9657                    memory_index,
9658                    memarg,
9659                    self.intrinsics.ptr_ty,
9660                    offset,
9661                    4,
9662                )?;
9663                let elem = err!(self.builder.build_load(
9664                    self.intrinsics.i32_ty,
9665                    effective_address,
9666                    ""
9667                ));
9668                self.annotate_user_memaccess(
9669                    memory_index,
9670                    memarg,
9671                    1,
9672                    elem.as_instruction_value().unwrap(),
9673                )?;
9674                let res = err!(self.builder.build_int_z_extend(
9675                    elem.into_int_value(),
9676                    self.intrinsics.i128_ty,
9677                    "",
9678                ));
9679                self.state.push1(res);
9680            }
9681            Operator::V128Load64Zero { ref memarg } => {
9682                let offset = self.state.pop1()?.into_int_value();
9683                let memory_index = MemoryIndex::from_u32(0);
9684                let effective_address = self.resolve_memory_ptr(
9685                    memory_index,
9686                    memarg,
9687                    self.intrinsics.ptr_ty,
9688                    offset,
9689                    8,
9690                )?;
9691                let elem = err!(self.builder.build_load(
9692                    self.intrinsics.i64_ty,
9693                    effective_address,
9694                    ""
9695                ));
9696                self.annotate_user_memaccess(
9697                    memory_index,
9698                    memarg,
9699                    1,
9700                    elem.as_instruction_value().unwrap(),
9701                )?;
9702                let res = err!(self.builder.build_int_z_extend(
9703                    elem.into_int_value(),
9704                    self.intrinsics.i128_ty,
9705                    "",
9706                ));
9707                self.state.push1(res);
9708            }
9709            Operator::V128Load8Splat { ref memarg } => {
9710                let offset = self.state.pop1()?.into_int_value();
9711                let memory_index = MemoryIndex::from_u32(0);
9712                let effective_address = self.resolve_memory_ptr(
9713                    memory_index,
9714                    memarg,
9715                    self.intrinsics.ptr_ty,
9716                    offset,
9717                    1,
9718                )?;
9719                let elem = err!(self.builder.build_load(
9720                    self.intrinsics.i8_ty,
9721                    effective_address,
9722                    ""
9723                ));
9724                self.annotate_user_memaccess(
9725                    memory_index,
9726                    memarg,
9727                    1,
9728                    elem.as_instruction_value().unwrap(),
9729                )?;
9730                let res = self.splat_vector(elem, self.intrinsics.i8x16_ty)?;
9731                let res = err!(
9732                    self.builder
9733                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9734                );
9735                self.state.push1(res);
9736            }
9737            Operator::V128Load16Splat { ref memarg } => {
9738                let offset = self.state.pop1()?.into_int_value();
9739                let memory_index = MemoryIndex::from_u32(0);
9740                let effective_address = self.resolve_memory_ptr(
9741                    memory_index,
9742                    memarg,
9743                    self.intrinsics.ptr_ty,
9744                    offset,
9745                    2,
9746                )?;
9747                let elem = err!(self.builder.build_load(
9748                    self.intrinsics.i16_ty,
9749                    effective_address,
9750                    ""
9751                ));
9752                self.annotate_user_memaccess(
9753                    memory_index,
9754                    memarg,
9755                    1,
9756                    elem.as_instruction_value().unwrap(),
9757                )?;
9758                let res = self.splat_vector(elem, self.intrinsics.i16x8_ty)?;
9759                let res = err!(
9760                    self.builder
9761                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9762                );
9763                self.state.push1(res);
9764            }
9765            Operator::V128Load32Splat { ref memarg } => {
9766                let offset = self.state.pop1()?.into_int_value();
9767                let memory_index = MemoryIndex::from_u32(0);
9768                let effective_address = self.resolve_memory_ptr(
9769                    memory_index,
9770                    memarg,
9771                    self.intrinsics.ptr_ty,
9772                    offset,
9773                    4,
9774                )?;
9775                let elem = err!(self.builder.build_load(
9776                    self.intrinsics.i32_ty,
9777                    effective_address,
9778                    ""
9779                ));
9780                self.annotate_user_memaccess(
9781                    memory_index,
9782                    memarg,
9783                    1,
9784                    elem.as_instruction_value().unwrap(),
9785                )?;
9786                let res = self.splat_vector(elem, self.intrinsics.i32x4_ty)?;
9787                let res = err!(
9788                    self.builder
9789                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9790                );
9791                self.state.push1(res);
9792            }
9793            Operator::V128Load64Splat { ref memarg } => {
9794                let offset = self.state.pop1()?.into_int_value();
9795                let memory_index = MemoryIndex::from_u32(0);
9796                let effective_address = self.resolve_memory_ptr(
9797                    memory_index,
9798                    memarg,
9799                    self.intrinsics.ptr_ty,
9800                    offset,
9801                    8,
9802                )?;
9803                let elem = err!(self.builder.build_load(
9804                    self.intrinsics.i64_ty,
9805                    effective_address,
9806                    ""
9807                ));
9808                self.annotate_user_memaccess(
9809                    memory_index,
9810                    memarg,
9811                    1,
9812                    elem.as_instruction_value().unwrap(),
9813                )?;
9814                let res = self.splat_vector(elem, self.intrinsics.i64x2_ty)?;
9815                let res = err!(
9816                    self.builder
9817                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9818                );
9819                self.state.push1(res);
9820            }
9821            Operator::AtomicFence => {
9822                // Fence is a nop.
9823                //
9824                // Fence was added to preserve information about fences from
9825                // source languages. If in the future Wasm extends the memory
9826                // model, and if we hadn't recorded what fences used to be there,
9827                // it would lead to data races that weren't present in the
9828                // original source language.
9829            }
9830            Operator::I32AtomicLoad { ref memarg } => {
9831                let offset = self.state.pop1()?.into_int_value();
9832                let memory_index = MemoryIndex::from_u32(0);
9833                let effective_address = self.resolve_memory_ptr(
9834                    memory_index,
9835                    memarg,
9836                    self.intrinsics.ptr_ty,
9837                    offset,
9838                    4,
9839                )?;
9840                self.trap_if_misaligned(memarg, effective_address, 4)?;
9841                let result = err!(self.builder.build_load(
9842                    self.intrinsics.i32_ty,
9843                    effective_address,
9844                    "atomic_load"
9845                ));
9846                let load = result.as_instruction_value().unwrap();
9847                self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
9848                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9849                    .unwrap();
9850                self.state.push1(result);
9851            }
9852            Operator::I64AtomicLoad { ref memarg } => {
9853                let offset = self.state.pop1()?.into_int_value();
9854                let memory_index = MemoryIndex::from_u32(0);
9855                let effective_address = self.resolve_memory_ptr(
9856                    memory_index,
9857                    memarg,
9858                    self.intrinsics.ptr_ty,
9859                    offset,
9860                    8,
9861                )?;
9862                self.trap_if_misaligned(memarg, effective_address, 8)?;
9863                let result = err!(self.builder.build_load(
9864                    self.intrinsics.i64_ty,
9865                    effective_address,
9866                    ""
9867                ));
9868                let load = result.as_instruction_value().unwrap();
9869                self.annotate_user_memaccess(memory_index, memarg, 8, load)?;
9870                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9871                    .unwrap();
9872                self.state.push1(result);
9873            }
9874            Operator::I32AtomicLoad8U { ref memarg } => {
9875                let offset = self.state.pop1()?.into_int_value();
9876                let memory_index = MemoryIndex::from_u32(0);
9877                let effective_address = self.resolve_memory_ptr(
9878                    memory_index,
9879                    memarg,
9880                    self.intrinsics.ptr_ty,
9881                    offset,
9882                    1,
9883                )?;
9884                self.trap_if_misaligned(memarg, effective_address, 1)?;
9885                let narrow_result = err!(self.builder.build_load(
9886                    self.intrinsics.i8_ty,
9887                    effective_address,
9888                    ""
9889                ))
9890                .into_int_value();
9891                let load = narrow_result.as_instruction_value().unwrap();
9892                self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9893                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9894                    .unwrap();
9895                let result = err!(self.builder.build_int_z_extend(
9896                    narrow_result,
9897                    self.intrinsics.i32_ty,
9898                    ""
9899                ));
9900                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9901            }
9902            Operator::I32AtomicLoad16U { ref memarg } => {
9903                let offset = self.state.pop1()?.into_int_value();
9904                let memory_index = MemoryIndex::from_u32(0);
9905                let effective_address = self.resolve_memory_ptr(
9906                    memory_index,
9907                    memarg,
9908                    self.intrinsics.ptr_ty,
9909                    offset,
9910                    2,
9911                )?;
9912                self.trap_if_misaligned(memarg, effective_address, 2)?;
9913                let narrow_result = err!(self.builder.build_load(
9914                    self.intrinsics.i16_ty,
9915                    effective_address,
9916                    ""
9917                ))
9918                .into_int_value();
9919                let load = narrow_result.as_instruction_value().unwrap();
9920                self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9921                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9922                    .unwrap();
9923                let result = err!(self.builder.build_int_z_extend(
9924                    narrow_result,
9925                    self.intrinsics.i32_ty,
9926                    ""
9927                ));
9928                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9929            }
9930            Operator::I64AtomicLoad8U { ref memarg } => {
9931                let offset = self.state.pop1()?.into_int_value();
9932                let memory_index = MemoryIndex::from_u32(0);
9933                let effective_address = self.resolve_memory_ptr(
9934                    memory_index,
9935                    memarg,
9936                    self.intrinsics.ptr_ty,
9937                    offset,
9938                    1,
9939                )?;
9940                self.trap_if_misaligned(memarg, effective_address, 1)?;
9941                let narrow_result = err!(self.builder.build_load(
9942                    self.intrinsics.i8_ty,
9943                    effective_address,
9944                    ""
9945                ))
9946                .into_int_value();
9947                let load = narrow_result.as_instruction_value().unwrap();
9948                self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9949                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9950                    .unwrap();
9951                let result = err!(self.builder.build_int_z_extend(
9952                    narrow_result,
9953                    self.intrinsics.i64_ty,
9954                    ""
9955                ));
9956                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9957            }
9958            Operator::I64AtomicLoad16U { ref memarg } => {
9959                let offset = self.state.pop1()?.into_int_value();
9960                let memory_index = MemoryIndex::from_u32(0);
9961                let effective_address = self.resolve_memory_ptr(
9962                    memory_index,
9963                    memarg,
9964                    self.intrinsics.ptr_ty,
9965                    offset,
9966                    2,
9967                )?;
9968                self.trap_if_misaligned(memarg, effective_address, 2)?;
9969                let narrow_result = err!(self.builder.build_load(
9970                    self.intrinsics.i16_ty,
9971                    effective_address,
9972                    ""
9973                ))
9974                .into_int_value();
9975                let load = narrow_result.as_instruction_value().unwrap();
9976                self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9977                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9978                    .unwrap();
9979                let result = err!(self.builder.build_int_z_extend(
9980                    narrow_result,
9981                    self.intrinsics.i64_ty,
9982                    ""
9983                ));
9984                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9985            }
9986            Operator::I64AtomicLoad32U { ref memarg } => {
9987                let offset = self.state.pop1()?.into_int_value();
9988                let memory_index = MemoryIndex::from_u32(0);
9989                let effective_address = self.resolve_memory_ptr(
9990                    memory_index,
9991                    memarg,
9992                    self.intrinsics.ptr_ty,
9993                    offset,
9994                    4,
9995                )?;
9996                self.trap_if_misaligned(memarg, effective_address, 4)?;
9997                let narrow_result = err!(self.builder.build_load(
9998                    self.intrinsics.i32_ty,
9999                    effective_address,
10000                    ""
10001                ))
10002                .into_int_value();
10003                let load = narrow_result.as_instruction_value().unwrap();
10004                self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10005                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10006                    .unwrap();
10007                let result = err!(self.builder.build_int_z_extend(
10008                    narrow_result,
10009                    self.intrinsics.i64_ty,
10010                    ""
10011                ));
10012                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10013            }
10014            Operator::I32AtomicStore { ref memarg } => {
10015                let value = self.state.pop1()?;
10016                let offset = self.state.pop1()?.into_int_value();
10017                let memory_index = MemoryIndex::from_u32(0);
10018                let effective_address = self.resolve_memory_ptr(
10019                    memory_index,
10020                    memarg,
10021                    self.intrinsics.ptr_ty,
10022                    offset,
10023                    4,
10024                )?;
10025                self.trap_if_misaligned(memarg, effective_address, 4)?;
10026                let store = err!(self.builder.build_store(effective_address, value));
10027                self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10028                store
10029                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10030                    .unwrap();
10031            }
10032            Operator::I64AtomicStore { ref memarg } => {
10033                let value = self.state.pop1()?;
10034                let offset = self.state.pop1()?.into_int_value();
10035                let memory_index = MemoryIndex::from_u32(0);
10036                let effective_address = self.resolve_memory_ptr(
10037                    memory_index,
10038                    memarg,
10039                    self.intrinsics.ptr_ty,
10040                    offset,
10041                    8,
10042                )?;
10043                self.trap_if_misaligned(memarg, effective_address, 8)?;
10044                let store = err!(self.builder.build_store(effective_address, value));
10045                self.annotate_user_memaccess(memory_index, memarg, 8, store)?;
10046                store
10047                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10048                    .unwrap();
10049            }
10050            Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => {
10051                let value = self.state.pop1()?.into_int_value();
10052                let offset = self.state.pop1()?.into_int_value();
10053                let memory_index = MemoryIndex::from_u32(0);
10054                let effective_address = self.resolve_memory_ptr(
10055                    memory_index,
10056                    memarg,
10057                    self.intrinsics.ptr_ty,
10058                    offset,
10059                    1,
10060                )?;
10061                self.trap_if_misaligned(memarg, effective_address, 1)?;
10062                let narrow_value = err!(self.builder.build_int_truncate(
10063                    value,
10064                    self.intrinsics.i8_ty,
10065                    ""
10066                ));
10067                let store = err!(self.builder.build_store(effective_address, narrow_value));
10068                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
10069                store
10070                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10071                    .unwrap();
10072            }
10073            Operator::I32AtomicStore16 { ref memarg }
10074            | Operator::I64AtomicStore16 { ref memarg } => {
10075                let value = self.state.pop1()?.into_int_value();
10076                let offset = self.state.pop1()?.into_int_value();
10077                let memory_index = MemoryIndex::from_u32(0);
10078                let effective_address = self.resolve_memory_ptr(
10079                    memory_index,
10080                    memarg,
10081                    self.intrinsics.ptr_ty,
10082                    offset,
10083                    2,
10084                )?;
10085                self.trap_if_misaligned(memarg, effective_address, 2)?;
10086                let narrow_value = err!(self.builder.build_int_truncate(
10087                    value,
10088                    self.intrinsics.i16_ty,
10089                    ""
10090                ));
10091                let store = err!(self.builder.build_store(effective_address, narrow_value));
10092                self.annotate_user_memaccess(memory_index, memarg, 2, store)?;
10093                store
10094                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10095                    .unwrap();
10096            }
10097            Operator::I64AtomicStore32 { ref memarg } => {
10098                let value = self.state.pop1()?.into_int_value();
10099                let offset = self.state.pop1()?.into_int_value();
10100                let memory_index = MemoryIndex::from_u32(0);
10101                let effective_address = self.resolve_memory_ptr(
10102                    memory_index,
10103                    memarg,
10104                    self.intrinsics.ptr_ty,
10105                    offset,
10106                    4,
10107                )?;
10108                self.trap_if_misaligned(memarg, effective_address, 4)?;
10109                let narrow_value = err!(self.builder.build_int_truncate(
10110                    value,
10111                    self.intrinsics.i32_ty,
10112                    ""
10113                ));
10114                let store = err!(self.builder.build_store(effective_address, narrow_value));
10115                self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10116                store
10117                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10118                    .unwrap();
10119            }
10120            Operator::I32AtomicRmw8AddU { ref memarg } => {
10121                let value = self.state.pop1()?.into_int_value();
10122                let offset = self.state.pop1()?.into_int_value();
10123                let memory_index = MemoryIndex::from_u32(0);
10124                let effective_address = self.resolve_memory_ptr(
10125                    memory_index,
10126                    memarg,
10127                    self.intrinsics.ptr_ty,
10128                    offset,
10129                    1,
10130                )?;
10131                self.trap_if_misaligned(memarg, effective_address, 1)?;
10132                let narrow_value = err!(self.builder.build_int_truncate(
10133                    value,
10134                    self.intrinsics.i8_ty,
10135                    ""
10136                ));
10137                let old = self
10138                    .builder
10139                    .build_atomicrmw(
10140                        AtomicRMWBinOp::Add,
10141                        effective_address,
10142                        narrow_value,
10143                        AtomicOrdering::SequentiallyConsistent,
10144                    )
10145                    .unwrap();
10146                tbaa_label(
10147                    self.module,
10148                    self.intrinsics,
10149                    format!("memory {}", memory_index.as_u32()),
10150                    old.as_instruction_value().unwrap(),
10151                );
10152                let old = err!(
10153                    self.builder
10154                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10155                );
10156                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10157            }
10158            Operator::I32AtomicRmw16AddU { ref memarg } => {
10159                let value = self.state.pop1()?.into_int_value();
10160                let offset = self.state.pop1()?.into_int_value();
10161                let memory_index = MemoryIndex::from_u32(0);
10162                let effective_address = self.resolve_memory_ptr(
10163                    memory_index,
10164                    memarg,
10165                    self.intrinsics.ptr_ty,
10166                    offset,
10167                    2,
10168                )?;
10169                self.trap_if_misaligned(memarg, effective_address, 2)?;
10170                let narrow_value = err!(self.builder.build_int_truncate(
10171                    value,
10172                    self.intrinsics.i16_ty,
10173                    ""
10174                ));
10175                let old = self
10176                    .builder
10177                    .build_atomicrmw(
10178                        AtomicRMWBinOp::Add,
10179                        effective_address,
10180                        narrow_value,
10181                        AtomicOrdering::SequentiallyConsistent,
10182                    )
10183                    .unwrap();
10184                tbaa_label(
10185                    self.module,
10186                    self.intrinsics,
10187                    format!("memory {}", memory_index.as_u32()),
10188                    old.as_instruction_value().unwrap(),
10189                );
10190                let old = err!(
10191                    self.builder
10192                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10193                );
10194                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10195            }
10196            Operator::I32AtomicRmwAdd { ref memarg } => {
10197                let value = self.state.pop1()?.into_int_value();
10198                let offset = self.state.pop1()?.into_int_value();
10199                let memory_index = MemoryIndex::from_u32(0);
10200                let effective_address = self.resolve_memory_ptr(
10201                    memory_index,
10202                    memarg,
10203                    self.intrinsics.ptr_ty,
10204                    offset,
10205                    4,
10206                )?;
10207                self.trap_if_misaligned(memarg, effective_address, 4)?;
10208                let old = self
10209                    .builder
10210                    .build_atomicrmw(
10211                        AtomicRMWBinOp::Add,
10212                        effective_address,
10213                        value,
10214                        AtomicOrdering::SequentiallyConsistent,
10215                    )
10216                    .unwrap();
10217                tbaa_label(
10218                    self.module,
10219                    self.intrinsics,
10220                    format!("memory {}", memory_index.as_u32()),
10221                    old.as_instruction_value().unwrap(),
10222                );
10223                self.state.push1(old);
10224            }
10225            Operator::I64AtomicRmw8AddU { ref memarg } => {
10226                let value = self.state.pop1()?.into_int_value();
10227                let offset = self.state.pop1()?.into_int_value();
10228                let memory_index = MemoryIndex::from_u32(0);
10229                let effective_address = self.resolve_memory_ptr(
10230                    memory_index,
10231                    memarg,
10232                    self.intrinsics.ptr_ty,
10233                    offset,
10234                    1,
10235                )?;
10236                self.trap_if_misaligned(memarg, effective_address, 1)?;
10237                let narrow_value = err!(self.builder.build_int_truncate(
10238                    value,
10239                    self.intrinsics.i8_ty,
10240                    ""
10241                ));
10242                let old = self
10243                    .builder
10244                    .build_atomicrmw(
10245                        AtomicRMWBinOp::Add,
10246                        effective_address,
10247                        narrow_value,
10248                        AtomicOrdering::SequentiallyConsistent,
10249                    )
10250                    .unwrap();
10251                self.annotate_user_memaccess(
10252                    memory_index,
10253                    memarg,
10254                    0,
10255                    old.as_instruction_value().unwrap(),
10256                )?;
10257                let old = err!(
10258                    self.builder
10259                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10260                );
10261                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10262            }
10263            Operator::I64AtomicRmw16AddU { ref memarg } => {
10264                let value = self.state.pop1()?.into_int_value();
10265                let offset = self.state.pop1()?.into_int_value();
10266                let memory_index = MemoryIndex::from_u32(0);
10267                let effective_address = self.resolve_memory_ptr(
10268                    memory_index,
10269                    memarg,
10270                    self.intrinsics.ptr_ty,
10271                    offset,
10272                    2,
10273                )?;
10274                self.trap_if_misaligned(memarg, effective_address, 2)?;
10275                let narrow_value = err!(self.builder.build_int_truncate(
10276                    value,
10277                    self.intrinsics.i16_ty,
10278                    ""
10279                ));
10280                let old = self
10281                    .builder
10282                    .build_atomicrmw(
10283                        AtomicRMWBinOp::Add,
10284                        effective_address,
10285                        narrow_value,
10286                        AtomicOrdering::SequentiallyConsistent,
10287                    )
10288                    .unwrap();
10289                self.annotate_user_memaccess(
10290                    memory_index,
10291                    memarg,
10292                    0,
10293                    old.as_instruction_value().unwrap(),
10294                )?;
10295                let old = err!(
10296                    self.builder
10297                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10298                );
10299                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10300            }
10301            Operator::I64AtomicRmw32AddU { ref memarg } => {
10302                let value = self.state.pop1()?.into_int_value();
10303                let offset = self.state.pop1()?.into_int_value();
10304                let memory_index = MemoryIndex::from_u32(0);
10305                let effective_address = self.resolve_memory_ptr(
10306                    memory_index,
10307                    memarg,
10308                    self.intrinsics.ptr_ty,
10309                    offset,
10310                    4,
10311                )?;
10312                self.trap_if_misaligned(memarg, effective_address, 4)?;
10313                let narrow_value = err!(self.builder.build_int_truncate(
10314                    value,
10315                    self.intrinsics.i32_ty,
10316                    ""
10317                ));
10318                let old = self
10319                    .builder
10320                    .build_atomicrmw(
10321                        AtomicRMWBinOp::Add,
10322                        effective_address,
10323                        narrow_value,
10324                        AtomicOrdering::SequentiallyConsistent,
10325                    )
10326                    .unwrap();
10327                self.annotate_user_memaccess(
10328                    memory_index,
10329                    memarg,
10330                    0,
10331                    old.as_instruction_value().unwrap(),
10332                )?;
10333                let old = err!(
10334                    self.builder
10335                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10336                );
10337                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10338            }
10339            Operator::I64AtomicRmwAdd { ref memarg } => {
10340                let value = self.state.pop1()?.into_int_value();
10341                let offset = self.state.pop1()?.into_int_value();
10342                let memory_index = MemoryIndex::from_u32(0);
10343                let effective_address = self.resolve_memory_ptr(
10344                    memory_index,
10345                    memarg,
10346                    self.intrinsics.ptr_ty,
10347                    offset,
10348                    8,
10349                )?;
10350                self.trap_if_misaligned(memarg, effective_address, 8)?;
10351                let old = self
10352                    .builder
10353                    .build_atomicrmw(
10354                        AtomicRMWBinOp::Add,
10355                        effective_address,
10356                        value,
10357                        AtomicOrdering::SequentiallyConsistent,
10358                    )
10359                    .unwrap();
10360                self.annotate_user_memaccess(
10361                    memory_index,
10362                    memarg,
10363                    0,
10364                    old.as_instruction_value().unwrap(),
10365                )?;
10366                self.state.push1(old);
10367            }
10368            Operator::I32AtomicRmw8SubU { ref memarg } => {
10369                let value = self.state.pop1()?.into_int_value();
10370                let offset = self.state.pop1()?.into_int_value();
10371                let memory_index = MemoryIndex::from_u32(0);
10372                let effective_address = self.resolve_memory_ptr(
10373                    memory_index,
10374                    memarg,
10375                    self.intrinsics.ptr_ty,
10376                    offset,
10377                    1,
10378                )?;
10379                self.trap_if_misaligned(memarg, effective_address, 1)?;
10380                let narrow_value = err!(self.builder.build_int_truncate(
10381                    value,
10382                    self.intrinsics.i8_ty,
10383                    ""
10384                ));
10385                let old = self
10386                    .builder
10387                    .build_atomicrmw(
10388                        AtomicRMWBinOp::Sub,
10389                        effective_address,
10390                        narrow_value,
10391                        AtomicOrdering::SequentiallyConsistent,
10392                    )
10393                    .unwrap();
10394                self.annotate_user_memaccess(
10395                    memory_index,
10396                    memarg,
10397                    0,
10398                    old.as_instruction_value().unwrap(),
10399                )?;
10400                let old = err!(
10401                    self.builder
10402                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10403                );
10404                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10405            }
10406            Operator::I32AtomicRmw16SubU { ref memarg } => {
10407                let value = self.state.pop1()?.into_int_value();
10408                let offset = self.state.pop1()?.into_int_value();
10409                let memory_index = MemoryIndex::from_u32(0);
10410                let effective_address = self.resolve_memory_ptr(
10411                    memory_index,
10412                    memarg,
10413                    self.intrinsics.ptr_ty,
10414                    offset,
10415                    2,
10416                )?;
10417                self.trap_if_misaligned(memarg, effective_address, 2)?;
10418                let narrow_value = err!(self.builder.build_int_truncate(
10419                    value,
10420                    self.intrinsics.i16_ty,
10421                    ""
10422                ));
10423                let old = self
10424                    .builder
10425                    .build_atomicrmw(
10426                        AtomicRMWBinOp::Sub,
10427                        effective_address,
10428                        narrow_value,
10429                        AtomicOrdering::SequentiallyConsistent,
10430                    )
10431                    .unwrap();
10432                self.annotate_user_memaccess(
10433                    memory_index,
10434                    memarg,
10435                    0,
10436                    old.as_instruction_value().unwrap(),
10437                )?;
10438                let old = err!(
10439                    self.builder
10440                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10441                );
10442                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10443            }
10444            Operator::I32AtomicRmwSub { ref memarg } => {
10445                let value = self.state.pop1()?.into_int_value();
10446                let offset = self.state.pop1()?.into_int_value();
10447                let memory_index = MemoryIndex::from_u32(0);
10448                let effective_address = self.resolve_memory_ptr(
10449                    memory_index,
10450                    memarg,
10451                    self.intrinsics.ptr_ty,
10452                    offset,
10453                    4,
10454                )?;
10455                self.trap_if_misaligned(memarg, effective_address, 4)?;
10456                let old = self
10457                    .builder
10458                    .build_atomicrmw(
10459                        AtomicRMWBinOp::Sub,
10460                        effective_address,
10461                        value,
10462                        AtomicOrdering::SequentiallyConsistent,
10463                    )
10464                    .unwrap();
10465                self.annotate_user_memaccess(
10466                    memory_index,
10467                    memarg,
10468                    0,
10469                    old.as_instruction_value().unwrap(),
10470                )?;
10471                self.state.push1(old);
10472            }
10473            Operator::I64AtomicRmw8SubU { ref memarg } => {
10474                let value = self.state.pop1()?.into_int_value();
10475                let offset = self.state.pop1()?.into_int_value();
10476                let memory_index = MemoryIndex::from_u32(0);
10477                let effective_address = self.resolve_memory_ptr(
10478                    memory_index,
10479                    memarg,
10480                    self.intrinsics.ptr_ty,
10481                    offset,
10482                    1,
10483                )?;
10484                self.trap_if_misaligned(memarg, effective_address, 1)?;
10485                let narrow_value = err!(self.builder.build_int_truncate(
10486                    value,
10487                    self.intrinsics.i8_ty,
10488                    ""
10489                ));
10490                let old = self
10491                    .builder
10492                    .build_atomicrmw(
10493                        AtomicRMWBinOp::Sub,
10494                        effective_address,
10495                        narrow_value,
10496                        AtomicOrdering::SequentiallyConsistent,
10497                    )
10498                    .unwrap();
10499                self.annotate_user_memaccess(
10500                    memory_index,
10501                    memarg,
10502                    0,
10503                    old.as_instruction_value().unwrap(),
10504                )?;
10505                let old = err!(
10506                    self.builder
10507                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10508                );
10509                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10510            }
10511            Operator::I64AtomicRmw16SubU { ref memarg } => {
10512                let value = self.state.pop1()?.into_int_value();
10513                let offset = self.state.pop1()?.into_int_value();
10514                let memory_index = MemoryIndex::from_u32(0);
10515                let effective_address = self.resolve_memory_ptr(
10516                    memory_index,
10517                    memarg,
10518                    self.intrinsics.ptr_ty,
10519                    offset,
10520                    2,
10521                )?;
10522                self.trap_if_misaligned(memarg, effective_address, 2)?;
10523                let narrow_value = err!(self.builder.build_int_truncate(
10524                    value,
10525                    self.intrinsics.i16_ty,
10526                    ""
10527                ));
10528                let old = self
10529                    .builder
10530                    .build_atomicrmw(
10531                        AtomicRMWBinOp::Sub,
10532                        effective_address,
10533                        narrow_value,
10534                        AtomicOrdering::SequentiallyConsistent,
10535                    )
10536                    .unwrap();
10537                self.annotate_user_memaccess(
10538                    memory_index,
10539                    memarg,
10540                    0,
10541                    old.as_instruction_value().unwrap(),
10542                )?;
10543                let old = err!(
10544                    self.builder
10545                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10546                );
10547                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10548            }
10549            Operator::I64AtomicRmw32SubU { ref memarg } => {
10550                let value = self.state.pop1()?.into_int_value();
10551                let offset = self.state.pop1()?.into_int_value();
10552                let memory_index = MemoryIndex::from_u32(0);
10553                let effective_address = self.resolve_memory_ptr(
10554                    memory_index,
10555                    memarg,
10556                    self.intrinsics.ptr_ty,
10557                    offset,
10558                    4,
10559                )?;
10560                self.trap_if_misaligned(memarg, effective_address, 4)?;
10561                let narrow_value = err!(self.builder.build_int_truncate(
10562                    value,
10563                    self.intrinsics.i32_ty,
10564                    ""
10565                ));
10566                let old = self
10567                    .builder
10568                    .build_atomicrmw(
10569                        AtomicRMWBinOp::Sub,
10570                        effective_address,
10571                        narrow_value,
10572                        AtomicOrdering::SequentiallyConsistent,
10573                    )
10574                    .unwrap();
10575                self.annotate_user_memaccess(
10576                    memory_index,
10577                    memarg,
10578                    0,
10579                    old.as_instruction_value().unwrap(),
10580                )?;
10581                let old = err!(
10582                    self.builder
10583                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10584                );
10585                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10586            }
10587            Operator::I64AtomicRmwSub { ref memarg } => {
10588                let value = self.state.pop1()?.into_int_value();
10589                let offset = self.state.pop1()?.into_int_value();
10590                let memory_index = MemoryIndex::from_u32(0);
10591                let effective_address = self.resolve_memory_ptr(
10592                    memory_index,
10593                    memarg,
10594                    self.intrinsics.ptr_ty,
10595                    offset,
10596                    8,
10597                )?;
10598                self.trap_if_misaligned(memarg, effective_address, 8)?;
10599                let old = self
10600                    .builder
10601                    .build_atomicrmw(
10602                        AtomicRMWBinOp::Sub,
10603                        effective_address,
10604                        value,
10605                        AtomicOrdering::SequentiallyConsistent,
10606                    )
10607                    .unwrap();
10608                self.annotate_user_memaccess(
10609                    memory_index,
10610                    memarg,
10611                    0,
10612                    old.as_instruction_value().unwrap(),
10613                )?;
10614                self.state.push1(old);
10615            }
10616            Operator::I32AtomicRmw8AndU { ref memarg } => {
10617                let value = self.state.pop1()?.into_int_value();
10618                let offset = self.state.pop1()?.into_int_value();
10619                let memory_index = MemoryIndex::from_u32(0);
10620                let effective_address = self.resolve_memory_ptr(
10621                    memory_index,
10622                    memarg,
10623                    self.intrinsics.ptr_ty,
10624                    offset,
10625                    1,
10626                )?;
10627                self.trap_if_misaligned(memarg, effective_address, 1)?;
10628                let narrow_value = err!(self.builder.build_int_truncate(
10629                    value,
10630                    self.intrinsics.i8_ty,
10631                    ""
10632                ));
10633                let old = self
10634                    .builder
10635                    .build_atomicrmw(
10636                        AtomicRMWBinOp::And,
10637                        effective_address,
10638                        narrow_value,
10639                        AtomicOrdering::SequentiallyConsistent,
10640                    )
10641                    .unwrap();
10642                self.annotate_user_memaccess(
10643                    memory_index,
10644                    memarg,
10645                    0,
10646                    old.as_instruction_value().unwrap(),
10647                )?;
10648                let old = err!(
10649                    self.builder
10650                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10651                );
10652                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10653            }
10654            Operator::I32AtomicRmw16AndU { ref memarg } => {
10655                let value = self.state.pop1()?.into_int_value();
10656                let offset = self.state.pop1()?.into_int_value();
10657                let memory_index = MemoryIndex::from_u32(0);
10658                let effective_address = self.resolve_memory_ptr(
10659                    memory_index,
10660                    memarg,
10661                    self.intrinsics.ptr_ty,
10662                    offset,
10663                    2,
10664                )?;
10665                self.trap_if_misaligned(memarg, effective_address, 2)?;
10666                let narrow_value = err!(self.builder.build_int_truncate(
10667                    value,
10668                    self.intrinsics.i16_ty,
10669                    ""
10670                ));
10671                let old = self
10672                    .builder
10673                    .build_atomicrmw(
10674                        AtomicRMWBinOp::And,
10675                        effective_address,
10676                        narrow_value,
10677                        AtomicOrdering::SequentiallyConsistent,
10678                    )
10679                    .unwrap();
10680                self.annotate_user_memaccess(
10681                    memory_index,
10682                    memarg,
10683                    0,
10684                    old.as_instruction_value().unwrap(),
10685                )?;
10686                let old = err!(
10687                    self.builder
10688                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10689                );
10690                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10691            }
10692            Operator::I32AtomicRmwAnd { ref memarg } => {
10693                let value = self.state.pop1()?.into_int_value();
10694                let offset = self.state.pop1()?.into_int_value();
10695                let memory_index = MemoryIndex::from_u32(0);
10696                let effective_address = self.resolve_memory_ptr(
10697                    memory_index,
10698                    memarg,
10699                    self.intrinsics.ptr_ty,
10700                    offset,
10701                    4,
10702                )?;
10703                self.trap_if_misaligned(memarg, effective_address, 4)?;
10704                let old = self
10705                    .builder
10706                    .build_atomicrmw(
10707                        AtomicRMWBinOp::And,
10708                        effective_address,
10709                        value,
10710                        AtomicOrdering::SequentiallyConsistent,
10711                    )
10712                    .unwrap();
10713                self.annotate_user_memaccess(
10714                    memory_index,
10715                    memarg,
10716                    0,
10717                    old.as_instruction_value().unwrap(),
10718                )?;
10719                self.state.push1(old);
10720            }
10721            Operator::I64AtomicRmw8AndU { ref memarg } => {
10722                let value = self.state.pop1()?.into_int_value();
10723                let offset = self.state.pop1()?.into_int_value();
10724                let memory_index = MemoryIndex::from_u32(0);
10725                let effective_address = self.resolve_memory_ptr(
10726                    memory_index,
10727                    memarg,
10728                    self.intrinsics.ptr_ty,
10729                    offset,
10730                    1,
10731                )?;
10732                self.trap_if_misaligned(memarg, effective_address, 1)?;
10733                let narrow_value = err!(self.builder.build_int_truncate(
10734                    value,
10735                    self.intrinsics.i8_ty,
10736                    ""
10737                ));
10738                let old = self
10739                    .builder
10740                    .build_atomicrmw(
10741                        AtomicRMWBinOp::And,
10742                        effective_address,
10743                        narrow_value,
10744                        AtomicOrdering::SequentiallyConsistent,
10745                    )
10746                    .unwrap();
10747                self.annotate_user_memaccess(
10748                    memory_index,
10749                    memarg,
10750                    0,
10751                    old.as_instruction_value().unwrap(),
10752                )?;
10753                let old = err!(
10754                    self.builder
10755                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10756                );
10757                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10758            }
10759            Operator::I64AtomicRmw16AndU { ref memarg } => {
10760                let value = self.state.pop1()?.into_int_value();
10761                let offset = self.state.pop1()?.into_int_value();
10762                let memory_index = MemoryIndex::from_u32(0);
10763                let effective_address = self.resolve_memory_ptr(
10764                    memory_index,
10765                    memarg,
10766                    self.intrinsics.ptr_ty,
10767                    offset,
10768                    2,
10769                )?;
10770                self.trap_if_misaligned(memarg, effective_address, 2)?;
10771                let narrow_value = err!(self.builder.build_int_truncate(
10772                    value,
10773                    self.intrinsics.i16_ty,
10774                    ""
10775                ));
10776                let old = self
10777                    .builder
10778                    .build_atomicrmw(
10779                        AtomicRMWBinOp::And,
10780                        effective_address,
10781                        narrow_value,
10782                        AtomicOrdering::SequentiallyConsistent,
10783                    )
10784                    .unwrap();
10785                self.annotate_user_memaccess(
10786                    memory_index,
10787                    memarg,
10788                    0,
10789                    old.as_instruction_value().unwrap(),
10790                )?;
10791                let old = err!(
10792                    self.builder
10793                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10794                );
10795                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10796            }
10797            Operator::I64AtomicRmw32AndU { ref memarg } => {
10798                let value = self.state.pop1()?.into_int_value();
10799                let offset = self.state.pop1()?.into_int_value();
10800                let memory_index = MemoryIndex::from_u32(0);
10801                let effective_address = self.resolve_memory_ptr(
10802                    memory_index,
10803                    memarg,
10804                    self.intrinsics.ptr_ty,
10805                    offset,
10806                    4,
10807                )?;
10808                self.trap_if_misaligned(memarg, effective_address, 4)?;
10809                let narrow_value = err!(self.builder.build_int_truncate(
10810                    value,
10811                    self.intrinsics.i32_ty,
10812                    ""
10813                ));
10814                let old = self
10815                    .builder
10816                    .build_atomicrmw(
10817                        AtomicRMWBinOp::And,
10818                        effective_address,
10819                        narrow_value,
10820                        AtomicOrdering::SequentiallyConsistent,
10821                    )
10822                    .unwrap();
10823                self.annotate_user_memaccess(
10824                    memory_index,
10825                    memarg,
10826                    0,
10827                    old.as_instruction_value().unwrap(),
10828                )?;
10829                let old = err!(
10830                    self.builder
10831                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10832                );
10833                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10834            }
10835            Operator::I64AtomicRmwAnd { ref memarg } => {
10836                let value = self.state.pop1()?.into_int_value();
10837                let offset = self.state.pop1()?.into_int_value();
10838                let memory_index = MemoryIndex::from_u32(0);
10839                let effective_address = self.resolve_memory_ptr(
10840                    memory_index,
10841                    memarg,
10842                    self.intrinsics.ptr_ty,
10843                    offset,
10844                    8,
10845                )?;
10846                self.trap_if_misaligned(memarg, effective_address, 8)?;
10847                let old = self
10848                    .builder
10849                    .build_atomicrmw(
10850                        AtomicRMWBinOp::And,
10851                        effective_address,
10852                        value,
10853                        AtomicOrdering::SequentiallyConsistent,
10854                    )
10855                    .unwrap();
10856                self.annotate_user_memaccess(
10857                    memory_index,
10858                    memarg,
10859                    0,
10860                    old.as_instruction_value().unwrap(),
10861                )?;
10862                self.state.push1(old);
10863            }
10864            Operator::I32AtomicRmw8OrU { ref memarg } => {
10865                let value = self.state.pop1()?.into_int_value();
10866                let offset = self.state.pop1()?.into_int_value();
10867                let memory_index = MemoryIndex::from_u32(0);
10868                let effective_address = self.resolve_memory_ptr(
10869                    memory_index,
10870                    memarg,
10871                    self.intrinsics.ptr_ty,
10872                    offset,
10873                    1,
10874                )?;
10875                self.trap_if_misaligned(memarg, effective_address, 1)?;
10876                let narrow_value = err!(self.builder.build_int_truncate(
10877                    value,
10878                    self.intrinsics.i8_ty,
10879                    ""
10880                ));
10881                let old = self
10882                    .builder
10883                    .build_atomicrmw(
10884                        AtomicRMWBinOp::Or,
10885                        effective_address,
10886                        narrow_value,
10887                        AtomicOrdering::SequentiallyConsistent,
10888                    )
10889                    .unwrap();
10890                self.annotate_user_memaccess(
10891                    memory_index,
10892                    memarg,
10893                    0,
10894                    old.as_instruction_value().unwrap(),
10895                )?;
10896                let old = err!(
10897                    self.builder
10898                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10899                );
10900                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10901            }
10902            Operator::I32AtomicRmw16OrU { ref memarg } => {
10903                let value = self.state.pop1()?.into_int_value();
10904                let offset = self.state.pop1()?.into_int_value();
10905                let memory_index = MemoryIndex::from_u32(0);
10906                let effective_address = self.resolve_memory_ptr(
10907                    memory_index,
10908                    memarg,
10909                    self.intrinsics.ptr_ty,
10910                    offset,
10911                    2,
10912                )?;
10913                self.trap_if_misaligned(memarg, effective_address, 2)?;
10914                let narrow_value = err!(self.builder.build_int_truncate(
10915                    value,
10916                    self.intrinsics.i16_ty,
10917                    ""
10918                ));
10919                let old = self
10920                    .builder
10921                    .build_atomicrmw(
10922                        AtomicRMWBinOp::Or,
10923                        effective_address,
10924                        narrow_value,
10925                        AtomicOrdering::SequentiallyConsistent,
10926                    )
10927                    .unwrap();
10928                self.annotate_user_memaccess(
10929                    memory_index,
10930                    memarg,
10931                    0,
10932                    old.as_instruction_value().unwrap(),
10933                )?;
10934                let old = err!(
10935                    self.builder
10936                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10937                );
10938                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10939            }
10940            Operator::I32AtomicRmwOr { ref memarg } => {
10941                let value = self.state.pop1()?.into_int_value();
10942                let offset = self.state.pop1()?.into_int_value();
10943                let memory_index = MemoryIndex::from_u32(0);
10944                let effective_address = self.resolve_memory_ptr(
10945                    memory_index,
10946                    memarg,
10947                    self.intrinsics.ptr_ty,
10948                    offset,
10949                    4,
10950                )?;
10951                self.trap_if_misaligned(memarg, effective_address, 4)?;
10952                let old = self
10953                    .builder
10954                    .build_atomicrmw(
10955                        AtomicRMWBinOp::Or,
10956                        effective_address,
10957                        value,
10958                        AtomicOrdering::SequentiallyConsistent,
10959                    )
10960                    .unwrap();
10961                self.annotate_user_memaccess(
10962                    memory_index,
10963                    memarg,
10964                    0,
10965                    old.as_instruction_value().unwrap(),
10966                )?;
10967                let old = err!(
10968                    self.builder
10969                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10970                );
10971                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10972            }
10973            Operator::I64AtomicRmw8OrU { ref memarg } => {
10974                let value = self.state.pop1()?.into_int_value();
10975                let offset = self.state.pop1()?.into_int_value();
10976                let memory_index = MemoryIndex::from_u32(0);
10977                let effective_address = self.resolve_memory_ptr(
10978                    memory_index,
10979                    memarg,
10980                    self.intrinsics.ptr_ty,
10981                    offset,
10982                    1,
10983                )?;
10984                self.trap_if_misaligned(memarg, effective_address, 1)?;
10985                let narrow_value = err!(self.builder.build_int_truncate(
10986                    value,
10987                    self.intrinsics.i8_ty,
10988                    ""
10989                ));
10990                let old = self
10991                    .builder
10992                    .build_atomicrmw(
10993                        AtomicRMWBinOp::Or,
10994                        effective_address,
10995                        narrow_value,
10996                        AtomicOrdering::SequentiallyConsistent,
10997                    )
10998                    .unwrap();
10999                self.annotate_user_memaccess(
11000                    memory_index,
11001                    memarg,
11002                    0,
11003                    old.as_instruction_value().unwrap(),
11004                )?;
11005                let old = err!(
11006                    self.builder
11007                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11008                );
11009                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11010            }
11011            Operator::I64AtomicRmw16OrU { ref memarg } => {
11012                let value = self.state.pop1()?.into_int_value();
11013                let offset = self.state.pop1()?.into_int_value();
11014                let memory_index = MemoryIndex::from_u32(0);
11015                let effective_address = self.resolve_memory_ptr(
11016                    memory_index,
11017                    memarg,
11018                    self.intrinsics.ptr_ty,
11019                    offset,
11020                    2,
11021                )?;
11022                self.trap_if_misaligned(memarg, effective_address, 2)?;
11023                let narrow_value = err!(self.builder.build_int_truncate(
11024                    value,
11025                    self.intrinsics.i16_ty,
11026                    ""
11027                ));
11028                let old = self
11029                    .builder
11030                    .build_atomicrmw(
11031                        AtomicRMWBinOp::Or,
11032                        effective_address,
11033                        narrow_value,
11034                        AtomicOrdering::SequentiallyConsistent,
11035                    )
11036                    .unwrap();
11037                self.annotate_user_memaccess(
11038                    memory_index,
11039                    memarg,
11040                    0,
11041                    old.as_instruction_value().unwrap(),
11042                )?;
11043                let old = err!(
11044                    self.builder
11045                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11046                );
11047                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11048            }
11049            Operator::I64AtomicRmw32OrU { ref memarg } => {
11050                let value = self.state.pop1()?.into_int_value();
11051                let offset = self.state.pop1()?.into_int_value();
11052                let memory_index = MemoryIndex::from_u32(0);
11053                let effective_address = self.resolve_memory_ptr(
11054                    memory_index,
11055                    memarg,
11056                    self.intrinsics.ptr_ty,
11057                    offset,
11058                    4,
11059                )?;
11060                self.trap_if_misaligned(memarg, effective_address, 4)?;
11061                let narrow_value = err!(self.builder.build_int_truncate(
11062                    value,
11063                    self.intrinsics.i32_ty,
11064                    ""
11065                ));
11066                let old = self
11067                    .builder
11068                    .build_atomicrmw(
11069                        AtomicRMWBinOp::Or,
11070                        effective_address,
11071                        narrow_value,
11072                        AtomicOrdering::SequentiallyConsistent,
11073                    )
11074                    .unwrap();
11075                self.annotate_user_memaccess(
11076                    memory_index,
11077                    memarg,
11078                    0,
11079                    old.as_instruction_value().unwrap(),
11080                )?;
11081                let old = err!(
11082                    self.builder
11083                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11084                );
11085                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11086            }
11087            Operator::I64AtomicRmwOr { ref memarg } => {
11088                let value = self.state.pop1()?.into_int_value();
11089                let offset = self.state.pop1()?.into_int_value();
11090                let memory_index = MemoryIndex::from_u32(0);
11091                let effective_address = self.resolve_memory_ptr(
11092                    memory_index,
11093                    memarg,
11094                    self.intrinsics.ptr_ty,
11095                    offset,
11096                    8,
11097                )?;
11098                self.trap_if_misaligned(memarg, effective_address, 8)?;
11099                let old = self
11100                    .builder
11101                    .build_atomicrmw(
11102                        AtomicRMWBinOp::Or,
11103                        effective_address,
11104                        value,
11105                        AtomicOrdering::SequentiallyConsistent,
11106                    )
11107                    .unwrap();
11108                self.annotate_user_memaccess(
11109                    memory_index,
11110                    memarg,
11111                    0,
11112                    old.as_instruction_value().unwrap(),
11113                )?;
11114                self.state.push1(old);
11115            }
11116            Operator::I32AtomicRmw8XorU { ref memarg } => {
11117                let value = self.state.pop1()?.into_int_value();
11118                let offset = self.state.pop1()?.into_int_value();
11119                let memory_index = MemoryIndex::from_u32(0);
11120                let effective_address = self.resolve_memory_ptr(
11121                    memory_index,
11122                    memarg,
11123                    self.intrinsics.ptr_ty,
11124                    offset,
11125                    1,
11126                )?;
11127                self.trap_if_misaligned(memarg, effective_address, 2)?;
11128                let narrow_value = err!(self.builder.build_int_truncate(
11129                    value,
11130                    self.intrinsics.i8_ty,
11131                    ""
11132                ));
11133                let old = self
11134                    .builder
11135                    .build_atomicrmw(
11136                        AtomicRMWBinOp::Xor,
11137                        effective_address,
11138                        narrow_value,
11139                        AtomicOrdering::SequentiallyConsistent,
11140                    )
11141                    .unwrap();
11142                self.annotate_user_memaccess(
11143                    memory_index,
11144                    memarg,
11145                    0,
11146                    old.as_instruction_value().unwrap(),
11147                )?;
11148                let old = err!(
11149                    self.builder
11150                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11151                );
11152                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11153            }
11154            Operator::I32AtomicRmw16XorU { ref memarg } => {
11155                let value = self.state.pop1()?.into_int_value();
11156                let offset = self.state.pop1()?.into_int_value();
11157                let memory_index = MemoryIndex::from_u32(0);
11158                let effective_address = self.resolve_memory_ptr(
11159                    memory_index,
11160                    memarg,
11161                    self.intrinsics.ptr_ty,
11162                    offset,
11163                    2,
11164                )?;
11165                self.trap_if_misaligned(memarg, effective_address, 2)?;
11166                let narrow_value = err!(self.builder.build_int_truncate(
11167                    value,
11168                    self.intrinsics.i16_ty,
11169                    ""
11170                ));
11171                let old = self
11172                    .builder
11173                    .build_atomicrmw(
11174                        AtomicRMWBinOp::Xor,
11175                        effective_address,
11176                        narrow_value,
11177                        AtomicOrdering::SequentiallyConsistent,
11178                    )
11179                    .unwrap();
11180                self.annotate_user_memaccess(
11181                    memory_index,
11182                    memarg,
11183                    0,
11184                    old.as_instruction_value().unwrap(),
11185                )?;
11186                let old = err!(
11187                    self.builder
11188                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11189                );
11190                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11191            }
11192            Operator::I32AtomicRmwXor { ref memarg } => {
11193                let value = self.state.pop1()?.into_int_value();
11194                let offset = self.state.pop1()?.into_int_value();
11195                let memory_index = MemoryIndex::from_u32(0);
11196                let effective_address = self.resolve_memory_ptr(
11197                    memory_index,
11198                    memarg,
11199                    self.intrinsics.ptr_ty,
11200                    offset,
11201                    4,
11202                )?;
11203                self.trap_if_misaligned(memarg, effective_address, 4)?;
11204                let old = self
11205                    .builder
11206                    .build_atomicrmw(
11207                        AtomicRMWBinOp::Xor,
11208                        effective_address,
11209                        value,
11210                        AtomicOrdering::SequentiallyConsistent,
11211                    )
11212                    .unwrap();
11213                self.annotate_user_memaccess(
11214                    memory_index,
11215                    memarg,
11216                    0,
11217                    old.as_instruction_value().unwrap(),
11218                )?;
11219                self.state.push1(old);
11220            }
11221            Operator::I64AtomicRmw8XorU { ref memarg } => {
11222                let value = self.state.pop1()?.into_int_value();
11223                let offset = self.state.pop1()?.into_int_value();
11224                let memory_index = MemoryIndex::from_u32(0);
11225                let effective_address = self.resolve_memory_ptr(
11226                    memory_index,
11227                    memarg,
11228                    self.intrinsics.ptr_ty,
11229                    offset,
11230                    1,
11231                )?;
11232                self.trap_if_misaligned(memarg, effective_address, 1)?;
11233                let narrow_value = err!(self.builder.build_int_truncate(
11234                    value,
11235                    self.intrinsics.i8_ty,
11236                    ""
11237                ));
11238                let old = self
11239                    .builder
11240                    .build_atomicrmw(
11241                        AtomicRMWBinOp::Xor,
11242                        effective_address,
11243                        narrow_value,
11244                        AtomicOrdering::SequentiallyConsistent,
11245                    )
11246                    .unwrap();
11247                self.annotate_user_memaccess(
11248                    memory_index,
11249                    memarg,
11250                    0,
11251                    old.as_instruction_value().unwrap(),
11252                )?;
11253                let old = err!(
11254                    self.builder
11255                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11256                );
11257                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11258            }
11259            Operator::I64AtomicRmw16XorU { ref memarg } => {
11260                let value = self.state.pop1()?.into_int_value();
11261                let offset = self.state.pop1()?.into_int_value();
11262                let memory_index = MemoryIndex::from_u32(0);
11263                let effective_address = self.resolve_memory_ptr(
11264                    memory_index,
11265                    memarg,
11266                    self.intrinsics.ptr_ty,
11267                    offset,
11268                    2,
11269                )?;
11270                self.trap_if_misaligned(memarg, effective_address, 2)?;
11271                let narrow_value = err!(self.builder.build_int_truncate(
11272                    value,
11273                    self.intrinsics.i16_ty,
11274                    ""
11275                ));
11276                let old = self
11277                    .builder
11278                    .build_atomicrmw(
11279                        AtomicRMWBinOp::Xor,
11280                        effective_address,
11281                        narrow_value,
11282                        AtomicOrdering::SequentiallyConsistent,
11283                    )
11284                    .unwrap();
11285                self.annotate_user_memaccess(
11286                    memory_index,
11287                    memarg,
11288                    0,
11289                    old.as_instruction_value().unwrap(),
11290                )?;
11291                let old = err!(
11292                    self.builder
11293                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11294                );
11295                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11296            }
11297            Operator::I64AtomicRmw32XorU { ref memarg } => {
11298                let value = self.state.pop1()?.into_int_value();
11299                let offset = self.state.pop1()?.into_int_value();
11300                let memory_index = MemoryIndex::from_u32(0);
11301                let effective_address = self.resolve_memory_ptr(
11302                    memory_index,
11303                    memarg,
11304                    self.intrinsics.ptr_ty,
11305                    offset,
11306                    4,
11307                )?;
11308                self.trap_if_misaligned(memarg, effective_address, 4)?;
11309                let narrow_value = err!(self.builder.build_int_truncate(
11310                    value,
11311                    self.intrinsics.i32_ty,
11312                    ""
11313                ));
11314                let old = self
11315                    .builder
11316                    .build_atomicrmw(
11317                        AtomicRMWBinOp::Xor,
11318                        effective_address,
11319                        narrow_value,
11320                        AtomicOrdering::SequentiallyConsistent,
11321                    )
11322                    .unwrap();
11323                self.annotate_user_memaccess(
11324                    memory_index,
11325                    memarg,
11326                    0,
11327                    old.as_instruction_value().unwrap(),
11328                )?;
11329                let old = err!(
11330                    self.builder
11331                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11332                );
11333                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11334            }
11335            Operator::I64AtomicRmwXor { ref memarg } => {
11336                let value = self.state.pop1()?.into_int_value();
11337                let offset = self.state.pop1()?.into_int_value();
11338                let memory_index = MemoryIndex::from_u32(0);
11339                let effective_address = self.resolve_memory_ptr(
11340                    memory_index,
11341                    memarg,
11342                    self.intrinsics.ptr_ty,
11343                    offset,
11344                    8,
11345                )?;
11346                self.trap_if_misaligned(memarg, effective_address, 8)?;
11347                let old = self
11348                    .builder
11349                    .build_atomicrmw(
11350                        AtomicRMWBinOp::Xor,
11351                        effective_address,
11352                        value,
11353                        AtomicOrdering::SequentiallyConsistent,
11354                    )
11355                    .unwrap();
11356                self.annotate_user_memaccess(
11357                    memory_index,
11358                    memarg,
11359                    0,
11360                    old.as_instruction_value().unwrap(),
11361                )?;
11362                self.state.push1(old);
11363            }
11364            Operator::I32AtomicRmw8XchgU { ref memarg } => {
11365                let value = self.state.pop1()?.into_int_value();
11366                let offset = self.state.pop1()?.into_int_value();
11367                let memory_index = MemoryIndex::from_u32(0);
11368                let effective_address = self.resolve_memory_ptr(
11369                    memory_index,
11370                    memarg,
11371                    self.intrinsics.ptr_ty,
11372                    offset,
11373                    1,
11374                )?;
11375                self.trap_if_misaligned(memarg, effective_address, 1)?;
11376                let narrow_value = err!(self.builder.build_int_truncate(
11377                    value,
11378                    self.intrinsics.i8_ty,
11379                    ""
11380                ));
11381                let old = self
11382                    .builder
11383                    .build_atomicrmw(
11384                        AtomicRMWBinOp::Xchg,
11385                        effective_address,
11386                        narrow_value,
11387                        AtomicOrdering::SequentiallyConsistent,
11388                    )
11389                    .unwrap();
11390                self.annotate_user_memaccess(
11391                    memory_index,
11392                    memarg,
11393                    0,
11394                    old.as_instruction_value().unwrap(),
11395                )?;
11396                let old = err!(
11397                    self.builder
11398                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11399                );
11400                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11401            }
11402            Operator::I32AtomicRmw16XchgU { ref memarg } => {
11403                let value = self.state.pop1()?.into_int_value();
11404                let offset = self.state.pop1()?.into_int_value();
11405                let memory_index = MemoryIndex::from_u32(0);
11406                let effective_address = self.resolve_memory_ptr(
11407                    memory_index,
11408                    memarg,
11409                    self.intrinsics.ptr_ty,
11410                    offset,
11411                    2,
11412                )?;
11413                self.trap_if_misaligned(memarg, effective_address, 2)?;
11414                let narrow_value = err!(self.builder.build_int_truncate(
11415                    value,
11416                    self.intrinsics.i16_ty,
11417                    ""
11418                ));
11419                let old = self
11420                    .builder
11421                    .build_atomicrmw(
11422                        AtomicRMWBinOp::Xchg,
11423                        effective_address,
11424                        narrow_value,
11425                        AtomicOrdering::SequentiallyConsistent,
11426                    )
11427                    .unwrap();
11428                self.annotate_user_memaccess(
11429                    memory_index,
11430                    memarg,
11431                    0,
11432                    old.as_instruction_value().unwrap(),
11433                )?;
11434                let old = err!(
11435                    self.builder
11436                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11437                );
11438                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11439            }
11440            Operator::I32AtomicRmwXchg { ref memarg } => {
11441                let value = self.state.pop1()?.into_int_value();
11442                let offset = self.state.pop1()?.into_int_value();
11443                let memory_index = MemoryIndex::from_u32(0);
11444                let effective_address = self.resolve_memory_ptr(
11445                    memory_index,
11446                    memarg,
11447                    self.intrinsics.ptr_ty,
11448                    offset,
11449                    4,
11450                )?;
11451                self.trap_if_misaligned(memarg, effective_address, 4)?;
11452                let old = self
11453                    .builder
11454                    .build_atomicrmw(
11455                        AtomicRMWBinOp::Xchg,
11456                        effective_address,
11457                        value,
11458                        AtomicOrdering::SequentiallyConsistent,
11459                    )
11460                    .unwrap();
11461                self.annotate_user_memaccess(
11462                    memory_index,
11463                    memarg,
11464                    0,
11465                    old.as_instruction_value().unwrap(),
11466                )?;
11467                self.state.push1(old);
11468            }
11469            Operator::I64AtomicRmw8XchgU { ref memarg } => {
11470                let value = self.state.pop1()?.into_int_value();
11471                let offset = self.state.pop1()?.into_int_value();
11472                let memory_index = MemoryIndex::from_u32(0);
11473                let effective_address = self.resolve_memory_ptr(
11474                    memory_index,
11475                    memarg,
11476                    self.intrinsics.ptr_ty,
11477                    offset,
11478                    1,
11479                )?;
11480                self.trap_if_misaligned(memarg, effective_address, 1)?;
11481                let narrow_value = err!(self.builder.build_int_truncate(
11482                    value,
11483                    self.intrinsics.i8_ty,
11484                    ""
11485                ));
11486                let old = self
11487                    .builder
11488                    .build_atomicrmw(
11489                        AtomicRMWBinOp::Xchg,
11490                        effective_address,
11491                        narrow_value,
11492                        AtomicOrdering::SequentiallyConsistent,
11493                    )
11494                    .unwrap();
11495                self.annotate_user_memaccess(
11496                    memory_index,
11497                    memarg,
11498                    0,
11499                    old.as_instruction_value().unwrap(),
11500                )?;
11501                let old = err!(
11502                    self.builder
11503                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11504                );
11505                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11506            }
11507            Operator::I64AtomicRmw16XchgU { ref memarg } => {
11508                let value = self.state.pop1()?.into_int_value();
11509                let offset = self.state.pop1()?.into_int_value();
11510                let memory_index = MemoryIndex::from_u32(0);
11511                let effective_address = self.resolve_memory_ptr(
11512                    memory_index,
11513                    memarg,
11514                    self.intrinsics.ptr_ty,
11515                    offset,
11516                    2,
11517                )?;
11518                self.trap_if_misaligned(memarg, effective_address, 2)?;
11519                let narrow_value = err!(self.builder.build_int_truncate(
11520                    value,
11521                    self.intrinsics.i16_ty,
11522                    ""
11523                ));
11524                let old = self
11525                    .builder
11526                    .build_atomicrmw(
11527                        AtomicRMWBinOp::Xchg,
11528                        effective_address,
11529                        narrow_value,
11530                        AtomicOrdering::SequentiallyConsistent,
11531                    )
11532                    .unwrap();
11533                self.annotate_user_memaccess(
11534                    memory_index,
11535                    memarg,
11536                    0,
11537                    old.as_instruction_value().unwrap(),
11538                )?;
11539                let old = err!(
11540                    self.builder
11541                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11542                );
11543                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11544            }
11545            Operator::I64AtomicRmw32XchgU { ref memarg } => {
11546                let value = self.state.pop1()?.into_int_value();
11547                let offset = self.state.pop1()?.into_int_value();
11548                let memory_index = MemoryIndex::from_u32(0);
11549                let effective_address = self.resolve_memory_ptr(
11550                    memory_index,
11551                    memarg,
11552                    self.intrinsics.ptr_ty,
11553                    offset,
11554                    4,
11555                )?;
11556                self.trap_if_misaligned(memarg, effective_address, 4)?;
11557                let narrow_value = err!(self.builder.build_int_truncate(
11558                    value,
11559                    self.intrinsics.i32_ty,
11560                    ""
11561                ));
11562                let old = self
11563                    .builder
11564                    .build_atomicrmw(
11565                        AtomicRMWBinOp::Xchg,
11566                        effective_address,
11567                        narrow_value,
11568                        AtomicOrdering::SequentiallyConsistent,
11569                    )
11570                    .unwrap();
11571                self.annotate_user_memaccess(
11572                    memory_index,
11573                    memarg,
11574                    0,
11575                    old.as_instruction_value().unwrap(),
11576                )?;
11577                let old = err!(
11578                    self.builder
11579                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11580                );
11581                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11582            }
11583            Operator::I64AtomicRmwXchg { ref memarg } => {
11584                let value = self.state.pop1()?.into_int_value();
11585                let offset = self.state.pop1()?.into_int_value();
11586                let memory_index = MemoryIndex::from_u32(0);
11587                let effective_address = self.resolve_memory_ptr(
11588                    memory_index,
11589                    memarg,
11590                    self.intrinsics.ptr_ty,
11591                    offset,
11592                    8,
11593                )?;
11594                self.trap_if_misaligned(memarg, effective_address, 8)?;
11595                let old = self
11596                    .builder
11597                    .build_atomicrmw(
11598                        AtomicRMWBinOp::Xchg,
11599                        effective_address,
11600                        value,
11601                        AtomicOrdering::SequentiallyConsistent,
11602                    )
11603                    .unwrap();
11604                self.annotate_user_memaccess(
11605                    memory_index,
11606                    memarg,
11607                    0,
11608                    old.as_instruction_value().unwrap(),
11609                )?;
11610                self.state.push1(old);
11611            }
11612            Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
11613                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11614                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11615                let new = self.apply_pending_canonicalization(new, new_info)?;
11616                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11617                let offset = self.state.pop1()?.into_int_value();
11618                let memory_index = MemoryIndex::from_u32(0);
11619                let effective_address = self.resolve_memory_ptr(
11620                    memory_index,
11621                    memarg,
11622                    self.intrinsics.ptr_ty,
11623                    offset,
11624                    1,
11625                )?;
11626                self.trap_if_misaligned(memarg, effective_address, 1)?;
11627                let narrow_cmp = err!(self.builder.build_int_truncate(
11628                    cmp,
11629                    self.intrinsics.i8_ty,
11630                    ""
11631                ));
11632                let narrow_new = err!(self.builder.build_int_truncate(
11633                    new,
11634                    self.intrinsics.i8_ty,
11635                    ""
11636                ));
11637                let old = self
11638                    .builder
11639                    .build_cmpxchg(
11640                        effective_address,
11641                        narrow_cmp,
11642                        narrow_new,
11643                        AtomicOrdering::SequentiallyConsistent,
11644                        AtomicOrdering::SequentiallyConsistent,
11645                    )
11646                    .unwrap();
11647                self.annotate_user_memaccess(
11648                    memory_index,
11649                    memarg,
11650                    0,
11651                    old.as_instruction_value().unwrap(),
11652                )?;
11653                let old = self
11654                    .builder
11655                    .build_extract_value(old, 0, "")
11656                    .unwrap()
11657                    .into_int_value();
11658                let old = err!(
11659                    self.builder
11660                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11661                );
11662                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11663            }
11664            Operator::I32AtomicRmw16CmpxchgU { ref memarg } => {
11665                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11666                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11667                let new = self.apply_pending_canonicalization(new, new_info)?;
11668                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11669                let offset = self.state.pop1()?.into_int_value();
11670                let memory_index = MemoryIndex::from_u32(0);
11671                let effective_address = self.resolve_memory_ptr(
11672                    memory_index,
11673                    memarg,
11674                    self.intrinsics.ptr_ty,
11675                    offset,
11676                    2,
11677                )?;
11678                self.trap_if_misaligned(memarg, effective_address, 2)?;
11679                let narrow_cmp = err!(self.builder.build_int_truncate(
11680                    cmp,
11681                    self.intrinsics.i16_ty,
11682                    ""
11683                ));
11684                let narrow_new = err!(self.builder.build_int_truncate(
11685                    new,
11686                    self.intrinsics.i16_ty,
11687                    ""
11688                ));
11689                let old = self
11690                    .builder
11691                    .build_cmpxchg(
11692                        effective_address,
11693                        narrow_cmp,
11694                        narrow_new,
11695                        AtomicOrdering::SequentiallyConsistent,
11696                        AtomicOrdering::SequentiallyConsistent,
11697                    )
11698                    .unwrap();
11699                self.annotate_user_memaccess(
11700                    memory_index,
11701                    memarg,
11702                    0,
11703                    old.as_instruction_value().unwrap(),
11704                )?;
11705                let old = self
11706                    .builder
11707                    .build_extract_value(old, 0, "")
11708                    .unwrap()
11709                    .into_int_value();
11710                let old = err!(
11711                    self.builder
11712                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11713                );
11714                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11715            }
11716            Operator::I32AtomicRmwCmpxchg { ref memarg } => {
11717                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11718                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11719                let new = self.apply_pending_canonicalization(new, new_info)?;
11720                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11721                let offset = self.state.pop1()?.into_int_value();
11722                let memory_index = MemoryIndex::from_u32(0);
11723                let effective_address = self.resolve_memory_ptr(
11724                    memory_index,
11725                    memarg,
11726                    self.intrinsics.ptr_ty,
11727                    offset,
11728                    4,
11729                )?;
11730                self.trap_if_misaligned(memarg, effective_address, 4)?;
11731                let old = self
11732                    .builder
11733                    .build_cmpxchg(
11734                        effective_address,
11735                        cmp,
11736                        new,
11737                        AtomicOrdering::SequentiallyConsistent,
11738                        AtomicOrdering::SequentiallyConsistent,
11739                    )
11740                    .unwrap();
11741                self.annotate_user_memaccess(
11742                    memory_index,
11743                    memarg,
11744                    0,
11745                    old.as_instruction_value().unwrap(),
11746                )?;
11747                let old = err!(self.builder.build_extract_value(old, 0, ""));
11748                self.state.push1(old);
11749            }
11750            Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
11751                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11752                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11753                let new = self.apply_pending_canonicalization(new, new_info)?;
11754                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11755                let offset = self.state.pop1()?.into_int_value();
11756                let memory_index = MemoryIndex::from_u32(0);
11757                let effective_address = self.resolve_memory_ptr(
11758                    memory_index,
11759                    memarg,
11760                    self.intrinsics.ptr_ty,
11761                    offset,
11762                    1,
11763                )?;
11764                self.trap_if_misaligned(memarg, effective_address, 1)?;
11765                let narrow_cmp = err!(self.builder.build_int_truncate(
11766                    cmp,
11767                    self.intrinsics.i8_ty,
11768                    ""
11769                ));
11770                let narrow_new = err!(self.builder.build_int_truncate(
11771                    new,
11772                    self.intrinsics.i8_ty,
11773                    ""
11774                ));
11775                let old = self
11776                    .builder
11777                    .build_cmpxchg(
11778                        effective_address,
11779                        narrow_cmp,
11780                        narrow_new,
11781                        AtomicOrdering::SequentiallyConsistent,
11782                        AtomicOrdering::SequentiallyConsistent,
11783                    )
11784                    .unwrap();
11785                self.annotate_user_memaccess(
11786                    memory_index,
11787                    memarg,
11788                    0,
11789                    old.as_instruction_value().unwrap(),
11790                )?;
11791                let old = self
11792                    .builder
11793                    .build_extract_value(old, 0, "")
11794                    .unwrap()
11795                    .into_int_value();
11796                let old = err!(
11797                    self.builder
11798                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11799                );
11800                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11801            }
11802            Operator::I64AtomicRmw16CmpxchgU { ref memarg } => {
11803                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11804                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11805                let new = self.apply_pending_canonicalization(new, new_info)?;
11806                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11807                let offset = self.state.pop1()?.into_int_value();
11808                let memory_index = MemoryIndex::from_u32(0);
11809                let effective_address = self.resolve_memory_ptr(
11810                    memory_index,
11811                    memarg,
11812                    self.intrinsics.ptr_ty,
11813                    offset,
11814                    2,
11815                )?;
11816                self.trap_if_misaligned(memarg, effective_address, 2)?;
11817                let narrow_cmp = err!(self.builder.build_int_truncate(
11818                    cmp,
11819                    self.intrinsics.i16_ty,
11820                    ""
11821                ));
11822                let narrow_new = err!(self.builder.build_int_truncate(
11823                    new,
11824                    self.intrinsics.i16_ty,
11825                    ""
11826                ));
11827                let old = self
11828                    .builder
11829                    .build_cmpxchg(
11830                        effective_address,
11831                        narrow_cmp,
11832                        narrow_new,
11833                        AtomicOrdering::SequentiallyConsistent,
11834                        AtomicOrdering::SequentiallyConsistent,
11835                    )
11836                    .unwrap();
11837                self.annotate_user_memaccess(
11838                    memory_index,
11839                    memarg,
11840                    0,
11841                    old.as_instruction_value().unwrap(),
11842                )?;
11843                let old = self
11844                    .builder
11845                    .build_extract_value(old, 0, "")
11846                    .unwrap()
11847                    .into_int_value();
11848                let old = err!(
11849                    self.builder
11850                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11851                );
11852                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11853            }
11854            Operator::I64AtomicRmw32CmpxchgU { ref memarg } => {
11855                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11856                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11857                let new = self.apply_pending_canonicalization(new, new_info)?;
11858                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11859                let offset = self.state.pop1()?.into_int_value();
11860                let memory_index = MemoryIndex::from_u32(0);
11861                let effective_address = self.resolve_memory_ptr(
11862                    memory_index,
11863                    memarg,
11864                    self.intrinsics.ptr_ty,
11865                    offset,
11866                    4,
11867                )?;
11868                self.trap_if_misaligned(memarg, effective_address, 4)?;
11869                let narrow_cmp = err!(self.builder.build_int_truncate(
11870                    cmp,
11871                    self.intrinsics.i32_ty,
11872                    ""
11873                ));
11874                let narrow_new = err!(self.builder.build_int_truncate(
11875                    new,
11876                    self.intrinsics.i32_ty,
11877                    ""
11878                ));
11879                let old = self
11880                    .builder
11881                    .build_cmpxchg(
11882                        effective_address,
11883                        narrow_cmp,
11884                        narrow_new,
11885                        AtomicOrdering::SequentiallyConsistent,
11886                        AtomicOrdering::SequentiallyConsistent,
11887                    )
11888                    .unwrap();
11889                self.annotate_user_memaccess(
11890                    memory_index,
11891                    memarg,
11892                    0,
11893                    old.as_instruction_value().unwrap(),
11894                )?;
11895                let old = self
11896                    .builder
11897                    .build_extract_value(old, 0, "")
11898                    .unwrap()
11899                    .into_int_value();
11900                let old = err!(
11901                    self.builder
11902                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11903                );
11904                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11905            }
11906            Operator::I64AtomicRmwCmpxchg { ref memarg } => {
11907                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11908                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11909                let new = self.apply_pending_canonicalization(new, new_info)?;
11910                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11911                let offset = self.state.pop1()?.into_int_value();
11912                let memory_index = MemoryIndex::from_u32(0);
11913                let effective_address = self.resolve_memory_ptr(
11914                    memory_index,
11915                    memarg,
11916                    self.intrinsics.ptr_ty,
11917                    offset,
11918                    8,
11919                )?;
11920                self.trap_if_misaligned(memarg, effective_address, 8)?;
11921                let old = self
11922                    .builder
11923                    .build_cmpxchg(
11924                        effective_address,
11925                        cmp,
11926                        new,
11927                        AtomicOrdering::SequentiallyConsistent,
11928                        AtomicOrdering::SequentiallyConsistent,
11929                    )
11930                    .unwrap();
11931                self.annotate_user_memaccess(
11932                    memory_index,
11933                    memarg,
11934                    0,
11935                    old.as_instruction_value().unwrap(),
11936                )?;
11937                let old = err!(self.builder.build_extract_value(old, 0, ""));
11938                self.state.push1(old);
11939            }
11940
11941            Operator::MemoryGrow { mem } => {
11942                let memory_index = MemoryIndex::from_u32(mem);
11943                let delta = self.state.pop1()?;
11944                let grow_fn_ptr = self.ctx.memory_grow(memory_index, self.intrinsics)?;
11945                let grow = err!(self.builder.build_indirect_call(
11946                    self.intrinsics.memory_grow_ty,
11947                    grow_fn_ptr,
11948                    &[
11949                        vmctx.as_basic_value_enum().into(),
11950                        delta.into(),
11951                        self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11952                    ],
11953                    "",
11954                ));
11955                self.state.push1(grow.try_as_basic_value().unwrap_basic());
11956            }
11957            Operator::MemorySize { mem } => {
11958                let memory_index = MemoryIndex::from_u32(mem);
11959                let size_fn_ptr = self.ctx.memory_size(memory_index, self.intrinsics)?;
11960                let size = err!(self.builder.build_indirect_call(
11961                    self.intrinsics.memory_size_ty,
11962                    size_fn_ptr,
11963                    &[
11964                        vmctx.as_basic_value_enum().into(),
11965                        self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11966                    ],
11967                    "",
11968                ));
11969                //size.add_attribute(AttributeLoc::Function, self.intrinsics.readonly);
11970                self.state.push1(size.try_as_basic_value().unwrap_basic());
11971            }
11972            Operator::MemoryInit { data_index, mem } => {
11973                let (dest, src, len) = self.state.pop3()?;
11974                let mem = self.intrinsics.i32_ty.const_int(mem.into(), false);
11975                let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11976                err!(self.builder.build_call(
11977                    self.intrinsics.memory_init,
11978                    &[
11979                        vmctx.as_basic_value_enum().into(),
11980                        mem.into(),
11981                        segment.into(),
11982                        dest.into(),
11983                        src.into(),
11984                        len.into(),
11985                    ],
11986                    "",
11987                ));
11988            }
11989            Operator::DataDrop { data_index } => {
11990                let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11991                err!(self.builder.build_call(
11992                    self.intrinsics.data_drop,
11993                    &[vmctx.as_basic_value_enum().into(), segment.into()],
11994                    "",
11995                ));
11996            }
11997            Operator::MemoryCopy { dst_mem, src_mem } => {
11998                // ignored until we support multiple memories
11999                let _dst = dst_mem;
12000                let (memory_copy, src) = if let Some(local_memory_index) = self
12001                    .wasm_module
12002                    .local_memory_index(MemoryIndex::from_u32(src_mem))
12003                {
12004                    (self.intrinsics.memory_copy, local_memory_index.as_u32())
12005                } else {
12006                    (self.intrinsics.imported_memory_copy, src_mem)
12007                };
12008
12009                let (dest_pos, src_pos, len) = self.state.pop3()?;
12010                let src_index = self.intrinsics.i32_ty.const_int(src.into(), false);
12011                err!(self.builder.build_call(
12012                    memory_copy,
12013                    &[
12014                        vmctx.as_basic_value_enum().into(),
12015                        src_index.into(),
12016                        dest_pos.into(),
12017                        src_pos.into(),
12018                        len.into(),
12019                    ],
12020                    "",
12021                ));
12022            }
12023            Operator::MemoryFill { mem } => {
12024                let (memory_fill, mem) = if let Some(local_memory_index) = self
12025                    .wasm_module
12026                    .local_memory_index(MemoryIndex::from_u32(mem))
12027                {
12028                    (self.intrinsics.memory_fill, local_memory_index.as_u32())
12029                } else {
12030                    (self.intrinsics.imported_memory_fill, mem)
12031                };
12032
12033                let (dst, val, len) = self.state.pop3()?;
12034                let mem_index = self.intrinsics.i32_ty.const_int(mem.into(), false);
12035                err!(self.builder.build_call(
12036                    memory_fill,
12037                    &[
12038                        vmctx.as_basic_value_enum().into(),
12039                        mem_index.into(),
12040                        dst.into(),
12041                        val.into(),
12042                        len.into(),
12043                    ],
12044                    "",
12045                ));
12046            }
12047            /***************************
12048             * Reference types.
12049             * https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md
12050             ***************************/
12051            Operator::RefNull { hty } => {
12052                let ty = err!(wpheaptype_to_type(hty));
12053                let ty = type_to_llvm(self.intrinsics, ty)?;
12054                self.state.push1(ty.const_zero());
12055            }
12056            Operator::RefIsNull => {
12057                let value = self.state.pop1()?.into_pointer_value();
12058                let is_null = err!(self.builder.build_is_null(value, ""));
12059                let is_null = err!(self.builder.build_int_z_extend(
12060                    is_null,
12061                    self.intrinsics.i32_ty,
12062                    ""
12063                ));
12064                self.state.push1(is_null);
12065            }
12066            Operator::RefFunc { function_index } => {
12067                let index = self
12068                    .intrinsics
12069                    .i32_ty
12070                    .const_int(function_index.into(), false);
12071                let value = err!(self.builder.build_call(
12072                    self.intrinsics.func_ref,
12073                    &[self.ctx.basic().into(), index.into()],
12074                    "",
12075                ))
12076                .try_as_basic_value()
12077                .unwrap_basic();
12078                self.state.push1(value);
12079            }
12080            Operator::TableGet { table } => {
12081                let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12082                let elem = self.state.pop1()?;
12083                let table_get = if self
12084                    .wasm_module
12085                    .local_table_index(TableIndex::from_u32(table))
12086                    .is_some()
12087                {
12088                    self.intrinsics.table_get
12089                } else {
12090                    self.intrinsics.imported_table_get
12091                };
12092                let value = err!(self.builder.build_call(
12093                    table_get,
12094                    &[self.ctx.basic().into(), table_index.into(), elem.into()],
12095                    "",
12096                ))
12097                .try_as_basic_value()
12098                .unwrap_basic();
12099                let value = err!(
12100                    self.builder.build_bit_cast(
12101                        value,
12102                        type_to_llvm(
12103                            self.intrinsics,
12104                            self.wasm_module
12105                                .tables
12106                                .get(TableIndex::from_u32(table))
12107                                .unwrap()
12108                                .ty,
12109                        )?,
12110                        "",
12111                    )
12112                );
12113                self.state.push1(value);
12114            }
12115            Operator::TableSet { table } => {
12116                let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12117                let (elem, value) = self.state.pop2()?;
12118                let value = err!(
12119                    self.builder
12120                        .build_bit_cast(value, self.intrinsics.ptr_ty, "")
12121                );
12122                let table_set = if self
12123                    .wasm_module
12124                    .local_table_index(TableIndex::from_u32(table))
12125                    .is_some()
12126                {
12127                    self.intrinsics.table_set
12128                } else {
12129                    self.intrinsics.imported_table_set
12130                };
12131                err!(self.builder.build_call(
12132                    table_set,
12133                    &[
12134                        self.ctx.basic().into(),
12135                        table_index.into(),
12136                        elem.into(),
12137                        value.into(),
12138                    ],
12139                    "",
12140                ));
12141            }
12142            Operator::TableCopy {
12143                dst_table,
12144                src_table,
12145            } => {
12146                let (dst, src, len) = self.state.pop3()?;
12147                let dst_table = self.intrinsics.i32_ty.const_int(dst_table as u64, false);
12148                let src_table = self.intrinsics.i32_ty.const_int(src_table as u64, false);
12149                err!(self.builder.build_call(
12150                    self.intrinsics.table_copy,
12151                    &[
12152                        self.ctx.basic().into(),
12153                        dst_table.into(),
12154                        src_table.into(),
12155                        dst.into(),
12156                        src.into(),
12157                        len.into(),
12158                    ],
12159                    "",
12160                ));
12161            }
12162            Operator::TableInit { elem_index, table } => {
12163                let (dst, src, len) = self.state.pop3()?;
12164                let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12165                let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12166                err!(self.builder.build_call(
12167                    self.intrinsics.table_init,
12168                    &[
12169                        self.ctx.basic().into(),
12170                        table.into(),
12171                        segment.into(),
12172                        dst.into(),
12173                        src.into(),
12174                        len.into(),
12175                    ],
12176                    "",
12177                ));
12178            }
12179            Operator::ElemDrop { elem_index } => {
12180                let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12181                err!(self.builder.build_call(
12182                    self.intrinsics.elem_drop,
12183                    &[self.ctx.basic().into(), segment.into()],
12184                    "",
12185                ));
12186            }
12187            Operator::TableFill { table } => {
12188                let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12189                let (start, elem, len) = self.state.pop3()?;
12190                let elem = err!(
12191                    self.builder
12192                        .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12193                );
12194                err!(self.builder.build_call(
12195                    self.intrinsics.table_fill,
12196                    &[
12197                        self.ctx.basic().into(),
12198                        table.into(),
12199                        start.into(),
12200                        elem.into(),
12201                        len.into(),
12202                    ],
12203                    "",
12204                ));
12205            }
12206            Operator::TableGrow { table } => {
12207                let (elem, delta) = self.state.pop2()?;
12208                let elem = err!(
12209                    self.builder
12210                        .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12211                );
12212                let (table_grow, table_index) = if let Some(local_table_index) = self
12213                    .wasm_module
12214                    .local_table_index(TableIndex::from_u32(table))
12215                {
12216                    (self.intrinsics.table_grow, local_table_index.as_u32())
12217                } else {
12218                    (self.intrinsics.imported_table_grow, table)
12219                };
12220                let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12221                let size = err!(self.builder.build_call(
12222                    table_grow,
12223                    &[
12224                        self.ctx.basic().into(),
12225                        elem.into(),
12226                        delta.into(),
12227                        table_index.into(),
12228                    ],
12229                    "",
12230                ))
12231                .try_as_basic_value()
12232                .unwrap_basic();
12233                self.state.push1(size);
12234            }
12235            Operator::TableSize { table } => {
12236                let (table_size, table_index) = if let Some(local_table_index) = self
12237                    .wasm_module
12238                    .local_table_index(TableIndex::from_u32(table))
12239                {
12240                    (self.intrinsics.table_size, local_table_index.as_u32())
12241                } else {
12242                    (self.intrinsics.imported_table_size, table)
12243                };
12244                let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12245                let size = err!(self.builder.build_call(
12246                    table_size,
12247                    &[self.ctx.basic().into(), table_index.into()],
12248                    "",
12249                ))
12250                .try_as_basic_value()
12251                .unwrap_basic();
12252                self.state.push1(size);
12253            }
12254            Operator::MemoryAtomicWait32 { memarg } => {
12255                let memory_index = MemoryIndex::from_u32(memarg.memory);
12256                let (dst, val, timeout) = self.state.pop3()?;
12257                let wait32_fn_ptr = self.ctx.memory_wait32(memory_index, self.intrinsics)?;
12258                let ret = err!(
12259                    self.builder.build_indirect_call(
12260                        self.intrinsics.memory_wait32_ty,
12261                        wait32_fn_ptr,
12262                        &[
12263                            vmctx.as_basic_value_enum().into(),
12264                            self.intrinsics
12265                                .i32_ty
12266                                .const_int(memarg.memory as u64, false)
12267                                .into(),
12268                            dst.into(),
12269                            val.into(),
12270                            timeout.into(),
12271                        ],
12272                        "",
12273                    )
12274                );
12275                self.state.push1(ret.try_as_basic_value().unwrap_basic());
12276            }
12277            Operator::MemoryAtomicWait64 { memarg } => {
12278                let memory_index = MemoryIndex::from_u32(memarg.memory);
12279                let (dst, val, timeout) = self.state.pop3()?;
12280                let wait64_fn_ptr = self.ctx.memory_wait64(memory_index, self.intrinsics)?;
12281                let ret = err!(
12282                    self.builder.build_indirect_call(
12283                        self.intrinsics.memory_wait64_ty,
12284                        wait64_fn_ptr,
12285                        &[
12286                            vmctx.as_basic_value_enum().into(),
12287                            self.intrinsics
12288                                .i32_ty
12289                                .const_int(memarg.memory as u64, false)
12290                                .into(),
12291                            dst.into(),
12292                            val.into(),
12293                            timeout.into(),
12294                        ],
12295                        "",
12296                    )
12297                );
12298                self.state.push1(ret.try_as_basic_value().unwrap_basic());
12299            }
12300            Operator::MemoryAtomicNotify { memarg } => {
12301                let memory_index = MemoryIndex::from_u32(memarg.memory);
12302                let (dst, count) = self.state.pop2()?;
12303                let notify_fn_ptr = self.ctx.memory_notify(memory_index, self.intrinsics)?;
12304                let cnt = err!(
12305                    self.builder.build_indirect_call(
12306                        self.intrinsics.memory_notify_ty,
12307                        notify_fn_ptr,
12308                        &[
12309                            vmctx.as_basic_value_enum().into(),
12310                            self.intrinsics
12311                                .i32_ty
12312                                .const_int(memarg.memory as u64, false)
12313                                .into(),
12314                            dst.into(),
12315                            count.into(),
12316                        ],
12317                        "",
12318                    )
12319                );
12320                self.state.push1(cnt.try_as_basic_value().unwrap_basic());
12321            }
12322
12323            Operator::TryTable { try_table } => {
12324                let current_block = self
12325                    .builder
12326                    .get_insert_block()
12327                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12328
12329                self.builder.position_at_end(current_block);
12330
12331                let end_block = self.context.append_basic_block(self.function, "try_end");
12332
12333                let end_phis = {
12334                    self.builder.position_at_end(end_block);
12335
12336                    let phis = self
12337                        .module_translation
12338                        .blocktype_params_results(&try_table.ty)?
12339                        .1
12340                        .iter()
12341                        .map(|&wp_ty| {
12342                            err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
12343                                type_to_llvm(self.intrinsics, wasm_ty)
12344                                    .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
12345                            })
12346                        })
12347                        .collect::<Result<_, _>>()?;
12348
12349                    self.builder.position_at_end(current_block);
12350                    phis
12351                };
12352
12353                // Collect unique catches. It is not a "hard" error on the wasm side,
12354                // but LLVM will definitely complain about having the same identifier
12355                // match two different branches in the switch below.
12356                let catches: Vec<_> = try_table
12357                    .catches
12358                    .into_iter()
12359                    .unique_by(|v| match v {
12360                        Catch::One { tag, .. } | Catch::OneRef { tag, .. } => *tag as i32,
12361                        Catch::All { .. } | Catch::AllRef { .. } => CATCH_ALL_TAG_VALUE,
12362                    })
12363                    .collect();
12364
12365                // Build the landing pad.
12366                let null = self.intrinsics.ptr_ty.const_zero();
12367
12368                let mut catch_tag_values = vec![];
12369                let mut lpad_clauses: Vec<BasicValueEnum<'ctx>> = catches
12370                    .iter()
12371                    .map(|catch| match catch {
12372                        Catch::All { .. } | Catch::AllRef { .. } => {
12373                            catch_tag_values.push(CATCH_ALL_TAG_VALUE as u32);
12374                            Ok(null.into())
12375                        }
12376                        Catch::One { tag, .. } | Catch::OneRef { tag, .. } => {
12377                            catch_tag_values.push(*tag);
12378                            Ok(self.get_or_insert_tag_type_info_global(*tag as i32))
12379                        }
12380                    })
12381                    .collect::<Result<Vec<BasicValueEnum<'ctx>>, CompileError>>()?;
12382
12383                // Since jumping between landingpads is not possible, we need to collect
12384                // all tags from outer try_tables as well to build a clause for *every*
12385                // possible tag that might be caught.
12386                let mut outer_catch_blocks = vec![];
12387                for outer_landingpad in self.state.landingpads.iter().rev() {
12388                    for catch_info @ TagCatchInfo { tag, .. } in &outer_landingpad.tags {
12389                        if !catch_tag_values.contains(tag) {
12390                            catch_tag_values.push(*tag);
12391                            lpad_clauses.push(if *tag as i32 == CATCH_ALL_TAG_VALUE {
12392                                null.into()
12393                            } else {
12394                                *self.tags_cache.get(&(*tag as i32)).expect(
12395                                    "If a previous try_table encountered a tag, \
12396                                    it should be in the cache",
12397                                )
12398                            });
12399                            outer_catch_blocks.push(*catch_info);
12400                        }
12401                    }
12402                }
12403
12404                // If there are no catch clauses, we have to skip everything, since
12405                // an lpad without catch clauses is invalid (and won't ever be jumped
12406                // to anyway)
12407                let mut maybe_lpad_block = None;
12408                let mut catch_blocks = vec![];
12409                if !lpad_clauses.is_empty() {
12410                    let lpad_block = self.context.append_basic_block(self.function, "catch");
12411                    let catch_all_block =
12412                        self.context.append_basic_block(self.function, "catch_all");
12413                    let catch_specific_block = self
12414                        .context
12415                        .append_basic_block(self.function, "catch_specific");
12416                    let catch_end_block =
12417                        self.context.append_basic_block(self.function, "catch_end");
12418                    let rethrow_block = self.context.append_basic_block(self.function, "rethrow");
12419
12420                    self.builder.position_at_end(lpad_block);
12421
12422                    let res = err!(self.builder.build_landing_pad(
12423                        self.intrinsics.lpad_exception_ty,
12424                        self.intrinsics.personality,
12425                        &lpad_clauses,
12426                        false,
12427                        "exc_struct",
12428                    ));
12429
12430                    let res = res.into_struct_value();
12431
12432                    let uw_exc = err!(self.builder.build_extract_value(res, 0, "exc_ptr"));
12433                    let pre_selector =
12434                        err!(self.builder.build_extract_value(res, 1, "pre_selector"));
12435
12436                    // The pre-selector can be either 0 (for catch-all) or 1 (for a
12437                    // specific, but as-yet-unknown tag).
12438                    let pre_selector_is_zero = err!(self.builder.build_int_compare(
12439                        IntPredicate::EQ,
12440                        pre_selector.into_int_value(),
12441                        self.intrinsics.i32_zero,
12442                        "pre_selector_is_zero"
12443                    ));
12444                    err!(self.builder.build_conditional_branch(
12445                        pre_selector_is_zero,
12446                        catch_all_block,
12447                        catch_specific_block
12448                    ));
12449
12450                    self.builder.position_at_end(catch_all_block);
12451                    err!(self.builder.build_unconditional_branch(catch_end_block));
12452
12453                    self.builder.position_at_end(catch_specific_block);
12454                    let selector_value = err!(self.builder.build_call(
12455                        self.intrinsics.personality2,
12456                        &[self.ctx.basic().into(), uw_exc.into()],
12457                        "selector"
12458                    ));
12459                    err!(self.builder.build_unconditional_branch(catch_end_block));
12460
12461                    self.builder.position_at_end(catch_end_block);
12462                    let selector = err!(self.builder.build_phi(self.intrinsics.i32_ty, "selector"));
12463                    selector.add_incoming(&[
12464                        (
12465                            &self
12466                                .intrinsics
12467                                .i32_ty
12468                                .const_int(CATCH_ALL_TAG_VALUE as u64, false),
12469                            catch_all_block,
12470                        ),
12471                        (
12472                            &selector_value
12473                                .try_as_basic_value()
12474                                .unwrap_basic()
12475                                .into_int_value(),
12476                            catch_specific_block,
12477                        ),
12478                    ]);
12479
12480                    // Now we're done looking at the exception, it's time to deallocate and get
12481                    // the exnref out of it. When an exception is caught, "rethrowing" simply
12482                    // means starting another unwind by calling _Unwind_RaiseException with the
12483                    // same exception bits. Instead of keeping the same exception around, we
12484                    // deallocate the exception once it's caught, and if we need to rethrow, we
12485                    // just re-allocate a new exception.
12486                    //
12487                    // Note that this is different from how it's done in C++ land, where the
12488                    // exception object is kept around for rethrowing; this discrepency exists
12489                    // because in C++, exception handling is lexical (i.e. there's an implicit
12490                    // "current exception" in catch blocks) whereas in WASM, you rethrow with
12491                    // an exnref that may very well have come from somewhere else; consider this
12492                    // (badly implemented and erroneous) pseudo-module:
12493                    //
12494                    // (module
12495                    //   (global $e (mut exnref) (ref.null exn))
12496                    //   ;; Store the given exnref, return the previous one
12497                    //   (func $delay_exnref (param exnref) (result exnref)
12498                    //     (global.get $e)
12499                    //     (local.get 0)
12500                    //     (global.set $e)
12501                    //   )
12502                    //   (func foo
12503                    //     (block $catch (result exnref)
12504                    //       (try_table (catch_all_ref $catch)
12505                    //         ...
12506                    //       )
12507                    //     )
12508                    //     (call $delay_exnref) ;; store the exnref caught above
12509                    //     throw_ref ;; throw the previous exnref
12510                    //   )
12511                    // )
12512                    //
12513                    // Here, it's impossible to reuse the same exception object since the
12514                    // exnref given to throw_ref is a different one than the one we caught
12515                    // with the try_table.
12516                    //
12517                    // Another difference is that C++ exceptions may well carry lots of data
12518                    // around; a WASM exception is just an exnref, backed by a u32, which is
12519                    // just 4 bytes, and is cheap to reallocate. C++ exceptions may also carry
12520                    // things with dtors around; another thing that doesn't exist in WASM.
12521                    //
12522                    // All of this is to say that putting exception deallocation and exnref
12523                    // retrieval in the same function has been a very deliberate choice.
12524                    let uw_exc = uw_exc.into_pointer_value();
12525                    let exnref = err!(self.builder.build_call(
12526                        self.intrinsics.exception_into_exnref,
12527                        &[uw_exc.into()],
12528                        "exnref"
12529                    ));
12530
12531                    let exnref = exnref.try_as_basic_value().unwrap_basic().into_int_value();
12532                    let selector = selector.as_basic_value().into_int_value();
12533
12534                    for catch in catches.iter() {
12535                        match catch {
12536                            Catch::All { label } => {
12537                                let b = self
12538                                    .context
12539                                    .append_basic_block(self.function, "catch_all_clause");
12540                                self.builder.position_at_end(b);
12541                                let frame = self.state.frame_at_depth(*label)?;
12542
12543                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12544
12545                                self.builder.position_at_end(catch_end_block);
12546                                catch_blocks.push((b, None));
12547                            }
12548                            Catch::One { tag, label } => {
12549                                let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12550                                let signature = &self.wasm_module.signatures[tag_idx];
12551                                let params = signature.params();
12552
12553                                let b = self.context.append_basic_block(
12554                                    self.function,
12555                                    format!("catch_one_clause_{tag}").as_str(),
12556                                );
12557                                self.builder.position_at_end(b);
12558
12559                                let exnref_phi = err!(
12560                                    self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12561                                );
12562                                exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12563
12564                                // Get the payload pointer.
12565                                let exn_payload_ptr = err!(self.builder.build_direct_call(
12566                                    self.intrinsics.read_exnref,
12567                                    &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12568                                    "exn_ptr",
12569                                ));
12570                                let exn_payload_ptr = exn_payload_ptr
12571                                    .try_as_basic_value()
12572                                    .unwrap_basic()
12573                                    .into_pointer_value();
12574
12575                                // Read each value from the data ptr.
12576                                let values = params
12577                                    .iter()
12578                                    .enumerate()
12579                                    .map(|(i, v)| {
12580                                        let name = format!("value_{i}");
12581                                        let ptr = err!(unsafe {
12582                                            self.builder.build_gep(
12583                                                self.intrinsics.i128_ty,
12584                                                exn_payload_ptr,
12585                                                &[self
12586                                                    .intrinsics
12587                                                    .i32_ty
12588                                                    .const_int(i as u64, false)],
12589                                                format!("{name}_ptr").as_str(),
12590                                            )
12591                                        });
12592                                        err_nt!(self.builder.build_load(
12593                                            type_to_llvm(self.intrinsics, *v)?,
12594                                            ptr,
12595                                            &name,
12596                                        ))
12597                                    })
12598                                    .collect::<Result<Vec<_>, CompileError>>()?;
12599
12600                                let frame = self.state.frame_at_depth(*label)?;
12601
12602                                for (phi, value) in frame.phis().iter().zip(values.iter()) {
12603                                    phi.add_incoming(&[(value, b)])
12604                                }
12605
12606                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12607
12608                                self.builder.position_at_end(catch_end_block);
12609                                catch_blocks.push((b, Some(exnref_phi)));
12610                            }
12611                            Catch::OneRef { label, tag } => {
12612                                let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12613                                let signature = &self.wasm_module.signatures[tag_idx];
12614                                let params = signature.params();
12615
12616                                let b = self.context.append_basic_block(
12617                                    self.function,
12618                                    format!("catch_one_ref_clause_{tag}").as_str(),
12619                                );
12620                                self.builder.position_at_end(b);
12621
12622                                let exnref_phi = err!(
12623                                    self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12624                                );
12625                                exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12626
12627                                // Get the payload pointer.
12628                                let exn_payload_ptr = err!(self.builder.build_direct_call(
12629                                    self.intrinsics.read_exnref,
12630                                    &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12631                                    "exn_ptr",
12632                                ));
12633                                let exn_payload_ptr = exn_payload_ptr
12634                                    .try_as_basic_value()
12635                                    .unwrap_basic()
12636                                    .into_pointer_value();
12637
12638                                // Read each value from the data ptr.
12639                                let mut values = params
12640                                    .iter()
12641                                    .enumerate()
12642                                    .map(|(i, v)| {
12643                                        let name = format!("value_{i}");
12644                                        let ptr = err!(unsafe {
12645                                            self.builder.build_gep(
12646                                                self.intrinsics.i128_ty,
12647                                                exn_payload_ptr,
12648                                                &[self
12649                                                    .intrinsics
12650                                                    .i32_ty
12651                                                    .const_int(i as u64, false)],
12652                                                format!("{name}_ptr").as_str(),
12653                                            )
12654                                        });
12655                                        err_nt!(self.builder.build_load(
12656                                            type_to_llvm(self.intrinsics, *v)?,
12657                                            ptr,
12658                                            &name,
12659                                        ))
12660                                    })
12661                                    .collect::<Result<Vec<_>, CompileError>>()?;
12662
12663                                values.push(exnref_phi.as_basic_value());
12664
12665                                let frame = self.state.frame_at_depth(*label)?;
12666
12667                                for (phi, value) in frame.phis().iter().zip(values.iter()) {
12668                                    phi.add_incoming(&[(value, b)])
12669                                }
12670
12671                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12672
12673                                self.builder.position_at_end(catch_end_block);
12674                                catch_blocks.push((b, Some(exnref_phi)));
12675                            }
12676                            Catch::AllRef { label } => {
12677                                let b = self
12678                                    .context
12679                                    .append_basic_block(self.function, "catch_all_ref_clause");
12680                                self.builder.position_at_end(b);
12681
12682                                let exnref_phi = err!(
12683                                    self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12684                                );
12685                                exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12686
12687                                let frame = self.state.frame_at_depth(*label)?;
12688
12689                                let phis = frame.phis();
12690
12691                                assert_eq!(phis.len(), 1);
12692                                phis[0].add_incoming(&[(&exnref_phi.as_basic_value(), b)]);
12693
12694                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12695
12696                                self.builder.position_at_end(catch_end_block);
12697                                catch_blocks.push((b, Some(exnref_phi)));
12698                            }
12699                        }
12700                    }
12701
12702                    for catch_info in &outer_catch_blocks {
12703                        if let Some(phi) = catch_info.exnref_phi {
12704                            phi.add_incoming(&[(&exnref, catch_end_block)]);
12705                        }
12706                    }
12707
12708                    err!(
12709                        self.builder.build_switch(
12710                            selector,
12711                            rethrow_block,
12712                            catch_blocks
12713                                .iter()
12714                                .enumerate()
12715                                .map(|(i, v)| (
12716                                    self.intrinsics
12717                                        .i32_ty
12718                                        .const_int(catch_tag_values[i] as _, false),
12719                                    v.0
12720                                ))
12721                                .chain(outer_catch_blocks.iter().map(|catch_info| (
12722                                    self.intrinsics.i32_ty.const_int(catch_info.tag as _, false),
12723                                    catch_info.catch_block
12724                                )))
12725                                .collect::<Vec<_>>()
12726                                .as_slice()
12727                        )
12728                    );
12729
12730                    // -- end
12731
12732                    // -- The rethrow block
12733                    self.builder.position_at_end(rethrow_block);
12734
12735                    err!(self.builder.build_call(
12736                        self.intrinsics.throw,
12737                        &[self.ctx.basic().into(), exnref.into()],
12738                        "rethrow"
12739                    ));
12740                    // can't reach after an explicit throw!
12741                    err!(self.builder.build_unreachable());
12742
12743                    maybe_lpad_block = Some(lpad_block);
12744                }
12745
12746                // Move back to current block
12747                self.builder.position_at_end(current_block);
12748
12749                // Note: catch_tag_values also containes outer tags, but zipping with
12750                // catch_blocks will let us ignore the extra ones.
12751                let catch_tags_and_blocks = catch_tag_values
12752                    .into_iter()
12753                    .zip(catch_blocks)
12754                    .map(|(tag, (block, exnref_phi))| TagCatchInfo {
12755                        tag,
12756                        catch_block: block,
12757                        exnref_phi,
12758                    })
12759                    .collect::<Vec<_>>();
12760                self.state.push_landingpad(
12761                    maybe_lpad_block,
12762                    end_block,
12763                    end_phis,
12764                    &catch_tags_and_blocks,
12765                    self.module_translation
12766                        .blocktype_params_results(&try_table.ty)?
12767                        .0
12768                        .len(),
12769                );
12770            }
12771            Operator::Throw { tag_index } => {
12772                let current_block = self
12773                    .builder
12774                    .get_insert_block()
12775                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12776
12777                let sig_index = self.wasm_module.tags[TagIndex::from_u32(tag_index)];
12778                let signature = &self.wasm_module.signatures[sig_index];
12779                let params = signature.params();
12780                let values = self.state.popn_save_extra(params.len())?;
12781
12782                values.iter().enumerate().try_for_each(|(i, (v, _))| {
12783                    let t = type_to_llvm(self.intrinsics, params[i])?;
12784                    if t != v.get_type() {
12785                        return Err(CompileError::Codegen(format!(
12786                            "Incompatible types: {:?} != {:?}",
12787                            t,
12788                            v.get_type()
12789                        )));
12790                    }
12791
12792                    Ok(())
12793                })?;
12794
12795                // Allocate the necessary bytes for the exception.
12796                let exnref = err!(
12797                    self.builder.build_direct_call(
12798                        self.intrinsics.alloc_exception,
12799                        &[
12800                            self.ctx.basic().into(),
12801                            self.intrinsics
12802                                .i32_ty
12803                                .const_int(tag_index as _, false)
12804                                .into()
12805                        ],
12806                        "exnref",
12807                    )
12808                );
12809                let exnref = exnref.try_as_basic_value().unwrap_basic();
12810
12811                let exn_payload_ptr = err!(self.builder.build_direct_call(
12812                    self.intrinsics.read_exnref,
12813                    &[self.ctx.basic().into(), exnref.into()],
12814                    "exn_ptr",
12815                ));
12816                let exn_payload_ptr = exn_payload_ptr
12817                    .try_as_basic_value()
12818                    .unwrap_basic()
12819                    .into_pointer_value();
12820
12821                for (i, value) in values.into_iter().enumerate() {
12822                    let ptr = err!(unsafe {
12823                        self.builder.build_gep(
12824                            self.intrinsics.i128_ty,
12825                            exn_payload_ptr,
12826                            &[self.intrinsics.i32_ty.const_int(i as u64, false)],
12827                            format!("value_{i}_ptr").as_str(),
12828                        )
12829                    });
12830                    err!(self.builder.build_store(ptr, value.0));
12831                }
12832
12833                if let Some(pad) = self.state.get_innermost_landingpad() {
12834                    let unreachable_block = self
12835                        .context
12836                        .append_basic_block(self.function, "_throw_unreachable");
12837
12838                    err!(self.builder.build_invoke(
12839                        self.intrinsics.throw,
12840                        &[self.ctx.basic(), exnref],
12841                        unreachable_block,
12842                        pad,
12843                        "throw",
12844                    ));
12845
12846                    self.builder.position_at_end(unreachable_block);
12847                    // can't reach after an explicit throw!
12848                    err!(self.builder.build_unreachable());
12849
12850                    self.builder.position_at_end(current_block);
12851                } else {
12852                    err!(self.builder.build_call(
12853                        self.intrinsics.throw,
12854                        &[self.ctx.basic().into(), exnref.into()],
12855                        "throw"
12856                    ));
12857                    // can't reach after an explicit throw!
12858                    err!(self.builder.build_unreachable());
12859                }
12860
12861                self.state.reachable = false;
12862            }
12863            Operator::ThrowRef => {
12864                let current_block = self
12865                    .builder
12866                    .get_insert_block()
12867                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12868
12869                let exnref = self.state.pop1()?;
12870
12871                if let Some(pad) = self.state.get_innermost_landingpad() {
12872                    let unreachable_block = self
12873                        .context
12874                        .append_basic_block(self.function, "_rethrow_unreachable");
12875
12876                    err!(self.builder.build_invoke(
12877                        self.intrinsics.throw,
12878                        &[self.ctx.basic(), exnref],
12879                        unreachable_block,
12880                        pad,
12881                        "throw",
12882                    ));
12883
12884                    self.builder.position_at_end(unreachable_block);
12885                    // can't reach after an explicit throw!
12886                    err!(self.builder.build_unreachable());
12887
12888                    self.builder.position_at_end(current_block);
12889                } else {
12890                    err!(self.builder.build_call(
12891                        self.intrinsics.throw,
12892                        &[self.ctx.basic().into(), exnref.into()],
12893                        "throw"
12894                    ));
12895                    // can't reach after an explicit throw!
12896                    err!(self.builder.build_unreachable());
12897                }
12898
12899                self.state.reachable = false;
12900            }
12901            _ => {
12902                return Err(CompileError::Codegen(format!(
12903                    "Operator {op:?} unimplemented",
12904                )));
12905            }
12906        }
12907
12908        Ok(())
12909    }
12910}
12911
12912fn is_f32_arithmetic(bits: u32) -> bool {
12913    // Mask off sign bit.
12914    let bits = bits & 0x7FFF_FFFF;
12915    bits < 0x7FC0_0000
12916}
12917
12918fn is_f64_arithmetic(bits: u64) -> bool {
12919    // Mask off sign bit.
12920    let bits = bits & 0x7FFF_FFFF_FFFF_FFFF;
12921    bits < 0x7FF8_0000_0000_0000
12922}
12923
12924// Constants for the bounds of truncation operations. These are the least or
12925// greatest exact floats in either f32 or f64 representation
12926// greater-than-or-equal-to (for least) or less-than-or-equal-to (for greatest)
12927// the i32 or i64 or u32 or u64 min (for least) or max (for greatest), when
12928// rounding towards zero.
12929
12930/// Least Exact Float (32 bits) greater-than-or-equal-to i32::MIN when rounding towards zero.
12931const LEF32_GEQ_I32_MIN: u64 = i32::MIN as u64;
12932/// Greatest Exact Float (32 bits) less-than-or-equal-to i32::MAX when rounding towards zero.
12933const GEF32_LEQ_I32_MAX: u64 = 2147483520; // bits as f32: 0x4eff_ffff
12934/// Least Exact Float (64 bits) greater-than-or-equal-to i32::MIN when rounding towards zero.
12935const LEF64_GEQ_I32_MIN: u64 = i32::MIN as u64;
12936/// Greatest Exact Float (64 bits) less-than-or-equal-to i32::MAX when rounding towards zero.
12937const GEF64_LEQ_I32_MAX: u64 = i32::MAX as u64;
12938/// Least Exact Float (32 bits) greater-than-or-equal-to u32::MIN when rounding towards zero.
12939const LEF32_GEQ_U32_MIN: u64 = u32::MIN as u64;
12940/// Greatest Exact Float (32 bits) less-than-or-equal-to u32::MAX when rounding towards zero.
12941const GEF32_LEQ_U32_MAX: u64 = 4294967040; // bits as f32: 0x4f7f_ffff
12942/// Least Exact Float (64 bits) greater-than-or-equal-to u32::MIN when rounding towards zero.
12943const LEF64_GEQ_U32_MIN: u64 = u32::MIN as u64;
12944/// Greatest Exact Float (64 bits) less-than-or-equal-to u32::MAX when rounding towards zero.
12945const GEF64_LEQ_U32_MAX: u64 = 4294967295; // bits as f64: 0x41ef_ffff_ffff_ffff
12946/// Least Exact Float (32 bits) greater-than-or-equal-to i64::MIN when rounding towards zero.
12947const LEF32_GEQ_I64_MIN: u64 = i64::MIN as u64;
12948/// Greatest Exact Float (32 bits) less-than-or-equal-to i64::MAX when rounding towards zero.
12949const GEF32_LEQ_I64_MAX: u64 = 9223371487098961920; // bits as f32: 0x5eff_ffff
12950/// Least Exact Float (64 bits) greater-than-or-equal-to i64::MIN when rounding towards zero.
12951const LEF64_GEQ_I64_MIN: u64 = i64::MIN as u64;
12952/// Greatest Exact Float (64 bits) less-than-or-equal-to i64::MAX when rounding towards zero.
12953const GEF64_LEQ_I64_MAX: u64 = 9223372036854774784; // bits as f64: 0x43df_ffff_ffff_ffff
12954/// Least Exact Float (32 bits) greater-than-or-equal-to u64::MIN when rounding towards zero.
12955const LEF32_GEQ_U64_MIN: u64 = u64::MIN;
12956/// Greatest Exact Float (32 bits) less-than-or-equal-to u64::MAX when rounding towards zero.
12957const GEF32_LEQ_U64_MAX: u64 = 18446742974197923840; // bits as f32: 0x5f7f_ffff
12958/// Least Exact Float (64 bits) greater-than-or-equal-to u64::MIN when rounding towards zero.
12959const LEF64_GEQ_U64_MIN: u64 = u64::MIN;
12960/// Greatest Exact Float (64 bits) less-than-or-equal-to u64::MAX when rounding towards zero.
12961const GEF64_LEQ_U64_MAX: u64 = 18446744073709549568; // bits as f64: 0x43ef_ffff_ffff_ffff