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        AnyValue, 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;
28
29use crate::{
30    abi::{Abi, G0M0FunctionKind, LocalFunctionG0M0params, get_abi},
31    config::{CompiledKind, 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    types::{
39        relocation::RelocationTarget,
40        symbols::{Symbol, SymbolRegistry},
41    },
42    wasmparser::{Catch, MemArg, Operator},
43    wpheaptype_to_type, wptype_to_type,
44};
45use wasmer_types::{
46    CompileError, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex,
47    ModuleInfo, SignatureIndex, TableIndex, Type,
48};
49use wasmer_types::{TagIndex, entity::PrimaryMap};
50use wasmer_vm::{MemoryStyle, TableStyle, VMOffsets};
51
52const FUNCTION_SECTION_ELF: &str = "__TEXT,wasmer_function";
53const FUNCTION_SECTION_MACHO: &str = "__TEXT";
54const FUNCTION_SEGMENT_MACHO: &str = "wasmer_function";
55
56// Since we want to use module-local tag numbers for landing pads,
57// the catch-all tag can't be zero; we instead use i32::MAX, which
58// is hopefully large enough to not conflict with any real tag.
59// If you have 2 billion tags in a single module, you deserve what you get.
60// ( Arshia: that comment above is AI-generated... AI is savage XD )
61const CATCH_ALL_TAG_VALUE: i32 = i32::MAX;
62
63pub struct FuncTranslator {
64    ctx: Context,
65    target_machine: TargetMachine,
66    abi: Box<dyn Abi>,
67    binary_fmt: BinaryFormat,
68    func_section: String,
69}
70
71impl FuncTranslator {
72    pub fn new(
73        target_machine: TargetMachine,
74        binary_fmt: BinaryFormat,
75    ) -> Result<Self, CompileError> {
76        let abi = get_abi(&target_machine);
77        Ok(Self {
78            ctx: Context::create(),
79            target_machine,
80            abi,
81            func_section: match binary_fmt {
82                BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
83                BinaryFormat::Macho => FUNCTION_SEGMENT_MACHO.to_string(),
84                _ => {
85                    return Err(CompileError::UnsupportedTarget(format!(
86                        "Unsupported binary format: {binary_fmt:?}"
87                    )));
88                }
89            },
90            binary_fmt,
91        })
92    }
93
94    #[allow(clippy::too_many_arguments)]
95    pub fn translate_to_module(
96        &self,
97        wasm_module: &ModuleInfo,
98        module_translation: &ModuleTranslationState,
99        local_func_index: &LocalFunctionIndex,
100        function_body: &FunctionBodyData,
101        config: &LLVM,
102        memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
103        _table_styles: &PrimaryMap<TableIndex, TableStyle>,
104        symbol_registry: &dyn SymbolRegistry,
105    ) -> Result<Module, CompileError> {
106        // The function type, used for the callbacks.
107        let function = CompiledKind::Local(*local_func_index);
108        let func_index = wasm_module.func_index(*local_func_index);
109        let function_name =
110            symbol_registry.symbol_to_name(Symbol::LocalFunction(*local_func_index));
111
112        let g0m0_is_enabled = config.enable_g0m0_opt;
113        let func_kind = if g0m0_is_enabled {
114            Some(G0M0FunctionKind::Local)
115        } else {
116            None
117        };
118
119        let module_name = match wasm_module.name.as_ref() {
120            None => format!("<anonymous module> function {function_name}"),
121            Some(module_name) => format!("module {module_name} function {function_name}"),
122        };
123        let module = self.ctx.create_module(module_name.as_str());
124
125        let target_machine = &self.target_machine;
126        let target_triple = target_machine.get_triple();
127        let target_data = target_machine.get_target_data();
128        module.set_triple(&target_triple);
129        module.set_data_layout(&target_data.get_data_layout());
130        let wasm_fn_type = wasm_module
131            .signatures
132            .get(wasm_module.functions[func_index])
133            .unwrap();
134
135        // TODO: pointer width
136        let offsets = VMOffsets::new(8, wasm_module);
137        let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data, &self.binary_fmt);
138        let (func_type, func_attrs) = self.abi.func_type_to_llvm(
139            &self.ctx,
140            &intrinsics,
141            Some(&offsets),
142            wasm_fn_type,
143            func_kind,
144        )?;
145
146        let func = module.add_function(&function_name, func_type, Some(Linkage::External));
147        for (attr, attr_loc) in &func_attrs {
148            func.add_attribute(*attr_loc, *attr);
149        }
150
151        func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe);
152        func.add_attribute(AttributeLoc::Function, intrinsics.uwtable);
153        func.add_attribute(AttributeLoc::Function, intrinsics.frame_pointer);
154
155        let section = match self.binary_fmt {
156            BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
157            BinaryFormat::Macho => {
158                format!("{FUNCTION_SECTION_MACHO},{FUNCTION_SEGMENT_MACHO}")
159            }
160            _ => {
161                return Err(CompileError::UnsupportedTarget(format!(
162                    "Unsupported binary format: {:?}",
163                    self.binary_fmt
164                )));
165            }
166        };
167
168        func.set_personality_function(intrinsics.personality);
169        func.as_global_value().set_section(Some(&section));
170
171        func.set_linkage(Linkage::DLLExport);
172        func.as_global_value()
173            .set_dll_storage_class(DLLStorageClass::Export);
174
175        let entry = self.ctx.append_basic_block(func, "entry");
176        let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
177        let return_ = self.ctx.append_basic_block(func, "return");
178        let alloca_builder = self.ctx.create_builder();
179        let cache_builder = self.ctx.create_builder();
180        let builder = self.ctx.create_builder();
181        cache_builder.position_at_end(entry);
182        let br = err!(cache_builder.build_unconditional_branch(start_of_code));
183        alloca_builder.position_before(&br);
184        cache_builder.position_before(&br);
185        builder.position_at_end(start_of_code);
186
187        let mut state = State::new();
188        builder.position_at_end(return_);
189        let phis: SmallVec<[PhiValue; 1]> = wasm_fn_type
190            .results()
191            .iter()
192            .map(|&wasm_ty| {
193                type_to_llvm(&intrinsics, wasm_ty).map(|ty| builder.build_phi(ty, "").unwrap())
194            })
195            .collect::<Result<_, _>>()?;
196        state.push_block(return_, phis, 0);
197        builder.position_at_end(start_of_code);
198
199        let mut reader = MiddlewareBinaryReader::new_with_offset(
200            function_body.data,
201            function_body.module_offset,
202        );
203        reader.set_middleware_chain(
204            config
205                .middlewares
206                .generate_function_middleware_chain(*local_func_index),
207        );
208
209        let mut params = vec![];
210        let first_param =
211            if func_type.get_return_type().is_none() && wasm_fn_type.results().len() > 1 {
212                if g0m0_is_enabled { 4 } else { 2 }
213            } else if g0m0_is_enabled {
214                3
215            } else {
216                1
217            };
218        let mut is_first_alloca = true;
219        let mut insert_alloca = |ty, name: String| -> Result<PointerValue, CompileError> {
220            let alloca = err!(alloca_builder.build_alloca(ty, &name));
221            if is_first_alloca {
222                alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
223                is_first_alloca = false;
224            }
225            Ok(alloca)
226        };
227
228        // Uncomment to print, at the start of the function, the function name.
229        // (poor man's debugger!)
230        //let func_name_str =
231        //    err!(alloca_builder.build_global_string_ptr(&function_name, "function_name"));
232        //
233        //_ = alloca_builder.build_call(
234        //    intrinsics.debug_str,
235        //    &[
236        //        func_name_str.as_pointer_value().into(),
237        //        intrinsics
238        //            .i32_ty
239        //            .const_int(function_name.len() as _, false)
240        //            .into(),
241        //    ],
242        //    "",
243        //);
244
245        for idx in 0..wasm_fn_type.params().len() {
246            let ty = wasm_fn_type.params()[idx];
247            let ty = type_to_llvm(&intrinsics, ty)?;
248            let value = func
249                .get_nth_param((idx as u32).checked_add(first_param).unwrap())
250                .unwrap();
251            let alloca = insert_alloca(ty, format!("param_{idx}"))?;
252            err!(cache_builder.build_store(alloca, value));
253            params.push((ty, alloca));
254        }
255
256        let mut locals = vec![];
257        let num_locals = reader.read_local_count()?;
258        for idx in 0..num_locals {
259            let (count, ty) = reader.read_local_decl()?;
260            let ty = err!(wptype_to_type(ty));
261            let ty = type_to_llvm(&intrinsics, ty)?;
262            for _ in 0..count {
263                let alloca = insert_alloca(ty, format!("local_{idx}"))?;
264                err!(cache_builder.build_store(alloca, ty.const_zero()));
265                locals.push((ty, alloca));
266            }
267        }
268
269        let mut params_locals = params.clone();
270        params_locals.extend(locals.iter().cloned());
271
272        let mut g0m0_params = None;
273
274        if g0m0_is_enabled {
275            let value = self.abi.get_g0_ptr_param(&func);
276            let g0 = insert_alloca(intrinsics.i32_ty.as_basic_type_enum(), "g0".to_string())?;
277            err!(cache_builder.build_store(g0, value));
278            g0.set_name("g0");
279            let m0 = self.abi.get_m0_ptr_param(&func);
280            m0.set_name("m0_base_ptr");
281
282            g0m0_params = Some((g0, m0));
283        }
284
285        let mut fcg = LLVMFunctionCodeGenerator {
286            g0m0: g0m0_params,
287            context: &self.ctx,
288            builder,
289            alloca_builder,
290            intrinsics: &intrinsics,
291            state,
292            function: func,
293            locals: params_locals,
294            ctx: CtxType::new(wasm_module, &func, &cache_builder, &*self.abi, config),
295            unreachable_depth: 0,
296            memory_styles,
297            _table_styles,
298            module: &module,
299            module_translation,
300            wasm_module,
301            symbol_registry,
302            abi: &*self.abi,
303            config,
304            exception_types_cache: HashMap::new(),
305            vmctx_alloca: None,
306            tags_cache: HashMap::new(),
307            binary_fmt: self.binary_fmt,
308        };
309
310        fcg.ctx.add_func(
311            func_index,
312            func.as_global_value().as_pointer_value(),
313            func_type,
314            fcg.ctx.basic(),
315            &func_attrs,
316        );
317
318        while fcg.state.has_control_frames() {
319            let pos = reader.current_position() as u32;
320            let op = reader.read_operator()?;
321            fcg.translate_operator(op, pos)?;
322        }
323
324        fcg.finalize(wasm_fn_type)?;
325
326        if let Some(ref callbacks) = config.callbacks {
327            callbacks.preopt_ir(&function, &module);
328        }
329
330        let mut passes = vec![];
331
332        if config.enable_verifier {
333            passes.push("verify");
334        }
335
336        passes.push("sccp");
337        passes.push("early-cse");
338        //passes.push("deadargelim");
339        passes.push("adce");
340        passes.push("sroa");
341        passes.push("aggressive-instcombine");
342        passes.push("jump-threading");
343        //passes.push("ipsccp");
344        passes.push("simplifycfg");
345        passes.push("reassociate");
346        passes.push("loop-rotate");
347        passes.push("indvars");
348        //passes.push("lcssa");
349        //passes.push("licm");
350        //passes.push("instcombine");
351        passes.push("sccp");
352        passes.push("reassociate");
353        passes.push("simplifycfg");
354        passes.push("gvn");
355        passes.push("memcpyopt");
356        passes.push("dse");
357        passes.push("dce");
358        //passes.push("instcombine");
359        passes.push("reassociate");
360        passes.push("simplifycfg");
361        passes.push("mem2reg");
362
363        //let llvm_dump_path = std::env::var("WASMER_LLVM_DUMP_DIR");
364        //if let Ok(ref llvm_dump_path) = llvm_dump_path {
365        //    let path = std::path::Path::new(llvm_dump_path);
366        //    if !path.exists() {
367        //        std::fs::create_dir_all(path).unwrap()
368        //    }
369        //    let path = path.join(format!("{function_name}.ll"));
370        //    _ = module.print_to_file(path).unwrap();
371        //}
372
373        module
374            .run_passes(
375                passes.join(",").as_str(),
376                target_machine,
377                PassBuilderOptions::create(),
378            )
379            .unwrap();
380
381        //if let Ok(ref llvm_dump_path) = llvm_dump_path {
382        //    if !passes.is_empty() {
383        //        let path =
384        //            std::path::Path::new(llvm_dump_path).join(format!("{function_name}_opt.ll"));
385        //        _ = module.print_to_file(path).unwrap();
386        //    }
387        //}
388
389        if let Some(ref callbacks) = config.callbacks {
390            callbacks.postopt_ir(&function, &module);
391        }
392
393        Ok(module)
394    }
395
396    #[allow(clippy::too_many_arguments)]
397    pub fn translate(
398        &self,
399        wasm_module: &ModuleInfo,
400        module_translation: &ModuleTranslationState,
401        local_func_index: &LocalFunctionIndex,
402        function_body: &FunctionBodyData,
403        config: &LLVM,
404        memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
405        table_styles: &PrimaryMap<TableIndex, TableStyle>,
406        symbol_registry: &dyn SymbolRegistry,
407    ) -> Result<CompiledFunction, CompileError> {
408        let module = self.translate_to_module(
409            wasm_module,
410            module_translation,
411            local_func_index,
412            function_body,
413            config,
414            memory_styles,
415            table_styles,
416            symbol_registry,
417        )?;
418        let function = CompiledKind::Local(*local_func_index);
419        let target_machine = &self.target_machine;
420        let memory_buffer = target_machine
421            .write_to_memory_buffer(&module, FileType::Object)
422            .unwrap();
423
424        if let Some(ref callbacks) = config.callbacks {
425            callbacks.obj_memory_buffer(&function, &memory_buffer);
426            let asm_buffer = target_machine
427                .write_to_memory_buffer(&module, FileType::Assembly)
428                .unwrap();
429            callbacks.asm_memory_buffer(&function, &asm_buffer)
430        }
431
432        let mem_buf_slice = memory_buffer.as_slice();
433
434        load_object_file(
435            mem_buf_slice,
436            &self.func_section,
437            RelocationTarget::LocalFunc(*local_func_index),
438            |name: &str| {
439                Ok({
440                    let name = if matches!(self.binary_fmt, BinaryFormat::Macho) {
441                        if name.starts_with("_") {
442                            name.replacen("_", "", 1)
443                        } else {
444                            name.to_string()
445                        }
446                    } else {
447                        name.to_string()
448                    };
449                    if let Some(Symbol::LocalFunction(local_func_index)) =
450                        symbol_registry.name_to_symbol(&name)
451                    {
452                        Some(RelocationTarget::LocalFunc(local_func_index))
453                    } else {
454                        None
455                    }
456                })
457            },
458            self.binary_fmt,
459        )
460    }
461}
462
463impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
464    // Create a vector where each lane contains the same value.
465    fn splat_vector(
466        &self,
467        value: BasicValueEnum<'ctx>,
468        vec_ty: VectorType<'ctx>,
469    ) -> Result<VectorValue<'ctx>, CompileError> {
470        // Use insert_element to insert the element into an undef vector, then use
471        // shuffle vector to copy that lane to all lanes.
472        err_nt!(
473            self.builder.build_shuffle_vector(
474                err!(self.builder.build_insert_element(
475                    vec_ty.get_undef(),
476                    value,
477                    self.intrinsics.i32_zero,
478                    "",
479                )),
480                vec_ty.get_undef(),
481                self.intrinsics
482                    .i32_ty
483                    .vec_type(vec_ty.get_size())
484                    .const_zero(),
485                "",
486            )
487        )
488    }
489
490    // Convert floating point vector to integer and saturate when out of range.
491    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
492    #[allow(clippy::too_many_arguments)]
493    fn trunc_sat<T: FloatMathType<'ctx>>(
494        &self,
495        fvec_ty: T,
496        ivec_ty: T::MathConvType,
497        lower_bound: u64, // Exclusive (least representable value)
498        upper_bound: u64, // Exclusive (greatest representable value)
499        int_min_value: u64,
500        int_max_value: u64,
501        value: IntValue<'ctx>,
502    ) -> Result<VectorValue<'ctx>, CompileError> {
503        // a) Compare vector with itself to identify NaN lanes.
504        // b) Compare vector with splat of inttofp(upper_bound) to identify
505        //    lanes that need to saturate to max.
506        // c) Compare vector with splat of inttofp(lower_bound) to identify
507        //    lanes that need to saturate to min.
508        // d) Use vector select (not shuffle) to pick from either the
509        //    splat vector or the input vector depending on whether the
510        //    comparison indicates that we have an unrepresentable value. Replace
511        //    unrepresentable values with zero.
512        // e) Now that the value is safe, fpto[su]i it.
513        // f) Use our previous comparison results to replace certain zeros with
514        //    int_min or int_max.
515
516        let fvec_ty = fvec_ty.as_basic_type_enum().into_vector_type();
517        let ivec_ty = ivec_ty.as_basic_type_enum().into_vector_type();
518        let fvec_element_ty = fvec_ty.get_element_type().into_float_type();
519        let ivec_element_ty = ivec_ty.get_element_type().into_int_type();
520
521        let is_signed = int_min_value != 0;
522        let int_min_value = self.splat_vector(
523            ivec_element_ty
524                .const_int(int_min_value, is_signed)
525                .as_basic_value_enum(),
526            ivec_ty,
527        )?;
528        let int_max_value = self.splat_vector(
529            ivec_element_ty
530                .const_int(int_max_value, is_signed)
531                .as_basic_value_enum(),
532            ivec_ty,
533        )?;
534        let lower_bound = if is_signed {
535            err!(self.builder.build_signed_int_to_float(
536                ivec_element_ty.const_int(lower_bound, is_signed),
537                fvec_element_ty,
538                "",
539            ))
540        } else {
541            err!(self.builder.build_unsigned_int_to_float(
542                ivec_element_ty.const_int(lower_bound, is_signed),
543                fvec_element_ty,
544                "",
545            ))
546        };
547        let upper_bound = if is_signed {
548            err!(self.builder.build_signed_int_to_float(
549                ivec_element_ty.const_int(upper_bound, is_signed),
550                fvec_element_ty,
551                "",
552            ))
553        } else {
554            err!(self.builder.build_unsigned_int_to_float(
555                ivec_element_ty.const_int(upper_bound, is_signed),
556                fvec_element_ty,
557                "",
558            ))
559        };
560
561        let value = err!(self.builder.build_bit_cast(value, fvec_ty, "")).into_vector_value();
562        let zero = fvec_ty.const_zero();
563        let lower_bound = self.splat_vector(lower_bound.as_basic_value_enum(), fvec_ty)?;
564        let upper_bound = self.splat_vector(upper_bound.as_basic_value_enum(), fvec_ty)?;
565        let nan_cmp =
566            err!(
567                self.builder
568                    .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
569            );
570        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
571            FloatPredicate::OGT,
572            value,
573            upper_bound,
574            "above_upper_bound",
575        ));
576        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
577            FloatPredicate::OLT,
578            value,
579            lower_bound,
580            "below_lower_bound",
581        ));
582        let not_representable = err!(self.builder.build_or(
583            err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
584            below_lower_bound_cmp,
585            "not_representable_as_int",
586        ));
587        let value =
588            err!(
589                self.builder
590                    .build_select(not_representable, zero, value, "safe_to_convert")
591            )
592            .into_vector_value();
593        let value = if is_signed {
594            self.builder
595                .build_float_to_signed_int(value, ivec_ty, "as_int")
596        } else {
597            self.builder
598                .build_float_to_unsigned_int(value, ivec_ty, "as_int")
599        };
600
601        let value = err!(value);
602        let value =
603            err!(
604                self.builder
605                    .build_select(above_upper_bound_cmp, int_max_value, value, "")
606            )
607            .into_vector_value();
608        err_nt!(
609            self.builder
610                .build_select(below_lower_bound_cmp, int_min_value, value, "")
611                .map(|v| v.into_vector_value())
612        )
613    }
614
615    // Convert floating point vector to integer and saturate when out of range.
616    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
617    #[allow(clippy::too_many_arguments)]
618    fn trunc_sat_into_int<T: FloatMathType<'ctx>>(
619        &self,
620        fvec_ty: T,
621        ivec_ty: T::MathConvType,
622        lower_bound: u64, // Exclusive (least representable value)
623        upper_bound: u64, // Exclusive (greatest representable value)
624        int_min_value: u64,
625        int_max_value: u64,
626        value: IntValue<'ctx>,
627    ) -> Result<IntValue<'ctx>, CompileError> {
628        let res = self.trunc_sat(
629            fvec_ty,
630            ivec_ty,
631            lower_bound,
632            upper_bound,
633            int_min_value,
634            int_max_value,
635            value,
636        )?;
637        err_nt!(
638            self.builder
639                .build_bit_cast(res, self.intrinsics.i128_ty, "")
640                .map(|v| v.into_int_value())
641        )
642    }
643
644    // Convert floating point vector to integer and saturate when out of range.
645    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
646    fn trunc_sat_scalar(
647        &self,
648        int_ty: IntType<'ctx>,
649        lower_bound: u64, // Exclusive (least representable value)
650        upper_bound: u64, // Exclusive (greatest representable value)
651        int_min_value: u64,
652        int_max_value: u64,
653        value: FloatValue<'ctx>,
654    ) -> Result<IntValue<'ctx>, CompileError> {
655        // TODO: this is a scalarized version of the process in trunc_sat. Either
656        // we should merge with trunc_sat, or we should simplify this function.
657
658        // a) Compare value with itself to identify NaN.
659        // b) Compare value inttofp(upper_bound) to identify values that need to
660        //    saturate to max.
661        // c) Compare value with inttofp(lower_bound) to identify values that need
662        //    to saturate to min.
663        // d) Use select to pick from either zero or the input vector depending on
664        //    whether the comparison indicates that we have an unrepresentable
665        //    value.
666        // e) Now that the value is safe, fpto[su]i it.
667        // f) Use our previous comparison results to replace certain zeros with
668        //    int_min or int_max.
669
670        let is_signed = int_min_value != 0;
671        let int_min_value = int_ty.const_int(int_min_value, is_signed);
672        let int_max_value = int_ty.const_int(int_max_value, is_signed);
673
674        let lower_bound = if is_signed {
675            err!(self.builder.build_signed_int_to_float(
676                int_ty.const_int(lower_bound, is_signed),
677                value.get_type(),
678                "",
679            ))
680        } else {
681            err!(self.builder.build_unsigned_int_to_float(
682                int_ty.const_int(lower_bound, is_signed),
683                value.get_type(),
684                "",
685            ))
686        };
687        let upper_bound = if is_signed {
688            err!(self.builder.build_signed_int_to_float(
689                int_ty.const_int(upper_bound, is_signed),
690                value.get_type(),
691                "",
692            ))
693        } else {
694            err!(self.builder.build_unsigned_int_to_float(
695                int_ty.const_int(upper_bound, is_signed),
696                value.get_type(),
697                "",
698            ))
699        };
700
701        let zero = value.get_type().const_zero();
702
703        let nan_cmp =
704            err!(
705                self.builder
706                    .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
707            );
708        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
709            FloatPredicate::OGT,
710            value,
711            upper_bound,
712            "above_upper_bound",
713        ));
714        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
715            FloatPredicate::OLT,
716            value,
717            lower_bound,
718            "below_lower_bound",
719        ));
720        let not_representable = err!(self.builder.build_or(
721            err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
722            below_lower_bound_cmp,
723            "not_representable_as_int",
724        ));
725        let value =
726            err!(
727                self.builder
728                    .build_select(not_representable, zero, value, "safe_to_convert")
729            )
730            .into_float_value();
731        let value = if is_signed {
732            err!(
733                self.builder
734                    .build_float_to_signed_int(value, int_ty, "as_int")
735            )
736        } else {
737            err!(
738                self.builder
739                    .build_float_to_unsigned_int(value, int_ty, "as_int")
740            )
741        };
742        let value =
743            err!(
744                self.builder
745                    .build_select(above_upper_bound_cmp, int_max_value, value, "")
746            )
747            .into_int_value();
748        let value =
749            err!(
750                self.builder
751                    .build_select(below_lower_bound_cmp, int_min_value, value, "")
752            )
753            .into_int_value();
754
755        err_nt!(
756            self.builder
757                .build_bit_cast(value, int_ty, "")
758                .map(|v| v.into_int_value())
759        )
760    }
761
762    fn trap_if_not_representable_as_int(
763        &self,
764        lower_bound: u64, // Inclusive (not a trapping value)
765        upper_bound: u64, // Inclusive (not a trapping value)
766        value: FloatValue,
767    ) -> Result<(), CompileError> {
768        let float_ty = value.get_type();
769        let int_ty = if float_ty == self.intrinsics.f32_ty {
770            self.intrinsics.i32_ty
771        } else {
772            self.intrinsics.i64_ty
773        };
774
775        let lower_bound = err!(self.builder.build_bit_cast(
776            int_ty.const_int(lower_bound, false),
777            float_ty,
778            ""
779        ))
780        .into_float_value();
781        let upper_bound = err!(self.builder.build_bit_cast(
782            int_ty.const_int(upper_bound, false),
783            float_ty,
784            ""
785        ))
786        .into_float_value();
787
788        // The 'U' in the float predicate is short for "unordered" which means that
789        // the comparison will compare true if either operand is a NaN. Thus, NaNs
790        // are out of bounds.
791        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
792            FloatPredicate::UGT,
793            value,
794            upper_bound,
795            "above_upper_bound",
796        ));
797        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
798            FloatPredicate::ULT,
799            value,
800            lower_bound,
801            "below_lower_bound",
802        ));
803        let out_of_bounds = err!(self.builder.build_or(
804            above_upper_bound_cmp,
805            below_lower_bound_cmp,
806            "out_of_bounds",
807        ));
808
809        let failure_block = self
810            .context
811            .append_basic_block(self.function, "conversion_failure_block");
812        let continue_block = self
813            .context
814            .append_basic_block(self.function, "conversion_success_block");
815
816        err!(
817            self.builder
818                .build_conditional_branch(out_of_bounds, failure_block, continue_block)
819        );
820        self.builder.position_at_end(failure_block);
821        let is_nan =
822            err!(
823                self.builder
824                    .build_float_compare(FloatPredicate::UNO, value, value, "is_nan")
825            );
826        let trap_code = err!(self.builder.build_select(
827            is_nan,
828            self.intrinsics.trap_bad_conversion_to_integer,
829            self.intrinsics.trap_illegal_arithmetic,
830            "",
831        ));
832        err!(
833            self.builder
834                .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
835        );
836        err!(self.builder.build_unreachable());
837        self.builder.position_at_end(continue_block);
838
839        Ok(())
840    }
841
842    fn trap_if_zero_or_overflow(
843        &self,
844        left: IntValue,
845        right: IntValue,
846    ) -> Result<(), CompileError> {
847        let int_type = left.get_type();
848
849        let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
850            let min_value = int_type.const_int(i32::MIN as u64, false);
851            let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
852            (min_value, neg_one_value)
853        } else if int_type == self.intrinsics.i64_ty {
854            let min_value = int_type.const_int(i64::MIN as u64, false);
855            let neg_one_value = int_type.const_int(-1i64 as u64, false);
856            (min_value, neg_one_value)
857        } else {
858            unreachable!()
859        };
860
861        let divisor_is_zero = err!(self.builder.build_int_compare(
862            IntPredicate::EQ,
863            right,
864            int_type.const_zero(),
865            "divisor_is_zero",
866        ));
867        let should_trap = err!(self.builder.build_or(
868            divisor_is_zero,
869            err!(self.builder.build_and(
870                err!(self.builder.build_int_compare(
871                    IntPredicate::EQ,
872                    left,
873                    min_value,
874                    "left_is_min"
875                )),
876                err!(self.builder.build_int_compare(
877                    IntPredicate::EQ,
878                    right,
879                    neg_one_value,
880                    "right_is_neg_one",
881                )),
882                "div_will_overflow",
883            )),
884            "div_should_trap",
885        ));
886
887        let should_trap = err!(self.builder.build_call(
888            self.intrinsics.expect_i1,
889            &[
890                should_trap.into(),
891                self.intrinsics.i1_ty.const_zero().into(),
892            ],
893            "should_trap_expect",
894        ))
895        .try_as_basic_value()
896        .left()
897        .unwrap()
898        .into_int_value();
899
900        let shouldnt_trap_block = self
901            .context
902            .append_basic_block(self.function, "shouldnt_trap_block");
903        let should_trap_block = self
904            .context
905            .append_basic_block(self.function, "should_trap_block");
906        err!(self.builder.build_conditional_branch(
907            should_trap,
908            should_trap_block,
909            shouldnt_trap_block
910        ));
911        self.builder.position_at_end(should_trap_block);
912        let trap_code = err!(self.builder.build_select(
913            divisor_is_zero,
914            self.intrinsics.trap_integer_division_by_zero,
915            self.intrinsics.trap_illegal_arithmetic,
916            "",
917        ));
918        err!(
919            self.builder
920                .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
921        );
922        err!(self.builder.build_unreachable());
923        self.builder.position_at_end(shouldnt_trap_block);
924
925        Ok(())
926    }
927
928    fn trap_if_zero(&self, value: IntValue) -> Result<(), CompileError> {
929        let int_type = value.get_type();
930        let should_trap = err!(self.builder.build_int_compare(
931            IntPredicate::EQ,
932            value,
933            int_type.const_zero(),
934            "divisor_is_zero",
935        ));
936
937        let should_trap = err!(self.builder.build_call(
938            self.intrinsics.expect_i1,
939            &[
940                should_trap.into(),
941                self.intrinsics.i1_ty.const_zero().into(),
942            ],
943            "should_trap_expect",
944        ))
945        .try_as_basic_value()
946        .left()
947        .unwrap()
948        .into_int_value();
949
950        let shouldnt_trap_block = self
951            .context
952            .append_basic_block(self.function, "shouldnt_trap_block");
953        let should_trap_block = self
954            .context
955            .append_basic_block(self.function, "should_trap_block");
956        err!(self.builder.build_conditional_branch(
957            should_trap,
958            should_trap_block,
959            shouldnt_trap_block
960        ));
961        self.builder.position_at_end(should_trap_block);
962        err!(self.builder.build_call(
963            self.intrinsics.throw_trap,
964            &[self.intrinsics.trap_integer_division_by_zero.into()],
965            "throw",
966        ));
967        err!(self.builder.build_unreachable());
968        self.builder.position_at_end(shouldnt_trap_block);
969
970        Ok(())
971    }
972
973    fn v128_into_int_vec(
974        &self,
975        value: BasicValueEnum<'ctx>,
976        info: ExtraInfo,
977        int_vec_ty: VectorType<'ctx>,
978    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
979        let (value, info) = if info.has_pending_f32_nan() {
980            let value = err!(
981                self.builder
982                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
983            );
984            (self.canonicalize_nans(value)?, info.strip_pending())
985        } else if info.has_pending_f64_nan() {
986            let value = err!(
987                self.builder
988                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
989            );
990            (self.canonicalize_nans(value)?, info.strip_pending())
991        } else {
992            (value, info)
993        };
994        Ok((
995            err!(self.builder.build_bit_cast(value, int_vec_ty, "")).into_vector_value(),
996            info,
997        ))
998    }
999
1000    fn v128_into_i8x16(
1001        &self,
1002        value: BasicValueEnum<'ctx>,
1003        info: ExtraInfo,
1004    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1005        self.v128_into_int_vec(value, info, self.intrinsics.i8x16_ty)
1006    }
1007
1008    fn v128_into_i16x8(
1009        &self,
1010        value: BasicValueEnum<'ctx>,
1011        info: ExtraInfo,
1012    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1013        self.v128_into_int_vec(value, info, self.intrinsics.i16x8_ty)
1014    }
1015
1016    fn v128_into_i32x4(
1017        &self,
1018        value: BasicValueEnum<'ctx>,
1019        info: ExtraInfo,
1020    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1021        self.v128_into_int_vec(value, info, self.intrinsics.i32x4_ty)
1022    }
1023
1024    fn v128_into_i64x2(
1025        &self,
1026        value: BasicValueEnum<'ctx>,
1027        info: ExtraInfo,
1028    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1029        self.v128_into_int_vec(value, info, self.intrinsics.i64x2_ty)
1030    }
1031
1032    // If the value is pending a 64-bit canonicalization, do it now.
1033    // Return a f32x4 vector.
1034    fn v128_into_f32x4(
1035        &self,
1036        value: BasicValueEnum<'ctx>,
1037        info: ExtraInfo,
1038    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1039        let (value, info) = if info.has_pending_f64_nan() {
1040            let value = err!(
1041                self.builder
1042                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1043            );
1044            (self.canonicalize_nans(value)?, info.strip_pending())
1045        } else {
1046            (value, info)
1047        };
1048        Ok((
1049            err!(
1050                self.builder
1051                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1052            )
1053            .into_vector_value(),
1054            info,
1055        ))
1056    }
1057
1058    // If the value is pending a 32-bit canonicalization, do it now.
1059    // Return a f64x2 vector.
1060    fn v128_into_f64x2(
1061        &self,
1062        value: BasicValueEnum<'ctx>,
1063        info: ExtraInfo,
1064    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1065        let (value, info) = if info.has_pending_f32_nan() {
1066            let value = err!(
1067                self.builder
1068                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1069            );
1070            (self.canonicalize_nans(value)?, info.strip_pending())
1071        } else {
1072            (value, info)
1073        };
1074        Ok((
1075            err!(
1076                self.builder
1077                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1078            )
1079            .into_vector_value(),
1080            info,
1081        ))
1082    }
1083
1084    fn apply_pending_canonicalization(
1085        &self,
1086        value: BasicValueEnum<'ctx>,
1087        info: ExtraInfo,
1088    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1089        if !self.config.enable_nan_canonicalization {
1090            return Ok(value);
1091        }
1092
1093        if info.has_pending_f32_nan() {
1094            if value.get_type().is_vector_type()
1095                || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1096            {
1097                let ty = value.get_type();
1098                let value = err!(
1099                    self.builder
1100                        .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1101                );
1102                let value = self.canonicalize_nans(value)?;
1103                err_nt!(self.builder.build_bit_cast(value, ty, ""))
1104            } else {
1105                self.canonicalize_nans(value)
1106            }
1107        } else if info.has_pending_f64_nan() {
1108            if value.get_type().is_vector_type()
1109                || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1110            {
1111                let ty = value.get_type();
1112                let value = err!(
1113                    self.builder
1114                        .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1115                );
1116                let value = self.canonicalize_nans(value)?;
1117                err_nt!(self.builder.build_bit_cast(value, ty, ""))
1118            } else {
1119                self.canonicalize_nans(value)
1120            }
1121        } else {
1122            Ok(value)
1123        }
1124    }
1125
1126    // Replaces any NaN with the canonical QNaN, otherwise leaves the value alone.
1127    fn canonicalize_nans(
1128        &self,
1129        value: BasicValueEnum<'ctx>,
1130    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1131        if !self.config.enable_nan_canonicalization {
1132            return Ok(value);
1133        }
1134
1135        let f_ty = value.get_type();
1136        if f_ty.is_vector_type() {
1137            let value = value.into_vector_value();
1138            let f_ty = f_ty.into_vector_type();
1139            let zero = f_ty.const_zero();
1140            let nan_cmp =
1141                err!(
1142                    self.builder
1143                        .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1144                );
1145            let canonical_qnan = f_ty
1146                .get_element_type()
1147                .into_float_type()
1148                .const_float(f64::NAN);
1149            let canonical_qnan = self.splat_vector(canonical_qnan.as_basic_value_enum(), f_ty)?;
1150            err_nt!(
1151                self.builder
1152                    .build_select(nan_cmp, canonical_qnan, value, "")
1153                    .map(|v| v.as_basic_value_enum())
1154            )
1155        } else {
1156            let value = value.into_float_value();
1157            let f_ty = f_ty.into_float_type();
1158            let zero = f_ty.const_zero();
1159            let nan_cmp =
1160                err!(
1161                    self.builder
1162                        .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1163                );
1164            let canonical_qnan = f_ty.const_float(f64::NAN);
1165            err_nt!(
1166                self.builder
1167                    .build_select(nan_cmp, canonical_qnan, value, "")
1168                    .map(|v| v.as_basic_value_enum())
1169            )
1170        }
1171    }
1172
1173    fn quiet_nan(&self, value: BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, CompileError> {
1174        let intrinsic = if value
1175            .get_type()
1176            .eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1177        {
1178            Some(self.intrinsics.add_f32)
1179        } else if value
1180            .get_type()
1181            .eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1182        {
1183            Some(self.intrinsics.add_f64)
1184        } else if value
1185            .get_type()
1186            .eq(&self.intrinsics.f32x4_ty.as_basic_type_enum())
1187        {
1188            Some(self.intrinsics.add_f32x4)
1189        } else if value
1190            .get_type()
1191            .eq(&self.intrinsics.f64x2_ty.as_basic_type_enum())
1192        {
1193            Some(self.intrinsics.add_f64x2)
1194        } else {
1195            None
1196        };
1197
1198        match intrinsic {
1199            Some(intrinsic) => err_nt!(
1200                self.builder
1201                    .build_call(
1202                        intrinsic,
1203                        &[
1204                            value.into(),
1205                            value.get_type().const_zero().into(),
1206                            self.intrinsics.fp_rounding_md,
1207                            self.intrinsics.fp_exception_md,
1208                        ],
1209                        "",
1210                    )
1211                    .map(|v| v.try_as_basic_value().left().unwrap())
1212            ),
1213            None => Ok(value),
1214        }
1215    }
1216
1217    // If this memory access must trap when out of bounds (i.e. it is a memory
1218    // access written in the user program as opposed to one used by our VM)
1219    // then mark that it can't be delete.
1220    fn mark_memaccess_nodelete(
1221        &mut self,
1222        memory_index: MemoryIndex,
1223        memaccess: InstructionValue<'ctx>,
1224    ) -> Result<(), CompileError> {
1225        if let MemoryCache::Static { base_ptr: _ } = self.ctx.memory(
1226            memory_index,
1227            self.intrinsics,
1228            self.module,
1229            self.memory_styles,
1230        )? {
1231            // The best we've got is `volatile`.
1232            // TODO: convert unwrap fail to CompileError
1233            memaccess.set_volatile(true).unwrap();
1234        }
1235        Ok(())
1236    }
1237
1238    fn annotate_user_memaccess(
1239        &mut self,
1240        memory_index: MemoryIndex,
1241        _memarg: &MemArg,
1242        alignment: u32,
1243        memaccess: InstructionValue<'ctx>,
1244    ) -> Result<(), CompileError> {
1245        match memaccess.get_opcode() {
1246            InstructionOpcode::Load | InstructionOpcode::Store => {
1247                memaccess.set_alignment(alignment).unwrap();
1248            }
1249            _ => {}
1250        };
1251        self.mark_memaccess_nodelete(memory_index, memaccess)?;
1252        tbaa_label(
1253            self.module,
1254            self.intrinsics,
1255            format!("memory {}", memory_index.as_u32()),
1256            memaccess,
1257        );
1258        Ok(())
1259    }
1260
1261    fn resolve_memory_ptr(
1262        &mut self,
1263        memory_index: MemoryIndex,
1264        memarg: &MemArg,
1265        ptr_ty: PointerType<'ctx>,
1266        var_offset: IntValue<'ctx>,
1267        value_size: usize,
1268    ) -> Result<PointerValue<'ctx>, CompileError> {
1269        let builder = &self.builder;
1270        let intrinsics = &self.intrinsics;
1271        let context = &self.context;
1272        let function = &self.function;
1273
1274        // Compute the offset into the storage.
1275        let imm_offset = intrinsics.i64_ty.const_int(memarg.offset, false);
1276        let var_offset = err!(builder.build_int_z_extend(var_offset, intrinsics.i64_ty, ""));
1277        let offset = err!(builder.build_int_add(var_offset, imm_offset, ""));
1278
1279        // Look up the memory base (as pointer) and bounds (as unsigned integer).
1280        let base_ptr = if let Some((_, ref m0)) = self.g0m0 {
1281            *m0
1282        } else {
1283            match self
1284                .ctx
1285                .memory(memory_index, intrinsics, self.module, self.memory_styles)?
1286            {
1287                MemoryCache::Dynamic {
1288                    ptr_to_base_ptr,
1289                    ptr_to_current_length,
1290                } => {
1291                    // Bounds check it.
1292                    let minimum = self.wasm_module.memories[memory_index].minimum;
1293                    let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
1294                    let ptr_in_bounds = if offset.is_const() {
1295                        // When the offset is constant, if it's below the minimum
1296                        // memory size, we've statically shown that it's safe.
1297                        let load_offset_end = offset.const_add(value_size_v);
1298                        let ptr_in_bounds = load_offset_end.const_int_compare(
1299                            IntPredicate::ULE,
1300                            intrinsics.i64_ty.const_int(minimum.bytes().0 as u64, false),
1301                        );
1302                        if ptr_in_bounds.get_zero_extended_constant() == Some(1) {
1303                            Some(ptr_in_bounds)
1304                        } else {
1305                            None
1306                        }
1307                    } else {
1308                        None
1309                    };
1310
1311                    let ptr_in_bounds = match ptr_in_bounds {
1312                        Some(ptr) => ptr,
1313                        None => {
1314                            let load_offset_end = err!(builder.build_int_add(
1315                                offset,
1316                                value_size_v,
1317                                "load_offset_end"
1318                            ));
1319
1320                            let current_length = err!(builder.build_load(
1321                                self.intrinsics.i32_ty,
1322                                ptr_to_current_length,
1323                                "current_length"
1324                            ))
1325                            .into_int_value();
1326                            tbaa_label(
1327                                self.module,
1328                                self.intrinsics,
1329                                format!("memory {} length", memory_index.as_u32()),
1330                                current_length.as_instruction_value().unwrap(),
1331                            );
1332                            let current_length = err!(builder.build_int_z_extend(
1333                                current_length,
1334                                intrinsics.i64_ty,
1335                                "current_length_zextd"
1336                            ));
1337
1338                            err!(builder.build_int_compare(
1339                                IntPredicate::ULE,
1340                                load_offset_end,
1341                                current_length,
1342                                "ptr_in_bounds",
1343                            ))
1344                        }
1345                    };
1346
1347                    if !ptr_in_bounds.is_constant_int()
1348                        || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
1349                    {
1350                        // LLVM may have folded this into 'i1 true' in which case we know
1351                        // the pointer is in bounds. LLVM may also have folded it into a
1352                        // constant expression, not known to be either true or false yet.
1353                        // If it's false, unknown-but-constant, or not-a-constant, emit a
1354                        // runtime bounds check. LLVM may yet succeed at optimizing it away.
1355                        let ptr_in_bounds = err!(builder.build_call(
1356                            intrinsics.expect_i1,
1357                            &[
1358                                ptr_in_bounds.into(),
1359                                intrinsics.i1_ty.const_int(1, true).into(),
1360                            ],
1361                            "ptr_in_bounds_expect",
1362                        ))
1363                        .try_as_basic_value()
1364                        .left()
1365                        .unwrap()
1366                        .into_int_value();
1367
1368                        let in_bounds_continue_block =
1369                            context.append_basic_block(*function, "in_bounds_continue_block");
1370                        let not_in_bounds_block =
1371                            context.append_basic_block(*function, "not_in_bounds_block");
1372                        err!(builder.build_conditional_branch(
1373                            ptr_in_bounds,
1374                            in_bounds_continue_block,
1375                            not_in_bounds_block,
1376                        ));
1377                        builder.position_at_end(not_in_bounds_block);
1378                        err!(builder.build_call(
1379                            intrinsics.throw_trap,
1380                            &[intrinsics.trap_memory_oob.into()],
1381                            "throw",
1382                        ));
1383                        err!(builder.build_unreachable());
1384                        builder.position_at_end(in_bounds_continue_block);
1385                    }
1386                    let ptr_to_base =
1387                        err!(builder.build_load(intrinsics.ptr_ty, ptr_to_base_ptr, "ptr_to_base"))
1388                            .into_pointer_value();
1389                    tbaa_label(
1390                        self.module,
1391                        self.intrinsics,
1392                        format!("memory base_ptr {}", memory_index.as_u32()),
1393                        ptr_to_base.as_instruction_value().unwrap(),
1394                    );
1395                    ptr_to_base
1396                }
1397                MemoryCache::Static { base_ptr } => base_ptr,
1398            }
1399        };
1400        let value_ptr = unsafe {
1401            err!(builder.build_gep(self.intrinsics.i8_ty, base_ptr, &[offset], "mem_value_ptr"))
1402        };
1403        err_nt!(
1404            builder
1405                .build_bit_cast(value_ptr, ptr_ty, "mem_value")
1406                .map(|v| v.into_pointer_value())
1407        )
1408    }
1409
1410    fn trap_if_misaligned(
1411        &self,
1412        _memarg: &MemArg,
1413        ptr: PointerValue<'ctx>,
1414        align: u8,
1415    ) -> Result<(), CompileError> {
1416        if align <= 1 {
1417            return Ok(());
1418        }
1419        let value = err!(self.builder.build_ptr_to_int(
1420            ptr,
1421            self.intrinsics.i64_ty,
1422            "mischeck_value"
1423        ));
1424        let and = err!(self.builder.build_and(
1425            value,
1426            self.intrinsics.i64_ty.const_int((align - 1).into(), false),
1427            "misaligncheck",
1428        ));
1429        let aligned = err!(self.builder.build_int_compare(
1430            IntPredicate::EQ,
1431            and,
1432            self.intrinsics.i64_zero,
1433            "is_aligned"
1434        ));
1435        let aligned = err!(self.builder.build_call(
1436            self.intrinsics.expect_i1,
1437            &[
1438                aligned.into(),
1439                self.intrinsics.i1_ty.const_int(1, false).into(),
1440            ],
1441            "is_aligned_expect",
1442        ))
1443        .try_as_basic_value()
1444        .left()
1445        .unwrap()
1446        .into_int_value();
1447
1448        let continue_block = self
1449            .context
1450            .append_basic_block(self.function, "aligned_access_continue_block");
1451        let not_aligned_block = self
1452            .context
1453            .append_basic_block(self.function, "misaligned_trap_block");
1454        err!(
1455            self.builder
1456                .build_conditional_branch(aligned, continue_block, not_aligned_block)
1457        );
1458
1459        self.builder.position_at_end(not_aligned_block);
1460        err!(self.builder.build_call(
1461            self.intrinsics.throw_trap,
1462            &[self.intrinsics.trap_unaligned_atomic.into()],
1463            "throw",
1464        ));
1465        err!(self.builder.build_unreachable());
1466
1467        self.builder.position_at_end(continue_block);
1468        Ok(())
1469    }
1470
1471    fn finalize(&mut self, wasm_fn_type: &FunctionType) -> Result<(), CompileError> {
1472        let func_type = self.function.get_type();
1473
1474        let results = self.state.popn_save_extra(wasm_fn_type.results().len())?;
1475        let results = err!(
1476            results
1477                .into_iter()
1478                .map(|(v, i)| self.apply_pending_canonicalization(v, i))
1479                .collect::<Result<Vec<_>, _>>()
1480        );
1481
1482        if wasm_fn_type.results().is_empty() {
1483            err!(self.builder.build_return(None));
1484        } else if self.abi.is_sret(wasm_fn_type)? {
1485            let sret = self
1486                .function
1487                .get_first_param()
1488                .unwrap()
1489                .into_pointer_value();
1490            let llvm_params: Vec<_> = wasm_fn_type
1491                .results()
1492                .iter()
1493                .map(|x| type_to_llvm(self.intrinsics, *x).unwrap())
1494                .collect();
1495            let mut struct_value = self
1496                .context
1497                .struct_type(llvm_params.as_slice(), false)
1498                .get_undef();
1499            for (idx, value) in results.into_iter().enumerate() {
1500                let value = err!(self.builder.build_bit_cast(
1501                    value,
1502                    type_to_llvm(self.intrinsics, wasm_fn_type.results()[idx])?,
1503                    "",
1504                ));
1505                struct_value =
1506                    err!(
1507                        self.builder
1508                            .build_insert_value(struct_value, value, idx as u32, "")
1509                    )
1510                    .into_struct_value();
1511            }
1512            err!(self.builder.build_store(sret, struct_value));
1513            err!(self.builder.build_return(None));
1514        } else {
1515            err!(
1516                self.builder
1517                    .build_return(Some(&self.abi.pack_values_for_register_return(
1518                        self.intrinsics,
1519                        &self.builder,
1520                        &results,
1521                        &func_type,
1522                    )?))
1523            );
1524        }
1525        Ok(())
1526    }
1527
1528    // Generates a global constant with the tag's module-local index, which can be used
1529    // as the "type info" of a catch clause.
1530    fn get_or_insert_tag_type_info_global(&mut self, tag: i32) -> BasicValueEnum<'ctx> {
1531        if let Some(tag) = self.tags_cache.get(&tag) {
1532            return *tag;
1533        }
1534
1535        let tag_ty = self
1536            .context
1537            .struct_type(&[self.intrinsics.i32_ty.into()], false);
1538        let tag_glbl = self.module.add_global(
1539            tag_ty,
1540            Some(AddressSpace::default()),
1541            &format!("__wasmer_eh_type_info_{tag}"),
1542        );
1543        tag_glbl.set_initializer(
1544            &tag_ty
1545                .const_named_struct(&[self.intrinsics.i32_ty.const_int(tag as _, false).into()])
1546                .as_basic_value_enum(),
1547        );
1548
1549        tag_glbl.set_linkage(Linkage::External);
1550        tag_glbl.set_constant(true);
1551        // Why set this to a specific section? On macOS it would land on a specifc read only data
1552        // section. GOT-based relocations will probably be generated with a non-zero addend, making
1553        // some EH-related intricacies not working.
1554        //
1555        // The general idea is that each tag has its own section, so the GOT-based relocation can
1556        // have a zero addend, i.e. the data of the tag is the first (and only) value in a specific
1557        // section we can target in relocations.
1558        if matches!(self.binary_fmt, target_lexicon::BinaryFormat::Macho) {
1559            tag_glbl.set_section(Some(&format!("{FUNCTION_SECTION_MACHO},_eh_ti_{tag}")));
1560        }
1561
1562        let tag_glbl = tag_glbl.as_basic_value_enum();
1563
1564        self.tags_cache.insert(tag, tag_glbl);
1565        tag_glbl
1566    }
1567
1568    fn get_or_insert_exception_type(
1569        &mut self,
1570        tag: u32,
1571        signature: &FunctionType,
1572    ) -> Result<inkwell::types::StructType<'ctx>, CompileError> {
1573        if let Some(ty) = self.exception_types_cache.get(&tag) {
1574            return Ok(*ty);
1575        }
1576        let types = signature
1577            .params()
1578            .iter()
1579            .map(|v| type_to_llvm(self.intrinsics, *v))
1580            .collect::<Result<Vec<_>, CompileError>>()?;
1581
1582        let ty = self.context.struct_type(&types, false);
1583        self.exception_types_cache.insert(tag, ty);
1584        Ok(ty)
1585    }
1586
1587    fn build_g0m0_indirect_call(
1588        &mut self,
1589        table_index: u32,
1590        ctx_ptr: PointerValue<'ctx>,
1591        func_type: &FunctionType,
1592        func_ptr: PointerValue<'ctx>,
1593        func_index: IntValue<'ctx>,
1594    ) -> Result<(), CompileError> {
1595        let Some((g0, m0)) = self.g0m0 else {
1596            return Err(CompileError::Codegen(
1597                "Call to build_g0m0_indirect_call without g0m0 parameters!".to_string(),
1598            ));
1599        };
1600
1601        let mut local_func_indices = vec![];
1602        let mut foreign_func_indices = vec![];
1603
1604        for t in &self.wasm_module.table_initializers {
1605            if t.table_index.as_u32() == table_index {
1606                for (func_in_table_idx, func_idx) in t.elements.iter().enumerate() {
1607                    if self.wasm_module.local_func_index(*func_idx).is_some() {
1608                        local_func_indices.push(func_in_table_idx)
1609                    } else {
1610                        foreign_func_indices.push(func_in_table_idx)
1611                    }
1612                }
1613                break;
1614            }
1615        }
1616
1617        // removed with mem2reg.
1618        //
1619        let g0_value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, "g0"));
1620
1621        let needs_switch = self.g0m0.is_some()
1622            && !local_func_indices.is_empty()
1623            && !foreign_func_indices.is_empty();
1624
1625        if needs_switch {
1626            let foreign_idx_block = self
1627                .context
1628                .append_basic_block(self.function, "foreign_call_block");
1629            let local_idx_block = self
1630                .context
1631                .append_basic_block(self.function, "local_call_block");
1632            let unreachable_indirect_call_branch_block = self
1633                .context
1634                .append_basic_block(self.function, "unreachable_indirect_call_branch");
1635
1636            let cont = self.context.append_basic_block(self.function, "cont");
1637
1638            err!(
1639                self.builder.build_switch(
1640                    func_index,
1641                    unreachable_indirect_call_branch_block,
1642                    &local_func_indices
1643                        .into_iter()
1644                        .map(|v| (
1645                            self.intrinsics.i32_ty.const_int(v as _, false),
1646                            local_idx_block
1647                        ))
1648                        .chain(foreign_func_indices.into_iter().map(|v| (
1649                            self.intrinsics.i32_ty.const_int(v as _, false),
1650                            foreign_idx_block
1651                        )))
1652                        .collect::<Vec<_>>()
1653                )
1654            );
1655
1656            self.builder
1657                .position_at_end(unreachable_indirect_call_branch_block);
1658            err!(self.builder.build_unreachable());
1659
1660            //let current_block = self.builder.get_insert_block().unwrap();
1661            self.builder.position_at_end(local_idx_block);
1662            let local_call_site = self.build_indirect_call(
1663                ctx_ptr,
1664                func_type,
1665                func_ptr,
1666                Some(G0M0FunctionKind::Local),
1667                Some((g0_value.into_int_value(), m0)),
1668            )?;
1669
1670            let local_rets = self.abi.rets_from_call(
1671                &self.builder,
1672                self.intrinsics,
1673                local_call_site,
1674                func_type,
1675            )?;
1676
1677            err!(self.builder.build_unconditional_branch(cont));
1678
1679            self.builder.position_at_end(foreign_idx_block);
1680            let foreign_call_site = self.build_indirect_call(
1681                ctx_ptr,
1682                func_type,
1683                func_ptr,
1684                Some(G0M0FunctionKind::Imported),
1685                None,
1686            )?;
1687
1688            let foreign_rets = self.abi.rets_from_call(
1689                &self.builder,
1690                self.intrinsics,
1691                foreign_call_site,
1692                func_type,
1693            )?;
1694
1695            err!(self.builder.build_unconditional_branch(cont));
1696
1697            self.builder.position_at_end(cont);
1698
1699            for i in 0..foreign_rets.len() {
1700                let f_i = foreign_rets[i];
1701                let l_i = local_rets[i];
1702                let ty = f_i.get_type();
1703                let v = err!(self.builder.build_phi(ty, ""));
1704                v.add_incoming(&[(&f_i, foreign_idx_block), (&l_i, local_idx_block)]);
1705                self.state.push1(v.as_basic_value());
1706            }
1707        } else if foreign_func_indices.is_empty() {
1708            let call_site = self.build_indirect_call(
1709                ctx_ptr,
1710                func_type,
1711                func_ptr,
1712                Some(G0M0FunctionKind::Local),
1713                Some((g0_value.into_int_value(), m0)),
1714            )?;
1715
1716            self.abi
1717                .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1718                .iter()
1719                .for_each(|ret| self.state.push1(*ret));
1720        } else {
1721            let call_site = self.build_indirect_call(
1722                ctx_ptr,
1723                func_type,
1724                func_ptr,
1725                Some(G0M0FunctionKind::Imported),
1726                Some((g0_value.into_int_value(), m0)),
1727            )?;
1728            self.abi
1729                .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1730                .iter()
1731                .for_each(|ret| self.state.push1(*ret));
1732        }
1733
1734        Ok(())
1735    }
1736
1737    fn build_indirect_call(
1738        &mut self,
1739        ctx_ptr: PointerValue<'ctx>,
1740        func_type: &FunctionType,
1741        func_ptr: PointerValue<'ctx>,
1742        func_kind: Option<G0M0FunctionKind>,
1743        g0m0_params: LocalFunctionG0M0params<'ctx>,
1744    ) -> Result<CallSiteValue<'ctx>, CompileError> {
1745        let (llvm_func_type, llvm_func_attrs) = self.abi.func_type_to_llvm(
1746            self.context,
1747            self.intrinsics,
1748            Some(self.ctx.get_offsets()),
1749            func_type,
1750            func_kind,
1751        )?;
1752
1753        let params = self.state.popn_save_extra(func_type.params().len())?;
1754
1755        // Apply pending canonicalizations.
1756        let params = params
1757            .iter()
1758            .zip(func_type.params().iter())
1759            .map(|((v, info), wasm_ty)| match wasm_ty {
1760                Type::F32 => err_nt!(self.builder.build_bit_cast(
1761                    self.apply_pending_canonicalization(*v, *info)?,
1762                    self.intrinsics.f32_ty,
1763                    "",
1764                )),
1765                Type::F64 => err_nt!(self.builder.build_bit_cast(
1766                    self.apply_pending_canonicalization(*v, *info)?,
1767                    self.intrinsics.f64_ty,
1768                    "",
1769                )),
1770                Type::V128 => self.apply_pending_canonicalization(*v, *info),
1771                _ => Ok(*v),
1772            })
1773            .collect::<Result<Vec<_>, _>>()?;
1774
1775        let params = self.abi.args_to_call(
1776            &self.alloca_builder,
1777            func_type,
1778            &llvm_func_type,
1779            ctx_ptr,
1780            params.as_slice(),
1781            self.intrinsics,
1782            g0m0_params,
1783        )?;
1784
1785        let typed_func_ptr = err!(self.builder.build_pointer_cast(
1786            func_ptr,
1787            self.context.ptr_type(AddressSpace::default()),
1788            "typed_func_ptr",
1789        ));
1790
1791        /*
1792        if self.track_state {
1793            if let Some(offset) = opcode_offset {
1794                let mut stackmaps = self.stackmaps.borrow_mut();
1795                emit_stack_map(
1796                    &info,
1797                    self.intrinsics,
1798                    self.builder,
1799                    self.index,
1800                    &mut *stackmaps,
1801                    StackmapEntryKind::Call,
1802                    &self.locals,
1803                    state,
1804                    ctx,
1805                    offset,
1806                )
1807            }
1808        }
1809        */
1810
1811        let call_site_local = if let Some(lpad) = self.state.get_innermost_landingpad() {
1812            let then_block = self.context.append_basic_block(self.function, "then_block");
1813
1814            let ret = err!(self.builder.build_indirect_invoke(
1815                llvm_func_type,
1816                typed_func_ptr,
1817                params.as_slice(),
1818                then_block,
1819                lpad,
1820                "",
1821            ));
1822
1823            self.builder.position_at_end(then_block);
1824            ret
1825        } else {
1826            err!(
1827                self.builder.build_indirect_call(
1828                    llvm_func_type,
1829                    typed_func_ptr,
1830                    params
1831                        .iter()
1832                        .copied()
1833                        .map(Into::into)
1834                        .collect::<Vec<BasicMetadataValueEnum>>()
1835                        .as_slice(),
1836                    "indirect_call",
1837                )
1838            )
1839        };
1840        for (attr, attr_loc) in llvm_func_attrs {
1841            call_site_local.add_attribute(attr_loc, attr);
1842        }
1843
1844        Ok(call_site_local)
1845    }
1846
1847    fn build_or_get_vmctx_alloca(&mut self) -> Result<PointerValue<'ctx>, CompileError> {
1848        if let Some(vmctx_alloca) = self.vmctx_alloca {
1849            return Ok(vmctx_alloca);
1850        }
1851
1852        let vmctx_alloca = err!(
1853            self.alloca_builder
1854                .build_alloca(self.intrinsics.ptr_ty, "vmctx")
1855        );
1856        err!(
1857            self.alloca_builder
1858                .build_store(vmctx_alloca, self.ctx.basic())
1859        );
1860        self.vmctx_alloca = Some(vmctx_alloca);
1861        Ok(vmctx_alloca)
1862    }
1863}
1864
1865/*
1866fn emit_stack_map<'ctx>(
1867    intrinsics: &Intrinsics<'ctx>,
1868    builder: &Builder<'ctx>,
1869    local_function_id: usize,
1870    target: &mut StackmapRegistry,
1871    kind: StackmapEntryKind,
1872    locals: &[PointerValue],
1873    state: &State<'ctx>,
1874    _ctx: &mut CtxType<'ctx>,
1875    opcode_offset: usize,
1876) {
1877    let stackmap_id = target.entries.len();
1878
1879    let mut params = Vec::with_capacity(2 + locals.len() + state.stack.len());
1880
1881    params.push(
1882        intrinsics
1883            .i64_ty
1884            .const_int(stackmap_id as u64, false)
1885            .as_basic_value_enum(),
1886    );
1887    params.push(intrinsics.i32_ty.const_zero().as_basic_value_enum());
1888
1889    let locals: Vec<_> = locals.iter().map(|x| x.as_basic_value_enum()).collect();
1890    let mut value_semantics: Vec<ValueSemantic> =
1891        Vec::with_capacity(locals.len() + state.stack.len());
1892
1893    params.extend_from_slice(&locals);
1894    value_semantics.extend((0..locals.len()).map(ValueSemantic::WasmLocal));
1895
1896    params.extend(state.stack.iter().map(|x| x.0));
1897    value_semantics.extend((0..state.stack.len()).map(ValueSemantic::WasmStack));
1898
1899    // FIXME: Information needed for Abstract -> Runtime state transform is not fully preserved
1900    // to accelerate compilation and reduce memory usage. Check this again when we try to support
1901    // "full" LLVM OSR.
1902
1903    assert_eq!(params.len(), value_semantics.len() + 2);
1904
1905    builder.build_call(intrinsics.experimental_stackmap, &params, "");
1906
1907    target.entries.push(StackmapEntry {
1908        kind,
1909        local_function_id,
1910        local_count: locals.len(),
1911        stack_count: state.stack.len(),
1912        opcode_offset,
1913        value_semantics,
1914        is_start: true,
1915    });
1916}
1917
1918fn finalize_opcode_stack_map<'ctx>(
1919    intrinsics: &Intrinsics<'ctx>,
1920    builder: &Builder<'ctx>,
1921    local_function_id: usize,
1922    target: &mut StackmapRegistry,
1923    kind: StackmapEntryKind,
1924    opcode_offset: usize,
1925) {
1926    let stackmap_id = target.entries.len();
1927    builder.build_call(
1928        intrinsics.experimental_stackmap,
1929        &[
1930            intrinsics
1931                .i64_ty
1932                .const_int(stackmap_id as u64, false)
1933                .as_basic_value_enum(),
1934            intrinsics.i32_ty.const_zero().as_basic_value_enum(),
1935        ],
1936        "opcode_stack_map_end",
1937    );
1938    target.entries.push(StackmapEntry {
1939        kind,
1940        local_function_id,
1941        local_count: 0,
1942        stack_count: 0,
1943        opcode_offset,
1944        value_semantics: vec![],
1945        is_start: false,
1946    });
1947}
1948 */
1949
1950pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
1951    g0m0: Option<(PointerValue<'ctx>, PointerValue<'ctx>)>,
1952    context: &'ctx Context,
1953    builder: Builder<'ctx>,
1954    alloca_builder: Builder<'ctx>,
1955    intrinsics: &'a Intrinsics<'ctx>,
1956    state: State<'ctx>,
1957    function: FunctionValue<'ctx>,
1958    locals: Vec<(BasicTypeEnum<'ctx>, PointerValue<'ctx>)>, // Contains params and locals
1959    ctx: CtxType<'ctx, 'a>,
1960    unreachable_depth: usize,
1961    memory_styles: &'a PrimaryMap<MemoryIndex, MemoryStyle>,
1962    _table_styles: &'a PrimaryMap<TableIndex, TableStyle>,
1963
1964    // This is support for stackmaps:
1965    /*
1966    stackmaps: Rc<RefCell<StackmapRegistry>>,
1967    index: usize,
1968    opcode_offset: usize,
1969    track_state: bool,
1970    */
1971    module: &'a Module<'ctx>,
1972    module_translation: &'a ModuleTranslationState,
1973    wasm_module: &'a ModuleInfo,
1974    symbol_registry: &'a dyn SymbolRegistry,
1975    abi: &'a dyn Abi,
1976    config: &'a LLVM,
1977    tags_cache: HashMap<i32, BasicValueEnum<'ctx>>,
1978    exception_types_cache: HashMap<u32, inkwell::types::StructType<'ctx>>,
1979    vmctx_alloca: Option<PointerValue<'ctx>>,
1980    binary_fmt: target_lexicon::BinaryFormat,
1981}
1982
1983impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
1984    fn translate_operator(&mut self, op: Operator, _source_loc: u32) -> Result<(), CompileError> {
1985        // TODO: remove this vmctx by moving everything into CtxType. Values
1986        // computed off vmctx usually benefit from caching.
1987        let vmctx = &self.ctx.basic().into_pointer_value();
1988
1989        //let opcode_offset: Option<usize> = None;
1990
1991        if !self.state.reachable {
1992            match op {
1993                Operator::Block { blockty: _ }
1994                | Operator::Loop { blockty: _ }
1995                | Operator::If { blockty: _ } => {
1996                    self.unreachable_depth += 1;
1997                    return Ok(());
1998                }
1999                Operator::Else => {
2000                    if self.unreachable_depth != 0 {
2001                        return Ok(());
2002                    }
2003                }
2004                Operator::End => {
2005                    if self.unreachable_depth != 0 {
2006                        self.unreachable_depth -= 1;
2007                        return Ok(());
2008                    }
2009                }
2010                _ => {
2011                    return Ok(());
2012                }
2013            }
2014        }
2015
2016        match op {
2017            /***************************
2018             * Control Flow instructions.
2019             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions
2020             ***************************/
2021            Operator::Block { blockty } => {
2022                let current_block = self
2023                    .builder
2024                    .get_insert_block()
2025                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2026
2027                let end_block = self.context.append_basic_block(self.function, "end");
2028                self.builder.position_at_end(end_block);
2029
2030                let phis: SmallVec<[PhiValue<'ctx>; 1]> = self
2031                    .module_translation
2032                    .blocktype_params_results(&blockty)?
2033                    .1
2034                    .iter()
2035                    .map(|&wp_ty| {
2036                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2037                            type_to_llvm(self.intrinsics, wasm_ty)
2038                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2039                        })
2040                    })
2041                    .collect::<Result<_, _>>()?;
2042
2043                self.state.push_block(
2044                    end_block,
2045                    phis,
2046                    self.module_translation
2047                        .blocktype_params_results(&blockty)?
2048                        .0
2049                        .len(),
2050                );
2051                self.builder.position_at_end(current_block);
2052            }
2053            Operator::Loop { blockty } => {
2054                let loop_body = self.context.append_basic_block(self.function, "loop_body");
2055                let loop_next = self.context.append_basic_block(self.function, "loop_outer");
2056                let pre_loop_block = self.builder.get_insert_block().unwrap();
2057
2058                err!(self.builder.build_unconditional_branch(loop_body));
2059
2060                self.builder.position_at_end(loop_next);
2061                let blocktypes = self.module_translation.blocktype_params_results(&blockty)?;
2062                let phis = blocktypes
2063                    .1
2064                    .iter()
2065                    .map(|&wp_ty| {
2066                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2067                            type_to_llvm(self.intrinsics, wasm_ty)
2068                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2069                        })
2070                    })
2071                    .collect::<Result<_, _>>()?;
2072                self.builder.position_at_end(loop_body);
2073                let loop_phis: SmallVec<[PhiValue<'ctx>; 1]> = blocktypes
2074                    .0
2075                    .iter()
2076                    .map(|&wp_ty| {
2077                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2078                            type_to_llvm(self.intrinsics, wasm_ty)
2079                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2080                        })
2081                    })
2082                    .collect::<Result<_, _>>()?;
2083                for phi in loop_phis.iter().rev() {
2084                    let (value, info) = self.state.pop1_extra()?;
2085                    let value = self.apply_pending_canonicalization(value, info)?;
2086                    phi.add_incoming(&[(&value, pre_loop_block)]);
2087                }
2088                for phi in &loop_phis {
2089                    self.state.push1(phi.as_basic_value());
2090                }
2091
2092                let num_inputs = loop_phis.len();
2093                self.state
2094                    .push_loop(loop_body, loop_next, loop_phis, phis, num_inputs);
2095            }
2096            Operator::Br { relative_depth } => {
2097                let frame = self.state.frame_at_depth(relative_depth)?;
2098
2099                let current_block = self
2100                    .builder
2101                    .get_insert_block()
2102                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2103
2104                let phis = if frame.is_loop() {
2105                    frame.loop_body_phis()
2106                } else {
2107                    frame.phis()
2108                };
2109
2110                let len = phis.len();
2111                let values = self.state.peekn_extra(len)?;
2112                let values = values
2113                    .iter()
2114                    .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2115                    .collect::<Result<Vec<_>, _>>()?;
2116
2117                // For each result of the block we're branching to,
2118                // pop a value off the value stack and load it into
2119                // the corresponding phi.
2120                for (phi, value) in phis.iter().zip(values.into_iter()) {
2121                    phi.add_incoming(&[(&value, current_block)]);
2122                }
2123
2124                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2125
2126                self.state.popn(len)?;
2127                self.state.reachable = false;
2128            }
2129            Operator::BrIf { relative_depth } => {
2130                let cond = self.state.pop1()?;
2131                let frame = self.state.frame_at_depth(relative_depth)?;
2132
2133                let current_block = self
2134                    .builder
2135                    .get_insert_block()
2136                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2137
2138                let phis = if frame.is_loop() {
2139                    frame.loop_body_phis()
2140                } else {
2141                    frame.phis()
2142                };
2143
2144                let param_stack = self.state.peekn_extra(phis.len())?;
2145                let param_stack = param_stack
2146                    .iter()
2147                    .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2148                    .collect::<Result<Vec<_>, _>>()?;
2149
2150                for (phi, value) in phis.iter().zip(param_stack) {
2151                    phi.add_incoming(&[(&value, current_block)]);
2152                }
2153
2154                let else_block = self.context.append_basic_block(self.function, "else");
2155
2156                let cond_value = err!(self.builder.build_int_compare(
2157                    IntPredicate::NE,
2158                    cond.into_int_value(),
2159                    self.intrinsics.i32_zero,
2160                    "",
2161                ));
2162                err!(self.builder.build_conditional_branch(
2163                    cond_value,
2164                    *frame.br_dest(),
2165                    else_block
2166                ));
2167                self.builder.position_at_end(else_block);
2168            }
2169            Operator::BrTable { ref targets } => {
2170                let current_block = self
2171                    .builder
2172                    .get_insert_block()
2173                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2174
2175                let index = self.state.pop1()?;
2176
2177                let default_frame = self.state.frame_at_depth(targets.default())?;
2178
2179                let phis = if default_frame.is_loop() {
2180                    default_frame.loop_body_phis()
2181                } else {
2182                    default_frame.phis()
2183                };
2184                let args = self.state.peekn(phis.len())?;
2185
2186                for (phi, value) in phis.iter().zip(args.iter()) {
2187                    phi.add_incoming(&[(value, current_block)]);
2188                }
2189
2190                let cases: Vec<_> = targets
2191                    .targets()
2192                    .enumerate()
2193                    .map(|(case_index, depth)| {
2194                        let depth = depth.map_err(from_binaryreadererror_wasmerror)?;
2195                        let frame_result: Result<&ControlFrame, CompileError> =
2196                            self.state.frame_at_depth(depth);
2197                        let frame = match frame_result {
2198                            Ok(v) => v,
2199                            Err(e) => return Err(e),
2200                        };
2201                        let case_index_literal =
2202                            self.context.i32_type().const_int(case_index as u64, false);
2203                        let phis = if frame.is_loop() {
2204                            frame.loop_body_phis()
2205                        } else {
2206                            frame.phis()
2207                        };
2208                        for (phi, value) in phis.iter().zip(args.iter()) {
2209                            phi.add_incoming(&[(value, current_block)]);
2210                        }
2211
2212                        Ok((case_index_literal, *frame.br_dest()))
2213                    })
2214                    .collect::<Result<_, _>>()?;
2215
2216                err!(self.builder.build_switch(
2217                    index.into_int_value(),
2218                    *default_frame.br_dest(),
2219                    &cases[..],
2220                ));
2221
2222                let args_len = args.len();
2223                self.state.popn(args_len)?;
2224                self.state.reachable = false;
2225            }
2226            Operator::If { blockty } => {
2227                let current_block = self
2228                    .builder
2229                    .get_insert_block()
2230                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2231                let if_then_block = self.context.append_basic_block(self.function, "if_then");
2232                let if_else_block = self.context.append_basic_block(self.function, "if_else");
2233                let end_block = self.context.append_basic_block(self.function, "if_end");
2234
2235                let end_phis = {
2236                    self.builder.position_at_end(end_block);
2237
2238                    let phis = self
2239                        .module_translation
2240                        .blocktype_params_results(&blockty)?
2241                        .1
2242                        .iter()
2243                        .map(|&wp_ty| {
2244                            err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2245                                type_to_llvm(self.intrinsics, wasm_ty)
2246                                    .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2247                            })
2248                        })
2249                        .collect::<Result<_, _>>()?;
2250
2251                    self.builder.position_at_end(current_block);
2252                    phis
2253                };
2254
2255                let cond = self.state.pop1()?;
2256
2257                let cond_value = err!(self.builder.build_int_compare(
2258                    IntPredicate::NE,
2259                    cond.into_int_value(),
2260                    self.intrinsics.i32_zero,
2261                    "",
2262                ));
2263
2264                err!(self.builder.build_conditional_branch(
2265                    cond_value,
2266                    if_then_block,
2267                    if_else_block
2268                ));
2269                self.builder.position_at_end(if_else_block);
2270                let block_param_types = self
2271                    .module_translation
2272                    .blocktype_params_results(&blockty)?
2273                    .0
2274                    .iter()
2275                    .map(|&wp_ty| {
2276                        err_nt!(wptype_to_type(wp_ty))
2277                            .and_then(|wasm_ty| type_to_llvm(self.intrinsics, wasm_ty))
2278                    })
2279                    .collect::<Result<Vec<_>, _>>()?;
2280                let else_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2281                    .iter()
2282                    .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2283                    .collect::<Result<SmallVec<_>, _>>()?;
2284                self.builder.position_at_end(if_then_block);
2285                let then_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2286                    .iter()
2287                    .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2288                    .collect::<Result<SmallVec<_>, _>>()?;
2289                for (else_phi, then_phi) in else_phis.iter().rev().zip(then_phis.iter().rev()) {
2290                    let (value, info) = self.state.pop1_extra()?;
2291                    let value = self.apply_pending_canonicalization(value, info)?;
2292                    else_phi.add_incoming(&[(&value, current_block)]);
2293                    then_phi.add_incoming(&[(&value, current_block)]);
2294                }
2295                for phi in then_phis.iter() {
2296                    self.state.push1(phi.as_basic_value());
2297                }
2298
2299                self.state.push_if(
2300                    if_then_block,
2301                    if_else_block,
2302                    end_block,
2303                    then_phis,
2304                    else_phis,
2305                    end_phis,
2306                    block_param_types.len(),
2307                );
2308            }
2309            Operator::Else => {
2310                if self.state.reachable {
2311                    let frame = self.state.frame_at_depth(0)?;
2312                    let current_block = self.builder.get_insert_block().ok_or_else(|| {
2313                        CompileError::Codegen("not currently in a block".to_string())
2314                    })?;
2315
2316                    for phi in frame.phis().to_vec().iter().rev() {
2317                        let (value, info) = self.state.pop1_extra()?;
2318                        let value = self.apply_pending_canonicalization(value, info)?;
2319                        phi.add_incoming(&[(&value, current_block)])
2320                    }
2321
2322                    let frame = self.state.frame_at_depth(0)?;
2323                    err!(self.builder.build_unconditional_branch(*frame.code_after()));
2324                }
2325
2326                let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
2327                    if_else,
2328                    if_else_state,
2329                    ..
2330                } = self.state.frame_at_depth_mut(0)?
2331                {
2332                    (if_else, if_else_state)
2333                } else {
2334                    unreachable!()
2335                };
2336
2337                *if_else_state = IfElseState::Else;
2338
2339                self.builder.position_at_end(*if_else_block);
2340                self.state.reachable = true;
2341
2342                if let ControlFrame::IfElse { else_phis, .. } = self.state.frame_at_depth(0)? {
2343                    // Push our own 'else' phi nodes to the stack.
2344                    for phi in else_phis.clone().iter() {
2345                        self.state.push1(phi.as_basic_value());
2346                    }
2347                };
2348            }
2349
2350            Operator::End => {
2351                let frame = self.state.pop_frame()?;
2352                let current_block = self
2353                    .builder
2354                    .get_insert_block()
2355                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2356
2357                if self.state.reachable {
2358                    for phi in frame.phis().iter().rev() {
2359                        let (value, info) = self.state.pop1_extra()?;
2360                        let value = self.apply_pending_canonicalization(value, info)?;
2361                        phi.add_incoming(&[(&value, current_block)]);
2362                    }
2363
2364                    err!(self.builder.build_unconditional_branch(*frame.code_after()));
2365                }
2366
2367                if let ControlFrame::IfElse {
2368                    if_else,
2369                    next,
2370                    if_else_state: IfElseState::If,
2371                    else_phis,
2372                    ..
2373                } = &frame
2374                {
2375                    for (phi, else_phi) in frame.phis().iter().zip(else_phis.iter()) {
2376                        phi.add_incoming(&[(&else_phi.as_basic_value(), *if_else)]);
2377                    }
2378                    self.builder.position_at_end(*if_else);
2379                    err!(self.builder.build_unconditional_branch(*next));
2380                } else if let ControlFrame::Landingpad { .. } = &frame {
2381                    self.state.pop_landingpad();
2382                };
2383
2384                self.builder.position_at_end(*frame.code_after());
2385                self.state.reset_stack(&frame);
2386
2387                self.state.reachable = true;
2388
2389                // Push each phi value to the value stack.
2390                for phi in frame.phis() {
2391                    if phi.count_incoming() != 0 {
2392                        self.state.push1(phi.as_basic_value());
2393                    } else {
2394                        // TODO if there are no incoming phi values, it means
2395                        // this block has no predecessors, and we can skip it
2396                        // altogether. However, fixing this is non-trivial as
2397                        // some places in the code rely on code getting generated
2398                        // for unreachable end blocks. For now, we let LLVM remove
2399                        // the block during dead code elimination instead.
2400                        let basic_ty = phi.as_basic_value().get_type();
2401                        let placeholder_value = basic_ty.const_zero();
2402                        self.state.push1(placeholder_value);
2403                        phi.as_instruction().erase_from_basic_block();
2404                    }
2405                }
2406            }
2407            Operator::Return => {
2408                let current_block = self
2409                    .builder
2410                    .get_insert_block()
2411                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2412
2413                let frame = self.state.outermost_frame()?;
2414                for phi in frame.phis().to_vec().iter().rev() {
2415                    let (arg, info) = self.state.pop1_extra()?;
2416                    let arg = self.apply_pending_canonicalization(arg, info)?;
2417                    phi.add_incoming(&[(&arg, current_block)]);
2418                }
2419                let frame = self.state.outermost_frame()?;
2420                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2421
2422                self.state.reachable = false;
2423            }
2424
2425            Operator::Unreachable => {
2426                err!(self.builder.build_call(
2427                    self.intrinsics.throw_trap,
2428                    &[self.intrinsics.trap_unreachable.into()],
2429                    "throw",
2430                ));
2431                err!(self.builder.build_unreachable());
2432
2433                self.state.reachable = false;
2434            }
2435
2436            /***************************
2437             * Basic instructions.
2438             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#basic-instructions
2439             ***************************/
2440            Operator::Nop => {
2441                // Do nothing.
2442            }
2443            Operator::Drop => {
2444                self.state.pop1()?;
2445            }
2446
2447            // Generate const values.
2448            Operator::I32Const { value } => {
2449                let i = self.intrinsics.i32_ty.const_int(value as u64, false);
2450                let info = if is_f32_arithmetic(value as u32) {
2451                    ExtraInfo::arithmetic_f32()
2452                } else {
2453                    Default::default()
2454                };
2455                self.state.push1_extra(i, info);
2456            }
2457            Operator::I64Const { value } => {
2458                let i = self.intrinsics.i64_ty.const_int(value as u64, false);
2459                let info = if is_f64_arithmetic(value as u64) {
2460                    ExtraInfo::arithmetic_f64()
2461                } else {
2462                    Default::default()
2463                };
2464                self.state.push1_extra(i, info);
2465            }
2466            Operator::F32Const { value } => {
2467                let bits = self.intrinsics.i32_ty.const_int(value.bits() as u64, false);
2468                let info = if is_f32_arithmetic(value.bits()) {
2469                    ExtraInfo::arithmetic_f32()
2470                } else {
2471                    Default::default()
2472                };
2473                let f = err!(
2474                    self.builder
2475                        .build_bit_cast(bits, self.intrinsics.f32_ty, "f")
2476                );
2477                self.state.push1_extra(f, info);
2478            }
2479            Operator::F64Const { value } => {
2480                let bits = self.intrinsics.i64_ty.const_int(value.bits(), false);
2481                let info = if is_f64_arithmetic(value.bits()) {
2482                    ExtraInfo::arithmetic_f64()
2483                } else {
2484                    Default::default()
2485                };
2486                let f = err!(
2487                    self.builder
2488                        .build_bit_cast(bits, self.intrinsics.f64_ty, "f")
2489                );
2490                self.state.push1_extra(f, info);
2491            }
2492            Operator::V128Const { value } => {
2493                let mut hi: [u8; 8] = Default::default();
2494                let mut lo: [u8; 8] = Default::default();
2495                hi.copy_from_slice(&value.bytes()[0..8]);
2496                lo.copy_from_slice(&value.bytes()[8..16]);
2497                let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
2498                let i = self
2499                    .intrinsics
2500                    .i128_ty
2501                    .const_int_arbitrary_precision(&packed);
2502                let mut quad1: [u8; 4] = Default::default();
2503                let mut quad2: [u8; 4] = Default::default();
2504                let mut quad3: [u8; 4] = Default::default();
2505                let mut quad4: [u8; 4] = Default::default();
2506                quad1.copy_from_slice(&value.bytes()[0..4]);
2507                quad2.copy_from_slice(&value.bytes()[4..8]);
2508                quad3.copy_from_slice(&value.bytes()[8..12]);
2509                quad4.copy_from_slice(&value.bytes()[12..16]);
2510                let mut info: ExtraInfo = Default::default();
2511                if is_f32_arithmetic(u32::from_le_bytes(quad1))
2512                    && is_f32_arithmetic(u32::from_le_bytes(quad2))
2513                    && is_f32_arithmetic(u32::from_le_bytes(quad3))
2514                    && is_f32_arithmetic(u32::from_le_bytes(quad4))
2515                {
2516                    info |= ExtraInfo::arithmetic_f32();
2517                }
2518                if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
2519                    info |= ExtraInfo::arithmetic_f64();
2520                }
2521                self.state.push1_extra(i, info);
2522            }
2523
2524            Operator::I8x16Splat => {
2525                let (v, i) = self.state.pop1_extra()?;
2526                let v = v.into_int_value();
2527                let v = err!(
2528                    self.builder
2529                        .build_int_truncate(v, self.intrinsics.i8_ty, "")
2530                );
2531                let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
2532                let res = err!(
2533                    self.builder
2534                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2535                );
2536                self.state.push1_extra(res, i);
2537            }
2538            Operator::I16x8Splat => {
2539                let (v, i) = self.state.pop1_extra()?;
2540                let v = v.into_int_value();
2541                let v = err!(
2542                    self.builder
2543                        .build_int_truncate(v, self.intrinsics.i16_ty, "")
2544                );
2545                let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
2546                let res = err!(
2547                    self.builder
2548                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2549                );
2550                self.state.push1_extra(res, i);
2551            }
2552            Operator::I32x4Splat => {
2553                let (v, i) = self.state.pop1_extra()?;
2554                let res = self.splat_vector(v, self.intrinsics.i32x4_ty)?;
2555                let res = err!(
2556                    self.builder
2557                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2558                );
2559                self.state.push1_extra(res, i);
2560            }
2561            Operator::I64x2Splat => {
2562                let (v, i) = self.state.pop1_extra()?;
2563                let res = self.splat_vector(v, self.intrinsics.i64x2_ty)?;
2564                let res = err!(
2565                    self.builder
2566                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2567                );
2568                self.state.push1_extra(res, i);
2569            }
2570            Operator::F32x4Splat => {
2571                let (v, i) = self.state.pop1_extra()?;
2572                let res = self.splat_vector(v, self.intrinsics.f32x4_ty)?;
2573                let res = err!(
2574                    self.builder
2575                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2576                );
2577                // The spec is unclear, we interpret splat as preserving NaN
2578                // payload bits.
2579                self.state.push1_extra(res, i);
2580            }
2581            Operator::F64x2Splat => {
2582                let (v, i) = self.state.pop1_extra()?;
2583                let res = self.splat_vector(v, self.intrinsics.f64x2_ty)?;
2584                let res = err!(
2585                    self.builder
2586                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2587                );
2588                // The spec is unclear, we interpret splat as preserving NaN
2589                // payload bits.
2590                self.state.push1_extra(res, i);
2591            }
2592
2593            // Operate on self.locals.
2594            Operator::LocalGet { local_index } => {
2595                let (type_value, pointer_value) = self.locals[local_index as usize];
2596                let v = err!(self.builder.build_load(
2597                    type_value,
2598                    pointer_value,
2599                    &format!("local_{local_index}_get")
2600                ));
2601                tbaa_label(
2602                    self.module,
2603                    self.intrinsics,
2604                    format!("local {local_index}"),
2605                    v.as_instruction_value().unwrap(),
2606                );
2607                self.state.push1(v);
2608            }
2609            Operator::LocalSet { local_index } => {
2610                let pointer_value = self.locals[local_index as usize].1;
2611                let (v, i) = self.state.pop1_extra()?;
2612                let v = self.apply_pending_canonicalization(v, i)?;
2613                let store = err!(self.builder.build_store(pointer_value, v));
2614                tbaa_label(
2615                    self.module,
2616                    self.intrinsics,
2617                    format!("local {local_index}"),
2618                    store,
2619                );
2620            }
2621            Operator::LocalTee { local_index } => {
2622                let pointer_value = self.locals[local_index as usize].1;
2623                let (v, i) = self.state.peek1_extra()?;
2624                let v = self.apply_pending_canonicalization(v, i)?;
2625                let store = err!(self.builder.build_store(pointer_value, v));
2626                tbaa_label(
2627                    self.module,
2628                    self.intrinsics,
2629                    format!("local {local_index}"),
2630                    store,
2631                );
2632            }
2633
2634            Operator::GlobalGet { global_index } => {
2635                if self.g0m0.is_some() && global_index == 0 {
2636                    let Some((g0, _)) = self.g0m0 else {
2637                        unreachable!()
2638                    };
2639
2640                    // Removed with mem2reg.
2641                    let value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, ""));
2642
2643                    self.state.push1(value);
2644                } else {
2645                    let global_index = GlobalIndex::from_u32(global_index);
2646                    match self
2647                        .ctx
2648                        .global(global_index, self.intrinsics, self.module)?
2649                    {
2650                        GlobalCache::Const { value } => {
2651                            self.state.push1(*value);
2652                        }
2653                        GlobalCache::Mut {
2654                            ptr_to_value,
2655                            value_type,
2656                        } => {
2657                            let value =
2658                                err!(self.builder.build_load(*value_type, *ptr_to_value, ""));
2659                            tbaa_label(
2660                                self.module,
2661                                self.intrinsics,
2662                                format!("global {}", global_index.as_u32()),
2663                                value.as_instruction_value().unwrap(),
2664                            );
2665                            self.state.push1(value);
2666                        }
2667                    }
2668                }
2669            }
2670            Operator::GlobalSet { global_index } => {
2671                if self.g0m0.is_some() && global_index == 0 {
2672                    let Some((g0, _)) = self.g0m0 else {
2673                        unreachable!()
2674                    };
2675                    let ptr_to_value = g0;
2676                    let (value, info) = self.state.pop1_extra()?;
2677                    let value = self.apply_pending_canonicalization(value, info)?;
2678                    let store = err!(self.builder.build_store(ptr_to_value, value));
2679                    tbaa_label(self.module, self.intrinsics, "global 0".to_string(), store);
2680                } else {
2681                    let global_index = GlobalIndex::from_u32(global_index);
2682                    match self
2683                        .ctx
2684                        .global(global_index, self.intrinsics, self.module)?
2685                    {
2686                        GlobalCache::Const { value: _ } => {
2687                            return Err(CompileError::Codegen(format!(
2688                                "global.set on immutable global index {}",
2689                                global_index.as_u32()
2690                            )));
2691                        }
2692                        GlobalCache::Mut { ptr_to_value, .. } => {
2693                            let ptr_to_value = *ptr_to_value;
2694                            let (value, info) = self.state.pop1_extra()?;
2695                            let value = self.apply_pending_canonicalization(value, info)?;
2696                            let store = err!(self.builder.build_store(ptr_to_value, value));
2697                            tbaa_label(
2698                                self.module,
2699                                self.intrinsics,
2700                                format!("global {}", global_index.as_u32()),
2701                                store,
2702                            );
2703                        }
2704                    }
2705                }
2706            }
2707
2708            // `TypedSelect` must be used for extern refs so ref counting should
2709            // be done with TypedSelect. But otherwise they're the same.
2710            Operator::TypedSelect { .. } | Operator::Select => {
2711                let ((v1, i1), (v2, i2), (cond, _)) = self.state.pop3_extra()?;
2712                // We don't bother canonicalizing 'cond' here because we only
2713                // compare it to zero, and that's invariant under
2714                // canonicalization.
2715
2716                // If the pending bits of v1 and v2 are the same, we can pass
2717                // them along to the result. Otherwise, apply pending
2718                // canonicalizations now.
2719                let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
2720                    || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
2721                {
2722                    (
2723                        self.apply_pending_canonicalization(v1, i1)?,
2724                        i1.strip_pending(),
2725                        self.apply_pending_canonicalization(v2, i2)?,
2726                        i2.strip_pending(),
2727                    )
2728                } else {
2729                    (v1, i1, v2, i2)
2730                };
2731                let cond_value = err!(self.builder.build_int_compare(
2732                    IntPredicate::NE,
2733                    cond.into_int_value(),
2734                    self.intrinsics.i32_zero,
2735                    "",
2736                ));
2737                let res = err!(self.builder.build_select(cond_value, v1, v2, ""));
2738                let info = {
2739                    let mut info = (i1.strip_pending() & i2.strip_pending())?;
2740                    if i1.has_pending_f32_nan() {
2741                        debug_assert!(i2.has_pending_f32_nan());
2742                        info = (info | ExtraInfo::pending_f32_nan())?;
2743                    }
2744                    if i1.has_pending_f64_nan() {
2745                        debug_assert!(i2.has_pending_f64_nan());
2746                        info = (info | ExtraInfo::pending_f64_nan())?;
2747                    }
2748                    info
2749                };
2750                self.state.push1_extra(res, info);
2751            }
2752            Operator::Call { function_index } => {
2753                let func_index = FunctionIndex::from_u32(function_index);
2754                let sigindex = &self.wasm_module.functions[func_index];
2755                let func_type = &self.wasm_module.signatures[*sigindex];
2756
2757                let mut g0m0_params = None;
2758
2759                let FunctionCache {
2760                    func,
2761                    llvm_func_type,
2762                    vmctx: callee_vmctx,
2763                    attrs,
2764                } = if let Some(local_func_index) = self.wasm_module.local_func_index(func_index) {
2765                    if let Some((g0, m0)) = &self.g0m0 {
2766                        // removed with mem2reg.
2767                        let value = err!(self.builder.build_load(self.intrinsics.i32_ty, *g0, ""));
2768
2769                        g0m0_params = Some((value.into_int_value(), *m0));
2770                    }
2771
2772                    let function_name = self
2773                        .symbol_registry
2774                        .symbol_to_name(Symbol::LocalFunction(local_func_index));
2775
2776                    self.ctx.local_func(
2777                        local_func_index,
2778                        func_index,
2779                        self.intrinsics,
2780                        self.module,
2781                        self.context,
2782                        func_type,
2783                        &function_name,
2784                    )?
2785                } else {
2786                    self.ctx
2787                        .func(func_index, self.intrinsics, self.context, func_type)?
2788                };
2789                let llvm_func_type = *llvm_func_type;
2790                let func = *func;
2791                let callee_vmctx = *callee_vmctx;
2792                let attrs = attrs.clone();
2793
2794                /*
2795                let func_ptr = self.llvm.functions.borrow_mut()[&func_index];
2796
2797                (params, func_ptr.as_global_value().as_pointer_value())
2798                */
2799                let params = self.state.popn_save_extra(func_type.params().len())?;
2800
2801                // Apply pending canonicalizations.
2802                let params = params
2803                    .iter()
2804                    .zip(func_type.params().iter())
2805                    .map(|((v, info), wasm_ty)| match wasm_ty {
2806                        Type::F32 => err_nt!(self.builder.build_bit_cast(
2807                            self.apply_pending_canonicalization(*v, *info)?,
2808                            self.intrinsics.f32_ty,
2809                            "",
2810                        )),
2811                        Type::F64 => err_nt!(self.builder.build_bit_cast(
2812                            self.apply_pending_canonicalization(*v, *info)?,
2813                            self.intrinsics.f64_ty,
2814                            "",
2815                        )),
2816                        Type::V128 => self.apply_pending_canonicalization(*v, *info),
2817                        _ => Ok(*v),
2818                    })
2819                    .collect::<Result<Vec<_>, _>>()?;
2820
2821                let params = self.abi.args_to_call(
2822                    &self.alloca_builder,
2823                    func_type,
2824                    &llvm_func_type,
2825                    callee_vmctx.into_pointer_value(),
2826                    params.as_slice(),
2827                    self.intrinsics,
2828                    g0m0_params,
2829                )?;
2830
2831                /*
2832                if self.track_state {
2833                    if let Some(offset) = opcode_offset {
2834                        let mut stackmaps = self.stackmaps.borrow_mut();
2835                        emit_stack_map(
2836                            &info,
2837                            self.intrinsics,
2838                            self.builder,
2839                            self.index,
2840                            &mut *stackmaps,
2841                            StackmapEntryKind::Call,
2842                            &self.locals,
2843                            state,
2844                            ctx,
2845                            offset,
2846                        )
2847                    }
2848                }
2849                */
2850                let call_site = if let Some(lpad) = self.state.get_innermost_landingpad() {
2851                    let then_block = self.context.append_basic_block(self.function, "then_block");
2852
2853                    let ret = err!(self.builder.build_indirect_invoke(
2854                        llvm_func_type,
2855                        func,
2856                        params.as_slice(),
2857                        then_block,
2858                        lpad,
2859                        "",
2860                    ));
2861
2862                    self.builder.position_at_end(then_block);
2863                    ret
2864                } else {
2865                    err!(
2866                        self.builder.build_indirect_call(
2867                            llvm_func_type,
2868                            func,
2869                            params
2870                                .iter()
2871                                .copied()
2872                                .map(Into::into)
2873                                .collect::<Vec<BasicMetadataValueEnum>>()
2874                                .as_slice(),
2875                            "",
2876                        )
2877                    )
2878                };
2879                for (attr, attr_loc) in attrs {
2880                    call_site.add_attribute(attr_loc, attr);
2881                }
2882                /*
2883                if self.track_state {
2884                    if let Some(offset) = opcode_offset {
2885                        let mut stackmaps = self.stackmaps.borrow_mut();
2886                        finalize_opcode_stack_map(
2887                            self.intrinsics,
2888                            self.builder,
2889                            self.index,
2890                            &mut *stackmaps,
2891                            StackmapEntryKind::Call,
2892                            offset,
2893                        )
2894                    }
2895                }
2896                */
2897
2898                self.abi
2899                    .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
2900                    .iter()
2901                    .for_each(|ret| self.state.push1(*ret));
2902            }
2903            Operator::CallIndirect {
2904                type_index,
2905                table_index,
2906            } => {
2907                let sigindex = SignatureIndex::from_u32(type_index);
2908                let func_type = &self.wasm_module.signatures[sigindex];
2909                let expected_dynamic_sigindex =
2910                    self.ctx
2911                        .dynamic_sigindex(sigindex, self.intrinsics, self.module)?;
2912                let (table_base, table_bound) = self.ctx.table(
2913                    TableIndex::from_u32(table_index),
2914                    self.intrinsics,
2915                    self.module,
2916                    &self.builder,
2917                )?;
2918                let func_index = self.state.pop1()?.into_int_value();
2919
2920                let truncated_table_bounds = err!(self.builder.build_int_truncate(
2921                    table_bound,
2922                    self.intrinsics.i32_ty,
2923                    "truncated_table_bounds",
2924                ));
2925
2926                // First, check if the index is outside of the table bounds.
2927                let index_in_bounds = err!(self.builder.build_int_compare(
2928                    IntPredicate::ULT,
2929                    func_index,
2930                    truncated_table_bounds,
2931                    "index_in_bounds",
2932                ));
2933
2934                let index_in_bounds = err!(self.builder.build_call(
2935                    self.intrinsics.expect_i1,
2936                    &[
2937                        index_in_bounds.into(),
2938                        self.intrinsics.i1_ty.const_int(1, false).into(),
2939                    ],
2940                    "index_in_bounds_expect",
2941                ))
2942                .try_as_basic_value()
2943                .left()
2944                .unwrap()
2945                .into_int_value();
2946
2947                let in_bounds_continue_block = self
2948                    .context
2949                    .append_basic_block(self.function, "in_bounds_continue_block");
2950                let not_in_bounds_block = self
2951                    .context
2952                    .append_basic_block(self.function, "not_in_bounds_block");
2953                err!(self.builder.build_conditional_branch(
2954                    index_in_bounds,
2955                    in_bounds_continue_block,
2956                    not_in_bounds_block,
2957                ));
2958                self.builder.position_at_end(not_in_bounds_block);
2959                err!(self.builder.build_call(
2960                    self.intrinsics.throw_trap,
2961                    &[self.intrinsics.trap_table_access_oob.into()],
2962                    "throw",
2963                ));
2964                err!(self.builder.build_unreachable());
2965                self.builder.position_at_end(in_bounds_continue_block);
2966
2967                // We assume the table has the `funcref` (pointer to `anyfunc`)
2968                // element type.
2969                let casted_table_base = err!(self.builder.build_pointer_cast(
2970                    table_base,
2971                    self.context.ptr_type(AddressSpace::default()),
2972                    "casted_table_base",
2973                ));
2974
2975                let funcref_ptr = unsafe {
2976                    err!(self.builder.build_in_bounds_gep(
2977                        self.intrinsics.ptr_ty,
2978                        casted_table_base,
2979                        &[func_index],
2980                        "funcref_ptr",
2981                    ))
2982                };
2983
2984                // a funcref (pointer to `anyfunc`)
2985                let anyfunc_struct_ptr = err!(self.builder.build_load(
2986                    self.intrinsics.ptr_ty,
2987                    funcref_ptr,
2988                    "anyfunc_struct_ptr",
2989                ))
2990                .into_pointer_value();
2991
2992                // trap if we're trying to call a null funcref
2993                {
2994                    let funcref_not_null = err!(
2995                        self.builder
2996                            .build_is_not_null(anyfunc_struct_ptr, "null funcref check")
2997                    );
2998
2999                    let funcref_continue_deref_block = self
3000                        .context
3001                        .append_basic_block(self.function, "funcref_continue deref_block");
3002
3003                    let funcref_is_null_block = self
3004                        .context
3005                        .append_basic_block(self.function, "funcref_is_null_block");
3006                    err!(self.builder.build_conditional_branch(
3007                        funcref_not_null,
3008                        funcref_continue_deref_block,
3009                        funcref_is_null_block,
3010                    ));
3011                    self.builder.position_at_end(funcref_is_null_block);
3012                    err!(self.builder.build_call(
3013                        self.intrinsics.throw_trap,
3014                        &[self.intrinsics.trap_call_indirect_null.into()],
3015                        "throw",
3016                    ));
3017                    err!(self.builder.build_unreachable());
3018                    self.builder.position_at_end(funcref_continue_deref_block);
3019                }
3020
3021                // Load things from the anyfunc data structure.
3022                let func_ptr_ptr = self
3023                    .builder
3024                    .build_struct_gep(
3025                        self.intrinsics.anyfunc_ty,
3026                        anyfunc_struct_ptr,
3027                        0,
3028                        "func_ptr_ptr",
3029                    )
3030                    .unwrap();
3031                let sigindex_ptr = self
3032                    .builder
3033                    .build_struct_gep(
3034                        self.intrinsics.anyfunc_ty,
3035                        anyfunc_struct_ptr,
3036                        1,
3037                        "sigindex_ptr",
3038                    )
3039                    .unwrap();
3040                let ctx_ptr_ptr = self
3041                    .builder
3042                    .build_struct_gep(
3043                        self.intrinsics.anyfunc_ty,
3044                        anyfunc_struct_ptr,
3045                        2,
3046                        "ctx_ptr_ptr",
3047                    )
3048                    .unwrap();
3049                let (func_ptr, found_dynamic_sigindex, ctx_ptr) = (
3050                    err!(
3051                        self.builder
3052                            .build_load(self.intrinsics.ptr_ty, func_ptr_ptr, "func_ptr")
3053                    )
3054                    .into_pointer_value(),
3055                    err!(
3056                        self.builder
3057                            .build_load(self.intrinsics.i32_ty, sigindex_ptr, "sigindex")
3058                    )
3059                    .into_int_value(),
3060                    err!(
3061                        self.builder
3062                            .build_load(self.intrinsics.ptr_ty, ctx_ptr_ptr, "ctx_ptr")
3063                    ),
3064                );
3065
3066                // Next, check if the table element is initialized.
3067
3068                // TODO: we may not need this check anymore
3069                let elem_initialized = err!(self.builder.build_is_not_null(func_ptr, ""));
3070
3071                // Next, check if the signature id is correct.
3072
3073                let sigindices_equal = err!(self.builder.build_int_compare(
3074                    IntPredicate::EQ,
3075                    expected_dynamic_sigindex,
3076                    found_dynamic_sigindex,
3077                    "sigindices_equal",
3078                ));
3079
3080                let initialized_and_sigindices_match = err!(self.builder.build_and(
3081                    elem_initialized,
3082                    sigindices_equal,
3083                    ""
3084                ));
3085
3086                // Tell llvm that `expected_dynamic_sigindex` should equal `found_dynamic_sigindex`.
3087                let initialized_and_sigindices_match = err!(self.builder.build_call(
3088                    self.intrinsics.expect_i1,
3089                    &[
3090                        initialized_and_sigindices_match.into(),
3091                        self.intrinsics.i1_ty.const_int(1, false).into(),
3092                    ],
3093                    "initialized_and_sigindices_match_expect",
3094                ))
3095                .try_as_basic_value()
3096                .left()
3097                .unwrap()
3098                .into_int_value();
3099
3100                let continue_block = self
3101                    .context
3102                    .append_basic_block(self.function, "continue_block");
3103                let sigindices_notequal_block = self
3104                    .context
3105                    .append_basic_block(self.function, "sigindices_notequal_block");
3106                err!(self.builder.build_conditional_branch(
3107                    initialized_and_sigindices_match,
3108                    continue_block,
3109                    sigindices_notequal_block,
3110                ));
3111
3112                self.builder.position_at_end(sigindices_notequal_block);
3113                let trap_code = err!(self.builder.build_select(
3114                    elem_initialized,
3115                    self.intrinsics.trap_call_indirect_sig,
3116                    self.intrinsics.trap_call_indirect_null,
3117                    "",
3118                ));
3119                err!(self.builder.build_call(
3120                    self.intrinsics.throw_trap,
3121                    &[trap_code.into()],
3122                    "throw"
3123                ));
3124                err!(self.builder.build_unreachable());
3125                self.builder.position_at_end(continue_block);
3126
3127                if self.g0m0.is_some() {
3128                    self.build_g0m0_indirect_call(
3129                        table_index,
3130                        ctx_ptr.into_pointer_value(),
3131                        func_type,
3132                        func_ptr,
3133                        func_index,
3134                    )?;
3135                } else {
3136                    let call_site = self.build_indirect_call(
3137                        ctx_ptr.into_pointer_value(),
3138                        func_type,
3139                        func_ptr,
3140                        None,
3141                        None,
3142                    )?;
3143
3144                    self.abi
3145                        .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
3146                        .iter()
3147                        .for_each(|ret| self.state.push1(*ret));
3148                }
3149            }
3150
3151            /***************************
3152             * Integer Arithmetic instructions.
3153             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-arithmetic-instructions
3154             ***************************/
3155            Operator::I32Add | Operator::I64Add => {
3156                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3157                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3158                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3159                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3160                let res = err!(self.builder.build_int_add(v1, v2, ""));
3161                self.state.push1(res);
3162            }
3163            Operator::I8x16Add => {
3164                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3165                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3166                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3167                let res = err!(self.builder.build_int_add(v1, v2, ""));
3168                let res = err!(
3169                    self.builder
3170                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3171                );
3172                self.state.push1(res);
3173            }
3174            Operator::I16x8Add => {
3175                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3176                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3177                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3178                let res = err!(self.builder.build_int_add(v1, v2, ""));
3179                let res = err!(
3180                    self.builder
3181                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3182                );
3183                self.state.push1(res);
3184            }
3185            Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U => {
3186                let extend_op = match op {
3187                    Operator::I16x8ExtAddPairwiseI8x16S => {
3188                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, "")
3189                    }
3190                    Operator::I16x8ExtAddPairwiseI8x16U => {
3191                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, "")
3192                    }
3193                    _ => unreachable!("Unhandled internal variant"),
3194                };
3195                let (v, i) = self.state.pop1_extra()?;
3196                let (v, _) = self.v128_into_i8x16(v, i)?;
3197
3198                let left = err!(self.builder.build_shuffle_vector(
3199                    v,
3200                    v.get_type().get_undef(),
3201                    VectorType::const_vector(&[
3202                        self.intrinsics.i32_consts[0],
3203                        self.intrinsics.i32_consts[2],
3204                        self.intrinsics.i32_consts[4],
3205                        self.intrinsics.i32_consts[6],
3206                        self.intrinsics.i32_consts[8],
3207                        self.intrinsics.i32_consts[10],
3208                        self.intrinsics.i32_consts[12],
3209                        self.intrinsics.i32_consts[14],
3210                    ]),
3211                    "",
3212                ));
3213                let left = err!(extend_op(self, left));
3214                let right = err!(self.builder.build_shuffle_vector(
3215                    v,
3216                    v.get_type().get_undef(),
3217                    VectorType::const_vector(&[
3218                        self.intrinsics.i32_consts[1],
3219                        self.intrinsics.i32_consts[3],
3220                        self.intrinsics.i32_consts[5],
3221                        self.intrinsics.i32_consts[7],
3222                        self.intrinsics.i32_consts[9],
3223                        self.intrinsics.i32_consts[11],
3224                        self.intrinsics.i32_consts[13],
3225                        self.intrinsics.i32_consts[15],
3226                    ]),
3227                    "",
3228                ));
3229                let right = err!(extend_op(self, right));
3230
3231                let res = err!(self.builder.build_int_add(left, right, ""));
3232                let res = err!(
3233                    self.builder
3234                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3235                );
3236                self.state.push1(res);
3237            }
3238            Operator::I32x4Add => {
3239                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3240                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3241                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3242                let res = err!(self.builder.build_int_add(v1, v2, ""));
3243                let res = err!(
3244                    self.builder
3245                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3246                );
3247                self.state.push1(res);
3248            }
3249            Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
3250                let extend_op = match op {
3251                    Operator::I32x4ExtAddPairwiseI16x8S => {
3252                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3253                    }
3254                    Operator::I32x4ExtAddPairwiseI16x8U => {
3255                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3256                    }
3257                    _ => unreachable!("Unhandled internal variant"),
3258                };
3259                let (v, i) = self.state.pop1_extra()?;
3260                let (v, _) = self.v128_into_i16x8(v, i)?;
3261
3262                let left = err!(self.builder.build_shuffle_vector(
3263                    v,
3264                    v.get_type().get_undef(),
3265                    VectorType::const_vector(&[
3266                        self.intrinsics.i32_consts[0],
3267                        self.intrinsics.i32_consts[2],
3268                        self.intrinsics.i32_consts[4],
3269                        self.intrinsics.i32_consts[6],
3270                    ]),
3271                    "",
3272                ));
3273                let left = err!(extend_op(self, left));
3274                let right = err!(self.builder.build_shuffle_vector(
3275                    v,
3276                    v.get_type().get_undef(),
3277                    VectorType::const_vector(&[
3278                        self.intrinsics.i32_consts[1],
3279                        self.intrinsics.i32_consts[3],
3280                        self.intrinsics.i32_consts[5],
3281                        self.intrinsics.i32_consts[7],
3282                    ]),
3283                    "",
3284                ));
3285                let right = err!(extend_op(self, right));
3286
3287                let res = err!(self.builder.build_int_add(left, right, ""));
3288                let res = err!(
3289                    self.builder
3290                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3291                );
3292                self.state.push1(res);
3293            }
3294            Operator::I64x2Add => {
3295                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3296                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3297                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3298                let res = err!(self.builder.build_int_add(v1, v2, ""));
3299                let res = err!(
3300                    self.builder
3301                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3302                );
3303                self.state.push1(res);
3304            }
3305            Operator::I8x16AddSatS => {
3306                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3307                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3308                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3309                let res = err!(self.builder.build_call(
3310                    self.intrinsics.sadd_sat_i8x16,
3311                    &[v1.into(), v2.into()],
3312                    ""
3313                ))
3314                .try_as_basic_value()
3315                .left()
3316                .unwrap();
3317                let res = err!(
3318                    self.builder
3319                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3320                );
3321                self.state.push1(res);
3322            }
3323            Operator::I16x8AddSatS => {
3324                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3325                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3326                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3327                let res = err!(self.builder.build_call(
3328                    self.intrinsics.sadd_sat_i16x8,
3329                    &[v1.into(), v2.into()],
3330                    ""
3331                ))
3332                .try_as_basic_value()
3333                .left()
3334                .unwrap();
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::I8x16AddSatU => {
3342                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3343                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3344                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3345                let res = err!(self.builder.build_call(
3346                    self.intrinsics.uadd_sat_i8x16,
3347                    &[v1.into(), v2.into()],
3348                    ""
3349                ))
3350                .try_as_basic_value()
3351                .left()
3352                .unwrap();
3353                let res = err!(
3354                    self.builder
3355                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3356                );
3357                self.state.push1(res);
3358            }
3359            Operator::I16x8AddSatU => {
3360                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3361                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3362                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3363                let res = err!(self.builder.build_call(
3364                    self.intrinsics.uadd_sat_i16x8,
3365                    &[v1.into(), v2.into()],
3366                    ""
3367                ))
3368                .try_as_basic_value()
3369                .left()
3370                .unwrap();
3371                let res = err!(
3372                    self.builder
3373                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3374                );
3375                self.state.push1(res);
3376            }
3377            Operator::I32Sub | Operator::I64Sub => {
3378                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3379                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3380                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3381                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3382                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3383                self.state.push1(res);
3384            }
3385            Operator::I8x16Sub => {
3386                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3387                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3388                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3389                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3390                let res = err!(
3391                    self.builder
3392                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3393                );
3394                self.state.push1(res);
3395            }
3396            Operator::I16x8Sub => {
3397                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3398                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3399                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3400                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3401                let res = err!(
3402                    self.builder
3403                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3404                );
3405                self.state.push1(res);
3406            }
3407            Operator::I32x4Sub => {
3408                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3409                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3410                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3411                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3412                let res = err!(
3413                    self.builder
3414                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3415                );
3416                self.state.push1(res);
3417            }
3418            Operator::I64x2Sub => {
3419                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3420                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3421                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3422                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3423                let res = err!(
3424                    self.builder
3425                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3426                );
3427                self.state.push1(res);
3428            }
3429            Operator::I8x16SubSatS => {
3430                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3431                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3432                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3433                let res = err!(self.builder.build_call(
3434                    self.intrinsics.ssub_sat_i8x16,
3435                    &[v1.into(), v2.into()],
3436                    ""
3437                ))
3438                .try_as_basic_value()
3439                .left()
3440                .unwrap();
3441                let res = err!(
3442                    self.builder
3443                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3444                );
3445                self.state.push1(res);
3446            }
3447            Operator::I16x8SubSatS => {
3448                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3449                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3450                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3451                let res = err!(self.builder.build_call(
3452                    self.intrinsics.ssub_sat_i16x8,
3453                    &[v1.into(), v2.into()],
3454                    ""
3455                ))
3456                .try_as_basic_value()
3457                .left()
3458                .unwrap();
3459                let res = err!(
3460                    self.builder
3461                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3462                );
3463                self.state.push1(res);
3464            }
3465            Operator::I8x16SubSatU => {
3466                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3467                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3468                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3469                let res = err!(self.builder.build_call(
3470                    self.intrinsics.usub_sat_i8x16,
3471                    &[v1.into(), v2.into()],
3472                    ""
3473                ))
3474                .try_as_basic_value()
3475                .left()
3476                .unwrap();
3477                let res = err!(
3478                    self.builder
3479                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3480                );
3481                self.state.push1(res);
3482            }
3483            Operator::I16x8SubSatU => {
3484                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3485                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3486                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3487                let res = err!(self.builder.build_call(
3488                    self.intrinsics.usub_sat_i16x8,
3489                    &[v1.into(), v2.into()],
3490                    ""
3491                ))
3492                .try_as_basic_value()
3493                .left()
3494                .unwrap();
3495                let res = err!(
3496                    self.builder
3497                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3498                );
3499                self.state.push1(res);
3500            }
3501            Operator::I32Mul | Operator::I64Mul => {
3502                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3503                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3504                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3505                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3506                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3507                self.state.push1(res);
3508            }
3509            Operator::I16x8Mul => {
3510                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3511                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3512                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3513                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3514                let res = err!(
3515                    self.builder
3516                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3517                );
3518                self.state.push1(res);
3519            }
3520            Operator::I32x4Mul => {
3521                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3522                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3523                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3524                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3525                let res = err!(
3526                    self.builder
3527                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3528                );
3529                self.state.push1(res);
3530            }
3531            Operator::I64x2Mul => {
3532                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3533                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3534                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3535                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3536                let res = err!(
3537                    self.builder
3538                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3539                );
3540                self.state.push1(res);
3541            }
3542            Operator::I16x8Q15MulrSatS => {
3543                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3544                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3545                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3546
3547                let max_value = self.intrinsics.i16_ty.const_int(i16::MAX as u64, false);
3548                let max_values = VectorType::const_vector(&[max_value; 8]);
3549
3550                let v1 = err!(
3551                    self.builder
3552                        .build_int_s_extend(v1, self.intrinsics.i32x8_ty, "")
3553                );
3554                let v2 = err!(
3555                    self.builder
3556                        .build_int_s_extend(v2, self.intrinsics.i32x8_ty, "")
3557                );
3558                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3559
3560                // magic number specified by the spec
3561                let bit = self.intrinsics.i32_ty.const_int(0x4000, false);
3562                let bits = VectorType::const_vector(&[bit; 8]);
3563
3564                let res = err!(self.builder.build_int_add(res, bits, ""));
3565
3566                let fifteen = self.intrinsics.i32_consts[15];
3567                let fifteens = VectorType::const_vector(&[fifteen; 8]);
3568
3569                let res = err!(self.builder.build_right_shift(res, fifteens, true, ""));
3570                let saturate_up = {
3571                    let max_values = err!(self.builder.build_int_s_extend(
3572                        max_values,
3573                        self.intrinsics.i32x8_ty,
3574                        ""
3575                    ));
3576                    err!(
3577                        self.builder
3578                            .build_int_compare(IntPredicate::SGT, res, max_values, "")
3579                    )
3580                };
3581
3582                let res = err!(
3583                    self.builder
3584                        .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
3585                );
3586
3587                let res = err!(self.builder.build_select(saturate_up, max_values, res, ""))
3588                    .into_vector_value();
3589                let res = err!(
3590                    self.builder
3591                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3592                );
3593                self.state.push1(res);
3594            }
3595            Operator::I16x8ExtMulLowI8x16S
3596            | Operator::I16x8ExtMulLowI8x16U
3597            | Operator::I16x8ExtMulHighI8x16S
3598            | Operator::I16x8ExtMulHighI8x16U => {
3599                let extend_op = match op {
3600                    Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulHighI8x16S => {
3601                        |s: &Self, v| -> Result<VectorValue, CompileError> {
3602                            err_nt!(s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, ""))
3603                        }
3604                    }
3605                    Operator::I16x8ExtMulLowI8x16U | Operator::I16x8ExtMulHighI8x16U => {
3606                        |s: &Self, v| -> Result<VectorValue, CompileError> {
3607                            err_nt!(s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, ""))
3608                        }
3609                    }
3610                    _ => unreachable!("Unhandled internal variant"),
3611                };
3612                let shuffle_array = match op {
3613                    Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulLowI8x16U => [
3614                        self.intrinsics.i32_consts[0],
3615                        self.intrinsics.i32_consts[2],
3616                        self.intrinsics.i32_consts[4],
3617                        self.intrinsics.i32_consts[6],
3618                        self.intrinsics.i32_consts[8],
3619                        self.intrinsics.i32_consts[10],
3620                        self.intrinsics.i32_consts[12],
3621                        self.intrinsics.i32_consts[14],
3622                    ],
3623                    Operator::I16x8ExtMulHighI8x16S | Operator::I16x8ExtMulHighI8x16U => [
3624                        self.intrinsics.i32_consts[1],
3625                        self.intrinsics.i32_consts[3],
3626                        self.intrinsics.i32_consts[5],
3627                        self.intrinsics.i32_consts[7],
3628                        self.intrinsics.i32_consts[9],
3629                        self.intrinsics.i32_consts[11],
3630                        self.intrinsics.i32_consts[13],
3631                        self.intrinsics.i32_consts[15],
3632                    ],
3633                    _ => unreachable!("Unhandled internal variant"),
3634                };
3635                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3636                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3637                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3638                let val1 = err!(self.builder.build_shuffle_vector(
3639                    v1,
3640                    v1.get_type().get_undef(),
3641                    VectorType::const_vector(&shuffle_array),
3642                    "",
3643                ));
3644                let val1 = err!(extend_op(self, val1));
3645                let val2 = err!(self.builder.build_shuffle_vector(
3646                    v2,
3647                    v2.get_type().get_undef(),
3648                    VectorType::const_vector(&shuffle_array),
3649                    "",
3650                ));
3651                let val2 = err!(extend_op(self, val2));
3652                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3653                let res = err!(
3654                    self.builder
3655                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3656                );
3657                self.state.push1(res);
3658            }
3659            Operator::I32x4ExtMulLowI16x8S
3660            | Operator::I32x4ExtMulLowI16x8U
3661            | Operator::I32x4ExtMulHighI16x8S
3662            | Operator::I32x4ExtMulHighI16x8U => {
3663                let extend_op = match op {
3664                    Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulHighI16x8S => {
3665                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3666                    }
3667                    Operator::I32x4ExtMulLowI16x8U | Operator::I32x4ExtMulHighI16x8U => {
3668                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3669                    }
3670                    _ => unreachable!("Unhandled internal variant"),
3671                };
3672                let shuffle_array = match op {
3673                    Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulLowI16x8U => [
3674                        self.intrinsics.i32_consts[0],
3675                        self.intrinsics.i32_consts[2],
3676                        self.intrinsics.i32_consts[4],
3677                        self.intrinsics.i32_consts[6],
3678                    ],
3679                    Operator::I32x4ExtMulHighI16x8S | Operator::I32x4ExtMulHighI16x8U => [
3680                        self.intrinsics.i32_consts[1],
3681                        self.intrinsics.i32_consts[3],
3682                        self.intrinsics.i32_consts[5],
3683                        self.intrinsics.i32_consts[7],
3684                    ],
3685                    _ => unreachable!("Unhandled internal variant"),
3686                };
3687                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3688                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3689                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3690                let val1 = err!(self.builder.build_shuffle_vector(
3691                    v1,
3692                    v1.get_type().get_undef(),
3693                    VectorType::const_vector(&shuffle_array),
3694                    "",
3695                ));
3696                let val1 = err!(extend_op(self, val1));
3697                let val2 = err!(self.builder.build_shuffle_vector(
3698                    v2,
3699                    v2.get_type().get_undef(),
3700                    VectorType::const_vector(&shuffle_array),
3701                    "",
3702                ));
3703                let val2 = err!(extend_op(self, val2));
3704                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3705                let res = err!(
3706                    self.builder
3707                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3708                );
3709                self.state.push1(res);
3710            }
3711            Operator::I64x2ExtMulLowI32x4S
3712            | Operator::I64x2ExtMulLowI32x4U
3713            | Operator::I64x2ExtMulHighI32x4S
3714            | Operator::I64x2ExtMulHighI32x4U => {
3715                let extend_op = match op {
3716                    Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulHighI32x4S => {
3717                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
3718                    }
3719                    Operator::I64x2ExtMulLowI32x4U | Operator::I64x2ExtMulHighI32x4U => {
3720                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
3721                    }
3722                    _ => unreachable!("Unhandled internal variant"),
3723                };
3724                let shuffle_array = match op {
3725                    Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulLowI32x4U => {
3726                        [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[2]]
3727                    }
3728                    Operator::I64x2ExtMulHighI32x4S | Operator::I64x2ExtMulHighI32x4U => {
3729                        [self.intrinsics.i32_consts[1], self.intrinsics.i32_consts[3]]
3730                    }
3731                    _ => unreachable!("Unhandled internal variant"),
3732                };
3733                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3734                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3735                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3736                let val1 = err!(self.builder.build_shuffle_vector(
3737                    v1,
3738                    v1.get_type().get_undef(),
3739                    VectorType::const_vector(&shuffle_array),
3740                    "",
3741                ));
3742                let val1 = err!(extend_op(self, val1));
3743                let val2 = err!(self.builder.build_shuffle_vector(
3744                    v2,
3745                    v2.get_type().get_undef(),
3746                    VectorType::const_vector(&shuffle_array),
3747                    "",
3748                ));
3749                let val2 = err!(extend_op(self, val2));
3750                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3751                let res = err!(
3752                    self.builder
3753                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3754                );
3755                self.state.push1(res);
3756            }
3757            Operator::I32x4DotI16x8S => {
3758                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3759                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3760                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3761                let low_i16 = [
3762                    self.intrinsics.i32_consts[0],
3763                    self.intrinsics.i32_consts[2],
3764                    self.intrinsics.i32_consts[4],
3765                    self.intrinsics.i32_consts[6],
3766                ];
3767                let high_i16 = [
3768                    self.intrinsics.i32_consts[1],
3769                    self.intrinsics.i32_consts[3],
3770                    self.intrinsics.i32_consts[5],
3771                    self.intrinsics.i32_consts[7],
3772                ];
3773                let v1_low = err!(self.builder.build_shuffle_vector(
3774                    v1,
3775                    v1.get_type().get_undef(),
3776                    VectorType::const_vector(&low_i16),
3777                    "",
3778                ));
3779                let v1_low = err!(self.builder.build_int_s_extend(
3780                    v1_low,
3781                    self.intrinsics.i32x4_ty,
3782                    ""
3783                ));
3784                let v1_high = err!(self.builder.build_shuffle_vector(
3785                    v1,
3786                    v1.get_type().get_undef(),
3787                    VectorType::const_vector(&high_i16),
3788                    "",
3789                ));
3790                let v1_high = err!(self.builder.build_int_s_extend(
3791                    v1_high,
3792                    self.intrinsics.i32x4_ty,
3793                    ""
3794                ));
3795                let v2_low = err!(self.builder.build_shuffle_vector(
3796                    v2,
3797                    v2.get_type().get_undef(),
3798                    VectorType::const_vector(&low_i16),
3799                    "",
3800                ));
3801                let v2_low = err!(self.builder.build_int_s_extend(
3802                    v2_low,
3803                    self.intrinsics.i32x4_ty,
3804                    ""
3805                ));
3806                let v2_high = err!(self.builder.build_shuffle_vector(
3807                    v2,
3808                    v2.get_type().get_undef(),
3809                    VectorType::const_vector(&high_i16),
3810                    "",
3811                ));
3812                let v2_high = err!(self.builder.build_int_s_extend(
3813                    v2_high,
3814                    self.intrinsics.i32x4_ty,
3815                    ""
3816                ));
3817                let low_product = err!(self.builder.build_int_mul(v1_low, v2_low, ""));
3818                let high_product = err!(self.builder.build_int_mul(v1_high, v2_high, ""));
3819
3820                let res = err!(self.builder.build_int_add(low_product, high_product, ""));
3821                let res = err!(
3822                    self.builder
3823                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3824                );
3825                self.state.push1(res);
3826            }
3827            Operator::I32DivS | Operator::I64DivS => {
3828                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3829                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3830                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3831                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3832
3833                self.trap_if_zero_or_overflow(v1, v2)?;
3834
3835                let res = err!(self.builder.build_int_signed_div(v1, v2, ""));
3836                self.state.push1(res);
3837            }
3838            Operator::I32DivU | Operator::I64DivU => {
3839                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3840                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3841                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3842                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3843
3844                self.trap_if_zero(v2)?;
3845
3846                let res = err!(self.builder.build_int_unsigned_div(v1, v2, ""));
3847                self.state.push1(res);
3848            }
3849            Operator::I32RemS | Operator::I64RemS => {
3850                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3851                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3852                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3853                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3854                let int_type = v1.get_type();
3855                let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
3856                    let min_value = int_type.const_int(i32::MIN as u64, false);
3857                    let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
3858                    (min_value, neg_one_value)
3859                } else if int_type == self.intrinsics.i64_ty {
3860                    let min_value = int_type.const_int(i64::MIN as u64, false);
3861                    let neg_one_value = int_type.const_int(-1i64 as u64, false);
3862                    (min_value, neg_one_value)
3863                } else {
3864                    unreachable!()
3865                };
3866
3867                self.trap_if_zero(v2)?;
3868
3869                // "Overflow also leads to undefined behavior; this is a rare
3870                // case, but can occur, for example, by taking the remainder of
3871                // a 32-bit division of -2147483648 by -1. (The remainder
3872                // doesn’t actually overflow, but this rule lets srem be
3873                // implemented using instructions that return both the result
3874                // of the division and the remainder.)"
3875                //   -- https://llvm.org/docs/LangRef.html#srem-instruction
3876                //
3877                // In Wasm, the i32.rem_s i32.const -2147483648 i32.const -1 is
3878                // i32.const 0. We implement this by swapping out the left value
3879                // for 0 in this case.
3880                let will_overflow = err!(self.builder.build_and(
3881                    err!(self.builder.build_int_compare(
3882                        IntPredicate::EQ,
3883                        v1,
3884                        min_value,
3885                        "left_is_min"
3886                    )),
3887                    err!(self.builder.build_int_compare(
3888                        IntPredicate::EQ,
3889                        v2,
3890                        neg_one_value,
3891                        "right_is_neg_one",
3892                    )),
3893                    "srem_will_overflow",
3894                ));
3895                let v1 =
3896                    err!(
3897                        self.builder
3898                            .build_select(will_overflow, int_type.const_zero(), v1, "")
3899                    )
3900                    .into_int_value();
3901                let res = err!(self.builder.build_int_signed_rem(v1, v2, ""));
3902                self.state.push1(res);
3903            }
3904            Operator::I32RemU | Operator::I64RemU => {
3905                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3906                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3907                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3908                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3909
3910                self.trap_if_zero(v2)?;
3911
3912                let res = err!(self.builder.build_int_unsigned_rem(v1, v2, ""));
3913                self.state.push1(res);
3914            }
3915            Operator::I32And | Operator::I64And | Operator::V128And => {
3916                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3917                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3918                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3919                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3920                let res = err!(self.builder.build_and(v1, v2, ""));
3921                self.state.push1(res);
3922            }
3923            Operator::I32Or | Operator::I64Or | Operator::V128Or => {
3924                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3925                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3926                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3927                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3928                let res = err!(self.builder.build_or(v1, v2, ""));
3929                self.state.push1(res);
3930            }
3931            Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
3932                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3933                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3934                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3935                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3936                let res = err!(self.builder.build_xor(v1, v2, ""));
3937                self.state.push1(res);
3938            }
3939            Operator::V128AndNot => {
3940                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3941                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3942                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3943                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3944                let v2 = err!(self.builder.build_not(v2, ""));
3945                let res = err!(self.builder.build_and(v1, v2, ""));
3946                self.state.push1(res);
3947            }
3948            Operator::V128Bitselect => {
3949                let ((v1, i1), (v2, i2), (cond, cond_info)) = self.state.pop3_extra()?;
3950                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3951                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3952                let cond = self.apply_pending_canonicalization(cond, cond_info)?;
3953                let v1 = err!(
3954                    self.builder
3955                        .build_bit_cast(v1, self.intrinsics.i1x128_ty, "")
3956                )
3957                .into_vector_value();
3958                let v2 = err!(
3959                    self.builder
3960                        .build_bit_cast(v2, self.intrinsics.i1x128_ty, "")
3961                )
3962                .into_vector_value();
3963                let cond = err!(
3964                    self.builder
3965                        .build_bit_cast(cond, self.intrinsics.i1x128_ty, "")
3966                )
3967                .into_vector_value();
3968                let res = err!(self.builder.build_select(cond, v1, v2, ""));
3969                let res = err!(
3970                    self.builder
3971                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3972                );
3973                self.state.push1(res);
3974            }
3975            Operator::I8x16Bitmask => {
3976                let (v, i) = self.state.pop1_extra()?;
3977                let (v, _) = self.v128_into_i8x16(v, i)?;
3978
3979                let zeros = self.intrinsics.i8x16_ty.const_zero();
3980                let res = err!(
3981                    self.builder
3982                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
3983                );
3984                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i16_ty, ""))
3985                    .into_int_value();
3986                let res = err!(
3987                    self.builder
3988                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
3989                );
3990                self.state.push1(res);
3991            }
3992            Operator::I16x8Bitmask => {
3993                let (v, i) = self.state.pop1_extra()?;
3994                let (v, _) = self.v128_into_i16x8(v, i)?;
3995
3996                let zeros = self.intrinsics.i16x8_ty.const_zero();
3997                let res = err!(
3998                    self.builder
3999                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4000                );
4001                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i8_ty, ""))
4002                    .into_int_value();
4003                let res = err!(
4004                    self.builder
4005                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4006                );
4007                self.state.push1(res);
4008            }
4009            Operator::I32x4Bitmask => {
4010                let (v, i) = self.state.pop1_extra()?;
4011                let (v, _) = self.v128_into_i32x4(v, i)?;
4012
4013                let zeros = self.intrinsics.i32x4_ty.const_zero();
4014                let res = err!(
4015                    self.builder
4016                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4017                );
4018                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i4_ty, ""))
4019                    .into_int_value();
4020                let res = err!(
4021                    self.builder
4022                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4023                );
4024                self.state.push1(res);
4025            }
4026            Operator::I64x2Bitmask => {
4027                let (v, i) = self.state.pop1_extra()?;
4028                let (v, _) = self.v128_into_i64x2(v, i)?;
4029
4030                let zeros = self.intrinsics.i64x2_ty.const_zero();
4031                let res = err!(
4032                    self.builder
4033                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4034                );
4035                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i2_ty, ""))
4036                    .into_int_value();
4037                let res = err!(
4038                    self.builder
4039                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4040                );
4041                self.state.push1(res);
4042            }
4043            Operator::I32Shl => {
4044                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4045                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4046                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4047                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4048                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4049                let v2 = err!(self.builder.build_and(v2, mask, ""));
4050                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4051                self.state.push1(res);
4052            }
4053            Operator::I64Shl => {
4054                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4055                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4056                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4057                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4058                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4059                let v2 = err!(self.builder.build_and(v2, mask, ""));
4060                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4061                self.state.push1(res);
4062            }
4063            Operator::I8x16Shl => {
4064                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4065                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4066                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4067                let v2 = v2.into_int_value();
4068                let v2 = err!(
4069                    self.builder
4070                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4071                );
4072                let v2 = err!(
4073                    self.builder
4074                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4075                );
4076                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4077                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4078                let res = err!(
4079                    self.builder
4080                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4081                );
4082                self.state.push1(res);
4083            }
4084            Operator::I16x8Shl => {
4085                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4086                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4087                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4088                let v2 = v2.into_int_value();
4089                let v2 = err!(
4090                    self.builder
4091                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4092                );
4093                let v2 = err!(
4094                    self.builder
4095                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4096                );
4097                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4098                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4099                let res = err!(
4100                    self.builder
4101                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4102                );
4103                self.state.push1(res);
4104            }
4105            Operator::I32x4Shl => {
4106                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4107                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4108                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4109                let v2 = v2.into_int_value();
4110                let v2 = err!(self.builder.build_and(
4111                    v2,
4112                    self.intrinsics.i32_ty.const_int(31, false),
4113                    ""
4114                ));
4115                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_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::I64x2Shl => {
4124                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4125                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4126                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4127                let v2 = v2.into_int_value();
4128                let v2 = err!(self.builder.build_and(
4129                    v2,
4130                    self.intrinsics.i32_ty.const_int(63, false),
4131                    ""
4132                ));
4133                let v2 = err!(
4134                    self.builder
4135                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4136                );
4137                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4138                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4139                let res = err!(
4140                    self.builder
4141                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4142                );
4143                self.state.push1(res);
4144            }
4145            Operator::I32ShrS => {
4146                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4147                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4148                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4149                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4150                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4151                let v2 = err!(self.builder.build_and(v2, mask, ""));
4152                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4153                self.state.push1(res);
4154            }
4155            Operator::I64ShrS => {
4156                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4157                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4158                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4159                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4160                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4161                let v2 = err!(self.builder.build_and(v2, mask, ""));
4162                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4163                self.state.push1(res);
4164            }
4165            Operator::I8x16ShrS => {
4166                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4167                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4168                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4169                let v2 = v2.into_int_value();
4170                let v2 = err!(
4171                    self.builder
4172                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4173                );
4174                let v2 = err!(
4175                    self.builder
4176                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4177                );
4178                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4179                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4180                let res = err!(
4181                    self.builder
4182                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4183                );
4184                self.state.push1(res);
4185            }
4186            Operator::I16x8ShrS => {
4187                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4188                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4189                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4190                let v2 = v2.into_int_value();
4191                let v2 = err!(
4192                    self.builder
4193                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4194                );
4195                let v2 = err!(
4196                    self.builder
4197                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4198                );
4199                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4200                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4201                let res = err!(
4202                    self.builder
4203                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4204                );
4205                self.state.push1(res);
4206            }
4207            Operator::I32x4ShrS => {
4208                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4209                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4210                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4211                let v2 = v2.into_int_value();
4212                let v2 = err!(self.builder.build_and(
4213                    v2,
4214                    self.intrinsics.i32_ty.const_int(31, false),
4215                    ""
4216                ));
4217                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_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::I64x2ShrS => {
4226                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4227                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4228                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4229                let v2 = v2.into_int_value();
4230                let v2 = err!(self.builder.build_and(
4231                    v2,
4232                    self.intrinsics.i32_ty.const_int(63, false),
4233                    ""
4234                ));
4235                let v2 = err!(
4236                    self.builder
4237                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4238                );
4239                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4240                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4241                let res = err!(
4242                    self.builder
4243                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4244                );
4245                self.state.push1(res);
4246            }
4247            Operator::I32ShrU => {
4248                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4249                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4250                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4251                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4252                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4253                let v2 = err!(self.builder.build_and(v2, mask, ""));
4254                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4255                self.state.push1(res);
4256            }
4257            Operator::I64ShrU => {
4258                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4259                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4260                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4261                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4262                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4263                let v2 = err!(self.builder.build_and(v2, mask, ""));
4264                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4265                self.state.push1(res);
4266            }
4267            Operator::I8x16ShrU => {
4268                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4269                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4270                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4271                let v2 = v2.into_int_value();
4272                let v2 = err!(
4273                    self.builder
4274                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4275                );
4276                let v2 = err!(
4277                    self.builder
4278                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4279                );
4280                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4281                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4282                let res = err!(
4283                    self.builder
4284                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4285                );
4286                self.state.push1(res);
4287            }
4288            Operator::I16x8ShrU => {
4289                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4290                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4291                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4292                let v2 = v2.into_int_value();
4293                let v2 = err!(
4294                    self.builder
4295                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4296                );
4297                let v2 = err!(
4298                    self.builder
4299                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4300                );
4301                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4302                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4303                let res = err!(
4304                    self.builder
4305                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4306                );
4307                self.state.push1(res);
4308            }
4309            Operator::I32x4ShrU => {
4310                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4311                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4312                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4313                let v2 = v2.into_int_value();
4314                let v2 = err!(self.builder.build_and(
4315                    v2,
4316                    self.intrinsics.i32_ty.const_int(31, false),
4317                    ""
4318                ));
4319                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_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::I64x2ShrU => {
4328                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4329                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4330                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4331                let v2 = v2.into_int_value();
4332                let v2 = err!(self.builder.build_and(
4333                    v2,
4334                    self.intrinsics.i32_ty.const_int(63, false),
4335                    ""
4336                ));
4337                let v2 = err!(
4338                    self.builder
4339                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4340                );
4341                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4342                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4343                let res = err!(
4344                    self.builder
4345                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4346                );
4347                self.state.push1(res);
4348            }
4349            Operator::I32Rotl => {
4350                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4351                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4352                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4353                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4354                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4355                let v2 = err!(self.builder.build_and(v2, mask, ""));
4356                let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4357                let rhs = {
4358                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4359                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4360                    err!(self.builder.build_right_shift(v1, rhs, false, ""))
4361                };
4362                let res = err!(self.builder.build_or(lhs, rhs, ""));
4363                self.state.push1(res);
4364            }
4365            Operator::I64Rotl => {
4366                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4367                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4368                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4369                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4370                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4371                let v2 = err!(self.builder.build_and(v2, mask, ""));
4372                let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4373                let rhs = {
4374                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4375                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4376                    err!(self.builder.build_right_shift(v1, rhs, false, ""))
4377                };
4378                let res = err!(self.builder.build_or(lhs, rhs, ""));
4379                self.state.push1(res);
4380            }
4381            Operator::I32Rotr => {
4382                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4383                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4384                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4385                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4386                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4387                let v2 = err!(self.builder.build_and(v2, mask, ""));
4388                let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4389                let rhs = {
4390                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4391                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4392                    err!(self.builder.build_left_shift(v1, rhs, ""))
4393                };
4394                let res = err!(self.builder.build_or(lhs, rhs, ""));
4395                self.state.push1(res);
4396            }
4397            Operator::I64Rotr => {
4398                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4399                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4400                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4401                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4402                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4403                let v2 = err!(self.builder.build_and(v2, mask, ""));
4404                let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4405                let rhs = {
4406                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4407                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4408                    err!(self.builder.build_left_shift(v1, rhs, ""))
4409                };
4410                let res = err!(self.builder.build_or(lhs, rhs, ""));
4411                self.state.push1(res);
4412            }
4413            Operator::I32Clz => {
4414                let (input, info) = self.state.pop1_extra()?;
4415                let input = self.apply_pending_canonicalization(input, info)?;
4416                let is_zero_undef = self.intrinsics.i1_zero;
4417                let res = err!(self.builder.build_call(
4418                    self.intrinsics.ctlz_i32,
4419                    &[input.into(), is_zero_undef.into()],
4420                    "",
4421                ))
4422                .try_as_basic_value()
4423                .left()
4424                .unwrap();
4425                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4426            }
4427            Operator::I64Clz => {
4428                let (input, info) = self.state.pop1_extra()?;
4429                let input = self.apply_pending_canonicalization(input, info)?;
4430                let is_zero_undef = self.intrinsics.i1_zero;
4431                let res = err!(self.builder.build_call(
4432                    self.intrinsics.ctlz_i64,
4433                    &[input.into(), is_zero_undef.into()],
4434                    "",
4435                ))
4436                .try_as_basic_value()
4437                .left()
4438                .unwrap();
4439                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4440            }
4441            Operator::I32Ctz => {
4442                let (input, info) = self.state.pop1_extra()?;
4443                let input = self.apply_pending_canonicalization(input, info)?;
4444                let is_zero_undef = self.intrinsics.i1_zero;
4445                let res = err!(self.builder.build_call(
4446                    self.intrinsics.cttz_i32,
4447                    &[input.into(), is_zero_undef.into()],
4448                    "",
4449                ))
4450                .try_as_basic_value()
4451                .left()
4452                .unwrap();
4453                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4454            }
4455            Operator::I64Ctz => {
4456                let (input, info) = self.state.pop1_extra()?;
4457                let input = self.apply_pending_canonicalization(input, info)?;
4458                let is_zero_undef = self.intrinsics.i1_zero;
4459                let res = err!(self.builder.build_call(
4460                    self.intrinsics.cttz_i64,
4461                    &[input.into(), is_zero_undef.into()],
4462                    "",
4463                ))
4464                .try_as_basic_value()
4465                .left()
4466                .unwrap();
4467                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4468            }
4469            Operator::I8x16Popcnt => {
4470                let (v, i) = self.state.pop1_extra()?;
4471                let (v, _) = self.v128_into_i8x16(v, i)?;
4472                let res = err!(self.builder.build_call(
4473                    self.intrinsics.ctpop_i8x16,
4474                    &[v.into()],
4475                    ""
4476                ))
4477                .try_as_basic_value()
4478                .left()
4479                .unwrap();
4480                let res = err!(
4481                    self.builder
4482                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4483                );
4484                self.state.push1(res);
4485            }
4486            Operator::I32Popcnt => {
4487                let (input, info) = self.state.pop1_extra()?;
4488                let input = self.apply_pending_canonicalization(input, info)?;
4489                let res = err!(self.builder.build_call(
4490                    self.intrinsics.ctpop_i32,
4491                    &[input.into()],
4492                    ""
4493                ))
4494                .try_as_basic_value()
4495                .left()
4496                .unwrap();
4497                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4498            }
4499            Operator::I64Popcnt => {
4500                let (input, info) = self.state.pop1_extra()?;
4501                let input = self.apply_pending_canonicalization(input, info)?;
4502                let res = err!(self.builder.build_call(
4503                    self.intrinsics.ctpop_i64,
4504                    &[input.into()],
4505                    ""
4506                ))
4507                .try_as_basic_value()
4508                .left()
4509                .unwrap();
4510                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4511            }
4512            Operator::I32Eqz => {
4513                let input = self.state.pop1()?.into_int_value();
4514                let cond = err!(self.builder.build_int_compare(
4515                    IntPredicate::EQ,
4516                    input,
4517                    self.intrinsics.i32_zero,
4518                    "",
4519                ));
4520                let res = err!(
4521                    self.builder
4522                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4523                );
4524                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4525            }
4526            Operator::I64Eqz => {
4527                let input = self.state.pop1()?.into_int_value();
4528                let cond = err!(self.builder.build_int_compare(
4529                    IntPredicate::EQ,
4530                    input,
4531                    self.intrinsics.i64_zero,
4532                    "",
4533                ));
4534                let res = err!(
4535                    self.builder
4536                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4537                );
4538                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4539            }
4540            Operator::I8x16Abs => {
4541                let (v, i) = self.state.pop1_extra()?;
4542                let (v, _) = self.v128_into_i8x16(v, i)?;
4543
4544                let seven = self.intrinsics.i8_ty.const_int(7, false);
4545                let seven = VectorType::const_vector(&[seven; 16]);
4546                let all_sign_bits = err!(self.builder.build_right_shift(v, seven, true, ""));
4547                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4548                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4549                let res = err!(
4550                    self.builder
4551                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4552                );
4553                self.state.push1(res);
4554            }
4555            Operator::I16x8Abs => {
4556                let (v, i) = self.state.pop1_extra()?;
4557                let (v, _) = self.v128_into_i16x8(v, i)?;
4558
4559                let fifteen = self.intrinsics.i16_ty.const_int(15, false);
4560                let fifteen = VectorType::const_vector(&[fifteen; 8]);
4561                let all_sign_bits = err!(self.builder.build_right_shift(v, fifteen, true, ""));
4562                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4563                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4564                let res = err!(
4565                    self.builder
4566                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4567                );
4568                self.state.push1(res);
4569            }
4570            Operator::I32x4Abs => {
4571                let (v, i) = self.state.pop1_extra()?;
4572                let (v, _) = self.v128_into_i32x4(v, i)?;
4573
4574                let thirtyone = self.intrinsics.i32_ty.const_int(31, false);
4575                let thirtyone = VectorType::const_vector(&[thirtyone; 4]);
4576                let all_sign_bits = err!(self.builder.build_right_shift(v, thirtyone, true, ""));
4577                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4578                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4579                let res = err!(
4580                    self.builder
4581                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4582                );
4583                self.state.push1(res);
4584            }
4585            Operator::I64x2Abs => {
4586                let (v, i) = self.state.pop1_extra()?;
4587                let (v, _) = self.v128_into_i64x2(v, i)?;
4588
4589                let sixtythree = self.intrinsics.i64_ty.const_int(63, false);
4590                let sixtythree = VectorType::const_vector(&[sixtythree; 2]);
4591                let all_sign_bits = err!(self.builder.build_right_shift(v, sixtythree, true, ""));
4592                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4593                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4594                let res = err!(
4595                    self.builder
4596                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4597                );
4598                self.state.push1(res);
4599            }
4600            Operator::I8x16MinS => {
4601                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4602                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4603                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4604                let cmp = err!(
4605                    self.builder
4606                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4607                );
4608                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4609                let res = err!(
4610                    self.builder
4611                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4612                );
4613                self.state.push1(res);
4614            }
4615            Operator::I8x16MinU => {
4616                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4617                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4618                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4619                let cmp = err!(
4620                    self.builder
4621                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4622                );
4623                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4624                let res = err!(
4625                    self.builder
4626                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4627                );
4628                self.state.push1(res);
4629            }
4630            Operator::I8x16MaxS => {
4631                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4632                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4633                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4634                let cmp = err!(
4635                    self.builder
4636                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4637                );
4638                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4639                let res = err!(
4640                    self.builder
4641                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4642                );
4643                self.state.push1(res);
4644            }
4645            Operator::I8x16MaxU => {
4646                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4647                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4648                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4649                let cmp = err!(
4650                    self.builder
4651                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4652                );
4653                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4654                let res = err!(
4655                    self.builder
4656                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4657                );
4658                self.state.push1(res);
4659            }
4660            Operator::I16x8MinS => {
4661                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4662                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4663                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4664                let cmp = err!(
4665                    self.builder
4666                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4667                );
4668                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4669                let res = err!(
4670                    self.builder
4671                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4672                );
4673                self.state.push1(res);
4674            }
4675            Operator::I16x8MinU => {
4676                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4677                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4678                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4679                let cmp = err!(
4680                    self.builder
4681                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4682                );
4683                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4684                let res = err!(
4685                    self.builder
4686                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4687                );
4688                self.state.push1(res);
4689            }
4690            Operator::I16x8MaxS => {
4691                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4692                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4693                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4694                let cmp = err!(
4695                    self.builder
4696                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4697                );
4698                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4699                let res = err!(
4700                    self.builder
4701                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4702                );
4703                self.state.push1(res);
4704            }
4705            Operator::I16x8MaxU => {
4706                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4707                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4708                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4709                let cmp = err!(
4710                    self.builder
4711                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4712                );
4713                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4714                let res = err!(
4715                    self.builder
4716                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4717                );
4718                self.state.push1(res);
4719            }
4720            Operator::I32x4MinS => {
4721                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4722                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4723                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4724                let cmp = err!(
4725                    self.builder
4726                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4727                );
4728                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4729                let res = err!(
4730                    self.builder
4731                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4732                );
4733                self.state.push1(res);
4734            }
4735            Operator::I32x4MinU => {
4736                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4737                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4738                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4739                let cmp = err!(
4740                    self.builder
4741                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4742                );
4743                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4744                let res = err!(
4745                    self.builder
4746                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4747                );
4748                self.state.push1(res);
4749            }
4750            Operator::I32x4MaxS => {
4751                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4752                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4753                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4754                let cmp = err!(
4755                    self.builder
4756                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4757                );
4758                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4759                let res = err!(
4760                    self.builder
4761                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4762                );
4763                self.state.push1(res);
4764            }
4765            Operator::I32x4MaxU => {
4766                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4767                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4768                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4769                let cmp = err!(
4770                    self.builder
4771                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4772                );
4773                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4774                let res = err!(
4775                    self.builder
4776                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4777                );
4778                self.state.push1(res);
4779            }
4780            Operator::I8x16AvgrU => {
4781                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4782                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4783                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4784
4785                // This approach is faster on x86-64 when the PAVG[BW]
4786                // instructions are available. On other platforms, an alternative
4787                // implementation appears likely to outperform, described here:
4788                //   %a = or %v1, %v2
4789                //   %b = and %a, 1
4790                //   %v1 = lshr %v1, 1
4791                //   %v2 = lshr %v2, 1
4792                //   %sum = add %v1, %v2
4793                //   %res = add %sum, %b
4794
4795                let ext_ty = self.intrinsics.i16_ty.vec_type(16);
4796                let one = self.intrinsics.i16_ty.const_int(1, false);
4797                let one = VectorType::const_vector(&[one; 16]);
4798
4799                let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4800                let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4801                let res = err!(self.builder.build_int_add(
4802                    err!(self.builder.build_int_add(one, v1, "")),
4803                    v2,
4804                    ""
4805                ));
4806                let res = err!(self.builder.build_right_shift(res, one, false, ""));
4807                let res = err!(
4808                    self.builder
4809                        .build_int_truncate(res, self.intrinsics.i8x16_ty, "")
4810                );
4811                let res = err!(
4812                    self.builder
4813                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4814                );
4815                self.state.push1(res);
4816            }
4817            Operator::I16x8AvgrU => {
4818                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4819                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4820                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4821
4822                // This approach is faster on x86-64 when the PAVG[BW]
4823                // instructions are available. On other platforms, an alternative
4824                // implementation appears likely to outperform, described here:
4825                //   %a = or %v1, %v2
4826                //   %b = and %a, 1
4827                //   %v1 = lshr %v1, 1
4828                //   %v2 = lshr %v2, 1
4829                //   %sum = add %v1, %v2
4830                //   %res = add %sum, %b
4831
4832                let ext_ty = self.intrinsics.i32_ty.vec_type(8);
4833                let one = self.intrinsics.i32_consts[1];
4834                let one = VectorType::const_vector(&[one; 8]);
4835
4836                let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4837                let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4838                let res = err!(self.builder.build_int_add(
4839                    err!(self.builder.build_int_add(one, v1, "")),
4840                    v2,
4841                    ""
4842                ));
4843                let res = err!(self.builder.build_right_shift(res, one, false, ""));
4844                let res = err!(
4845                    self.builder
4846                        .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
4847                );
4848                let res = err!(
4849                    self.builder
4850                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4851                );
4852                self.state.push1(res);
4853            }
4854
4855            /***************************
4856             * Floating-Point Arithmetic instructions.
4857             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-arithmetic-instructions
4858             ***************************/
4859            Operator::F32Add => {
4860                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4861                let res = err!(self.builder.build_call(
4862                    self.intrinsics.add_f32,
4863                    &[
4864                        v1.into(),
4865                        v2.into(),
4866                        self.intrinsics.fp_rounding_md,
4867                        self.intrinsics.fp_exception_md,
4868                    ],
4869                    "",
4870                ))
4871                .try_as_basic_value()
4872                .left()
4873                .unwrap();
4874                self.state.push1_extra(
4875                    res,
4876                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4877                );
4878            }
4879            Operator::F64Add => {
4880                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4881                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4882                let res = err!(self.builder.build_call(
4883                    self.intrinsics.add_f64,
4884                    &[
4885                        v1.into(),
4886                        v2.into(),
4887                        self.intrinsics.fp_rounding_md,
4888                        self.intrinsics.fp_exception_md,
4889                    ],
4890                    "",
4891                ))
4892                .try_as_basic_value()
4893                .left()
4894                .unwrap();
4895                self.state.push1_extra(
4896                    res,
4897                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4898                );
4899            }
4900            Operator::F32x4Add => {
4901                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4902                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4903                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4904                let res = err!(self.builder.build_call(
4905                    self.intrinsics.add_f32x4,
4906                    &[
4907                        v1.into(),
4908                        v2.into(),
4909                        self.intrinsics.fp_rounding_md,
4910                        self.intrinsics.fp_exception_md,
4911                    ],
4912                    "",
4913                ))
4914                .try_as_basic_value()
4915                .left()
4916                .unwrap();
4917                let res = err!(
4918                    self.builder
4919                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4920                );
4921                self.state.push1_extra(
4922                    res,
4923                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4924                );
4925            }
4926            Operator::F64x2Add => {
4927                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4928                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
4929                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
4930                let res = err!(self.builder.build_call(
4931                    self.intrinsics.add_f64x2,
4932                    &[
4933                        v1.into(),
4934                        v2.into(),
4935                        self.intrinsics.fp_rounding_md,
4936                        self.intrinsics.fp_exception_md,
4937                    ],
4938                    "",
4939                ))
4940                .try_as_basic_value()
4941                .left()
4942                .unwrap();
4943                let res = err!(
4944                    self.builder
4945                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4946                );
4947                self.state.push1_extra(
4948                    res,
4949                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4950                );
4951            }
4952            Operator::F32Sub => {
4953                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4954                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4955                let res = err!(self.builder.build_call(
4956                    self.intrinsics.sub_f32,
4957                    &[
4958                        v1.into(),
4959                        v2.into(),
4960                        self.intrinsics.fp_rounding_md,
4961                        self.intrinsics.fp_exception_md,
4962                    ],
4963                    "",
4964                ))
4965                .try_as_basic_value()
4966                .left()
4967                .unwrap();
4968                self.state.push1_extra(
4969                    res,
4970                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4971                );
4972            }
4973            Operator::F64Sub => {
4974                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4975                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4976                let res = err!(self.builder.build_call(
4977                    self.intrinsics.sub_f64,
4978                    &[
4979                        v1.into(),
4980                        v2.into(),
4981                        self.intrinsics.fp_rounding_md,
4982                        self.intrinsics.fp_exception_md,
4983                    ],
4984                    "",
4985                ))
4986                .try_as_basic_value()
4987                .left()
4988                .unwrap();
4989                self.state.push1_extra(
4990                    res,
4991                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4992                );
4993            }
4994            Operator::F32x4Sub => {
4995                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4996                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4997                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4998                let res = err!(self.builder.build_call(
4999                    self.intrinsics.sub_f32x4,
5000                    &[
5001                        v1.into(),
5002                        v2.into(),
5003                        self.intrinsics.fp_rounding_md,
5004                        self.intrinsics.fp_exception_md,
5005                    ],
5006                    "",
5007                ))
5008                .try_as_basic_value()
5009                .left()
5010                .unwrap();
5011                let res = err!(
5012                    self.builder
5013                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5014                );
5015                self.state.push1_extra(
5016                    res,
5017                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5018                );
5019            }
5020            Operator::F64x2Sub => {
5021                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5022                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5023                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5024                let res = err!(self.builder.build_call(
5025                    self.intrinsics.sub_f64x2,
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                .left()
5036                .unwrap();
5037                let res = err!(
5038                    self.builder
5039                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5040                );
5041                self.state.push1_extra(
5042                    res,
5043                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5044                );
5045            }
5046            Operator::F32Mul => {
5047                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5048                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5049                let res = err!(self.builder.build_call(
5050                    self.intrinsics.mul_f32,
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                .left()
5061                .unwrap();
5062                self.state.push1_extra(
5063                    res,
5064                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5065                );
5066            }
5067            Operator::F64Mul => {
5068                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5069                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5070                let res = err!(self.builder.build_call(
5071                    self.intrinsics.mul_f64,
5072                    &[
5073                        v1.into(),
5074                        v2.into(),
5075                        self.intrinsics.fp_rounding_md,
5076                        self.intrinsics.fp_exception_md,
5077                    ],
5078                    "",
5079                ))
5080                .try_as_basic_value()
5081                .left()
5082                .unwrap();
5083                self.state.push1_extra(
5084                    res,
5085                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5086                );
5087            }
5088            Operator::F32x4Mul => {
5089                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5090                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5091                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5092                let res = err!(self.builder.build_call(
5093                    self.intrinsics.mul_f32x4,
5094                    &[
5095                        v1.into(),
5096                        v2.into(),
5097                        self.intrinsics.fp_rounding_md,
5098                        self.intrinsics.fp_exception_md,
5099                    ],
5100                    "",
5101                ))
5102                .try_as_basic_value()
5103                .left()
5104                .unwrap();
5105                let res = err!(
5106                    self.builder
5107                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5108                );
5109                self.state.push1_extra(
5110                    res,
5111                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5112                );
5113            }
5114            Operator::F64x2Mul => {
5115                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5116                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5117                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5118                let res = err!(self.builder.build_call(
5119                    self.intrinsics.mul_f64x2,
5120                    &[
5121                        v1.into(),
5122                        v2.into(),
5123                        self.intrinsics.fp_rounding_md,
5124                        self.intrinsics.fp_exception_md,
5125                    ],
5126                    "",
5127                ))
5128                .try_as_basic_value()
5129                .left()
5130                .unwrap();
5131                let res = err!(
5132                    self.builder
5133                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5134                );
5135                self.state.push1_extra(
5136                    res,
5137                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5138                );
5139            }
5140            Operator::F32Div => {
5141                let (v1, v2) = self.state.pop2()?;
5142                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5143                let res = err!(self.builder.build_call(
5144                    self.intrinsics.div_f32,
5145                    &[
5146                        v1.into(),
5147                        v2.into(),
5148                        self.intrinsics.fp_rounding_md,
5149                        self.intrinsics.fp_exception_md,
5150                    ],
5151                    "",
5152                ))
5153                .try_as_basic_value()
5154                .left()
5155                .unwrap();
5156                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5157            }
5158            Operator::F64Div => {
5159                let (v1, v2) = self.state.pop2()?;
5160                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5161                let res = err!(self.builder.build_call(
5162                    self.intrinsics.div_f64,
5163                    &[
5164                        v1.into(),
5165                        v2.into(),
5166                        self.intrinsics.fp_rounding_md,
5167                        self.intrinsics.fp_exception_md,
5168                    ],
5169                    "",
5170                ))
5171                .try_as_basic_value()
5172                .left()
5173                .unwrap();
5174                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5175            }
5176            Operator::F32x4Div => {
5177                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5178                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5179                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5180                let res = err!(self.builder.build_call(
5181                    self.intrinsics.div_f32x4,
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                .left()
5192                .unwrap();
5193                let res = err!(
5194                    self.builder
5195                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5196                );
5197                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5198            }
5199            Operator::F64x2Div => {
5200                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5201                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5202                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5203                let res = err!(self.builder.build_call(
5204                    self.intrinsics.div_f64x2,
5205                    &[
5206                        v1.into(),
5207                        v2.into(),
5208                        self.intrinsics.fp_rounding_md,
5209                        self.intrinsics.fp_exception_md,
5210                    ],
5211                    "",
5212                ))
5213                .try_as_basic_value()
5214                .left()
5215                .unwrap();
5216                let res = err!(
5217                    self.builder
5218                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5219                );
5220                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5221            }
5222            Operator::F32Sqrt => {
5223                let input = self.state.pop1()?;
5224                let res = err!(self.builder.build_call(
5225                    self.intrinsics.sqrt_f32,
5226                    &[input.into()],
5227                    ""
5228                ))
5229                .try_as_basic_value()
5230                .left()
5231                .unwrap();
5232                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5233            }
5234            Operator::F64Sqrt => {
5235                let input = self.state.pop1()?;
5236                let res = err!(self.builder.build_call(
5237                    self.intrinsics.sqrt_f64,
5238                    &[input.into()],
5239                    ""
5240                ))
5241                .try_as_basic_value()
5242                .left()
5243                .unwrap();
5244                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5245            }
5246            Operator::F32x4Sqrt => {
5247                let (v, i) = self.state.pop1_extra()?;
5248                let (v, _) = self.v128_into_f32x4(v, i)?;
5249                let res = err!(self.builder.build_call(
5250                    self.intrinsics.sqrt_f32x4,
5251                    &[v.into()],
5252                    ""
5253                ))
5254                .try_as_basic_value()
5255                .left()
5256                .unwrap();
5257                let bits = err!(
5258                    self.builder
5259                        .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5260                );
5261                self.state.push1_extra(bits, ExtraInfo::pending_f32_nan());
5262            }
5263            Operator::F64x2Sqrt => {
5264                let (v, i) = self.state.pop1_extra()?;
5265                let (v, _) = self.v128_into_f64x2(v, i)?;
5266                let res = err!(self.builder.build_call(
5267                    self.intrinsics.sqrt_f64x2,
5268                    &[v.into()],
5269                    ""
5270                ))
5271                .try_as_basic_value()
5272                .left()
5273                .unwrap();
5274                let bits = err!(
5275                    self.builder
5276                        .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5277                );
5278                self.state.push1(bits);
5279            }
5280            Operator::F32Min => {
5281                // This implements the same logic as LLVM's @llvm.minimum
5282                // intrinsic would, but x86 lowering of that intrinsic
5283                // encounters a fatal error in LLVM 11.
5284                let (v1, v2) = self.state.pop2()?;
5285                let v1 = self.canonicalize_nans(v1)?;
5286                let v2 = self.canonicalize_nans(v2)?;
5287
5288                let v1_is_nan = err!(self.builder.build_call(
5289                    self.intrinsics.cmp_f32,
5290                    &[
5291                        v1.into(),
5292                        self.intrinsics.f32_zero.into(),
5293                        self.intrinsics.fp_uno_md,
5294                        self.intrinsics.fp_exception_md,
5295                    ],
5296                    "",
5297                ))
5298                .try_as_basic_value()
5299                .left()
5300                .unwrap()
5301                .into_int_value();
5302                let v2_is_nan = err!(self.builder.build_call(
5303                    self.intrinsics.cmp_f32,
5304                    &[
5305                        v2.into(),
5306                        self.intrinsics.f32_zero.into(),
5307                        self.intrinsics.fp_uno_md,
5308                        self.intrinsics.fp_exception_md,
5309                    ],
5310                    "",
5311                ))
5312                .try_as_basic_value()
5313                .left()
5314                .unwrap()
5315                .into_int_value();
5316                let v1_lt_v2 = err!(self.builder.build_call(
5317                    self.intrinsics.cmp_f32,
5318                    &[
5319                        v1.into(),
5320                        v2.into(),
5321                        self.intrinsics.fp_olt_md,
5322                        self.intrinsics.fp_exception_md,
5323                    ],
5324                    "",
5325                ))
5326                .try_as_basic_value()
5327                .left()
5328                .unwrap()
5329                .into_int_value();
5330                let v1_gt_v2 = err!(self.builder.build_call(
5331                    self.intrinsics.cmp_f32,
5332                    &[
5333                        v1.into(),
5334                        v2.into(),
5335                        self.intrinsics.fp_ogt_md,
5336                        self.intrinsics.fp_exception_md,
5337                    ],
5338                    "",
5339                ))
5340                .try_as_basic_value()
5341                .left()
5342                .unwrap()
5343                .into_int_value();
5344
5345                let res = err!(self.builder.build_select(
5346                    v1_is_nan,
5347                    self.quiet_nan(v1)?,
5348                    err!(self.builder.build_select(
5349                        v2_is_nan,
5350                        self.quiet_nan(v2)?,
5351                        err!(self.builder.build_select(
5352                            v1_lt_v2,
5353                            v1,
5354                            err!(self.builder.build_select(
5355                                v1_gt_v2,
5356                                v2,
5357                                err!(self.builder.build_bit_cast(
5358                                    err!(self.builder.build_or(
5359                                        err!(self.builder.build_bit_cast(
5360                                            v1,
5361                                            self.intrinsics.i32_ty,
5362                                            ""
5363                                        ))
5364                                        .into_int_value(),
5365                                        err!(self.builder.build_bit_cast(
5366                                            v2,
5367                                            self.intrinsics.i32_ty,
5368                                            ""
5369                                        ))
5370                                        .into_int_value(),
5371                                        "",
5372                                    )),
5373                                    self.intrinsics.f32_ty,
5374                                    "",
5375                                )),
5376                                "",
5377                            )),
5378                            "",
5379                        )),
5380                        "",
5381                    )),
5382                    "",
5383                ));
5384
5385                self.state.push1(res);
5386            }
5387            Operator::F64Min => {
5388                // This implements the same logic as LLVM's @llvm.minimum
5389                // intrinsic would, but x86 lowering of that intrinsic
5390                // encounters a fatal error in LLVM 11.
5391                let (v1, v2) = self.state.pop2()?;
5392                let v1 = self.canonicalize_nans(v1)?;
5393                let v2 = self.canonicalize_nans(v2)?;
5394
5395                let v1_is_nan = err!(self.builder.build_call(
5396                    self.intrinsics.cmp_f64,
5397                    &[
5398                        v1.into(),
5399                        self.intrinsics.f64_zero.into(),
5400                        self.intrinsics.fp_uno_md,
5401                        self.intrinsics.fp_exception_md,
5402                    ],
5403                    "",
5404                ))
5405                .try_as_basic_value()
5406                .left()
5407                .unwrap()
5408                .into_int_value();
5409                let v2_is_nan = err!(self.builder.build_call(
5410                    self.intrinsics.cmp_f64,
5411                    &[
5412                        v2.into(),
5413                        self.intrinsics.f64_zero.into(),
5414                        self.intrinsics.fp_uno_md,
5415                        self.intrinsics.fp_exception_md,
5416                    ],
5417                    "",
5418                ))
5419                .try_as_basic_value()
5420                .left()
5421                .unwrap()
5422                .into_int_value();
5423                let v1_lt_v2 = err!(self.builder.build_call(
5424                    self.intrinsics.cmp_f64,
5425                    &[
5426                        v1.into(),
5427                        v2.into(),
5428                        self.intrinsics.fp_olt_md,
5429                        self.intrinsics.fp_exception_md,
5430                    ],
5431                    "",
5432                ))
5433                .try_as_basic_value()
5434                .left()
5435                .unwrap()
5436                .into_int_value();
5437                let v1_gt_v2 = err!(self.builder.build_call(
5438                    self.intrinsics.cmp_f64,
5439                    &[
5440                        v1.into(),
5441                        v2.into(),
5442                        self.intrinsics.fp_ogt_md,
5443                        self.intrinsics.fp_exception_md,
5444                    ],
5445                    "",
5446                ))
5447                .try_as_basic_value()
5448                .left()
5449                .unwrap()
5450                .into_int_value();
5451
5452                let res = err!(self.builder.build_select(
5453                    v1_is_nan,
5454                    self.quiet_nan(v1)?,
5455                    err!(self.builder.build_select(
5456                        v2_is_nan,
5457                        self.quiet_nan(v2)?,
5458                        err!(self.builder.build_select(
5459                            v1_lt_v2,
5460                            v1,
5461                            err!(self.builder.build_select(
5462                                v1_gt_v2,
5463                                v2,
5464                                err!(self.builder.build_bit_cast(
5465                                    err!(self.builder.build_or(
5466                                        err!(self.builder.build_bit_cast(
5467                                            v1,
5468                                            self.intrinsics.i64_ty,
5469                                            ""
5470                                        ))
5471                                        .into_int_value(),
5472                                        err!(self.builder.build_bit_cast(
5473                                            v2,
5474                                            self.intrinsics.i64_ty,
5475                                            ""
5476                                        ))
5477                                        .into_int_value(),
5478                                        "",
5479                                    )),
5480                                    self.intrinsics.f64_ty,
5481                                    "",
5482                                )),
5483                                "",
5484                            )),
5485                            "",
5486                        )),
5487                        "",
5488                    )),
5489                    "",
5490                ));
5491
5492                self.state.push1(res);
5493            }
5494            Operator::F32x4Min => {
5495                // This implements the same logic as LLVM's @llvm.minimum
5496                // intrinsic would, but x86 lowering of that intrinsic
5497                // encounters a fatal error in LLVM 11.
5498                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5499                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5500                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5501
5502                let v1_is_nan = err!(self.builder.build_call(
5503                    self.intrinsics.cmp_f32x4,
5504                    &[
5505                        v1.into(),
5506                        self.intrinsics.f32x4_zero.into(),
5507                        self.intrinsics.fp_uno_md,
5508                        self.intrinsics.fp_exception_md,
5509                    ],
5510                    "",
5511                ))
5512                .try_as_basic_value()
5513                .left()
5514                .unwrap()
5515                .into_vector_value();
5516                let v2_is_nan = err!(self.builder.build_call(
5517                    self.intrinsics.cmp_f32x4,
5518                    &[
5519                        v2.into(),
5520                        self.intrinsics.f32x4_zero.into(),
5521                        self.intrinsics.fp_uno_md,
5522                        self.intrinsics.fp_exception_md,
5523                    ],
5524                    "",
5525                ))
5526                .try_as_basic_value()
5527                .left()
5528                .unwrap()
5529                .into_vector_value();
5530                let v1_lt_v2 = err!(self.builder.build_call(
5531                    self.intrinsics.cmp_f32x4,
5532                    &[
5533                        v1.into(),
5534                        v2.into(),
5535                        self.intrinsics.fp_olt_md,
5536                        self.intrinsics.fp_exception_md,
5537                    ],
5538                    "",
5539                ))
5540                .try_as_basic_value()
5541                .left()
5542                .unwrap()
5543                .into_vector_value();
5544                let v1_gt_v2 = err!(self.builder.build_call(
5545                    self.intrinsics.cmp_f32x4,
5546                    &[
5547                        v1.into(),
5548                        v2.into(),
5549                        self.intrinsics.fp_ogt_md,
5550                        self.intrinsics.fp_exception_md,
5551                    ],
5552                    "",
5553                ))
5554                .try_as_basic_value()
5555                .left()
5556                .unwrap()
5557                .into_vector_value();
5558
5559                let res = err!(
5560                    self.builder.build_select(
5561                        v1_is_nan,
5562                        self.quiet_nan(v1.into())?.into_vector_value(),
5563                        err!(
5564                            self.builder.build_select(
5565                                v2_is_nan,
5566                                self.quiet_nan(v2.into())?.into_vector_value(),
5567                                err!(self.builder.build_select(
5568                                    v1_lt_v2,
5569                                    v1.into(),
5570                                    err!(self.builder.build_select(
5571                                        v1_gt_v2,
5572                                        v2.into(),
5573                                        err!(self.builder.build_bit_cast(
5574                                            err!(self.builder.build_or(
5575                                        err!(self.builder.build_bit_cast(
5576                                            v1,
5577                                            self.intrinsics.i32x4_ty,
5578                                            "",
5579                                        ))
5580                                        .into_vector_value(),
5581                                        err!(self.builder.build_bit_cast(
5582                                            v2,
5583                                            self.intrinsics.i32x4_ty,
5584                                            "",
5585                                        ))
5586                                        .into_vector_value(),
5587                                        "",
5588                                    )),
5589                                            self.intrinsics.f32x4_ty,
5590                                            "",
5591                                        )),
5592                                        "",
5593                                    )),
5594                                    "",
5595                                ))
5596                                .into_vector_value(),
5597                                "",
5598                            )
5599                        )
5600                        .into_vector_value(),
5601                        "",
5602                    )
5603                );
5604
5605                let res = err!(
5606                    self.builder
5607                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5608                );
5609                self.state.push1(res);
5610            }
5611            Operator::F32x4PMin => {
5612                // Pseudo-min: b < a ? b : a
5613                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5614                let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5615                let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5616                let cmp = err!(
5617                    self.builder
5618                        .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5619                );
5620                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5621                let res = err!(
5622                    self.builder
5623                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5624                );
5625                self.state.push1(res);
5626            }
5627            Operator::F64x2Min => {
5628                // This implements the same logic as LLVM's @llvm.minimum
5629                // intrinsic would, but x86 lowering of that intrinsic
5630                // encounters a fatal error in LLVM 11.
5631                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5632                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5633                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5634
5635                let v1_is_nan = err!(self.builder.build_call(
5636                    self.intrinsics.cmp_f64x2,
5637                    &[
5638                        v1.into(),
5639                        self.intrinsics.f64x2_zero.into(),
5640                        self.intrinsics.fp_uno_md,
5641                        self.intrinsics.fp_exception_md,
5642                    ],
5643                    "",
5644                ))
5645                .try_as_basic_value()
5646                .left()
5647                .unwrap()
5648                .into_vector_value();
5649                let v2_is_nan = err!(self.builder.build_call(
5650                    self.intrinsics.cmp_f64x2,
5651                    &[
5652                        v2.into(),
5653                        self.intrinsics.f64x2_zero.into(),
5654                        self.intrinsics.fp_uno_md,
5655                        self.intrinsics.fp_exception_md,
5656                    ],
5657                    "",
5658                ))
5659                .try_as_basic_value()
5660                .left()
5661                .unwrap()
5662                .into_vector_value();
5663                let v1_lt_v2 = err!(self.builder.build_call(
5664                    self.intrinsics.cmp_f64x2,
5665                    &[
5666                        v1.into(),
5667                        v2.into(),
5668                        self.intrinsics.fp_olt_md,
5669                        self.intrinsics.fp_exception_md,
5670                    ],
5671                    "",
5672                ))
5673                .try_as_basic_value()
5674                .left()
5675                .unwrap()
5676                .into_vector_value();
5677                let v1_gt_v2 = err!(self.builder.build_call(
5678                    self.intrinsics.cmp_f64x2,
5679                    &[
5680                        v1.into(),
5681                        v2.into(),
5682                        self.intrinsics.fp_ogt_md,
5683                        self.intrinsics.fp_exception_md,
5684                    ],
5685                    "",
5686                ))
5687                .try_as_basic_value()
5688                .left()
5689                .unwrap()
5690                .into_vector_value();
5691
5692                let res = err!(
5693                    self.builder.build_select(
5694                        v1_is_nan,
5695                        self.quiet_nan(v1.into())?.into_vector_value(),
5696                        err!(
5697                            self.builder.build_select(
5698                                v2_is_nan,
5699                                self.quiet_nan(v2.into())?.into_vector_value(),
5700                                err!(self.builder.build_select(
5701                                    v1_lt_v2,
5702                                    v1.into(),
5703                                    err!(self.builder.build_select(
5704                                        v1_gt_v2,
5705                                        v2.into(),
5706                                        err!(self.builder.build_bit_cast(
5707                                            err!(self.builder.build_or(
5708                                        err!(self.builder.build_bit_cast(
5709                                            v1,
5710                                            self.intrinsics.i64x2_ty,
5711                                            "",
5712                                        ))
5713                                        .into_vector_value(),
5714                                        err!(self.builder.build_bit_cast(
5715                                            v2,
5716                                            self.intrinsics.i64x2_ty,
5717                                            "",
5718                                        ))
5719                                        .into_vector_value(),
5720                                        "",
5721                                    )),
5722                                            self.intrinsics.f64x2_ty,
5723                                            "",
5724                                        )),
5725                                        "",
5726                                    )),
5727                                    "",
5728                                ))
5729                                .into_vector_value(),
5730                                "",
5731                            )
5732                        )
5733                        .into_vector_value(),
5734                        "",
5735                    )
5736                );
5737
5738                let res = err!(
5739                    self.builder
5740                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5741                );
5742                self.state.push1(res);
5743            }
5744            Operator::F64x2PMin => {
5745                // Pseudo-min: b < a ? b : a
5746                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5747                let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5748                let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5749                let cmp = err!(
5750                    self.builder
5751                        .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5752                );
5753                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5754                let res = err!(
5755                    self.builder
5756                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5757                );
5758                self.state.push1(res);
5759            }
5760            Operator::F32Max => {
5761                // This implements the same logic as LLVM's @llvm.maximum
5762                // intrinsic would, but x86 lowering of that intrinsic
5763                // encounters a fatal error in LLVM 11.
5764                let (v1, v2) = self.state.pop2()?;
5765                let v1 = self.canonicalize_nans(v1)?;
5766                let v2 = self.canonicalize_nans(v2)?;
5767
5768                let v1_is_nan = err!(self.builder.build_call(
5769                    self.intrinsics.cmp_f32,
5770                    &[
5771                        v1.into(),
5772                        self.intrinsics.f32_zero.into(),
5773                        self.intrinsics.fp_uno_md,
5774                        self.intrinsics.fp_exception_md,
5775                    ],
5776                    "",
5777                ))
5778                .try_as_basic_value()
5779                .left()
5780                .unwrap()
5781                .into_int_value();
5782                let v2_is_nan = err!(self.builder.build_call(
5783                    self.intrinsics.cmp_f32,
5784                    &[
5785                        v2.into(),
5786                        self.intrinsics.f32_zero.into(),
5787                        self.intrinsics.fp_uno_md,
5788                        self.intrinsics.fp_exception_md,
5789                    ],
5790                    "",
5791                ))
5792                .try_as_basic_value()
5793                .left()
5794                .unwrap()
5795                .into_int_value();
5796                let v1_lt_v2 = err!(self.builder.build_call(
5797                    self.intrinsics.cmp_f32,
5798                    &[
5799                        v1.into(),
5800                        v2.into(),
5801                        self.intrinsics.fp_olt_md,
5802                        self.intrinsics.fp_exception_md,
5803                    ],
5804                    "",
5805                ))
5806                .try_as_basic_value()
5807                .left()
5808                .unwrap()
5809                .into_int_value();
5810                let v1_gt_v2 = err!(self.builder.build_call(
5811                    self.intrinsics.cmp_f32,
5812                    &[
5813                        v1.into(),
5814                        v2.into(),
5815                        self.intrinsics.fp_ogt_md,
5816                        self.intrinsics.fp_exception_md,
5817                    ],
5818                    "",
5819                ))
5820                .try_as_basic_value()
5821                .left()
5822                .unwrap()
5823                .into_int_value();
5824
5825                let res = err!(self.builder.build_select(
5826                    v1_is_nan,
5827                    self.quiet_nan(v1)?,
5828                    err!(self.builder.build_select(
5829                        v2_is_nan,
5830                        self.quiet_nan(v2)?,
5831                        err!(self.builder.build_select(
5832                            v1_lt_v2,
5833                            v2,
5834                            err!(self.builder.build_select(
5835                                v1_gt_v2,
5836                                v1,
5837                                err!(self.builder.build_bit_cast(
5838                                    err!(self.builder.build_and(
5839                                        err!(self.builder.build_bit_cast(
5840                                            v1,
5841                                            self.intrinsics.i32_ty,
5842                                            ""
5843                                        ))
5844                                        .into_int_value(),
5845                                        err!(self.builder.build_bit_cast(
5846                                            v2,
5847                                            self.intrinsics.i32_ty,
5848                                            ""
5849                                        ))
5850                                        .into_int_value(),
5851                                        "",
5852                                    )),
5853                                    self.intrinsics.f32_ty,
5854                                    "",
5855                                )),
5856                                "",
5857                            )),
5858                            "",
5859                        )),
5860                        "",
5861                    )),
5862                    "",
5863                ));
5864
5865                self.state.push1(res);
5866            }
5867            Operator::F64Max => {
5868                // This implements the same logic as LLVM's @llvm.maximum
5869                // intrinsic would, but x86 lowering of that intrinsic
5870                // encounters a fatal error in LLVM 11.
5871                let (v1, v2) = self.state.pop2()?;
5872                let v1 = self.canonicalize_nans(v1)?;
5873                let v2 = self.canonicalize_nans(v2)?;
5874
5875                let v1_is_nan = err!(self.builder.build_call(
5876                    self.intrinsics.cmp_f64,
5877                    &[
5878                        v1.into(),
5879                        self.intrinsics.f64_zero.into(),
5880                        self.intrinsics.fp_uno_md,
5881                        self.intrinsics.fp_exception_md,
5882                    ],
5883                    "",
5884                ))
5885                .try_as_basic_value()
5886                .left()
5887                .unwrap()
5888                .into_int_value();
5889                let v2_is_nan = err!(self.builder.build_call(
5890                    self.intrinsics.cmp_f64,
5891                    &[
5892                        v2.into(),
5893                        self.intrinsics.f64_zero.into(),
5894                        self.intrinsics.fp_uno_md,
5895                        self.intrinsics.fp_exception_md,
5896                    ],
5897                    "",
5898                ))
5899                .try_as_basic_value()
5900                .left()
5901                .unwrap()
5902                .into_int_value();
5903                let v1_lt_v2 = err!(self.builder.build_call(
5904                    self.intrinsics.cmp_f64,
5905                    &[
5906                        v1.into(),
5907                        v2.into(),
5908                        self.intrinsics.fp_olt_md,
5909                        self.intrinsics.fp_exception_md,
5910                    ],
5911                    "",
5912                ))
5913                .try_as_basic_value()
5914                .left()
5915                .unwrap()
5916                .into_int_value();
5917                let v1_gt_v2 = err!(self.builder.build_call(
5918                    self.intrinsics.cmp_f64,
5919                    &[
5920                        v1.into(),
5921                        v2.into(),
5922                        self.intrinsics.fp_ogt_md,
5923                        self.intrinsics.fp_exception_md,
5924                    ],
5925                    "",
5926                ))
5927                .try_as_basic_value()
5928                .left()
5929                .unwrap()
5930                .into_int_value();
5931
5932                let res = err!(self.builder.build_select(
5933                    v1_is_nan,
5934                    self.quiet_nan(v1)?,
5935                    err!(self.builder.build_select(
5936                        v2_is_nan,
5937                        self.quiet_nan(v2)?,
5938                        err!(self.builder.build_select(
5939                            v1_lt_v2,
5940                            v2,
5941                            err!(self.builder.build_select(
5942                                v1_gt_v2,
5943                                v1,
5944                                err!(self.builder.build_bit_cast(
5945                                    err!(self.builder.build_and(
5946                                        err!(self.builder.build_bit_cast(
5947                                            v1,
5948                                            self.intrinsics.i64_ty,
5949                                            ""
5950                                        ))
5951                                        .into_int_value(),
5952                                        err!(self.builder.build_bit_cast(
5953                                            v2,
5954                                            self.intrinsics.i64_ty,
5955                                            ""
5956                                        ))
5957                                        .into_int_value(),
5958                                        "",
5959                                    )),
5960                                    self.intrinsics.f64_ty,
5961                                    "",
5962                                )),
5963                                "",
5964                            )),
5965                            "",
5966                        )),
5967                        "",
5968                    )),
5969                    "",
5970                ));
5971
5972                self.state.push1(res);
5973            }
5974            Operator::F32x4Max => {
5975                // This implements the same logic as LLVM's @llvm.maximum
5976                // intrinsic would, but x86 lowering of that intrinsic
5977                // encounters a fatal error in LLVM 11.
5978                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5979                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5980                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5981
5982                let v1_is_nan = err!(self.builder.build_call(
5983                    self.intrinsics.cmp_f32x4,
5984                    &[
5985                        v1.into(),
5986                        self.intrinsics.f32x4_zero.into(),
5987                        self.intrinsics.fp_uno_md,
5988                        self.intrinsics.fp_exception_md,
5989                    ],
5990                    "",
5991                ))
5992                .try_as_basic_value()
5993                .left()
5994                .unwrap()
5995                .into_vector_value();
5996                let v2_is_nan = err!(self.builder.build_call(
5997                    self.intrinsics.cmp_f32x4,
5998                    &[
5999                        v2.into(),
6000                        self.intrinsics.f32x4_zero.into(),
6001                        self.intrinsics.fp_uno_md,
6002                        self.intrinsics.fp_exception_md,
6003                    ],
6004                    "",
6005                ))
6006                .try_as_basic_value()
6007                .left()
6008                .unwrap()
6009                .into_vector_value();
6010                let v1_lt_v2 = err!(self.builder.build_call(
6011                    self.intrinsics.cmp_f32x4,
6012                    &[
6013                        v1.into(),
6014                        v2.into(),
6015                        self.intrinsics.fp_olt_md,
6016                        self.intrinsics.fp_exception_md,
6017                    ],
6018                    "",
6019                ))
6020                .try_as_basic_value()
6021                .left()
6022                .unwrap()
6023                .into_vector_value();
6024                let v1_gt_v2 = err!(self.builder.build_call(
6025                    self.intrinsics.cmp_f32x4,
6026                    &[
6027                        v1.into(),
6028                        v2.into(),
6029                        self.intrinsics.fp_ogt_md,
6030                        self.intrinsics.fp_exception_md,
6031                    ],
6032                    "",
6033                ))
6034                .try_as_basic_value()
6035                .left()
6036                .unwrap()
6037                .into_vector_value();
6038
6039                let res = err!(
6040                    self.builder.build_select(
6041                        v1_is_nan,
6042                        self.quiet_nan(v1.into())?.into_vector_value(),
6043                        err!(
6044                            self.builder.build_select(
6045                                v2_is_nan,
6046                                self.quiet_nan(v2.into())?.into_vector_value(),
6047                                err!(self.builder.build_select(
6048                                    v1_lt_v2,
6049                                    v2.into(),
6050                                    err!(self.builder.build_select(
6051                                        v1_gt_v2,
6052                                        v1.into(),
6053                                        err!(self.builder.build_bit_cast(
6054                                            err!(self.builder.build_and(
6055                                        err!(self.builder.build_bit_cast(
6056                                            v1,
6057                                            self.intrinsics.i32x4_ty,
6058                                            "",
6059                                        ))
6060                                        .into_vector_value(),
6061                                        err!(self.builder.build_bit_cast(
6062                                            v2,
6063                                            self.intrinsics.i32x4_ty,
6064                                            "",
6065                                        ))
6066                                        .into_vector_value(),
6067                                        "",
6068                                    )),
6069                                            self.intrinsics.f32x4_ty,
6070                                            "",
6071                                        )),
6072                                        "",
6073                                    )),
6074                                    "",
6075                                ))
6076                                .into_vector_value(),
6077                                "",
6078                            )
6079                        )
6080                        .into_vector_value(),
6081                        "",
6082                    )
6083                );
6084
6085                let res = err!(
6086                    self.builder
6087                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6088                );
6089                self.state.push1(res);
6090            }
6091            Operator::F32x4PMax => {
6092                // Pseudo-max: a < b ? b : a
6093                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6094                let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
6095                let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
6096                let cmp = err!(
6097                    self.builder
6098                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6099                );
6100                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
6101
6102                let res = err!(
6103                    self.builder
6104                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6105                );
6106                self.state.push1(res);
6107            }
6108            Operator::F64x2Max => {
6109                // This implements the same logic as LLVM's @llvm.maximum
6110                // intrinsic would, but x86 lowering of that intrinsic
6111                // encounters a fatal error in LLVM 11.
6112                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6113                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6114                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6115
6116                let v1_is_nan = err!(self.builder.build_call(
6117                    self.intrinsics.cmp_f64x2,
6118                    &[
6119                        v1.into(),
6120                        self.intrinsics.f64x2_zero.into(),
6121                        self.intrinsics.fp_uno_md,
6122                        self.intrinsics.fp_exception_md,
6123                    ],
6124                    "",
6125                ))
6126                .try_as_basic_value()
6127                .left()
6128                .unwrap()
6129                .into_vector_value();
6130                let v2_is_nan = err!(self.builder.build_call(
6131                    self.intrinsics.cmp_f64x2,
6132                    &[
6133                        v2.into(),
6134                        self.intrinsics.f64x2_zero.into(),
6135                        self.intrinsics.fp_uno_md,
6136                        self.intrinsics.fp_exception_md,
6137                    ],
6138                    "",
6139                ))
6140                .try_as_basic_value()
6141                .left()
6142                .unwrap()
6143                .into_vector_value();
6144                let v1_lt_v2 = err!(self.builder.build_call(
6145                    self.intrinsics.cmp_f64x2,
6146                    &[
6147                        v1.into(),
6148                        v2.into(),
6149                        self.intrinsics.fp_olt_md,
6150                        self.intrinsics.fp_exception_md,
6151                    ],
6152                    "",
6153                ))
6154                .try_as_basic_value()
6155                .left()
6156                .unwrap()
6157                .into_vector_value();
6158                let v1_gt_v2 = err!(self.builder.build_call(
6159                    self.intrinsics.cmp_f64x2,
6160                    &[
6161                        v1.into(),
6162                        v2.into(),
6163                        self.intrinsics.fp_ogt_md,
6164                        self.intrinsics.fp_exception_md,
6165                    ],
6166                    "",
6167                ))
6168                .try_as_basic_value()
6169                .left()
6170                .unwrap()
6171                .into_vector_value();
6172
6173                let res = err!(
6174                    self.builder.build_select(
6175                        v1_is_nan,
6176                        self.quiet_nan(v1.into())?.into_vector_value(),
6177                        err!(
6178                            self.builder.build_select(
6179                                v2_is_nan,
6180                                self.quiet_nan(v2.into())?.into_vector_value(),
6181                                err!(self.builder.build_select(
6182                                    v1_lt_v2,
6183                                    v2.into(),
6184                                    err!(self.builder.build_select(
6185                                        v1_gt_v2,
6186                                        v1.into(),
6187                                        err!(self.builder.build_bit_cast(
6188                                            err!(self.builder.build_and(
6189                                        err!(self.builder.build_bit_cast(
6190                                            v1,
6191                                            self.intrinsics.i64x2_ty,
6192                                            "",
6193                                        ))
6194                                        .into_vector_value(),
6195                                        err!(self.builder.build_bit_cast(
6196                                            v2,
6197                                            self.intrinsics.i64x2_ty,
6198                                            "",
6199                                        ))
6200                                        .into_vector_value(),
6201                                        "",
6202                                    )),
6203                                            self.intrinsics.f64x2_ty,
6204                                            "",
6205                                        )),
6206                                        "",
6207                                    )),
6208                                    "",
6209                                ))
6210                                .into_vector_value(),
6211                                "",
6212                            )
6213                        )
6214                        .into_vector_value(),
6215                        "",
6216                    )
6217                );
6218
6219                let res = err!(
6220                    self.builder
6221                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6222                );
6223                self.state.push1(res);
6224            }
6225            Operator::F64x2PMax => {
6226                // Pseudo-max: a < b ? b : a
6227                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6228                let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
6229                let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
6230                let cmp = err!(
6231                    self.builder
6232                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6233                );
6234                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
6235                let res = err!(
6236                    self.builder
6237                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6238                );
6239                self.state.push1(res);
6240            }
6241            Operator::F32Ceil => {
6242                let (input, info) = self.state.pop1_extra()?;
6243                let res = err!(self.builder.build_call(
6244                    self.intrinsics.ceil_f32,
6245                    &[input.into()],
6246                    ""
6247                ))
6248                .try_as_basic_value()
6249                .left()
6250                .unwrap();
6251                self.state
6252                    .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
6253            }
6254            Operator::F32x4Ceil => {
6255                let (v, i) = self.state.pop1_extra()?;
6256                let (v, _) = self.v128_into_f32x4(v, i)?;
6257                let res = err!(self.builder.build_call(
6258                    self.intrinsics.ceil_f32x4,
6259                    &[v.into()],
6260                    ""
6261                ))
6262                .try_as_basic_value()
6263                .left()
6264                .unwrap();
6265                let res = err!(
6266                    self.builder
6267                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6268                );
6269                self.state
6270                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6271            }
6272            Operator::F64Ceil => {
6273                let (input, info) = self.state.pop1_extra()?;
6274                let res = err!(self.builder.build_call(
6275                    self.intrinsics.ceil_f64,
6276                    &[input.into()],
6277                    ""
6278                ))
6279                .try_as_basic_value()
6280                .left()
6281                .unwrap();
6282                self.state
6283                    .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
6284            }
6285            Operator::F64x2Ceil => {
6286                let (v, i) = self.state.pop1_extra()?;
6287                let (v, _) = self.v128_into_f64x2(v, i)?;
6288                let res = err!(self.builder.build_call(
6289                    self.intrinsics.ceil_f64x2,
6290                    &[v.into()],
6291                    ""
6292                ))
6293                .try_as_basic_value()
6294                .left()
6295                .unwrap();
6296                let res = err!(
6297                    self.builder
6298                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6299                );
6300                self.state
6301                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6302            }
6303            Operator::F32Floor => {
6304                let (input, info) = self.state.pop1_extra()?;
6305                let res = err!(self.builder.build_call(
6306                    self.intrinsics.floor_f32,
6307                    &[input.into()],
6308                    ""
6309                ))
6310                .try_as_basic_value()
6311                .left()
6312                .unwrap();
6313                self.state
6314                    .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
6315            }
6316            Operator::F32x4Floor => {
6317                let (v, i) = self.state.pop1_extra()?;
6318                let (v, _) = self.v128_into_f32x4(v, i)?;
6319                let res = err!(self.builder.build_call(
6320                    self.intrinsics.floor_f32x4,
6321                    &[v.into()],
6322                    ""
6323                ))
6324                .try_as_basic_value()
6325                .left()
6326                .unwrap();
6327                let res = err!(
6328                    self.builder
6329                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6330                );
6331                self.state
6332                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6333            }
6334            Operator::F64Floor => {
6335                let (input, info) = self.state.pop1_extra()?;
6336                let res = err!(self.builder.build_call(
6337                    self.intrinsics.floor_f64,
6338                    &[input.into()],
6339                    ""
6340                ))
6341                .try_as_basic_value()
6342                .left()
6343                .unwrap();
6344                self.state
6345                    .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
6346            }
6347            Operator::F64x2Floor => {
6348                let (v, i) = self.state.pop1_extra()?;
6349                let (v, _) = self.v128_into_f64x2(v, i)?;
6350                let res = err!(self.builder.build_call(
6351                    self.intrinsics.floor_f64x2,
6352                    &[v.into()],
6353                    ""
6354                ))
6355                .try_as_basic_value()
6356                .left()
6357                .unwrap();
6358                let res = err!(
6359                    self.builder
6360                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6361                );
6362                self.state
6363                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6364            }
6365            Operator::F32Trunc => {
6366                let (v, i) = self.state.pop1_extra()?;
6367                let res = err!(
6368                    self.builder
6369                        .build_call(self.intrinsics.trunc_f32, &[v.into()], "")
6370                )
6371                .try_as_basic_value()
6372                .left()
6373                .unwrap();
6374                self.state
6375                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6376            }
6377            Operator::F32x4Trunc => {
6378                let (v, i) = self.state.pop1_extra()?;
6379                let (v, _) = self.v128_into_f32x4(v, i)?;
6380                let res = err!(self.builder.build_call(
6381                    self.intrinsics.trunc_f32x4,
6382                    &[v.into()],
6383                    ""
6384                ))
6385                .try_as_basic_value()
6386                .left()
6387                .unwrap();
6388                let res = err!(
6389                    self.builder
6390                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6391                );
6392                self.state
6393                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6394            }
6395            Operator::F64Trunc => {
6396                let (v, i) = self.state.pop1_extra()?;
6397                let res = err!(
6398                    self.builder
6399                        .build_call(self.intrinsics.trunc_f64, &[v.into()], "")
6400                )
6401                .try_as_basic_value()
6402                .left()
6403                .unwrap();
6404                self.state
6405                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6406            }
6407            Operator::F64x2Trunc => {
6408                let (v, i) = self.state.pop1_extra()?;
6409                let (v, _) = self.v128_into_f64x2(v, i)?;
6410                let res = err!(self.builder.build_call(
6411                    self.intrinsics.trunc_f64x2,
6412                    &[v.into()],
6413                    ""
6414                ))
6415                .try_as_basic_value()
6416                .left()
6417                .unwrap();
6418                let res = err!(
6419                    self.builder
6420                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6421                );
6422                self.state
6423                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6424            }
6425            Operator::F32Nearest => {
6426                let (v, i) = self.state.pop1_extra()?;
6427                let res = err!(self.builder.build_call(
6428                    self.intrinsics.nearbyint_f32,
6429                    &[v.into()],
6430                    ""
6431                ))
6432                .try_as_basic_value()
6433                .left()
6434                .unwrap();
6435                self.state
6436                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6437            }
6438            Operator::F32x4Nearest => {
6439                let (v, i) = self.state.pop1_extra()?;
6440                let (v, _) = self.v128_into_f32x4(v, i)?;
6441                let res = err!(self.builder.build_call(
6442                    self.intrinsics.nearbyint_f32x4,
6443                    &[v.into()],
6444                    ""
6445                ))
6446                .try_as_basic_value()
6447                .left()
6448                .unwrap();
6449                let res = err!(
6450                    self.builder
6451                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6452                );
6453                self.state
6454                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6455            }
6456            Operator::F64Nearest => {
6457                let (v, i) = self.state.pop1_extra()?;
6458                let res = err!(self.builder.build_call(
6459                    self.intrinsics.nearbyint_f64,
6460                    &[v.into()],
6461                    ""
6462                ))
6463                .try_as_basic_value()
6464                .left()
6465                .unwrap();
6466                self.state
6467                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6468            }
6469            Operator::F64x2Nearest => {
6470                let (v, i) = self.state.pop1_extra()?;
6471                let (v, _) = self.v128_into_f64x2(v, i)?;
6472                let res = err!(self.builder.build_call(
6473                    self.intrinsics.nearbyint_f64x2,
6474                    &[v.into()],
6475                    ""
6476                ))
6477                .try_as_basic_value()
6478                .left()
6479                .unwrap();
6480                let res = err!(
6481                    self.builder
6482                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6483                );
6484                self.state
6485                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6486            }
6487            Operator::F32Abs => {
6488                let (v, i) = self.state.pop1_extra()?;
6489                let v = self.apply_pending_canonicalization(v, i)?;
6490                let res = err!(
6491                    self.builder
6492                        .build_call(self.intrinsics.fabs_f32, &[v.into()], "")
6493                )
6494                .try_as_basic_value()
6495                .left()
6496                .unwrap();
6497                // The exact NaN returned by F32Abs is fully defined. Do not
6498                // adjust.
6499                self.state.push1_extra(res, i.strip_pending());
6500            }
6501            Operator::F64Abs => {
6502                let (v, i) = self.state.pop1_extra()?;
6503                let v = self.apply_pending_canonicalization(v, i)?;
6504                let res = err!(
6505                    self.builder
6506                        .build_call(self.intrinsics.fabs_f64, &[v.into()], "")
6507                )
6508                .try_as_basic_value()
6509                .left()
6510                .unwrap();
6511                // The exact NaN returned by F64Abs is fully defined. Do not
6512                // adjust.
6513                self.state.push1_extra(res, i.strip_pending());
6514            }
6515            Operator::F32x4Abs => {
6516                let (v, i) = self.state.pop1_extra()?;
6517                let v = err!(self.builder.build_bit_cast(
6518                    v.into_int_value(),
6519                    self.intrinsics.f32x4_ty,
6520                    ""
6521                ));
6522                let v = self.apply_pending_canonicalization(v, i)?;
6523                let res = err!(self.builder.build_call(
6524                    self.intrinsics.fabs_f32x4,
6525                    &[v.into()],
6526                    ""
6527                ))
6528                .try_as_basic_value()
6529                .left()
6530                .unwrap();
6531                let res = err!(
6532                    self.builder
6533                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6534                );
6535                // The exact NaN returned by F32x4Abs is fully defined. Do not
6536                // adjust.
6537                self.state.push1_extra(res, i.strip_pending());
6538            }
6539            Operator::F64x2Abs => {
6540                let (v, i) = self.state.pop1_extra()?;
6541                let v = err!(self.builder.build_bit_cast(
6542                    v.into_int_value(),
6543                    self.intrinsics.f64x2_ty,
6544                    ""
6545                ));
6546                let v = self.apply_pending_canonicalization(v, i)?;
6547                let res = err!(self.builder.build_call(
6548                    self.intrinsics.fabs_f64x2,
6549                    &[v.into()],
6550                    ""
6551                ))
6552                .try_as_basic_value()
6553                .left()
6554                .unwrap();
6555                let res = err!(
6556                    self.builder
6557                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6558                );
6559                // The exact NaN returned by F32x4Abs is fully defined. Do not
6560                // adjust.
6561                self.state.push1_extra(res, i.strip_pending());
6562            }
6563            Operator::F32x4Neg => {
6564                let (v, i) = self.state.pop1_extra()?;
6565                let v = err!(self.builder.build_bit_cast(
6566                    v.into_int_value(),
6567                    self.intrinsics.f32x4_ty,
6568                    ""
6569                ));
6570                let v = self
6571                    .apply_pending_canonicalization(v, i)?
6572                    .into_vector_value();
6573                let res = err!(self.builder.build_float_neg(v, ""));
6574                let res = err!(
6575                    self.builder
6576                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6577                );
6578                // The exact NaN returned by F32x4Neg is fully defined. Do not
6579                // adjust.
6580                self.state.push1_extra(res, i.strip_pending());
6581            }
6582            Operator::F64x2Neg => {
6583                let (v, i) = self.state.pop1_extra()?;
6584                let v = err!(self.builder.build_bit_cast(
6585                    v.into_int_value(),
6586                    self.intrinsics.f64x2_ty,
6587                    ""
6588                ));
6589                let v = self
6590                    .apply_pending_canonicalization(v, i)?
6591                    .into_vector_value();
6592                let res = err!(self.builder.build_float_neg(v, ""));
6593                let res = err!(
6594                    self.builder
6595                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6596                );
6597                // The exact NaN returned by F64x2Neg is fully defined. Do not
6598                // adjust.
6599                self.state.push1_extra(res, i.strip_pending());
6600            }
6601            Operator::F32Neg | Operator::F64Neg => {
6602                let (v, i) = self.state.pop1_extra()?;
6603                let v = self
6604                    .apply_pending_canonicalization(v, i)?
6605                    .into_float_value();
6606                let res = err!(self.builder.build_float_neg(v, ""));
6607                // The exact NaN returned by F32Neg and F64Neg are fully defined.
6608                // Do not adjust.
6609                self.state.push1_extra(res, i.strip_pending());
6610            }
6611            Operator::F32Copysign => {
6612                let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
6613                let mag = self.apply_pending_canonicalization(mag, mag_info)?;
6614                let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
6615                let res = err!(self.builder.build_call(
6616                    self.intrinsics.copysign_f32,
6617                    &[mag.into(), sgn.into()],
6618                    ""
6619                ))
6620                .try_as_basic_value()
6621                .left()
6622                .unwrap();
6623                // The exact NaN returned by F32Copysign is fully defined.
6624                // Do not adjust.
6625                self.state.push1_extra(res, mag_info.strip_pending());
6626            }
6627            Operator::F64Copysign => {
6628                let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
6629                let mag = self.apply_pending_canonicalization(mag, mag_info)?;
6630                let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
6631                let res = err!(self.builder.build_call(
6632                    self.intrinsics.copysign_f64,
6633                    &[mag.into(), sgn.into()],
6634                    ""
6635                ))
6636                .try_as_basic_value()
6637                .left()
6638                .unwrap();
6639                // The exact NaN returned by F32Copysign is fully defined.
6640                // Do not adjust.
6641                self.state.push1_extra(res, mag_info.strip_pending());
6642            }
6643
6644            /***************************
6645             * Integer Comparison instructions.
6646             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-comparison-instructions
6647             ***************************/
6648            Operator::I32Eq | Operator::I64Eq => {
6649                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6650                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6651                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6652                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6653                let cond = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6654                let res = err!(
6655                    self.builder
6656                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6657                );
6658                self.state.push1_extra(
6659                    res,
6660                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6661                );
6662            }
6663            Operator::I8x16Eq => {
6664                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6665                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6666                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6667                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6668                let res = err!(
6669                    self.builder
6670                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6671                );
6672                let res = err!(
6673                    self.builder
6674                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6675                );
6676                self.state.push1(res);
6677            }
6678            Operator::I16x8Eq => {
6679                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6680                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6681                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6682                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6683                let res = err!(
6684                    self.builder
6685                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6686                );
6687                let res = err!(
6688                    self.builder
6689                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6690                );
6691                self.state.push1(res);
6692            }
6693            Operator::I32x4Eq => {
6694                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6695                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6696                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6697                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6698                let res = err!(
6699                    self.builder
6700                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6701                );
6702                let res = err!(
6703                    self.builder
6704                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6705                );
6706                self.state.push1(res);
6707            }
6708            Operator::I64x2Eq => {
6709                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6710                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6711                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6712                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6713                let res = err!(
6714                    self.builder
6715                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6716                );
6717                let res = err!(
6718                    self.builder
6719                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6720                );
6721                self.state.push1(res);
6722            }
6723            Operator::I32Ne | Operator::I64Ne => {
6724                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6725                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6726                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6727                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6728                let cond = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6729                let res = err!(
6730                    self.builder
6731                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6732                );
6733                self.state.push1_extra(
6734                    res,
6735                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6736                );
6737            }
6738            Operator::I8x16Ne => {
6739                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6740                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6741                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6742                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6743                let res = err!(
6744                    self.builder
6745                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6746                );
6747                let res = err!(
6748                    self.builder
6749                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6750                );
6751                self.state.push1(res);
6752            }
6753            Operator::I16x8Ne => {
6754                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6755                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6756                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6757                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6758                let res = err!(
6759                    self.builder
6760                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6761                );
6762                let res = err!(
6763                    self.builder
6764                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6765                );
6766                self.state.push1(res);
6767            }
6768            Operator::I32x4Ne => {
6769                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6770                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6771                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6772                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6773                let res = err!(
6774                    self.builder
6775                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6776                );
6777                let res = err!(
6778                    self.builder
6779                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6780                );
6781                self.state.push1(res);
6782            }
6783            Operator::I64x2Ne => {
6784                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6785                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6786                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6787                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6788                let res = err!(
6789                    self.builder
6790                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6791                );
6792                let res = err!(
6793                    self.builder
6794                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6795                );
6796                self.state.push1(res);
6797            }
6798            Operator::I32LtS | Operator::I64LtS => {
6799                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6800                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6801                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6802                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6803                let cond = err!(
6804                    self.builder
6805                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6806                );
6807                let res = err!(
6808                    self.builder
6809                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6810                );
6811                self.state.push1_extra(
6812                    res,
6813                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6814                );
6815            }
6816            Operator::I8x16LtS => {
6817                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6818                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6819                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6820                let res = err!(
6821                    self.builder
6822                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6823                );
6824                let res = err!(
6825                    self.builder
6826                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6827                );
6828                let res = err!(
6829                    self.builder
6830                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6831                );
6832                self.state.push1(res);
6833            }
6834            Operator::I16x8LtS => {
6835                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6836                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6837                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6838                let res = err!(
6839                    self.builder
6840                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6841                );
6842                let res = err!(
6843                    self.builder
6844                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6845                );
6846                let res = err!(
6847                    self.builder
6848                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6849                );
6850                self.state.push1(res);
6851            }
6852            Operator::I32x4LtS => {
6853                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6854                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6855                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6856                let res = err!(
6857                    self.builder
6858                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6859                );
6860                let res = err!(
6861                    self.builder
6862                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6863                );
6864                let res = err!(
6865                    self.builder
6866                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6867                );
6868                self.state.push1(res);
6869            }
6870            Operator::I64x2LtS => {
6871                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6872                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6873                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6874                let res = err!(
6875                    self.builder
6876                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6877                );
6878                let res = err!(
6879                    self.builder
6880                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6881                );
6882                let res = err!(
6883                    self.builder
6884                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6885                );
6886                self.state.push1(res);
6887            }
6888            Operator::I32LtU | Operator::I64LtU => {
6889                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6890                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6891                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6892                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6893                let cond = err!(
6894                    self.builder
6895                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6896                );
6897                let res = err!(
6898                    self.builder
6899                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6900                );
6901                self.state.push1(res);
6902            }
6903            Operator::I8x16LtU => {
6904                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6905                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6906                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6907                let res = err!(
6908                    self.builder
6909                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6910                );
6911                let res = err!(
6912                    self.builder
6913                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6914                );
6915                let res = err!(
6916                    self.builder
6917                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6918                );
6919                self.state.push1(res);
6920            }
6921            Operator::I16x8LtU => {
6922                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6923                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6924                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6925                let res = err!(
6926                    self.builder
6927                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6928                );
6929                let res = err!(
6930                    self.builder
6931                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6932                );
6933                let res = err!(
6934                    self.builder
6935                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6936                );
6937                self.state.push1(res);
6938            }
6939            Operator::I32x4LtU => {
6940                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6941                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6942                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6943                let res = err!(
6944                    self.builder
6945                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6946                );
6947                let res = err!(
6948                    self.builder
6949                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6950                );
6951                let res = err!(
6952                    self.builder
6953                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6954                );
6955                self.state.push1(res);
6956            }
6957            Operator::I32LeS | Operator::I64LeS => {
6958                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6959                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6960                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6961                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6962                let cond = err!(
6963                    self.builder
6964                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6965                );
6966                let res = err!(
6967                    self.builder
6968                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6969                );
6970                self.state.push1_extra(
6971                    res,
6972                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6973                );
6974            }
6975            Operator::I8x16LeS => {
6976                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6977                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6978                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6979                let res = err!(
6980                    self.builder
6981                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6982                );
6983                let res = err!(
6984                    self.builder
6985                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6986                );
6987                let res = err!(
6988                    self.builder
6989                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6990                );
6991                self.state.push1(res);
6992            }
6993            Operator::I16x8LeS => {
6994                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6995                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6996                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6997                let res = err!(
6998                    self.builder
6999                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
7000                );
7001                let res = err!(
7002                    self.builder
7003                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7004                );
7005                let res = err!(
7006                    self.builder
7007                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7008                );
7009                self.state.push1(res);
7010            }
7011            Operator::I32x4LeS => {
7012                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7013                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7014                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7015                let res = err!(
7016                    self.builder
7017                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
7018                );
7019                let res = err!(
7020                    self.builder
7021                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7022                );
7023                let res = err!(
7024                    self.builder
7025                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7026                );
7027                self.state.push1(res);
7028            }
7029            Operator::I64x2LeS => {
7030                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7031                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
7032                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
7033                let res = err!(
7034                    self.builder
7035                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
7036                );
7037                let res = err!(
7038                    self.builder
7039                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7040                );
7041                let res = err!(
7042                    self.builder
7043                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7044                );
7045                self.state.push1(res);
7046            }
7047            Operator::I32LeU | Operator::I64LeU => {
7048                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7049                let v1 = self.apply_pending_canonicalization(v1, i1)?;
7050                let v2 = self.apply_pending_canonicalization(v2, i2)?;
7051                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7052                let cond = err!(
7053                    self.builder
7054                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
7055                );
7056                let res = err!(
7057                    self.builder
7058                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7059                );
7060                self.state.push1_extra(
7061                    res,
7062                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7063                );
7064            }
7065            Operator::I8x16LeU => {
7066                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7067                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7068                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7069                let res = err!(
7070                    self.builder
7071                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
7072                );
7073                let res = err!(
7074                    self.builder
7075                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7076                );
7077                let res = err!(
7078                    self.builder
7079                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7080                );
7081                self.state.push1(res);
7082            }
7083            Operator::I16x8LeU => {
7084                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7085                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7086                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7087                let res = err!(
7088                    self.builder
7089                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
7090                );
7091                let res = err!(
7092                    self.builder
7093                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7094                );
7095                let res = err!(
7096                    self.builder
7097                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7098                );
7099                self.state.push1(res);
7100            }
7101            Operator::I32x4LeU => {
7102                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7103                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7104                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7105                let res = err!(
7106                    self.builder
7107                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
7108                );
7109                let res = err!(
7110                    self.builder
7111                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7112                );
7113                let res = err!(
7114                    self.builder
7115                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7116                );
7117                self.state.push1(res);
7118            }
7119            Operator::I32GtS | Operator::I64GtS => {
7120                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7121                let v1 = self.apply_pending_canonicalization(v1, i1)?;
7122                let v2 = self.apply_pending_canonicalization(v2, i2)?;
7123                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7124                let cond = err!(
7125                    self.builder
7126                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
7127                );
7128                let res = err!(
7129                    self.builder
7130                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7131                );
7132                self.state.push1_extra(
7133                    res,
7134                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7135                );
7136            }
7137            Operator::I8x16GtS => {
7138                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7139                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7140                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7141                let res = err!(
7142                    self.builder
7143                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
7144                );
7145                let res = err!(
7146                    self.builder
7147                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7148                );
7149                let res = err!(
7150                    self.builder
7151                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7152                );
7153                self.state.push1(res);
7154            }
7155            Operator::I16x8GtS => {
7156                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7157                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7158                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7159                let res = err!(
7160                    self.builder
7161                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
7162                );
7163                let res = err!(
7164                    self.builder
7165                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7166                );
7167                let res = err!(
7168                    self.builder
7169                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7170                );
7171                self.state.push1(res);
7172            }
7173            Operator::I32x4GtS => {
7174                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7175                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7176                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7177                let res = err!(
7178                    self.builder
7179                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
7180                );
7181                let res = err!(
7182                    self.builder
7183                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7184                );
7185                let res = err!(
7186                    self.builder
7187                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7188                );
7189                self.state.push1(res);
7190            }
7191            Operator::I64x2GtS => {
7192                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7193                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
7194                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
7195                let res = err!(
7196                    self.builder
7197                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
7198                );
7199                let res = err!(
7200                    self.builder
7201                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7202                );
7203                let res = err!(
7204                    self.builder
7205                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7206                );
7207                self.state.push1(res);
7208            }
7209            Operator::I32GtU | Operator::I64GtU => {
7210                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7211                let v1 = self.apply_pending_canonicalization(v1, i1)?;
7212                let v2 = self.apply_pending_canonicalization(v2, i2)?;
7213                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7214                let cond = err!(
7215                    self.builder
7216                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
7217                );
7218                let res = err!(
7219                    self.builder
7220                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7221                );
7222                self.state.push1_extra(
7223                    res,
7224                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7225                );
7226            }
7227            Operator::I8x16GtU => {
7228                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7229                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7230                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7231                let res = err!(
7232                    self.builder
7233                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
7234                );
7235                let res = err!(
7236                    self.builder
7237                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7238                );
7239                let res = err!(
7240                    self.builder
7241                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7242                );
7243                self.state.push1(res);
7244            }
7245            Operator::I16x8GtU => {
7246                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7247                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7248                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7249                let res = err!(
7250                    self.builder
7251                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
7252                );
7253                let res = err!(
7254                    self.builder
7255                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7256                );
7257                let res = err!(
7258                    self.builder
7259                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7260                );
7261                self.state.push1(res);
7262            }
7263            Operator::I32x4GtU => {
7264                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7265                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7266                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7267                let res = err!(
7268                    self.builder
7269                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
7270                );
7271                let res = err!(
7272                    self.builder
7273                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7274                );
7275                let res = err!(
7276                    self.builder
7277                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7278                );
7279                self.state.push1(res);
7280            }
7281            Operator::I32GeS | Operator::I64GeS => {
7282                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7283                let v1 = self.apply_pending_canonicalization(v1, i1)?;
7284                let v2 = self.apply_pending_canonicalization(v2, i2)?;
7285                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7286                let cond = err!(
7287                    self.builder
7288                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
7289                );
7290                let res = err!(
7291                    self.builder
7292                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7293                );
7294                self.state.push1(res);
7295            }
7296            Operator::I8x16GeS => {
7297                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7298                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7299                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7300                let res = err!(
7301                    self.builder
7302                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
7303                );
7304                let res = err!(
7305                    self.builder
7306                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7307                );
7308                let res = err!(
7309                    self.builder
7310                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7311                );
7312                self.state.push1(res);
7313            }
7314            Operator::I16x8GeS => {
7315                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7316                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7317                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7318                let res = err!(
7319                    self.builder
7320                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
7321                );
7322                let res = err!(
7323                    self.builder
7324                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7325                );
7326                let res = err!(
7327                    self.builder
7328                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7329                );
7330                self.state.push1(res);
7331            }
7332            Operator::I32x4GeS => {
7333                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7334                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7335                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7336                let res = err!(
7337                    self.builder
7338                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
7339                );
7340                let res = err!(
7341                    self.builder
7342                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7343                );
7344                let res = err!(
7345                    self.builder
7346                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7347                );
7348                self.state.push1(res);
7349            }
7350            Operator::I64x2GeS => {
7351                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7352                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
7353                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
7354                let res = err!(
7355                    self.builder
7356                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
7357                );
7358                let res = err!(
7359                    self.builder
7360                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7361                );
7362                let res = err!(
7363                    self.builder
7364                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7365                );
7366                self.state.push1(res);
7367            }
7368            Operator::I32GeU | Operator::I64GeU => {
7369                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7370                let v1 = self.apply_pending_canonicalization(v1, i1)?;
7371                let v2 = self.apply_pending_canonicalization(v2, i2)?;
7372                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7373                let cond = err!(
7374                    self.builder
7375                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
7376                );
7377                let res = err!(
7378                    self.builder
7379                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7380                );
7381                self.state.push1_extra(
7382                    res,
7383                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7384                );
7385            }
7386            Operator::I8x16GeU => {
7387                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7388                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7389                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7390                let res = err!(
7391                    self.builder
7392                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
7393                );
7394                let res = err!(
7395                    self.builder
7396                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7397                );
7398                let res = err!(
7399                    self.builder
7400                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7401                );
7402                self.state.push1(res);
7403            }
7404            Operator::I16x8GeU => {
7405                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7406                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7407                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7408                let res = err!(
7409                    self.builder
7410                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
7411                );
7412                let res = err!(
7413                    self.builder
7414                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7415                );
7416                let res = err!(
7417                    self.builder
7418                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7419                );
7420                self.state.push1(res);
7421            }
7422            Operator::I32x4GeU => {
7423                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7424                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7425                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7426                let res = err!(
7427                    self.builder
7428                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
7429                );
7430                let res = err!(
7431                    self.builder
7432                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7433                );
7434                let res = err!(
7435                    self.builder
7436                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7437                );
7438                self.state.push1(res);
7439            }
7440
7441            /***************************
7442             * Floating-Point Comparison instructions.
7443             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-comparison-instructions
7444             ***************************/
7445            Operator::F32Eq | Operator::F64Eq => {
7446                let (v1, v2) = self.state.pop2()?;
7447                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7448                let cond = err!(
7449                    self.builder
7450                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
7451                );
7452                let res = err!(
7453                    self.builder
7454                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7455                );
7456                self.state.push1_extra(
7457                    res,
7458                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7459                );
7460            }
7461            Operator::F32x4Eq => {
7462                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7463                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7464                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7465                let res = err!(
7466                    self.builder
7467                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
7468                );
7469                let res = err!(
7470                    self.builder
7471                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7472                );
7473                let res = err!(
7474                    self.builder
7475                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7476                );
7477                self.state.push1(res);
7478            }
7479            Operator::F64x2Eq => {
7480                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7481                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7482                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7483                let res = err!(
7484                    self.builder
7485                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
7486                );
7487                let res = err!(
7488                    self.builder
7489                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7490                );
7491                let res = err!(
7492                    self.builder
7493                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7494                );
7495                self.state.push1(res);
7496            }
7497            Operator::F32Ne | Operator::F64Ne => {
7498                let (v1, v2) = self.state.pop2()?;
7499                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7500                let cond = err!(
7501                    self.builder
7502                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
7503                );
7504                let res = err!(
7505                    self.builder
7506                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7507                );
7508                self.state.push1_extra(
7509                    res,
7510                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7511                );
7512            }
7513            Operator::F32x4Ne => {
7514                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7515                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7516                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7517                let res = err!(
7518                    self.builder
7519                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
7520                );
7521                let res = err!(
7522                    self.builder
7523                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
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::F64x2Ne => {
7532                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7533                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7534                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7535                let res = err!(
7536                    self.builder
7537                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
7538                );
7539                let res = err!(
7540                    self.builder
7541                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7542                );
7543                let res = err!(
7544                    self.builder
7545                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7546                );
7547                self.state.push1(res);
7548            }
7549            Operator::F32Lt | Operator::F64Lt => {
7550                let (v1, v2) = self.state.pop2()?;
7551                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7552                let cond = err!(
7553                    self.builder
7554                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
7555                );
7556                let res = err!(
7557                    self.builder
7558                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7559                );
7560                self.state.push1_extra(
7561                    res,
7562                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7563                );
7564            }
7565            Operator::F32x4Lt => {
7566                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7567                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7568                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7569                let res = err!(
7570                    self.builder
7571                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
7572                );
7573                let res = err!(
7574                    self.builder
7575                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7576                );
7577                let res = err!(
7578                    self.builder
7579                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7580                );
7581                self.state.push1(res);
7582            }
7583            Operator::F64x2Lt => {
7584                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7585                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7586                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7587                let res = err!(
7588                    self.builder
7589                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
7590                );
7591                let res = err!(
7592                    self.builder
7593                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7594                );
7595                let res = err!(
7596                    self.builder
7597                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7598                );
7599                self.state.push1(res);
7600            }
7601            Operator::F32Le | Operator::F64Le => {
7602                let (v1, v2) = self.state.pop2()?;
7603                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7604                let cond = err!(
7605                    self.builder
7606                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
7607                );
7608                let res = err!(
7609                    self.builder
7610                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7611                );
7612                self.state.push1_extra(
7613                    res,
7614                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7615                );
7616            }
7617            Operator::F32x4Le => {
7618                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7619                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7620                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7621                let res = err!(
7622                    self.builder
7623                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
7624                );
7625                let res = err!(
7626                    self.builder
7627                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7628                );
7629                let res = err!(
7630                    self.builder
7631                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7632                );
7633                self.state.push1(res);
7634            }
7635            Operator::F64x2Le => {
7636                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7637                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7638                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7639                let res = err!(
7640                    self.builder
7641                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
7642                );
7643                let res = err!(
7644                    self.builder
7645                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7646                );
7647                let res = err!(
7648                    self.builder
7649                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7650                );
7651                self.state.push1(res);
7652            }
7653            Operator::F32Gt | Operator::F64Gt => {
7654                let (v1, v2) = self.state.pop2()?;
7655                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7656                let cond = err!(
7657                    self.builder
7658                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
7659                );
7660                let res = err!(
7661                    self.builder
7662                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7663                );
7664                self.state.push1_extra(
7665                    res,
7666                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7667                );
7668            }
7669            Operator::F32x4Gt => {
7670                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7671                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7672                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7673                let res = err!(
7674                    self.builder
7675                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
7676                );
7677                let res = err!(
7678                    self.builder
7679                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7680                );
7681                let res = err!(
7682                    self.builder
7683                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7684                );
7685                self.state.push1(res);
7686            }
7687            Operator::F64x2Gt => {
7688                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7689                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7690                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7691                let res = err!(
7692                    self.builder
7693                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
7694                );
7695                let res = err!(
7696                    self.builder
7697                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7698                );
7699                let res = err!(
7700                    self.builder
7701                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7702                );
7703                self.state.push1(res);
7704            }
7705            Operator::F32Ge | Operator::F64Ge => {
7706                let (v1, v2) = self.state.pop2()?;
7707                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7708                let cond = err!(
7709                    self.builder
7710                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7711                );
7712                let res = err!(
7713                    self.builder
7714                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7715                );
7716                self.state.push1_extra(
7717                    res,
7718                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7719                );
7720            }
7721            Operator::F32x4Ge => {
7722                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7723                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7724                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7725                let res = err!(
7726                    self.builder
7727                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7728                );
7729                let res = err!(
7730                    self.builder
7731                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7732                );
7733                let res = err!(
7734                    self.builder
7735                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7736                );
7737                self.state.push1(res);
7738            }
7739            Operator::F64x2Ge => {
7740                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7741                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7742                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7743                let res = err!(
7744                    self.builder
7745                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7746                );
7747                let res = err!(
7748                    self.builder
7749                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7750                );
7751                let res = err!(
7752                    self.builder
7753                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7754                );
7755                self.state.push1(res);
7756            }
7757
7758            /***************************
7759             * Conversion instructions.
7760             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#conversion-instructions
7761             ***************************/
7762            Operator::I32WrapI64 => {
7763                let (v, i) = self.state.pop1_extra()?;
7764                let v = self.apply_pending_canonicalization(v, i)?;
7765                let v = v.into_int_value();
7766                let res = err!(
7767                    self.builder
7768                        .build_int_truncate(v, self.intrinsics.i32_ty, "")
7769                );
7770                self.state.push1(res);
7771            }
7772            Operator::I64ExtendI32S => {
7773                let (v, i) = self.state.pop1_extra()?;
7774                let v = self.apply_pending_canonicalization(v, i)?;
7775                let v = v.into_int_value();
7776                let res = err!(
7777                    self.builder
7778                        .build_int_s_extend(v, self.intrinsics.i64_ty, "")
7779                );
7780                self.state.push1(res);
7781            }
7782            Operator::I64ExtendI32U => {
7783                let (v, i) = self.state.pop1_extra()?;
7784                let v = self.apply_pending_canonicalization(v, i)?;
7785                let v = v.into_int_value();
7786                let res = err!(
7787                    self.builder
7788                        .build_int_z_extend(v, self.intrinsics.i64_ty, "")
7789                );
7790                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
7791            }
7792            Operator::I16x8ExtendLowI8x16S => {
7793                let (v, i) = self.state.pop1_extra()?;
7794                let (v, _) = self.v128_into_i8x16(v, i)?;
7795                let low = err!(self.builder.build_shuffle_vector(
7796                    v,
7797                    v.get_type().get_undef(),
7798                    VectorType::const_vector(&[
7799                        self.intrinsics.i32_consts[0],
7800                        self.intrinsics.i32_consts[1],
7801                        self.intrinsics.i32_consts[2],
7802                        self.intrinsics.i32_consts[3],
7803                        self.intrinsics.i32_consts[4],
7804                        self.intrinsics.i32_consts[5],
7805                        self.intrinsics.i32_consts[6],
7806                        self.intrinsics.i32_consts[7],
7807                    ]),
7808                    "",
7809                ));
7810                let res = err!(
7811                    self.builder
7812                        .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7813                );
7814                let res = err!(
7815                    self.builder
7816                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7817                );
7818                self.state.push1(res);
7819            }
7820            Operator::I16x8ExtendHighI8x16S => {
7821                let (v, i) = self.state.pop1_extra()?;
7822                let (v, _) = self.v128_into_i8x16(v, i)?;
7823                let low = err!(self.builder.build_shuffle_vector(
7824                    v,
7825                    v.get_type().get_undef(),
7826                    VectorType::const_vector(&[
7827                        self.intrinsics.i32_consts[8],
7828                        self.intrinsics.i32_consts[9],
7829                        self.intrinsics.i32_consts[10],
7830                        self.intrinsics.i32_consts[11],
7831                        self.intrinsics.i32_consts[12],
7832                        self.intrinsics.i32_consts[13],
7833                        self.intrinsics.i32_consts[14],
7834                        self.intrinsics.i32_consts[15],
7835                    ]),
7836                    "",
7837                ));
7838                let res = err!(
7839                    self.builder
7840                        .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7841                );
7842                let res = err!(
7843                    self.builder
7844                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7845                );
7846                self.state.push1(res);
7847            }
7848            Operator::I16x8ExtendLowI8x16U => {
7849                let (v, i) = self.state.pop1_extra()?;
7850                let (v, _) = self.v128_into_i8x16(v, i)?;
7851                let low = err!(self.builder.build_shuffle_vector(
7852                    v,
7853                    v.get_type().get_undef(),
7854                    VectorType::const_vector(&[
7855                        self.intrinsics.i32_consts[0],
7856                        self.intrinsics.i32_consts[1],
7857                        self.intrinsics.i32_consts[2],
7858                        self.intrinsics.i32_consts[3],
7859                        self.intrinsics.i32_consts[4],
7860                        self.intrinsics.i32_consts[5],
7861                        self.intrinsics.i32_consts[6],
7862                        self.intrinsics.i32_consts[7],
7863                    ]),
7864                    "",
7865                ));
7866                let res = err!(
7867                    self.builder
7868                        .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7869                );
7870                let res = err!(
7871                    self.builder
7872                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7873                );
7874                self.state.push1(res);
7875            }
7876            Operator::I16x8ExtendHighI8x16U => {
7877                let (v, i) = self.state.pop1_extra()?;
7878                let (v, _) = self.v128_into_i8x16(v, i)?;
7879                let low = err!(self.builder.build_shuffle_vector(
7880                    v,
7881                    v.get_type().get_undef(),
7882                    VectorType::const_vector(&[
7883                        self.intrinsics.i32_consts[8],
7884                        self.intrinsics.i32_consts[9],
7885                        self.intrinsics.i32_consts[10],
7886                        self.intrinsics.i32_consts[11],
7887                        self.intrinsics.i32_consts[12],
7888                        self.intrinsics.i32_consts[13],
7889                        self.intrinsics.i32_consts[14],
7890                        self.intrinsics.i32_consts[15],
7891                    ]),
7892                    "",
7893                ));
7894                let res = err!(
7895                    self.builder
7896                        .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7897                );
7898                let res = err!(
7899                    self.builder
7900                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7901                );
7902                self.state.push1(res);
7903            }
7904            Operator::I32x4ExtendLowI16x8S => {
7905                let (v, i) = self.state.pop1_extra()?;
7906                let (v, _) = self.v128_into_i16x8(v, i)?;
7907                let low = err!(self.builder.build_shuffle_vector(
7908                    v,
7909                    v.get_type().get_undef(),
7910                    VectorType::const_vector(&[
7911                        self.intrinsics.i32_consts[0],
7912                        self.intrinsics.i32_consts[1],
7913                        self.intrinsics.i32_consts[2],
7914                        self.intrinsics.i32_consts[3],
7915                    ]),
7916                    "",
7917                ));
7918                let res = err!(
7919                    self.builder
7920                        .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7921                );
7922                let res = err!(
7923                    self.builder
7924                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7925                );
7926                self.state.push1(res);
7927            }
7928            Operator::I32x4ExtendHighI16x8S => {
7929                let (v, i) = self.state.pop1_extra()?;
7930                let (v, _) = self.v128_into_i16x8(v, i)?;
7931                let low = err!(self.builder.build_shuffle_vector(
7932                    v,
7933                    v.get_type().get_undef(),
7934                    VectorType::const_vector(&[
7935                        self.intrinsics.i32_consts[4],
7936                        self.intrinsics.i32_consts[5],
7937                        self.intrinsics.i32_consts[6],
7938                        self.intrinsics.i32_consts[7],
7939                    ]),
7940                    "",
7941                ));
7942                let res = err!(
7943                    self.builder
7944                        .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7945                );
7946                let res = err!(
7947                    self.builder
7948                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7949                );
7950                self.state.push1(res);
7951            }
7952            Operator::I32x4ExtendLowI16x8U => {
7953                let (v, i) = self.state.pop1_extra()?;
7954                let (v, _) = self.v128_into_i16x8(v, i)?;
7955                let low = err!(self.builder.build_shuffle_vector(
7956                    v,
7957                    v.get_type().get_undef(),
7958                    VectorType::const_vector(&[
7959                        self.intrinsics.i32_consts[0],
7960                        self.intrinsics.i32_consts[1],
7961                        self.intrinsics.i32_consts[2],
7962                        self.intrinsics.i32_consts[3],
7963                    ]),
7964                    "",
7965                ));
7966                let res = err!(
7967                    self.builder
7968                        .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7969                );
7970                let res = err!(
7971                    self.builder
7972                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7973                );
7974                self.state.push1(res);
7975            }
7976            Operator::I32x4ExtendHighI16x8U => {
7977                let (v, i) = self.state.pop1_extra()?;
7978                let (v, _) = self.v128_into_i16x8(v, i)?;
7979                let low = err!(self.builder.build_shuffle_vector(
7980                    v,
7981                    v.get_type().get_undef(),
7982                    VectorType::const_vector(&[
7983                        self.intrinsics.i32_consts[4],
7984                        self.intrinsics.i32_consts[5],
7985                        self.intrinsics.i32_consts[6],
7986                        self.intrinsics.i32_consts[7],
7987                    ]),
7988                    "",
7989                ));
7990                let res = err!(
7991                    self.builder
7992                        .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7993                );
7994                let res = err!(
7995                    self.builder
7996                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7997                );
7998                self.state.push1(res);
7999            }
8000            Operator::I64x2ExtendLowI32x4U
8001            | Operator::I64x2ExtendLowI32x4S
8002            | Operator::I64x2ExtendHighI32x4U
8003            | Operator::I64x2ExtendHighI32x4S => {
8004                let extend = match op {
8005                    Operator::I64x2ExtendLowI32x4U | Operator::I64x2ExtendHighI32x4U => {
8006                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8007                    }
8008                    Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendHighI32x4S => {
8009                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8010                    }
8011                    _ => unreachable!("Unhandled inner case"),
8012                };
8013                let indices = match op {
8014                    Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendLowI32x4U => {
8015                        [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[1]]
8016                    }
8017                    Operator::I64x2ExtendHighI32x4S | Operator::I64x2ExtendHighI32x4U => {
8018                        [self.intrinsics.i32_consts[2], self.intrinsics.i32_consts[3]]
8019                    }
8020                    _ => unreachable!("Unhandled inner case"),
8021                };
8022                let (v, i) = self.state.pop1_extra()?;
8023                let (v, _) = self.v128_into_i32x4(v, i)?;
8024                let low = err!(self.builder.build_shuffle_vector(
8025                    v,
8026                    v.get_type().get_undef(),
8027                    VectorType::const_vector(&indices),
8028                    "",
8029                ));
8030                let res = err!(extend(self, low));
8031                let res = err!(
8032                    self.builder
8033                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8034                );
8035                self.state.push1(res);
8036            }
8037            Operator::I8x16NarrowI16x8S => {
8038                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8039                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
8040                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
8041                let min = self.intrinsics.i16_ty.const_int(0xff80, false);
8042                let max = self.intrinsics.i16_ty.const_int(0x007f, false);
8043                let min = VectorType::const_vector(&[min; 8]);
8044                let max = VectorType::const_vector(&[max; 8]);
8045                let apply_min_clamp_v1 =
8046                    err!(
8047                        self.builder
8048                            .build_int_compare(IntPredicate::SLT, v1, min, "")
8049                    );
8050                let apply_max_clamp_v1 =
8051                    err!(
8052                        self.builder
8053                            .build_int_compare(IntPredicate::SGT, v1, max, "")
8054                    );
8055                let apply_min_clamp_v2 =
8056                    err!(
8057                        self.builder
8058                            .build_int_compare(IntPredicate::SLT, v2, min, "")
8059                    );
8060                let apply_max_clamp_v2 =
8061                    err!(
8062                        self.builder
8063                            .build_int_compare(IntPredicate::SGT, v2, max, "")
8064                    );
8065                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8066                    .into_vector_value();
8067                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8068                    .into_vector_value();
8069                let v1 = err!(self.builder.build_int_truncate(
8070                    v1,
8071                    self.intrinsics.i8_ty.vec_type(8),
8072                    ""
8073                ));
8074                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8075                    .into_vector_value();
8076                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8077                    .into_vector_value();
8078                let v2 = err!(self.builder.build_int_truncate(
8079                    v2,
8080                    self.intrinsics.i8_ty.vec_type(8),
8081                    ""
8082                ));
8083                let res = err!(self.builder.build_shuffle_vector(
8084                    v1,
8085                    v2,
8086                    VectorType::const_vector(&[
8087                        self.intrinsics.i32_consts[0],
8088                        self.intrinsics.i32_consts[1],
8089                        self.intrinsics.i32_consts[2],
8090                        self.intrinsics.i32_consts[3],
8091                        self.intrinsics.i32_consts[4],
8092                        self.intrinsics.i32_consts[5],
8093                        self.intrinsics.i32_consts[6],
8094                        self.intrinsics.i32_consts[7],
8095                        self.intrinsics.i32_consts[8],
8096                        self.intrinsics.i32_consts[9],
8097                        self.intrinsics.i32_consts[10],
8098                        self.intrinsics.i32_consts[11],
8099                        self.intrinsics.i32_consts[12],
8100                        self.intrinsics.i32_consts[13],
8101                        self.intrinsics.i32_consts[14],
8102                        self.intrinsics.i32_consts[15],
8103                    ]),
8104                    "",
8105                ));
8106                let res = err!(
8107                    self.builder
8108                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8109                );
8110                self.state.push1(res);
8111            }
8112            Operator::I8x16NarrowI16x8U => {
8113                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8114                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
8115                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
8116                let min = self.intrinsics.i16x8_ty.const_zero();
8117                let max = self.intrinsics.i16_ty.const_int(0x00ff, false);
8118                let max = VectorType::const_vector(&[max; 8]);
8119                let apply_min_clamp_v1 =
8120                    err!(
8121                        self.builder
8122                            .build_int_compare(IntPredicate::SLT, v1, min, "")
8123                    );
8124                let apply_max_clamp_v1 =
8125                    err!(
8126                        self.builder
8127                            .build_int_compare(IntPredicate::SGT, v1, max, "")
8128                    );
8129                let apply_min_clamp_v2 =
8130                    err!(
8131                        self.builder
8132                            .build_int_compare(IntPredicate::SLT, v2, min, "")
8133                    );
8134                let apply_max_clamp_v2 =
8135                    err!(
8136                        self.builder
8137                            .build_int_compare(IntPredicate::SGT, v2, max, "")
8138                    );
8139                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8140                    .into_vector_value();
8141                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8142                    .into_vector_value();
8143                let v1 = err!(self.builder.build_int_truncate(
8144                    v1,
8145                    self.intrinsics.i8_ty.vec_type(8),
8146                    ""
8147                ));
8148                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8149                    .into_vector_value();
8150                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8151                    .into_vector_value();
8152                let v2 = err!(self.builder.build_int_truncate(
8153                    v2,
8154                    self.intrinsics.i8_ty.vec_type(8),
8155                    ""
8156                ));
8157                let res = err!(self.builder.build_shuffle_vector(
8158                    v1,
8159                    v2,
8160                    VectorType::const_vector(&[
8161                        self.intrinsics.i32_consts[0],
8162                        self.intrinsics.i32_consts[1],
8163                        self.intrinsics.i32_consts[2],
8164                        self.intrinsics.i32_consts[3],
8165                        self.intrinsics.i32_consts[4],
8166                        self.intrinsics.i32_consts[5],
8167                        self.intrinsics.i32_consts[6],
8168                        self.intrinsics.i32_consts[7],
8169                        self.intrinsics.i32_consts[8],
8170                        self.intrinsics.i32_consts[9],
8171                        self.intrinsics.i32_consts[10],
8172                        self.intrinsics.i32_consts[11],
8173                        self.intrinsics.i32_consts[12],
8174                        self.intrinsics.i32_consts[13],
8175                        self.intrinsics.i32_consts[14],
8176                        self.intrinsics.i32_consts[15],
8177                    ]),
8178                    "",
8179                ));
8180                let res = err!(
8181                    self.builder
8182                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8183                );
8184                self.state.push1(res);
8185            }
8186            Operator::I16x8NarrowI32x4S => {
8187                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8188                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
8189                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
8190                let min = self.intrinsics.i32_ty.const_int(0xffff8000, false);
8191                let max = self.intrinsics.i32_ty.const_int(0x00007fff, false);
8192                let min = VectorType::const_vector(&[min; 4]);
8193                let max = VectorType::const_vector(&[max; 4]);
8194                let apply_min_clamp_v1 =
8195                    err!(
8196                        self.builder
8197                            .build_int_compare(IntPredicate::SLT, v1, min, "")
8198                    );
8199                let apply_max_clamp_v1 =
8200                    err!(
8201                        self.builder
8202                            .build_int_compare(IntPredicate::SGT, v1, max, "")
8203                    );
8204                let apply_min_clamp_v2 =
8205                    err!(
8206                        self.builder
8207                            .build_int_compare(IntPredicate::SLT, v2, min, "")
8208                    );
8209                let apply_max_clamp_v2 =
8210                    err!(
8211                        self.builder
8212                            .build_int_compare(IntPredicate::SGT, v2, max, "")
8213                    );
8214                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8215                    .into_vector_value();
8216                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8217                    .into_vector_value();
8218                let v1 = err!(self.builder.build_int_truncate(
8219                    v1,
8220                    self.intrinsics.i16_ty.vec_type(4),
8221                    ""
8222                ));
8223                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8224                    .into_vector_value();
8225                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8226                    .into_vector_value();
8227                let v2 = err!(self.builder.build_int_truncate(
8228                    v2,
8229                    self.intrinsics.i16_ty.vec_type(4),
8230                    ""
8231                ));
8232                let res = err!(self.builder.build_shuffle_vector(
8233                    v1,
8234                    v2,
8235                    VectorType::const_vector(&[
8236                        self.intrinsics.i32_consts[0],
8237                        self.intrinsics.i32_consts[1],
8238                        self.intrinsics.i32_consts[2],
8239                        self.intrinsics.i32_consts[3],
8240                        self.intrinsics.i32_consts[4],
8241                        self.intrinsics.i32_consts[5],
8242                        self.intrinsics.i32_consts[6],
8243                        self.intrinsics.i32_consts[7],
8244                    ]),
8245                    "",
8246                ));
8247                let res = err!(
8248                    self.builder
8249                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8250                );
8251                self.state.push1(res);
8252            }
8253            Operator::I16x8NarrowI32x4U => {
8254                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8255                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
8256                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
8257                let min = self.intrinsics.i32x4_ty.const_zero();
8258                let max = self.intrinsics.i32_ty.const_int(0xffff, false);
8259                let max = VectorType::const_vector(&[max; 4]);
8260                let apply_min_clamp_v1 =
8261                    err!(
8262                        self.builder
8263                            .build_int_compare(IntPredicate::SLT, v1, min, "")
8264                    );
8265                let apply_max_clamp_v1 =
8266                    err!(
8267                        self.builder
8268                            .build_int_compare(IntPredicate::SGT, v1, max, "")
8269                    );
8270                let apply_min_clamp_v2 =
8271                    err!(
8272                        self.builder
8273                            .build_int_compare(IntPredicate::SLT, v2, min, "")
8274                    );
8275                let apply_max_clamp_v2 =
8276                    err!(
8277                        self.builder
8278                            .build_int_compare(IntPredicate::SGT, v2, max, "")
8279                    );
8280                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8281                    .into_vector_value();
8282                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8283                    .into_vector_value();
8284                let v1 = err!(self.builder.build_int_truncate(
8285                    v1,
8286                    self.intrinsics.i16_ty.vec_type(4),
8287                    ""
8288                ));
8289                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8290                    .into_vector_value();
8291                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8292                    .into_vector_value();
8293                let v2 = err!(self.builder.build_int_truncate(
8294                    v2,
8295                    self.intrinsics.i16_ty.vec_type(4),
8296                    ""
8297                ));
8298                let res = err!(self.builder.build_shuffle_vector(
8299                    v1,
8300                    v2,
8301                    VectorType::const_vector(&[
8302                        self.intrinsics.i32_consts[0],
8303                        self.intrinsics.i32_consts[1],
8304                        self.intrinsics.i32_consts[2],
8305                        self.intrinsics.i32_consts[3],
8306                        self.intrinsics.i32_consts[4],
8307                        self.intrinsics.i32_consts[5],
8308                        self.intrinsics.i32_consts[6],
8309                        self.intrinsics.i32_consts[7],
8310                    ]),
8311                    "",
8312                ));
8313                let res = err!(
8314                    self.builder
8315                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8316                );
8317                self.state.push1(res);
8318            }
8319            Operator::I32x4TruncSatF32x4S => {
8320                let (v, i) = self.state.pop1_extra()?;
8321                let v = self.apply_pending_canonicalization(v, i)?;
8322                let v = v.into_int_value();
8323                let res = self.trunc_sat_into_int(
8324                    self.intrinsics.f32x4_ty,
8325                    self.intrinsics.i32x4_ty,
8326                    LEF32_GEQ_I32_MIN,
8327                    GEF32_LEQ_I32_MAX,
8328                    i32::MIN as u64,
8329                    i32::MAX as u64,
8330                    v,
8331                )?;
8332                self.state.push1(res);
8333            }
8334            Operator::I32x4TruncSatF32x4U => {
8335                let (v, i) = self.state.pop1_extra()?;
8336                let v = self.apply_pending_canonicalization(v, i)?;
8337                let v = v.into_int_value();
8338                let res = self.trunc_sat_into_int(
8339                    self.intrinsics.f32x4_ty,
8340                    self.intrinsics.i32x4_ty,
8341                    LEF32_GEQ_U32_MIN,
8342                    GEF32_LEQ_U32_MAX,
8343                    u32::MIN as u64,
8344                    u32::MAX as u64,
8345                    v,
8346                )?;
8347                self.state.push1(res);
8348            }
8349            Operator::I32x4TruncSatF64x2SZero | Operator::I32x4TruncSatF64x2UZero => {
8350                let ((min, max), (cmp_min, cmp_max)) = match op {
8351                    Operator::I32x4TruncSatF64x2SZero => (
8352                        (i32::MIN as u64, i32::MAX as u64),
8353                        (LEF64_GEQ_I32_MIN, GEF64_LEQ_I32_MAX),
8354                    ),
8355                    Operator::I32x4TruncSatF64x2UZero => (
8356                        (u32::MIN as u64, u32::MAX as u64),
8357                        (LEF64_GEQ_U32_MIN, GEF64_LEQ_U32_MAX),
8358                    ),
8359                    _ => unreachable!("Unhandled internal variant"),
8360                };
8361                let (v, i) = self.state.pop1_extra()?;
8362                let v = self.apply_pending_canonicalization(v, i)?;
8363                let v = v.into_int_value();
8364                let res = self.trunc_sat(
8365                    self.intrinsics.f64x2_ty,
8366                    self.intrinsics.i32_ty.vec_type(2),
8367                    cmp_min,
8368                    cmp_max,
8369                    min,
8370                    max,
8371                    v,
8372                )?;
8373
8374                let zero = self.intrinsics.i32_consts[0];
8375                let zeros = VectorType::const_vector(&[zero; 2]);
8376                let res = err!(self.builder.build_shuffle_vector(
8377                    res,
8378                    zeros,
8379                    VectorType::const_vector(&[
8380                        self.intrinsics.i32_consts[0],
8381                        self.intrinsics.i32_consts[1],
8382                        self.intrinsics.i32_consts[2],
8383                        self.intrinsics.i32_consts[3],
8384                    ]),
8385                    "",
8386                ));
8387                let res = err!(
8388                    self.builder
8389                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8390                );
8391                self.state.push1(res);
8392            }
8393            // Operator::I64x2TruncSatF64x2S => {
8394            //     let (v, i) = self.state.pop1_extra()?;
8395            //     let v = self.apply_pending_canonicalization(v, i)?;
8396            //     let v = v.into_int_value();
8397            //     let res = self.trunc_sat_into_int(
8398            //         self.intrinsics.f64x2_ty,
8399            //         self.intrinsics.i64x2_ty,
8400            //         i64::MIN as u64,
8401            //         i64::MAX as u64,
8402            //         i64::MIN as u64,
8403            //         i64::MAX as u64,
8404            //         v,
8405            //     )?;
8406            //     self.state.push1(res);
8407            // }
8408            // Operator::I64x2TruncSatF64x2U => {
8409            //     let (v, i) = self.state.pop1_extra()?;
8410            //     let v = self.apply_pending_canonicalization(v, i)?;
8411            //     let v = v.into_int_value();
8412            //     let res = self.trunc_sat_into_int(
8413            //         self.intrinsics.f64x2_ty,
8414            //         self.intrinsics.i64x2_ty,
8415            //         u64::MIN,
8416            //         u64::MAX,
8417            //         u64::MIN,
8418            //         u64::MAX,
8419            //         v,
8420            //     )?;
8421            //     self.state.push1(res);
8422            // }
8423            Operator::I32TruncF32S => {
8424                let v1 = self.state.pop1()?.into_float_value();
8425                self.trap_if_not_representable_as_int(
8426                    0xcf000000, // -2147483600.0
8427                    0x4effffff, // 2147483500.0
8428                    v1,
8429                )?;
8430                let res = err!(self.builder.build_float_to_signed_int(
8431                    v1,
8432                    self.intrinsics.i32_ty,
8433                    ""
8434                ));
8435                self.state.push1(res);
8436            }
8437            Operator::I32TruncF64S => {
8438                let v1 = self.state.pop1()?.into_float_value();
8439                self.trap_if_not_representable_as_int(
8440                    0xc1e00000001fffff, // -2147483648.9999995
8441                    0x41dfffffffffffff, // 2147483647.9999998
8442                    v1,
8443                )?;
8444                let res = err!(self.builder.build_float_to_signed_int(
8445                    v1,
8446                    self.intrinsics.i32_ty,
8447                    ""
8448                ));
8449                self.state.push1(res);
8450            }
8451            Operator::I32TruncSatF32S => {
8452                let (v, i) = self.state.pop1_extra()?;
8453                let v = self.apply_pending_canonicalization(v, i)?;
8454                let v = v.into_float_value();
8455                let res = self.trunc_sat_scalar(
8456                    self.intrinsics.i32_ty,
8457                    LEF32_GEQ_I32_MIN,
8458                    GEF32_LEQ_I32_MAX,
8459                    i32::MIN as u32 as u64,
8460                    i32::MAX as u32 as u64,
8461                    v,
8462                )?;
8463                self.state.push1(res);
8464            }
8465            Operator::I32TruncSatF64S => {
8466                let (v, i) = self.state.pop1_extra()?;
8467                let v = self.apply_pending_canonicalization(v, i)?;
8468                let v = v.into_float_value();
8469                let res = self.trunc_sat_scalar(
8470                    self.intrinsics.i32_ty,
8471                    LEF64_GEQ_I32_MIN,
8472                    GEF64_LEQ_I32_MAX,
8473                    i32::MIN as u64,
8474                    i32::MAX as u64,
8475                    v,
8476                )?;
8477                self.state.push1(res);
8478            }
8479            Operator::I64TruncF32S => {
8480                let v1 = self.state.pop1()?.into_float_value();
8481                self.trap_if_not_representable_as_int(
8482                    0xdf000000, // -9223372000000000000.0
8483                    0x5effffff, // 9223371500000000000.0
8484                    v1,
8485                )?;
8486                let res = err!(self.builder.build_float_to_signed_int(
8487                    v1,
8488                    self.intrinsics.i64_ty,
8489                    ""
8490                ));
8491                self.state.push1(res);
8492            }
8493            Operator::I64TruncF64S => {
8494                let v1 = self.state.pop1()?.into_float_value();
8495                self.trap_if_not_representable_as_int(
8496                    0xc3e0000000000000, // -9223372036854776000.0
8497                    0x43dfffffffffffff, // 9223372036854775000.0
8498                    v1,
8499                )?;
8500                let res = err!(self.builder.build_float_to_signed_int(
8501                    v1,
8502                    self.intrinsics.i64_ty,
8503                    ""
8504                ));
8505                self.state.push1(res);
8506            }
8507            Operator::I64TruncSatF32S => {
8508                let (v, i) = self.state.pop1_extra()?;
8509                let v = self.apply_pending_canonicalization(v, i)?;
8510                let v = v.into_float_value();
8511                let res = self.trunc_sat_scalar(
8512                    self.intrinsics.i64_ty,
8513                    LEF32_GEQ_I64_MIN,
8514                    GEF32_LEQ_I64_MAX,
8515                    i64::MIN as u64,
8516                    i64::MAX as u64,
8517                    v,
8518                )?;
8519                self.state.push1(res);
8520            }
8521            Operator::I64TruncSatF64S => {
8522                let (v, i) = self.state.pop1_extra()?;
8523                let v = self.apply_pending_canonicalization(v, i)?;
8524                let v = v.into_float_value();
8525                let res = self.trunc_sat_scalar(
8526                    self.intrinsics.i64_ty,
8527                    LEF64_GEQ_I64_MIN,
8528                    GEF64_LEQ_I64_MAX,
8529                    i64::MIN as u64,
8530                    i64::MAX as u64,
8531                    v,
8532                )?;
8533                self.state.push1(res);
8534            }
8535            Operator::I32TruncF32U => {
8536                let v1 = self.state.pop1()?.into_float_value();
8537                self.trap_if_not_representable_as_int(
8538                    0xbf7fffff, // -0.99999994
8539                    0x4f7fffff, // 4294967000.0
8540                    v1,
8541                )?;
8542                let res = err!(self.builder.build_float_to_unsigned_int(
8543                    v1,
8544                    self.intrinsics.i32_ty,
8545                    ""
8546                ));
8547                self.state.push1(res);
8548            }
8549            Operator::I32TruncF64U => {
8550                let v1 = self.state.pop1()?.into_float_value();
8551                self.trap_if_not_representable_as_int(
8552                    0xbfefffffffffffff, // -0.9999999999999999
8553                    0x41efffffffffffff, // 4294967295.9999995
8554                    v1,
8555                )?;
8556                let res = err!(self.builder.build_float_to_unsigned_int(
8557                    v1,
8558                    self.intrinsics.i32_ty,
8559                    ""
8560                ));
8561                self.state.push1(res);
8562            }
8563            Operator::I32TruncSatF32U => {
8564                let (v, i) = self.state.pop1_extra()?;
8565                let v = self.apply_pending_canonicalization(v, i)?;
8566                let v = v.into_float_value();
8567                let res = self.trunc_sat_scalar(
8568                    self.intrinsics.i32_ty,
8569                    LEF32_GEQ_U32_MIN,
8570                    GEF32_LEQ_U32_MAX,
8571                    u32::MIN as u64,
8572                    u32::MAX as u64,
8573                    v,
8574                )?;
8575                self.state.push1(res);
8576            }
8577            Operator::I32TruncSatF64U => {
8578                let (v, i) = self.state.pop1_extra()?;
8579                let v = self.apply_pending_canonicalization(v, i)?;
8580                let v = v.into_float_value();
8581                let res = self.trunc_sat_scalar(
8582                    self.intrinsics.i32_ty,
8583                    LEF64_GEQ_U32_MIN,
8584                    GEF64_LEQ_U32_MAX,
8585                    u32::MIN as u64,
8586                    u32::MAX as u64,
8587                    v,
8588                )?;
8589                self.state.push1(res);
8590            }
8591            Operator::I64TruncF32U => {
8592                let v1 = self.state.pop1()?.into_float_value();
8593                self.trap_if_not_representable_as_int(
8594                    0xbf7fffff, // -0.99999994
8595                    0x5f7fffff, // 18446743000000000000.0
8596                    v1,
8597                )?;
8598                let res = err!(self.builder.build_float_to_unsigned_int(
8599                    v1,
8600                    self.intrinsics.i64_ty,
8601                    ""
8602                ));
8603                self.state.push1(res);
8604            }
8605            Operator::I64TruncF64U => {
8606                let v1 = self.state.pop1()?.into_float_value();
8607                self.trap_if_not_representable_as_int(
8608                    0xbfefffffffffffff, // -0.9999999999999999
8609                    0x43efffffffffffff, // 18446744073709550000.0
8610                    v1,
8611                )?;
8612                let res = err!(self.builder.build_float_to_unsigned_int(
8613                    v1,
8614                    self.intrinsics.i64_ty,
8615                    ""
8616                ));
8617                self.state.push1(res);
8618            }
8619            Operator::I64TruncSatF32U => {
8620                let (v, i) = self.state.pop1_extra()?;
8621                let v = self.apply_pending_canonicalization(v, i)?;
8622                let v = v.into_float_value();
8623                let res = self.trunc_sat_scalar(
8624                    self.intrinsics.i64_ty,
8625                    LEF32_GEQ_U64_MIN,
8626                    GEF32_LEQ_U64_MAX,
8627                    u64::MIN,
8628                    u64::MAX,
8629                    v,
8630                )?;
8631                self.state.push1(res);
8632            }
8633            Operator::I64TruncSatF64U => {
8634                let (v, i) = self.state.pop1_extra()?;
8635                let v = self.apply_pending_canonicalization(v, i)?;
8636                let v = v.into_float_value();
8637                let res = self.trunc_sat_scalar(
8638                    self.intrinsics.i64_ty,
8639                    LEF64_GEQ_U64_MIN,
8640                    GEF64_LEQ_U64_MAX,
8641                    u64::MIN,
8642                    u64::MAX,
8643                    v,
8644                )?;
8645                self.state.push1(res);
8646            }
8647            Operator::F32DemoteF64 => {
8648                let v = self.state.pop1()?;
8649                let v = v.into_float_value();
8650                let res = err!(self.builder.build_call(
8651                    self.intrinsics.fptrunc_f64,
8652                    &[
8653                        v.into(),
8654                        self.intrinsics.fp_rounding_md,
8655                        self.intrinsics.fp_exception_md,
8656                    ],
8657                    "",
8658                ))
8659                .try_as_basic_value()
8660                .left()
8661                .unwrap();
8662                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8663            }
8664            Operator::F64PromoteF32 => {
8665                let v = self.state.pop1()?;
8666                let v = v.into_float_value();
8667                let res = err!(self.builder.build_call(
8668                    self.intrinsics.fpext_f32,
8669                    &[v.into(), self.intrinsics.fp_exception_md],
8670                    "",
8671                ))
8672                .try_as_basic_value()
8673                .left()
8674                .unwrap();
8675                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8676            }
8677            Operator::F32ConvertI32S | Operator::F32ConvertI64S => {
8678                let (v, i) = self.state.pop1_extra()?;
8679                let v = self.apply_pending_canonicalization(v, i)?;
8680                let v = v.into_int_value();
8681                let res = err!(self.builder.build_signed_int_to_float(
8682                    v,
8683                    self.intrinsics.f32_ty,
8684                    ""
8685                ));
8686                self.state.push1(res);
8687            }
8688            Operator::F64ConvertI32S | Operator::F64ConvertI64S => {
8689                let (v, i) = self.state.pop1_extra()?;
8690                let v = self.apply_pending_canonicalization(v, i)?;
8691                let v = v.into_int_value();
8692                let res = err!(self.builder.build_signed_int_to_float(
8693                    v,
8694                    self.intrinsics.f64_ty,
8695                    ""
8696                ));
8697                self.state.push1(res);
8698            }
8699            Operator::F32ConvertI32U | Operator::F32ConvertI64U => {
8700                let (v, i) = self.state.pop1_extra()?;
8701                let v = self.apply_pending_canonicalization(v, i)?;
8702                let v = v.into_int_value();
8703                let res = err!(self.builder.build_unsigned_int_to_float(
8704                    v,
8705                    self.intrinsics.f32_ty,
8706                    ""
8707                ));
8708                self.state.push1(res);
8709            }
8710            Operator::F64ConvertI32U | Operator::F64ConvertI64U => {
8711                let (v, i) = self.state.pop1_extra()?;
8712                let v = self.apply_pending_canonicalization(v, i)?;
8713                let v = v.into_int_value();
8714                let res = err!(self.builder.build_unsigned_int_to_float(
8715                    v,
8716                    self.intrinsics.f64_ty,
8717                    ""
8718                ));
8719                self.state.push1(res);
8720            }
8721            Operator::F32x4ConvertI32x4S => {
8722                let v = self.state.pop1()?;
8723                let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8724                    .into_vector_value();
8725                let res = err!(self.builder.build_signed_int_to_float(
8726                    v,
8727                    self.intrinsics.f32x4_ty,
8728                    ""
8729                ));
8730                let res = err!(
8731                    self.builder
8732                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8733                );
8734                self.state.push1(res);
8735            }
8736            Operator::F32x4ConvertI32x4U => {
8737                let v = self.state.pop1()?;
8738                let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8739                    .into_vector_value();
8740                let res = err!(self.builder.build_unsigned_int_to_float(
8741                    v,
8742                    self.intrinsics.f32x4_ty,
8743                    ""
8744                ));
8745                let res = err!(
8746                    self.builder
8747                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8748                );
8749                self.state.push1(res);
8750            }
8751            Operator::F64x2ConvertLowI32x4S | Operator::F64x2ConvertLowI32x4U => {
8752                let extend = match op {
8753                    Operator::F64x2ConvertLowI32x4U => {
8754                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8755                    }
8756                    Operator::F64x2ConvertLowI32x4S => {
8757                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8758                    }
8759                    _ => unreachable!("Unhandled inner case"),
8760                };
8761                let (v, i) = self.state.pop1_extra()?;
8762                let (v, _) = self.v128_into_i32x4(v, i)?;
8763                let low = err!(self.builder.build_shuffle_vector(
8764                    v,
8765                    v.get_type().get_undef(),
8766                    VectorType::const_vector(&[
8767                        self.intrinsics.i32_consts[0],
8768                        self.intrinsics.i32_consts[1],
8769                    ]),
8770                    "",
8771                ));
8772                let res = err!(extend(self, low));
8773                let res = err!(self.builder.build_signed_int_to_float(
8774                    res,
8775                    self.intrinsics.f64x2_ty,
8776                    ""
8777                ));
8778                let res = err!(
8779                    self.builder
8780                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8781                );
8782                self.state.push1(res);
8783            }
8784            Operator::F64x2PromoteLowF32x4 => {
8785                let (v, i) = self.state.pop1_extra()?;
8786                let (v, _) = self.v128_into_f32x4(v, i)?;
8787                let low = err!(self.builder.build_shuffle_vector(
8788                    v,
8789                    v.get_type().get_undef(),
8790                    VectorType::const_vector(&[
8791                        self.intrinsics.i32_consts[0],
8792                        self.intrinsics.i32_consts[1],
8793                    ]),
8794                    "",
8795                ));
8796                let res = err!(
8797                    self.builder
8798                        .build_float_ext(low, self.intrinsics.f64x2_ty, "")
8799                );
8800                let res = err!(
8801                    self.builder
8802                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8803                );
8804                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8805            }
8806            Operator::F32x4DemoteF64x2Zero => {
8807                let (v, i) = self.state.pop1_extra()?;
8808                let (v, _) = self.v128_into_f64x2(v, i)?;
8809                let f32x2_ty = self.intrinsics.f32_ty.vec_type(2);
8810                let res = err!(self.builder.build_float_trunc(v, f32x2_ty, ""));
8811                let zeros = f32x2_ty.const_zero();
8812                let res = err!(self.builder.build_shuffle_vector(
8813                    res,
8814                    zeros,
8815                    VectorType::const_vector(&[
8816                        self.intrinsics.i32_consts[0],
8817                        self.intrinsics.i32_consts[1],
8818                        self.intrinsics.i32_consts[2],
8819                        self.intrinsics.i32_consts[3],
8820                    ]),
8821                    "",
8822                ));
8823                let res = err!(
8824                    self.builder
8825                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8826                );
8827                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8828            }
8829            // Operator::F64x2ConvertI64x2S => {
8830            //     let v = self.state.pop1()?;
8831            //     let v = self
8832            //         .builder
8833            //         .build_bit_cast(v, self.intrinsics.i64x2_ty, "")
8834            //         .into_vector_value();
8835            //     let res = self
8836            //         .builder
8837            //         .build_signed_int_to_float(v, self.intrinsics.f64x2_ty, "");
8838            //     let res = chck_err!(self.builder.build_bit_cast(res, self.intrinsics.i128_ty, ""));
8839            //     self.state.push1(res);
8840            // }
8841            // Operator::F64x2ConvertI64x2U => {
8842            //     let v = self.state.pop1()?;
8843            //     let v = self
8844            //         .builder
8845            //         .build_bit_cast(v, self.intrinsics.i64x2_ty, "")
8846            //         .into_vector_value();
8847            //     let res = self
8848            //         .builder
8849            //         .build_unsigned_int_to_float(v, self.intrinsics.f64x2_ty, "");
8850            //     let res = chck_err!(self.builder.build_bit_cast(res, self.intrinsics.i128_ty, ""));
8851            //     self.state.push1(res);
8852            // }
8853            Operator::I32ReinterpretF32 => {
8854                let (v, i) = self.state.pop1_extra()?;
8855                let v = self.apply_pending_canonicalization(v, i)?;
8856                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i32_ty, ""));
8857                self.state.push1_extra(ret, ExtraInfo::arithmetic_f32());
8858            }
8859            Operator::I64ReinterpretF64 => {
8860                let (v, i) = self.state.pop1_extra()?;
8861                let v = self.apply_pending_canonicalization(v, i)?;
8862                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i64_ty, ""));
8863                self.state.push1_extra(ret, ExtraInfo::arithmetic_f64());
8864            }
8865            Operator::F32ReinterpretI32 => {
8866                let (v, i) = self.state.pop1_extra()?;
8867                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f32_ty, ""));
8868                self.state.push1_extra(ret, i);
8869            }
8870            Operator::F64ReinterpretI64 => {
8871                let (v, i) = self.state.pop1_extra()?;
8872                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f64_ty, ""));
8873                self.state.push1_extra(ret, i);
8874            }
8875
8876            /***************************
8877             * Sign-extension operators.
8878             * https://github.com/WebAssembly/sign-extension-ops/blob/master/proposals/sign-extension-ops/Overview.md
8879             ***************************/
8880            Operator::I32Extend8S => {
8881                let value = self.state.pop1()?.into_int_value();
8882                let narrow_value = err!(self.builder.build_int_truncate(
8883                    value,
8884                    self.intrinsics.i8_ty,
8885                    ""
8886                ));
8887                let extended_value = err!(self.builder.build_int_s_extend(
8888                    narrow_value,
8889                    self.intrinsics.i32_ty,
8890                    ""
8891                ));
8892                self.state.push1(extended_value);
8893            }
8894            Operator::I32Extend16S => {
8895                let value = self.state.pop1()?.into_int_value();
8896                let narrow_value = err!(self.builder.build_int_truncate(
8897                    value,
8898                    self.intrinsics.i16_ty,
8899                    ""
8900                ));
8901                let extended_value = err!(self.builder.build_int_s_extend(
8902                    narrow_value,
8903                    self.intrinsics.i32_ty,
8904                    ""
8905                ));
8906                self.state.push1(extended_value);
8907            }
8908            Operator::I64Extend8S => {
8909                let value = self.state.pop1()?.into_int_value();
8910                let narrow_value = err!(self.builder.build_int_truncate(
8911                    value,
8912                    self.intrinsics.i8_ty,
8913                    ""
8914                ));
8915                let extended_value = err!(self.builder.build_int_s_extend(
8916                    narrow_value,
8917                    self.intrinsics.i64_ty,
8918                    ""
8919                ));
8920                self.state.push1(extended_value);
8921            }
8922            Operator::I64Extend16S => {
8923                let value = self.state.pop1()?.into_int_value();
8924                let narrow_value = err!(self.builder.build_int_truncate(
8925                    value,
8926                    self.intrinsics.i16_ty,
8927                    ""
8928                ));
8929                let extended_value = err!(self.builder.build_int_s_extend(
8930                    narrow_value,
8931                    self.intrinsics.i64_ty,
8932                    ""
8933                ));
8934                self.state.push1(extended_value);
8935            }
8936            Operator::I64Extend32S => {
8937                let value = self.state.pop1()?.into_int_value();
8938                let narrow_value = err!(self.builder.build_int_truncate(
8939                    value,
8940                    self.intrinsics.i32_ty,
8941                    ""
8942                ));
8943                let extended_value = err!(self.builder.build_int_s_extend(
8944                    narrow_value,
8945                    self.intrinsics.i64_ty,
8946                    ""
8947                ));
8948                self.state.push1(extended_value);
8949            }
8950
8951            /***************************
8952             * Load and Store instructions.
8953             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#load-and-store-instructions
8954             ***************************/
8955            Operator::I32Load { ref memarg } => {
8956                let offset = self.state.pop1()?.into_int_value();
8957                let memory_index = MemoryIndex::from_u32(0);
8958                let effective_address = self.resolve_memory_ptr(
8959                    memory_index,
8960                    memarg,
8961                    self.intrinsics.ptr_ty,
8962                    offset,
8963                    4,
8964                )?;
8965                let result = err!(self.builder.build_load(
8966                    self.intrinsics.i32_ty,
8967                    effective_address,
8968                    ""
8969                ));
8970                self.annotate_user_memaccess(
8971                    memory_index,
8972                    memarg,
8973                    1,
8974                    result.as_instruction_value().unwrap(),
8975                )?;
8976                self.state.push1(result);
8977            }
8978            Operator::I64Load { ref memarg } => {
8979                let offset = self.state.pop1()?.into_int_value();
8980                let memory_index = MemoryIndex::from_u32(0);
8981                let effective_address = self.resolve_memory_ptr(
8982                    memory_index,
8983                    memarg,
8984                    self.intrinsics.ptr_ty,
8985                    offset,
8986                    8,
8987                )?;
8988                let result = err!(self.builder.build_load(
8989                    self.intrinsics.i64_ty,
8990                    effective_address,
8991                    ""
8992                ));
8993                self.annotate_user_memaccess(
8994                    memory_index,
8995                    memarg,
8996                    1,
8997                    result.as_instruction_value().unwrap(),
8998                )?;
8999                self.state.push1(result);
9000            }
9001            Operator::F32Load { ref memarg } => {
9002                let offset = self.state.pop1()?.into_int_value();
9003                let memory_index = MemoryIndex::from_u32(0);
9004                let effective_address = self.resolve_memory_ptr(
9005                    memory_index,
9006                    memarg,
9007                    self.intrinsics.ptr_ty,
9008                    offset,
9009                    4,
9010                )?;
9011                let result = err!(self.builder.build_load(
9012                    self.intrinsics.f32_ty,
9013                    effective_address,
9014                    ""
9015                ));
9016                self.annotate_user_memaccess(
9017                    memory_index,
9018                    memarg,
9019                    1,
9020                    result.as_instruction_value().unwrap(),
9021                )?;
9022                self.state.push1(result);
9023            }
9024            Operator::F64Load { ref memarg } => {
9025                let offset = self.state.pop1()?.into_int_value();
9026                let memory_index = MemoryIndex::from_u32(0);
9027                let effective_address = self.resolve_memory_ptr(
9028                    memory_index,
9029                    memarg,
9030                    self.intrinsics.ptr_ty,
9031                    offset,
9032                    8,
9033                )?;
9034                let result = err!(self.builder.build_load(
9035                    self.intrinsics.f64_ty,
9036                    effective_address,
9037                    ""
9038                ));
9039                self.annotate_user_memaccess(
9040                    memory_index,
9041                    memarg,
9042                    1,
9043                    result.as_instruction_value().unwrap(),
9044                )?;
9045                self.state.push1(result);
9046            }
9047            Operator::V128Load { ref memarg } => {
9048                let offset = self.state.pop1()?.into_int_value();
9049                let memory_index = MemoryIndex::from_u32(0);
9050                let effective_address = self.resolve_memory_ptr(
9051                    memory_index,
9052                    memarg,
9053                    self.intrinsics.ptr_ty,
9054                    offset,
9055                    16,
9056                )?;
9057                let result = err!(self.builder.build_load(
9058                    self.intrinsics.i128_ty,
9059                    effective_address,
9060                    ""
9061                ));
9062                self.annotate_user_memaccess(
9063                    memory_index,
9064                    memarg,
9065                    1,
9066                    result.as_instruction_value().unwrap(),
9067                )?;
9068                self.state.push1(result);
9069            }
9070            Operator::V128Load8Lane { ref memarg, lane } => {
9071                let (v, i) = self.state.pop1_extra()?;
9072                let (v, _i) = self.v128_into_i8x16(v, i)?;
9073                let offset = self.state.pop1()?.into_int_value();
9074                let memory_index = MemoryIndex::from_u32(memarg.memory);
9075                let effective_address = self.resolve_memory_ptr(
9076                    memory_index,
9077                    memarg,
9078                    self.intrinsics.ptr_ty,
9079                    offset,
9080                    1,
9081                )?;
9082                let element = err!(self.builder.build_load(
9083                    self.intrinsics.i8_ty,
9084                    effective_address,
9085                    ""
9086                ));
9087                self.annotate_user_memaccess(
9088                    memory_index,
9089                    memarg,
9090                    1,
9091                    element.as_instruction_value().unwrap(),
9092                )?;
9093                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9094                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9095                let res = err!(
9096                    self.builder
9097                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9098                );
9099                self.state.push1(res);
9100            }
9101            Operator::V128Load16Lane { ref memarg, lane } => {
9102                let (v, i) = self.state.pop1_extra()?;
9103                let (v, i) = self.v128_into_i16x8(v, i)?;
9104                let offset = self.state.pop1()?.into_int_value();
9105                let memory_index = MemoryIndex::from_u32(memarg.memory);
9106                let effective_address = self.resolve_memory_ptr(
9107                    memory_index,
9108                    memarg,
9109                    self.intrinsics.ptr_ty,
9110                    offset,
9111                    2,
9112                )?;
9113                let element = err!(self.builder.build_load(
9114                    self.intrinsics.i16_ty,
9115                    effective_address,
9116                    ""
9117                ));
9118                self.annotate_user_memaccess(
9119                    memory_index,
9120                    memarg,
9121                    1,
9122                    element.as_instruction_value().unwrap(),
9123                )?;
9124                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9125                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9126                let res = err!(
9127                    self.builder
9128                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9129                );
9130                self.state.push1_extra(res, i);
9131            }
9132            Operator::V128Load32Lane { ref memarg, lane } => {
9133                let (v, i) = self.state.pop1_extra()?;
9134                let (v, i) = self.v128_into_i32x4(v, i)?;
9135                let offset = self.state.pop1()?.into_int_value();
9136                let memory_index = MemoryIndex::from_u32(memarg.memory);
9137                let effective_address = self.resolve_memory_ptr(
9138                    memory_index,
9139                    memarg,
9140                    self.intrinsics.ptr_ty,
9141                    offset,
9142                    4,
9143                )?;
9144                let element = err!(self.builder.build_load(
9145                    self.intrinsics.i32_ty,
9146                    effective_address,
9147                    ""
9148                ));
9149                self.annotate_user_memaccess(
9150                    memory_index,
9151                    memarg,
9152                    1,
9153                    element.as_instruction_value().unwrap(),
9154                )?;
9155                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9156                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9157                let res = err!(
9158                    self.builder
9159                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9160                );
9161                self.state.push1_extra(res, i);
9162            }
9163            Operator::V128Load64Lane { ref memarg, lane } => {
9164                let (v, i) = self.state.pop1_extra()?;
9165                let (v, i) = self.v128_into_i64x2(v, i)?;
9166                let offset = self.state.pop1()?.into_int_value();
9167                let memory_index = MemoryIndex::from_u32(memarg.memory);
9168                let effective_address = self.resolve_memory_ptr(
9169                    memory_index,
9170                    memarg,
9171                    self.intrinsics.ptr_ty,
9172                    offset,
9173                    8,
9174                )?;
9175                let element = err!(self.builder.build_load(
9176                    self.intrinsics.i64_ty,
9177                    effective_address,
9178                    ""
9179                ));
9180                self.annotate_user_memaccess(
9181                    memory_index,
9182                    memarg,
9183                    1,
9184                    element.as_instruction_value().unwrap(),
9185                )?;
9186                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9187                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9188                let res = err!(
9189                    self.builder
9190                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9191                );
9192                self.state.push1_extra(res, i);
9193            }
9194
9195            Operator::I32Store { ref memarg } => {
9196                let value = self.state.pop1()?;
9197                let offset = self.state.pop1()?.into_int_value();
9198                let memory_index = MemoryIndex::from_u32(0);
9199                let effective_address = self.resolve_memory_ptr(
9200                    memory_index,
9201                    memarg,
9202                    self.intrinsics.ptr_ty,
9203                    offset,
9204                    4,
9205                )?;
9206                let dead_load = err!(self.builder.build_load(
9207                    self.intrinsics.i32_ty,
9208                    effective_address,
9209                    ""
9210                ));
9211                self.annotate_user_memaccess(
9212                    memory_index,
9213                    memarg,
9214                    1,
9215                    dead_load.as_instruction_value().unwrap(),
9216                )?;
9217                let store = err!(self.builder.build_store(effective_address, value));
9218                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9219            }
9220            Operator::I64Store { ref memarg } => {
9221                let value = self.state.pop1()?;
9222                let offset = self.state.pop1()?.into_int_value();
9223                let memory_index = MemoryIndex::from_u32(0);
9224                let effective_address = self.resolve_memory_ptr(
9225                    memory_index,
9226                    memarg,
9227                    self.intrinsics.ptr_ty,
9228                    offset,
9229                    8,
9230                )?;
9231                let dead_load = err!(self.builder.build_load(
9232                    self.intrinsics.i64_ty,
9233                    effective_address,
9234                    ""
9235                ));
9236                self.annotate_user_memaccess(
9237                    memory_index,
9238                    memarg,
9239                    1,
9240                    dead_load.as_instruction_value().unwrap(),
9241                )?;
9242                let store = err!(self.builder.build_store(effective_address, value));
9243                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9244            }
9245            Operator::F32Store { ref memarg } => {
9246                let (v, i) = self.state.pop1_extra()?;
9247                let v = self.apply_pending_canonicalization(v, i)?;
9248                let offset = self.state.pop1()?.into_int_value();
9249                let memory_index = MemoryIndex::from_u32(0);
9250                let effective_address = self.resolve_memory_ptr(
9251                    memory_index,
9252                    memarg,
9253                    self.intrinsics.ptr_ty,
9254                    offset,
9255                    4,
9256                )?;
9257                let dead_load = err!(self.builder.build_load(
9258                    self.intrinsics.f32_ty,
9259                    effective_address,
9260                    ""
9261                ));
9262                self.annotate_user_memaccess(
9263                    memory_index,
9264                    memarg,
9265                    1,
9266                    dead_load.as_instruction_value().unwrap(),
9267                )?;
9268                let store = err!(self.builder.build_store(effective_address, v));
9269                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9270            }
9271            Operator::F64Store { ref memarg } => {
9272                let (v, i) = self.state.pop1_extra()?;
9273                let v = self.apply_pending_canonicalization(v, i)?;
9274                let offset = self.state.pop1()?.into_int_value();
9275                let memory_index = MemoryIndex::from_u32(0);
9276                let effective_address = self.resolve_memory_ptr(
9277                    memory_index,
9278                    memarg,
9279                    self.intrinsics.ptr_ty,
9280                    offset,
9281                    8,
9282                )?;
9283                let dead_load = err!(self.builder.build_load(
9284                    self.intrinsics.f64_ty,
9285                    effective_address,
9286                    ""
9287                ));
9288                self.annotate_user_memaccess(
9289                    memory_index,
9290                    memarg,
9291                    1,
9292                    dead_load.as_instruction_value().unwrap(),
9293                )?;
9294                let store = err!(self.builder.build_store(effective_address, v));
9295                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9296            }
9297            Operator::V128Store { ref memarg } => {
9298                let (v, i) = self.state.pop1_extra()?;
9299                let v = self.apply_pending_canonicalization(v, i)?;
9300                let offset = self.state.pop1()?.into_int_value();
9301                let memory_index = MemoryIndex::from_u32(0);
9302                let effective_address = self.resolve_memory_ptr(
9303                    memory_index,
9304                    memarg,
9305                    self.intrinsics.ptr_ty,
9306                    offset,
9307                    16,
9308                )?;
9309                let dead_load = err!(self.builder.build_load(
9310                    self.intrinsics.i128_ty,
9311                    effective_address,
9312                    ""
9313                ));
9314                self.annotate_user_memaccess(
9315                    memory_index,
9316                    memarg,
9317                    1,
9318                    dead_load.as_instruction_value().unwrap(),
9319                )?;
9320                let store = err!(self.builder.build_store(effective_address, v));
9321                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9322            }
9323            Operator::V128Store8Lane { ref memarg, lane } => {
9324                let (v, i) = self.state.pop1_extra()?;
9325                let (v, _i) = self.v128_into_i8x16(v, i)?;
9326                let offset = self.state.pop1()?.into_int_value();
9327                let memory_index = MemoryIndex::from_u32(memarg.memory);
9328
9329                let effective_address = self.resolve_memory_ptr(
9330                    memory_index,
9331                    memarg,
9332                    self.intrinsics.ptr_ty,
9333                    offset,
9334                    1,
9335                )?;
9336                let dead_load = err!(self.builder.build_load(
9337                    self.intrinsics.i8_ty,
9338                    effective_address,
9339                    ""
9340                ));
9341                self.annotate_user_memaccess(
9342                    memory_index,
9343                    memarg,
9344                    1,
9345                    dead_load.as_instruction_value().unwrap(),
9346                )?;
9347                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9348                let val = err!(self.builder.build_extract_element(v, idx, ""));
9349                let store = err!(self.builder.build_store(effective_address, val));
9350                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9351            }
9352            Operator::V128Store16Lane { ref memarg, lane } => {
9353                let (v, i) = self.state.pop1_extra()?;
9354                let (v, _i) = self.v128_into_i16x8(v, i)?;
9355                let offset = self.state.pop1()?.into_int_value();
9356                let memory_index = MemoryIndex::from_u32(memarg.memory);
9357
9358                let effective_address = self.resolve_memory_ptr(
9359                    memory_index,
9360                    memarg,
9361                    self.intrinsics.ptr_ty,
9362                    offset,
9363                    2,
9364                )?;
9365                let dead_load = err!(self.builder.build_load(
9366                    self.intrinsics.i16_ty,
9367                    effective_address,
9368                    ""
9369                ));
9370                self.annotate_user_memaccess(
9371                    memory_index,
9372                    memarg,
9373                    1,
9374                    dead_load.as_instruction_value().unwrap(),
9375                )?;
9376                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9377                let val = err!(self.builder.build_extract_element(v, idx, ""));
9378                let store = err!(self.builder.build_store(effective_address, val));
9379                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9380            }
9381            Operator::V128Store32Lane { ref memarg, lane } => {
9382                let (v, i) = self.state.pop1_extra()?;
9383                let (v, _i) = self.v128_into_i32x4(v, i)?;
9384                let offset = self.state.pop1()?.into_int_value();
9385                let memory_index = MemoryIndex::from_u32(memarg.memory);
9386
9387                let effective_address = self.resolve_memory_ptr(
9388                    memory_index,
9389                    memarg,
9390                    self.intrinsics.ptr_ty,
9391                    offset,
9392                    4,
9393                )?;
9394                let dead_load = err!(self.builder.build_load(
9395                    self.intrinsics.i32_ty,
9396                    effective_address,
9397                    ""
9398                ));
9399                self.annotate_user_memaccess(
9400                    memory_index,
9401                    memarg,
9402                    1,
9403                    dead_load.as_instruction_value().unwrap(),
9404                )?;
9405                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9406                let val = err!(self.builder.build_extract_element(v, idx, ""));
9407                let store = err!(self.builder.build_store(effective_address, val));
9408                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9409            }
9410            Operator::V128Store64Lane { ref memarg, lane } => {
9411                let (v, i) = self.state.pop1_extra()?;
9412                let (v, _i) = self.v128_into_i64x2(v, i)?;
9413                let offset = self.state.pop1()?.into_int_value();
9414                let memory_index = MemoryIndex::from_u32(memarg.memory);
9415
9416                let effective_address = self.resolve_memory_ptr(
9417                    memory_index,
9418                    memarg,
9419                    self.intrinsics.ptr_ty,
9420                    offset,
9421                    8,
9422                )?;
9423                let dead_load = err!(self.builder.build_load(
9424                    self.intrinsics.i64_ty,
9425                    effective_address,
9426                    ""
9427                ));
9428                self.annotate_user_memaccess(
9429                    memory_index,
9430                    memarg,
9431                    1,
9432                    dead_load.as_instruction_value().unwrap(),
9433                )?;
9434                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9435                let val = err!(self.builder.build_extract_element(v, idx, ""));
9436                let store = err!(self.builder.build_store(effective_address, val));
9437                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9438            }
9439            Operator::I32Load8S { ref memarg } => {
9440                let offset = self.state.pop1()?.into_int_value();
9441                let memory_index = MemoryIndex::from_u32(0);
9442                let effective_address = self.resolve_memory_ptr(
9443                    memory_index,
9444                    memarg,
9445                    self.intrinsics.ptr_ty,
9446                    offset,
9447                    1,
9448                )?;
9449                let narrow_result = err!(self.builder.build_load(
9450                    self.intrinsics.i8_ty,
9451                    effective_address,
9452                    ""
9453                ));
9454                self.annotate_user_memaccess(
9455                    memory_index,
9456                    memarg,
9457                    1,
9458                    narrow_result.as_instruction_value().unwrap(),
9459                )?;
9460                let result = err!(self.builder.build_int_s_extend(
9461                    narrow_result.into_int_value(),
9462                    self.intrinsics.i32_ty,
9463                    "",
9464                ));
9465                self.state.push1(result);
9466            }
9467            Operator::I32Load16S { ref memarg } => {
9468                let offset = self.state.pop1()?.into_int_value();
9469                let memory_index = MemoryIndex::from_u32(0);
9470                let effective_address = self.resolve_memory_ptr(
9471                    memory_index,
9472                    memarg,
9473                    self.intrinsics.ptr_ty,
9474                    offset,
9475                    2,
9476                )?;
9477                let narrow_result = err!(self.builder.build_load(
9478                    self.intrinsics.i16_ty,
9479                    effective_address,
9480                    ""
9481                ));
9482                self.annotate_user_memaccess(
9483                    memory_index,
9484                    memarg,
9485                    1,
9486                    narrow_result.as_instruction_value().unwrap(),
9487                )?;
9488                let result = err!(self.builder.build_int_s_extend(
9489                    narrow_result.into_int_value(),
9490                    self.intrinsics.i32_ty,
9491                    "",
9492                ));
9493                self.state.push1(result);
9494            }
9495            Operator::I64Load8S { ref memarg } => {
9496                let offset = self.state.pop1()?.into_int_value();
9497                let memory_index = MemoryIndex::from_u32(0);
9498                let effective_address = self.resolve_memory_ptr(
9499                    memory_index,
9500                    memarg,
9501                    self.intrinsics.ptr_ty,
9502                    offset,
9503                    1,
9504                )?;
9505                let narrow_result = err!(self.builder.build_load(
9506                    self.intrinsics.i8_ty,
9507                    effective_address,
9508                    ""
9509                ))
9510                .into_int_value();
9511                self.annotate_user_memaccess(
9512                    memory_index,
9513                    memarg,
9514                    1,
9515                    narrow_result.as_instruction_value().unwrap(),
9516                )?;
9517                let result = err!(self.builder.build_int_s_extend(
9518                    narrow_result,
9519                    self.intrinsics.i64_ty,
9520                    ""
9521                ));
9522                self.state.push1(result);
9523            }
9524            Operator::I64Load16S { ref memarg } => {
9525                let offset = self.state.pop1()?.into_int_value();
9526                let memory_index = MemoryIndex::from_u32(0);
9527                let effective_address = self.resolve_memory_ptr(
9528                    memory_index,
9529                    memarg,
9530                    self.intrinsics.ptr_ty,
9531                    offset,
9532                    2,
9533                )?;
9534                let narrow_result = err!(self.builder.build_load(
9535                    self.intrinsics.i16_ty,
9536                    effective_address,
9537                    ""
9538                ))
9539                .into_int_value();
9540                self.annotate_user_memaccess(
9541                    memory_index,
9542                    memarg,
9543                    1,
9544                    narrow_result.as_instruction_value().unwrap(),
9545                )?;
9546                let result = err!(self.builder.build_int_s_extend(
9547                    narrow_result,
9548                    self.intrinsics.i64_ty,
9549                    ""
9550                ));
9551                self.state.push1(result);
9552            }
9553            Operator::I64Load32S { ref memarg } => {
9554                let offset = self.state.pop1()?.into_int_value();
9555                let memory_index = MemoryIndex::from_u32(0);
9556                let effective_address = self.resolve_memory_ptr(
9557                    memory_index,
9558                    memarg,
9559                    self.intrinsics.ptr_ty,
9560                    offset,
9561                    4,
9562                )?;
9563                let narrow_result = err!(self.builder.build_load(
9564                    self.intrinsics.i32_ty,
9565                    effective_address,
9566                    ""
9567                ));
9568                self.annotate_user_memaccess(
9569                    memory_index,
9570                    memarg,
9571                    1,
9572                    narrow_result.as_instruction_value().unwrap(),
9573                )?;
9574                let result = err!(self.builder.build_int_s_extend(
9575                    narrow_result.into_int_value(),
9576                    self.intrinsics.i64_ty,
9577                    "",
9578                ));
9579                self.state.push1(result);
9580            }
9581
9582            Operator::I32Load8U { ref memarg } => {
9583                let offset = self.state.pop1()?.into_int_value();
9584                let memory_index = MemoryIndex::from_u32(0);
9585                let effective_address = self.resolve_memory_ptr(
9586                    memory_index,
9587                    memarg,
9588                    self.intrinsics.ptr_ty,
9589                    offset,
9590                    1,
9591                )?;
9592                let narrow_result = err!(self.builder.build_load(
9593                    self.intrinsics.i8_ty,
9594                    effective_address,
9595                    ""
9596                ));
9597                self.annotate_user_memaccess(
9598                    memory_index,
9599                    memarg,
9600                    1,
9601                    narrow_result.as_instruction_value().unwrap(),
9602                )?;
9603                let result = err!(self.builder.build_int_z_extend(
9604                    narrow_result.into_int_value(),
9605                    self.intrinsics.i32_ty,
9606                    "",
9607                ));
9608                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9609            }
9610            Operator::I32Load16U { ref memarg } => {
9611                let offset = self.state.pop1()?.into_int_value();
9612                let memory_index = MemoryIndex::from_u32(0);
9613                let effective_address = self.resolve_memory_ptr(
9614                    memory_index,
9615                    memarg,
9616                    self.intrinsics.ptr_ty,
9617                    offset,
9618                    2,
9619                )?;
9620                let narrow_result = err!(self.builder.build_load(
9621                    self.intrinsics.i16_ty,
9622                    effective_address,
9623                    ""
9624                ));
9625                self.annotate_user_memaccess(
9626                    memory_index,
9627                    memarg,
9628                    1,
9629                    narrow_result.as_instruction_value().unwrap(),
9630                )?;
9631                let result = err!(self.builder.build_int_z_extend(
9632                    narrow_result.into_int_value(),
9633                    self.intrinsics.i32_ty,
9634                    "",
9635                ));
9636                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9637            }
9638            Operator::I64Load8U { ref memarg } => {
9639                let offset = self.state.pop1()?.into_int_value();
9640                let memory_index = MemoryIndex::from_u32(0);
9641                let effective_address = self.resolve_memory_ptr(
9642                    memory_index,
9643                    memarg,
9644                    self.intrinsics.ptr_ty,
9645                    offset,
9646                    1,
9647                )?;
9648                let narrow_result = err!(self.builder.build_load(
9649                    self.intrinsics.i8_ty,
9650                    effective_address,
9651                    ""
9652                ));
9653                self.annotate_user_memaccess(
9654                    memory_index,
9655                    memarg,
9656                    1,
9657                    narrow_result.as_instruction_value().unwrap(),
9658                )?;
9659                let result = err!(self.builder.build_int_z_extend(
9660                    narrow_result.into_int_value(),
9661                    self.intrinsics.i64_ty,
9662                    "",
9663                ));
9664                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9665            }
9666            Operator::I64Load16U { ref memarg } => {
9667                let offset = self.state.pop1()?.into_int_value();
9668                let memory_index = MemoryIndex::from_u32(0);
9669                let effective_address = self.resolve_memory_ptr(
9670                    memory_index,
9671                    memarg,
9672                    self.intrinsics.ptr_ty,
9673                    offset,
9674                    2,
9675                )?;
9676                let narrow_result = err!(self.builder.build_load(
9677                    self.intrinsics.i16_ty,
9678                    effective_address,
9679                    ""
9680                ));
9681                self.annotate_user_memaccess(
9682                    memory_index,
9683                    memarg,
9684                    1,
9685                    narrow_result.as_instruction_value().unwrap(),
9686                )?;
9687                let result = err!(self.builder.build_int_z_extend(
9688                    narrow_result.into_int_value(),
9689                    self.intrinsics.i64_ty,
9690                    "",
9691                ));
9692                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9693            }
9694            Operator::I64Load32U { ref memarg } => {
9695                let offset = self.state.pop1()?.into_int_value();
9696                let memory_index = MemoryIndex::from_u32(0);
9697                let effective_address = self.resolve_memory_ptr(
9698                    memory_index,
9699                    memarg,
9700                    self.intrinsics.ptr_ty,
9701                    offset,
9702                    4,
9703                )?;
9704                let narrow_result = err!(self.builder.build_load(
9705                    self.intrinsics.i32_ty,
9706                    effective_address,
9707                    ""
9708                ));
9709                self.annotate_user_memaccess(
9710                    memory_index,
9711                    memarg,
9712                    1,
9713                    narrow_result.as_instruction_value().unwrap(),
9714                )?;
9715                let result = err!(self.builder.build_int_z_extend(
9716                    narrow_result.into_int_value(),
9717                    self.intrinsics.i64_ty,
9718                    "",
9719                ));
9720                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9721            }
9722
9723            Operator::I32Store8 { ref memarg } | Operator::I64Store8 { ref memarg } => {
9724                let value = self.state.pop1()?.into_int_value();
9725                let offset = self.state.pop1()?.into_int_value();
9726                let memory_index = MemoryIndex::from_u32(0);
9727                let effective_address = self.resolve_memory_ptr(
9728                    memory_index,
9729                    memarg,
9730                    self.intrinsics.ptr_ty,
9731                    offset,
9732                    1,
9733                )?;
9734                let dead_load = err!(self.builder.build_load(
9735                    self.intrinsics.i8_ty,
9736                    effective_address,
9737                    ""
9738                ));
9739                self.annotate_user_memaccess(
9740                    memory_index,
9741                    memarg,
9742                    1,
9743                    dead_load.as_instruction_value().unwrap(),
9744                )?;
9745                let narrow_value = err!(self.builder.build_int_truncate(
9746                    value,
9747                    self.intrinsics.i8_ty,
9748                    ""
9749                ));
9750                let store = err!(self.builder.build_store(effective_address, narrow_value));
9751                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9752            }
9753            Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
9754                let value = self.state.pop1()?.into_int_value();
9755                let offset = self.state.pop1()?.into_int_value();
9756                let memory_index = MemoryIndex::from_u32(0);
9757                let effective_address = self.resolve_memory_ptr(
9758                    memory_index,
9759                    memarg,
9760                    self.intrinsics.ptr_ty,
9761                    offset,
9762                    2,
9763                )?;
9764                let dead_load = err!(self.builder.build_load(
9765                    self.intrinsics.i16_ty,
9766                    effective_address,
9767                    ""
9768                ));
9769                self.annotate_user_memaccess(
9770                    memory_index,
9771                    memarg,
9772                    1,
9773                    dead_load.as_instruction_value().unwrap(),
9774                )?;
9775                let narrow_value = err!(self.builder.build_int_truncate(
9776                    value,
9777                    self.intrinsics.i16_ty,
9778                    ""
9779                ));
9780                let store = err!(self.builder.build_store(effective_address, narrow_value));
9781                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9782            }
9783            Operator::I64Store32 { ref memarg } => {
9784                let value = self.state.pop1()?.into_int_value();
9785                let offset = self.state.pop1()?.into_int_value();
9786                let memory_index = MemoryIndex::from_u32(0);
9787                let effective_address = self.resolve_memory_ptr(
9788                    memory_index,
9789                    memarg,
9790                    self.intrinsics.ptr_ty,
9791                    offset,
9792                    4,
9793                )?;
9794                let dead_load = err!(self.builder.build_load(
9795                    self.intrinsics.i32_ty,
9796                    effective_address,
9797                    ""
9798                ));
9799                self.annotate_user_memaccess(
9800                    memory_index,
9801                    memarg,
9802                    1,
9803                    dead_load.as_instruction_value().unwrap(),
9804                )?;
9805                let narrow_value = err!(self.builder.build_int_truncate(
9806                    value,
9807                    self.intrinsics.i32_ty,
9808                    ""
9809                ));
9810                let store = err!(self.builder.build_store(effective_address, narrow_value));
9811                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9812            }
9813            Operator::I8x16Neg => {
9814                let (v, i) = self.state.pop1_extra()?;
9815                let (v, _) = self.v128_into_i8x16(v, i)?;
9816                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9817                let res = err!(
9818                    self.builder
9819                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9820                );
9821                self.state.push1(res);
9822            }
9823            Operator::I16x8Neg => {
9824                let (v, i) = self.state.pop1_extra()?;
9825                let (v, _) = self.v128_into_i16x8(v, i)?;
9826                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9827                let res = err!(
9828                    self.builder
9829                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9830                );
9831                self.state.push1(res);
9832            }
9833            Operator::I32x4Neg => {
9834                let (v, i) = self.state.pop1_extra()?;
9835                let (v, _) = self.v128_into_i32x4(v, i)?;
9836                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9837                let res = err!(
9838                    self.builder
9839                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9840                );
9841                self.state.push1(res);
9842            }
9843            Operator::I64x2Neg => {
9844                let (v, i) = self.state.pop1_extra()?;
9845                let (v, _) = self.v128_into_i64x2(v, i)?;
9846                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9847                let res = err!(
9848                    self.builder
9849                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9850                );
9851                self.state.push1(res);
9852            }
9853            Operator::V128Not => {
9854                let (v, i) = self.state.pop1_extra()?;
9855                let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9856                let res = err!(self.builder.build_not(v, ""));
9857                self.state.push1(res);
9858            }
9859            Operator::V128AnyTrue => {
9860                // | Operator::I64x2AnyTrue
9861                // Skip canonicalization, it never changes non-zero values to zero or vice versa.
9862                let v = self.state.pop1()?.into_int_value();
9863                let res = err!(self.builder.build_int_compare(
9864                    IntPredicate::NE,
9865                    v,
9866                    v.get_type().const_zero(),
9867                    "",
9868                ));
9869                let res = err!(
9870                    self.builder
9871                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9872                );
9873                self.state.push1_extra(
9874                    res,
9875                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9876                );
9877            }
9878            Operator::I8x16AllTrue
9879            | Operator::I16x8AllTrue
9880            | Operator::I32x4AllTrue
9881            | Operator::I64x2AllTrue => {
9882                let vec_ty = match op {
9883                    Operator::I8x16AllTrue => self.intrinsics.i8x16_ty,
9884                    Operator::I16x8AllTrue => self.intrinsics.i16x8_ty,
9885                    Operator::I32x4AllTrue => self.intrinsics.i32x4_ty,
9886                    Operator::I64x2AllTrue => self.intrinsics.i64x2_ty,
9887                    _ => unreachable!(),
9888                };
9889                let (v, i) = self.state.pop1_extra()?;
9890                let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9891                let lane_int_ty = self.context.custom_width_int_type(vec_ty.get_size());
9892                let vec = err!(self.builder.build_bit_cast(v, vec_ty, "vec")).into_vector_value();
9893                let mask = err!(self.builder.build_int_compare(
9894                    IntPredicate::NE,
9895                    vec,
9896                    vec_ty.const_zero(),
9897                    "mask",
9898                ));
9899                let cmask =
9900                    err!(self.builder.build_bit_cast(mask, lane_int_ty, "cmask")).into_int_value();
9901                let res = err!(self.builder.build_int_compare(
9902                    IntPredicate::EQ,
9903                    cmask,
9904                    lane_int_ty.const_int(u64::MAX, true),
9905                    "",
9906                ));
9907                let res = err!(
9908                    self.builder
9909                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9910                );
9911                self.state.push1_extra(
9912                    res,
9913                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9914                );
9915            }
9916            Operator::I8x16ExtractLaneS { lane } => {
9917                let (v, i) = self.state.pop1_extra()?;
9918                let (v, _) = self.v128_into_i8x16(v, i)?;
9919                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9920                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9921                let res = err!(
9922                    self.builder
9923                        .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9924                );
9925                self.state.push1(res);
9926            }
9927            Operator::I8x16ExtractLaneU { lane } => {
9928                let (v, i) = self.state.pop1_extra()?;
9929                let (v, _) = self.v128_into_i8x16(v, i)?;
9930                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9931                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9932                let res = err!(
9933                    self.builder
9934                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9935                );
9936                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9937            }
9938            Operator::I16x8ExtractLaneS { lane } => {
9939                let (v, i) = self.state.pop1_extra()?;
9940                let (v, _) = self.v128_into_i16x8(v, i)?;
9941                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9942                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9943                let res = err!(
9944                    self.builder
9945                        .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9946                );
9947                self.state.push1(res);
9948            }
9949            Operator::I16x8ExtractLaneU { lane } => {
9950                let (v, i) = self.state.pop1_extra()?;
9951                let (v, _) = self.v128_into_i16x8(v, i)?;
9952                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9953                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9954                let res = err!(
9955                    self.builder
9956                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9957                );
9958                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9959            }
9960            Operator::I32x4ExtractLane { lane } => {
9961                let (v, i) = self.state.pop1_extra()?;
9962                let (v, i) = self.v128_into_i32x4(v, i)?;
9963                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9964                let res = err!(self.builder.build_extract_element(v, idx, ""));
9965                self.state.push1_extra(res, i);
9966            }
9967            Operator::I64x2ExtractLane { lane } => {
9968                let (v, i) = self.state.pop1_extra()?;
9969                let (v, i) = self.v128_into_i64x2(v, i)?;
9970                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9971                let res = err!(self.builder.build_extract_element(v, idx, ""));
9972                self.state.push1_extra(res, i);
9973            }
9974            Operator::F32x4ExtractLane { lane } => {
9975                let (v, i) = self.state.pop1_extra()?;
9976                let (v, i) = self.v128_into_f32x4(v, i)?;
9977                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9978                let res = err!(self.builder.build_extract_element(v, idx, ""));
9979                self.state.push1_extra(res, i);
9980            }
9981            Operator::F64x2ExtractLane { lane } => {
9982                let (v, i) = self.state.pop1_extra()?;
9983                let (v, i) = self.v128_into_f64x2(v, i)?;
9984                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9985                let res = err!(self.builder.build_extract_element(v, idx, ""));
9986                self.state.push1_extra(res, i);
9987            }
9988            Operator::I8x16ReplaceLane { lane } => {
9989                let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9990                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
9991                let v2 = v2.into_int_value();
9992                let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i8_ty, ""));
9993                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9994                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9995                let res = err!(
9996                    self.builder
9997                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9998                );
9999                self.state.push1(res);
10000            }
10001            Operator::I16x8ReplaceLane { lane } => {
10002                let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
10003                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
10004                let v2 = v2.into_int_value();
10005                let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i16_ty, ""));
10006                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10007                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10008                let res = err!(
10009                    self.builder
10010                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10011                );
10012                self.state.push1(res);
10013            }
10014            Operator::I32x4ReplaceLane { lane } => {
10015                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10016                let (v1, i1) = self.v128_into_i32x4(v1, i1)?;
10017                let v2 = self.apply_pending_canonicalization(v2, i2)?;
10018                let v2 = v2.into_int_value();
10019                let i2 = i2.strip_pending();
10020                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10021                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10022                let res = err!(
10023                    self.builder
10024                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10025                );
10026                self.state
10027                    .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f32())?);
10028            }
10029            Operator::I64x2ReplaceLane { lane } => {
10030                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10031                let (v1, i1) = self.v128_into_i64x2(v1, i1)?;
10032                let v2 = self.apply_pending_canonicalization(v2, i2)?;
10033                let v2 = v2.into_int_value();
10034                let i2 = i2.strip_pending();
10035                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10036                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10037                let res = err!(
10038                    self.builder
10039                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10040                );
10041                self.state
10042                    .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f64())?);
10043            }
10044            Operator::F32x4ReplaceLane { lane } => {
10045                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10046                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
10047                let push_pending_f32_nan_to_result =
10048                    i1.has_pending_f32_nan() && i2.has_pending_f32_nan();
10049                let (v1, v2) = if !push_pending_f32_nan_to_result {
10050                    (
10051                        self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
10052                            .into_vector_value(),
10053                        self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
10054                            .into_float_value(),
10055                    )
10056                } else {
10057                    (v1, v2.into_float_value())
10058                };
10059                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10060                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10061                let res = err!(
10062                    self.builder
10063                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10064                );
10065                let info = if push_pending_f32_nan_to_result {
10066                    ExtraInfo::pending_f32_nan()
10067                } else {
10068                    (i1.strip_pending() & i2.strip_pending())?
10069                };
10070                self.state.push1_extra(res, info);
10071            }
10072            Operator::F64x2ReplaceLane { lane } => {
10073                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10074                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
10075                let push_pending_f64_nan_to_result =
10076                    i1.has_pending_f64_nan() && i2.has_pending_f64_nan();
10077                let (v1, v2) = if !push_pending_f64_nan_to_result {
10078                    (
10079                        self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
10080                            .into_vector_value(),
10081                        self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
10082                            .into_float_value(),
10083                    )
10084                } else {
10085                    (v1, v2.into_float_value())
10086                };
10087                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10088                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10089                let res = err!(
10090                    self.builder
10091                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10092                );
10093                let info = if push_pending_f64_nan_to_result {
10094                    ExtraInfo::pending_f64_nan()
10095                } else {
10096                    (i1.strip_pending() & i2.strip_pending())?
10097                };
10098                self.state.push1_extra(res, info);
10099            }
10100            Operator::I8x16Swizzle => {
10101                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10102                let v1 = self.apply_pending_canonicalization(v1, i1)?;
10103                let v1 = err!(
10104                    self.builder
10105                        .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
10106                )
10107                .into_vector_value();
10108                let v2 = self.apply_pending_canonicalization(v2, i2)?;
10109                let v2 = err!(
10110                    self.builder
10111                        .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
10112                )
10113                .into_vector_value();
10114                let lanes = self.intrinsics.i8_ty.const_int(16, false);
10115                let lanes =
10116                    self.splat_vector(lanes.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
10117                let mut res = self.intrinsics.i8x16_ty.get_undef();
10118                let idx_out_of_range = err!(self.builder.build_int_compare(
10119                    IntPredicate::UGE,
10120                    v2,
10121                    lanes,
10122                    "idx_out_of_range",
10123                ));
10124                let idx_clamped = err!(self.builder.build_select(
10125                    idx_out_of_range,
10126                    self.intrinsics.i8x16_ty.const_zero(),
10127                    v2,
10128                    "idx_clamped",
10129                ))
10130                .into_vector_value();
10131                for i in 0..16 {
10132                    let idx = err!(self.builder.build_extract_element(
10133                        idx_clamped,
10134                        self.intrinsics.i32_ty.const_int(i, false),
10135                        "idx",
10136                    ))
10137                    .into_int_value();
10138                    let replace_with_zero = err!(self.builder.build_extract_element(
10139                        idx_out_of_range,
10140                        self.intrinsics.i32_ty.const_int(i, false),
10141                        "replace_with_zero",
10142                    ))
10143                    .into_int_value();
10144                    let elem =
10145                        err!(self.builder.build_extract_element(v1, idx, "elem")).into_int_value();
10146                    let elem_or_zero = err!(self.builder.build_select(
10147                        replace_with_zero,
10148                        self.intrinsics.i8_zero,
10149                        elem,
10150                        "elem_or_zero",
10151                    ));
10152                    res = err!(self.builder.build_insert_element(
10153                        res,
10154                        elem_or_zero,
10155                        self.intrinsics.i32_ty.const_int(i, false),
10156                        "",
10157                    ));
10158                }
10159                let res = err!(
10160                    self.builder
10161                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10162                );
10163                self.state.push1(res);
10164            }
10165            Operator::I8x16Shuffle { lanes } => {
10166                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10167                let v1 = self.apply_pending_canonicalization(v1, i1)?;
10168                let v1 = err!(
10169                    self.builder
10170                        .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
10171                )
10172                .into_vector_value();
10173                let v2 = self.apply_pending_canonicalization(v2, i2)?;
10174                let v2 = err!(
10175                    self.builder
10176                        .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
10177                )
10178                .into_vector_value();
10179                let mask = VectorType::const_vector(
10180                    lanes
10181                        .iter()
10182                        .map(|l| self.intrinsics.i32_ty.const_int((*l).into(), false))
10183                        .collect::<Vec<IntValue>>()
10184                        .as_slice(),
10185                );
10186                let res = err!(self.builder.build_shuffle_vector(v1, v2, mask, ""));
10187                let res = err!(
10188                    self.builder
10189                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10190                );
10191                self.state.push1(res);
10192            }
10193            Operator::V128Load8x8S { ref memarg } => {
10194                let offset = self.state.pop1()?.into_int_value();
10195                let memory_index = MemoryIndex::from_u32(0);
10196                let effective_address = self.resolve_memory_ptr(
10197                    memory_index,
10198                    memarg,
10199                    self.intrinsics.ptr_ty,
10200                    offset,
10201                    8,
10202                )?;
10203                let v = err!(self.builder.build_load(
10204                    self.intrinsics.i64_ty,
10205                    effective_address,
10206                    ""
10207                ));
10208                let v = err!(
10209                    self.builder
10210                        .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
10211                )
10212                .into_vector_value();
10213                let res = err!(
10214                    self.builder
10215                        .build_int_s_extend(v, self.intrinsics.i16x8_ty, "")
10216                );
10217                let res = err!(
10218                    self.builder
10219                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10220                );
10221                self.state.push1(res);
10222            }
10223            Operator::V128Load8x8U { ref memarg } => {
10224                let offset = self.state.pop1()?.into_int_value();
10225                let memory_index = MemoryIndex::from_u32(0);
10226                let effective_address = self.resolve_memory_ptr(
10227                    memory_index,
10228                    memarg,
10229                    self.intrinsics.ptr_ty,
10230                    offset,
10231                    8,
10232                )?;
10233                let v = err!(self.builder.build_load(
10234                    self.intrinsics.i64_ty,
10235                    effective_address,
10236                    ""
10237                ));
10238                let v = err!(
10239                    self.builder
10240                        .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
10241                )
10242                .into_vector_value();
10243                let res = err!(
10244                    self.builder
10245                        .build_int_z_extend(v, self.intrinsics.i16x8_ty, "")
10246                );
10247                let res = err!(
10248                    self.builder
10249                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10250                );
10251                self.state.push1(res);
10252            }
10253            Operator::V128Load16x4S { ref memarg } => {
10254                let offset = self.state.pop1()?.into_int_value();
10255                let memory_index = MemoryIndex::from_u32(0);
10256                let effective_address = self.resolve_memory_ptr(
10257                    memory_index,
10258                    memarg,
10259                    self.intrinsics.ptr_ty,
10260                    offset,
10261                    8,
10262                )?;
10263                let v = err!(self.builder.build_load(
10264                    self.intrinsics.i64_ty,
10265                    effective_address,
10266                    ""
10267                ));
10268                let v = err!(self.builder.build_bit_cast(
10269                    v,
10270                    self.intrinsics.i16_ty.vec_type(4),
10271                    ""
10272                ))
10273                .into_vector_value();
10274                let res = err!(
10275                    self.builder
10276                        .build_int_s_extend(v, self.intrinsics.i32x4_ty, "")
10277                );
10278                let res = err!(
10279                    self.builder
10280                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10281                );
10282                self.state.push1(res);
10283            }
10284            Operator::V128Load16x4U { ref memarg } => {
10285                let offset = self.state.pop1()?.into_int_value();
10286                let memory_index = MemoryIndex::from_u32(0);
10287                let effective_address = self.resolve_memory_ptr(
10288                    memory_index,
10289                    memarg,
10290                    self.intrinsics.ptr_ty,
10291                    offset,
10292                    8,
10293                )?;
10294                let v = err!(self.builder.build_load(
10295                    self.intrinsics.i64_ty,
10296                    effective_address,
10297                    ""
10298                ));
10299                let v = err!(self.builder.build_bit_cast(
10300                    v,
10301                    self.intrinsics.i16_ty.vec_type(4),
10302                    ""
10303                ))
10304                .into_vector_value();
10305                let res = err!(
10306                    self.builder
10307                        .build_int_z_extend(v, self.intrinsics.i32x4_ty, "")
10308                );
10309                let res = err!(
10310                    self.builder
10311                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10312                );
10313                self.state.push1(res);
10314            }
10315            Operator::V128Load32x2S { ref memarg } => {
10316                let offset = self.state.pop1()?.into_int_value();
10317                let memory_index = MemoryIndex::from_u32(0);
10318                let effective_address = self.resolve_memory_ptr(
10319                    memory_index,
10320                    memarg,
10321                    self.intrinsics.ptr_ty,
10322                    offset,
10323                    8,
10324                )?;
10325                let v = err!(self.builder.build_load(
10326                    self.intrinsics.i64_ty,
10327                    effective_address,
10328                    ""
10329                ));
10330                let v = err!(self.builder.build_bit_cast(
10331                    v,
10332                    self.intrinsics.i32_ty.vec_type(2),
10333                    ""
10334                ))
10335                .into_vector_value();
10336                let res = err!(
10337                    self.builder
10338                        .build_int_s_extend(v, self.intrinsics.i64x2_ty, "")
10339                );
10340                let res = err!(
10341                    self.builder
10342                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10343                );
10344                self.state.push1(res);
10345            }
10346            Operator::V128Load32x2U { ref memarg } => {
10347                let offset = self.state.pop1()?.into_int_value();
10348                let memory_index = MemoryIndex::from_u32(0);
10349                let effective_address = self.resolve_memory_ptr(
10350                    memory_index,
10351                    memarg,
10352                    self.intrinsics.ptr_ty,
10353                    offset,
10354                    8,
10355                )?;
10356                let v = err!(self.builder.build_load(
10357                    self.intrinsics.i64_ty,
10358                    effective_address,
10359                    ""
10360                ));
10361                let v = err!(self.builder.build_bit_cast(
10362                    v,
10363                    self.intrinsics.i32_ty.vec_type(2),
10364                    ""
10365                ))
10366                .into_vector_value();
10367                let res = err!(
10368                    self.builder
10369                        .build_int_z_extend(v, self.intrinsics.i64x2_ty, "")
10370                );
10371                let res = err!(
10372                    self.builder
10373                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10374                );
10375                self.state.push1(res);
10376            }
10377            Operator::V128Load32Zero { ref memarg } => {
10378                let offset = self.state.pop1()?.into_int_value();
10379                let memory_index = MemoryIndex::from_u32(0);
10380                let effective_address = self.resolve_memory_ptr(
10381                    memory_index,
10382                    memarg,
10383                    self.intrinsics.ptr_ty,
10384                    offset,
10385                    4,
10386                )?;
10387                let elem = err!(self.builder.build_load(
10388                    self.intrinsics.i32_ty,
10389                    effective_address,
10390                    ""
10391                ));
10392                self.annotate_user_memaccess(
10393                    memory_index,
10394                    memarg,
10395                    1,
10396                    elem.as_instruction_value().unwrap(),
10397                )?;
10398                let res = err!(self.builder.build_int_z_extend(
10399                    elem.into_int_value(),
10400                    self.intrinsics.i128_ty,
10401                    "",
10402                ));
10403                self.state.push1(res);
10404            }
10405            Operator::V128Load64Zero { ref memarg } => {
10406                let offset = self.state.pop1()?.into_int_value();
10407                let memory_index = MemoryIndex::from_u32(0);
10408                let effective_address = self.resolve_memory_ptr(
10409                    memory_index,
10410                    memarg,
10411                    self.intrinsics.ptr_ty,
10412                    offset,
10413                    8,
10414                )?;
10415                let elem = err!(self.builder.build_load(
10416                    self.intrinsics.i64_ty,
10417                    effective_address,
10418                    ""
10419                ));
10420                self.annotate_user_memaccess(
10421                    memory_index,
10422                    memarg,
10423                    1,
10424                    elem.as_instruction_value().unwrap(),
10425                )?;
10426                let res = err!(self.builder.build_int_z_extend(
10427                    elem.into_int_value(),
10428                    self.intrinsics.i128_ty,
10429                    "",
10430                ));
10431                self.state.push1(res);
10432            }
10433            Operator::V128Load8Splat { ref memarg } => {
10434                let offset = self.state.pop1()?.into_int_value();
10435                let memory_index = MemoryIndex::from_u32(0);
10436                let effective_address = self.resolve_memory_ptr(
10437                    memory_index,
10438                    memarg,
10439                    self.intrinsics.ptr_ty,
10440                    offset,
10441                    1,
10442                )?;
10443                let elem = err!(self.builder.build_load(
10444                    self.intrinsics.i8_ty,
10445                    effective_address,
10446                    ""
10447                ));
10448                self.annotate_user_memaccess(
10449                    memory_index,
10450                    memarg,
10451                    1,
10452                    elem.as_instruction_value().unwrap(),
10453                )?;
10454                let res = self.splat_vector(elem, self.intrinsics.i8x16_ty)?;
10455                let res = err!(
10456                    self.builder
10457                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10458                );
10459                self.state.push1(res);
10460            }
10461            Operator::V128Load16Splat { ref memarg } => {
10462                let offset = self.state.pop1()?.into_int_value();
10463                let memory_index = MemoryIndex::from_u32(0);
10464                let effective_address = self.resolve_memory_ptr(
10465                    memory_index,
10466                    memarg,
10467                    self.intrinsics.ptr_ty,
10468                    offset,
10469                    2,
10470                )?;
10471                let elem = err!(self.builder.build_load(
10472                    self.intrinsics.i16_ty,
10473                    effective_address,
10474                    ""
10475                ));
10476                self.annotate_user_memaccess(
10477                    memory_index,
10478                    memarg,
10479                    1,
10480                    elem.as_instruction_value().unwrap(),
10481                )?;
10482                let res = self.splat_vector(elem, self.intrinsics.i16x8_ty)?;
10483                let res = err!(
10484                    self.builder
10485                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10486                );
10487                self.state.push1(res);
10488            }
10489            Operator::V128Load32Splat { ref memarg } => {
10490                let offset = self.state.pop1()?.into_int_value();
10491                let memory_index = MemoryIndex::from_u32(0);
10492                let effective_address = self.resolve_memory_ptr(
10493                    memory_index,
10494                    memarg,
10495                    self.intrinsics.ptr_ty,
10496                    offset,
10497                    4,
10498                )?;
10499                let elem = err!(self.builder.build_load(
10500                    self.intrinsics.i32_ty,
10501                    effective_address,
10502                    ""
10503                ));
10504                self.annotate_user_memaccess(
10505                    memory_index,
10506                    memarg,
10507                    1,
10508                    elem.as_instruction_value().unwrap(),
10509                )?;
10510                let res = self.splat_vector(elem, self.intrinsics.i32x4_ty)?;
10511                let res = err!(
10512                    self.builder
10513                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10514                );
10515                self.state.push1(res);
10516            }
10517            Operator::V128Load64Splat { ref memarg } => {
10518                let offset = self.state.pop1()?.into_int_value();
10519                let memory_index = MemoryIndex::from_u32(0);
10520                let effective_address = self.resolve_memory_ptr(
10521                    memory_index,
10522                    memarg,
10523                    self.intrinsics.ptr_ty,
10524                    offset,
10525                    8,
10526                )?;
10527                let elem = err!(self.builder.build_load(
10528                    self.intrinsics.i64_ty,
10529                    effective_address,
10530                    ""
10531                ));
10532                self.annotate_user_memaccess(
10533                    memory_index,
10534                    memarg,
10535                    1,
10536                    elem.as_instruction_value().unwrap(),
10537                )?;
10538                let res = self.splat_vector(elem, self.intrinsics.i64x2_ty)?;
10539                let res = err!(
10540                    self.builder
10541                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
10542                );
10543                self.state.push1(res);
10544            }
10545            Operator::AtomicFence => {
10546                // Fence is a nop.
10547                //
10548                // Fence was added to preserve information about fences from
10549                // source languages. If in the future Wasm extends the memory
10550                // model, and if we hadn't recorded what fences used to be there,
10551                // it would lead to data races that weren't present in the
10552                // original source language.
10553            }
10554            Operator::I32AtomicLoad { ref memarg } => {
10555                let offset = self.state.pop1()?.into_int_value();
10556                let memory_index = MemoryIndex::from_u32(0);
10557                let effective_address = self.resolve_memory_ptr(
10558                    memory_index,
10559                    memarg,
10560                    self.intrinsics.ptr_ty,
10561                    offset,
10562                    4,
10563                )?;
10564                self.trap_if_misaligned(memarg, effective_address, 4)?;
10565                let result = err!(self.builder.build_load(
10566                    self.intrinsics.i32_ty,
10567                    effective_address,
10568                    "atomic_load"
10569                ));
10570                let load = result.as_instruction_value().unwrap();
10571                self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10572                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10573                    .unwrap();
10574                self.state.push1(result);
10575            }
10576            Operator::I64AtomicLoad { ref memarg } => {
10577                let offset = self.state.pop1()?.into_int_value();
10578                let memory_index = MemoryIndex::from_u32(0);
10579                let effective_address = self.resolve_memory_ptr(
10580                    memory_index,
10581                    memarg,
10582                    self.intrinsics.ptr_ty,
10583                    offset,
10584                    8,
10585                )?;
10586                self.trap_if_misaligned(memarg, effective_address, 8)?;
10587                let result = err!(self.builder.build_load(
10588                    self.intrinsics.i64_ty,
10589                    effective_address,
10590                    ""
10591                ));
10592                let load = result.as_instruction_value().unwrap();
10593                self.annotate_user_memaccess(memory_index, memarg, 8, load)?;
10594                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10595                    .unwrap();
10596                self.state.push1(result);
10597            }
10598            Operator::I32AtomicLoad8U { ref memarg } => {
10599                let offset = self.state.pop1()?.into_int_value();
10600                let memory_index = MemoryIndex::from_u32(0);
10601                let effective_address = self.resolve_memory_ptr(
10602                    memory_index,
10603                    memarg,
10604                    self.intrinsics.ptr_ty,
10605                    offset,
10606                    1,
10607                )?;
10608                self.trap_if_misaligned(memarg, effective_address, 1)?;
10609                let narrow_result = err!(self.builder.build_load(
10610                    self.intrinsics.i8_ty,
10611                    effective_address,
10612                    ""
10613                ))
10614                .into_int_value();
10615                let load = narrow_result.as_instruction_value().unwrap();
10616                self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
10617                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10618                    .unwrap();
10619                let result = err!(self.builder.build_int_z_extend(
10620                    narrow_result,
10621                    self.intrinsics.i32_ty,
10622                    ""
10623                ));
10624                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
10625            }
10626            Operator::I32AtomicLoad16U { ref memarg } => {
10627                let offset = self.state.pop1()?.into_int_value();
10628                let memory_index = MemoryIndex::from_u32(0);
10629                let effective_address = self.resolve_memory_ptr(
10630                    memory_index,
10631                    memarg,
10632                    self.intrinsics.ptr_ty,
10633                    offset,
10634                    2,
10635                )?;
10636                self.trap_if_misaligned(memarg, effective_address, 2)?;
10637                let narrow_result = err!(self.builder.build_load(
10638                    self.intrinsics.i16_ty,
10639                    effective_address,
10640                    ""
10641                ))
10642                .into_int_value();
10643                let load = narrow_result.as_instruction_value().unwrap();
10644                self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
10645                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10646                    .unwrap();
10647                let result = err!(self.builder.build_int_z_extend(
10648                    narrow_result,
10649                    self.intrinsics.i32_ty,
10650                    ""
10651                ));
10652                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
10653            }
10654            Operator::I64AtomicLoad8U { ref memarg } => {
10655                let offset = self.state.pop1()?.into_int_value();
10656                let memory_index = MemoryIndex::from_u32(0);
10657                let effective_address = self.resolve_memory_ptr(
10658                    memory_index,
10659                    memarg,
10660                    self.intrinsics.ptr_ty,
10661                    offset,
10662                    1,
10663                )?;
10664                self.trap_if_misaligned(memarg, effective_address, 1)?;
10665                let narrow_result = err!(self.builder.build_load(
10666                    self.intrinsics.i8_ty,
10667                    effective_address,
10668                    ""
10669                ))
10670                .into_int_value();
10671                let load = narrow_result.as_instruction_value().unwrap();
10672                self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
10673                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10674                    .unwrap();
10675                let result = err!(self.builder.build_int_z_extend(
10676                    narrow_result,
10677                    self.intrinsics.i64_ty,
10678                    ""
10679                ));
10680                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10681            }
10682            Operator::I64AtomicLoad16U { ref memarg } => {
10683                let offset = self.state.pop1()?.into_int_value();
10684                let memory_index = MemoryIndex::from_u32(0);
10685                let effective_address = self.resolve_memory_ptr(
10686                    memory_index,
10687                    memarg,
10688                    self.intrinsics.ptr_ty,
10689                    offset,
10690                    2,
10691                )?;
10692                self.trap_if_misaligned(memarg, effective_address, 2)?;
10693                let narrow_result = err!(self.builder.build_load(
10694                    self.intrinsics.i16_ty,
10695                    effective_address,
10696                    ""
10697                ))
10698                .into_int_value();
10699                let load = narrow_result.as_instruction_value().unwrap();
10700                self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
10701                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10702                    .unwrap();
10703                let result = err!(self.builder.build_int_z_extend(
10704                    narrow_result,
10705                    self.intrinsics.i64_ty,
10706                    ""
10707                ));
10708                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10709            }
10710            Operator::I64AtomicLoad32U { ref memarg } => {
10711                let offset = self.state.pop1()?.into_int_value();
10712                let memory_index = MemoryIndex::from_u32(0);
10713                let effective_address = self.resolve_memory_ptr(
10714                    memory_index,
10715                    memarg,
10716                    self.intrinsics.ptr_ty,
10717                    offset,
10718                    4,
10719                )?;
10720                self.trap_if_misaligned(memarg, effective_address, 4)?;
10721                let narrow_result = err!(self.builder.build_load(
10722                    self.intrinsics.i32_ty,
10723                    effective_address,
10724                    ""
10725                ))
10726                .into_int_value();
10727                let load = narrow_result.as_instruction_value().unwrap();
10728                self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10729                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10730                    .unwrap();
10731                let result = err!(self.builder.build_int_z_extend(
10732                    narrow_result,
10733                    self.intrinsics.i64_ty,
10734                    ""
10735                ));
10736                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10737            }
10738            Operator::I32AtomicStore { ref memarg } => {
10739                let value = self.state.pop1()?;
10740                let offset = self.state.pop1()?.into_int_value();
10741                let memory_index = MemoryIndex::from_u32(0);
10742                let effective_address = self.resolve_memory_ptr(
10743                    memory_index,
10744                    memarg,
10745                    self.intrinsics.ptr_ty,
10746                    offset,
10747                    4,
10748                )?;
10749                self.trap_if_misaligned(memarg, effective_address, 4)?;
10750                let store = err!(self.builder.build_store(effective_address, value));
10751                self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10752                store
10753                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10754                    .unwrap();
10755            }
10756            Operator::I64AtomicStore { ref memarg } => {
10757                let value = self.state.pop1()?;
10758                let offset = self.state.pop1()?.into_int_value();
10759                let memory_index = MemoryIndex::from_u32(0);
10760                let effective_address = self.resolve_memory_ptr(
10761                    memory_index,
10762                    memarg,
10763                    self.intrinsics.ptr_ty,
10764                    offset,
10765                    8,
10766                )?;
10767                self.trap_if_misaligned(memarg, effective_address, 8)?;
10768                let store = err!(self.builder.build_store(effective_address, value));
10769                self.annotate_user_memaccess(memory_index, memarg, 8, store)?;
10770                store
10771                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10772                    .unwrap();
10773            }
10774            Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => {
10775                let value = self.state.pop1()?.into_int_value();
10776                let offset = self.state.pop1()?.into_int_value();
10777                let memory_index = MemoryIndex::from_u32(0);
10778                let effective_address = self.resolve_memory_ptr(
10779                    memory_index,
10780                    memarg,
10781                    self.intrinsics.ptr_ty,
10782                    offset,
10783                    1,
10784                )?;
10785                self.trap_if_misaligned(memarg, effective_address, 1)?;
10786                let narrow_value = err!(self.builder.build_int_truncate(
10787                    value,
10788                    self.intrinsics.i8_ty,
10789                    ""
10790                ));
10791                let store = err!(self.builder.build_store(effective_address, narrow_value));
10792                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
10793                store
10794                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10795                    .unwrap();
10796            }
10797            Operator::I32AtomicStore16 { ref memarg }
10798            | Operator::I64AtomicStore16 { ref memarg } => {
10799                let value = self.state.pop1()?.into_int_value();
10800                let offset = self.state.pop1()?.into_int_value();
10801                let memory_index = MemoryIndex::from_u32(0);
10802                let effective_address = self.resolve_memory_ptr(
10803                    memory_index,
10804                    memarg,
10805                    self.intrinsics.ptr_ty,
10806                    offset,
10807                    2,
10808                )?;
10809                self.trap_if_misaligned(memarg, effective_address, 2)?;
10810                let narrow_value = err!(self.builder.build_int_truncate(
10811                    value,
10812                    self.intrinsics.i16_ty,
10813                    ""
10814                ));
10815                let store = err!(self.builder.build_store(effective_address, narrow_value));
10816                self.annotate_user_memaccess(memory_index, memarg, 2, store)?;
10817                store
10818                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10819                    .unwrap();
10820            }
10821            Operator::I64AtomicStore32 { ref memarg } => {
10822                let value = self.state.pop1()?.into_int_value();
10823                let offset = self.state.pop1()?.into_int_value();
10824                let memory_index = MemoryIndex::from_u32(0);
10825                let effective_address = self.resolve_memory_ptr(
10826                    memory_index,
10827                    memarg,
10828                    self.intrinsics.ptr_ty,
10829                    offset,
10830                    4,
10831                )?;
10832                self.trap_if_misaligned(memarg, effective_address, 4)?;
10833                let narrow_value = err!(self.builder.build_int_truncate(
10834                    value,
10835                    self.intrinsics.i32_ty,
10836                    ""
10837                ));
10838                let store = err!(self.builder.build_store(effective_address, narrow_value));
10839                self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10840                store
10841                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10842                    .unwrap();
10843            }
10844            Operator::I32AtomicRmw8AddU { ref memarg } => {
10845                let value = self.state.pop1()?.into_int_value();
10846                let offset = self.state.pop1()?.into_int_value();
10847                let memory_index = MemoryIndex::from_u32(0);
10848                let effective_address = self.resolve_memory_ptr(
10849                    memory_index,
10850                    memarg,
10851                    self.intrinsics.ptr_ty,
10852                    offset,
10853                    1,
10854                )?;
10855                self.trap_if_misaligned(memarg, effective_address, 1)?;
10856                let narrow_value = err!(self.builder.build_int_truncate(
10857                    value,
10858                    self.intrinsics.i8_ty,
10859                    ""
10860                ));
10861                let old = self
10862                    .builder
10863                    .build_atomicrmw(
10864                        AtomicRMWBinOp::Add,
10865                        effective_address,
10866                        narrow_value,
10867                        AtomicOrdering::SequentiallyConsistent,
10868                    )
10869                    .unwrap();
10870                tbaa_label(
10871                    self.module,
10872                    self.intrinsics,
10873                    format!("memory {}", memory_index.as_u32()),
10874                    old.as_instruction_value().unwrap(),
10875                );
10876                let old = err!(
10877                    self.builder
10878                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10879                );
10880                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10881            }
10882            Operator::I32AtomicRmw16AddU { ref memarg } => {
10883                let value = self.state.pop1()?.into_int_value();
10884                let offset = self.state.pop1()?.into_int_value();
10885                let memory_index = MemoryIndex::from_u32(0);
10886                let effective_address = self.resolve_memory_ptr(
10887                    memory_index,
10888                    memarg,
10889                    self.intrinsics.ptr_ty,
10890                    offset,
10891                    2,
10892                )?;
10893                self.trap_if_misaligned(memarg, effective_address, 2)?;
10894                let narrow_value = err!(self.builder.build_int_truncate(
10895                    value,
10896                    self.intrinsics.i16_ty,
10897                    ""
10898                ));
10899                let old = self
10900                    .builder
10901                    .build_atomicrmw(
10902                        AtomicRMWBinOp::Add,
10903                        effective_address,
10904                        narrow_value,
10905                        AtomicOrdering::SequentiallyConsistent,
10906                    )
10907                    .unwrap();
10908                tbaa_label(
10909                    self.module,
10910                    self.intrinsics,
10911                    format!("memory {}", memory_index.as_u32()),
10912                    old.as_instruction_value().unwrap(),
10913                );
10914                let old = err!(
10915                    self.builder
10916                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10917                );
10918                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10919            }
10920            Operator::I32AtomicRmwAdd { ref memarg } => {
10921                let value = self.state.pop1()?.into_int_value();
10922                let offset = self.state.pop1()?.into_int_value();
10923                let memory_index = MemoryIndex::from_u32(0);
10924                let effective_address = self.resolve_memory_ptr(
10925                    memory_index,
10926                    memarg,
10927                    self.intrinsics.ptr_ty,
10928                    offset,
10929                    4,
10930                )?;
10931                self.trap_if_misaligned(memarg, effective_address, 4)?;
10932                let old = self
10933                    .builder
10934                    .build_atomicrmw(
10935                        AtomicRMWBinOp::Add,
10936                        effective_address,
10937                        value,
10938                        AtomicOrdering::SequentiallyConsistent,
10939                    )
10940                    .unwrap();
10941                tbaa_label(
10942                    self.module,
10943                    self.intrinsics,
10944                    format!("memory {}", memory_index.as_u32()),
10945                    old.as_instruction_value().unwrap(),
10946                );
10947                self.state.push1(old);
10948            }
10949            Operator::I64AtomicRmw8AddU { ref memarg } => {
10950                let value = self.state.pop1()?.into_int_value();
10951                let offset = self.state.pop1()?.into_int_value();
10952                let memory_index = MemoryIndex::from_u32(0);
10953                let effective_address = self.resolve_memory_ptr(
10954                    memory_index,
10955                    memarg,
10956                    self.intrinsics.ptr_ty,
10957                    offset,
10958                    1,
10959                )?;
10960                self.trap_if_misaligned(memarg, effective_address, 1)?;
10961                let narrow_value = err!(self.builder.build_int_truncate(
10962                    value,
10963                    self.intrinsics.i8_ty,
10964                    ""
10965                ));
10966                let old = self
10967                    .builder
10968                    .build_atomicrmw(
10969                        AtomicRMWBinOp::Add,
10970                        effective_address,
10971                        narrow_value,
10972                        AtomicOrdering::SequentiallyConsistent,
10973                    )
10974                    .unwrap();
10975                self.annotate_user_memaccess(
10976                    memory_index,
10977                    memarg,
10978                    0,
10979                    old.as_instruction_value().unwrap(),
10980                )?;
10981                let old = err!(
10982                    self.builder
10983                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10984                );
10985                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10986            }
10987            Operator::I64AtomicRmw16AddU { ref memarg } => {
10988                let value = self.state.pop1()?.into_int_value();
10989                let offset = self.state.pop1()?.into_int_value();
10990                let memory_index = MemoryIndex::from_u32(0);
10991                let effective_address = self.resolve_memory_ptr(
10992                    memory_index,
10993                    memarg,
10994                    self.intrinsics.ptr_ty,
10995                    offset,
10996                    2,
10997                )?;
10998                self.trap_if_misaligned(memarg, effective_address, 2)?;
10999                let narrow_value = err!(self.builder.build_int_truncate(
11000                    value,
11001                    self.intrinsics.i16_ty,
11002                    ""
11003                ));
11004                let old = self
11005                    .builder
11006                    .build_atomicrmw(
11007                        AtomicRMWBinOp::Add,
11008                        effective_address,
11009                        narrow_value,
11010                        AtomicOrdering::SequentiallyConsistent,
11011                    )
11012                    .unwrap();
11013                self.annotate_user_memaccess(
11014                    memory_index,
11015                    memarg,
11016                    0,
11017                    old.as_instruction_value().unwrap(),
11018                )?;
11019                let old = err!(
11020                    self.builder
11021                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11022                );
11023                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11024            }
11025            Operator::I64AtomicRmw32AddU { ref memarg } => {
11026                let value = self.state.pop1()?.into_int_value();
11027                let offset = self.state.pop1()?.into_int_value();
11028                let memory_index = MemoryIndex::from_u32(0);
11029                let effective_address = self.resolve_memory_ptr(
11030                    memory_index,
11031                    memarg,
11032                    self.intrinsics.ptr_ty,
11033                    offset,
11034                    4,
11035                )?;
11036                self.trap_if_misaligned(memarg, effective_address, 4)?;
11037                let narrow_value = err!(self.builder.build_int_truncate(
11038                    value,
11039                    self.intrinsics.i32_ty,
11040                    ""
11041                ));
11042                let old = self
11043                    .builder
11044                    .build_atomicrmw(
11045                        AtomicRMWBinOp::Add,
11046                        effective_address,
11047                        narrow_value,
11048                        AtomicOrdering::SequentiallyConsistent,
11049                    )
11050                    .unwrap();
11051                self.annotate_user_memaccess(
11052                    memory_index,
11053                    memarg,
11054                    0,
11055                    old.as_instruction_value().unwrap(),
11056                )?;
11057                let old = err!(
11058                    self.builder
11059                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11060                );
11061                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11062            }
11063            Operator::I64AtomicRmwAdd { ref memarg } => {
11064                let value = self.state.pop1()?.into_int_value();
11065                let offset = self.state.pop1()?.into_int_value();
11066                let memory_index = MemoryIndex::from_u32(0);
11067                let effective_address = self.resolve_memory_ptr(
11068                    memory_index,
11069                    memarg,
11070                    self.intrinsics.ptr_ty,
11071                    offset,
11072                    8,
11073                )?;
11074                self.trap_if_misaligned(memarg, effective_address, 8)?;
11075                let old = self
11076                    .builder
11077                    .build_atomicrmw(
11078                        AtomicRMWBinOp::Add,
11079                        effective_address,
11080                        value,
11081                        AtomicOrdering::SequentiallyConsistent,
11082                    )
11083                    .unwrap();
11084                self.annotate_user_memaccess(
11085                    memory_index,
11086                    memarg,
11087                    0,
11088                    old.as_instruction_value().unwrap(),
11089                )?;
11090                self.state.push1(old);
11091            }
11092            Operator::I32AtomicRmw8SubU { ref memarg } => {
11093                let value = self.state.pop1()?.into_int_value();
11094                let offset = self.state.pop1()?.into_int_value();
11095                let memory_index = MemoryIndex::from_u32(0);
11096                let effective_address = self.resolve_memory_ptr(
11097                    memory_index,
11098                    memarg,
11099                    self.intrinsics.ptr_ty,
11100                    offset,
11101                    1,
11102                )?;
11103                self.trap_if_misaligned(memarg, effective_address, 1)?;
11104                let narrow_value = err!(self.builder.build_int_truncate(
11105                    value,
11106                    self.intrinsics.i8_ty,
11107                    ""
11108                ));
11109                let old = self
11110                    .builder
11111                    .build_atomicrmw(
11112                        AtomicRMWBinOp::Sub,
11113                        effective_address,
11114                        narrow_value,
11115                        AtomicOrdering::SequentiallyConsistent,
11116                    )
11117                    .unwrap();
11118                self.annotate_user_memaccess(
11119                    memory_index,
11120                    memarg,
11121                    0,
11122                    old.as_instruction_value().unwrap(),
11123                )?;
11124                let old = err!(
11125                    self.builder
11126                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11127                );
11128                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11129            }
11130            Operator::I32AtomicRmw16SubU { ref memarg } => {
11131                let value = self.state.pop1()?.into_int_value();
11132                let offset = self.state.pop1()?.into_int_value();
11133                let memory_index = MemoryIndex::from_u32(0);
11134                let effective_address = self.resolve_memory_ptr(
11135                    memory_index,
11136                    memarg,
11137                    self.intrinsics.ptr_ty,
11138                    offset,
11139                    2,
11140                )?;
11141                self.trap_if_misaligned(memarg, effective_address, 2)?;
11142                let narrow_value = err!(self.builder.build_int_truncate(
11143                    value,
11144                    self.intrinsics.i16_ty,
11145                    ""
11146                ));
11147                let old = self
11148                    .builder
11149                    .build_atomicrmw(
11150                        AtomicRMWBinOp::Sub,
11151                        effective_address,
11152                        narrow_value,
11153                        AtomicOrdering::SequentiallyConsistent,
11154                    )
11155                    .unwrap();
11156                self.annotate_user_memaccess(
11157                    memory_index,
11158                    memarg,
11159                    0,
11160                    old.as_instruction_value().unwrap(),
11161                )?;
11162                let old = err!(
11163                    self.builder
11164                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11165                );
11166                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11167            }
11168            Operator::I32AtomicRmwSub { ref memarg } => {
11169                let value = self.state.pop1()?.into_int_value();
11170                let offset = self.state.pop1()?.into_int_value();
11171                let memory_index = MemoryIndex::from_u32(0);
11172                let effective_address = self.resolve_memory_ptr(
11173                    memory_index,
11174                    memarg,
11175                    self.intrinsics.ptr_ty,
11176                    offset,
11177                    4,
11178                )?;
11179                self.trap_if_misaligned(memarg, effective_address, 4)?;
11180                let old = self
11181                    .builder
11182                    .build_atomicrmw(
11183                        AtomicRMWBinOp::Sub,
11184                        effective_address,
11185                        value,
11186                        AtomicOrdering::SequentiallyConsistent,
11187                    )
11188                    .unwrap();
11189                self.annotate_user_memaccess(
11190                    memory_index,
11191                    memarg,
11192                    0,
11193                    old.as_instruction_value().unwrap(),
11194                )?;
11195                self.state.push1(old);
11196            }
11197            Operator::I64AtomicRmw8SubU { ref memarg } => {
11198                let value = self.state.pop1()?.into_int_value();
11199                let offset = self.state.pop1()?.into_int_value();
11200                let memory_index = MemoryIndex::from_u32(0);
11201                let effective_address = self.resolve_memory_ptr(
11202                    memory_index,
11203                    memarg,
11204                    self.intrinsics.ptr_ty,
11205                    offset,
11206                    1,
11207                )?;
11208                self.trap_if_misaligned(memarg, effective_address, 1)?;
11209                let narrow_value = err!(self.builder.build_int_truncate(
11210                    value,
11211                    self.intrinsics.i8_ty,
11212                    ""
11213                ));
11214                let old = self
11215                    .builder
11216                    .build_atomicrmw(
11217                        AtomicRMWBinOp::Sub,
11218                        effective_address,
11219                        narrow_value,
11220                        AtomicOrdering::SequentiallyConsistent,
11221                    )
11222                    .unwrap();
11223                self.annotate_user_memaccess(
11224                    memory_index,
11225                    memarg,
11226                    0,
11227                    old.as_instruction_value().unwrap(),
11228                )?;
11229                let old = err!(
11230                    self.builder
11231                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11232                );
11233                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11234            }
11235            Operator::I64AtomicRmw16SubU { ref memarg } => {
11236                let value = self.state.pop1()?.into_int_value();
11237                let offset = self.state.pop1()?.into_int_value();
11238                let memory_index = MemoryIndex::from_u32(0);
11239                let effective_address = self.resolve_memory_ptr(
11240                    memory_index,
11241                    memarg,
11242                    self.intrinsics.ptr_ty,
11243                    offset,
11244                    2,
11245                )?;
11246                self.trap_if_misaligned(memarg, effective_address, 2)?;
11247                let narrow_value = err!(self.builder.build_int_truncate(
11248                    value,
11249                    self.intrinsics.i16_ty,
11250                    ""
11251                ));
11252                let old = self
11253                    .builder
11254                    .build_atomicrmw(
11255                        AtomicRMWBinOp::Sub,
11256                        effective_address,
11257                        narrow_value,
11258                        AtomicOrdering::SequentiallyConsistent,
11259                    )
11260                    .unwrap();
11261                self.annotate_user_memaccess(
11262                    memory_index,
11263                    memarg,
11264                    0,
11265                    old.as_instruction_value().unwrap(),
11266                )?;
11267                let old = err!(
11268                    self.builder
11269                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11270                );
11271                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11272            }
11273            Operator::I64AtomicRmw32SubU { ref memarg } => {
11274                let value = self.state.pop1()?.into_int_value();
11275                let offset = self.state.pop1()?.into_int_value();
11276                let memory_index = MemoryIndex::from_u32(0);
11277                let effective_address = self.resolve_memory_ptr(
11278                    memory_index,
11279                    memarg,
11280                    self.intrinsics.ptr_ty,
11281                    offset,
11282                    4,
11283                )?;
11284                self.trap_if_misaligned(memarg, effective_address, 4)?;
11285                let narrow_value = err!(self.builder.build_int_truncate(
11286                    value,
11287                    self.intrinsics.i32_ty,
11288                    ""
11289                ));
11290                let old = self
11291                    .builder
11292                    .build_atomicrmw(
11293                        AtomicRMWBinOp::Sub,
11294                        effective_address,
11295                        narrow_value,
11296                        AtomicOrdering::SequentiallyConsistent,
11297                    )
11298                    .unwrap();
11299                self.annotate_user_memaccess(
11300                    memory_index,
11301                    memarg,
11302                    0,
11303                    old.as_instruction_value().unwrap(),
11304                )?;
11305                let old = err!(
11306                    self.builder
11307                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11308                );
11309                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11310            }
11311            Operator::I64AtomicRmwSub { ref memarg } => {
11312                let value = self.state.pop1()?.into_int_value();
11313                let offset = self.state.pop1()?.into_int_value();
11314                let memory_index = MemoryIndex::from_u32(0);
11315                let effective_address = self.resolve_memory_ptr(
11316                    memory_index,
11317                    memarg,
11318                    self.intrinsics.ptr_ty,
11319                    offset,
11320                    8,
11321                )?;
11322                self.trap_if_misaligned(memarg, effective_address, 8)?;
11323                let old = self
11324                    .builder
11325                    .build_atomicrmw(
11326                        AtomicRMWBinOp::Sub,
11327                        effective_address,
11328                        value,
11329                        AtomicOrdering::SequentiallyConsistent,
11330                    )
11331                    .unwrap();
11332                self.annotate_user_memaccess(
11333                    memory_index,
11334                    memarg,
11335                    0,
11336                    old.as_instruction_value().unwrap(),
11337                )?;
11338                self.state.push1(old);
11339            }
11340            Operator::I32AtomicRmw8AndU { ref memarg } => {
11341                let value = self.state.pop1()?.into_int_value();
11342                let offset = self.state.pop1()?.into_int_value();
11343                let memory_index = MemoryIndex::from_u32(0);
11344                let effective_address = self.resolve_memory_ptr(
11345                    memory_index,
11346                    memarg,
11347                    self.intrinsics.ptr_ty,
11348                    offset,
11349                    1,
11350                )?;
11351                self.trap_if_misaligned(memarg, effective_address, 1)?;
11352                let narrow_value = err!(self.builder.build_int_truncate(
11353                    value,
11354                    self.intrinsics.i8_ty,
11355                    ""
11356                ));
11357                let old = self
11358                    .builder
11359                    .build_atomicrmw(
11360                        AtomicRMWBinOp::And,
11361                        effective_address,
11362                        narrow_value,
11363                        AtomicOrdering::SequentiallyConsistent,
11364                    )
11365                    .unwrap();
11366                self.annotate_user_memaccess(
11367                    memory_index,
11368                    memarg,
11369                    0,
11370                    old.as_instruction_value().unwrap(),
11371                )?;
11372                let old = err!(
11373                    self.builder
11374                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11375                );
11376                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11377            }
11378            Operator::I32AtomicRmw16AndU { ref memarg } => {
11379                let value = self.state.pop1()?.into_int_value();
11380                let offset = self.state.pop1()?.into_int_value();
11381                let memory_index = MemoryIndex::from_u32(0);
11382                let effective_address = self.resolve_memory_ptr(
11383                    memory_index,
11384                    memarg,
11385                    self.intrinsics.ptr_ty,
11386                    offset,
11387                    2,
11388                )?;
11389                self.trap_if_misaligned(memarg, effective_address, 2)?;
11390                let narrow_value = err!(self.builder.build_int_truncate(
11391                    value,
11392                    self.intrinsics.i16_ty,
11393                    ""
11394                ));
11395                let old = self
11396                    .builder
11397                    .build_atomicrmw(
11398                        AtomicRMWBinOp::And,
11399                        effective_address,
11400                        narrow_value,
11401                        AtomicOrdering::SequentiallyConsistent,
11402                    )
11403                    .unwrap();
11404                self.annotate_user_memaccess(
11405                    memory_index,
11406                    memarg,
11407                    0,
11408                    old.as_instruction_value().unwrap(),
11409                )?;
11410                let old = err!(
11411                    self.builder
11412                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11413                );
11414                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11415            }
11416            Operator::I32AtomicRmwAnd { ref memarg } => {
11417                let value = self.state.pop1()?.into_int_value();
11418                let offset = self.state.pop1()?.into_int_value();
11419                let memory_index = MemoryIndex::from_u32(0);
11420                let effective_address = self.resolve_memory_ptr(
11421                    memory_index,
11422                    memarg,
11423                    self.intrinsics.ptr_ty,
11424                    offset,
11425                    4,
11426                )?;
11427                self.trap_if_misaligned(memarg, effective_address, 4)?;
11428                let old = self
11429                    .builder
11430                    .build_atomicrmw(
11431                        AtomicRMWBinOp::And,
11432                        effective_address,
11433                        value,
11434                        AtomicOrdering::SequentiallyConsistent,
11435                    )
11436                    .unwrap();
11437                self.annotate_user_memaccess(
11438                    memory_index,
11439                    memarg,
11440                    0,
11441                    old.as_instruction_value().unwrap(),
11442                )?;
11443                self.state.push1(old);
11444            }
11445            Operator::I64AtomicRmw8AndU { ref memarg } => {
11446                let value = self.state.pop1()?.into_int_value();
11447                let offset = self.state.pop1()?.into_int_value();
11448                let memory_index = MemoryIndex::from_u32(0);
11449                let effective_address = self.resolve_memory_ptr(
11450                    memory_index,
11451                    memarg,
11452                    self.intrinsics.ptr_ty,
11453                    offset,
11454                    1,
11455                )?;
11456                self.trap_if_misaligned(memarg, effective_address, 1)?;
11457                let narrow_value = err!(self.builder.build_int_truncate(
11458                    value,
11459                    self.intrinsics.i8_ty,
11460                    ""
11461                ));
11462                let old = self
11463                    .builder
11464                    .build_atomicrmw(
11465                        AtomicRMWBinOp::And,
11466                        effective_address,
11467                        narrow_value,
11468                        AtomicOrdering::SequentiallyConsistent,
11469                    )
11470                    .unwrap();
11471                self.annotate_user_memaccess(
11472                    memory_index,
11473                    memarg,
11474                    0,
11475                    old.as_instruction_value().unwrap(),
11476                )?;
11477                let old = err!(
11478                    self.builder
11479                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11480                );
11481                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11482            }
11483            Operator::I64AtomicRmw16AndU { ref memarg } => {
11484                let value = self.state.pop1()?.into_int_value();
11485                let offset = self.state.pop1()?.into_int_value();
11486                let memory_index = MemoryIndex::from_u32(0);
11487                let effective_address = self.resolve_memory_ptr(
11488                    memory_index,
11489                    memarg,
11490                    self.intrinsics.ptr_ty,
11491                    offset,
11492                    2,
11493                )?;
11494                self.trap_if_misaligned(memarg, effective_address, 2)?;
11495                let narrow_value = err!(self.builder.build_int_truncate(
11496                    value,
11497                    self.intrinsics.i16_ty,
11498                    ""
11499                ));
11500                let old = self
11501                    .builder
11502                    .build_atomicrmw(
11503                        AtomicRMWBinOp::And,
11504                        effective_address,
11505                        narrow_value,
11506                        AtomicOrdering::SequentiallyConsistent,
11507                    )
11508                    .unwrap();
11509                self.annotate_user_memaccess(
11510                    memory_index,
11511                    memarg,
11512                    0,
11513                    old.as_instruction_value().unwrap(),
11514                )?;
11515                let old = err!(
11516                    self.builder
11517                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11518                );
11519                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11520            }
11521            Operator::I64AtomicRmw32AndU { ref memarg } => {
11522                let value = self.state.pop1()?.into_int_value();
11523                let offset = self.state.pop1()?.into_int_value();
11524                let memory_index = MemoryIndex::from_u32(0);
11525                let effective_address = self.resolve_memory_ptr(
11526                    memory_index,
11527                    memarg,
11528                    self.intrinsics.ptr_ty,
11529                    offset,
11530                    4,
11531                )?;
11532                self.trap_if_misaligned(memarg, effective_address, 4)?;
11533                let narrow_value = err!(self.builder.build_int_truncate(
11534                    value,
11535                    self.intrinsics.i32_ty,
11536                    ""
11537                ));
11538                let old = self
11539                    .builder
11540                    .build_atomicrmw(
11541                        AtomicRMWBinOp::And,
11542                        effective_address,
11543                        narrow_value,
11544                        AtomicOrdering::SequentiallyConsistent,
11545                    )
11546                    .unwrap();
11547                self.annotate_user_memaccess(
11548                    memory_index,
11549                    memarg,
11550                    0,
11551                    old.as_instruction_value().unwrap(),
11552                )?;
11553                let old = err!(
11554                    self.builder
11555                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11556                );
11557                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11558            }
11559            Operator::I64AtomicRmwAnd { ref memarg } => {
11560                let value = self.state.pop1()?.into_int_value();
11561                let offset = self.state.pop1()?.into_int_value();
11562                let memory_index = MemoryIndex::from_u32(0);
11563                let effective_address = self.resolve_memory_ptr(
11564                    memory_index,
11565                    memarg,
11566                    self.intrinsics.ptr_ty,
11567                    offset,
11568                    8,
11569                )?;
11570                self.trap_if_misaligned(memarg, effective_address, 8)?;
11571                let old = self
11572                    .builder
11573                    .build_atomicrmw(
11574                        AtomicRMWBinOp::And,
11575                        effective_address,
11576                        value,
11577                        AtomicOrdering::SequentiallyConsistent,
11578                    )
11579                    .unwrap();
11580                self.annotate_user_memaccess(
11581                    memory_index,
11582                    memarg,
11583                    0,
11584                    old.as_instruction_value().unwrap(),
11585                )?;
11586                self.state.push1(old);
11587            }
11588            Operator::I32AtomicRmw8OrU { ref memarg } => {
11589                let value = self.state.pop1()?.into_int_value();
11590                let offset = self.state.pop1()?.into_int_value();
11591                let memory_index = MemoryIndex::from_u32(0);
11592                let effective_address = self.resolve_memory_ptr(
11593                    memory_index,
11594                    memarg,
11595                    self.intrinsics.ptr_ty,
11596                    offset,
11597                    1,
11598                )?;
11599                self.trap_if_misaligned(memarg, effective_address, 1)?;
11600                let narrow_value = err!(self.builder.build_int_truncate(
11601                    value,
11602                    self.intrinsics.i8_ty,
11603                    ""
11604                ));
11605                let old = self
11606                    .builder
11607                    .build_atomicrmw(
11608                        AtomicRMWBinOp::Or,
11609                        effective_address,
11610                        narrow_value,
11611                        AtomicOrdering::SequentiallyConsistent,
11612                    )
11613                    .unwrap();
11614                self.annotate_user_memaccess(
11615                    memory_index,
11616                    memarg,
11617                    0,
11618                    old.as_instruction_value().unwrap(),
11619                )?;
11620                let old = err!(
11621                    self.builder
11622                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11623                );
11624                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11625            }
11626            Operator::I32AtomicRmw16OrU { ref memarg } => {
11627                let value = self.state.pop1()?.into_int_value();
11628                let offset = self.state.pop1()?.into_int_value();
11629                let memory_index = MemoryIndex::from_u32(0);
11630                let effective_address = self.resolve_memory_ptr(
11631                    memory_index,
11632                    memarg,
11633                    self.intrinsics.ptr_ty,
11634                    offset,
11635                    2,
11636                )?;
11637                self.trap_if_misaligned(memarg, effective_address, 2)?;
11638                let narrow_value = err!(self.builder.build_int_truncate(
11639                    value,
11640                    self.intrinsics.i16_ty,
11641                    ""
11642                ));
11643                let old = self
11644                    .builder
11645                    .build_atomicrmw(
11646                        AtomicRMWBinOp::Or,
11647                        effective_address,
11648                        narrow_value,
11649                        AtomicOrdering::SequentiallyConsistent,
11650                    )
11651                    .unwrap();
11652                self.annotate_user_memaccess(
11653                    memory_index,
11654                    memarg,
11655                    0,
11656                    old.as_instruction_value().unwrap(),
11657                )?;
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::I32AtomicRmwOr { ref memarg } => {
11665                let value = self.state.pop1()?.into_int_value();
11666                let offset = self.state.pop1()?.into_int_value();
11667                let memory_index = MemoryIndex::from_u32(0);
11668                let effective_address = self.resolve_memory_ptr(
11669                    memory_index,
11670                    memarg,
11671                    self.intrinsics.ptr_ty,
11672                    offset,
11673                    4,
11674                )?;
11675                self.trap_if_misaligned(memarg, effective_address, 4)?;
11676                let old = self
11677                    .builder
11678                    .build_atomicrmw(
11679                        AtomicRMWBinOp::Or,
11680                        effective_address,
11681                        value,
11682                        AtomicOrdering::SequentiallyConsistent,
11683                    )
11684                    .unwrap();
11685                self.annotate_user_memaccess(
11686                    memory_index,
11687                    memarg,
11688                    0,
11689                    old.as_instruction_value().unwrap(),
11690                )?;
11691                let old = err!(
11692                    self.builder
11693                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11694                );
11695                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11696            }
11697            Operator::I64AtomicRmw8OrU { ref memarg } => {
11698                let value = self.state.pop1()?.into_int_value();
11699                let offset = self.state.pop1()?.into_int_value();
11700                let memory_index = MemoryIndex::from_u32(0);
11701                let effective_address = self.resolve_memory_ptr(
11702                    memory_index,
11703                    memarg,
11704                    self.intrinsics.ptr_ty,
11705                    offset,
11706                    1,
11707                )?;
11708                self.trap_if_misaligned(memarg, effective_address, 1)?;
11709                let narrow_value = err!(self.builder.build_int_truncate(
11710                    value,
11711                    self.intrinsics.i8_ty,
11712                    ""
11713                ));
11714                let old = self
11715                    .builder
11716                    .build_atomicrmw(
11717                        AtomicRMWBinOp::Or,
11718                        effective_address,
11719                        narrow_value,
11720                        AtomicOrdering::SequentiallyConsistent,
11721                    )
11722                    .unwrap();
11723                self.annotate_user_memaccess(
11724                    memory_index,
11725                    memarg,
11726                    0,
11727                    old.as_instruction_value().unwrap(),
11728                )?;
11729                let old = err!(
11730                    self.builder
11731                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11732                );
11733                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11734            }
11735            Operator::I64AtomicRmw16OrU { ref memarg } => {
11736                let value = self.state.pop1()?.into_int_value();
11737                let offset = self.state.pop1()?.into_int_value();
11738                let memory_index = MemoryIndex::from_u32(0);
11739                let effective_address = self.resolve_memory_ptr(
11740                    memory_index,
11741                    memarg,
11742                    self.intrinsics.ptr_ty,
11743                    offset,
11744                    2,
11745                )?;
11746                self.trap_if_misaligned(memarg, effective_address, 2)?;
11747                let narrow_value = err!(self.builder.build_int_truncate(
11748                    value,
11749                    self.intrinsics.i16_ty,
11750                    ""
11751                ));
11752                let old = self
11753                    .builder
11754                    .build_atomicrmw(
11755                        AtomicRMWBinOp::Or,
11756                        effective_address,
11757                        narrow_value,
11758                        AtomicOrdering::SequentiallyConsistent,
11759                    )
11760                    .unwrap();
11761                self.annotate_user_memaccess(
11762                    memory_index,
11763                    memarg,
11764                    0,
11765                    old.as_instruction_value().unwrap(),
11766                )?;
11767                let old = err!(
11768                    self.builder
11769                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11770                );
11771                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11772            }
11773            Operator::I64AtomicRmw32OrU { ref memarg } => {
11774                let value = self.state.pop1()?.into_int_value();
11775                let offset = self.state.pop1()?.into_int_value();
11776                let memory_index = MemoryIndex::from_u32(0);
11777                let effective_address = self.resolve_memory_ptr(
11778                    memory_index,
11779                    memarg,
11780                    self.intrinsics.ptr_ty,
11781                    offset,
11782                    4,
11783                )?;
11784                self.trap_if_misaligned(memarg, effective_address, 4)?;
11785                let narrow_value = err!(self.builder.build_int_truncate(
11786                    value,
11787                    self.intrinsics.i32_ty,
11788                    ""
11789                ));
11790                let old = self
11791                    .builder
11792                    .build_atomicrmw(
11793                        AtomicRMWBinOp::Or,
11794                        effective_address,
11795                        narrow_value,
11796                        AtomicOrdering::SequentiallyConsistent,
11797                    )
11798                    .unwrap();
11799                self.annotate_user_memaccess(
11800                    memory_index,
11801                    memarg,
11802                    0,
11803                    old.as_instruction_value().unwrap(),
11804                )?;
11805                let old = err!(
11806                    self.builder
11807                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11808                );
11809                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11810            }
11811            Operator::I64AtomicRmwOr { ref memarg } => {
11812                let value = self.state.pop1()?.into_int_value();
11813                let offset = self.state.pop1()?.into_int_value();
11814                let memory_index = MemoryIndex::from_u32(0);
11815                let effective_address = self.resolve_memory_ptr(
11816                    memory_index,
11817                    memarg,
11818                    self.intrinsics.ptr_ty,
11819                    offset,
11820                    8,
11821                )?;
11822                self.trap_if_misaligned(memarg, effective_address, 8)?;
11823                let old = self
11824                    .builder
11825                    .build_atomicrmw(
11826                        AtomicRMWBinOp::Or,
11827                        effective_address,
11828                        value,
11829                        AtomicOrdering::SequentiallyConsistent,
11830                    )
11831                    .unwrap();
11832                self.annotate_user_memaccess(
11833                    memory_index,
11834                    memarg,
11835                    0,
11836                    old.as_instruction_value().unwrap(),
11837                )?;
11838                self.state.push1(old);
11839            }
11840            Operator::I32AtomicRmw8XorU { ref memarg } => {
11841                let value = self.state.pop1()?.into_int_value();
11842                let offset = self.state.pop1()?.into_int_value();
11843                let memory_index = MemoryIndex::from_u32(0);
11844                let effective_address = self.resolve_memory_ptr(
11845                    memory_index,
11846                    memarg,
11847                    self.intrinsics.ptr_ty,
11848                    offset,
11849                    1,
11850                )?;
11851                self.trap_if_misaligned(memarg, effective_address, 2)?;
11852                let narrow_value = err!(self.builder.build_int_truncate(
11853                    value,
11854                    self.intrinsics.i8_ty,
11855                    ""
11856                ));
11857                let old = self
11858                    .builder
11859                    .build_atomicrmw(
11860                        AtomicRMWBinOp::Xor,
11861                        effective_address,
11862                        narrow_value,
11863                        AtomicOrdering::SequentiallyConsistent,
11864                    )
11865                    .unwrap();
11866                self.annotate_user_memaccess(
11867                    memory_index,
11868                    memarg,
11869                    0,
11870                    old.as_instruction_value().unwrap(),
11871                )?;
11872                let old = err!(
11873                    self.builder
11874                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11875                );
11876                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11877            }
11878            Operator::I32AtomicRmw16XorU { ref memarg } => {
11879                let value = self.state.pop1()?.into_int_value();
11880                let offset = self.state.pop1()?.into_int_value();
11881                let memory_index = MemoryIndex::from_u32(0);
11882                let effective_address = self.resolve_memory_ptr(
11883                    memory_index,
11884                    memarg,
11885                    self.intrinsics.ptr_ty,
11886                    offset,
11887                    2,
11888                )?;
11889                self.trap_if_misaligned(memarg, effective_address, 2)?;
11890                let narrow_value = err!(self.builder.build_int_truncate(
11891                    value,
11892                    self.intrinsics.i16_ty,
11893                    ""
11894                ));
11895                let old = self
11896                    .builder
11897                    .build_atomicrmw(
11898                        AtomicRMWBinOp::Xor,
11899                        effective_address,
11900                        narrow_value,
11901                        AtomicOrdering::SequentiallyConsistent,
11902                    )
11903                    .unwrap();
11904                self.annotate_user_memaccess(
11905                    memory_index,
11906                    memarg,
11907                    0,
11908                    old.as_instruction_value().unwrap(),
11909                )?;
11910                let old = err!(
11911                    self.builder
11912                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11913                );
11914                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11915            }
11916            Operator::I32AtomicRmwXor { ref memarg } => {
11917                let value = self.state.pop1()?.into_int_value();
11918                let offset = self.state.pop1()?.into_int_value();
11919                let memory_index = MemoryIndex::from_u32(0);
11920                let effective_address = self.resolve_memory_ptr(
11921                    memory_index,
11922                    memarg,
11923                    self.intrinsics.ptr_ty,
11924                    offset,
11925                    4,
11926                )?;
11927                self.trap_if_misaligned(memarg, effective_address, 4)?;
11928                let old = self
11929                    .builder
11930                    .build_atomicrmw(
11931                        AtomicRMWBinOp::Xor,
11932                        effective_address,
11933                        value,
11934                        AtomicOrdering::SequentiallyConsistent,
11935                    )
11936                    .unwrap();
11937                self.annotate_user_memaccess(
11938                    memory_index,
11939                    memarg,
11940                    0,
11941                    old.as_instruction_value().unwrap(),
11942                )?;
11943                self.state.push1(old);
11944            }
11945            Operator::I64AtomicRmw8XorU { ref memarg } => {
11946                let value = self.state.pop1()?.into_int_value();
11947                let offset = self.state.pop1()?.into_int_value();
11948                let memory_index = MemoryIndex::from_u32(0);
11949                let effective_address = self.resolve_memory_ptr(
11950                    memory_index,
11951                    memarg,
11952                    self.intrinsics.ptr_ty,
11953                    offset,
11954                    1,
11955                )?;
11956                self.trap_if_misaligned(memarg, effective_address, 1)?;
11957                let narrow_value = err!(self.builder.build_int_truncate(
11958                    value,
11959                    self.intrinsics.i8_ty,
11960                    ""
11961                ));
11962                let old = self
11963                    .builder
11964                    .build_atomicrmw(
11965                        AtomicRMWBinOp::Xor,
11966                        effective_address,
11967                        narrow_value,
11968                        AtomicOrdering::SequentiallyConsistent,
11969                    )
11970                    .unwrap();
11971                self.annotate_user_memaccess(
11972                    memory_index,
11973                    memarg,
11974                    0,
11975                    old.as_instruction_value().unwrap(),
11976                )?;
11977                let old = err!(
11978                    self.builder
11979                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11980                );
11981                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11982            }
11983            Operator::I64AtomicRmw16XorU { ref memarg } => {
11984                let value = self.state.pop1()?.into_int_value();
11985                let offset = self.state.pop1()?.into_int_value();
11986                let memory_index = MemoryIndex::from_u32(0);
11987                let effective_address = self.resolve_memory_ptr(
11988                    memory_index,
11989                    memarg,
11990                    self.intrinsics.ptr_ty,
11991                    offset,
11992                    2,
11993                )?;
11994                self.trap_if_misaligned(memarg, effective_address, 2)?;
11995                let narrow_value = err!(self.builder.build_int_truncate(
11996                    value,
11997                    self.intrinsics.i16_ty,
11998                    ""
11999                ));
12000                let old = self
12001                    .builder
12002                    .build_atomicrmw(
12003                        AtomicRMWBinOp::Xor,
12004                        effective_address,
12005                        narrow_value,
12006                        AtomicOrdering::SequentiallyConsistent,
12007                    )
12008                    .unwrap();
12009                self.annotate_user_memaccess(
12010                    memory_index,
12011                    memarg,
12012                    0,
12013                    old.as_instruction_value().unwrap(),
12014                )?;
12015                let old = err!(
12016                    self.builder
12017                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12018                );
12019                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12020            }
12021            Operator::I64AtomicRmw32XorU { ref memarg } => {
12022                let value = self.state.pop1()?.into_int_value();
12023                let offset = self.state.pop1()?.into_int_value();
12024                let memory_index = MemoryIndex::from_u32(0);
12025                let effective_address = self.resolve_memory_ptr(
12026                    memory_index,
12027                    memarg,
12028                    self.intrinsics.ptr_ty,
12029                    offset,
12030                    4,
12031                )?;
12032                self.trap_if_misaligned(memarg, effective_address, 4)?;
12033                let narrow_value = err!(self.builder.build_int_truncate(
12034                    value,
12035                    self.intrinsics.i32_ty,
12036                    ""
12037                ));
12038                let old = self
12039                    .builder
12040                    .build_atomicrmw(
12041                        AtomicRMWBinOp::Xor,
12042                        effective_address,
12043                        narrow_value,
12044                        AtomicOrdering::SequentiallyConsistent,
12045                    )
12046                    .unwrap();
12047                self.annotate_user_memaccess(
12048                    memory_index,
12049                    memarg,
12050                    0,
12051                    old.as_instruction_value().unwrap(),
12052                )?;
12053                let old = err!(
12054                    self.builder
12055                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12056                );
12057                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12058            }
12059            Operator::I64AtomicRmwXor { ref memarg } => {
12060                let value = self.state.pop1()?.into_int_value();
12061                let offset = self.state.pop1()?.into_int_value();
12062                let memory_index = MemoryIndex::from_u32(0);
12063                let effective_address = self.resolve_memory_ptr(
12064                    memory_index,
12065                    memarg,
12066                    self.intrinsics.ptr_ty,
12067                    offset,
12068                    8,
12069                )?;
12070                self.trap_if_misaligned(memarg, effective_address, 8)?;
12071                let old = self
12072                    .builder
12073                    .build_atomicrmw(
12074                        AtomicRMWBinOp::Xor,
12075                        effective_address,
12076                        value,
12077                        AtomicOrdering::SequentiallyConsistent,
12078                    )
12079                    .unwrap();
12080                self.annotate_user_memaccess(
12081                    memory_index,
12082                    memarg,
12083                    0,
12084                    old.as_instruction_value().unwrap(),
12085                )?;
12086                self.state.push1(old);
12087            }
12088            Operator::I32AtomicRmw8XchgU { ref memarg } => {
12089                let value = self.state.pop1()?.into_int_value();
12090                let offset = self.state.pop1()?.into_int_value();
12091                let memory_index = MemoryIndex::from_u32(0);
12092                let effective_address = self.resolve_memory_ptr(
12093                    memory_index,
12094                    memarg,
12095                    self.intrinsics.ptr_ty,
12096                    offset,
12097                    1,
12098                )?;
12099                self.trap_if_misaligned(memarg, effective_address, 1)?;
12100                let narrow_value = err!(self.builder.build_int_truncate(
12101                    value,
12102                    self.intrinsics.i8_ty,
12103                    ""
12104                ));
12105                let old = self
12106                    .builder
12107                    .build_atomicrmw(
12108                        AtomicRMWBinOp::Xchg,
12109                        effective_address,
12110                        narrow_value,
12111                        AtomicOrdering::SequentiallyConsistent,
12112                    )
12113                    .unwrap();
12114                self.annotate_user_memaccess(
12115                    memory_index,
12116                    memarg,
12117                    0,
12118                    old.as_instruction_value().unwrap(),
12119                )?;
12120                let old = err!(
12121                    self.builder
12122                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12123                );
12124                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12125            }
12126            Operator::I32AtomicRmw16XchgU { ref memarg } => {
12127                let value = self.state.pop1()?.into_int_value();
12128                let offset = self.state.pop1()?.into_int_value();
12129                let memory_index = MemoryIndex::from_u32(0);
12130                let effective_address = self.resolve_memory_ptr(
12131                    memory_index,
12132                    memarg,
12133                    self.intrinsics.ptr_ty,
12134                    offset,
12135                    2,
12136                )?;
12137                self.trap_if_misaligned(memarg, effective_address, 2)?;
12138                let narrow_value = err!(self.builder.build_int_truncate(
12139                    value,
12140                    self.intrinsics.i16_ty,
12141                    ""
12142                ));
12143                let old = self
12144                    .builder
12145                    .build_atomicrmw(
12146                        AtomicRMWBinOp::Xchg,
12147                        effective_address,
12148                        narrow_value,
12149                        AtomicOrdering::SequentiallyConsistent,
12150                    )
12151                    .unwrap();
12152                self.annotate_user_memaccess(
12153                    memory_index,
12154                    memarg,
12155                    0,
12156                    old.as_instruction_value().unwrap(),
12157                )?;
12158                let old = err!(
12159                    self.builder
12160                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12161                );
12162                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12163            }
12164            Operator::I32AtomicRmwXchg { ref memarg } => {
12165                let value = self.state.pop1()?.into_int_value();
12166                let offset = self.state.pop1()?.into_int_value();
12167                let memory_index = MemoryIndex::from_u32(0);
12168                let effective_address = self.resolve_memory_ptr(
12169                    memory_index,
12170                    memarg,
12171                    self.intrinsics.ptr_ty,
12172                    offset,
12173                    4,
12174                )?;
12175                self.trap_if_misaligned(memarg, effective_address, 4)?;
12176                let old = self
12177                    .builder
12178                    .build_atomicrmw(
12179                        AtomicRMWBinOp::Xchg,
12180                        effective_address,
12181                        value,
12182                        AtomicOrdering::SequentiallyConsistent,
12183                    )
12184                    .unwrap();
12185                self.annotate_user_memaccess(
12186                    memory_index,
12187                    memarg,
12188                    0,
12189                    old.as_instruction_value().unwrap(),
12190                )?;
12191                self.state.push1(old);
12192            }
12193            Operator::I64AtomicRmw8XchgU { ref memarg } => {
12194                let value = self.state.pop1()?.into_int_value();
12195                let offset = self.state.pop1()?.into_int_value();
12196                let memory_index = MemoryIndex::from_u32(0);
12197                let effective_address = self.resolve_memory_ptr(
12198                    memory_index,
12199                    memarg,
12200                    self.intrinsics.ptr_ty,
12201                    offset,
12202                    1,
12203                )?;
12204                self.trap_if_misaligned(memarg, effective_address, 1)?;
12205                let narrow_value = err!(self.builder.build_int_truncate(
12206                    value,
12207                    self.intrinsics.i8_ty,
12208                    ""
12209                ));
12210                let old = self
12211                    .builder
12212                    .build_atomicrmw(
12213                        AtomicRMWBinOp::Xchg,
12214                        effective_address,
12215                        narrow_value,
12216                        AtomicOrdering::SequentiallyConsistent,
12217                    )
12218                    .unwrap();
12219                self.annotate_user_memaccess(
12220                    memory_index,
12221                    memarg,
12222                    0,
12223                    old.as_instruction_value().unwrap(),
12224                )?;
12225                let old = err!(
12226                    self.builder
12227                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12228                );
12229                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12230            }
12231            Operator::I64AtomicRmw16XchgU { ref memarg } => {
12232                let value = self.state.pop1()?.into_int_value();
12233                let offset = self.state.pop1()?.into_int_value();
12234                let memory_index = MemoryIndex::from_u32(0);
12235                let effective_address = self.resolve_memory_ptr(
12236                    memory_index,
12237                    memarg,
12238                    self.intrinsics.ptr_ty,
12239                    offset,
12240                    2,
12241                )?;
12242                self.trap_if_misaligned(memarg, effective_address, 2)?;
12243                let narrow_value = err!(self.builder.build_int_truncate(
12244                    value,
12245                    self.intrinsics.i16_ty,
12246                    ""
12247                ));
12248                let old = self
12249                    .builder
12250                    .build_atomicrmw(
12251                        AtomicRMWBinOp::Xchg,
12252                        effective_address,
12253                        narrow_value,
12254                        AtomicOrdering::SequentiallyConsistent,
12255                    )
12256                    .unwrap();
12257                self.annotate_user_memaccess(
12258                    memory_index,
12259                    memarg,
12260                    0,
12261                    old.as_instruction_value().unwrap(),
12262                )?;
12263                let old = err!(
12264                    self.builder
12265                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12266                );
12267                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12268            }
12269            Operator::I64AtomicRmw32XchgU { ref memarg } => {
12270                let value = self.state.pop1()?.into_int_value();
12271                let offset = self.state.pop1()?.into_int_value();
12272                let memory_index = MemoryIndex::from_u32(0);
12273                let effective_address = self.resolve_memory_ptr(
12274                    memory_index,
12275                    memarg,
12276                    self.intrinsics.ptr_ty,
12277                    offset,
12278                    4,
12279                )?;
12280                self.trap_if_misaligned(memarg, effective_address, 4)?;
12281                let narrow_value = err!(self.builder.build_int_truncate(
12282                    value,
12283                    self.intrinsics.i32_ty,
12284                    ""
12285                ));
12286                let old = self
12287                    .builder
12288                    .build_atomicrmw(
12289                        AtomicRMWBinOp::Xchg,
12290                        effective_address,
12291                        narrow_value,
12292                        AtomicOrdering::SequentiallyConsistent,
12293                    )
12294                    .unwrap();
12295                self.annotate_user_memaccess(
12296                    memory_index,
12297                    memarg,
12298                    0,
12299                    old.as_instruction_value().unwrap(),
12300                )?;
12301                let old = err!(
12302                    self.builder
12303                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12304                );
12305                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12306            }
12307            Operator::I64AtomicRmwXchg { ref memarg } => {
12308                let value = self.state.pop1()?.into_int_value();
12309                let offset = self.state.pop1()?.into_int_value();
12310                let memory_index = MemoryIndex::from_u32(0);
12311                let effective_address = self.resolve_memory_ptr(
12312                    memory_index,
12313                    memarg,
12314                    self.intrinsics.ptr_ty,
12315                    offset,
12316                    8,
12317                )?;
12318                self.trap_if_misaligned(memarg, effective_address, 8)?;
12319                let old = self
12320                    .builder
12321                    .build_atomicrmw(
12322                        AtomicRMWBinOp::Xchg,
12323                        effective_address,
12324                        value,
12325                        AtomicOrdering::SequentiallyConsistent,
12326                    )
12327                    .unwrap();
12328                self.annotate_user_memaccess(
12329                    memory_index,
12330                    memarg,
12331                    0,
12332                    old.as_instruction_value().unwrap(),
12333                )?;
12334                self.state.push1(old);
12335            }
12336            Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
12337                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12338                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12339                let new = self.apply_pending_canonicalization(new, new_info)?;
12340                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12341                let offset = self.state.pop1()?.into_int_value();
12342                let memory_index = MemoryIndex::from_u32(0);
12343                let effective_address = self.resolve_memory_ptr(
12344                    memory_index,
12345                    memarg,
12346                    self.intrinsics.ptr_ty,
12347                    offset,
12348                    1,
12349                )?;
12350                self.trap_if_misaligned(memarg, effective_address, 1)?;
12351                let narrow_cmp = err!(self.builder.build_int_truncate(
12352                    cmp,
12353                    self.intrinsics.i8_ty,
12354                    ""
12355                ));
12356                let narrow_new = err!(self.builder.build_int_truncate(
12357                    new,
12358                    self.intrinsics.i8_ty,
12359                    ""
12360                ));
12361                let old = self
12362                    .builder
12363                    .build_cmpxchg(
12364                        effective_address,
12365                        narrow_cmp,
12366                        narrow_new,
12367                        AtomicOrdering::SequentiallyConsistent,
12368                        AtomicOrdering::SequentiallyConsistent,
12369                    )
12370                    .unwrap();
12371                self.annotate_user_memaccess(
12372                    memory_index,
12373                    memarg,
12374                    0,
12375                    old.as_instruction_value().unwrap(),
12376                )?;
12377                let old = self
12378                    .builder
12379                    .build_extract_value(old, 0, "")
12380                    .unwrap()
12381                    .into_int_value();
12382                let old = err!(
12383                    self.builder
12384                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12385                );
12386                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12387            }
12388            Operator::I32AtomicRmw16CmpxchgU { ref memarg } => {
12389                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12390                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12391                let new = self.apply_pending_canonicalization(new, new_info)?;
12392                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12393                let offset = self.state.pop1()?.into_int_value();
12394                let memory_index = MemoryIndex::from_u32(0);
12395                let effective_address = self.resolve_memory_ptr(
12396                    memory_index,
12397                    memarg,
12398                    self.intrinsics.ptr_ty,
12399                    offset,
12400                    2,
12401                )?;
12402                self.trap_if_misaligned(memarg, effective_address, 2)?;
12403                let narrow_cmp = err!(self.builder.build_int_truncate(
12404                    cmp,
12405                    self.intrinsics.i16_ty,
12406                    ""
12407                ));
12408                let narrow_new = err!(self.builder.build_int_truncate(
12409                    new,
12410                    self.intrinsics.i16_ty,
12411                    ""
12412                ));
12413                let old = self
12414                    .builder
12415                    .build_cmpxchg(
12416                        effective_address,
12417                        narrow_cmp,
12418                        narrow_new,
12419                        AtomicOrdering::SequentiallyConsistent,
12420                        AtomicOrdering::SequentiallyConsistent,
12421                    )
12422                    .unwrap();
12423                self.annotate_user_memaccess(
12424                    memory_index,
12425                    memarg,
12426                    0,
12427                    old.as_instruction_value().unwrap(),
12428                )?;
12429                let old = self
12430                    .builder
12431                    .build_extract_value(old, 0, "")
12432                    .unwrap()
12433                    .into_int_value();
12434                let old = err!(
12435                    self.builder
12436                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12437                );
12438                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12439            }
12440            Operator::I32AtomicRmwCmpxchg { ref memarg } => {
12441                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12442                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12443                let new = self.apply_pending_canonicalization(new, new_info)?;
12444                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12445                let offset = self.state.pop1()?.into_int_value();
12446                let memory_index = MemoryIndex::from_u32(0);
12447                let effective_address = self.resolve_memory_ptr(
12448                    memory_index,
12449                    memarg,
12450                    self.intrinsics.ptr_ty,
12451                    offset,
12452                    4,
12453                )?;
12454                self.trap_if_misaligned(memarg, effective_address, 4)?;
12455                let old = self
12456                    .builder
12457                    .build_cmpxchg(
12458                        effective_address,
12459                        cmp,
12460                        new,
12461                        AtomicOrdering::SequentiallyConsistent,
12462                        AtomicOrdering::SequentiallyConsistent,
12463                    )
12464                    .unwrap();
12465                self.annotate_user_memaccess(
12466                    memory_index,
12467                    memarg,
12468                    0,
12469                    old.as_instruction_value().unwrap(),
12470                )?;
12471                let old = err!(self.builder.build_extract_value(old, 0, ""));
12472                self.state.push1(old);
12473            }
12474            Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
12475                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12476                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12477                let new = self.apply_pending_canonicalization(new, new_info)?;
12478                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12479                let offset = self.state.pop1()?.into_int_value();
12480                let memory_index = MemoryIndex::from_u32(0);
12481                let effective_address = self.resolve_memory_ptr(
12482                    memory_index,
12483                    memarg,
12484                    self.intrinsics.ptr_ty,
12485                    offset,
12486                    1,
12487                )?;
12488                self.trap_if_misaligned(memarg, effective_address, 1)?;
12489                let narrow_cmp = err!(self.builder.build_int_truncate(
12490                    cmp,
12491                    self.intrinsics.i8_ty,
12492                    ""
12493                ));
12494                let narrow_new = err!(self.builder.build_int_truncate(
12495                    new,
12496                    self.intrinsics.i8_ty,
12497                    ""
12498                ));
12499                let old = self
12500                    .builder
12501                    .build_cmpxchg(
12502                        effective_address,
12503                        narrow_cmp,
12504                        narrow_new,
12505                        AtomicOrdering::SequentiallyConsistent,
12506                        AtomicOrdering::SequentiallyConsistent,
12507                    )
12508                    .unwrap();
12509                self.annotate_user_memaccess(
12510                    memory_index,
12511                    memarg,
12512                    0,
12513                    old.as_instruction_value().unwrap(),
12514                )?;
12515                let old = self
12516                    .builder
12517                    .build_extract_value(old, 0, "")
12518                    .unwrap()
12519                    .into_int_value();
12520                let old = err!(
12521                    self.builder
12522                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12523                );
12524                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12525            }
12526            Operator::I64AtomicRmw16CmpxchgU { ref memarg } => {
12527                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12528                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12529                let new = self.apply_pending_canonicalization(new, new_info)?;
12530                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12531                let offset = self.state.pop1()?.into_int_value();
12532                let memory_index = MemoryIndex::from_u32(0);
12533                let effective_address = self.resolve_memory_ptr(
12534                    memory_index,
12535                    memarg,
12536                    self.intrinsics.ptr_ty,
12537                    offset,
12538                    2,
12539                )?;
12540                self.trap_if_misaligned(memarg, effective_address, 2)?;
12541                let narrow_cmp = err!(self.builder.build_int_truncate(
12542                    cmp,
12543                    self.intrinsics.i16_ty,
12544                    ""
12545                ));
12546                let narrow_new = err!(self.builder.build_int_truncate(
12547                    new,
12548                    self.intrinsics.i16_ty,
12549                    ""
12550                ));
12551                let old = self
12552                    .builder
12553                    .build_cmpxchg(
12554                        effective_address,
12555                        narrow_cmp,
12556                        narrow_new,
12557                        AtomicOrdering::SequentiallyConsistent,
12558                        AtomicOrdering::SequentiallyConsistent,
12559                    )
12560                    .unwrap();
12561                self.annotate_user_memaccess(
12562                    memory_index,
12563                    memarg,
12564                    0,
12565                    old.as_instruction_value().unwrap(),
12566                )?;
12567                let old = self
12568                    .builder
12569                    .build_extract_value(old, 0, "")
12570                    .unwrap()
12571                    .into_int_value();
12572                let old = err!(
12573                    self.builder
12574                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12575                );
12576                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12577            }
12578            Operator::I64AtomicRmw32CmpxchgU { ref memarg } => {
12579                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12580                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12581                let new = self.apply_pending_canonicalization(new, new_info)?;
12582                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12583                let offset = self.state.pop1()?.into_int_value();
12584                let memory_index = MemoryIndex::from_u32(0);
12585                let effective_address = self.resolve_memory_ptr(
12586                    memory_index,
12587                    memarg,
12588                    self.intrinsics.ptr_ty,
12589                    offset,
12590                    4,
12591                )?;
12592                self.trap_if_misaligned(memarg, effective_address, 4)?;
12593                let narrow_cmp = err!(self.builder.build_int_truncate(
12594                    cmp,
12595                    self.intrinsics.i32_ty,
12596                    ""
12597                ));
12598                let narrow_new = err!(self.builder.build_int_truncate(
12599                    new,
12600                    self.intrinsics.i32_ty,
12601                    ""
12602                ));
12603                let old = self
12604                    .builder
12605                    .build_cmpxchg(
12606                        effective_address,
12607                        narrow_cmp,
12608                        narrow_new,
12609                        AtomicOrdering::SequentiallyConsistent,
12610                        AtomicOrdering::SequentiallyConsistent,
12611                    )
12612                    .unwrap();
12613                self.annotate_user_memaccess(
12614                    memory_index,
12615                    memarg,
12616                    0,
12617                    old.as_instruction_value().unwrap(),
12618                )?;
12619                let old = self
12620                    .builder
12621                    .build_extract_value(old, 0, "")
12622                    .unwrap()
12623                    .into_int_value();
12624                let old = err!(
12625                    self.builder
12626                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12627                );
12628                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12629            }
12630            Operator::I64AtomicRmwCmpxchg { ref memarg } => {
12631                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12632                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12633                let new = self.apply_pending_canonicalization(new, new_info)?;
12634                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12635                let offset = self.state.pop1()?.into_int_value();
12636                let memory_index = MemoryIndex::from_u32(0);
12637                let effective_address = self.resolve_memory_ptr(
12638                    memory_index,
12639                    memarg,
12640                    self.intrinsics.ptr_ty,
12641                    offset,
12642                    8,
12643                )?;
12644                self.trap_if_misaligned(memarg, effective_address, 8)?;
12645                let old = self
12646                    .builder
12647                    .build_cmpxchg(
12648                        effective_address,
12649                        cmp,
12650                        new,
12651                        AtomicOrdering::SequentiallyConsistent,
12652                        AtomicOrdering::SequentiallyConsistent,
12653                    )
12654                    .unwrap();
12655                self.annotate_user_memaccess(
12656                    memory_index,
12657                    memarg,
12658                    0,
12659                    old.as_instruction_value().unwrap(),
12660                )?;
12661                let old = err!(self.builder.build_extract_value(old, 0, ""));
12662                self.state.push1(old);
12663            }
12664
12665            Operator::MemoryGrow { mem } => {
12666                let memory_index = MemoryIndex::from_u32(mem);
12667                let delta = self.state.pop1()?;
12668                let grow_fn_ptr = self.ctx.memory_grow(memory_index, self.intrinsics)?;
12669                let grow = err!(self.builder.build_indirect_call(
12670                    self.intrinsics.memory_grow_ty,
12671                    grow_fn_ptr,
12672                    &[
12673                        vmctx.as_basic_value_enum().into(),
12674                        delta.into(),
12675                        self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
12676                    ],
12677                    "",
12678                ));
12679                self.state.push1(grow.try_as_basic_value().left().unwrap());
12680            }
12681            Operator::MemorySize { mem } => {
12682                let memory_index = MemoryIndex::from_u32(mem);
12683                let size_fn_ptr = self.ctx.memory_size(memory_index, self.intrinsics)?;
12684                let size = err!(self.builder.build_indirect_call(
12685                    self.intrinsics.memory_size_ty,
12686                    size_fn_ptr,
12687                    &[
12688                        vmctx.as_basic_value_enum().into(),
12689                        self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
12690                    ],
12691                    "",
12692                ));
12693                //size.add_attribute(AttributeLoc::Function, self.intrinsics.readonly);
12694                self.state.push1(size.try_as_basic_value().left().unwrap());
12695            }
12696            Operator::MemoryInit { data_index, mem } => {
12697                let (dest, src, len) = self.state.pop3()?;
12698                let mem = self.intrinsics.i32_ty.const_int(mem.into(), false);
12699                let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
12700                err!(self.builder.build_call(
12701                    self.intrinsics.memory_init,
12702                    &[
12703                        vmctx.as_basic_value_enum().into(),
12704                        mem.into(),
12705                        segment.into(),
12706                        dest.into(),
12707                        src.into(),
12708                        len.into(),
12709                    ],
12710                    "",
12711                ));
12712            }
12713            Operator::DataDrop { data_index } => {
12714                let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
12715                err!(self.builder.build_call(
12716                    self.intrinsics.data_drop,
12717                    &[vmctx.as_basic_value_enum().into(), segment.into()],
12718                    "",
12719                ));
12720            }
12721            Operator::MemoryCopy { dst_mem, src_mem } => {
12722                // ignored until we support multiple memories
12723                let _dst = dst_mem;
12724                let (memory_copy, src) = if let Some(local_memory_index) = self
12725                    .wasm_module
12726                    .local_memory_index(MemoryIndex::from_u32(src_mem))
12727                {
12728                    (self.intrinsics.memory_copy, local_memory_index.as_u32())
12729                } else {
12730                    (self.intrinsics.imported_memory_copy, src_mem)
12731                };
12732
12733                let (dest_pos, src_pos, len) = self.state.pop3()?;
12734                let src_index = self.intrinsics.i32_ty.const_int(src.into(), false);
12735                err!(self.builder.build_call(
12736                    memory_copy,
12737                    &[
12738                        vmctx.as_basic_value_enum().into(),
12739                        src_index.into(),
12740                        dest_pos.into(),
12741                        src_pos.into(),
12742                        len.into(),
12743                    ],
12744                    "",
12745                ));
12746            }
12747            Operator::MemoryFill { mem } => {
12748                let (memory_fill, mem) = if let Some(local_memory_index) = self
12749                    .wasm_module
12750                    .local_memory_index(MemoryIndex::from_u32(mem))
12751                {
12752                    (self.intrinsics.memory_fill, local_memory_index.as_u32())
12753                } else {
12754                    (self.intrinsics.imported_memory_fill, mem)
12755                };
12756
12757                let (dst, val, len) = self.state.pop3()?;
12758                let mem_index = self.intrinsics.i32_ty.const_int(mem.into(), false);
12759                err!(self.builder.build_call(
12760                    memory_fill,
12761                    &[
12762                        vmctx.as_basic_value_enum().into(),
12763                        mem_index.into(),
12764                        dst.into(),
12765                        val.into(),
12766                        len.into(),
12767                    ],
12768                    "",
12769                ));
12770            }
12771            /***************************
12772             * Reference types.
12773             * https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md
12774             ***************************/
12775            Operator::RefNull { hty } => {
12776                let ty = err!(wpheaptype_to_type(hty));
12777                let ty = type_to_llvm(self.intrinsics, ty)?;
12778                self.state.push1(ty.const_zero());
12779            }
12780            Operator::RefIsNull => {
12781                let value = self.state.pop1()?.into_pointer_value();
12782                let is_null = err!(self.builder.build_is_null(value, ""));
12783                let is_null = err!(self.builder.build_int_z_extend(
12784                    is_null,
12785                    self.intrinsics.i32_ty,
12786                    ""
12787                ));
12788                self.state.push1(is_null);
12789            }
12790            Operator::RefFunc { function_index } => {
12791                let index = self
12792                    .intrinsics
12793                    .i32_ty
12794                    .const_int(function_index.into(), false);
12795                let value = err!(self.builder.build_call(
12796                    self.intrinsics.func_ref,
12797                    &[self.ctx.basic().into(), index.into()],
12798                    "",
12799                ))
12800                .try_as_basic_value()
12801                .left()
12802                .unwrap();
12803                self.state.push1(value);
12804            }
12805            Operator::TableGet { table } => {
12806                let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12807                let elem = self.state.pop1()?;
12808                let table_get = if self
12809                    .wasm_module
12810                    .local_table_index(TableIndex::from_u32(table))
12811                    .is_some()
12812                {
12813                    self.intrinsics.table_get
12814                } else {
12815                    self.intrinsics.imported_table_get
12816                };
12817                let value = err!(self.builder.build_call(
12818                    table_get,
12819                    &[self.ctx.basic().into(), table_index.into(), elem.into()],
12820                    "",
12821                ))
12822                .try_as_basic_value()
12823                .left()
12824                .unwrap();
12825                let value = err!(
12826                    self.builder.build_bit_cast(
12827                        value,
12828                        type_to_llvm(
12829                            self.intrinsics,
12830                            self.wasm_module
12831                                .tables
12832                                .get(TableIndex::from_u32(table))
12833                                .unwrap()
12834                                .ty,
12835                        )?,
12836                        "",
12837                    )
12838                );
12839                self.state.push1(value);
12840            }
12841            Operator::TableSet { table } => {
12842                let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12843                let (elem, value) = self.state.pop2()?;
12844                let value = err!(
12845                    self.builder
12846                        .build_bit_cast(value, self.intrinsics.ptr_ty, "")
12847                );
12848                let table_set = if self
12849                    .wasm_module
12850                    .local_table_index(TableIndex::from_u32(table))
12851                    .is_some()
12852                {
12853                    self.intrinsics.table_set
12854                } else {
12855                    self.intrinsics.imported_table_set
12856                };
12857                err!(self.builder.build_call(
12858                    table_set,
12859                    &[
12860                        self.ctx.basic().into(),
12861                        table_index.into(),
12862                        elem.into(),
12863                        value.into(),
12864                    ],
12865                    "",
12866                ));
12867            }
12868            Operator::TableCopy {
12869                dst_table,
12870                src_table,
12871            } => {
12872                let (dst, src, len) = self.state.pop3()?;
12873                let dst_table = self.intrinsics.i32_ty.const_int(dst_table as u64, false);
12874                let src_table = self.intrinsics.i32_ty.const_int(src_table as u64, false);
12875                err!(self.builder.build_call(
12876                    self.intrinsics.table_copy,
12877                    &[
12878                        self.ctx.basic().into(),
12879                        dst_table.into(),
12880                        src_table.into(),
12881                        dst.into(),
12882                        src.into(),
12883                        len.into(),
12884                    ],
12885                    "",
12886                ));
12887            }
12888            Operator::TableInit { elem_index, table } => {
12889                let (dst, src, len) = self.state.pop3()?;
12890                let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12891                let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12892                err!(self.builder.build_call(
12893                    self.intrinsics.table_init,
12894                    &[
12895                        self.ctx.basic().into(),
12896                        table.into(),
12897                        segment.into(),
12898                        dst.into(),
12899                        src.into(),
12900                        len.into(),
12901                    ],
12902                    "",
12903                ));
12904            }
12905            Operator::ElemDrop { elem_index } => {
12906                let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12907                err!(self.builder.build_call(
12908                    self.intrinsics.elem_drop,
12909                    &[self.ctx.basic().into(), segment.into()],
12910                    "",
12911                ));
12912            }
12913            Operator::TableFill { table } => {
12914                let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12915                let (start, elem, len) = self.state.pop3()?;
12916                let elem = err!(
12917                    self.builder
12918                        .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12919                );
12920                err!(self.builder.build_call(
12921                    self.intrinsics.table_fill,
12922                    &[
12923                        self.ctx.basic().into(),
12924                        table.into(),
12925                        start.into(),
12926                        elem.into(),
12927                        len.into(),
12928                    ],
12929                    "",
12930                ));
12931            }
12932            Operator::TableGrow { table } => {
12933                let (elem, delta) = self.state.pop2()?;
12934                let elem = err!(
12935                    self.builder
12936                        .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12937                );
12938                let (table_grow, table_index) = if let Some(local_table_index) = self
12939                    .wasm_module
12940                    .local_table_index(TableIndex::from_u32(table))
12941                {
12942                    (self.intrinsics.table_grow, local_table_index.as_u32())
12943                } else {
12944                    (self.intrinsics.imported_table_grow, table)
12945                };
12946                let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12947                let size = err!(self.builder.build_call(
12948                    table_grow,
12949                    &[
12950                        self.ctx.basic().into(),
12951                        elem.into(),
12952                        delta.into(),
12953                        table_index.into(),
12954                    ],
12955                    "",
12956                ))
12957                .try_as_basic_value()
12958                .left()
12959                .unwrap();
12960                self.state.push1(size);
12961            }
12962            Operator::TableSize { table } => {
12963                let (table_size, table_index) = if let Some(local_table_index) = self
12964                    .wasm_module
12965                    .local_table_index(TableIndex::from_u32(table))
12966                {
12967                    (self.intrinsics.table_size, local_table_index.as_u32())
12968                } else {
12969                    (self.intrinsics.imported_table_size, table)
12970                };
12971                let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12972                let size = err!(self.builder.build_call(
12973                    table_size,
12974                    &[self.ctx.basic().into(), table_index.into()],
12975                    "",
12976                ))
12977                .try_as_basic_value()
12978                .left()
12979                .unwrap();
12980                self.state.push1(size);
12981            }
12982            Operator::MemoryAtomicWait32 { memarg } => {
12983                let memory_index = MemoryIndex::from_u32(memarg.memory);
12984                let (dst, val, timeout) = self.state.pop3()?;
12985                let wait32_fn_ptr = self.ctx.memory_wait32(memory_index, self.intrinsics)?;
12986                let ret = err!(
12987                    self.builder.build_indirect_call(
12988                        self.intrinsics.memory_wait32_ty,
12989                        wait32_fn_ptr,
12990                        &[
12991                            vmctx.as_basic_value_enum().into(),
12992                            self.intrinsics
12993                                .i32_ty
12994                                .const_int(memarg.memory as u64, false)
12995                                .into(),
12996                            dst.into(),
12997                            val.into(),
12998                            timeout.into(),
12999                        ],
13000                        "",
13001                    )
13002                );
13003                self.state.push1(ret.try_as_basic_value().left().unwrap());
13004            }
13005            Operator::MemoryAtomicWait64 { memarg } => {
13006                let memory_index = MemoryIndex::from_u32(memarg.memory);
13007                let (dst, val, timeout) = self.state.pop3()?;
13008                let wait64_fn_ptr = self.ctx.memory_wait64(memory_index, self.intrinsics)?;
13009                let ret = err!(
13010                    self.builder.build_indirect_call(
13011                        self.intrinsics.memory_wait64_ty,
13012                        wait64_fn_ptr,
13013                        &[
13014                            vmctx.as_basic_value_enum().into(),
13015                            self.intrinsics
13016                                .i32_ty
13017                                .const_int(memarg.memory as u64, false)
13018                                .into(),
13019                            dst.into(),
13020                            val.into(),
13021                            timeout.into(),
13022                        ],
13023                        "",
13024                    )
13025                );
13026                self.state.push1(ret.try_as_basic_value().left().unwrap());
13027            }
13028            Operator::MemoryAtomicNotify { memarg } => {
13029                let memory_index = MemoryIndex::from_u32(memarg.memory);
13030                let (dst, count) = self.state.pop2()?;
13031                let notify_fn_ptr = self.ctx.memory_notify(memory_index, self.intrinsics)?;
13032                let cnt = err!(
13033                    self.builder.build_indirect_call(
13034                        self.intrinsics.memory_notify_ty,
13035                        notify_fn_ptr,
13036                        &[
13037                            vmctx.as_basic_value_enum().into(),
13038                            self.intrinsics
13039                                .i32_ty
13040                                .const_int(memarg.memory as u64, false)
13041                                .into(),
13042                            dst.into(),
13043                            count.into(),
13044                        ],
13045                        "",
13046                    )
13047                );
13048                self.state.push1(cnt.try_as_basic_value().left().unwrap());
13049            }
13050
13051            Operator::TryTable { try_table } => {
13052                let current_block = self
13053                    .builder
13054                    .get_insert_block()
13055                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
13056
13057                self.builder.position_at_end(current_block);
13058
13059                let end_block = self.context.append_basic_block(self.function, "try_end");
13060
13061                let end_phis = {
13062                    self.builder.position_at_end(end_block);
13063
13064                    let phis = self
13065                        .module_translation
13066                        .blocktype_params_results(&try_table.ty)?
13067                        .1
13068                        .iter()
13069                        .map(|&wp_ty| {
13070                            err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
13071                                type_to_llvm(self.intrinsics, wasm_ty)
13072                                    .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
13073                            })
13074                        })
13075                        .collect::<Result<_, _>>()?;
13076
13077                    self.builder.position_at_end(current_block);
13078                    phis
13079                };
13080
13081                // Collect unique catches. It is not a "hard" error on the wasm side,
13082                // but LLVM will definitely complain about having the same identifier
13083                // match two different branches in the switch below.
13084                let catches: Vec<_> = try_table
13085                    .catches
13086                    .into_iter()
13087                    .unique_by(|v| match v {
13088                        Catch::One { tag, .. } | Catch::OneRef { tag, .. } => *tag as i32,
13089                        Catch::All { .. } | Catch::AllRef { .. } => CATCH_ALL_TAG_VALUE,
13090                    })
13091                    .collect();
13092
13093                // Build the landing pad.
13094                let null = self.intrinsics.ptr_ty.const_zero();
13095                let exception_type = self.context.struct_type(
13096                    &[self.intrinsics.ptr_ty.into(), self.intrinsics.i32_ty.into()],
13097                    false,
13098                );
13099
13100                let mut catch_tag_values = vec![];
13101                let mut lpad_clauses: Vec<BasicValueEnum<'ctx>> = catches
13102                    .iter()
13103                    .map(|catch| match catch {
13104                        Catch::All { .. } | Catch::AllRef { .. } => {
13105                            catch_tag_values.push(CATCH_ALL_TAG_VALUE as u32);
13106                            Ok(null.into())
13107                        }
13108                        Catch::One { tag, .. } | Catch::OneRef { tag, .. } => {
13109                            catch_tag_values.push(*tag);
13110                            Ok(self.get_or_insert_tag_type_info_global(*tag as i32))
13111                        }
13112                    })
13113                    .collect::<Result<Vec<BasicValueEnum<'ctx>>, CompileError>>()?;
13114
13115                // Since jumping between landingpads is not possible, we need to collect
13116                // all tags from outer try_tables as well to build a clause for *every*
13117                // possible tag that might be caught.
13118                let mut outer_catch_blocks = vec![];
13119                for outer_landingpad in self.state.landingpads.iter().rev() {
13120                    for catch_info @ TagCatchInfo { tag, .. } in &outer_landingpad.tags {
13121                        if !catch_tag_values.contains(tag) {
13122                            catch_tag_values.push(*tag);
13123                            lpad_clauses.push(if *tag as i32 == CATCH_ALL_TAG_VALUE {
13124                                null.into()
13125                            } else {
13126                                *self.tags_cache.get(&(*tag as i32)).expect(
13127                                    "If a previous try_table encountered a tag, \
13128                                    it should be in the cache",
13129                                )
13130                            });
13131                            outer_catch_blocks.push(*catch_info);
13132                        }
13133                    }
13134                }
13135
13136                // If there are no catch clauses, we have to skip everything, since
13137                // an lpad without catch clauses is invalid (and won't ever be jumped
13138                // to anyway)
13139                let mut maybe_lpad_block = None;
13140                let mut catch_blocks = vec![];
13141                if !lpad_clauses.is_empty() {
13142                    let lpad_block = self.context.append_basic_block(self.function, "catch");
13143                    let catch_all_block =
13144                        self.context.append_basic_block(self.function, "catch_all");
13145                    let catch_specific_block = self
13146                        .context
13147                        .append_basic_block(self.function, "catch_specific");
13148                    let catch_end_block =
13149                        self.context.append_basic_block(self.function, "catch_end");
13150                    let rethrow_block = self.context.append_basic_block(self.function, "rethrow");
13151
13152                    self.builder.position_at_end(lpad_block);
13153
13154                    let res = err!(self.builder.build_landing_pad(
13155                        exception_type,
13156                        self.intrinsics.personality,
13157                        &lpad_clauses,
13158                        false,
13159                        "exc_struct",
13160                    ));
13161
13162                    let res = res.into_struct_value();
13163
13164                    let uw_exc = err!(self.builder.build_extract_value(res, 0, "exc_ptr"));
13165                    let pre_selector =
13166                        err!(self.builder.build_extract_value(res, 1, "pre_selector"));
13167
13168                    // The pre-selector can be either 0 (for catch-all) or 1 (for a
13169                    // specific, but as-yet-unknown tag).
13170                    let pre_selector_is_zero = err!(self.builder.build_int_compare(
13171                        IntPredicate::EQ,
13172                        pre_selector.into_int_value(),
13173                        self.intrinsics.i32_zero,
13174                        "pre_selector_is_zero"
13175                    ));
13176                    err!(self.builder.build_conditional_branch(
13177                        pre_selector_is_zero,
13178                        catch_all_block,
13179                        catch_specific_block
13180                    ));
13181
13182                    self.builder.position_at_end(catch_all_block);
13183                    err!(self.builder.build_unconditional_branch(catch_end_block));
13184
13185                    self.builder.position_at_end(catch_specific_block);
13186                    let vmctx_alloca = err!(self.build_or_get_vmctx_alloca());
13187                    let vmctx_ptr = err!(self.builder.build_load(
13188                        self.intrinsics.ptr_ty,
13189                        vmctx_alloca,
13190                        "vmctx"
13191                    ));
13192                    let selector_value = err!(self.builder.build_call(
13193                        self.intrinsics.personality2,
13194                        &[vmctx_ptr.into(), uw_exc.into()],
13195                        "selector"
13196                    ));
13197                    err!(self.builder.build_unconditional_branch(catch_end_block));
13198
13199                    self.builder.position_at_end(catch_end_block);
13200                    let selector = err!(self.builder.build_phi(self.intrinsics.i32_ty, "selector"));
13201                    selector.add_incoming(&[
13202                        (
13203                            &self
13204                                .intrinsics
13205                                .i32_ty
13206                                .const_int(CATCH_ALL_TAG_VALUE as u64, false),
13207                            catch_all_block,
13208                        ),
13209                        (
13210                            &selector_value
13211                                .try_as_basic_value()
13212                                .left()
13213                                .unwrap()
13214                                .into_int_value(),
13215                            catch_specific_block,
13216                        ),
13217                    ]);
13218
13219                    // The exception we get at this point is a wrapper around the [`WasmerException`]
13220                    // type. This is needed because when we create the exception to pass it to
13221                    // libunwind, the exception object needs to begin with a specific set of fields
13222                    // (those in `__Unwind_Exception`). During unwinding, libunwind uses some of these
13223                    // fields and we need to pass them back when rethrowing. This to say, we need to
13224                    // keep the original exception passed to us by libunwind to be able to rethrow it.
13225                    let uw_exc = uw_exc.into_pointer_value();
13226                    let wasmer_exc = err!(self.builder.build_call(
13227                        self.intrinsics.read_exception,
13228                        &[uw_exc.into()],
13229                        "wasmer_exc_ptr"
13230                    ));
13231
13232                    let wasmer_exc = wasmer_exc.as_any_value_enum().into_pointer_value();
13233                    let selector = selector.as_basic_value().into_int_value();
13234
13235                    for catch in catches.iter() {
13236                        match catch {
13237                            Catch::All { label } => {
13238                                let b = self
13239                                    .context
13240                                    .append_basic_block(self.function, "catch_all_clause");
13241                                self.builder.position_at_end(b);
13242                                let frame = self.state.frame_at_depth(*label)?;
13243
13244                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13245
13246                                self.builder.position_at_end(catch_end_block);
13247                                catch_blocks.push((b, None, None));
13248                            }
13249                            Catch::One { tag, label } => {
13250                                let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
13251                                let signature = &self.wasm_module.signatures[tag_idx];
13252                                let params = signature.params();
13253
13254                                let b = self
13255                                    .context
13256                                    .append_basic_block(self.function, "catch_one_clause");
13257                                self.builder.position_at_end(b);
13258
13259                                let wasmer_exc_phi = err!(
13260                                    self.builder
13261                                        .build_phi(self.intrinsics.ptr_ty, "wasmer_exc_phi")
13262                                );
13263                                wasmer_exc_phi.add_incoming(&[(&wasmer_exc, catch_end_block)]);
13264
13265                                // Get the type of the exception.
13266                                let inner_exc_ty =
13267                                    self.get_or_insert_exception_type(*tag, signature)?;
13268
13269                                // Cast the outer exception - a pointer - to a pointer to a struct of
13270                                // type WasmerException.
13271                                // let wasmer_exc_ptr = err!(self.builder.build_pointer_cast(
13272                                //     exc,
13273                                //     self.intrinsics.exc_ty,
13274                                //     "wasmer_exc_ptr"
13275                                // ));
13276                                //
13277                                // Not actually needed, since ptr is a single, unique type.
13278
13279                                // Points at the `data` field of the exception.
13280                                let wasmer_exc_data_ptr_ptr = err!(self.builder.build_struct_gep(
13281                                    self.intrinsics.exc_ty,
13282                                    wasmer_exc_phi.as_basic_value().into_pointer_value(),
13283                                    1,
13284                                    "wasmer_exc_data_ptr_ptr"
13285                                ));
13286
13287                                let wasmer_exc_data_ptr = err!(self.builder.build_load(
13288                                    self.intrinsics.ptr_ty,
13289                                    wasmer_exc_data_ptr_ptr,
13290                                    "wasmer_exc_data_ptr"
13291                                ));
13292
13293                                let wasmer_exc_data_ptr = wasmer_exc_data_ptr.into_pointer_value();
13294
13295                                // Read each value from the data ptr.
13296                                let values = params
13297                                    .iter()
13298                                    .enumerate()
13299                                    .map(|(i, v)| {
13300                                        let name = format!("value{i}");
13301                                        let ptr = err!(self.builder.build_struct_gep(
13302                                            inner_exc_ty,
13303                                            wasmer_exc_data_ptr,
13304                                            i as u32,
13305                                            &(name.clone() + "ptr")
13306                                        ));
13307                                        err_nt!(self.builder.build_load(
13308                                            type_to_llvm(self.intrinsics, *v)?,
13309                                            ptr,
13310                                            &name,
13311                                        ))
13312                                    })
13313                                    .collect::<Result<Vec<_>, CompileError>>()?;
13314
13315                                let frame = self.state.frame_at_depth(*label)?;
13316
13317                                // todo: check that the types are compatible
13318
13319                                for (phi, value) in frame.phis().iter().zip(values.iter()) {
13320                                    phi.add_incoming(&[(value, b)])
13321                                }
13322
13323                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13324
13325                                self.builder.position_at_end(catch_end_block);
13326                                catch_blocks.push((b, Some(wasmer_exc_phi), None));
13327                            }
13328                            Catch::OneRef { label, tag } => {
13329                                let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
13330                                let signature = &self.wasm_module.signatures[tag_idx];
13331                                let params = signature.params();
13332
13333                                let b = self
13334                                    .context
13335                                    .append_basic_block(self.function, "catch_one_ref_clause");
13336                                self.builder.position_at_end(b);
13337
13338                                let wasmer_exc_phi = err!(
13339                                    self.builder
13340                                        .build_phi(self.intrinsics.ptr_ty, "wasmer_exc_phi")
13341                                );
13342                                wasmer_exc_phi.add_incoming(&[(&wasmer_exc, catch_end_block)]);
13343
13344                                let uw_exc_ptr_phi = err!(
13345                                    self.builder
13346                                        .build_phi(self.intrinsics.ptr_ty, "uw_exc_ptr_phi")
13347                                );
13348                                uw_exc_ptr_phi.add_incoming(&[(&uw_exc, catch_end_block)]);
13349
13350                                // Get the type of the exception.
13351                                let inner_exc_ty =
13352                                    self.get_or_insert_exception_type(*tag, signature)?;
13353
13354                                // Cast the outer exception - a pointer - to a pointer to a struct of
13355                                // type WasmerException.
13356                                // let wasmer_exc_ptr = err!(self.builder.build_pointer_cast(
13357                                //     exc,
13358                                //     self.intrinsics.exc_ty,
13359                                //     "wasmer_exc_ptr"
13360                                // ));
13361                                //
13362                                // Not actually needed, since ptr is a single, unique type.
13363
13364                                // Points at the `data` field of the exception.
13365                                let wasmer_exc_data_ptr_ptr = err!(self.builder.build_struct_gep(
13366                                    self.intrinsics.exc_ty,
13367                                    wasmer_exc_phi.as_basic_value().into_pointer_value(),
13368                                    1,
13369                                    "wasmer_exc_data_ptr"
13370                                ));
13371
13372                                let wasmer_exc_data_ptr = err!(self.builder.build_load(
13373                                    self.intrinsics.ptr_ty,
13374                                    wasmer_exc_data_ptr_ptr,
13375                                    "wasmer_exc_data_ptr"
13376                                ));
13377
13378                                let wasmer_exc_data_ptr = wasmer_exc_data_ptr.into_pointer_value();
13379
13380                                // Read each value from the data ptr.
13381                                let mut values = params
13382                                    .iter()
13383                                    .enumerate()
13384                                    .map(|(i, v)| {
13385                                        let name = format!("value{i}");
13386                                        let ptr = err!(self.builder.build_struct_gep(
13387                                            inner_exc_ty,
13388                                            wasmer_exc_data_ptr,
13389                                            i as u32,
13390                                            &(name.clone() + "ptr")
13391                                        ));
13392                                        err_nt!(self.builder.build_load(
13393                                            type_to_llvm(self.intrinsics, *v)?,
13394                                            ptr,
13395                                            &name,
13396                                        ))
13397                                    })
13398                                    .collect::<Result<Vec<_>, CompileError>>()?;
13399
13400                                values.push(uw_exc_ptr_phi.as_basic_value());
13401
13402                                let frame = self.state.frame_at_depth(*label)?;
13403
13404                                // todo: check that the types are compatible
13405
13406                                for (phi, value) in frame.phis().iter().zip(values.iter()) {
13407                                    phi.add_incoming(&[(value, b)])
13408                                }
13409
13410                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13411
13412                                self.builder.position_at_end(catch_end_block);
13413                                catch_blocks.push((b, Some(wasmer_exc_phi), Some(uw_exc_ptr_phi)));
13414                            }
13415                            Catch::AllRef { label } => {
13416                                let b = self
13417                                    .context
13418                                    .append_basic_block(self.function, "catch_all_ref_clause");
13419                                self.builder.position_at_end(b);
13420
13421                                let uw_exc_ptr_phi = err!(
13422                                    self.builder
13423                                        .build_phi(self.intrinsics.ptr_ty, "uw_exc_ptr_phi")
13424                                );
13425                                uw_exc_ptr_phi.add_incoming(&[(&uw_exc, catch_end_block)]);
13426
13427                                let frame = self.state.frame_at_depth(*label)?;
13428
13429                                let phis = frame.phis();
13430
13431                                // sanity check (todo): check that the phi has only one element
13432
13433                                for phi in phis.iter() {
13434                                    phi.add_incoming(&[(&uw_exc_ptr_phi.as_basic_value(), b)])
13435                                }
13436
13437                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13438
13439                                self.builder.position_at_end(catch_end_block);
13440                                catch_blocks.push((b, None, Some(uw_exc_ptr_phi)));
13441                            }
13442                        }
13443                    }
13444
13445                    for catch_info in &outer_catch_blocks {
13446                        if let Some(phi) = catch_info.wasmer_exc_phi {
13447                            phi.add_incoming(&[(
13448                                &wasmer_exc.as_basic_value_enum(),
13449                                catch_end_block,
13450                            )]);
13451                        }
13452                        if let Some(phi) = catch_info.uw_exc_ptr_phi {
13453                            phi.add_incoming(&[(&uw_exc.as_basic_value_enum(), catch_end_block)]);
13454                        }
13455                    }
13456
13457                    err!(
13458                        self.builder.build_switch(
13459                            selector,
13460                            rethrow_block,
13461                            catch_blocks
13462                                .iter()
13463                                .enumerate()
13464                                .map(|(i, v)| (
13465                                    self.intrinsics
13466                                        .i32_ty
13467                                        .const_int(catch_tag_values[i] as _, false),
13468                                    v.0
13469                                ))
13470                                .chain(outer_catch_blocks.iter().map(|catch_info| (
13471                                    self.intrinsics.i32_ty.const_int(catch_info.tag as _, false),
13472                                    catch_info.catch_block
13473                                )))
13474                                .collect::<Vec<_>>()
13475                                .as_slice()
13476                        )
13477                    );
13478
13479                    // -- end
13480
13481                    // -- The rethrow block
13482                    self.builder.position_at_end(rethrow_block);
13483
13484                    err!(self.builder.build_call(
13485                        self.intrinsics.rethrow,
13486                        &[uw_exc.into()],
13487                        "rethrow"
13488                    ));
13489                    // can't reach after an explicit throw!
13490                    err!(self.builder.build_unreachable());
13491
13492                    maybe_lpad_block = Some(lpad_block);
13493                }
13494
13495                // Move back to current block
13496                self.builder.position_at_end(current_block);
13497
13498                // Note: catch_tag_values also containes outer tags, but zipping with
13499                // catch_blocks will let us ignore the extra ones.
13500                let catch_tags_and_blocks = catch_tag_values
13501                    .into_iter()
13502                    .zip(catch_blocks)
13503                    .map(
13504                        |(tag, (block, wasmer_exc_phi, uw_exc_ptr_phi))| TagCatchInfo {
13505                            tag,
13506                            catch_block: block,
13507                            wasmer_exc_phi,
13508                            uw_exc_ptr_phi,
13509                        },
13510                    )
13511                    .collect::<Vec<_>>();
13512                self.state.push_landingpad(
13513                    maybe_lpad_block,
13514                    end_block,
13515                    end_phis,
13516                    &catch_tags_and_blocks,
13517                    self.module_translation
13518                        .blocktype_params_results(&try_table.ty)?
13519                        .0
13520                        .len(),
13521                );
13522            }
13523            Operator::Throw { tag_index } => {
13524                let current_block = self
13525                    .builder
13526                    .get_insert_block()
13527                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
13528
13529                let tag = self.wasm_module.tags[TagIndex::from_u32(tag_index)];
13530                let signature = &self.wasm_module.signatures[tag];
13531                let params = signature.params();
13532                let values = self.state.popn_save_extra(params.len())?;
13533
13534                let vmctx_alloca = err!(self.build_or_get_vmctx_alloca());
13535                let vmctx_ptr = err!(self.builder.build_load(
13536                    self.intrinsics.ptr_ty,
13537                    vmctx_alloca,
13538                    "vmctx"
13539                ));
13540
13541                values.iter().enumerate().try_for_each(|(i, (v, _))| {
13542                    let t = type_to_llvm(self.intrinsics, params[i])?;
13543                    if t != v.get_type() {
13544                        return Err(CompileError::Codegen(format!(
13545                            "Incompatible types: {:?} != {:?}",
13546                            t,
13547                            v.get_type()
13548                        )));
13549                    }
13550
13551                    Ok(())
13552                })?;
13553
13554                let exception_type: inkwell::types::StructType =
13555                    self.get_or_insert_exception_type(tag_index, signature)?;
13556
13557                let size = exception_type.size_of().unwrap();
13558
13559                // Allocate the necessary bytes for the exception.
13560                let exc = err!(self.builder.build_direct_call(
13561                    self.intrinsics.alloc_exception,
13562                    &[size.into()],
13563                    "exception_ptr",
13564                ));
13565                let exc = exc.try_as_basic_value().left().unwrap();
13566                let exc = exc.into_pointer_value();
13567
13568                for (i, value) in values.into_iter().enumerate() {
13569                    let ptr = err!(self.builder.build_struct_gep(
13570                        exception_type,
13571                        exc,
13572                        i as u32,
13573                        i.to_string().as_str(),
13574                    ));
13575                    err!(self.builder.build_store(ptr, value.0));
13576                }
13577
13578                if let Some(pad) = self.state.get_innermost_landingpad() {
13579                    let unreachable_block = self
13580                        .context
13581                        .append_basic_block(self.function, "_throw_unreachable");
13582
13583                    err!(
13584                        self.builder.build_invoke(
13585                            self.intrinsics.throw,
13586                            &[
13587                                self.intrinsics
13588                                    .i32_ty
13589                                    .const_int(tag_index as _, false)
13590                                    .into(),
13591                                vmctx_ptr,
13592                                exc.into(),
13593                                size.into()
13594                            ],
13595                            unreachable_block,
13596                            pad,
13597                            "throw",
13598                        )
13599                    );
13600
13601                    self.builder.position_at_end(unreachable_block);
13602                    // can't reach after an explicit throw!
13603                    err!(self.builder.build_unreachable());
13604
13605                    self.builder.position_at_end(current_block);
13606                } else {
13607                    err!(
13608                        self.builder.build_call(
13609                            self.intrinsics.throw,
13610                            &[
13611                                // We pass in the module-local tag index, but it'll be translated
13612                                // to a store-unique index in the `throw` intrinsic.
13613                                self.intrinsics
13614                                    .i32_ty
13615                                    .const_int(tag_index as _, false)
13616                                    .into(),
13617                                vmctx_ptr.into(),
13618                                exc.into(),
13619                                size.into()
13620                            ],
13621                            "throw"
13622                        )
13623                    );
13624                    // can't reach after an explicit throw!
13625                    err!(self.builder.build_unreachable());
13626                }
13627
13628                self.state.reachable = false;
13629            }
13630            Operator::ThrowRef => {
13631                let current_block = self
13632                    .builder
13633                    .get_insert_block()
13634                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
13635
13636                let exc = self.state.pop1()?;
13637
13638                if let Some(pad) = self.state.get_innermost_landingpad() {
13639                    let unreachable_block = self
13640                        .context
13641                        .append_basic_block(self.function, "_rethrow_unreachable");
13642
13643                    err!(self.builder.build_invoke(
13644                        self.intrinsics.rethrow,
13645                        &[exc],
13646                        unreachable_block,
13647                        pad,
13648                        "throw",
13649                    ));
13650
13651                    self.builder.position_at_end(unreachable_block);
13652                    // can't reach after an explicit throw!
13653                    err!(self.builder.build_unreachable());
13654
13655                    self.builder.position_at_end(current_block);
13656                } else {
13657                    err!(self.builder.build_call(
13658                        self.intrinsics.rethrow,
13659                        &[exc.into(),],
13660                        "rethrow"
13661                    ));
13662                    // can't reach after an explicit throw!
13663                    err!(self.builder.build_unreachable());
13664                }
13665
13666                self.state.reachable = false;
13667            }
13668            _ => {
13669                return Err(CompileError::Codegen(format!(
13670                    "Operator {op:?} unimplemented",
13671                )));
13672            }
13673        }
13674
13675        Ok(())
13676    }
13677}
13678
13679fn is_f32_arithmetic(bits: u32) -> bool {
13680    // Mask off sign bit.
13681    let bits = bits & 0x7FFF_FFFF;
13682    bits < 0x7FC0_0000
13683}
13684
13685fn is_f64_arithmetic(bits: u64) -> bool {
13686    // Mask off sign bit.
13687    let bits = bits & 0x7FFF_FFFF_FFFF_FFFF;
13688    bits < 0x7FF8_0000_0000_0000
13689}
13690
13691// Constants for the bounds of truncation operations. These are the least or
13692// greatest exact floats in either f32 or f64 representation
13693// greater-than-or-equal-to (for least) or less-than-or-equal-to (for greatest)
13694// the i32 or i64 or u32 or u64 min (for least) or max (for greatest), when
13695// rounding towards zero.
13696
13697/// Least Exact Float (32 bits) greater-than-or-equal-to i32::MIN when rounding towards zero.
13698const LEF32_GEQ_I32_MIN: u64 = i32::MIN as u64;
13699/// Greatest Exact Float (32 bits) less-than-or-equal-to i32::MAX when rounding towards zero.
13700const GEF32_LEQ_I32_MAX: u64 = 2147483520; // bits as f32: 0x4eff_ffff
13701/// Least Exact Float (64 bits) greater-than-or-equal-to i32::MIN when rounding towards zero.
13702const LEF64_GEQ_I32_MIN: u64 = i32::MIN as u64;
13703/// Greatest Exact Float (64 bits) less-than-or-equal-to i32::MAX when rounding towards zero.
13704const GEF64_LEQ_I32_MAX: u64 = i32::MAX as u64;
13705/// Least Exact Float (32 bits) greater-than-or-equal-to u32::MIN when rounding towards zero.
13706const LEF32_GEQ_U32_MIN: u64 = u32::MIN as u64;
13707/// Greatest Exact Float (32 bits) less-than-or-equal-to u32::MAX when rounding towards zero.
13708const GEF32_LEQ_U32_MAX: u64 = 4294967040; // bits as f32: 0x4f7f_ffff
13709/// Least Exact Float (64 bits) greater-than-or-equal-to u32::MIN when rounding towards zero.
13710const LEF64_GEQ_U32_MIN: u64 = u32::MIN as u64;
13711/// Greatest Exact Float (64 bits) less-than-or-equal-to u32::MAX when rounding towards zero.
13712const GEF64_LEQ_U32_MAX: u64 = 4294967295; // bits as f64: 0x41ef_ffff_ffff_ffff
13713/// Least Exact Float (32 bits) greater-than-or-equal-to i64::MIN when rounding towards zero.
13714const LEF32_GEQ_I64_MIN: u64 = i64::MIN as u64;
13715/// Greatest Exact Float (32 bits) less-than-or-equal-to i64::MAX when rounding towards zero.
13716const GEF32_LEQ_I64_MAX: u64 = 9223371487098961920; // bits as f32: 0x5eff_ffff
13717/// Least Exact Float (64 bits) greater-than-or-equal-to i64::MIN when rounding towards zero.
13718const LEF64_GEQ_I64_MIN: u64 = i64::MIN as u64;
13719/// Greatest Exact Float (64 bits) less-than-or-equal-to i64::MAX when rounding towards zero.
13720const GEF64_LEQ_I64_MAX: u64 = 9223372036854774784; // bits as f64: 0x43df_ffff_ffff_ffff
13721/// Least Exact Float (32 bits) greater-than-or-equal-to u64::MIN when rounding towards zero.
13722const LEF32_GEQ_U64_MIN: u64 = u64::MIN;
13723/// Greatest Exact Float (32 bits) less-than-or-equal-to u64::MAX when rounding towards zero.
13724const GEF32_LEQ_U64_MAX: u64 = 18446742974197923840; // bits as f32: 0x5f7f_ffff
13725/// Least Exact Float (64 bits) greater-than-or-equal-to u64::MIN when rounding towards zero.
13726const LEF64_GEQ_U64_MIN: u64 = u64::MIN;
13727/// Greatest Exact Float (64 bits) less-than-or-equal-to u64::MAX when rounding towards zero.
13728const GEF64_LEQ_U64_MAX: u64 = 18446744073709549568; // bits as f64: 0x43ef_ffff_ffff_ffff