wasmer_compiler_llvm/translator/
code.rs

1use std::collections::HashMap;
2
3use super::{
4    intrinsics::{
5        CtxType, FunctionCache, GlobalCache, Intrinsics, MemoryCache, tbaa_label, type_to_llvm,
6    },
7    // stackmap::{StackmapEntry, StackmapEntryKind, StackmapRegistry, ValueSemantic},
8    state::{ControlFrame, ExtraInfo, IfElseState, State, TagCatchInfo},
9};
10use inkwell::{
11    AddressSpace, AtomicOrdering, AtomicRMWBinOp, DLLStorageClass, FloatPredicate, IntPredicate,
12    attributes::AttributeLoc,
13    builder::Builder,
14    context::Context,
15    module::{Linkage, Module},
16    passes::PassBuilderOptions,
17    targets::{FileType, TargetMachine},
18    types::{BasicType, BasicTypeEnum, FloatMathType, IntType, PointerType, VectorType},
19    values::{
20        BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue, FloatValue,
21        FunctionValue, InstructionOpcode, InstructionValue, IntValue, PhiValue, PointerValue,
22        VectorValue,
23    },
24};
25use itertools::Itertools;
26use smallvec::SmallVec;
27use target_lexicon::{BinaryFormat, OperatingSystem, Triple};
28
29use crate::{
30    abi::{Abi, G0M0FunctionKind, LocalFunctionG0M0params, get_abi},
31    config::LLVM,
32    error::{err, err_nt},
33    object_file::{CompiledFunction, load_object_file},
34};
35use wasmer_compiler::{
36    FunctionBinaryReader, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddlewareChain,
37    ModuleTranslationState, from_binaryreadererror_wasmerror,
38    misc::CompiledKind,
39    types::{
40        relocation::RelocationTarget,
41        symbols::{Symbol, SymbolRegistry},
42    },
43    wasmparser::{Catch, MemArg, Operator},
44    wpheaptype_to_type, wptype_to_type,
45};
46use wasmer_types::{
47    CompileError, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex,
48    ModuleInfo, SignatureIndex, TableIndex, Type,
49};
50use wasmer_types::{TagIndex, entity::PrimaryMap};
51use wasmer_vm::{MemoryStyle, TableStyle, VMOffsets};
52
53const FUNCTION_SECTION_ELF: &str = "__TEXT,wasmer_function";
54const FUNCTION_SECTION_MACHO: &str = "__TEXT";
55const FUNCTION_SEGMENT_MACHO: &str = "wasmer_function";
56
57// Since we want to use module-local tag numbers for landing pads,
58// the catch-all tag can't be zero; we instead use i32::MAX, which
59// is hopefully large enough to not conflict with any real tag.
60// If you have 2 billion tags in a single module, you deserve what you get.
61// ( Arshia: that comment above is AI-generated... AI is savage XD )
62const CATCH_ALL_TAG_VALUE: i32 = i32::MAX;
63
64// Use the lowest optimization level for very large function bodies to reduce compile time.
65// See #5997 for more numbers connected to the change.
66const LLVMIR_LARGE_FUNCTION_THRESHOLD: usize = 100_000;
67
68pub struct FuncTranslator {
69    ctx: Context,
70    target_machine: TargetMachine,
71    target_machine_no_opt: Option<TargetMachine>,
72    abi: Box<dyn Abi>,
73    binary_fmt: BinaryFormat,
74    func_section: String,
75}
76
77impl FuncTranslator {
78    pub fn new(
79        target_machine: TargetMachine,
80        target_machine_no_opt: Option<TargetMachine>,
81        binary_fmt: BinaryFormat,
82    ) -> Result<Self, CompileError> {
83        let abi = get_abi(&target_machine);
84        Ok(Self {
85            ctx: Context::create(),
86            target_machine,
87            target_machine_no_opt,
88            abi,
89            func_section: match binary_fmt {
90                BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
91                BinaryFormat::Macho => FUNCTION_SEGMENT_MACHO.to_string(),
92                _ => {
93                    return Err(CompileError::UnsupportedTarget(format!(
94                        "Unsupported binary format: {binary_fmt:?}"
95                    )));
96                }
97            },
98            binary_fmt,
99        })
100    }
101
102    #[allow(clippy::too_many_arguments)]
103    pub fn translate_to_module(
104        &self,
105        wasm_module: &ModuleInfo,
106        module_translation: &ModuleTranslationState,
107        local_func_index: &LocalFunctionIndex,
108        function_body: &FunctionBodyData,
109        config: &LLVM,
110        memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
111        _table_styles: &PrimaryMap<TableIndex, TableStyle>,
112        symbol_registry: &dyn SymbolRegistry,
113        target: &Triple,
114    ) -> Result<Module<'_>, CompileError> {
115        // The function type, used for the callbacks.
116        let func_index = wasm_module.func_index(*local_func_index);
117        let function =
118            CompiledKind::Local(*local_func_index, wasm_module.get_function_name(func_index));
119        let function_name =
120            symbol_registry.symbol_to_name(Symbol::LocalFunction(*local_func_index));
121
122        let g0m0_is_enabled = config.enable_g0m0_opt;
123        let func_kind = if g0m0_is_enabled {
124            Some(G0M0FunctionKind::Local)
125        } else {
126            None
127        };
128
129        let module_name = match wasm_module.name.as_ref() {
130            None => format!("<anonymous module> function {function_name}"),
131            Some(module_name) => format!("module {module_name} function {function_name}"),
132        };
133        let module = self.ctx.create_module(module_name.as_str());
134
135        let target_machine = &self.target_machine;
136        let target_triple = target_machine.get_triple();
137        let target_data = target_machine.get_target_data();
138        module.set_triple(&target_triple);
139        module.set_data_layout(&target_data.get_data_layout());
140        let wasm_fn_type = wasm_module
141            .signatures
142            .get(wasm_module.functions[func_index])
143            .unwrap();
144
145        // TODO: pointer width
146        let offsets = VMOffsets::new(8, wasm_module);
147        let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data, &self.binary_fmt);
148        let (func_type, func_attrs) = self.abi.func_type_to_llvm(
149            &self.ctx,
150            &intrinsics,
151            Some(&offsets),
152            wasm_fn_type,
153            func_kind,
154        )?;
155
156        let func = module.add_function(&function_name, func_type, Some(Linkage::External));
157        for (attr, attr_loc) in &func_attrs {
158            func.add_attribute(*attr_loc, *attr);
159        }
160
161        if !matches!(target.operating_system, OperatingSystem::Windows) {
162            func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe);
163        }
164
165        func.add_attribute(AttributeLoc::Function, intrinsics.uwtable);
166        func.add_attribute(AttributeLoc::Function, intrinsics.frame_pointer);
167
168        let section = match self.binary_fmt {
169            BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
170            BinaryFormat::Macho => {
171                format!("{FUNCTION_SECTION_MACHO},{FUNCTION_SEGMENT_MACHO}")
172            }
173            _ => {
174                return Err(CompileError::UnsupportedTarget(format!(
175                    "Unsupported binary format: {:?}",
176                    self.binary_fmt
177                )));
178            }
179        };
180
181        func.set_personality_function(intrinsics.personality);
182        func.as_global_value().set_section(Some(&section));
183
184        func.set_linkage(Linkage::DLLExport);
185        func.as_global_value()
186            .set_dll_storage_class(DLLStorageClass::Export);
187
188        let entry = self.ctx.append_basic_block(func, "entry");
189        let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
190        let return_ = self.ctx.append_basic_block(func, "return");
191        let alloca_builder = self.ctx.create_builder();
192        let cache_builder = self.ctx.create_builder();
193        let builder = self.ctx.create_builder();
194        cache_builder.position_at_end(entry);
195        let br = err!(cache_builder.build_unconditional_branch(start_of_code));
196        alloca_builder.position_before(&br);
197        cache_builder.position_before(&br);
198        builder.position_at_end(start_of_code);
199
200        let mut state = State::new();
201        builder.position_at_end(return_);
202        let phis: SmallVec<[PhiValue; 1]> = wasm_fn_type
203            .results()
204            .iter()
205            .map(|&wasm_ty| {
206                type_to_llvm(&intrinsics, wasm_ty).map(|ty| builder.build_phi(ty, "").unwrap())
207            })
208            .collect::<Result<_, _>>()?;
209        state.push_block(return_, phis, 0);
210        builder.position_at_end(start_of_code);
211
212        let mut reader = MiddlewareBinaryReader::new_with_offset(
213            function_body.data,
214            function_body.module_offset,
215        );
216        reader.set_middleware_chain(
217            config
218                .middlewares
219                .generate_function_middleware_chain(*local_func_index),
220        );
221
222        let mut params = vec![];
223        let first_param =
224            if func_type.get_return_type().is_none() && wasm_fn_type.results().len() > 1 {
225                if g0m0_is_enabled { 4 } else { 2 }
226            } else if g0m0_is_enabled {
227                3
228            } else {
229                1
230            };
231        let mut is_first_alloca = true;
232        let mut insert_alloca = |ty, name: String| -> Result<PointerValue, CompileError> {
233            let alloca = err!(alloca_builder.build_alloca(ty, &name));
234            if is_first_alloca {
235                alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
236                is_first_alloca = false;
237            }
238            Ok(alloca)
239        };
240
241        // Uncomment to print, at the start of the function, the function name.
242        // (poor man's debugger!)
243        //let func_name_str =
244        //    err!(alloca_builder.build_global_string_ptr(&function_name, "function_name"));
245        //
246        //_ = alloca_builder.build_call(
247        //    intrinsics.debug_str,
248        //    &[
249        //        func_name_str.as_pointer_value().into(),
250        //        intrinsics
251        //            .i32_ty
252        //            .const_int(function_name.len() as _, false)
253        //            .into(),
254        //    ],
255        //    "",
256        //);
257
258        for idx in 0..wasm_fn_type.params().len() {
259            let ty = wasm_fn_type.params()[idx];
260            let ty = type_to_llvm(&intrinsics, ty)?;
261            let value = func
262                .get_nth_param((idx as u32).checked_add(first_param).unwrap())
263                .unwrap();
264            let alloca = insert_alloca(ty, format!("param_{idx}"))?;
265            err!(cache_builder.build_store(alloca, value));
266            params.push((ty, alloca));
267        }
268
269        let mut locals = vec![];
270        let num_locals = reader.read_local_count()?;
271        for idx in 0..num_locals {
272            let (count, ty) = reader.read_local_decl()?;
273            let ty = err!(wptype_to_type(ty));
274            let ty = type_to_llvm(&intrinsics, ty)?;
275            for _ in 0..count {
276                let alloca = insert_alloca(ty, format!("local_{idx}"))?;
277                err!(cache_builder.build_store(alloca, ty.const_zero()));
278                locals.push((ty, alloca));
279            }
280        }
281
282        let mut params_locals = params.clone();
283        params_locals.extend(locals.iter().cloned());
284
285        let mut g0m0_params = None;
286
287        if g0m0_is_enabled {
288            let value = self.abi.get_g0_ptr_param(&func);
289            let g0 = insert_alloca(intrinsics.i32_ty.as_basic_type_enum(), "g0".to_string())?;
290            err!(cache_builder.build_store(g0, value));
291            g0.set_name("g0");
292            let m0 = self.abi.get_m0_ptr_param(&func);
293            m0.set_name("m0_base_ptr");
294
295            g0m0_params = Some((g0, m0));
296        }
297
298        let mut fcg = LLVMFunctionCodeGenerator {
299            g0m0: g0m0_params,
300            context: &self.ctx,
301            builder,
302            alloca_builder,
303            intrinsics: &intrinsics,
304            state,
305            function: func,
306            locals: params_locals,
307            ctx: CtxType::new(wasm_module, &func, &cache_builder, &*self.abi, config),
308            unreachable_depth: 0,
309            memory_styles,
310            _table_styles,
311            module: &module,
312            module_translation,
313            wasm_module,
314            symbol_registry,
315            abi: &*self.abi,
316            config,
317            tags_cache: HashMap::new(),
318            binary_fmt: self.binary_fmt,
319        };
320
321        fcg.ctx.add_func(
322            func_index,
323            func.as_global_value().as_pointer_value(),
324            func_type,
325            fcg.ctx.basic(),
326            &func_attrs,
327        );
328
329        while fcg.state.has_control_frames() {
330            let pos = reader.current_position() as u32;
331            let op = reader.read_operator()?;
332            fcg.translate_operator(op, pos)?;
333        }
334
335        fcg.finalize(wasm_fn_type)?;
336
337        if let Some(ref callbacks) = config.callbacks {
338            callbacks.preopt_ir(&function, &module);
339        }
340
341        let mut passes = vec![];
342
343        if config.enable_verifier {
344            passes.push("verify");
345        }
346
347        passes.push("sccp");
348        passes.push("early-cse");
349        //passes.push("deadargelim");
350        passes.push("adce");
351        passes.push("sroa");
352        passes.push("aggressive-instcombine");
353        passes.push("jump-threading");
354        //passes.push("ipsccp");
355        passes.push("simplifycfg");
356        passes.push("reassociate");
357        passes.push("loop-rotate");
358        passes.push("indvars");
359        //passes.push("lcssa");
360        //passes.push("licm");
361        //passes.push("instcombine");
362        passes.push("sccp");
363        passes.push("reassociate");
364        passes.push("simplifycfg");
365        passes.push("gvn");
366        passes.push("memcpyopt");
367        passes.push("dse");
368        passes.push("dce");
369        //passes.push("instcombine");
370        passes.push("reassociate");
371        passes.push("simplifycfg");
372        passes.push("mem2reg");
373
374        module
375            .run_passes(
376                passes.join(",").as_str(),
377                target_machine,
378                PassBuilderOptions::create(),
379            )
380            .unwrap();
381
382        if let Some(ref callbacks) = config.callbacks {
383            callbacks.postopt_ir(&function, &module);
384        }
385
386        Ok(module)
387    }
388
389    #[allow(clippy::too_many_arguments)]
390    pub fn translate(
391        &self,
392        wasm_module: &ModuleInfo,
393        module_translation: &ModuleTranslationState,
394        local_func_index: &LocalFunctionIndex,
395        function_body: &FunctionBodyData,
396        config: &LLVM,
397        memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
398        table_styles: &PrimaryMap<TableIndex, TableStyle>,
399        symbol_registry: &dyn SymbolRegistry,
400        target: &Triple,
401    ) -> Result<CompiledFunction, CompileError> {
402        let module = self.translate_to_module(
403            wasm_module,
404            module_translation,
405            local_func_index,
406            function_body,
407            config,
408            memory_styles,
409            table_styles,
410            symbol_registry,
411            target,
412        )?;
413        let function = CompiledKind::Local(
414            *local_func_index,
415            wasm_module.get_function_name(wasm_module.func_index(*local_func_index)),
416        );
417
418        let target_machine = if function_body.data.len() > LLVMIR_LARGE_FUNCTION_THRESHOLD {
419            self.target_machine_no_opt
420                .as_ref()
421                .unwrap_or(&self.target_machine)
422        } else {
423            &self.target_machine
424        };
425        let memory_buffer = target_machine
426            .write_to_memory_buffer(&module, FileType::Object)
427            .unwrap();
428
429        if let Some(ref callbacks) = config.callbacks {
430            callbacks.obj_memory_buffer(&function, &memory_buffer);
431            let asm_buffer = target_machine
432                .write_to_memory_buffer(&module, FileType::Assembly)
433                .unwrap();
434            callbacks.asm_memory_buffer(&function, &asm_buffer)
435        }
436
437        let mem_buf_slice = memory_buffer.as_slice();
438
439        load_object_file(
440            mem_buf_slice,
441            &self.func_section,
442            RelocationTarget::LocalFunc(*local_func_index),
443            |name: &str| {
444                Ok({
445                    let name = if matches!(self.binary_fmt, BinaryFormat::Macho) {
446                        if name.starts_with("_") {
447                            name.replacen("_", "", 1)
448                        } else {
449                            name.to_string()
450                        }
451                    } else {
452                        name.to_string()
453                    };
454                    if let Some(Symbol::LocalFunction(local_func_index)) =
455                        symbol_registry.name_to_symbol(&name)
456                    {
457                        Some(RelocationTarget::LocalFunc(local_func_index))
458                    } else {
459                        None
460                    }
461                })
462            },
463            self.binary_fmt,
464        )
465    }
466}
467
468impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
469    // Create a vector where each lane contains the same value.
470    fn splat_vector(
471        &self,
472        value: BasicValueEnum<'ctx>,
473        vec_ty: VectorType<'ctx>,
474    ) -> Result<VectorValue<'ctx>, CompileError> {
475        // Use insert_element to insert the element into an undef vector, then use
476        // shuffle vector to copy that lane to all lanes.
477        err_nt!(
478            self.builder.build_shuffle_vector(
479                err!(self.builder.build_insert_element(
480                    vec_ty.get_undef(),
481                    value,
482                    self.intrinsics.i32_zero,
483                    "",
484                )),
485                vec_ty.get_undef(),
486                self.intrinsics
487                    .i32_ty
488                    .vec_type(vec_ty.get_size())
489                    .const_zero(),
490                "",
491            )
492        )
493    }
494
495    // Convert floating point vector to integer and saturate when out of range.
496    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
497    #[allow(clippy::too_many_arguments)]
498    fn trunc_sat<T: FloatMathType<'ctx>>(
499        &self,
500        fvec_ty: T,
501        ivec_ty: T::MathConvType,
502        lower_bound: u64, // Exclusive (least representable value)
503        upper_bound: u64, // Exclusive (greatest representable value)
504        int_min_value: u64,
505        int_max_value: u64,
506        value: IntValue<'ctx>,
507    ) -> Result<VectorValue<'ctx>, CompileError> {
508        // a) Compare vector with itself to identify NaN lanes.
509        // b) Compare vector with splat of inttofp(upper_bound) to identify
510        //    lanes that need to saturate to max.
511        // c) Compare vector with splat of inttofp(lower_bound) to identify
512        //    lanes that need to saturate to min.
513        // d) Use vector select (not shuffle) to pick from either the
514        //    splat vector or the input vector depending on whether the
515        //    comparison indicates that we have an unrepresentable value. Replace
516        //    unrepresentable values with zero.
517        // e) Now that the value is safe, fpto[su]i it.
518        // f) Use our previous comparison results to replace certain zeros with
519        //    int_min or int_max.
520
521        let fvec_ty = fvec_ty.as_basic_type_enum().into_vector_type();
522        let ivec_ty = ivec_ty.as_basic_type_enum().into_vector_type();
523        let fvec_element_ty = fvec_ty.get_element_type().into_float_type();
524        let ivec_element_ty = ivec_ty.get_element_type().into_int_type();
525
526        let is_signed = int_min_value != 0;
527        let int_min_value = self.splat_vector(
528            ivec_element_ty
529                .const_int(int_min_value, is_signed)
530                .as_basic_value_enum(),
531            ivec_ty,
532        )?;
533        let int_max_value = self.splat_vector(
534            ivec_element_ty
535                .const_int(int_max_value, is_signed)
536                .as_basic_value_enum(),
537            ivec_ty,
538        )?;
539        let lower_bound = if is_signed {
540            err!(self.builder.build_signed_int_to_float(
541                ivec_element_ty.const_int(lower_bound, is_signed),
542                fvec_element_ty,
543                "",
544            ))
545        } else {
546            err!(self.builder.build_unsigned_int_to_float(
547                ivec_element_ty.const_int(lower_bound, is_signed),
548                fvec_element_ty,
549                "",
550            ))
551        };
552        let upper_bound = if is_signed {
553            err!(self.builder.build_signed_int_to_float(
554                ivec_element_ty.const_int(upper_bound, is_signed),
555                fvec_element_ty,
556                "",
557            ))
558        } else {
559            err!(self.builder.build_unsigned_int_to_float(
560                ivec_element_ty.const_int(upper_bound, is_signed),
561                fvec_element_ty,
562                "",
563            ))
564        };
565
566        let value = err!(self.builder.build_bit_cast(value, fvec_ty, "")).into_vector_value();
567        let zero = fvec_ty.const_zero();
568        let lower_bound = self.splat_vector(lower_bound.as_basic_value_enum(), fvec_ty)?;
569        let upper_bound = self.splat_vector(upper_bound.as_basic_value_enum(), fvec_ty)?;
570        let nan_cmp =
571            err!(
572                self.builder
573                    .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
574            );
575        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
576            FloatPredicate::OGT,
577            value,
578            upper_bound,
579            "above_upper_bound",
580        ));
581        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
582            FloatPredicate::OLT,
583            value,
584            lower_bound,
585            "below_lower_bound",
586        ));
587        let not_representable = err!(self.builder.build_or(
588            err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
589            below_lower_bound_cmp,
590            "not_representable_as_int",
591        ));
592        let value =
593            err!(
594                self.builder
595                    .build_select(not_representable, zero, value, "safe_to_convert")
596            )
597            .into_vector_value();
598        let value = if is_signed {
599            self.builder
600                .build_float_to_signed_int(value, ivec_ty, "as_int")
601        } else {
602            self.builder
603                .build_float_to_unsigned_int(value, ivec_ty, "as_int")
604        };
605
606        let value = err!(value);
607        let value =
608            err!(
609                self.builder
610                    .build_select(above_upper_bound_cmp, int_max_value, value, "")
611            )
612            .into_vector_value();
613        err_nt!(
614            self.builder
615                .build_select(below_lower_bound_cmp, int_min_value, value, "")
616                .map(|v| v.into_vector_value())
617        )
618    }
619
620    // Convert floating point vector to integer and saturate when out of range.
621    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
622    #[allow(clippy::too_many_arguments)]
623    fn trunc_sat_into_int<T: FloatMathType<'ctx>>(
624        &self,
625        fvec_ty: T,
626        ivec_ty: T::MathConvType,
627        lower_bound: u64, // Exclusive (least representable value)
628        upper_bound: u64, // Exclusive (greatest representable value)
629        int_min_value: u64,
630        int_max_value: u64,
631        value: IntValue<'ctx>,
632    ) -> Result<IntValue<'ctx>, CompileError> {
633        let res = self.trunc_sat(
634            fvec_ty,
635            ivec_ty,
636            lower_bound,
637            upper_bound,
638            int_min_value,
639            int_max_value,
640            value,
641        )?;
642        err_nt!(
643            self.builder
644                .build_bit_cast(res, self.intrinsics.i128_ty, "")
645                .map(|v| v.into_int_value())
646        )
647    }
648
649    // Convert floating point vector to integer and saturate when out of range.
650    // https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
651    fn trunc_sat_scalar(
652        &self,
653        int_ty: IntType<'ctx>,
654        lower_bound: u64, // Exclusive (least representable value)
655        upper_bound: u64, // Exclusive (greatest representable value)
656        int_min_value: u64,
657        int_max_value: u64,
658        value: FloatValue<'ctx>,
659    ) -> Result<IntValue<'ctx>, CompileError> {
660        // TODO: this is a scalarized version of the process in trunc_sat. Either
661        // we should merge with trunc_sat, or we should simplify this function.
662
663        // a) Compare value with itself to identify NaN.
664        // b) Compare value inttofp(upper_bound) to identify values that need to
665        //    saturate to max.
666        // c) Compare value with inttofp(lower_bound) to identify values that need
667        //    to saturate to min.
668        // d) Use select to pick from either zero or the input vector depending on
669        //    whether the comparison indicates that we have an unrepresentable
670        //    value.
671        // e) Now that the value is safe, fpto[su]i it.
672        // f) Use our previous comparison results to replace certain zeros with
673        //    int_min or int_max.
674
675        let is_signed = int_min_value != 0;
676        let int_min_value = int_ty.const_int(int_min_value, is_signed);
677        let int_max_value = int_ty.const_int(int_max_value, is_signed);
678
679        let lower_bound = if is_signed {
680            err!(self.builder.build_signed_int_to_float(
681                int_ty.const_int(lower_bound, is_signed),
682                value.get_type(),
683                "",
684            ))
685        } else {
686            err!(self.builder.build_unsigned_int_to_float(
687                int_ty.const_int(lower_bound, is_signed),
688                value.get_type(),
689                "",
690            ))
691        };
692        let upper_bound = if is_signed {
693            err!(self.builder.build_signed_int_to_float(
694                int_ty.const_int(upper_bound, is_signed),
695                value.get_type(),
696                "",
697            ))
698        } else {
699            err!(self.builder.build_unsigned_int_to_float(
700                int_ty.const_int(upper_bound, is_signed),
701                value.get_type(),
702                "",
703            ))
704        };
705
706        let zero = value.get_type().const_zero();
707
708        let nan_cmp =
709            err!(
710                self.builder
711                    .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
712            );
713        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
714            FloatPredicate::OGT,
715            value,
716            upper_bound,
717            "above_upper_bound",
718        ));
719        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
720            FloatPredicate::OLT,
721            value,
722            lower_bound,
723            "below_lower_bound",
724        ));
725        let not_representable = err!(self.builder.build_or(
726            err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
727            below_lower_bound_cmp,
728            "not_representable_as_int",
729        ));
730        let value =
731            err!(
732                self.builder
733                    .build_select(not_representable, zero, value, "safe_to_convert")
734            )
735            .into_float_value();
736        let value = if is_signed {
737            err!(
738                self.builder
739                    .build_float_to_signed_int(value, int_ty, "as_int")
740            )
741        } else {
742            err!(
743                self.builder
744                    .build_float_to_unsigned_int(value, int_ty, "as_int")
745            )
746        };
747        let value =
748            err!(
749                self.builder
750                    .build_select(above_upper_bound_cmp, int_max_value, value, "")
751            )
752            .into_int_value();
753        let value =
754            err!(
755                self.builder
756                    .build_select(below_lower_bound_cmp, int_min_value, value, "")
757            )
758            .into_int_value();
759
760        err_nt!(
761            self.builder
762                .build_bit_cast(value, int_ty, "")
763                .map(|v| v.into_int_value())
764        )
765    }
766
767    fn trap_if_not_representable_as_int(
768        &self,
769        lower_bound: u64, // Inclusive (not a trapping value)
770        upper_bound: u64, // Inclusive (not a trapping value)
771        value: FloatValue,
772    ) -> Result<(), CompileError> {
773        let float_ty = value.get_type();
774        let int_ty = if float_ty == self.intrinsics.f32_ty {
775            self.intrinsics.i32_ty
776        } else {
777            self.intrinsics.i64_ty
778        };
779
780        let lower_bound = err!(self.builder.build_bit_cast(
781            int_ty.const_int(lower_bound, false),
782            float_ty,
783            ""
784        ))
785        .into_float_value();
786        let upper_bound = err!(self.builder.build_bit_cast(
787            int_ty.const_int(upper_bound, false),
788            float_ty,
789            ""
790        ))
791        .into_float_value();
792
793        // The 'U' in the float predicate is short for "unordered" which means that
794        // the comparison will compare true if either operand is a NaN. Thus, NaNs
795        // are out of bounds.
796        let above_upper_bound_cmp = err!(self.builder.build_float_compare(
797            FloatPredicate::UGT,
798            value,
799            upper_bound,
800            "above_upper_bound",
801        ));
802        let below_lower_bound_cmp = err!(self.builder.build_float_compare(
803            FloatPredicate::ULT,
804            value,
805            lower_bound,
806            "below_lower_bound",
807        ));
808        let out_of_bounds = err!(self.builder.build_or(
809            above_upper_bound_cmp,
810            below_lower_bound_cmp,
811            "out_of_bounds",
812        ));
813
814        let failure_block = self
815            .context
816            .append_basic_block(self.function, "conversion_failure_block");
817        let continue_block = self
818            .context
819            .append_basic_block(self.function, "conversion_success_block");
820
821        err!(
822            self.builder
823                .build_conditional_branch(out_of_bounds, failure_block, continue_block)
824        );
825        self.builder.position_at_end(failure_block);
826        let is_nan =
827            err!(
828                self.builder
829                    .build_float_compare(FloatPredicate::UNO, value, value, "is_nan")
830            );
831        let trap_code = err!(self.builder.build_select(
832            is_nan,
833            self.intrinsics.trap_bad_conversion_to_integer,
834            self.intrinsics.trap_illegal_arithmetic,
835            "",
836        ));
837        err!(
838            self.builder
839                .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
840        );
841        err!(self.builder.build_unreachable());
842        self.builder.position_at_end(continue_block);
843
844        Ok(())
845    }
846
847    fn trap_if_zero_or_overflow(
848        &self,
849        left: IntValue,
850        right: IntValue,
851    ) -> Result<(), CompileError> {
852        let int_type = left.get_type();
853
854        let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
855            let min_value = int_type.const_int(i32::MIN as u64, false);
856            let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
857            (min_value, neg_one_value)
858        } else if int_type == self.intrinsics.i64_ty {
859            let min_value = int_type.const_int(i64::MIN as u64, false);
860            let neg_one_value = int_type.const_int(-1i64 as u64, false);
861            (min_value, neg_one_value)
862        } else {
863            unreachable!()
864        };
865
866        let divisor_is_zero = err!(self.builder.build_int_compare(
867            IntPredicate::EQ,
868            right,
869            int_type.const_zero(),
870            "divisor_is_zero",
871        ));
872        let should_trap = err!(self.builder.build_or(
873            divisor_is_zero,
874            err!(self.builder.build_and(
875                err!(self.builder.build_int_compare(
876                    IntPredicate::EQ,
877                    left,
878                    min_value,
879                    "left_is_min"
880                )),
881                err!(self.builder.build_int_compare(
882                    IntPredicate::EQ,
883                    right,
884                    neg_one_value,
885                    "right_is_neg_one",
886                )),
887                "div_will_overflow",
888            )),
889            "div_should_trap",
890        ));
891
892        let should_trap = err!(self.builder.build_call(
893            self.intrinsics.expect_i1,
894            &[
895                should_trap.into(),
896                self.intrinsics.i1_ty.const_zero().into(),
897            ],
898            "should_trap_expect",
899        ))
900        .try_as_basic_value()
901        .unwrap_basic()
902        .into_int_value();
903
904        let shouldnt_trap_block = self
905            .context
906            .append_basic_block(self.function, "shouldnt_trap_block");
907        let should_trap_block = self
908            .context
909            .append_basic_block(self.function, "should_trap_block");
910        err!(self.builder.build_conditional_branch(
911            should_trap,
912            should_trap_block,
913            shouldnt_trap_block
914        ));
915        self.builder.position_at_end(should_trap_block);
916        let trap_code = err!(self.builder.build_select(
917            divisor_is_zero,
918            self.intrinsics.trap_integer_division_by_zero,
919            self.intrinsics.trap_illegal_arithmetic,
920            "",
921        ));
922        err!(
923            self.builder
924                .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
925        );
926        err!(self.builder.build_unreachable());
927        self.builder.position_at_end(shouldnt_trap_block);
928
929        Ok(())
930    }
931
932    fn trap_if_zero(&self, value: IntValue) -> Result<(), CompileError> {
933        let int_type = value.get_type();
934        let should_trap = err!(self.builder.build_int_compare(
935            IntPredicate::EQ,
936            value,
937            int_type.const_zero(),
938            "divisor_is_zero",
939        ));
940
941        let should_trap = err!(self.builder.build_call(
942            self.intrinsics.expect_i1,
943            &[
944                should_trap.into(),
945                self.intrinsics.i1_ty.const_zero().into(),
946            ],
947            "should_trap_expect",
948        ))
949        .try_as_basic_value()
950        .unwrap_basic()
951        .into_int_value();
952
953        let shouldnt_trap_block = self
954            .context
955            .append_basic_block(self.function, "shouldnt_trap_block");
956        let should_trap_block = self
957            .context
958            .append_basic_block(self.function, "should_trap_block");
959        err!(self.builder.build_conditional_branch(
960            should_trap,
961            should_trap_block,
962            shouldnt_trap_block
963        ));
964        self.builder.position_at_end(should_trap_block);
965        err!(self.builder.build_call(
966            self.intrinsics.throw_trap,
967            &[self.intrinsics.trap_integer_division_by_zero.into()],
968            "throw",
969        ));
970        err!(self.builder.build_unreachable());
971        self.builder.position_at_end(shouldnt_trap_block);
972
973        Ok(())
974    }
975
976    fn v128_into_int_vec(
977        &self,
978        value: BasicValueEnum<'ctx>,
979        info: ExtraInfo,
980        int_vec_ty: VectorType<'ctx>,
981    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
982        let (value, info) = if self.config.enable_nan_canonicalization {
983            if info.has_pending_f32_nan() {
984                let value = err!(
985                    self.builder
986                        .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
987                );
988                (self.canonicalize_nans(value)?, info.strip_pending())
989            } else if info.has_pending_f64_nan() {
990                let value = err!(
991                    self.builder
992                        .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
993                );
994                (self.canonicalize_nans(value)?, info.strip_pending())
995            } else {
996                (value, info)
997            }
998        } else {
999            (value, info)
1000        };
1001        Ok((
1002            err!(self.builder.build_bit_cast(value, int_vec_ty, "")).into_vector_value(),
1003            info,
1004        ))
1005    }
1006
1007    fn v128_into_i8x16(
1008        &self,
1009        value: BasicValueEnum<'ctx>,
1010        info: ExtraInfo,
1011    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1012        self.v128_into_int_vec(value, info, self.intrinsics.i8x16_ty)
1013    }
1014
1015    fn v128_into_i16x8(
1016        &self,
1017        value: BasicValueEnum<'ctx>,
1018        info: ExtraInfo,
1019    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1020        self.v128_into_int_vec(value, info, self.intrinsics.i16x8_ty)
1021    }
1022
1023    fn v128_into_i32x4(
1024        &self,
1025        value: BasicValueEnum<'ctx>,
1026        info: ExtraInfo,
1027    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1028        self.v128_into_int_vec(value, info, self.intrinsics.i32x4_ty)
1029    }
1030
1031    fn v128_into_i64x2(
1032        &self,
1033        value: BasicValueEnum<'ctx>,
1034        info: ExtraInfo,
1035    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1036        self.v128_into_int_vec(value, info, self.intrinsics.i64x2_ty)
1037    }
1038
1039    // If the value is pending a 64-bit canonicalization, do it now.
1040    // Return a f32x4 vector.
1041    fn v128_into_f32x4(
1042        &self,
1043        value: BasicValueEnum<'ctx>,
1044        info: ExtraInfo,
1045    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1046        let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f64_nan()
1047        {
1048            let value = err!(
1049                self.builder
1050                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1051            );
1052            (self.canonicalize_nans(value)?, info.strip_pending())
1053        } else {
1054            (value, info)
1055        };
1056        Ok((
1057            err!(
1058                self.builder
1059                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1060            )
1061            .into_vector_value(),
1062            info,
1063        ))
1064    }
1065
1066    // If the value is pending a 32-bit canonicalization, do it now.
1067    // Return a f64x2 vector.
1068    fn v128_into_f64x2(
1069        &self,
1070        value: BasicValueEnum<'ctx>,
1071        info: ExtraInfo,
1072    ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1073        let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f32_nan()
1074        {
1075            let value = err!(
1076                self.builder
1077                    .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1078            );
1079            (self.canonicalize_nans(value)?, info.strip_pending())
1080        } else {
1081            (value, info)
1082        };
1083        Ok((
1084            err!(
1085                self.builder
1086                    .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1087            )
1088            .into_vector_value(),
1089            info,
1090        ))
1091    }
1092
1093    fn apply_pending_canonicalization(
1094        &self,
1095        value: BasicValueEnum<'ctx>,
1096        info: ExtraInfo,
1097    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1098        if !self.config.enable_nan_canonicalization {
1099            return Ok(value);
1100        }
1101
1102        if info.has_pending_f32_nan() {
1103            if value.get_type().is_vector_type()
1104                || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1105            {
1106                let ty = value.get_type();
1107                let value = err!(
1108                    self.builder
1109                        .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1110                );
1111                let value = self.canonicalize_nans(value)?;
1112                err_nt!(self.builder.build_bit_cast(value, ty, ""))
1113            } else {
1114                self.canonicalize_nans(value)
1115            }
1116        } else if info.has_pending_f64_nan() {
1117            if value.get_type().is_vector_type()
1118                || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1119            {
1120                let ty = value.get_type();
1121                let value = err!(
1122                    self.builder
1123                        .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1124                );
1125                let value = self.canonicalize_nans(value)?;
1126                err_nt!(self.builder.build_bit_cast(value, ty, ""))
1127            } else {
1128                self.canonicalize_nans(value)
1129            }
1130        } else {
1131            Ok(value)
1132        }
1133    }
1134
1135    // Replaces any NaN with the canonical QNaN, otherwise leaves the value alone.
1136    fn canonicalize_nans(
1137        &self,
1138        value: BasicValueEnum<'ctx>,
1139    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1140        if !self.config.enable_nan_canonicalization {
1141            return Ok(value);
1142        }
1143
1144        let f_ty = value.get_type();
1145        if f_ty.is_vector_type() {
1146            let value = value.into_vector_value();
1147            let f_ty = f_ty.into_vector_type();
1148            let zero = f_ty.const_zero();
1149            let nan_cmp =
1150                err!(
1151                    self.builder
1152                        .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1153                );
1154            let canonical_qnan = f_ty
1155                .get_element_type()
1156                .into_float_type()
1157                .const_float(f64::NAN);
1158            let canonical_qnan = self.splat_vector(canonical_qnan.as_basic_value_enum(), f_ty)?;
1159            err_nt!(
1160                self.builder
1161                    .build_select(nan_cmp, canonical_qnan, value, "")
1162                    .map(|v| v.as_basic_value_enum())
1163            )
1164        } else {
1165            let value = value.into_float_value();
1166            let f_ty = f_ty.into_float_type();
1167            let zero = f_ty.const_zero();
1168            let nan_cmp =
1169                err!(
1170                    self.builder
1171                        .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1172                );
1173            let canonical_qnan = f_ty.const_float(f64::NAN);
1174            err_nt!(
1175                self.builder
1176                    .build_select(nan_cmp, canonical_qnan, value, "")
1177                    .map(|v| v.as_basic_value_enum())
1178            )
1179        }
1180    }
1181
1182    // If this memory access must trap when out of bounds (i.e. it is a memory
1183    // access written in the user program as opposed to one used by our VM)
1184    // then mark that it can't be delete.
1185    fn mark_memaccess_nodelete(
1186        &mut self,
1187        memory_index: MemoryIndex,
1188        memaccess: InstructionValue<'ctx>,
1189    ) -> Result<(), CompileError> {
1190        if let MemoryCache::Static { base_ptr: _ } = self.ctx.memory(
1191            memory_index,
1192            self.intrinsics,
1193            self.module,
1194            self.memory_styles,
1195        )? {
1196            // The best we've got is `volatile`.
1197            // TODO: convert unwrap fail to CompileError
1198            memaccess.set_volatile(true).unwrap();
1199        }
1200        Ok(())
1201    }
1202
1203    fn annotate_user_memaccess(
1204        &mut self,
1205        memory_index: MemoryIndex,
1206        _memarg: &MemArg,
1207        alignment: u32,
1208        memaccess: InstructionValue<'ctx>,
1209    ) -> Result<(), CompileError> {
1210        match memaccess.get_opcode() {
1211            InstructionOpcode::Load | InstructionOpcode::Store => {
1212                memaccess.set_alignment(alignment).unwrap();
1213            }
1214            _ => {}
1215        };
1216        self.mark_memaccess_nodelete(memory_index, memaccess)?;
1217        tbaa_label(
1218            self.module,
1219            self.intrinsics,
1220            format!("memory {}", memory_index.as_u32()),
1221            memaccess,
1222        );
1223        Ok(())
1224    }
1225
1226    fn resolve_memory_ptr(
1227        &mut self,
1228        memory_index: MemoryIndex,
1229        memarg: &MemArg,
1230        ptr_ty: PointerType<'ctx>,
1231        var_offset: IntValue<'ctx>,
1232        value_size: usize,
1233    ) -> Result<PointerValue<'ctx>, CompileError> {
1234        let builder = &self.builder;
1235        let intrinsics = &self.intrinsics;
1236        let context = &self.context;
1237        let function = &self.function;
1238
1239        // Compute the offset into the storage.
1240        let imm_offset = intrinsics.i64_ty.const_int(memarg.offset, false);
1241        let var_offset = err!(builder.build_int_z_extend(var_offset, intrinsics.i64_ty, ""));
1242        let offset = err!(builder.build_int_add(var_offset, imm_offset, ""));
1243
1244        // Look up the memory base (as pointer) and bounds (as unsigned integer).
1245        let base_ptr = if let Some((_, ref m0)) = self.g0m0 {
1246            *m0
1247        } else {
1248            match self
1249                .ctx
1250                .memory(memory_index, intrinsics, self.module, self.memory_styles)?
1251            {
1252                MemoryCache::Dynamic {
1253                    ptr_to_base_ptr,
1254                    ptr_to_current_length,
1255                } => {
1256                    // Bounds check it.
1257                    let minimum = self.wasm_module.memories[memory_index].minimum;
1258                    let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
1259                    let ptr_in_bounds = if offset.is_const() {
1260                        // When the offset is constant, if it's below the minimum
1261                        // memory size, we've statically shown that it's safe.
1262                        let load_offset_end =
1263                            offset.const_add(value_size_v).get_zero_extended_constant();
1264                        if load_offset_end.is_some_and(|load_offset_end| {
1265                            load_offset_end <= minimum.bytes().0 as u64
1266                        }) {
1267                            Some(intrinsics.i64_ty.const_int(1, false))
1268                        } else {
1269                            None
1270                        }
1271                    } else {
1272                        None
1273                    };
1274
1275                    let ptr_in_bounds = match ptr_in_bounds {
1276                        Some(ptr) => ptr,
1277                        None => {
1278                            let load_offset_end = err!(builder.build_int_add(
1279                                offset,
1280                                value_size_v,
1281                                "load_offset_end"
1282                            ));
1283
1284                            let current_length = err!(builder.build_load(
1285                                self.intrinsics.i32_ty,
1286                                ptr_to_current_length,
1287                                "current_length"
1288                            ))
1289                            .into_int_value();
1290                            tbaa_label(
1291                                self.module,
1292                                self.intrinsics,
1293                                format!("memory {} length", memory_index.as_u32()),
1294                                current_length.as_instruction_value().unwrap(),
1295                            );
1296                            let current_length = err!(builder.build_int_z_extend(
1297                                current_length,
1298                                intrinsics.i64_ty,
1299                                "current_length_zextd"
1300                            ));
1301
1302                            err!(builder.build_int_compare(
1303                                IntPredicate::ULE,
1304                                load_offset_end,
1305                                current_length,
1306                                "ptr_in_bounds",
1307                            ))
1308                        }
1309                    };
1310
1311                    if !ptr_in_bounds.is_constant_int()
1312                        || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
1313                    {
1314                        // LLVM may have folded this into 'i1 true' in which case we know
1315                        // the pointer is in bounds. LLVM may also have folded it into a
1316                        // constant expression, not known to be either true or false yet.
1317                        // If it's false, unknown-but-constant, or not-a-constant, emit a
1318                        // runtime bounds check. LLVM may yet succeed at optimizing it away.
1319                        let ptr_in_bounds = err!(builder.build_call(
1320                            intrinsics.expect_i1,
1321                            &[
1322                                ptr_in_bounds.into(),
1323                                intrinsics.i1_ty.const_int(1, true).into(),
1324                            ],
1325                            "ptr_in_bounds_expect",
1326                        ))
1327                        .try_as_basic_value()
1328                        .unwrap_basic()
1329                        .into_int_value();
1330
1331                        let in_bounds_continue_block =
1332                            context.append_basic_block(*function, "in_bounds_continue_block");
1333                        let not_in_bounds_block =
1334                            context.append_basic_block(*function, "not_in_bounds_block");
1335                        err!(builder.build_conditional_branch(
1336                            ptr_in_bounds,
1337                            in_bounds_continue_block,
1338                            not_in_bounds_block,
1339                        ));
1340                        builder.position_at_end(not_in_bounds_block);
1341                        err!(builder.build_call(
1342                            intrinsics.throw_trap,
1343                            &[intrinsics.trap_memory_oob.into()],
1344                            "throw",
1345                        ));
1346                        err!(builder.build_unreachable());
1347                        builder.position_at_end(in_bounds_continue_block);
1348                    }
1349                    let ptr_to_base =
1350                        err!(builder.build_load(intrinsics.ptr_ty, ptr_to_base_ptr, "ptr_to_base"))
1351                            .into_pointer_value();
1352                    tbaa_label(
1353                        self.module,
1354                        self.intrinsics,
1355                        format!("memory base_ptr {}", memory_index.as_u32()),
1356                        ptr_to_base.as_instruction_value().unwrap(),
1357                    );
1358                    ptr_to_base
1359                }
1360                MemoryCache::Static { base_ptr } => base_ptr,
1361            }
1362        };
1363        let value_ptr = unsafe {
1364            err!(builder.build_gep(self.intrinsics.i8_ty, base_ptr, &[offset], "mem_value_ptr"))
1365        };
1366        err_nt!(
1367            builder
1368                .build_bit_cast(value_ptr, ptr_ty, "mem_value")
1369                .map(|v| v.into_pointer_value())
1370        )
1371    }
1372
1373    fn trap_if_misaligned(
1374        &self,
1375        _memarg: &MemArg,
1376        ptr: PointerValue<'ctx>,
1377        align: u8,
1378    ) -> Result<(), CompileError> {
1379        if align <= 1 {
1380            return Ok(());
1381        }
1382        let value = err!(self.builder.build_ptr_to_int(
1383            ptr,
1384            self.intrinsics.i64_ty,
1385            "mischeck_value"
1386        ));
1387        let and = err!(self.builder.build_and(
1388            value,
1389            self.intrinsics.i64_ty.const_int((align - 1).into(), false),
1390            "misaligncheck",
1391        ));
1392        let aligned = err!(self.builder.build_int_compare(
1393            IntPredicate::EQ,
1394            and,
1395            self.intrinsics.i64_zero,
1396            "is_aligned"
1397        ));
1398        let aligned = err!(self.builder.build_call(
1399            self.intrinsics.expect_i1,
1400            &[
1401                aligned.into(),
1402                self.intrinsics.i1_ty.const_int(1, false).into(),
1403            ],
1404            "is_aligned_expect",
1405        ))
1406        .try_as_basic_value()
1407        .unwrap_basic()
1408        .into_int_value();
1409
1410        let continue_block = self
1411            .context
1412            .append_basic_block(self.function, "aligned_access_continue_block");
1413        let not_aligned_block = self
1414            .context
1415            .append_basic_block(self.function, "misaligned_trap_block");
1416        err!(
1417            self.builder
1418                .build_conditional_branch(aligned, continue_block, not_aligned_block)
1419        );
1420
1421        self.builder.position_at_end(not_aligned_block);
1422        err!(self.builder.build_call(
1423            self.intrinsics.throw_trap,
1424            &[self.intrinsics.trap_unaligned_atomic.into()],
1425            "throw",
1426        ));
1427        err!(self.builder.build_unreachable());
1428
1429        self.builder.position_at_end(continue_block);
1430        Ok(())
1431    }
1432
1433    fn finalize(&mut self, wasm_fn_type: &FunctionType) -> Result<(), CompileError> {
1434        let func_type = self.function.get_type();
1435
1436        let results = self.state.popn_save_extra(wasm_fn_type.results().len())?;
1437        let results = err!(
1438            results
1439                .into_iter()
1440                .map(|(v, i)| self.apply_pending_canonicalization(v, i))
1441                .collect::<Result<Vec<_>, _>>()
1442        );
1443
1444        if wasm_fn_type.results().is_empty() {
1445            err!(self.builder.build_return(None));
1446        } else if self.abi.is_sret(wasm_fn_type)? {
1447            let sret = self
1448                .function
1449                .get_first_param()
1450                .unwrap()
1451                .into_pointer_value();
1452            let llvm_params: Vec<_> = wasm_fn_type
1453                .results()
1454                .iter()
1455                .map(|x| type_to_llvm(self.intrinsics, *x).unwrap())
1456                .collect();
1457            let mut struct_value = self
1458                .context
1459                .struct_type(llvm_params.as_slice(), false)
1460                .get_undef();
1461            for (idx, value) in results.into_iter().enumerate() {
1462                let value = err!(self.builder.build_bit_cast(
1463                    value,
1464                    type_to_llvm(self.intrinsics, wasm_fn_type.results()[idx])?,
1465                    "",
1466                ));
1467                struct_value =
1468                    err!(
1469                        self.builder
1470                            .build_insert_value(struct_value, value, idx as u32, "")
1471                    )
1472                    .into_struct_value();
1473            }
1474            err!(self.builder.build_store(sret, struct_value));
1475            err!(self.builder.build_return(None));
1476        } else {
1477            err!(
1478                self.builder
1479                    .build_return(Some(&self.abi.pack_values_for_register_return(
1480                        self.intrinsics,
1481                        &self.builder,
1482                        &results,
1483                        &func_type,
1484                    )?))
1485            );
1486        }
1487        Ok(())
1488    }
1489
1490    // Generates a global constant with the tag's module-local index, which can be used
1491    // as the "type info" of a catch clause.
1492    fn get_or_insert_tag_type_info_global(&mut self, tag: i32) -> BasicValueEnum<'ctx> {
1493        if let Some(tag) = self.tags_cache.get(&tag) {
1494            return *tag;
1495        }
1496
1497        let tag_ty = self
1498            .context
1499            .struct_type(&[self.intrinsics.i32_ty.into()], false);
1500        let tag_glbl = self.module.add_global(
1501            tag_ty,
1502            Some(AddressSpace::default()),
1503            &format!("__wasmer_eh_type_info_{tag}"),
1504        );
1505        tag_glbl.set_initializer(
1506            &tag_ty
1507                .const_named_struct(&[self.intrinsics.i32_ty.const_int(tag as _, false).into()])
1508                .as_basic_value_enum(),
1509        );
1510
1511        tag_glbl.set_linkage(Linkage::External);
1512        tag_glbl.set_constant(true);
1513        // Why set this to a specific section? On macOS it would land on a specifc read only data
1514        // section. GOT-based relocations will probably be generated with a non-zero addend, making
1515        // some EH-related intricacies not working.
1516        //
1517        // The general idea is that each tag has its own section, so the GOT-based relocation can
1518        // have a zero addend, i.e. the data of the tag is the first (and only) value in a specific
1519        // section we can target in relocations.
1520        if matches!(self.binary_fmt, target_lexicon::BinaryFormat::Macho) {
1521            tag_glbl.set_section(Some(&format!("{FUNCTION_SECTION_MACHO},_eh_ti_{tag}")));
1522        }
1523
1524        let tag_glbl = tag_glbl.as_basic_value_enum();
1525
1526        self.tags_cache.insert(tag, tag_glbl);
1527        tag_glbl
1528    }
1529
1530    fn build_g0m0_indirect_call(
1531        &mut self,
1532        table_index: u32,
1533        ctx_ptr: PointerValue<'ctx>,
1534        func_type: &FunctionType,
1535        func_ptr: PointerValue<'ctx>,
1536        func_index: IntValue<'ctx>,
1537    ) -> Result<(), CompileError> {
1538        let Some((g0, m0)) = self.g0m0 else {
1539            return Err(CompileError::Codegen(
1540                "Call to build_g0m0_indirect_call without g0m0 parameters!".to_string(),
1541            ));
1542        };
1543
1544        let mut local_func_indices = vec![];
1545        let mut foreign_func_indices = vec![];
1546
1547        for t in &self.wasm_module.table_initializers {
1548            if t.table_index.as_u32() == table_index {
1549                for (func_in_table_idx, func_idx) in t.elements.iter().enumerate() {
1550                    if self.wasm_module.local_func_index(*func_idx).is_some() {
1551                        local_func_indices.push(func_in_table_idx)
1552                    } else {
1553                        foreign_func_indices.push(func_in_table_idx)
1554                    }
1555                }
1556                break;
1557            }
1558        }
1559
1560        // removed with mem2reg.
1561        //
1562        let g0_value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, "g0"));
1563
1564        let needs_switch = self.g0m0.is_some()
1565            && !local_func_indices.is_empty()
1566            && !foreign_func_indices.is_empty();
1567
1568        if needs_switch {
1569            let foreign_idx_block = self
1570                .context
1571                .append_basic_block(self.function, "foreign_call_block");
1572            let local_idx_block = self
1573                .context
1574                .append_basic_block(self.function, "local_call_block");
1575            let unreachable_indirect_call_branch_block = self
1576                .context
1577                .append_basic_block(self.function, "unreachable_indirect_call_branch");
1578
1579            let cont = self.context.append_basic_block(self.function, "cont");
1580
1581            err!(
1582                self.builder.build_switch(
1583                    func_index,
1584                    unreachable_indirect_call_branch_block,
1585                    &local_func_indices
1586                        .into_iter()
1587                        .map(|v| (
1588                            self.intrinsics.i32_ty.const_int(v as _, false),
1589                            local_idx_block
1590                        ))
1591                        .chain(foreign_func_indices.into_iter().map(|v| (
1592                            self.intrinsics.i32_ty.const_int(v as _, false),
1593                            foreign_idx_block
1594                        )))
1595                        .collect::<Vec<_>>()
1596                )
1597            );
1598
1599            self.builder
1600                .position_at_end(unreachable_indirect_call_branch_block);
1601            err!(self.builder.build_unreachable());
1602
1603            //let current_block = self.builder.get_insert_block().unwrap();
1604            self.builder.position_at_end(local_idx_block);
1605            let local_call_site = self.build_indirect_call(
1606                ctx_ptr,
1607                func_type,
1608                func_ptr,
1609                Some(G0M0FunctionKind::Local),
1610                Some((g0_value.into_int_value(), m0)),
1611            )?;
1612
1613            let local_rets = self.abi.rets_from_call(
1614                &self.builder,
1615                self.intrinsics,
1616                local_call_site,
1617                func_type,
1618            )?;
1619
1620            err!(self.builder.build_unconditional_branch(cont));
1621
1622            self.builder.position_at_end(foreign_idx_block);
1623            let foreign_call_site = self.build_indirect_call(
1624                ctx_ptr,
1625                func_type,
1626                func_ptr,
1627                Some(G0M0FunctionKind::Imported),
1628                None,
1629            )?;
1630
1631            let foreign_rets = self.abi.rets_from_call(
1632                &self.builder,
1633                self.intrinsics,
1634                foreign_call_site,
1635                func_type,
1636            )?;
1637
1638            err!(self.builder.build_unconditional_branch(cont));
1639
1640            self.builder.position_at_end(cont);
1641
1642            for i in 0..foreign_rets.len() {
1643                let f_i = foreign_rets[i];
1644                let l_i = local_rets[i];
1645                let ty = f_i.get_type();
1646                let v = err!(self.builder.build_phi(ty, ""));
1647                v.add_incoming(&[(&f_i, foreign_idx_block), (&l_i, local_idx_block)]);
1648                self.state.push1(v.as_basic_value());
1649            }
1650        } else if foreign_func_indices.is_empty() {
1651            let call_site = self.build_indirect_call(
1652                ctx_ptr,
1653                func_type,
1654                func_ptr,
1655                Some(G0M0FunctionKind::Local),
1656                Some((g0_value.into_int_value(), m0)),
1657            )?;
1658
1659            self.abi
1660                .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1661                .iter()
1662                .for_each(|ret| self.state.push1(*ret));
1663        } else {
1664            let call_site = self.build_indirect_call(
1665                ctx_ptr,
1666                func_type,
1667                func_ptr,
1668                Some(G0M0FunctionKind::Imported),
1669                Some((g0_value.into_int_value(), m0)),
1670            )?;
1671            self.abi
1672                .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1673                .iter()
1674                .for_each(|ret| self.state.push1(*ret));
1675        }
1676
1677        Ok(())
1678    }
1679
1680    fn build_indirect_call(
1681        &mut self,
1682        ctx_ptr: PointerValue<'ctx>,
1683        func_type: &FunctionType,
1684        func_ptr: PointerValue<'ctx>,
1685        func_kind: Option<G0M0FunctionKind>,
1686        g0m0_params: LocalFunctionG0M0params<'ctx>,
1687    ) -> Result<CallSiteValue<'ctx>, CompileError> {
1688        let (llvm_func_type, llvm_func_attrs) = self.abi.func_type_to_llvm(
1689            self.context,
1690            self.intrinsics,
1691            Some(self.ctx.get_offsets()),
1692            func_type,
1693            func_kind,
1694        )?;
1695
1696        let params = self.state.popn_save_extra(func_type.params().len())?;
1697
1698        // Apply pending canonicalizations.
1699        let params = params
1700            .iter()
1701            .zip(func_type.params().iter())
1702            .map(|((v, info), wasm_ty)| match wasm_ty {
1703                Type::F32 => err_nt!(self.builder.build_bit_cast(
1704                    self.apply_pending_canonicalization(*v, *info)?,
1705                    self.intrinsics.f32_ty,
1706                    "",
1707                )),
1708                Type::F64 => err_nt!(self.builder.build_bit_cast(
1709                    self.apply_pending_canonicalization(*v, *info)?,
1710                    self.intrinsics.f64_ty,
1711                    "",
1712                )),
1713                Type::V128 => self.apply_pending_canonicalization(*v, *info),
1714                _ => Ok(*v),
1715            })
1716            .collect::<Result<Vec<_>, _>>()?;
1717
1718        let params = self.abi.args_to_call(
1719            &self.alloca_builder,
1720            func_type,
1721            &llvm_func_type,
1722            ctx_ptr,
1723            params.as_slice(),
1724            self.intrinsics,
1725            g0m0_params,
1726        )?;
1727
1728        let typed_func_ptr = err!(self.builder.build_pointer_cast(
1729            func_ptr,
1730            self.context.ptr_type(AddressSpace::default()),
1731            "typed_func_ptr",
1732        ));
1733
1734        /*
1735        if self.track_state {
1736            if let Some(offset) = opcode_offset {
1737                let mut stackmaps = self.stackmaps.borrow_mut();
1738                emit_stack_map(
1739                    &info,
1740                    self.intrinsics,
1741                    self.builder,
1742                    self.index,
1743                    &mut *stackmaps,
1744                    StackmapEntryKind::Call,
1745                    &self.locals,
1746                    state,
1747                    ctx,
1748                    offset,
1749                )
1750            }
1751        }
1752        */
1753
1754        let call_site_local = if let Some(lpad) = self.state.get_innermost_landingpad() {
1755            let then_block = self.context.append_basic_block(self.function, "then_block");
1756
1757            let ret = err!(self.builder.build_indirect_invoke(
1758                llvm_func_type,
1759                typed_func_ptr,
1760                params.as_slice(),
1761                then_block,
1762                lpad,
1763                "",
1764            ));
1765
1766            self.builder.position_at_end(then_block);
1767            ret
1768        } else {
1769            err!(
1770                self.builder.build_indirect_call(
1771                    llvm_func_type,
1772                    typed_func_ptr,
1773                    params
1774                        .iter()
1775                        .copied()
1776                        .map(Into::into)
1777                        .collect::<Vec<BasicMetadataValueEnum>>()
1778                        .as_slice(),
1779                    "indirect_call",
1780                )
1781            )
1782        };
1783        for (attr, attr_loc) in llvm_func_attrs {
1784            call_site_local.add_attribute(attr_loc, attr);
1785        }
1786
1787        Ok(call_site_local)
1788    }
1789}
1790
1791/*
1792fn emit_stack_map<'ctx>(
1793    intrinsics: &Intrinsics<'ctx>,
1794    builder: &Builder<'ctx>,
1795    local_function_id: usize,
1796    target: &mut StackmapRegistry,
1797    kind: StackmapEntryKind,
1798    locals: &[PointerValue],
1799    state: &State<'ctx>,
1800    _ctx: &mut CtxType<'ctx>,
1801    opcode_offset: usize,
1802) {
1803    let stackmap_id = target.entries.len();
1804
1805    let mut params = Vec::with_capacity(2 + locals.len() + state.stack.len());
1806
1807    params.push(
1808        intrinsics
1809            .i64_ty
1810            .const_int(stackmap_id as u64, false)
1811            .as_basic_value_enum(),
1812    );
1813    params.push(intrinsics.i32_ty.const_zero().as_basic_value_enum());
1814
1815    let locals: Vec<_> = locals.iter().map(|x| x.as_basic_value_enum()).collect();
1816    let mut value_semantics: Vec<ValueSemantic> =
1817        Vec::with_capacity(locals.len() + state.stack.len());
1818
1819    params.extend_from_slice(&locals);
1820    value_semantics.extend((0..locals.len()).map(ValueSemantic::WasmLocal));
1821
1822    params.extend(state.stack.iter().map(|x| x.0));
1823    value_semantics.extend((0..state.stack.len()).map(ValueSemantic::WasmStack));
1824
1825    // FIXME: Information needed for Abstract -> Runtime state transform is not fully preserved
1826    // to accelerate compilation and reduce memory usage. Check this again when we try to support
1827    // "full" LLVM OSR.
1828
1829    assert_eq!(params.len(), value_semantics.len() + 2);
1830
1831    builder.build_call(intrinsics.experimental_stackmap, &params, "");
1832
1833    target.entries.push(StackmapEntry {
1834        kind,
1835        local_function_id,
1836        local_count: locals.len(),
1837        stack_count: state.stack.len(),
1838        opcode_offset,
1839        value_semantics,
1840        is_start: true,
1841    });
1842}
1843
1844fn finalize_opcode_stack_map<'ctx>(
1845    intrinsics: &Intrinsics<'ctx>,
1846    builder: &Builder<'ctx>,
1847    local_function_id: usize,
1848    target: &mut StackmapRegistry,
1849    kind: StackmapEntryKind,
1850    opcode_offset: usize,
1851) {
1852    let stackmap_id = target.entries.len();
1853    builder.build_call(
1854        intrinsics.experimental_stackmap,
1855        &[
1856            intrinsics
1857                .i64_ty
1858                .const_int(stackmap_id as u64, false)
1859                .as_basic_value_enum(),
1860            intrinsics.i32_ty.const_zero().as_basic_value_enum(),
1861        ],
1862        "opcode_stack_map_end",
1863    );
1864    target.entries.push(StackmapEntry {
1865        kind,
1866        local_function_id,
1867        local_count: 0,
1868        stack_count: 0,
1869        opcode_offset,
1870        value_semantics: vec![],
1871        is_start: false,
1872    });
1873}
1874 */
1875
1876pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
1877    g0m0: Option<(PointerValue<'ctx>, PointerValue<'ctx>)>,
1878    context: &'ctx Context,
1879    builder: Builder<'ctx>,
1880    alloca_builder: Builder<'ctx>,
1881    intrinsics: &'a Intrinsics<'ctx>,
1882    state: State<'ctx>,
1883    function: FunctionValue<'ctx>,
1884    locals: Vec<(BasicTypeEnum<'ctx>, PointerValue<'ctx>)>, // Contains params and locals
1885    ctx: CtxType<'ctx, 'a>,
1886    unreachable_depth: usize,
1887    memory_styles: &'a PrimaryMap<MemoryIndex, MemoryStyle>,
1888    _table_styles: &'a PrimaryMap<TableIndex, TableStyle>,
1889
1890    // This is support for stackmaps:
1891    /*
1892    stackmaps: Rc<RefCell<StackmapRegistry>>,
1893    index: usize,
1894    opcode_offset: usize,
1895    track_state: bool,
1896    */
1897    module: &'a Module<'ctx>,
1898    module_translation: &'a ModuleTranslationState,
1899    wasm_module: &'a ModuleInfo,
1900    symbol_registry: &'a dyn SymbolRegistry,
1901    abi: &'a dyn Abi,
1902    config: &'a LLVM,
1903    tags_cache: HashMap<i32, BasicValueEnum<'ctx>>,
1904    binary_fmt: target_lexicon::BinaryFormat,
1905}
1906
1907impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
1908    fn quiet_nan(&self, value: BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, CompileError> {
1909        let intrinsic = if value
1910            .get_type()
1911            .eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1912        {
1913            Some(self.intrinsics.add_f32)
1914        } else if value
1915            .get_type()
1916            .eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1917        {
1918            Some(self.intrinsics.add_f64)
1919        } else if value
1920            .get_type()
1921            .eq(&self.intrinsics.f32x4_ty.as_basic_type_enum())
1922        {
1923            Some(self.intrinsics.add_f32x4)
1924        } else if value
1925            .get_type()
1926            .eq(&self.intrinsics.f64x2_ty.as_basic_type_enum())
1927        {
1928            Some(self.intrinsics.add_f64x2)
1929        } else {
1930            None
1931        };
1932
1933        match intrinsic {
1934            Some(intrinsic) => err_nt!(
1935                self.builder
1936                    .build_call(
1937                        intrinsic,
1938                        &[
1939                            value.into(),
1940                            value.get_type().const_zero().into(),
1941                            self.intrinsics.fp_rounding_md,
1942                            self.intrinsics.fp_exception_md,
1943                        ],
1944                        "",
1945                    )
1946                    .map(|v| v.try_as_basic_value().unwrap_basic())
1947            ),
1948            None => Ok(value),
1949        }
1950    }
1951
1952    fn finalize_minmax_result(
1953        &self,
1954        value: BasicValueEnum<'ctx>,
1955    ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1956        let ty = value.get_type();
1957        if ty.eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1958            || ty.eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1959        {
1960            let value = value.into_float_value();
1961            let is_nan = err!(self.builder.build_float_compare(
1962                FloatPredicate::UNO,
1963                value,
1964                value,
1965                "res_is_nan"
1966            ));
1967            let quiet = self.quiet_nan(value.as_basic_value_enum())?;
1968            let result =
1969                err!(
1970                    self.builder
1971                        .build_select(is_nan, quiet, value.as_basic_value_enum(), "")
1972                );
1973            Ok(result.as_basic_value_enum())
1974        } else if ty.eq(&self.intrinsics.f32x4_ty.as_basic_type_enum()) {
1975            let value = value.into_vector_value();
1976            let is_nan = err!(self.builder.build_call(
1977                self.intrinsics.cmp_f32x4,
1978                &[
1979                    value.into(),
1980                    value.into(),
1981                    self.intrinsics.fp_uno_md,
1982                    self.intrinsics.fp_exception_md,
1983                ],
1984                "",
1985            ))
1986            .try_as_basic_value()
1987            .unwrap_basic()
1988            .into_vector_value();
1989            let quiet = self
1990                .quiet_nan(value.as_basic_value_enum())?
1991                .into_vector_value();
1992            let result = err!(self.builder.build_select(
1993                is_nan,
1994                quiet.as_basic_value_enum(),
1995                value.as_basic_value_enum(),
1996                "",
1997            ));
1998            Ok(result.as_basic_value_enum())
1999        } else if ty.eq(&self.intrinsics.f64x2_ty.as_basic_type_enum()) {
2000            let value = value.into_vector_value();
2001            let is_nan = err!(self.builder.build_call(
2002                self.intrinsics.cmp_f64x2,
2003                &[
2004                    value.into(),
2005                    value.into(),
2006                    self.intrinsics.fp_uno_md,
2007                    self.intrinsics.fp_exception_md,
2008                ],
2009                "",
2010            ))
2011            .try_as_basic_value()
2012            .unwrap_basic()
2013            .into_vector_value();
2014            let quiet = self
2015                .quiet_nan(value.as_basic_value_enum())?
2016                .into_vector_value();
2017            let result = err!(self.builder.build_select(
2018                is_nan,
2019                quiet.as_basic_value_enum(),
2020                value.as_basic_value_enum(),
2021                "",
2022            ));
2023            Ok(result.as_basic_value_enum())
2024        } else {
2025            Ok(value)
2026        }
2027    }
2028
2029    fn translate_operator(&mut self, op: Operator, _source_loc: u32) -> Result<(), CompileError> {
2030        // TODO: remove this vmctx by moving everything into CtxType. Values
2031        // computed off vmctx usually benefit from caching.
2032        let vmctx = &self.ctx.basic().into_pointer_value();
2033
2034        //let opcode_offset: Option<usize> = None;
2035
2036        if !self.state.reachable {
2037            match op {
2038                Operator::Block { blockty: _ }
2039                | Operator::Loop { blockty: _ }
2040                | Operator::If { blockty: _ } => {
2041                    self.unreachable_depth += 1;
2042                    return Ok(());
2043                }
2044                Operator::Else => {
2045                    if self.unreachable_depth != 0 {
2046                        return Ok(());
2047                    }
2048                }
2049                Operator::End => {
2050                    if self.unreachable_depth != 0 {
2051                        self.unreachable_depth -= 1;
2052                        return Ok(());
2053                    }
2054                }
2055                _ => {
2056                    return Ok(());
2057                }
2058            }
2059        }
2060
2061        match op {
2062            /***************************
2063             * Control Flow instructions.
2064             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions
2065             ***************************/
2066            Operator::Block { blockty } => {
2067                let current_block = self
2068                    .builder
2069                    .get_insert_block()
2070                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2071
2072                let end_block = self.context.append_basic_block(self.function, "end");
2073                self.builder.position_at_end(end_block);
2074
2075                let phis: SmallVec<[PhiValue<'ctx>; 1]> = self
2076                    .module_translation
2077                    .blocktype_params_results(&blockty)?
2078                    .1
2079                    .iter()
2080                    .map(|&wp_ty| {
2081                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2082                            type_to_llvm(self.intrinsics, wasm_ty)
2083                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2084                        })
2085                    })
2086                    .collect::<Result<_, _>>()?;
2087
2088                self.state.push_block(
2089                    end_block,
2090                    phis,
2091                    self.module_translation
2092                        .blocktype_params_results(&blockty)?
2093                        .0
2094                        .len(),
2095                );
2096                self.builder.position_at_end(current_block);
2097            }
2098            Operator::Loop { blockty } => {
2099                let loop_body = self.context.append_basic_block(self.function, "loop_body");
2100                let loop_next = self.context.append_basic_block(self.function, "loop_outer");
2101                let pre_loop_block = self.builder.get_insert_block().unwrap();
2102
2103                err!(self.builder.build_unconditional_branch(loop_body));
2104
2105                self.builder.position_at_end(loop_next);
2106                let blocktypes = self.module_translation.blocktype_params_results(&blockty)?;
2107                let phis = blocktypes
2108                    .1
2109                    .iter()
2110                    .map(|&wp_ty| {
2111                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2112                            type_to_llvm(self.intrinsics, wasm_ty)
2113                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2114                        })
2115                    })
2116                    .collect::<Result<_, _>>()?;
2117                self.builder.position_at_end(loop_body);
2118                let loop_phis: SmallVec<[PhiValue<'ctx>; 1]> = blocktypes
2119                    .0
2120                    .iter()
2121                    .map(|&wp_ty| {
2122                        err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2123                            type_to_llvm(self.intrinsics, wasm_ty)
2124                                .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2125                        })
2126                    })
2127                    .collect::<Result<_, _>>()?;
2128                for phi in loop_phis.iter().rev() {
2129                    let (value, info) = self.state.pop1_extra()?;
2130                    let value = self.apply_pending_canonicalization(value, info)?;
2131                    phi.add_incoming(&[(&value, pre_loop_block)]);
2132                }
2133                for phi in &loop_phis {
2134                    self.state.push1(phi.as_basic_value());
2135                }
2136
2137                let num_inputs = loop_phis.len();
2138                self.state
2139                    .push_loop(loop_body, loop_next, loop_phis, phis, num_inputs);
2140            }
2141            Operator::Br { relative_depth } => {
2142                let frame = self.state.frame_at_depth(relative_depth)?;
2143
2144                let current_block = self
2145                    .builder
2146                    .get_insert_block()
2147                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2148
2149                let phis = if frame.is_loop() {
2150                    frame.loop_body_phis()
2151                } else {
2152                    frame.phis()
2153                };
2154
2155                let len = phis.len();
2156                let values = self.state.peekn_extra(len)?;
2157                let values = values
2158                    .iter()
2159                    .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2160                    .collect::<Result<Vec<_>, _>>()?;
2161
2162                // For each result of the block we're branching to,
2163                // pop a value off the value stack and load it into
2164                // the corresponding phi.
2165                for (phi, value) in phis.iter().zip(values.into_iter()) {
2166                    phi.add_incoming(&[(&value, current_block)]);
2167                }
2168
2169                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2170
2171                self.state.popn(len)?;
2172                self.state.reachable = false;
2173            }
2174            Operator::BrIf { relative_depth } => {
2175                let cond = self.state.pop1()?;
2176                let frame = self.state.frame_at_depth(relative_depth)?;
2177
2178                let current_block = self
2179                    .builder
2180                    .get_insert_block()
2181                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2182
2183                let phis = if frame.is_loop() {
2184                    frame.loop_body_phis()
2185                } else {
2186                    frame.phis()
2187                };
2188
2189                let param_stack = self.state.peekn_extra(phis.len())?;
2190                let param_stack = param_stack
2191                    .iter()
2192                    .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2193                    .collect::<Result<Vec<_>, _>>()?;
2194
2195                for (phi, value) in phis.iter().zip(param_stack) {
2196                    phi.add_incoming(&[(&value, current_block)]);
2197                }
2198
2199                let else_block = self.context.append_basic_block(self.function, "else");
2200
2201                let cond_value = err!(self.builder.build_int_compare(
2202                    IntPredicate::NE,
2203                    cond.into_int_value(),
2204                    self.intrinsics.i32_zero,
2205                    "",
2206                ));
2207                err!(self.builder.build_conditional_branch(
2208                    cond_value,
2209                    *frame.br_dest(),
2210                    else_block
2211                ));
2212                self.builder.position_at_end(else_block);
2213            }
2214            Operator::BrTable { ref targets } => {
2215                let current_block = self
2216                    .builder
2217                    .get_insert_block()
2218                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2219
2220                let index = self.state.pop1()?;
2221
2222                let default_frame = self.state.frame_at_depth(targets.default())?;
2223
2224                let phis = if default_frame.is_loop() {
2225                    default_frame.loop_body_phis()
2226                } else {
2227                    default_frame.phis()
2228                };
2229                let args = self.state.peekn(phis.len())?;
2230
2231                for (phi, value) in phis.iter().zip(args.iter()) {
2232                    phi.add_incoming(&[(value, current_block)]);
2233                }
2234
2235                let cases: Vec<_> = targets
2236                    .targets()
2237                    .enumerate()
2238                    .map(|(case_index, depth)| {
2239                        let depth = depth.map_err(from_binaryreadererror_wasmerror)?;
2240                        let frame_result: Result<&ControlFrame, CompileError> =
2241                            self.state.frame_at_depth(depth);
2242                        let frame = match frame_result {
2243                            Ok(v) => v,
2244                            Err(e) => return Err(e),
2245                        };
2246                        let case_index_literal =
2247                            self.context.i32_type().const_int(case_index as u64, false);
2248                        let phis = if frame.is_loop() {
2249                            frame.loop_body_phis()
2250                        } else {
2251                            frame.phis()
2252                        };
2253                        for (phi, value) in phis.iter().zip(args.iter()) {
2254                            phi.add_incoming(&[(value, current_block)]);
2255                        }
2256
2257                        Ok((case_index_literal, *frame.br_dest()))
2258                    })
2259                    .collect::<Result<_, _>>()?;
2260
2261                err!(self.builder.build_switch(
2262                    index.into_int_value(),
2263                    *default_frame.br_dest(),
2264                    &cases[..],
2265                ));
2266
2267                let args_len = args.len();
2268                self.state.popn(args_len)?;
2269                self.state.reachable = false;
2270            }
2271            Operator::If { blockty } => {
2272                let current_block = self
2273                    .builder
2274                    .get_insert_block()
2275                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2276                let if_then_block = self.context.append_basic_block(self.function, "if_then");
2277                let if_else_block = self.context.append_basic_block(self.function, "if_else");
2278                let end_block = self.context.append_basic_block(self.function, "if_end");
2279
2280                let end_phis = {
2281                    self.builder.position_at_end(end_block);
2282
2283                    let phis = self
2284                        .module_translation
2285                        .blocktype_params_results(&blockty)?
2286                        .1
2287                        .iter()
2288                        .map(|&wp_ty| {
2289                            err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2290                                type_to_llvm(self.intrinsics, wasm_ty)
2291                                    .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2292                            })
2293                        })
2294                        .collect::<Result<_, _>>()?;
2295
2296                    self.builder.position_at_end(current_block);
2297                    phis
2298                };
2299
2300                let cond = self.state.pop1()?;
2301
2302                let cond_value = err!(self.builder.build_int_compare(
2303                    IntPredicate::NE,
2304                    cond.into_int_value(),
2305                    self.intrinsics.i32_zero,
2306                    "",
2307                ));
2308
2309                err!(self.builder.build_conditional_branch(
2310                    cond_value,
2311                    if_then_block,
2312                    if_else_block
2313                ));
2314                self.builder.position_at_end(if_else_block);
2315                let block_param_types = self
2316                    .module_translation
2317                    .blocktype_params_results(&blockty)?
2318                    .0
2319                    .iter()
2320                    .map(|&wp_ty| {
2321                        err_nt!(wptype_to_type(wp_ty))
2322                            .and_then(|wasm_ty| type_to_llvm(self.intrinsics, wasm_ty))
2323                    })
2324                    .collect::<Result<Vec<_>, _>>()?;
2325                let else_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2326                    .iter()
2327                    .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2328                    .collect::<Result<SmallVec<_>, _>>()?;
2329                self.builder.position_at_end(if_then_block);
2330                let then_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2331                    .iter()
2332                    .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2333                    .collect::<Result<SmallVec<_>, _>>()?;
2334                for (else_phi, then_phi) in else_phis.iter().rev().zip(then_phis.iter().rev()) {
2335                    let (value, info) = self.state.pop1_extra()?;
2336                    let value = self.apply_pending_canonicalization(value, info)?;
2337                    else_phi.add_incoming(&[(&value, current_block)]);
2338                    then_phi.add_incoming(&[(&value, current_block)]);
2339                }
2340                for phi in then_phis.iter() {
2341                    self.state.push1(phi.as_basic_value());
2342                }
2343
2344                self.state.push_if(
2345                    if_then_block,
2346                    if_else_block,
2347                    end_block,
2348                    then_phis,
2349                    else_phis,
2350                    end_phis,
2351                    block_param_types.len(),
2352                );
2353            }
2354            Operator::Else => {
2355                if self.state.reachable {
2356                    let frame = self.state.frame_at_depth(0)?;
2357                    let current_block = self.builder.get_insert_block().ok_or_else(|| {
2358                        CompileError::Codegen("not currently in a block".to_string())
2359                    })?;
2360
2361                    for phi in frame.phis().to_vec().iter().rev() {
2362                        let (value, info) = self.state.pop1_extra()?;
2363                        let value = self.apply_pending_canonicalization(value, info)?;
2364                        phi.add_incoming(&[(&value, current_block)])
2365                    }
2366
2367                    let frame = self.state.frame_at_depth(0)?;
2368                    err!(self.builder.build_unconditional_branch(*frame.code_after()));
2369                }
2370
2371                let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
2372                    if_else,
2373                    if_else_state,
2374                    ..
2375                } = self.state.frame_at_depth_mut(0)?
2376                {
2377                    (if_else, if_else_state)
2378                } else {
2379                    unreachable!()
2380                };
2381
2382                *if_else_state = IfElseState::Else;
2383
2384                self.builder.position_at_end(*if_else_block);
2385                self.state.reachable = true;
2386
2387                if let ControlFrame::IfElse { else_phis, .. } = self.state.frame_at_depth(0)? {
2388                    // Push our own 'else' phi nodes to the stack.
2389                    for phi in else_phis.clone().iter() {
2390                        self.state.push1(phi.as_basic_value());
2391                    }
2392                };
2393            }
2394
2395            Operator::End => {
2396                let frame = self.state.pop_frame()?;
2397                let current_block = self
2398                    .builder
2399                    .get_insert_block()
2400                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2401
2402                if self.state.reachable {
2403                    for phi in frame.phis().iter().rev() {
2404                        let (value, info) = self.state.pop1_extra()?;
2405                        let value = self.apply_pending_canonicalization(value, info)?;
2406                        phi.add_incoming(&[(&value, current_block)]);
2407                    }
2408
2409                    err!(self.builder.build_unconditional_branch(*frame.code_after()));
2410                }
2411
2412                if let ControlFrame::IfElse {
2413                    if_else,
2414                    next,
2415                    if_else_state: IfElseState::If,
2416                    else_phis,
2417                    ..
2418                } = &frame
2419                {
2420                    for (phi, else_phi) in frame.phis().iter().zip(else_phis.iter()) {
2421                        phi.add_incoming(&[(&else_phi.as_basic_value(), *if_else)]);
2422                    }
2423                    self.builder.position_at_end(*if_else);
2424                    err!(self.builder.build_unconditional_branch(*next));
2425                } else if let ControlFrame::Landingpad { .. } = &frame {
2426                    self.state.pop_landingpad();
2427                };
2428
2429                self.builder.position_at_end(*frame.code_after());
2430                self.state.reset_stack(&frame);
2431
2432                self.state.reachable = true;
2433
2434                // Push each phi value to the value stack.
2435                for phi in frame.phis() {
2436                    if phi.count_incoming() != 0 {
2437                        self.state.push1(phi.as_basic_value());
2438                    } else {
2439                        // TODO if there are no incoming phi values, it means
2440                        // this block has no predecessors, and we can skip it
2441                        // altogether. However, fixing this is non-trivial as
2442                        // some places in the code rely on code getting generated
2443                        // for unreachable end blocks. For now, we let LLVM remove
2444                        // the block during dead code elimination instead.
2445                        let basic_ty = phi.as_basic_value().get_type();
2446                        let placeholder_value = basic_ty.const_zero();
2447                        self.state.push1(placeholder_value);
2448                        phi.as_instruction().erase_from_basic_block();
2449                    }
2450                }
2451            }
2452            Operator::Return => {
2453                let current_block = self
2454                    .builder
2455                    .get_insert_block()
2456                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2457
2458                let frame = self.state.outermost_frame()?;
2459                for phi in frame.phis().to_vec().iter().rev() {
2460                    let (arg, info) = self.state.pop1_extra()?;
2461                    let arg = self.apply_pending_canonicalization(arg, info)?;
2462                    phi.add_incoming(&[(&arg, current_block)]);
2463                }
2464                let frame = self.state.outermost_frame()?;
2465                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2466
2467                self.state.reachable = false;
2468            }
2469
2470            Operator::Unreachable => {
2471                err!(self.builder.build_call(
2472                    self.intrinsics.throw_trap,
2473                    &[self.intrinsics.trap_unreachable.into()],
2474                    "throw",
2475                ));
2476                err!(self.builder.build_unreachable());
2477
2478                self.state.reachable = false;
2479            }
2480
2481            /***************************
2482             * Basic instructions.
2483             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#basic-instructions
2484             ***************************/
2485            Operator::Nop => {
2486                // Do nothing.
2487            }
2488            Operator::Drop => {
2489                self.state.pop1()?;
2490            }
2491
2492            // Generate const values.
2493            Operator::I32Const { value } => {
2494                let i = self.intrinsics.i32_ty.const_int(value as u64, false);
2495                let info = if is_f32_arithmetic(value as u32) {
2496                    ExtraInfo::arithmetic_f32()
2497                } else {
2498                    Default::default()
2499                };
2500                self.state.push1_extra(i, info);
2501            }
2502            Operator::I64Const { value } => {
2503                let i = self.intrinsics.i64_ty.const_int(value as u64, false);
2504                let info = if is_f64_arithmetic(value as u64) {
2505                    ExtraInfo::arithmetic_f64()
2506                } else {
2507                    Default::default()
2508                };
2509                self.state.push1_extra(i, info);
2510            }
2511            Operator::F32Const { value } => {
2512                let bits = self.intrinsics.i32_ty.const_int(value.bits() as u64, false);
2513                let info = if is_f32_arithmetic(value.bits()) {
2514                    ExtraInfo::arithmetic_f32()
2515                } else {
2516                    Default::default()
2517                };
2518                let f = err!(
2519                    self.builder
2520                        .build_bit_cast(bits, self.intrinsics.f32_ty, "f")
2521                );
2522                self.state.push1_extra(f, info);
2523            }
2524            Operator::F64Const { value } => {
2525                let bits = self.intrinsics.i64_ty.const_int(value.bits(), false);
2526                let info = if is_f64_arithmetic(value.bits()) {
2527                    ExtraInfo::arithmetic_f64()
2528                } else {
2529                    Default::default()
2530                };
2531                let f = err!(
2532                    self.builder
2533                        .build_bit_cast(bits, self.intrinsics.f64_ty, "f")
2534                );
2535                self.state.push1_extra(f, info);
2536            }
2537            Operator::V128Const { value } => {
2538                let mut hi: [u8; 8] = Default::default();
2539                let mut lo: [u8; 8] = Default::default();
2540                hi.copy_from_slice(&value.bytes()[0..8]);
2541                lo.copy_from_slice(&value.bytes()[8..16]);
2542                let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
2543                let i = self
2544                    .intrinsics
2545                    .i128_ty
2546                    .const_int_arbitrary_precision(&packed);
2547                let mut quad1: [u8; 4] = Default::default();
2548                let mut quad2: [u8; 4] = Default::default();
2549                let mut quad3: [u8; 4] = Default::default();
2550                let mut quad4: [u8; 4] = Default::default();
2551                quad1.copy_from_slice(&value.bytes()[0..4]);
2552                quad2.copy_from_slice(&value.bytes()[4..8]);
2553                quad3.copy_from_slice(&value.bytes()[8..12]);
2554                quad4.copy_from_slice(&value.bytes()[12..16]);
2555                let mut info: ExtraInfo = Default::default();
2556                if is_f32_arithmetic(u32::from_le_bytes(quad1))
2557                    && is_f32_arithmetic(u32::from_le_bytes(quad2))
2558                    && is_f32_arithmetic(u32::from_le_bytes(quad3))
2559                    && is_f32_arithmetic(u32::from_le_bytes(quad4))
2560                {
2561                    info |= ExtraInfo::arithmetic_f32();
2562                }
2563                if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
2564                    info |= ExtraInfo::arithmetic_f64();
2565                }
2566                self.state.push1_extra(i, info);
2567            }
2568
2569            Operator::I8x16Splat => {
2570                let (v, i) = self.state.pop1_extra()?;
2571                let v = v.into_int_value();
2572                let v = err!(
2573                    self.builder
2574                        .build_int_truncate(v, self.intrinsics.i8_ty, "")
2575                );
2576                let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
2577                let res = err!(
2578                    self.builder
2579                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2580                );
2581                self.state.push1_extra(res, i);
2582            }
2583            Operator::I16x8Splat => {
2584                let (v, i) = self.state.pop1_extra()?;
2585                let v = v.into_int_value();
2586                let v = err!(
2587                    self.builder
2588                        .build_int_truncate(v, self.intrinsics.i16_ty, "")
2589                );
2590                let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
2591                let res = err!(
2592                    self.builder
2593                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2594                );
2595                self.state.push1_extra(res, i);
2596            }
2597            Operator::I32x4Splat => {
2598                let (v, i) = self.state.pop1_extra()?;
2599                let res = self.splat_vector(v, self.intrinsics.i32x4_ty)?;
2600                let res = err!(
2601                    self.builder
2602                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2603                );
2604                self.state.push1_extra(res, i);
2605            }
2606            Operator::I64x2Splat => {
2607                let (v, i) = self.state.pop1_extra()?;
2608                let res = self.splat_vector(v, self.intrinsics.i64x2_ty)?;
2609                let res = err!(
2610                    self.builder
2611                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2612                );
2613                self.state.push1_extra(res, i);
2614            }
2615            Operator::F32x4Splat => {
2616                let (v, i) = self.state.pop1_extra()?;
2617                let res = self.splat_vector(v, self.intrinsics.f32x4_ty)?;
2618                let res = err!(
2619                    self.builder
2620                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2621                );
2622                // The spec is unclear, we interpret splat as preserving NaN
2623                // payload bits.
2624                self.state.push1_extra(res, i);
2625            }
2626            Operator::F64x2Splat => {
2627                let (v, i) = self.state.pop1_extra()?;
2628                let res = self.splat_vector(v, self.intrinsics.f64x2_ty)?;
2629                let res = err!(
2630                    self.builder
2631                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
2632                );
2633                // The spec is unclear, we interpret splat as preserving NaN
2634                // payload bits.
2635                self.state.push1_extra(res, i);
2636            }
2637
2638            // Operate on self.locals.
2639            Operator::LocalGet { local_index } => {
2640                let (type_value, pointer_value) = self.locals[local_index as usize];
2641                let v = err!(self.builder.build_load(
2642                    type_value,
2643                    pointer_value,
2644                    &format!("local_{local_index}_get")
2645                ));
2646                tbaa_label(
2647                    self.module,
2648                    self.intrinsics,
2649                    format!("local {local_index}"),
2650                    v.as_instruction_value().unwrap(),
2651                );
2652                self.state.push1(v);
2653            }
2654            Operator::LocalSet { local_index } => {
2655                let pointer_value = self.locals[local_index as usize].1;
2656                let (v, i) = self.state.pop1_extra()?;
2657                let v = self.apply_pending_canonicalization(v, i)?;
2658                let store = err!(self.builder.build_store(pointer_value, v));
2659                tbaa_label(
2660                    self.module,
2661                    self.intrinsics,
2662                    format!("local {local_index}"),
2663                    store,
2664                );
2665            }
2666            Operator::LocalTee { local_index } => {
2667                let pointer_value = self.locals[local_index as usize].1;
2668                let (v, i) = self.state.peek1_extra()?;
2669                let v = self.apply_pending_canonicalization(v, i)?;
2670                let store = err!(self.builder.build_store(pointer_value, v));
2671                tbaa_label(
2672                    self.module,
2673                    self.intrinsics,
2674                    format!("local {local_index}"),
2675                    store,
2676                );
2677            }
2678
2679            Operator::GlobalGet { global_index } => {
2680                if self.g0m0.is_some() && global_index == 0 {
2681                    let Some((g0, _)) = self.g0m0 else {
2682                        unreachable!()
2683                    };
2684
2685                    // Removed with mem2reg.
2686                    let value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, ""));
2687
2688                    self.state.push1(value);
2689                } else {
2690                    let global_index = GlobalIndex::from_u32(global_index);
2691                    match self
2692                        .ctx
2693                        .global(global_index, self.intrinsics, self.module)?
2694                    {
2695                        GlobalCache::Const { value } => {
2696                            self.state.push1(*value);
2697                        }
2698                        GlobalCache::Mut {
2699                            ptr_to_value,
2700                            value_type,
2701                        } => {
2702                            let value =
2703                                err!(self.builder.build_load(*value_type, *ptr_to_value, ""));
2704                            tbaa_label(
2705                                self.module,
2706                                self.intrinsics,
2707                                format!("global {}", global_index.as_u32()),
2708                                value.as_instruction_value().unwrap(),
2709                            );
2710                            self.state.push1(value);
2711                        }
2712                    }
2713                }
2714            }
2715            Operator::GlobalSet { global_index } => {
2716                if self.g0m0.is_some() && global_index == 0 {
2717                    let Some((g0, _)) = self.g0m0 else {
2718                        unreachable!()
2719                    };
2720                    let ptr_to_value = g0;
2721                    let (value, info) = self.state.pop1_extra()?;
2722                    let value = self.apply_pending_canonicalization(value, info)?;
2723                    let store = err!(self.builder.build_store(ptr_to_value, value));
2724                    tbaa_label(self.module, self.intrinsics, "global 0".to_string(), store);
2725                } else {
2726                    let global_index = GlobalIndex::from_u32(global_index);
2727                    match self
2728                        .ctx
2729                        .global(global_index, self.intrinsics, self.module)?
2730                    {
2731                        GlobalCache::Const { value: _ } => {
2732                            return Err(CompileError::Codegen(format!(
2733                                "global.set on immutable global index {}",
2734                                global_index.as_u32()
2735                            )));
2736                        }
2737                        GlobalCache::Mut { ptr_to_value, .. } => {
2738                            let ptr_to_value = *ptr_to_value;
2739                            let (value, info) = self.state.pop1_extra()?;
2740                            let value = self.apply_pending_canonicalization(value, info)?;
2741                            let store = err!(self.builder.build_store(ptr_to_value, value));
2742                            tbaa_label(
2743                                self.module,
2744                                self.intrinsics,
2745                                format!("global {}", global_index.as_u32()),
2746                                store,
2747                            );
2748                        }
2749                    }
2750                }
2751            }
2752
2753            // `TypedSelect` must be used for extern refs so ref counting should
2754            // be done with TypedSelect. But otherwise they're the same.
2755            Operator::TypedSelect { .. } | Operator::Select => {
2756                let ((v1, i1), (v2, i2), (cond, _)) = self.state.pop3_extra()?;
2757                // We don't bother canonicalizing 'cond' here because we only
2758                // compare it to zero, and that's invariant under
2759                // canonicalization.
2760
2761                // If the pending bits of v1 and v2 are the same, we can pass
2762                // them along to the result. Otherwise, apply pending
2763                // canonicalizations now.
2764                let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
2765                    || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
2766                {
2767                    (
2768                        self.apply_pending_canonicalization(v1, i1)?,
2769                        i1.strip_pending(),
2770                        self.apply_pending_canonicalization(v2, i2)?,
2771                        i2.strip_pending(),
2772                    )
2773                } else {
2774                    (v1, i1, v2, i2)
2775                };
2776                let cond_value = err!(self.builder.build_int_compare(
2777                    IntPredicate::NE,
2778                    cond.into_int_value(),
2779                    self.intrinsics.i32_zero,
2780                    "",
2781                ));
2782                let res = err!(self.builder.build_select(cond_value, v1, v2, ""));
2783                let info = {
2784                    let mut info = (i1.strip_pending() & i2.strip_pending())?;
2785                    if i1.has_pending_f32_nan() {
2786                        debug_assert!(i2.has_pending_f32_nan());
2787                        info = (info | ExtraInfo::pending_f32_nan())?;
2788                    }
2789                    if i1.has_pending_f64_nan() {
2790                        debug_assert!(i2.has_pending_f64_nan());
2791                        info = (info | ExtraInfo::pending_f64_nan())?;
2792                    }
2793                    info
2794                };
2795                self.state.push1_extra(res, info);
2796            }
2797            Operator::Call { function_index } => {
2798                let func_index = FunctionIndex::from_u32(function_index);
2799                let sigindex = &self.wasm_module.functions[func_index];
2800                let func_type = &self.wasm_module.signatures[*sigindex];
2801
2802                let mut g0m0_params = None;
2803
2804                let FunctionCache {
2805                    func,
2806                    llvm_func_type,
2807                    vmctx: callee_vmctx,
2808                    attrs,
2809                } = if let Some(local_func_index) = self.wasm_module.local_func_index(func_index) {
2810                    if let Some((g0, m0)) = &self.g0m0 {
2811                        // removed with mem2reg.
2812                        let value = err!(self.builder.build_load(self.intrinsics.i32_ty, *g0, ""));
2813
2814                        g0m0_params = Some((value.into_int_value(), *m0));
2815                    }
2816
2817                    let function_name = self
2818                        .symbol_registry
2819                        .symbol_to_name(Symbol::LocalFunction(local_func_index));
2820
2821                    self.ctx.local_func(
2822                        local_func_index,
2823                        func_index,
2824                        self.intrinsics,
2825                        self.module,
2826                        self.context,
2827                        func_type,
2828                        &function_name,
2829                    )?
2830                } else {
2831                    self.ctx
2832                        .func(func_index, self.intrinsics, self.context, func_type)?
2833                };
2834                let llvm_func_type = *llvm_func_type;
2835                let func = *func;
2836                let callee_vmctx = *callee_vmctx;
2837                let attrs = attrs.clone();
2838
2839                /*
2840                let func_ptr = self.llvm.functions.borrow_mut()[&func_index];
2841
2842                (params, func_ptr.as_global_value().as_pointer_value())
2843                */
2844                let params = self.state.popn_save_extra(func_type.params().len())?;
2845
2846                // Apply pending canonicalizations.
2847                let params = params
2848                    .iter()
2849                    .zip(func_type.params().iter())
2850                    .map(|((v, info), wasm_ty)| match wasm_ty {
2851                        Type::F32 => err_nt!(self.builder.build_bit_cast(
2852                            self.apply_pending_canonicalization(*v, *info)?,
2853                            self.intrinsics.f32_ty,
2854                            "",
2855                        )),
2856                        Type::F64 => err_nt!(self.builder.build_bit_cast(
2857                            self.apply_pending_canonicalization(*v, *info)?,
2858                            self.intrinsics.f64_ty,
2859                            "",
2860                        )),
2861                        Type::V128 => self.apply_pending_canonicalization(*v, *info),
2862                        _ => Ok(*v),
2863                    })
2864                    .collect::<Result<Vec<_>, _>>()?;
2865
2866                let params = self.abi.args_to_call(
2867                    &self.alloca_builder,
2868                    func_type,
2869                    &llvm_func_type,
2870                    callee_vmctx.into_pointer_value(),
2871                    params.as_slice(),
2872                    self.intrinsics,
2873                    g0m0_params,
2874                )?;
2875
2876                /*
2877                if self.track_state {
2878                    if let Some(offset) = opcode_offset {
2879                        let mut stackmaps = self.stackmaps.borrow_mut();
2880                        emit_stack_map(
2881                            &info,
2882                            self.intrinsics,
2883                            self.builder,
2884                            self.index,
2885                            &mut *stackmaps,
2886                            StackmapEntryKind::Call,
2887                            &self.locals,
2888                            state,
2889                            ctx,
2890                            offset,
2891                        )
2892                    }
2893                }
2894                */
2895                let call_site = if let Some(lpad) = self.state.get_innermost_landingpad() {
2896                    let then_block = self.context.append_basic_block(self.function, "then_block");
2897
2898                    let ret = err!(self.builder.build_indirect_invoke(
2899                        llvm_func_type,
2900                        func,
2901                        params.as_slice(),
2902                        then_block,
2903                        lpad,
2904                        "",
2905                    ));
2906
2907                    self.builder.position_at_end(then_block);
2908                    ret
2909                } else {
2910                    err!(
2911                        self.builder.build_indirect_call(
2912                            llvm_func_type,
2913                            func,
2914                            params
2915                                .iter()
2916                                .copied()
2917                                .map(Into::into)
2918                                .collect::<Vec<BasicMetadataValueEnum>>()
2919                                .as_slice(),
2920                            "",
2921                        )
2922                    )
2923                };
2924                for (attr, attr_loc) in attrs {
2925                    call_site.add_attribute(attr_loc, attr);
2926                }
2927                /*
2928                if self.track_state {
2929                    if let Some(offset) = opcode_offset {
2930                        let mut stackmaps = self.stackmaps.borrow_mut();
2931                        finalize_opcode_stack_map(
2932                            self.intrinsics,
2933                            self.builder,
2934                            self.index,
2935                            &mut *stackmaps,
2936                            StackmapEntryKind::Call,
2937                            offset,
2938                        )
2939                    }
2940                }
2941                */
2942
2943                self.abi
2944                    .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
2945                    .iter()
2946                    .for_each(|ret| self.state.push1(*ret));
2947            }
2948            Operator::CallIndirect {
2949                type_index,
2950                table_index,
2951            } => {
2952                let sigindex = SignatureIndex::from_u32(type_index);
2953                let func_type = &self.wasm_module.signatures[sigindex];
2954                let expected_dynamic_sigindex =
2955                    self.ctx
2956                        .dynamic_sigindex(sigindex, self.intrinsics, self.module)?;
2957                let (table_base, table_bound) = self.ctx.table(
2958                    TableIndex::from_u32(table_index),
2959                    self.intrinsics,
2960                    self.module,
2961                    &self.builder,
2962                )?;
2963                let func_index = self.state.pop1()?.into_int_value();
2964
2965                let truncated_table_bounds = err!(self.builder.build_int_truncate(
2966                    table_bound,
2967                    self.intrinsics.i32_ty,
2968                    "truncated_table_bounds",
2969                ));
2970
2971                // First, check if the index is outside of the table bounds.
2972                let index_in_bounds = err!(self.builder.build_int_compare(
2973                    IntPredicate::ULT,
2974                    func_index,
2975                    truncated_table_bounds,
2976                    "index_in_bounds",
2977                ));
2978
2979                let index_in_bounds = err!(self.builder.build_call(
2980                    self.intrinsics.expect_i1,
2981                    &[
2982                        index_in_bounds.into(),
2983                        self.intrinsics.i1_ty.const_int(1, false).into(),
2984                    ],
2985                    "index_in_bounds_expect",
2986                ))
2987                .try_as_basic_value()
2988                .unwrap_basic()
2989                .into_int_value();
2990
2991                let in_bounds_continue_block = self
2992                    .context
2993                    .append_basic_block(self.function, "in_bounds_continue_block");
2994                let not_in_bounds_block = self
2995                    .context
2996                    .append_basic_block(self.function, "not_in_bounds_block");
2997                err!(self.builder.build_conditional_branch(
2998                    index_in_bounds,
2999                    in_bounds_continue_block,
3000                    not_in_bounds_block,
3001                ));
3002                self.builder.position_at_end(not_in_bounds_block);
3003                err!(self.builder.build_call(
3004                    self.intrinsics.throw_trap,
3005                    &[self.intrinsics.trap_table_access_oob.into()],
3006                    "throw",
3007                ));
3008                err!(self.builder.build_unreachable());
3009                self.builder.position_at_end(in_bounds_continue_block);
3010
3011                // We assume the table has the `funcref` (pointer to `anyfunc`)
3012                // element type.
3013                let casted_table_base = err!(self.builder.build_pointer_cast(
3014                    table_base,
3015                    self.context.ptr_type(AddressSpace::default()),
3016                    "casted_table_base",
3017                ));
3018
3019                let funcref_ptr = unsafe {
3020                    err!(self.builder.build_in_bounds_gep(
3021                        self.intrinsics.ptr_ty,
3022                        casted_table_base,
3023                        &[func_index],
3024                        "funcref_ptr",
3025                    ))
3026                };
3027
3028                // a funcref (pointer to `anyfunc`)
3029                let anyfunc_struct_ptr = err!(self.builder.build_load(
3030                    self.intrinsics.ptr_ty,
3031                    funcref_ptr,
3032                    "anyfunc_struct_ptr",
3033                ))
3034                .into_pointer_value();
3035
3036                // trap if we're trying to call a null funcref
3037                {
3038                    let funcref_not_null = err!(
3039                        self.builder
3040                            .build_is_not_null(anyfunc_struct_ptr, "null funcref check")
3041                    );
3042
3043                    let funcref_continue_deref_block = self
3044                        .context
3045                        .append_basic_block(self.function, "funcref_continue deref_block");
3046
3047                    let funcref_is_null_block = self
3048                        .context
3049                        .append_basic_block(self.function, "funcref_is_null_block");
3050                    err!(self.builder.build_conditional_branch(
3051                        funcref_not_null,
3052                        funcref_continue_deref_block,
3053                        funcref_is_null_block,
3054                    ));
3055                    self.builder.position_at_end(funcref_is_null_block);
3056                    err!(self.builder.build_call(
3057                        self.intrinsics.throw_trap,
3058                        &[self.intrinsics.trap_call_indirect_null.into()],
3059                        "throw",
3060                    ));
3061                    err!(self.builder.build_unreachable());
3062                    self.builder.position_at_end(funcref_continue_deref_block);
3063                }
3064
3065                // Load things from the anyfunc data structure.
3066                let func_ptr_ptr = self
3067                    .builder
3068                    .build_struct_gep(
3069                        self.intrinsics.anyfunc_ty,
3070                        anyfunc_struct_ptr,
3071                        0,
3072                        "func_ptr_ptr",
3073                    )
3074                    .unwrap();
3075                let sigindex_ptr = self
3076                    .builder
3077                    .build_struct_gep(
3078                        self.intrinsics.anyfunc_ty,
3079                        anyfunc_struct_ptr,
3080                        1,
3081                        "sigindex_ptr",
3082                    )
3083                    .unwrap();
3084                let ctx_ptr_ptr = self
3085                    .builder
3086                    .build_struct_gep(
3087                        self.intrinsics.anyfunc_ty,
3088                        anyfunc_struct_ptr,
3089                        2,
3090                        "ctx_ptr_ptr",
3091                    )
3092                    .unwrap();
3093                let (func_ptr, found_dynamic_sigindex, ctx_ptr) = (
3094                    err!(
3095                        self.builder
3096                            .build_load(self.intrinsics.ptr_ty, func_ptr_ptr, "func_ptr")
3097                    )
3098                    .into_pointer_value(),
3099                    err!(
3100                        self.builder
3101                            .build_load(self.intrinsics.i32_ty, sigindex_ptr, "sigindex")
3102                    )
3103                    .into_int_value(),
3104                    err!(
3105                        self.builder
3106                            .build_load(self.intrinsics.ptr_ty, ctx_ptr_ptr, "ctx_ptr")
3107                    ),
3108                );
3109
3110                // Next, check if the table element is initialized.
3111
3112                // TODO: we may not need this check anymore
3113                let elem_initialized = err!(self.builder.build_is_not_null(func_ptr, ""));
3114
3115                // Next, check if the signature id is correct.
3116
3117                let sigindices_equal = err!(self.builder.build_int_compare(
3118                    IntPredicate::EQ,
3119                    expected_dynamic_sigindex,
3120                    found_dynamic_sigindex,
3121                    "sigindices_equal",
3122                ));
3123
3124                let initialized_and_sigindices_match = err!(self.builder.build_and(
3125                    elem_initialized,
3126                    sigindices_equal,
3127                    ""
3128                ));
3129
3130                // Tell llvm that `expected_dynamic_sigindex` should equal `found_dynamic_sigindex`.
3131                let initialized_and_sigindices_match = err!(self.builder.build_call(
3132                    self.intrinsics.expect_i1,
3133                    &[
3134                        initialized_and_sigindices_match.into(),
3135                        self.intrinsics.i1_ty.const_int(1, false).into(),
3136                    ],
3137                    "initialized_and_sigindices_match_expect",
3138                ))
3139                .try_as_basic_value()
3140                .unwrap_basic()
3141                .into_int_value();
3142
3143                let continue_block = self
3144                    .context
3145                    .append_basic_block(self.function, "continue_block");
3146                let sigindices_notequal_block = self
3147                    .context
3148                    .append_basic_block(self.function, "sigindices_notequal_block");
3149                err!(self.builder.build_conditional_branch(
3150                    initialized_and_sigindices_match,
3151                    continue_block,
3152                    sigindices_notequal_block,
3153                ));
3154
3155                self.builder.position_at_end(sigindices_notequal_block);
3156                let trap_code = err!(self.builder.build_select(
3157                    elem_initialized,
3158                    self.intrinsics.trap_call_indirect_sig,
3159                    self.intrinsics.trap_call_indirect_null,
3160                    "",
3161                ));
3162                err!(self.builder.build_call(
3163                    self.intrinsics.throw_trap,
3164                    &[trap_code.into()],
3165                    "throw"
3166                ));
3167                err!(self.builder.build_unreachable());
3168                self.builder.position_at_end(continue_block);
3169
3170                if self.g0m0.is_some() {
3171                    self.build_g0m0_indirect_call(
3172                        table_index,
3173                        ctx_ptr.into_pointer_value(),
3174                        func_type,
3175                        func_ptr,
3176                        func_index,
3177                    )?;
3178                } else {
3179                    let call_site = self.build_indirect_call(
3180                        ctx_ptr.into_pointer_value(),
3181                        func_type,
3182                        func_ptr,
3183                        None,
3184                        None,
3185                    )?;
3186
3187                    self.abi
3188                        .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
3189                        .iter()
3190                        .for_each(|ret| self.state.push1(*ret));
3191                }
3192            }
3193
3194            /***************************
3195             * Integer Arithmetic instructions.
3196             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-arithmetic-instructions
3197             ***************************/
3198            Operator::I32Add | Operator::I64Add => {
3199                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3200                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3201                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3202                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3203                let res = err!(self.builder.build_int_add(v1, v2, ""));
3204                self.state.push1(res);
3205            }
3206            Operator::I8x16Add => {
3207                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3208                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3209                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3210                let res = err!(self.builder.build_int_add(v1, v2, ""));
3211                let res = err!(
3212                    self.builder
3213                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3214                );
3215                self.state.push1(res);
3216            }
3217            Operator::I16x8Add => {
3218                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3219                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3220                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3221                let res = err!(self.builder.build_int_add(v1, v2, ""));
3222                let res = err!(
3223                    self.builder
3224                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3225                );
3226                self.state.push1(res);
3227            }
3228            Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U => {
3229                let extend_op = match op {
3230                    Operator::I16x8ExtAddPairwiseI8x16S => {
3231                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, "")
3232                    }
3233                    Operator::I16x8ExtAddPairwiseI8x16U => {
3234                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, "")
3235                    }
3236                    _ => unreachable!("Unhandled internal variant"),
3237                };
3238                let (v, i) = self.state.pop1_extra()?;
3239                let (v, _) = self.v128_into_i8x16(v, i)?;
3240
3241                let left = err!(self.builder.build_shuffle_vector(
3242                    v,
3243                    v.get_type().get_undef(),
3244                    VectorType::const_vector(&[
3245                        self.intrinsics.i32_consts[0],
3246                        self.intrinsics.i32_consts[2],
3247                        self.intrinsics.i32_consts[4],
3248                        self.intrinsics.i32_consts[6],
3249                        self.intrinsics.i32_consts[8],
3250                        self.intrinsics.i32_consts[10],
3251                        self.intrinsics.i32_consts[12],
3252                        self.intrinsics.i32_consts[14],
3253                    ]),
3254                    "",
3255                ));
3256                let left = err!(extend_op(self, left));
3257                let right = err!(self.builder.build_shuffle_vector(
3258                    v,
3259                    v.get_type().get_undef(),
3260                    VectorType::const_vector(&[
3261                        self.intrinsics.i32_consts[1],
3262                        self.intrinsics.i32_consts[3],
3263                        self.intrinsics.i32_consts[5],
3264                        self.intrinsics.i32_consts[7],
3265                        self.intrinsics.i32_consts[9],
3266                        self.intrinsics.i32_consts[11],
3267                        self.intrinsics.i32_consts[13],
3268                        self.intrinsics.i32_consts[15],
3269                    ]),
3270                    "",
3271                ));
3272                let right = err!(extend_op(self, right));
3273
3274                let res = err!(self.builder.build_int_add(left, right, ""));
3275                let res = err!(
3276                    self.builder
3277                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3278                );
3279                self.state.push1(res);
3280            }
3281            Operator::I32x4Add => {
3282                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3283                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3284                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3285                let res = err!(self.builder.build_int_add(v1, v2, ""));
3286                let res = err!(
3287                    self.builder
3288                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3289                );
3290                self.state.push1(res);
3291            }
3292            Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
3293                let extend_op = match op {
3294                    Operator::I32x4ExtAddPairwiseI16x8S => {
3295                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3296                    }
3297                    Operator::I32x4ExtAddPairwiseI16x8U => {
3298                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3299                    }
3300                    _ => unreachable!("Unhandled internal variant"),
3301                };
3302                let (v, i) = self.state.pop1_extra()?;
3303                let (v, _) = self.v128_into_i16x8(v, i)?;
3304
3305                let left = err!(self.builder.build_shuffle_vector(
3306                    v,
3307                    v.get_type().get_undef(),
3308                    VectorType::const_vector(&[
3309                        self.intrinsics.i32_consts[0],
3310                        self.intrinsics.i32_consts[2],
3311                        self.intrinsics.i32_consts[4],
3312                        self.intrinsics.i32_consts[6],
3313                    ]),
3314                    "",
3315                ));
3316                let left = err!(extend_op(self, left));
3317                let right = err!(self.builder.build_shuffle_vector(
3318                    v,
3319                    v.get_type().get_undef(),
3320                    VectorType::const_vector(&[
3321                        self.intrinsics.i32_consts[1],
3322                        self.intrinsics.i32_consts[3],
3323                        self.intrinsics.i32_consts[5],
3324                        self.intrinsics.i32_consts[7],
3325                    ]),
3326                    "",
3327                ));
3328                let right = err!(extend_op(self, right));
3329
3330                let res = err!(self.builder.build_int_add(left, right, ""));
3331                let res = err!(
3332                    self.builder
3333                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3334                );
3335                self.state.push1(res);
3336            }
3337            Operator::I64x2Add => {
3338                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3339                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3340                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3341                let res = err!(self.builder.build_int_add(v1, v2, ""));
3342                let res = err!(
3343                    self.builder
3344                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3345                );
3346                self.state.push1(res);
3347            }
3348            Operator::I8x16AddSatS => {
3349                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3350                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3351                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3352                let res = err!(self.builder.build_call(
3353                    self.intrinsics.sadd_sat_i8x16,
3354                    &[v1.into(), v2.into()],
3355                    ""
3356                ))
3357                .try_as_basic_value()
3358                .unwrap_basic();
3359                let res = err!(
3360                    self.builder
3361                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3362                );
3363                self.state.push1(res);
3364            }
3365            Operator::I16x8AddSatS => {
3366                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3367                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3368                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3369                let res = err!(self.builder.build_call(
3370                    self.intrinsics.sadd_sat_i16x8,
3371                    &[v1.into(), v2.into()],
3372                    ""
3373                ))
3374                .try_as_basic_value()
3375                .unwrap_basic();
3376                let res = err!(
3377                    self.builder
3378                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3379                );
3380                self.state.push1(res);
3381            }
3382            Operator::I8x16AddSatU => {
3383                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3384                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3385                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3386                let res = err!(self.builder.build_call(
3387                    self.intrinsics.uadd_sat_i8x16,
3388                    &[v1.into(), v2.into()],
3389                    ""
3390                ))
3391                .try_as_basic_value()
3392                .unwrap_basic();
3393                let res = err!(
3394                    self.builder
3395                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3396                );
3397                self.state.push1(res);
3398            }
3399            Operator::I16x8AddSatU => {
3400                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3401                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3402                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3403                let res = err!(self.builder.build_call(
3404                    self.intrinsics.uadd_sat_i16x8,
3405                    &[v1.into(), v2.into()],
3406                    ""
3407                ))
3408                .try_as_basic_value()
3409                .unwrap_basic();
3410                let res = err!(
3411                    self.builder
3412                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3413                );
3414                self.state.push1(res);
3415            }
3416            Operator::I32Sub | Operator::I64Sub => {
3417                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3418                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3419                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3420                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3421                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3422                self.state.push1(res);
3423            }
3424            Operator::I8x16Sub => {
3425                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3426                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3427                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3428                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3429                let res = err!(
3430                    self.builder
3431                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3432                );
3433                self.state.push1(res);
3434            }
3435            Operator::I16x8Sub => {
3436                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3437                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3438                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3439                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3440                let res = err!(
3441                    self.builder
3442                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3443                );
3444                self.state.push1(res);
3445            }
3446            Operator::I32x4Sub => {
3447                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3448                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3449                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3450                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3451                let res = err!(
3452                    self.builder
3453                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3454                );
3455                self.state.push1(res);
3456            }
3457            Operator::I64x2Sub => {
3458                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3459                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3460                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3461                let res = err!(self.builder.build_int_sub(v1, v2, ""));
3462                let res = err!(
3463                    self.builder
3464                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3465                );
3466                self.state.push1(res);
3467            }
3468            Operator::I8x16SubSatS => {
3469                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3470                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3471                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3472                let res = err!(self.builder.build_call(
3473                    self.intrinsics.ssub_sat_i8x16,
3474                    &[v1.into(), v2.into()],
3475                    ""
3476                ))
3477                .try_as_basic_value()
3478                .unwrap_basic();
3479                let res = err!(
3480                    self.builder
3481                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3482                );
3483                self.state.push1(res);
3484            }
3485            Operator::I16x8SubSatS => {
3486                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3487                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3488                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3489                let res = err!(self.builder.build_call(
3490                    self.intrinsics.ssub_sat_i16x8,
3491                    &[v1.into(), v2.into()],
3492                    ""
3493                ))
3494                .try_as_basic_value()
3495                .unwrap_basic();
3496                let res = err!(
3497                    self.builder
3498                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3499                );
3500                self.state.push1(res);
3501            }
3502            Operator::I8x16SubSatU => {
3503                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3504                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3505                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3506                let res = err!(self.builder.build_call(
3507                    self.intrinsics.usub_sat_i8x16,
3508                    &[v1.into(), v2.into()],
3509                    ""
3510                ))
3511                .try_as_basic_value()
3512                .unwrap_basic();
3513                let res = err!(
3514                    self.builder
3515                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3516                );
3517                self.state.push1(res);
3518            }
3519            Operator::I16x8SubSatU => {
3520                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3521                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3522                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3523                let res = err!(self.builder.build_call(
3524                    self.intrinsics.usub_sat_i16x8,
3525                    &[v1.into(), v2.into()],
3526                    ""
3527                ))
3528                .try_as_basic_value()
3529                .unwrap_basic();
3530                let res = err!(
3531                    self.builder
3532                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3533                );
3534                self.state.push1(res);
3535            }
3536            Operator::I32Mul | Operator::I64Mul => {
3537                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3538                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3539                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3540                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3541                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3542                self.state.push1(res);
3543            }
3544            Operator::I16x8Mul => {
3545                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3546                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3547                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3548                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3549                let res = err!(
3550                    self.builder
3551                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3552                );
3553                self.state.push1(res);
3554            }
3555            Operator::I32x4Mul => {
3556                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3557                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3558                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3559                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3560                let res = err!(
3561                    self.builder
3562                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3563                );
3564                self.state.push1(res);
3565            }
3566            Operator::I64x2Mul => {
3567                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3568                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3569                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3570                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3571                let res = err!(
3572                    self.builder
3573                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3574                );
3575                self.state.push1(res);
3576            }
3577            Operator::I16x8Q15MulrSatS => {
3578                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3579                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3580                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3581
3582                let max_value = self.intrinsics.i16_ty.const_int(i16::MAX as u64, false);
3583                let max_values = VectorType::const_vector(&[max_value; 8]);
3584
3585                let v1 = err!(
3586                    self.builder
3587                        .build_int_s_extend(v1, self.intrinsics.i32x8_ty, "")
3588                );
3589                let v2 = err!(
3590                    self.builder
3591                        .build_int_s_extend(v2, self.intrinsics.i32x8_ty, "")
3592                );
3593                let res = err!(self.builder.build_int_mul(v1, v2, ""));
3594
3595                // magic number specified by the spec
3596                let bit = self.intrinsics.i32_ty.const_int(0x4000, false);
3597                let bits = VectorType::const_vector(&[bit; 8]);
3598
3599                let res = err!(self.builder.build_int_add(res, bits, ""));
3600
3601                let fifteen = self.intrinsics.i32_consts[15];
3602                let fifteens = VectorType::const_vector(&[fifteen; 8]);
3603
3604                let res = err!(self.builder.build_right_shift(res, fifteens, true, ""));
3605                let saturate_up = {
3606                    let max_values = err!(self.builder.build_int_s_extend(
3607                        max_values,
3608                        self.intrinsics.i32x8_ty,
3609                        ""
3610                    ));
3611                    err!(
3612                        self.builder
3613                            .build_int_compare(IntPredicate::SGT, res, max_values, "")
3614                    )
3615                };
3616
3617                let res = err!(
3618                    self.builder
3619                        .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
3620                );
3621
3622                let res = err!(self.builder.build_select(saturate_up, max_values, res, ""))
3623                    .into_vector_value();
3624                let res = err!(
3625                    self.builder
3626                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3627                );
3628                self.state.push1(res);
3629            }
3630            Operator::I16x8ExtMulLowI8x16S
3631            | Operator::I16x8ExtMulLowI8x16U
3632            | Operator::I16x8ExtMulHighI8x16S
3633            | Operator::I16x8ExtMulHighI8x16U => {
3634                let extend_op = match op {
3635                    Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulHighI8x16S => {
3636                        |s: &Self, v| -> Result<VectorValue, CompileError> {
3637                            err_nt!(s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, ""))
3638                        }
3639                    }
3640                    Operator::I16x8ExtMulLowI8x16U | Operator::I16x8ExtMulHighI8x16U => {
3641                        |s: &Self, v| -> Result<VectorValue, CompileError> {
3642                            err_nt!(s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, ""))
3643                        }
3644                    }
3645                    _ => unreachable!("Unhandled internal variant"),
3646                };
3647                let shuffle_array = match op {
3648                    Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulLowI8x16U => [
3649                        self.intrinsics.i32_consts[0],
3650                        self.intrinsics.i32_consts[2],
3651                        self.intrinsics.i32_consts[4],
3652                        self.intrinsics.i32_consts[6],
3653                        self.intrinsics.i32_consts[8],
3654                        self.intrinsics.i32_consts[10],
3655                        self.intrinsics.i32_consts[12],
3656                        self.intrinsics.i32_consts[14],
3657                    ],
3658                    Operator::I16x8ExtMulHighI8x16S | Operator::I16x8ExtMulHighI8x16U => [
3659                        self.intrinsics.i32_consts[1],
3660                        self.intrinsics.i32_consts[3],
3661                        self.intrinsics.i32_consts[5],
3662                        self.intrinsics.i32_consts[7],
3663                        self.intrinsics.i32_consts[9],
3664                        self.intrinsics.i32_consts[11],
3665                        self.intrinsics.i32_consts[13],
3666                        self.intrinsics.i32_consts[15],
3667                    ],
3668                    _ => unreachable!("Unhandled internal variant"),
3669                };
3670                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3671                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3672                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3673                let val1 = err!(self.builder.build_shuffle_vector(
3674                    v1,
3675                    v1.get_type().get_undef(),
3676                    VectorType::const_vector(&shuffle_array),
3677                    "",
3678                ));
3679                let val1 = err!(extend_op(self, val1));
3680                let val2 = err!(self.builder.build_shuffle_vector(
3681                    v2,
3682                    v2.get_type().get_undef(),
3683                    VectorType::const_vector(&shuffle_array),
3684                    "",
3685                ));
3686                let val2 = err!(extend_op(self, val2));
3687                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3688                let res = err!(
3689                    self.builder
3690                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3691                );
3692                self.state.push1(res);
3693            }
3694            Operator::I32x4ExtMulLowI16x8S
3695            | Operator::I32x4ExtMulLowI16x8U
3696            | Operator::I32x4ExtMulHighI16x8S
3697            | Operator::I32x4ExtMulHighI16x8U => {
3698                let extend_op = match op {
3699                    Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulHighI16x8S => {
3700                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3701                    }
3702                    Operator::I32x4ExtMulLowI16x8U | Operator::I32x4ExtMulHighI16x8U => {
3703                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3704                    }
3705                    _ => unreachable!("Unhandled internal variant"),
3706                };
3707                let shuffle_array = match op {
3708                    Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulLowI16x8U => [
3709                        self.intrinsics.i32_consts[0],
3710                        self.intrinsics.i32_consts[2],
3711                        self.intrinsics.i32_consts[4],
3712                        self.intrinsics.i32_consts[6],
3713                    ],
3714                    Operator::I32x4ExtMulHighI16x8S | Operator::I32x4ExtMulHighI16x8U => [
3715                        self.intrinsics.i32_consts[1],
3716                        self.intrinsics.i32_consts[3],
3717                        self.intrinsics.i32_consts[5],
3718                        self.intrinsics.i32_consts[7],
3719                    ],
3720                    _ => unreachable!("Unhandled internal variant"),
3721                };
3722                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3723                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3724                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3725                let val1 = err!(self.builder.build_shuffle_vector(
3726                    v1,
3727                    v1.get_type().get_undef(),
3728                    VectorType::const_vector(&shuffle_array),
3729                    "",
3730                ));
3731                let val1 = err!(extend_op(self, val1));
3732                let val2 = err!(self.builder.build_shuffle_vector(
3733                    v2,
3734                    v2.get_type().get_undef(),
3735                    VectorType::const_vector(&shuffle_array),
3736                    "",
3737                ));
3738                let val2 = err!(extend_op(self, val2));
3739                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3740                let res = err!(
3741                    self.builder
3742                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3743                );
3744                self.state.push1(res);
3745            }
3746            Operator::I64x2ExtMulLowI32x4S
3747            | Operator::I64x2ExtMulLowI32x4U
3748            | Operator::I64x2ExtMulHighI32x4S
3749            | Operator::I64x2ExtMulHighI32x4U => {
3750                let extend_op = match op {
3751                    Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulHighI32x4S => {
3752                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
3753                    }
3754                    Operator::I64x2ExtMulLowI32x4U | Operator::I64x2ExtMulHighI32x4U => {
3755                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
3756                    }
3757                    _ => unreachable!("Unhandled internal variant"),
3758                };
3759                let shuffle_array = match op {
3760                    Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulLowI32x4U => {
3761                        [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[2]]
3762                    }
3763                    Operator::I64x2ExtMulHighI32x4S | Operator::I64x2ExtMulHighI32x4U => {
3764                        [self.intrinsics.i32_consts[1], self.intrinsics.i32_consts[3]]
3765                    }
3766                    _ => unreachable!("Unhandled internal variant"),
3767                };
3768                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3769                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3770                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3771                let val1 = err!(self.builder.build_shuffle_vector(
3772                    v1,
3773                    v1.get_type().get_undef(),
3774                    VectorType::const_vector(&shuffle_array),
3775                    "",
3776                ));
3777                let val1 = err!(extend_op(self, val1));
3778                let val2 = err!(self.builder.build_shuffle_vector(
3779                    v2,
3780                    v2.get_type().get_undef(),
3781                    VectorType::const_vector(&shuffle_array),
3782                    "",
3783                ));
3784                let val2 = err!(extend_op(self, val2));
3785                let res = err!(self.builder.build_int_mul(val1, val2, ""));
3786                let res = err!(
3787                    self.builder
3788                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3789                );
3790                self.state.push1(res);
3791            }
3792            Operator::I32x4DotI16x8S => {
3793                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3794                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3795                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3796                let low_i16 = [
3797                    self.intrinsics.i32_consts[0],
3798                    self.intrinsics.i32_consts[2],
3799                    self.intrinsics.i32_consts[4],
3800                    self.intrinsics.i32_consts[6],
3801                ];
3802                let high_i16 = [
3803                    self.intrinsics.i32_consts[1],
3804                    self.intrinsics.i32_consts[3],
3805                    self.intrinsics.i32_consts[5],
3806                    self.intrinsics.i32_consts[7],
3807                ];
3808                let v1_low = err!(self.builder.build_shuffle_vector(
3809                    v1,
3810                    v1.get_type().get_undef(),
3811                    VectorType::const_vector(&low_i16),
3812                    "",
3813                ));
3814                let v1_low = err!(self.builder.build_int_s_extend(
3815                    v1_low,
3816                    self.intrinsics.i32x4_ty,
3817                    ""
3818                ));
3819                let v1_high = err!(self.builder.build_shuffle_vector(
3820                    v1,
3821                    v1.get_type().get_undef(),
3822                    VectorType::const_vector(&high_i16),
3823                    "",
3824                ));
3825                let v1_high = err!(self.builder.build_int_s_extend(
3826                    v1_high,
3827                    self.intrinsics.i32x4_ty,
3828                    ""
3829                ));
3830                let v2_low = err!(self.builder.build_shuffle_vector(
3831                    v2,
3832                    v2.get_type().get_undef(),
3833                    VectorType::const_vector(&low_i16),
3834                    "",
3835                ));
3836                let v2_low = err!(self.builder.build_int_s_extend(
3837                    v2_low,
3838                    self.intrinsics.i32x4_ty,
3839                    ""
3840                ));
3841                let v2_high = err!(self.builder.build_shuffle_vector(
3842                    v2,
3843                    v2.get_type().get_undef(),
3844                    VectorType::const_vector(&high_i16),
3845                    "",
3846                ));
3847                let v2_high = err!(self.builder.build_int_s_extend(
3848                    v2_high,
3849                    self.intrinsics.i32x4_ty,
3850                    ""
3851                ));
3852                let low_product = err!(self.builder.build_int_mul(v1_low, v2_low, ""));
3853                let high_product = err!(self.builder.build_int_mul(v1_high, v2_high, ""));
3854
3855                let res = err!(self.builder.build_int_add(low_product, high_product, ""));
3856                let res = err!(
3857                    self.builder
3858                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
3859                );
3860                self.state.push1(res);
3861            }
3862            Operator::I32DivS | Operator::I64DivS => {
3863                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3864                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3865                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3866                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3867
3868                self.trap_if_zero_or_overflow(v1, v2)?;
3869
3870                let res = err!(self.builder.build_int_signed_div(v1, v2, ""));
3871                self.state.push1(res);
3872            }
3873            Operator::I32DivU | Operator::I64DivU => {
3874                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3875                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3876                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3877                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3878
3879                self.trap_if_zero(v2)?;
3880
3881                let res = err!(self.builder.build_int_unsigned_div(v1, v2, ""));
3882                self.state.push1(res);
3883            }
3884            Operator::I32RemS | Operator::I64RemS => {
3885                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3886                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3887                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3888                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3889                let int_type = v1.get_type();
3890                let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
3891                    let min_value = int_type.const_int(i32::MIN as u64, false);
3892                    let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
3893                    (min_value, neg_one_value)
3894                } else if int_type == self.intrinsics.i64_ty {
3895                    let min_value = int_type.const_int(i64::MIN as u64, false);
3896                    let neg_one_value = int_type.const_int(-1i64 as u64, false);
3897                    (min_value, neg_one_value)
3898                } else {
3899                    unreachable!()
3900                };
3901
3902                self.trap_if_zero(v2)?;
3903
3904                // "Overflow also leads to undefined behavior; this is a rare
3905                // case, but can occur, for example, by taking the remainder of
3906                // a 32-bit division of -2147483648 by -1. (The remainder
3907                // doesn’t actually overflow, but this rule lets srem be
3908                // implemented using instructions that return both the result
3909                // of the division and the remainder.)"
3910                //   -- https://llvm.org/docs/LangRef.html#srem-instruction
3911                //
3912                // In Wasm, the i32.rem_s i32.const -2147483648 i32.const -1 is
3913                // i32.const 0. We implement this by swapping out the left value
3914                // for 0 in this case.
3915                let will_overflow = err!(self.builder.build_and(
3916                    err!(self.builder.build_int_compare(
3917                        IntPredicate::EQ,
3918                        v1,
3919                        min_value,
3920                        "left_is_min"
3921                    )),
3922                    err!(self.builder.build_int_compare(
3923                        IntPredicate::EQ,
3924                        v2,
3925                        neg_one_value,
3926                        "right_is_neg_one",
3927                    )),
3928                    "srem_will_overflow",
3929                ));
3930                let v1 =
3931                    err!(
3932                        self.builder
3933                            .build_select(will_overflow, int_type.const_zero(), v1, "")
3934                    )
3935                    .into_int_value();
3936                let res = err!(self.builder.build_int_signed_rem(v1, v2, ""));
3937                self.state.push1(res);
3938            }
3939            Operator::I32RemU | Operator::I64RemU => {
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
3945                self.trap_if_zero(v2)?;
3946
3947                let res = err!(self.builder.build_int_unsigned_rem(v1, v2, ""));
3948                self.state.push1(res);
3949            }
3950            Operator::I32And | Operator::I64And | Operator::V128And => {
3951                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3952                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3953                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3954                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3955                let res = err!(self.builder.build_and(v1, v2, ""));
3956                self.state.push1(res);
3957            }
3958            Operator::I32Or | Operator::I64Or | Operator::V128Or => {
3959                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3960                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3961                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3962                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3963                let res = err!(self.builder.build_or(v1, v2, ""));
3964                self.state.push1(res);
3965            }
3966            Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
3967                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3968                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3969                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3970                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3971                let res = err!(self.builder.build_xor(v1, v2, ""));
3972                self.state.push1(res);
3973            }
3974            Operator::V128AndNot => {
3975                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3976                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3977                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3978                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3979                let v2 = err!(self.builder.build_not(v2, ""));
3980                let res = err!(self.builder.build_and(v1, v2, ""));
3981                self.state.push1(res);
3982            }
3983            Operator::V128Bitselect => {
3984                let ((v1, i1), (v2, i2), (cond, cond_info)) = self.state.pop3_extra()?;
3985                let v1 = self.apply_pending_canonicalization(v1, i1)?;
3986                let v2 = self.apply_pending_canonicalization(v2, i2)?;
3987                let cond = self.apply_pending_canonicalization(cond, cond_info)?;
3988                let v1 = err!(
3989                    self.builder
3990                        .build_bit_cast(v1, self.intrinsics.i1x128_ty, "")
3991                )
3992                .into_vector_value();
3993                let v2 = err!(
3994                    self.builder
3995                        .build_bit_cast(v2, self.intrinsics.i1x128_ty, "")
3996                )
3997                .into_vector_value();
3998                let cond = err!(
3999                    self.builder
4000                        .build_bit_cast(cond, self.intrinsics.i1x128_ty, "")
4001                )
4002                .into_vector_value();
4003                let res = err!(self.builder.build_select(cond, v1, v2, ""));
4004                let res = err!(
4005                    self.builder
4006                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4007                );
4008                self.state.push1(res);
4009            }
4010            Operator::I8x16Bitmask => {
4011                let (v, i) = self.state.pop1_extra()?;
4012                let (v, _) = self.v128_into_i8x16(v, i)?;
4013
4014                let zeros = self.intrinsics.i8x16_ty.const_zero();
4015                let res = err!(
4016                    self.builder
4017                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4018                );
4019                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i16_ty, ""))
4020                    .into_int_value();
4021                let res = err!(
4022                    self.builder
4023                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4024                );
4025                self.state.push1(res);
4026            }
4027            Operator::I16x8Bitmask => {
4028                let (v, i) = self.state.pop1_extra()?;
4029                let (v, _) = self.v128_into_i16x8(v, i)?;
4030
4031                let zeros = self.intrinsics.i16x8_ty.const_zero();
4032                let res = err!(
4033                    self.builder
4034                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4035                );
4036                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i8_ty, ""))
4037                    .into_int_value();
4038                let res = err!(
4039                    self.builder
4040                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4041                );
4042                self.state.push1(res);
4043            }
4044            Operator::I32x4Bitmask => {
4045                let (v, i) = self.state.pop1_extra()?;
4046                let (v, _) = self.v128_into_i32x4(v, i)?;
4047
4048                let zeros = self.intrinsics.i32x4_ty.const_zero();
4049                let res = err!(
4050                    self.builder
4051                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4052                );
4053                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i4_ty, ""))
4054                    .into_int_value();
4055                let res = err!(
4056                    self.builder
4057                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4058                );
4059                self.state.push1(res);
4060            }
4061            Operator::I64x2Bitmask => {
4062                let (v, i) = self.state.pop1_extra()?;
4063                let (v, _) = self.v128_into_i64x2(v, i)?;
4064
4065                let zeros = self.intrinsics.i64x2_ty.const_zero();
4066                let res = err!(
4067                    self.builder
4068                        .build_int_compare(IntPredicate::SLT, v, zeros, "")
4069                );
4070                let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i2_ty, ""))
4071                    .into_int_value();
4072                let res = err!(
4073                    self.builder
4074                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4075                );
4076                self.state.push1(res);
4077            }
4078            Operator::I32Shl => {
4079                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4080                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4081                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4082                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4083                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4084                let v2 = err!(self.builder.build_and(v2, mask, ""));
4085                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4086                self.state.push1(res);
4087            }
4088            Operator::I64Shl => {
4089                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4090                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4091                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4092                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4093                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4094                let v2 = err!(self.builder.build_and(v2, mask, ""));
4095                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4096                self.state.push1(res);
4097            }
4098            Operator::I8x16Shl => {
4099                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4100                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4101                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4102                let v2 = v2.into_int_value();
4103                let v2 = err!(
4104                    self.builder
4105                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4106                );
4107                let v2 = err!(
4108                    self.builder
4109                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4110                );
4111                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4112                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4113                let res = err!(
4114                    self.builder
4115                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4116                );
4117                self.state.push1(res);
4118            }
4119            Operator::I16x8Shl => {
4120                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4121                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4122                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4123                let v2 = v2.into_int_value();
4124                let v2 = err!(
4125                    self.builder
4126                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4127                );
4128                let v2 = err!(
4129                    self.builder
4130                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4131                );
4132                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4133                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4134                let res = err!(
4135                    self.builder
4136                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4137                );
4138                self.state.push1(res);
4139            }
4140            Operator::I32x4Shl => {
4141                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4142                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4143                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4144                let v2 = v2.into_int_value();
4145                let v2 = err!(self.builder.build_and(
4146                    v2,
4147                    self.intrinsics.i32_ty.const_int(31, false),
4148                    ""
4149                ));
4150                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4151                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4152                let res = err!(
4153                    self.builder
4154                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4155                );
4156                self.state.push1(res);
4157            }
4158            Operator::I64x2Shl => {
4159                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4160                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4161                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4162                let v2 = v2.into_int_value();
4163                let v2 = err!(self.builder.build_and(
4164                    v2,
4165                    self.intrinsics.i32_ty.const_int(63, false),
4166                    ""
4167                ));
4168                let v2 = err!(
4169                    self.builder
4170                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4171                );
4172                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4173                let res = err!(self.builder.build_left_shift(v1, v2, ""));
4174                let res = err!(
4175                    self.builder
4176                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4177                );
4178                self.state.push1(res);
4179            }
4180            Operator::I32ShrS => {
4181                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4182                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4183                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4184                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4185                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4186                let v2 = err!(self.builder.build_and(v2, mask, ""));
4187                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4188                self.state.push1(res);
4189            }
4190            Operator::I64ShrS => {
4191                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4192                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4193                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4194                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4195                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4196                let v2 = err!(self.builder.build_and(v2, mask, ""));
4197                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4198                self.state.push1(res);
4199            }
4200            Operator::I8x16ShrS => {
4201                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4202                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4203                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4204                let v2 = v2.into_int_value();
4205                let v2 = err!(
4206                    self.builder
4207                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4208                );
4209                let v2 = err!(
4210                    self.builder
4211                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4212                );
4213                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4214                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4215                let res = err!(
4216                    self.builder
4217                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4218                );
4219                self.state.push1(res);
4220            }
4221            Operator::I16x8ShrS => {
4222                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4223                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4224                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4225                let v2 = v2.into_int_value();
4226                let v2 = err!(
4227                    self.builder
4228                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4229                );
4230                let v2 = err!(
4231                    self.builder
4232                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4233                );
4234                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4235                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4236                let res = err!(
4237                    self.builder
4238                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4239                );
4240                self.state.push1(res);
4241            }
4242            Operator::I32x4ShrS => {
4243                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4244                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4245                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4246                let v2 = v2.into_int_value();
4247                let v2 = err!(self.builder.build_and(
4248                    v2,
4249                    self.intrinsics.i32_ty.const_int(31, false),
4250                    ""
4251                ));
4252                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4253                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4254                let res = err!(
4255                    self.builder
4256                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4257                );
4258                self.state.push1(res);
4259            }
4260            Operator::I64x2ShrS => {
4261                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4262                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4263                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4264                let v2 = v2.into_int_value();
4265                let v2 = err!(self.builder.build_and(
4266                    v2,
4267                    self.intrinsics.i32_ty.const_int(63, false),
4268                    ""
4269                ));
4270                let v2 = err!(
4271                    self.builder
4272                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4273                );
4274                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4275                let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4276                let res = err!(
4277                    self.builder
4278                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4279                );
4280                self.state.push1(res);
4281            }
4282            Operator::I32ShrU => {
4283                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4284                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4285                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4286                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4287                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4288                let v2 = err!(self.builder.build_and(v2, mask, ""));
4289                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4290                self.state.push1(res);
4291            }
4292            Operator::I64ShrU => {
4293                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4294                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4295                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4296                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4297                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4298                let v2 = err!(self.builder.build_and(v2, mask, ""));
4299                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4300                self.state.push1(res);
4301            }
4302            Operator::I8x16ShrU => {
4303                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4304                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4305                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4306                let v2 = v2.into_int_value();
4307                let v2 = err!(
4308                    self.builder
4309                        .build_and(v2, self.intrinsics.i32_consts[7], "")
4310                );
4311                let v2 = err!(
4312                    self.builder
4313                        .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4314                );
4315                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4316                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4317                let res = err!(
4318                    self.builder
4319                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4320                );
4321                self.state.push1(res);
4322            }
4323            Operator::I16x8ShrU => {
4324                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4325                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4326                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4327                let v2 = v2.into_int_value();
4328                let v2 = err!(
4329                    self.builder
4330                        .build_and(v2, self.intrinsics.i32_consts[15], "")
4331                );
4332                let v2 = err!(
4333                    self.builder
4334                        .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4335                );
4336                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4337                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4338                let res = err!(
4339                    self.builder
4340                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4341                );
4342                self.state.push1(res);
4343            }
4344            Operator::I32x4ShrU => {
4345                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4346                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4347                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4348                let v2 = v2.into_int_value();
4349                let v2 = err!(self.builder.build_and(
4350                    v2,
4351                    self.intrinsics.i32_ty.const_int(31, false),
4352                    ""
4353                ));
4354                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4355                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4356                let res = err!(
4357                    self.builder
4358                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4359                );
4360                self.state.push1(res);
4361            }
4362            Operator::I64x2ShrU => {
4363                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4364                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4365                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4366                let v2 = v2.into_int_value();
4367                let v2 = err!(self.builder.build_and(
4368                    v2,
4369                    self.intrinsics.i32_ty.const_int(63, false),
4370                    ""
4371                ));
4372                let v2 = err!(
4373                    self.builder
4374                        .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4375                );
4376                let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4377                let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4378                let res = err!(
4379                    self.builder
4380                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4381                );
4382                self.state.push1(res);
4383            }
4384            Operator::I32Rotl => {
4385                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4386                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4387                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4388                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4389                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4390                let v2 = err!(self.builder.build_and(v2, mask, ""));
4391                let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4392                let rhs = {
4393                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4394                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4395                    err!(self.builder.build_right_shift(v1, rhs, false, ""))
4396                };
4397                let res = err!(self.builder.build_or(lhs, rhs, ""));
4398                self.state.push1(res);
4399            }
4400            Operator::I64Rotl => {
4401                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4402                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4403                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4404                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4405                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4406                let v2 = err!(self.builder.build_and(v2, mask, ""));
4407                let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4408                let rhs = {
4409                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4410                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4411                    err!(self.builder.build_right_shift(v1, rhs, false, ""))
4412                };
4413                let res = err!(self.builder.build_or(lhs, rhs, ""));
4414                self.state.push1(res);
4415            }
4416            Operator::I32Rotr => {
4417                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4418                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4419                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4420                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4421                let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4422                let v2 = err!(self.builder.build_and(v2, mask, ""));
4423                let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4424                let rhs = {
4425                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4426                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4427                    err!(self.builder.build_left_shift(v1, rhs, ""))
4428                };
4429                let res = err!(self.builder.build_or(lhs, rhs, ""));
4430                self.state.push1(res);
4431            }
4432            Operator::I64Rotr => {
4433                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4434                let v1 = self.apply_pending_canonicalization(v1, i1)?;
4435                let v2 = self.apply_pending_canonicalization(v2, i2)?;
4436                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4437                let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4438                let v2 = err!(self.builder.build_and(v2, mask, ""));
4439                let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4440                let rhs = {
4441                    let negv2 = err!(self.builder.build_int_neg(v2, ""));
4442                    let rhs = err!(self.builder.build_and(negv2, mask, ""));
4443                    err!(self.builder.build_left_shift(v1, rhs, ""))
4444                };
4445                let res = err!(self.builder.build_or(lhs, rhs, ""));
4446                self.state.push1(res);
4447            }
4448            Operator::I32Clz => {
4449                let (input, info) = self.state.pop1_extra()?;
4450                let input = self.apply_pending_canonicalization(input, info)?;
4451                let is_zero_undef = self.intrinsics.i1_zero;
4452                let res = err!(self.builder.build_call(
4453                    self.intrinsics.ctlz_i32,
4454                    &[input.into(), is_zero_undef.into()],
4455                    "",
4456                ))
4457                .try_as_basic_value()
4458                .unwrap_basic();
4459                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4460            }
4461            Operator::I64Clz => {
4462                let (input, info) = self.state.pop1_extra()?;
4463                let input = self.apply_pending_canonicalization(input, info)?;
4464                let is_zero_undef = self.intrinsics.i1_zero;
4465                let res = err!(self.builder.build_call(
4466                    self.intrinsics.ctlz_i64,
4467                    &[input.into(), is_zero_undef.into()],
4468                    "",
4469                ))
4470                .try_as_basic_value()
4471                .unwrap_basic();
4472                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4473            }
4474            Operator::I32Ctz => {
4475                let (input, info) = self.state.pop1_extra()?;
4476                let input = self.apply_pending_canonicalization(input, info)?;
4477                let is_zero_undef = self.intrinsics.i1_zero;
4478                let res = err!(self.builder.build_call(
4479                    self.intrinsics.cttz_i32,
4480                    &[input.into(), is_zero_undef.into()],
4481                    "",
4482                ))
4483                .try_as_basic_value()
4484                .unwrap_basic();
4485                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4486            }
4487            Operator::I64Ctz => {
4488                let (input, info) = self.state.pop1_extra()?;
4489                let input = self.apply_pending_canonicalization(input, info)?;
4490                let is_zero_undef = self.intrinsics.i1_zero;
4491                let res = err!(self.builder.build_call(
4492                    self.intrinsics.cttz_i64,
4493                    &[input.into(), is_zero_undef.into()],
4494                    "",
4495                ))
4496                .try_as_basic_value()
4497                .unwrap_basic();
4498                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4499            }
4500            Operator::I8x16Popcnt => {
4501                let (v, i) = self.state.pop1_extra()?;
4502                let (v, _) = self.v128_into_i8x16(v, i)?;
4503                let res = err!(self.builder.build_call(
4504                    self.intrinsics.ctpop_i8x16,
4505                    &[v.into()],
4506                    ""
4507                ))
4508                .try_as_basic_value()
4509                .unwrap_basic();
4510                let res = err!(
4511                    self.builder
4512                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4513                );
4514                self.state.push1(res);
4515            }
4516            Operator::I32Popcnt => {
4517                let (input, info) = self.state.pop1_extra()?;
4518                let input = self.apply_pending_canonicalization(input, info)?;
4519                let res = err!(self.builder.build_call(
4520                    self.intrinsics.ctpop_i32,
4521                    &[input.into()],
4522                    ""
4523                ))
4524                .try_as_basic_value()
4525                .unwrap_basic();
4526                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4527            }
4528            Operator::I64Popcnt => {
4529                let (input, info) = self.state.pop1_extra()?;
4530                let input = self.apply_pending_canonicalization(input, info)?;
4531                let res = err!(self.builder.build_call(
4532                    self.intrinsics.ctpop_i64,
4533                    &[input.into()],
4534                    ""
4535                ))
4536                .try_as_basic_value()
4537                .unwrap_basic();
4538                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4539            }
4540            Operator::I32Eqz => {
4541                let input = self.state.pop1()?.into_int_value();
4542                let cond = err!(self.builder.build_int_compare(
4543                    IntPredicate::EQ,
4544                    input,
4545                    self.intrinsics.i32_zero,
4546                    "",
4547                ));
4548                let res = err!(
4549                    self.builder
4550                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4551                );
4552                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4553            }
4554            Operator::I64Eqz => {
4555                let input = self.state.pop1()?.into_int_value();
4556                let cond = err!(self.builder.build_int_compare(
4557                    IntPredicate::EQ,
4558                    input,
4559                    self.intrinsics.i64_zero,
4560                    "",
4561                ));
4562                let res = err!(
4563                    self.builder
4564                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4565                );
4566                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4567            }
4568            Operator::I8x16Abs => {
4569                let (v, i) = self.state.pop1_extra()?;
4570                let (v, _) = self.v128_into_i8x16(v, i)?;
4571
4572                let seven = self.intrinsics.i8_ty.const_int(7, false);
4573                let seven = VectorType::const_vector(&[seven; 16]);
4574                let all_sign_bits = err!(self.builder.build_right_shift(v, seven, true, ""));
4575                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4576                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4577                let res = err!(
4578                    self.builder
4579                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4580                );
4581                self.state.push1(res);
4582            }
4583            Operator::I16x8Abs => {
4584                let (v, i) = self.state.pop1_extra()?;
4585                let (v, _) = self.v128_into_i16x8(v, i)?;
4586
4587                let fifteen = self.intrinsics.i16_ty.const_int(15, false);
4588                let fifteen = VectorType::const_vector(&[fifteen; 8]);
4589                let all_sign_bits = err!(self.builder.build_right_shift(v, fifteen, true, ""));
4590                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4591                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4592                let res = err!(
4593                    self.builder
4594                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4595                );
4596                self.state.push1(res);
4597            }
4598            Operator::I32x4Abs => {
4599                let (v, i) = self.state.pop1_extra()?;
4600                let (v, _) = self.v128_into_i32x4(v, i)?;
4601
4602                let thirtyone = self.intrinsics.i32_ty.const_int(31, false);
4603                let thirtyone = VectorType::const_vector(&[thirtyone; 4]);
4604                let all_sign_bits = err!(self.builder.build_right_shift(v, thirtyone, true, ""));
4605                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4606                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4607                let res = err!(
4608                    self.builder
4609                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4610                );
4611                self.state.push1(res);
4612            }
4613            Operator::I64x2Abs => {
4614                let (v, i) = self.state.pop1_extra()?;
4615                let (v, _) = self.v128_into_i64x2(v, i)?;
4616
4617                let sixtythree = self.intrinsics.i64_ty.const_int(63, false);
4618                let sixtythree = VectorType::const_vector(&[sixtythree; 2]);
4619                let all_sign_bits = err!(self.builder.build_right_shift(v, sixtythree, true, ""));
4620                let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4621                let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4622                let res = err!(
4623                    self.builder
4624                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4625                );
4626                self.state.push1(res);
4627            }
4628            Operator::I8x16MinS => {
4629                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4630                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4631                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4632                let cmp = err!(
4633                    self.builder
4634                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4635                );
4636                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4637                let res = err!(
4638                    self.builder
4639                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4640                );
4641                self.state.push1(res);
4642            }
4643            Operator::I8x16MinU => {
4644                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4645                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4646                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4647                let cmp = err!(
4648                    self.builder
4649                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4650                );
4651                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4652                let res = err!(
4653                    self.builder
4654                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4655                );
4656                self.state.push1(res);
4657            }
4658            Operator::I8x16MaxS => {
4659                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4660                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4661                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4662                let cmp = err!(
4663                    self.builder
4664                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4665                );
4666                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4667                let res = err!(
4668                    self.builder
4669                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4670                );
4671                self.state.push1(res);
4672            }
4673            Operator::I8x16MaxU => {
4674                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4675                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4676                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4677                let cmp = err!(
4678                    self.builder
4679                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4680                );
4681                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4682                let res = err!(
4683                    self.builder
4684                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4685                );
4686                self.state.push1(res);
4687            }
4688            Operator::I16x8MinS => {
4689                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4690                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4691                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4692                let cmp = err!(
4693                    self.builder
4694                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4695                );
4696                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4697                let res = err!(
4698                    self.builder
4699                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4700                );
4701                self.state.push1(res);
4702            }
4703            Operator::I16x8MinU => {
4704                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4705                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4706                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4707                let cmp = err!(
4708                    self.builder
4709                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4710                );
4711                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4712                let res = err!(
4713                    self.builder
4714                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4715                );
4716                self.state.push1(res);
4717            }
4718            Operator::I16x8MaxS => {
4719                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4720                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4721                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4722                let cmp = err!(
4723                    self.builder
4724                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4725                );
4726                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4727                let res = err!(
4728                    self.builder
4729                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4730                );
4731                self.state.push1(res);
4732            }
4733            Operator::I16x8MaxU => {
4734                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4735                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4736                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4737                let cmp = err!(
4738                    self.builder
4739                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4740                );
4741                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4742                let res = err!(
4743                    self.builder
4744                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4745                );
4746                self.state.push1(res);
4747            }
4748            Operator::I32x4MinS => {
4749                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4750                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4751                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4752                let cmp = err!(
4753                    self.builder
4754                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
4755                );
4756                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4757                let res = err!(
4758                    self.builder
4759                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4760                );
4761                self.state.push1(res);
4762            }
4763            Operator::I32x4MinU => {
4764                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4765                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4766                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4767                let cmp = err!(
4768                    self.builder
4769                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
4770                );
4771                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4772                let res = err!(
4773                    self.builder
4774                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4775                );
4776                self.state.push1(res);
4777            }
4778            Operator::I32x4MaxS => {
4779                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4780                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4781                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4782                let cmp = err!(
4783                    self.builder
4784                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
4785                );
4786                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4787                let res = err!(
4788                    self.builder
4789                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4790                );
4791                self.state.push1(res);
4792            }
4793            Operator::I32x4MaxU => {
4794                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4795                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4796                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4797                let cmp = err!(
4798                    self.builder
4799                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
4800                );
4801                let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4802                let res = err!(
4803                    self.builder
4804                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4805                );
4806                self.state.push1(res);
4807            }
4808            Operator::I8x16AvgrU => {
4809                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4810                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4811                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4812
4813                // This approach is faster on x86-64 when the PAVG[BW]
4814                // instructions are available. On other platforms, an alternative
4815                // implementation appears likely to outperform, described here:
4816                //   %a = or %v1, %v2
4817                //   %b = and %a, 1
4818                //   %v1 = lshr %v1, 1
4819                //   %v2 = lshr %v2, 1
4820                //   %sum = add %v1, %v2
4821                //   %res = add %sum, %b
4822
4823                let ext_ty = self.intrinsics.i16_ty.vec_type(16);
4824                let one = self.intrinsics.i16_ty.const_int(1, false);
4825                let one = VectorType::const_vector(&[one; 16]);
4826
4827                let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4828                let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4829                let res = err!(self.builder.build_int_add(
4830                    err!(self.builder.build_int_add(one, v1, "")),
4831                    v2,
4832                    ""
4833                ));
4834                let res = err!(self.builder.build_right_shift(res, one, false, ""));
4835                let res = err!(
4836                    self.builder
4837                        .build_int_truncate(res, self.intrinsics.i8x16_ty, "")
4838                );
4839                let res = err!(
4840                    self.builder
4841                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4842                );
4843                self.state.push1(res);
4844            }
4845            Operator::I16x8AvgrU => {
4846                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4847                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4848                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4849
4850                // This approach is faster on x86-64 when the PAVG[BW]
4851                // instructions are available. On other platforms, an alternative
4852                // implementation appears likely to outperform, described here:
4853                //   %a = or %v1, %v2
4854                //   %b = and %a, 1
4855                //   %v1 = lshr %v1, 1
4856                //   %v2 = lshr %v2, 1
4857                //   %sum = add %v1, %v2
4858                //   %res = add %sum, %b
4859
4860                let ext_ty = self.intrinsics.i32_ty.vec_type(8);
4861                let one = self.intrinsics.i32_consts[1];
4862                let one = VectorType::const_vector(&[one; 8]);
4863
4864                let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4865                let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4866                let res = err!(self.builder.build_int_add(
4867                    err!(self.builder.build_int_add(one, v1, "")),
4868                    v2,
4869                    ""
4870                ));
4871                let res = err!(self.builder.build_right_shift(res, one, false, ""));
4872                let res = err!(
4873                    self.builder
4874                        .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
4875                );
4876                let res = err!(
4877                    self.builder
4878                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4879                );
4880                self.state.push1(res);
4881            }
4882
4883            /***************************
4884             * Floating-Point Arithmetic instructions.
4885             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-arithmetic-instructions
4886             ***************************/
4887            Operator::F32Add => {
4888                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4889                let res = err!(self.builder.build_call(
4890                    self.intrinsics.add_f32,
4891                    &[
4892                        v1.into(),
4893                        v2.into(),
4894                        self.intrinsics.fp_rounding_md,
4895                        self.intrinsics.fp_exception_md,
4896                    ],
4897                    "",
4898                ))
4899                .try_as_basic_value()
4900                .unwrap_basic();
4901                self.state.push1_extra(
4902                    res,
4903                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4904                );
4905            }
4906            Operator::F64Add => {
4907                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4908                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4909                let res = err!(self.builder.build_call(
4910                    self.intrinsics.add_f64,
4911                    &[
4912                        v1.into(),
4913                        v2.into(),
4914                        self.intrinsics.fp_rounding_md,
4915                        self.intrinsics.fp_exception_md,
4916                    ],
4917                    "",
4918                ))
4919                .try_as_basic_value()
4920                .unwrap_basic();
4921                self.state.push1_extra(
4922                    res,
4923                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4924                );
4925            }
4926            Operator::F32x4Add => {
4927                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4928                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4929                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4930                let res = err!(self.builder.build_call(
4931                    self.intrinsics.add_f32x4,
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                .unwrap_basic();
4942                let res = err!(
4943                    self.builder
4944                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4945                );
4946                self.state.push1_extra(
4947                    res,
4948                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4949                );
4950            }
4951            Operator::F64x2Add => {
4952                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4953                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
4954                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
4955                let res = err!(self.builder.build_call(
4956                    self.intrinsics.add_f64x2,
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                .unwrap_basic();
4967                let res = err!(
4968                    self.builder
4969                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
4970                );
4971                self.state.push1_extra(
4972                    res,
4973                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4974                );
4975            }
4976            Operator::F32Sub => {
4977                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4978                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4979                let res = err!(self.builder.build_call(
4980                    self.intrinsics.sub_f32,
4981                    &[
4982                        v1.into(),
4983                        v2.into(),
4984                        self.intrinsics.fp_rounding_md,
4985                        self.intrinsics.fp_exception_md,
4986                    ],
4987                    "",
4988                ))
4989                .try_as_basic_value()
4990                .unwrap_basic();
4991                self.state.push1_extra(
4992                    res,
4993                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4994                );
4995            }
4996            Operator::F64Sub => {
4997                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4998                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4999                let res = err!(self.builder.build_call(
5000                    self.intrinsics.sub_f64,
5001                    &[
5002                        v1.into(),
5003                        v2.into(),
5004                        self.intrinsics.fp_rounding_md,
5005                        self.intrinsics.fp_exception_md,
5006                    ],
5007                    "",
5008                ))
5009                .try_as_basic_value()
5010                .unwrap_basic();
5011                self.state.push1_extra(
5012                    res,
5013                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5014                );
5015            }
5016            Operator::F32x4Sub => {
5017                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5018                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5019                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5020                let res = err!(self.builder.build_call(
5021                    self.intrinsics.sub_f32x4,
5022                    &[
5023                        v1.into(),
5024                        v2.into(),
5025                        self.intrinsics.fp_rounding_md,
5026                        self.intrinsics.fp_exception_md,
5027                    ],
5028                    "",
5029                ))
5030                .try_as_basic_value()
5031                .unwrap_basic();
5032                let res = err!(
5033                    self.builder
5034                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5035                );
5036                self.state.push1_extra(
5037                    res,
5038                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5039                );
5040            }
5041            Operator::F64x2Sub => {
5042                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5043                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5044                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5045                let res = err!(self.builder.build_call(
5046                    self.intrinsics.sub_f64x2,
5047                    &[
5048                        v1.into(),
5049                        v2.into(),
5050                        self.intrinsics.fp_rounding_md,
5051                        self.intrinsics.fp_exception_md,
5052                    ],
5053                    "",
5054                ))
5055                .try_as_basic_value()
5056                .unwrap_basic();
5057                let res = err!(
5058                    self.builder
5059                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5060                );
5061                self.state.push1_extra(
5062                    res,
5063                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5064                );
5065            }
5066            Operator::F32Mul => {
5067                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5068                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5069                let res = err!(self.builder.build_call(
5070                    self.intrinsics.mul_f32,
5071                    &[
5072                        v1.into(),
5073                        v2.into(),
5074                        self.intrinsics.fp_rounding_md,
5075                        self.intrinsics.fp_exception_md,
5076                    ],
5077                    "",
5078                ))
5079                .try_as_basic_value()
5080                .unwrap_basic();
5081                self.state.push1_extra(
5082                    res,
5083                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5084                );
5085            }
5086            Operator::F64Mul => {
5087                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5088                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5089                let res = err!(self.builder.build_call(
5090                    self.intrinsics.mul_f64,
5091                    &[
5092                        v1.into(),
5093                        v2.into(),
5094                        self.intrinsics.fp_rounding_md,
5095                        self.intrinsics.fp_exception_md,
5096                    ],
5097                    "",
5098                ))
5099                .try_as_basic_value()
5100                .unwrap_basic();
5101                self.state.push1_extra(
5102                    res,
5103                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5104                );
5105            }
5106            Operator::F32x4Mul => {
5107                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5108                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5109                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5110                let res = err!(self.builder.build_call(
5111                    self.intrinsics.mul_f32x4,
5112                    &[
5113                        v1.into(),
5114                        v2.into(),
5115                        self.intrinsics.fp_rounding_md,
5116                        self.intrinsics.fp_exception_md,
5117                    ],
5118                    "",
5119                ))
5120                .try_as_basic_value()
5121                .unwrap_basic();
5122                let res = err!(
5123                    self.builder
5124                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5125                );
5126                self.state.push1_extra(
5127                    res,
5128                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5129                );
5130            }
5131            Operator::F64x2Mul => {
5132                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5133                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5134                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5135                let res = err!(self.builder.build_call(
5136                    self.intrinsics.mul_f64x2,
5137                    &[
5138                        v1.into(),
5139                        v2.into(),
5140                        self.intrinsics.fp_rounding_md,
5141                        self.intrinsics.fp_exception_md,
5142                    ],
5143                    "",
5144                ))
5145                .try_as_basic_value()
5146                .unwrap_basic();
5147                let res = err!(
5148                    self.builder
5149                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5150                );
5151                self.state.push1_extra(
5152                    res,
5153                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5154                );
5155            }
5156            Operator::F32Div => {
5157                let (v1, v2) = self.state.pop2()?;
5158                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5159                let res = err!(self.builder.build_call(
5160                    self.intrinsics.div_f32,
5161                    &[
5162                        v1.into(),
5163                        v2.into(),
5164                        self.intrinsics.fp_rounding_md,
5165                        self.intrinsics.fp_exception_md,
5166                    ],
5167                    "",
5168                ))
5169                .try_as_basic_value()
5170                .unwrap_basic();
5171                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5172            }
5173            Operator::F64Div => {
5174                let (v1, v2) = self.state.pop2()?;
5175                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5176                let res = err!(self.builder.build_call(
5177                    self.intrinsics.div_f64,
5178                    &[
5179                        v1.into(),
5180                        v2.into(),
5181                        self.intrinsics.fp_rounding_md,
5182                        self.intrinsics.fp_exception_md,
5183                    ],
5184                    "",
5185                ))
5186                .try_as_basic_value()
5187                .unwrap_basic();
5188                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5189            }
5190            Operator::F32x4Div => {
5191                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5192                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5193                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5194                let res = err!(self.builder.build_call(
5195                    self.intrinsics.div_f32x4,
5196                    &[
5197                        v1.into(),
5198                        v2.into(),
5199                        self.intrinsics.fp_rounding_md,
5200                        self.intrinsics.fp_exception_md,
5201                    ],
5202                    "",
5203                ))
5204                .try_as_basic_value()
5205                .unwrap_basic();
5206                let res = err!(
5207                    self.builder
5208                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5209                );
5210                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5211            }
5212            Operator::F64x2Div => {
5213                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5214                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5215                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5216                let res = err!(self.builder.build_call(
5217                    self.intrinsics.div_f64x2,
5218                    &[
5219                        v1.into(),
5220                        v2.into(),
5221                        self.intrinsics.fp_rounding_md,
5222                        self.intrinsics.fp_exception_md,
5223                    ],
5224                    "",
5225                ))
5226                .try_as_basic_value()
5227                .unwrap_basic();
5228                let res = err!(
5229                    self.builder
5230                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5231                );
5232                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5233            }
5234            Operator::F32Sqrt => {
5235                let input = self.state.pop1()?;
5236                let res = err!(self.builder.build_call(
5237                    self.intrinsics.sqrt_f32,
5238                    &[input.into()],
5239                    ""
5240                ))
5241                .try_as_basic_value()
5242                .unwrap_basic();
5243                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5244            }
5245            Operator::F64Sqrt => {
5246                let input = self.state.pop1()?;
5247                let res = err!(self.builder.build_call(
5248                    self.intrinsics.sqrt_f64,
5249                    &[input.into()],
5250                    ""
5251                ))
5252                .try_as_basic_value()
5253                .unwrap_basic();
5254                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5255            }
5256            Operator::F32x4Sqrt => {
5257                let (v, i) = self.state.pop1_extra()?;
5258                let (v, _) = self.v128_into_f32x4(v, i)?;
5259                let res = err!(self.builder.build_call(
5260                    self.intrinsics.sqrt_f32x4,
5261                    &[v.into()],
5262                    ""
5263                ))
5264                .try_as_basic_value()
5265                .unwrap_basic();
5266                let bits = err!(
5267                    self.builder
5268                        .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5269                );
5270                self.state.push1_extra(bits, ExtraInfo::pending_f32_nan());
5271            }
5272            Operator::F64x2Sqrt => {
5273                let (v, i) = self.state.pop1_extra()?;
5274                let (v, _) = self.v128_into_f64x2(v, i)?;
5275                let res = err!(self.builder.build_call(
5276                    self.intrinsics.sqrt_f64x2,
5277                    &[v.into()],
5278                    ""
5279                ))
5280                .try_as_basic_value()
5281                .unwrap_basic();
5282                let bits = err!(
5283                    self.builder
5284                        .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5285                );
5286                self.state.push1(bits);
5287            }
5288            Operator::F32Min => {
5289                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5290                let lhs = self
5291                    .apply_pending_canonicalization(lhs, lhs_info)?
5292                    .into_float_value();
5293                let rhs = self
5294                    .apply_pending_canonicalization(rhs, rhs_info)?
5295                    .into_float_value();
5296
5297                let res = err!(self.builder.build_call(
5298                    self.intrinsics.minimum_f32,
5299                    &[lhs.into(), rhs.into()],
5300                    "",
5301                ))
5302                .try_as_basic_value()
5303                .unwrap_basic();
5304
5305                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5306                let res = res.into_float_value();
5307
5308                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5309            }
5310            Operator::F64Min => {
5311                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5312                let lhs = self
5313                    .apply_pending_canonicalization(lhs, lhs_info)?
5314                    .into_float_value();
5315                let rhs = self
5316                    .apply_pending_canonicalization(rhs, rhs_info)?
5317                    .into_float_value();
5318
5319                let res = err!(self.builder.build_call(
5320                    self.intrinsics.minimum_f64,
5321                    &[lhs.into(), rhs.into()],
5322                    "",
5323                ))
5324                .try_as_basic_value()
5325                .unwrap_basic();
5326
5327                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5328                let res = res.into_float_value();
5329
5330                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5331            }
5332            Operator::F32x4Min => {
5333                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5334                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5335                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5336                let res = err!(self.builder.build_call(
5337                    self.intrinsics.minimum_f32x4,
5338                    &[v1.into(), v2.into()],
5339                    "",
5340                ))
5341                .try_as_basic_value()
5342                .unwrap_basic();
5343
5344                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5345                let res = res.into_vector_value();
5346
5347                let res = err!(
5348                    self.builder
5349                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5350                );
5351                self.state.push1_extra(
5352                    res,
5353                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5354                );
5355            }
5356            Operator::F32x4PMin => {
5357                // Pseudo-min: b < a ? b : a
5358                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5359                let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5360                let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5361                let cmp = err!(
5362                    self.builder
5363                        .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5364                );
5365                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5366                let res = err!(
5367                    self.builder
5368                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5369                );
5370                self.state.push1(res);
5371            }
5372            Operator::F64x2Min => {
5373                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5374                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5375                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5376                let res = err!(self.builder.build_call(
5377                    self.intrinsics.minimum_f64x2,
5378                    &[v1.into(), v2.into()],
5379                    "",
5380                ))
5381                .try_as_basic_value()
5382                .unwrap_basic();
5383
5384                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5385                let res = res.into_vector_value();
5386
5387                let res = err!(
5388                    self.builder
5389                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5390                );
5391                self.state.push1_extra(
5392                    res,
5393                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5394                );
5395            }
5396            Operator::F64x2PMin => {
5397                // Pseudo-min: b < a ? b : a
5398                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5399                let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5400                let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5401                let cmp = err!(
5402                    self.builder
5403                        .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5404                );
5405                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5406                let res = err!(
5407                    self.builder
5408                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5409                );
5410                self.state.push1(res);
5411            }
5412            Operator::F32Max => {
5413                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5414                let lhs = self
5415                    .apply_pending_canonicalization(lhs, lhs_info)?
5416                    .into_float_value();
5417                let rhs = self
5418                    .apply_pending_canonicalization(rhs, rhs_info)?
5419                    .into_float_value();
5420
5421                let res = err!(self.builder.build_call(
5422                    self.intrinsics.maximum_f32,
5423                    &[lhs.into(), rhs.into()],
5424                    "",
5425                ))
5426                .try_as_basic_value()
5427                .unwrap_basic();
5428
5429                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5430                let res = res.into_float_value();
5431
5432                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5433            }
5434            Operator::F64Max => {
5435                let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5436                let lhs = self
5437                    .apply_pending_canonicalization(lhs, lhs_info)?
5438                    .into_float_value();
5439                let rhs = self
5440                    .apply_pending_canonicalization(rhs, rhs_info)?
5441                    .into_float_value();
5442
5443                let res = err!(self.builder.build_call(
5444                    self.intrinsics.maximum_f64,
5445                    &[lhs.into(), rhs.into()],
5446                    "",
5447                ))
5448                .try_as_basic_value()
5449                .unwrap_basic();
5450
5451                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5452                let res = res.into_float_value();
5453
5454                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5455            }
5456            Operator::F32x4Max => {
5457                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5458                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5459                let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5460                let res = err!(self.builder.build_call(
5461                    self.intrinsics.maximum_f32x4,
5462                    &[v1.into(), v2.into()],
5463                    "",
5464                ))
5465                .try_as_basic_value()
5466                .unwrap_basic();
5467
5468                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5469                let res = res.into_vector_value();
5470
5471                let res = err!(
5472                    self.builder
5473                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5474                );
5475                self.state.push1_extra(
5476                    res,
5477                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5478                );
5479            }
5480            Operator::F32x4PMax => {
5481                // Pseudo-max: a < b ? b : a
5482                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5483                let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5484                let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5485                let cmp = err!(
5486                    self.builder
5487                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5488                );
5489                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5490
5491                let res = err!(
5492                    self.builder
5493                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5494                );
5495                self.state.push1(res);
5496            }
5497            Operator::F64x2Max => {
5498                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5499                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5500                let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5501                let res = err!(self.builder.build_call(
5502                    self.intrinsics.maximum_f64x2,
5503                    &[v1.into(), v2.into()],
5504                    "",
5505                ))
5506                .try_as_basic_value()
5507                .unwrap_basic();
5508
5509                let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5510                let res = res.into_vector_value();
5511
5512                let res = err!(
5513                    self.builder
5514                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5515                );
5516                self.state.push1_extra(
5517                    res,
5518                    ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5519                );
5520            }
5521            Operator::F64x2PMax => {
5522                // Pseudo-max: a < b ? b : a
5523                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5524                let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5525                let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5526                let cmp = err!(
5527                    self.builder
5528                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5529                );
5530                let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5531                let res = err!(
5532                    self.builder
5533                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5534                );
5535                self.state.push1(res);
5536            }
5537            Operator::F32Ceil => {
5538                let (input, info) = self.state.pop1_extra()?;
5539                let res = err!(self.builder.build_call(
5540                    self.intrinsics.ceil_f32,
5541                    &[input.into()],
5542                    ""
5543                ))
5544                .try_as_basic_value()
5545                .unwrap_basic();
5546                self.state
5547                    .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5548            }
5549            Operator::F32x4Ceil => {
5550                let (v, i) = self.state.pop1_extra()?;
5551                let (v, _) = self.v128_into_f32x4(v, i)?;
5552                let res = err!(self.builder.build_call(
5553                    self.intrinsics.ceil_f32x4,
5554                    &[v.into()],
5555                    ""
5556                ))
5557                .try_as_basic_value()
5558                .unwrap_basic();
5559                let res = err!(
5560                    self.builder
5561                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5562                );
5563                self.state
5564                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5565            }
5566            Operator::F64Ceil => {
5567                let (input, info) = self.state.pop1_extra()?;
5568                let res = err!(self.builder.build_call(
5569                    self.intrinsics.ceil_f64,
5570                    &[input.into()],
5571                    ""
5572                ))
5573                .try_as_basic_value()
5574                .unwrap_basic();
5575                self.state
5576                    .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5577            }
5578            Operator::F64x2Ceil => {
5579                let (v, i) = self.state.pop1_extra()?;
5580                let (v, _) = self.v128_into_f64x2(v, i)?;
5581                let res = err!(self.builder.build_call(
5582                    self.intrinsics.ceil_f64x2,
5583                    &[v.into()],
5584                    ""
5585                ))
5586                .try_as_basic_value()
5587                .unwrap_basic();
5588                let res = err!(
5589                    self.builder
5590                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5591                );
5592                self.state
5593                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5594            }
5595            Operator::F32Floor => {
5596                let (input, info) = self.state.pop1_extra()?;
5597                let res = err!(self.builder.build_call(
5598                    self.intrinsics.floor_f32,
5599                    &[input.into()],
5600                    ""
5601                ))
5602                .try_as_basic_value()
5603                .unwrap_basic();
5604                self.state
5605                    .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5606            }
5607            Operator::F32x4Floor => {
5608                let (v, i) = self.state.pop1_extra()?;
5609                let (v, _) = self.v128_into_f32x4(v, i)?;
5610                let res = err!(self.builder.build_call(
5611                    self.intrinsics.floor_f32x4,
5612                    &[v.into()],
5613                    ""
5614                ))
5615                .try_as_basic_value()
5616                .unwrap_basic();
5617                let res = err!(
5618                    self.builder
5619                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5620                );
5621                self.state
5622                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5623            }
5624            Operator::F64Floor => {
5625                let (input, info) = self.state.pop1_extra()?;
5626                let res = err!(self.builder.build_call(
5627                    self.intrinsics.floor_f64,
5628                    &[input.into()],
5629                    ""
5630                ))
5631                .try_as_basic_value()
5632                .unwrap_basic();
5633                self.state
5634                    .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5635            }
5636            Operator::F64x2Floor => {
5637                let (v, i) = self.state.pop1_extra()?;
5638                let (v, _) = self.v128_into_f64x2(v, i)?;
5639                let res = err!(self.builder.build_call(
5640                    self.intrinsics.floor_f64x2,
5641                    &[v.into()],
5642                    ""
5643                ))
5644                .try_as_basic_value()
5645                .unwrap_basic();
5646                let res = err!(
5647                    self.builder
5648                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5649                );
5650                self.state
5651                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5652            }
5653            Operator::F32Trunc => {
5654                let (v, i) = self.state.pop1_extra()?;
5655                let res = err!(
5656                    self.builder
5657                        .build_call(self.intrinsics.trunc_f32, &[v.into()], "")
5658                )
5659                .try_as_basic_value()
5660                .unwrap_basic();
5661                self.state
5662                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5663            }
5664            Operator::F32x4Trunc => {
5665                let (v, i) = self.state.pop1_extra()?;
5666                let (v, _) = self.v128_into_f32x4(v, i)?;
5667                let res = err!(self.builder.build_call(
5668                    self.intrinsics.trunc_f32x4,
5669                    &[v.into()],
5670                    ""
5671                ))
5672                .try_as_basic_value()
5673                .unwrap_basic();
5674                let res = err!(
5675                    self.builder
5676                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5677                );
5678                self.state
5679                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5680            }
5681            Operator::F64Trunc => {
5682                let (v, i) = self.state.pop1_extra()?;
5683                let res = err!(
5684                    self.builder
5685                        .build_call(self.intrinsics.trunc_f64, &[v.into()], "")
5686                )
5687                .try_as_basic_value()
5688                .unwrap_basic();
5689                self.state
5690                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5691            }
5692            Operator::F64x2Trunc => {
5693                let (v, i) = self.state.pop1_extra()?;
5694                let (v, _) = self.v128_into_f64x2(v, i)?;
5695                let res = err!(self.builder.build_call(
5696                    self.intrinsics.trunc_f64x2,
5697                    &[v.into()],
5698                    ""
5699                ))
5700                .try_as_basic_value()
5701                .unwrap_basic();
5702                let res = err!(
5703                    self.builder
5704                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5705                );
5706                self.state
5707                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5708            }
5709            Operator::F32Nearest => {
5710                let (v, i) = self.state.pop1_extra()?;
5711                let res = err!(self.builder.build_call(
5712                    self.intrinsics.nearbyint_f32,
5713                    &[v.into()],
5714                    ""
5715                ))
5716                .try_as_basic_value()
5717                .unwrap_basic();
5718                self.state
5719                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5720            }
5721            Operator::F32x4Nearest => {
5722                let (v, i) = self.state.pop1_extra()?;
5723                let (v, _) = self.v128_into_f32x4(v, i)?;
5724                let res = err!(self.builder.build_call(
5725                    self.intrinsics.nearbyint_f32x4,
5726                    &[v.into()],
5727                    ""
5728                ))
5729                .try_as_basic_value()
5730                .unwrap_basic();
5731                let res = err!(
5732                    self.builder
5733                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5734                );
5735                self.state
5736                    .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5737            }
5738            Operator::F64Nearest => {
5739                let (v, i) = self.state.pop1_extra()?;
5740                let res = err!(self.builder.build_call(
5741                    self.intrinsics.nearbyint_f64,
5742                    &[v.into()],
5743                    ""
5744                ))
5745                .try_as_basic_value()
5746                .unwrap_basic();
5747                self.state
5748                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5749            }
5750            Operator::F64x2Nearest => {
5751                let (v, i) = self.state.pop1_extra()?;
5752                let (v, _) = self.v128_into_f64x2(v, i)?;
5753                let res = err!(self.builder.build_call(
5754                    self.intrinsics.nearbyint_f64x2,
5755                    &[v.into()],
5756                    ""
5757                ))
5758                .try_as_basic_value()
5759                .unwrap_basic();
5760                let res = err!(
5761                    self.builder
5762                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5763                );
5764                self.state
5765                    .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5766            }
5767            Operator::F32Abs => {
5768                let (v, i) = self.state.pop1_extra()?;
5769                let v = self.apply_pending_canonicalization(v, i)?;
5770                let res = err!(
5771                    self.builder
5772                        .build_call(self.intrinsics.fabs_f32, &[v.into()], "")
5773                )
5774                .try_as_basic_value()
5775                .unwrap_basic();
5776                // The exact NaN returned by F32Abs is fully defined. Do not
5777                // adjust.
5778                self.state.push1_extra(res, i.strip_pending());
5779            }
5780            Operator::F64Abs => {
5781                let (v, i) = self.state.pop1_extra()?;
5782                let v = self.apply_pending_canonicalization(v, i)?;
5783                let res = err!(
5784                    self.builder
5785                        .build_call(self.intrinsics.fabs_f64, &[v.into()], "")
5786                )
5787                .try_as_basic_value()
5788                .unwrap_basic();
5789                // The exact NaN returned by F64Abs is fully defined. Do not
5790                // adjust.
5791                self.state.push1_extra(res, i.strip_pending());
5792            }
5793            Operator::F32x4Abs => {
5794                let (v, i) = self.state.pop1_extra()?;
5795                let v = err!(self.builder.build_bit_cast(
5796                    v.into_int_value(),
5797                    self.intrinsics.f32x4_ty,
5798                    ""
5799                ));
5800                let v = self.apply_pending_canonicalization(v, i)?;
5801                let res = err!(self.builder.build_call(
5802                    self.intrinsics.fabs_f32x4,
5803                    &[v.into()],
5804                    ""
5805                ))
5806                .try_as_basic_value()
5807                .unwrap_basic();
5808                let res = err!(
5809                    self.builder
5810                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5811                );
5812                // The exact NaN returned by F32x4Abs is fully defined. Do not
5813                // adjust.
5814                self.state.push1_extra(res, i.strip_pending());
5815            }
5816            Operator::F64x2Abs => {
5817                let (v, i) = self.state.pop1_extra()?;
5818                let v = err!(self.builder.build_bit_cast(
5819                    v.into_int_value(),
5820                    self.intrinsics.f64x2_ty,
5821                    ""
5822                ));
5823                let v = self.apply_pending_canonicalization(v, i)?;
5824                let res = err!(self.builder.build_call(
5825                    self.intrinsics.fabs_f64x2,
5826                    &[v.into()],
5827                    ""
5828                ))
5829                .try_as_basic_value()
5830                .unwrap_basic();
5831                let res = err!(
5832                    self.builder
5833                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5834                );
5835                // The exact NaN returned by F32x4Abs is fully defined. Do not
5836                // adjust.
5837                self.state.push1_extra(res, i.strip_pending());
5838            }
5839            Operator::F32x4Neg => {
5840                let (v, i) = self.state.pop1_extra()?;
5841                let v = err!(self.builder.build_bit_cast(
5842                    v.into_int_value(),
5843                    self.intrinsics.f32x4_ty,
5844                    ""
5845                ));
5846                let v = self
5847                    .apply_pending_canonicalization(v, i)?
5848                    .into_vector_value();
5849                let res = err!(self.builder.build_float_neg(v, ""));
5850                let res = err!(
5851                    self.builder
5852                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5853                );
5854                // The exact NaN returned by F32x4Neg is fully defined. Do not
5855                // adjust.
5856                self.state.push1_extra(res, i.strip_pending());
5857            }
5858            Operator::F64x2Neg => {
5859                let (v, i) = self.state.pop1_extra()?;
5860                let v = err!(self.builder.build_bit_cast(
5861                    v.into_int_value(),
5862                    self.intrinsics.f64x2_ty,
5863                    ""
5864                ));
5865                let v = self
5866                    .apply_pending_canonicalization(v, i)?
5867                    .into_vector_value();
5868                let res = err!(self.builder.build_float_neg(v, ""));
5869                let res = err!(
5870                    self.builder
5871                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5872                );
5873                // The exact NaN returned by F64x2Neg is fully defined. Do not
5874                // adjust.
5875                self.state.push1_extra(res, i.strip_pending());
5876            }
5877            Operator::F32Neg | Operator::F64Neg => {
5878                let (v, i) = self.state.pop1_extra()?;
5879                let v = self
5880                    .apply_pending_canonicalization(v, i)?
5881                    .into_float_value();
5882                let res = err!(self.builder.build_float_neg(v, ""));
5883                // The exact NaN returned by F32Neg and F64Neg are fully defined.
5884                // Do not adjust.
5885                self.state.push1_extra(res, i.strip_pending());
5886            }
5887            Operator::F32Copysign => {
5888                let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5889                let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5890                let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5891                let res = err!(self.builder.build_call(
5892                    self.intrinsics.copysign_f32,
5893                    &[mag.into(), sgn.into()],
5894                    ""
5895                ))
5896                .try_as_basic_value()
5897                .unwrap_basic();
5898                // The exact NaN returned by F32Copysign is fully defined.
5899                // Do not adjust.
5900                self.state.push1_extra(res, mag_info.strip_pending());
5901            }
5902            Operator::F64Copysign => {
5903                let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5904                let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5905                let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5906                let res = err!(self.builder.build_call(
5907                    self.intrinsics.copysign_f64,
5908                    &[mag.into(), sgn.into()],
5909                    ""
5910                ))
5911                .try_as_basic_value()
5912                .unwrap_basic();
5913                // The exact NaN returned by F32Copysign is fully defined.
5914                // Do not adjust.
5915                self.state.push1_extra(res, mag_info.strip_pending());
5916            }
5917
5918            /***************************
5919             * Integer Comparison instructions.
5920             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#integer-comparison-instructions
5921             ***************************/
5922            Operator::I32Eq | Operator::I64Eq => {
5923                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5924                let v1 = self.apply_pending_canonicalization(v1, i1)?;
5925                let v2 = self.apply_pending_canonicalization(v2, i2)?;
5926                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
5927                let cond = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5928                let res = err!(
5929                    self.builder
5930                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
5931                );
5932                self.state.push1_extra(
5933                    res,
5934                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
5935                );
5936            }
5937            Operator::I8x16Eq => {
5938                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5939                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
5940                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
5941                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5942                let res = err!(
5943                    self.builder
5944                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
5945                );
5946                let res = err!(
5947                    self.builder
5948                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5949                );
5950                self.state.push1(res);
5951            }
5952            Operator::I16x8Eq => {
5953                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5954                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
5955                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
5956                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5957                let res = err!(
5958                    self.builder
5959                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
5960                );
5961                let res = err!(
5962                    self.builder
5963                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5964                );
5965                self.state.push1(res);
5966            }
5967            Operator::I32x4Eq => {
5968                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5969                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
5970                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
5971                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5972                let res = err!(
5973                    self.builder
5974                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
5975                );
5976                let res = err!(
5977                    self.builder
5978                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5979                );
5980                self.state.push1(res);
5981            }
5982            Operator::I64x2Eq => {
5983                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5984                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
5985                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
5986                let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5987                let res = err!(
5988                    self.builder
5989                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
5990                );
5991                let res = err!(
5992                    self.builder
5993                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
5994                );
5995                self.state.push1(res);
5996            }
5997            Operator::I32Ne | Operator::I64Ne => {
5998                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5999                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6000                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6001                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6002                let cond = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6003                let res = err!(
6004                    self.builder
6005                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6006                );
6007                self.state.push1_extra(
6008                    res,
6009                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6010                );
6011            }
6012            Operator::I8x16Ne => {
6013                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6014                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6015                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6016                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6017                let res = err!(
6018                    self.builder
6019                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6020                );
6021                let res = err!(
6022                    self.builder
6023                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6024                );
6025                self.state.push1(res);
6026            }
6027            Operator::I16x8Ne => {
6028                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6029                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6030                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6031                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6032                let res = err!(
6033                    self.builder
6034                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6035                );
6036                let res = err!(
6037                    self.builder
6038                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6039                );
6040                self.state.push1(res);
6041            }
6042            Operator::I32x4Ne => {
6043                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6044                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6045                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6046                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6047                let res = err!(
6048                    self.builder
6049                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6050                );
6051                let res = err!(
6052                    self.builder
6053                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6054                );
6055                self.state.push1(res);
6056            }
6057            Operator::I64x2Ne => {
6058                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6059                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6060                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6061                let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6062                let res = err!(
6063                    self.builder
6064                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6065                );
6066                let res = err!(
6067                    self.builder
6068                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6069                );
6070                self.state.push1(res);
6071            }
6072            Operator::I32LtS | Operator::I64LtS => {
6073                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6074                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6075                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6076                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6077                let cond = err!(
6078                    self.builder
6079                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6080                );
6081                let res = err!(
6082                    self.builder
6083                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6084                );
6085                self.state.push1_extra(
6086                    res,
6087                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6088                );
6089            }
6090            Operator::I8x16LtS => {
6091                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6092                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6093                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6094                let res = err!(
6095                    self.builder
6096                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6097                );
6098                let res = err!(
6099                    self.builder
6100                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
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::I16x8LtS => {
6109                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6110                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6111                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6112                let res = err!(
6113                    self.builder
6114                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6115                );
6116                let res = err!(
6117                    self.builder
6118                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6119                );
6120                let res = err!(
6121                    self.builder
6122                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6123                );
6124                self.state.push1(res);
6125            }
6126            Operator::I32x4LtS => {
6127                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6128                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6129                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6130                let res = err!(
6131                    self.builder
6132                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6133                );
6134                let res = err!(
6135                    self.builder
6136                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6137                );
6138                let res = err!(
6139                    self.builder
6140                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6141                );
6142                self.state.push1(res);
6143            }
6144            Operator::I64x2LtS => {
6145                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6146                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6147                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6148                let res = err!(
6149                    self.builder
6150                        .build_int_compare(IntPredicate::SLT, v1, v2, "")
6151                );
6152                let res = err!(
6153                    self.builder
6154                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6155                );
6156                let res = err!(
6157                    self.builder
6158                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6159                );
6160                self.state.push1(res);
6161            }
6162            Operator::I32LtU | Operator::I64LtU => {
6163                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6164                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6165                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6166                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6167                let cond = err!(
6168                    self.builder
6169                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6170                );
6171                let res = err!(
6172                    self.builder
6173                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6174                );
6175                self.state.push1(res);
6176            }
6177            Operator::I8x16LtU => {
6178                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6179                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6180                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6181                let res = err!(
6182                    self.builder
6183                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6184                );
6185                let res = err!(
6186                    self.builder
6187                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6188                );
6189                let res = err!(
6190                    self.builder
6191                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6192                );
6193                self.state.push1(res);
6194            }
6195            Operator::I16x8LtU => {
6196                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6197                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6198                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6199                let res = err!(
6200                    self.builder
6201                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6202                );
6203                let res = err!(
6204                    self.builder
6205                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6206                );
6207                let res = err!(
6208                    self.builder
6209                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6210                );
6211                self.state.push1(res);
6212            }
6213            Operator::I32x4LtU => {
6214                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6215                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6216                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6217                let res = err!(
6218                    self.builder
6219                        .build_int_compare(IntPredicate::ULT, v1, v2, "")
6220                );
6221                let res = err!(
6222                    self.builder
6223                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6224                );
6225                let res = err!(
6226                    self.builder
6227                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6228                );
6229                self.state.push1(res);
6230            }
6231            Operator::I32LeS | Operator::I64LeS => {
6232                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6233                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6234                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6235                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6236                let cond = err!(
6237                    self.builder
6238                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6239                );
6240                let res = err!(
6241                    self.builder
6242                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6243                );
6244                self.state.push1_extra(
6245                    res,
6246                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6247                );
6248            }
6249            Operator::I8x16LeS => {
6250                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6251                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6252                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6253                let res = err!(
6254                    self.builder
6255                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6256                );
6257                let res = err!(
6258                    self.builder
6259                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6260                );
6261                let res = err!(
6262                    self.builder
6263                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6264                );
6265                self.state.push1(res);
6266            }
6267            Operator::I16x8LeS => {
6268                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6269                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6270                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6271                let res = err!(
6272                    self.builder
6273                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6274                );
6275                let res = err!(
6276                    self.builder
6277                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6278                );
6279                let res = err!(
6280                    self.builder
6281                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6282                );
6283                self.state.push1(res);
6284            }
6285            Operator::I32x4LeS => {
6286                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6287                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6288                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6289                let res = err!(
6290                    self.builder
6291                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6292                );
6293                let res = err!(
6294                    self.builder
6295                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6296                );
6297                let res = err!(
6298                    self.builder
6299                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6300                );
6301                self.state.push1(res);
6302            }
6303            Operator::I64x2LeS => {
6304                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6305                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6306                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6307                let res = err!(
6308                    self.builder
6309                        .build_int_compare(IntPredicate::SLE, v1, v2, "")
6310                );
6311                let res = err!(
6312                    self.builder
6313                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6314                );
6315                let res = err!(
6316                    self.builder
6317                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6318                );
6319                self.state.push1(res);
6320            }
6321            Operator::I32LeU | Operator::I64LeU => {
6322                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6323                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6324                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6325                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6326                let cond = err!(
6327                    self.builder
6328                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6329                );
6330                let res = err!(
6331                    self.builder
6332                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6333                );
6334                self.state.push1_extra(
6335                    res,
6336                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6337                );
6338            }
6339            Operator::I8x16LeU => {
6340                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6341                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6342                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6343                let res = err!(
6344                    self.builder
6345                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6346                );
6347                let res = err!(
6348                    self.builder
6349                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6350                );
6351                let res = err!(
6352                    self.builder
6353                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6354                );
6355                self.state.push1(res);
6356            }
6357            Operator::I16x8LeU => {
6358                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6359                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6360                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6361                let res = err!(
6362                    self.builder
6363                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6364                );
6365                let res = err!(
6366                    self.builder
6367                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6368                );
6369                let res = err!(
6370                    self.builder
6371                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6372                );
6373                self.state.push1(res);
6374            }
6375            Operator::I32x4LeU => {
6376                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6377                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6378                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6379                let res = err!(
6380                    self.builder
6381                        .build_int_compare(IntPredicate::ULE, v1, v2, "")
6382                );
6383                let res = err!(
6384                    self.builder
6385                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6386                );
6387                let res = err!(
6388                    self.builder
6389                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6390                );
6391                self.state.push1(res);
6392            }
6393            Operator::I32GtS | Operator::I64GtS => {
6394                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6395                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6396                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6397                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6398                let cond = err!(
6399                    self.builder
6400                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6401                );
6402                let res = err!(
6403                    self.builder
6404                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6405                );
6406                self.state.push1_extra(
6407                    res,
6408                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6409                );
6410            }
6411            Operator::I8x16GtS => {
6412                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6413                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6414                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6415                let res = err!(
6416                    self.builder
6417                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6418                );
6419                let res = err!(
6420                    self.builder
6421                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6422                );
6423                let res = err!(
6424                    self.builder
6425                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6426                );
6427                self.state.push1(res);
6428            }
6429            Operator::I16x8GtS => {
6430                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6431                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6432                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6433                let res = err!(
6434                    self.builder
6435                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6436                );
6437                let res = err!(
6438                    self.builder
6439                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6440                );
6441                let res = err!(
6442                    self.builder
6443                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6444                );
6445                self.state.push1(res);
6446            }
6447            Operator::I32x4GtS => {
6448                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6449                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6450                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6451                let res = err!(
6452                    self.builder
6453                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6454                );
6455                let res = err!(
6456                    self.builder
6457                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6458                );
6459                let res = err!(
6460                    self.builder
6461                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6462                );
6463                self.state.push1(res);
6464            }
6465            Operator::I64x2GtS => {
6466                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6467                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6468                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6469                let res = err!(
6470                    self.builder
6471                        .build_int_compare(IntPredicate::SGT, v1, v2, "")
6472                );
6473                let res = err!(
6474                    self.builder
6475                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6476                );
6477                let res = err!(
6478                    self.builder
6479                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6480                );
6481                self.state.push1(res);
6482            }
6483            Operator::I32GtU | Operator::I64GtU => {
6484                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6485                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6486                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6487                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6488                let cond = err!(
6489                    self.builder
6490                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6491                );
6492                let res = err!(
6493                    self.builder
6494                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6495                );
6496                self.state.push1_extra(
6497                    res,
6498                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6499                );
6500            }
6501            Operator::I8x16GtU => {
6502                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6503                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6504                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6505                let res = err!(
6506                    self.builder
6507                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6508                );
6509                let res = err!(
6510                    self.builder
6511                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6512                );
6513                let res = err!(
6514                    self.builder
6515                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6516                );
6517                self.state.push1(res);
6518            }
6519            Operator::I16x8GtU => {
6520                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6521                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6522                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6523                let res = err!(
6524                    self.builder
6525                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6526                );
6527                let res = err!(
6528                    self.builder
6529                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6530                );
6531                let res = err!(
6532                    self.builder
6533                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6534                );
6535                self.state.push1(res);
6536            }
6537            Operator::I32x4GtU => {
6538                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6539                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6540                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6541                let res = err!(
6542                    self.builder
6543                        .build_int_compare(IntPredicate::UGT, v1, v2, "")
6544                );
6545                let res = err!(
6546                    self.builder
6547                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6548                );
6549                let res = err!(
6550                    self.builder
6551                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6552                );
6553                self.state.push1(res);
6554            }
6555            Operator::I32GeS | Operator::I64GeS => {
6556                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6557                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6558                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6559                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6560                let cond = err!(
6561                    self.builder
6562                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6563                );
6564                let res = err!(
6565                    self.builder
6566                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6567                );
6568                self.state.push1(res);
6569            }
6570            Operator::I8x16GeS => {
6571                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6572                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6573                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6574                let res = err!(
6575                    self.builder
6576                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6577                );
6578                let res = err!(
6579                    self.builder
6580                        .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6581                );
6582                let res = err!(
6583                    self.builder
6584                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6585                );
6586                self.state.push1(res);
6587            }
6588            Operator::I16x8GeS => {
6589                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6590                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6591                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6592                let res = err!(
6593                    self.builder
6594                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6595                );
6596                let res = err!(
6597                    self.builder
6598                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6599                );
6600                let res = err!(
6601                    self.builder
6602                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6603                );
6604                self.state.push1(res);
6605            }
6606            Operator::I32x4GeS => {
6607                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6608                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6609                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6610                let res = err!(
6611                    self.builder
6612                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6613                );
6614                let res = err!(
6615                    self.builder
6616                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6617                );
6618                let res = err!(
6619                    self.builder
6620                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6621                );
6622                self.state.push1(res);
6623            }
6624            Operator::I64x2GeS => {
6625                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6626                let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6627                let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6628                let res = err!(
6629                    self.builder
6630                        .build_int_compare(IntPredicate::SGE, v1, v2, "")
6631                );
6632                let res = err!(
6633                    self.builder
6634                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6635                );
6636                let res = err!(
6637                    self.builder
6638                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6639                );
6640                self.state.push1(res);
6641            }
6642            Operator::I32GeU | Operator::I64GeU => {
6643                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6644                let v1 = self.apply_pending_canonicalization(v1, i1)?;
6645                let v2 = self.apply_pending_canonicalization(v2, i2)?;
6646                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6647                let cond = err!(
6648                    self.builder
6649                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6650                );
6651                let res = err!(
6652                    self.builder
6653                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6654                );
6655                self.state.push1_extra(
6656                    res,
6657                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6658                );
6659            }
6660            Operator::I8x16GeU => {
6661                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6662                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6663                let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6664                let res = err!(
6665                    self.builder
6666                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6667                );
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::I16x8GeU => {
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!(
6683                    self.builder
6684                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6685                );
6686                let res = err!(
6687                    self.builder
6688                        .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6689                );
6690                let res = err!(
6691                    self.builder
6692                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6693                );
6694                self.state.push1(res);
6695            }
6696            Operator::I32x4GeU => {
6697                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6698                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6699                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6700                let res = err!(
6701                    self.builder
6702                        .build_int_compare(IntPredicate::UGE, v1, v2, "")
6703                );
6704                let res = err!(
6705                    self.builder
6706                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6707                );
6708                let res = err!(
6709                    self.builder
6710                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6711                );
6712                self.state.push1(res);
6713            }
6714
6715            /***************************
6716             * Floating-Point Comparison instructions.
6717             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#floating-point-comparison-instructions
6718             ***************************/
6719            Operator::F32Eq | Operator::F64Eq => {
6720                let (v1, v2) = self.state.pop2()?;
6721                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6722                let cond = err!(
6723                    self.builder
6724                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6725                );
6726                let res = err!(
6727                    self.builder
6728                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6729                );
6730                self.state.push1_extra(
6731                    res,
6732                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6733                );
6734            }
6735            Operator::F32x4Eq => {
6736                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6737                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6738                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6739                let res = err!(
6740                    self.builder
6741                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6742                );
6743                let res = err!(
6744                    self.builder
6745                        .build_int_s_extend(res, self.intrinsics.i32x4_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::F64x2Eq => {
6754                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6755                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6756                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6757                let res = err!(
6758                    self.builder
6759                        .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6760                );
6761                let res = err!(
6762                    self.builder
6763                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6764                );
6765                let res = err!(
6766                    self.builder
6767                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6768                );
6769                self.state.push1(res);
6770            }
6771            Operator::F32Ne | Operator::F64Ne => {
6772                let (v1, v2) = self.state.pop2()?;
6773                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6774                let cond = err!(
6775                    self.builder
6776                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6777                );
6778                let res = err!(
6779                    self.builder
6780                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6781                );
6782                self.state.push1_extra(
6783                    res,
6784                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6785                );
6786            }
6787            Operator::F32x4Ne => {
6788                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6789                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6790                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6791                let res = err!(
6792                    self.builder
6793                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6794                );
6795                let res = err!(
6796                    self.builder
6797                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6798                );
6799                let res = err!(
6800                    self.builder
6801                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6802                );
6803                self.state.push1(res);
6804            }
6805            Operator::F64x2Ne => {
6806                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6807                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6808                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6809                let res = err!(
6810                    self.builder
6811                        .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6812                );
6813                let res = err!(
6814                    self.builder
6815                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6816                );
6817                let res = err!(
6818                    self.builder
6819                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6820                );
6821                self.state.push1(res);
6822            }
6823            Operator::F32Lt | Operator::F64Lt => {
6824                let (v1, v2) = self.state.pop2()?;
6825                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6826                let cond = err!(
6827                    self.builder
6828                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6829                );
6830                let res = err!(
6831                    self.builder
6832                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6833                );
6834                self.state.push1_extra(
6835                    res,
6836                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6837                );
6838            }
6839            Operator::F32x4Lt => {
6840                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6841                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6842                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6843                let res = err!(
6844                    self.builder
6845                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6846                );
6847                let res = err!(
6848                    self.builder
6849                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6850                );
6851                let res = err!(
6852                    self.builder
6853                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6854                );
6855                self.state.push1(res);
6856            }
6857            Operator::F64x2Lt => {
6858                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6859                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6860                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6861                let res = err!(
6862                    self.builder
6863                        .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6864                );
6865                let res = err!(
6866                    self.builder
6867                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6868                );
6869                let res = err!(
6870                    self.builder
6871                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6872                );
6873                self.state.push1(res);
6874            }
6875            Operator::F32Le | Operator::F64Le => {
6876                let (v1, v2) = self.state.pop2()?;
6877                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6878                let cond = err!(
6879                    self.builder
6880                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6881                );
6882                let res = err!(
6883                    self.builder
6884                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6885                );
6886                self.state.push1_extra(
6887                    res,
6888                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6889                );
6890            }
6891            Operator::F32x4Le => {
6892                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6893                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6894                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6895                let res = err!(
6896                    self.builder
6897                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6898                );
6899                let res = err!(
6900                    self.builder
6901                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6902                );
6903                let res = err!(
6904                    self.builder
6905                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6906                );
6907                self.state.push1(res);
6908            }
6909            Operator::F64x2Le => {
6910                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6911                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6912                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6913                let res = err!(
6914                    self.builder
6915                        .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6916                );
6917                let res = err!(
6918                    self.builder
6919                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6920                );
6921                let res = err!(
6922                    self.builder
6923                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6924                );
6925                self.state.push1(res);
6926            }
6927            Operator::F32Gt | Operator::F64Gt => {
6928                let (v1, v2) = self.state.pop2()?;
6929                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6930                let cond = err!(
6931                    self.builder
6932                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6933                );
6934                let res = err!(
6935                    self.builder
6936                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6937                );
6938                self.state.push1_extra(
6939                    res,
6940                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6941                );
6942            }
6943            Operator::F32x4Gt => {
6944                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6945                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6946                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6947                let res = err!(
6948                    self.builder
6949                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6950                );
6951                let res = err!(
6952                    self.builder
6953                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6954                );
6955                let res = err!(
6956                    self.builder
6957                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6958                );
6959                self.state.push1(res);
6960            }
6961            Operator::F64x2Gt => {
6962                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6963                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6964                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6965                let res = err!(
6966                    self.builder
6967                        .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6968                );
6969                let res = err!(
6970                    self.builder
6971                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6972                );
6973                let res = err!(
6974                    self.builder
6975                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
6976                );
6977                self.state.push1(res);
6978            }
6979            Operator::F32Ge | Operator::F64Ge => {
6980                let (v1, v2) = self.state.pop2()?;
6981                let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6982                let cond = err!(
6983                    self.builder
6984                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
6985                );
6986                let res = err!(
6987                    self.builder
6988                        .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6989                );
6990                self.state.push1_extra(
6991                    res,
6992                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6993                );
6994            }
6995            Operator::F32x4Ge => {
6996                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6997                let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6998                let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6999                let res = err!(
7000                    self.builder
7001                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7002                );
7003                let res = err!(
7004                    self.builder
7005                        .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7006                );
7007                let res = err!(
7008                    self.builder
7009                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7010                );
7011                self.state.push1(res);
7012            }
7013            Operator::F64x2Ge => {
7014                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7015                let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7016                let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7017                let res = err!(
7018                    self.builder
7019                        .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7020                );
7021                let res = err!(
7022                    self.builder
7023                        .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7024                );
7025                let res = err!(
7026                    self.builder
7027                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7028                );
7029                self.state.push1(res);
7030            }
7031
7032            /***************************
7033             * Conversion instructions.
7034             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#conversion-instructions
7035             ***************************/
7036            Operator::I32WrapI64 => {
7037                let (v, i) = self.state.pop1_extra()?;
7038                let v = self.apply_pending_canonicalization(v, i)?;
7039                let v = v.into_int_value();
7040                let res = err!(
7041                    self.builder
7042                        .build_int_truncate(v, self.intrinsics.i32_ty, "")
7043                );
7044                self.state.push1(res);
7045            }
7046            Operator::I64ExtendI32S => {
7047                let (v, i) = self.state.pop1_extra()?;
7048                let v = self.apply_pending_canonicalization(v, i)?;
7049                let v = v.into_int_value();
7050                let res = err!(
7051                    self.builder
7052                        .build_int_s_extend(v, self.intrinsics.i64_ty, "")
7053                );
7054                self.state.push1(res);
7055            }
7056            Operator::I64ExtendI32U => {
7057                let (v, i) = self.state.pop1_extra()?;
7058                let v = self.apply_pending_canonicalization(v, i)?;
7059                let v = v.into_int_value();
7060                let res = err!(
7061                    self.builder
7062                        .build_int_z_extend(v, self.intrinsics.i64_ty, "")
7063                );
7064                self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
7065            }
7066            Operator::I16x8ExtendLowI8x16S => {
7067                let (v, i) = self.state.pop1_extra()?;
7068                let (v, _) = self.v128_into_i8x16(v, i)?;
7069                let low = err!(self.builder.build_shuffle_vector(
7070                    v,
7071                    v.get_type().get_undef(),
7072                    VectorType::const_vector(&[
7073                        self.intrinsics.i32_consts[0],
7074                        self.intrinsics.i32_consts[1],
7075                        self.intrinsics.i32_consts[2],
7076                        self.intrinsics.i32_consts[3],
7077                        self.intrinsics.i32_consts[4],
7078                        self.intrinsics.i32_consts[5],
7079                        self.intrinsics.i32_consts[6],
7080                        self.intrinsics.i32_consts[7],
7081                    ]),
7082                    "",
7083                ));
7084                let res = err!(
7085                    self.builder
7086                        .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7087                );
7088                let res = err!(
7089                    self.builder
7090                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7091                );
7092                self.state.push1(res);
7093            }
7094            Operator::I16x8ExtendHighI8x16S => {
7095                let (v, i) = self.state.pop1_extra()?;
7096                let (v, _) = self.v128_into_i8x16(v, i)?;
7097                let low = err!(self.builder.build_shuffle_vector(
7098                    v,
7099                    v.get_type().get_undef(),
7100                    VectorType::const_vector(&[
7101                        self.intrinsics.i32_consts[8],
7102                        self.intrinsics.i32_consts[9],
7103                        self.intrinsics.i32_consts[10],
7104                        self.intrinsics.i32_consts[11],
7105                        self.intrinsics.i32_consts[12],
7106                        self.intrinsics.i32_consts[13],
7107                        self.intrinsics.i32_consts[14],
7108                        self.intrinsics.i32_consts[15],
7109                    ]),
7110                    "",
7111                ));
7112                let res = err!(
7113                    self.builder
7114                        .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7115                );
7116                let res = err!(
7117                    self.builder
7118                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7119                );
7120                self.state.push1(res);
7121            }
7122            Operator::I16x8ExtendLowI8x16U => {
7123                let (v, i) = self.state.pop1_extra()?;
7124                let (v, _) = self.v128_into_i8x16(v, i)?;
7125                let low = err!(self.builder.build_shuffle_vector(
7126                    v,
7127                    v.get_type().get_undef(),
7128                    VectorType::const_vector(&[
7129                        self.intrinsics.i32_consts[0],
7130                        self.intrinsics.i32_consts[1],
7131                        self.intrinsics.i32_consts[2],
7132                        self.intrinsics.i32_consts[3],
7133                        self.intrinsics.i32_consts[4],
7134                        self.intrinsics.i32_consts[5],
7135                        self.intrinsics.i32_consts[6],
7136                        self.intrinsics.i32_consts[7],
7137                    ]),
7138                    "",
7139                ));
7140                let res = err!(
7141                    self.builder
7142                        .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7143                );
7144                let res = err!(
7145                    self.builder
7146                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7147                );
7148                self.state.push1(res);
7149            }
7150            Operator::I16x8ExtendHighI8x16U => {
7151                let (v, i) = self.state.pop1_extra()?;
7152                let (v, _) = self.v128_into_i8x16(v, i)?;
7153                let low = err!(self.builder.build_shuffle_vector(
7154                    v,
7155                    v.get_type().get_undef(),
7156                    VectorType::const_vector(&[
7157                        self.intrinsics.i32_consts[8],
7158                        self.intrinsics.i32_consts[9],
7159                        self.intrinsics.i32_consts[10],
7160                        self.intrinsics.i32_consts[11],
7161                        self.intrinsics.i32_consts[12],
7162                        self.intrinsics.i32_consts[13],
7163                        self.intrinsics.i32_consts[14],
7164                        self.intrinsics.i32_consts[15],
7165                    ]),
7166                    "",
7167                ));
7168                let res = err!(
7169                    self.builder
7170                        .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7171                );
7172                let res = err!(
7173                    self.builder
7174                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7175                );
7176                self.state.push1(res);
7177            }
7178            Operator::I32x4ExtendLowI16x8S => {
7179                let (v, i) = self.state.pop1_extra()?;
7180                let (v, _) = self.v128_into_i16x8(v, i)?;
7181                let low = err!(self.builder.build_shuffle_vector(
7182                    v,
7183                    v.get_type().get_undef(),
7184                    VectorType::const_vector(&[
7185                        self.intrinsics.i32_consts[0],
7186                        self.intrinsics.i32_consts[1],
7187                        self.intrinsics.i32_consts[2],
7188                        self.intrinsics.i32_consts[3],
7189                    ]),
7190                    "",
7191                ));
7192                let res = err!(
7193                    self.builder
7194                        .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7195                );
7196                let res = err!(
7197                    self.builder
7198                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7199                );
7200                self.state.push1(res);
7201            }
7202            Operator::I32x4ExtendHighI16x8S => {
7203                let (v, i) = self.state.pop1_extra()?;
7204                let (v, _) = self.v128_into_i16x8(v, i)?;
7205                let low = err!(self.builder.build_shuffle_vector(
7206                    v,
7207                    v.get_type().get_undef(),
7208                    VectorType::const_vector(&[
7209                        self.intrinsics.i32_consts[4],
7210                        self.intrinsics.i32_consts[5],
7211                        self.intrinsics.i32_consts[6],
7212                        self.intrinsics.i32_consts[7],
7213                    ]),
7214                    "",
7215                ));
7216                let res = err!(
7217                    self.builder
7218                        .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7219                );
7220                let res = err!(
7221                    self.builder
7222                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7223                );
7224                self.state.push1(res);
7225            }
7226            Operator::I32x4ExtendLowI16x8U => {
7227                let (v, i) = self.state.pop1_extra()?;
7228                let (v, _) = self.v128_into_i16x8(v, i)?;
7229                let low = err!(self.builder.build_shuffle_vector(
7230                    v,
7231                    v.get_type().get_undef(),
7232                    VectorType::const_vector(&[
7233                        self.intrinsics.i32_consts[0],
7234                        self.intrinsics.i32_consts[1],
7235                        self.intrinsics.i32_consts[2],
7236                        self.intrinsics.i32_consts[3],
7237                    ]),
7238                    "",
7239                ));
7240                let res = err!(
7241                    self.builder
7242                        .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7243                );
7244                let res = err!(
7245                    self.builder
7246                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7247                );
7248                self.state.push1(res);
7249            }
7250            Operator::I32x4ExtendHighI16x8U => {
7251                let (v, i) = self.state.pop1_extra()?;
7252                let (v, _) = self.v128_into_i16x8(v, i)?;
7253                let low = err!(self.builder.build_shuffle_vector(
7254                    v,
7255                    v.get_type().get_undef(),
7256                    VectorType::const_vector(&[
7257                        self.intrinsics.i32_consts[4],
7258                        self.intrinsics.i32_consts[5],
7259                        self.intrinsics.i32_consts[6],
7260                        self.intrinsics.i32_consts[7],
7261                    ]),
7262                    "",
7263                ));
7264                let res = err!(
7265                    self.builder
7266                        .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7267                );
7268                let res = err!(
7269                    self.builder
7270                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7271                );
7272                self.state.push1(res);
7273            }
7274            Operator::I64x2ExtendLowI32x4U
7275            | Operator::I64x2ExtendLowI32x4S
7276            | Operator::I64x2ExtendHighI32x4U
7277            | Operator::I64x2ExtendHighI32x4S => {
7278                let extend = match op {
7279                    Operator::I64x2ExtendLowI32x4U | Operator::I64x2ExtendHighI32x4U => {
7280                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
7281                    }
7282                    Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendHighI32x4S => {
7283                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
7284                    }
7285                    _ => unreachable!("Unhandled inner case"),
7286                };
7287                let indices = match op {
7288                    Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendLowI32x4U => {
7289                        [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[1]]
7290                    }
7291                    Operator::I64x2ExtendHighI32x4S | Operator::I64x2ExtendHighI32x4U => {
7292                        [self.intrinsics.i32_consts[2], self.intrinsics.i32_consts[3]]
7293                    }
7294                    _ => unreachable!("Unhandled inner case"),
7295                };
7296                let (v, i) = self.state.pop1_extra()?;
7297                let (v, _) = self.v128_into_i32x4(v, i)?;
7298                let low = err!(self.builder.build_shuffle_vector(
7299                    v,
7300                    v.get_type().get_undef(),
7301                    VectorType::const_vector(&indices),
7302                    "",
7303                ));
7304                let res = err!(extend(self, low));
7305                let res = err!(
7306                    self.builder
7307                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7308                );
7309                self.state.push1(res);
7310            }
7311            Operator::I8x16NarrowI16x8S => {
7312                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7313                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7314                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7315                let min = self.intrinsics.i16_ty.const_int(0xff80, false);
7316                let max = self.intrinsics.i16_ty.const_int(0x007f, false);
7317                let min = VectorType::const_vector(&[min; 8]);
7318                let max = VectorType::const_vector(&[max; 8]);
7319                let apply_min_clamp_v1 =
7320                    err!(
7321                        self.builder
7322                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7323                    );
7324                let apply_max_clamp_v1 =
7325                    err!(
7326                        self.builder
7327                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7328                    );
7329                let apply_min_clamp_v2 =
7330                    err!(
7331                        self.builder
7332                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7333                    );
7334                let apply_max_clamp_v2 =
7335                    err!(
7336                        self.builder
7337                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7338                    );
7339                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7340                    .into_vector_value();
7341                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7342                    .into_vector_value();
7343                let v1 = err!(self.builder.build_int_truncate(
7344                    v1,
7345                    self.intrinsics.i8_ty.vec_type(8),
7346                    ""
7347                ));
7348                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7349                    .into_vector_value();
7350                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7351                    .into_vector_value();
7352                let v2 = err!(self.builder.build_int_truncate(
7353                    v2,
7354                    self.intrinsics.i8_ty.vec_type(8),
7355                    ""
7356                ));
7357                let res = err!(self.builder.build_shuffle_vector(
7358                    v1,
7359                    v2,
7360                    VectorType::const_vector(&[
7361                        self.intrinsics.i32_consts[0],
7362                        self.intrinsics.i32_consts[1],
7363                        self.intrinsics.i32_consts[2],
7364                        self.intrinsics.i32_consts[3],
7365                        self.intrinsics.i32_consts[4],
7366                        self.intrinsics.i32_consts[5],
7367                        self.intrinsics.i32_consts[6],
7368                        self.intrinsics.i32_consts[7],
7369                        self.intrinsics.i32_consts[8],
7370                        self.intrinsics.i32_consts[9],
7371                        self.intrinsics.i32_consts[10],
7372                        self.intrinsics.i32_consts[11],
7373                        self.intrinsics.i32_consts[12],
7374                        self.intrinsics.i32_consts[13],
7375                        self.intrinsics.i32_consts[14],
7376                        self.intrinsics.i32_consts[15],
7377                    ]),
7378                    "",
7379                ));
7380                let res = err!(
7381                    self.builder
7382                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7383                );
7384                self.state.push1(res);
7385            }
7386            Operator::I8x16NarrowI16x8U => {
7387                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7388                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7389                let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7390                let min = self.intrinsics.i16x8_ty.const_zero();
7391                let max = self.intrinsics.i16_ty.const_int(0x00ff, false);
7392                let max = VectorType::const_vector(&[max; 8]);
7393                let apply_min_clamp_v1 =
7394                    err!(
7395                        self.builder
7396                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7397                    );
7398                let apply_max_clamp_v1 =
7399                    err!(
7400                        self.builder
7401                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7402                    );
7403                let apply_min_clamp_v2 =
7404                    err!(
7405                        self.builder
7406                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7407                    );
7408                let apply_max_clamp_v2 =
7409                    err!(
7410                        self.builder
7411                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7412                    );
7413                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7414                    .into_vector_value();
7415                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7416                    .into_vector_value();
7417                let v1 = err!(self.builder.build_int_truncate(
7418                    v1,
7419                    self.intrinsics.i8_ty.vec_type(8),
7420                    ""
7421                ));
7422                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7423                    .into_vector_value();
7424                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7425                    .into_vector_value();
7426                let v2 = err!(self.builder.build_int_truncate(
7427                    v2,
7428                    self.intrinsics.i8_ty.vec_type(8),
7429                    ""
7430                ));
7431                let res = err!(self.builder.build_shuffle_vector(
7432                    v1,
7433                    v2,
7434                    VectorType::const_vector(&[
7435                        self.intrinsics.i32_consts[0],
7436                        self.intrinsics.i32_consts[1],
7437                        self.intrinsics.i32_consts[2],
7438                        self.intrinsics.i32_consts[3],
7439                        self.intrinsics.i32_consts[4],
7440                        self.intrinsics.i32_consts[5],
7441                        self.intrinsics.i32_consts[6],
7442                        self.intrinsics.i32_consts[7],
7443                        self.intrinsics.i32_consts[8],
7444                        self.intrinsics.i32_consts[9],
7445                        self.intrinsics.i32_consts[10],
7446                        self.intrinsics.i32_consts[11],
7447                        self.intrinsics.i32_consts[12],
7448                        self.intrinsics.i32_consts[13],
7449                        self.intrinsics.i32_consts[14],
7450                        self.intrinsics.i32_consts[15],
7451                    ]),
7452                    "",
7453                ));
7454                let res = err!(
7455                    self.builder
7456                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7457                );
7458                self.state.push1(res);
7459            }
7460            Operator::I16x8NarrowI32x4S => {
7461                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7462                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7463                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7464                let min = self.intrinsics.i32_ty.const_int(0xffff8000, false);
7465                let max = self.intrinsics.i32_ty.const_int(0x00007fff, false);
7466                let min = VectorType::const_vector(&[min; 4]);
7467                let max = VectorType::const_vector(&[max; 4]);
7468                let apply_min_clamp_v1 =
7469                    err!(
7470                        self.builder
7471                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7472                    );
7473                let apply_max_clamp_v1 =
7474                    err!(
7475                        self.builder
7476                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7477                    );
7478                let apply_min_clamp_v2 =
7479                    err!(
7480                        self.builder
7481                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7482                    );
7483                let apply_max_clamp_v2 =
7484                    err!(
7485                        self.builder
7486                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7487                    );
7488                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7489                    .into_vector_value();
7490                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7491                    .into_vector_value();
7492                let v1 = err!(self.builder.build_int_truncate(
7493                    v1,
7494                    self.intrinsics.i16_ty.vec_type(4),
7495                    ""
7496                ));
7497                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7498                    .into_vector_value();
7499                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7500                    .into_vector_value();
7501                let v2 = err!(self.builder.build_int_truncate(
7502                    v2,
7503                    self.intrinsics.i16_ty.vec_type(4),
7504                    ""
7505                ));
7506                let res = err!(self.builder.build_shuffle_vector(
7507                    v1,
7508                    v2,
7509                    VectorType::const_vector(&[
7510                        self.intrinsics.i32_consts[0],
7511                        self.intrinsics.i32_consts[1],
7512                        self.intrinsics.i32_consts[2],
7513                        self.intrinsics.i32_consts[3],
7514                        self.intrinsics.i32_consts[4],
7515                        self.intrinsics.i32_consts[5],
7516                        self.intrinsics.i32_consts[6],
7517                        self.intrinsics.i32_consts[7],
7518                    ]),
7519                    "",
7520                ));
7521                let res = err!(
7522                    self.builder
7523                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7524                );
7525                self.state.push1(res);
7526            }
7527            Operator::I16x8NarrowI32x4U => {
7528                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7529                let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7530                let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7531                let min = self.intrinsics.i32x4_ty.const_zero();
7532                let max = self.intrinsics.i32_ty.const_int(0xffff, false);
7533                let max = VectorType::const_vector(&[max; 4]);
7534                let apply_min_clamp_v1 =
7535                    err!(
7536                        self.builder
7537                            .build_int_compare(IntPredicate::SLT, v1, min, "")
7538                    );
7539                let apply_max_clamp_v1 =
7540                    err!(
7541                        self.builder
7542                            .build_int_compare(IntPredicate::SGT, v1, max, "")
7543                    );
7544                let apply_min_clamp_v2 =
7545                    err!(
7546                        self.builder
7547                            .build_int_compare(IntPredicate::SLT, v2, min, "")
7548                    );
7549                let apply_max_clamp_v2 =
7550                    err!(
7551                        self.builder
7552                            .build_int_compare(IntPredicate::SGT, v2, max, "")
7553                    );
7554                let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7555                    .into_vector_value();
7556                let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7557                    .into_vector_value();
7558                let v1 = err!(self.builder.build_int_truncate(
7559                    v1,
7560                    self.intrinsics.i16_ty.vec_type(4),
7561                    ""
7562                ));
7563                let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7564                    .into_vector_value();
7565                let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7566                    .into_vector_value();
7567                let v2 = err!(self.builder.build_int_truncate(
7568                    v2,
7569                    self.intrinsics.i16_ty.vec_type(4),
7570                    ""
7571                ));
7572                let res = err!(self.builder.build_shuffle_vector(
7573                    v1,
7574                    v2,
7575                    VectorType::const_vector(&[
7576                        self.intrinsics.i32_consts[0],
7577                        self.intrinsics.i32_consts[1],
7578                        self.intrinsics.i32_consts[2],
7579                        self.intrinsics.i32_consts[3],
7580                        self.intrinsics.i32_consts[4],
7581                        self.intrinsics.i32_consts[5],
7582                        self.intrinsics.i32_consts[6],
7583                        self.intrinsics.i32_consts[7],
7584                    ]),
7585                    "",
7586                ));
7587                let res = err!(
7588                    self.builder
7589                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7590                );
7591                self.state.push1(res);
7592            }
7593            Operator::I32x4TruncSatF32x4S => {
7594                let (v, i) = self.state.pop1_extra()?;
7595                let v = self.apply_pending_canonicalization(v, i)?;
7596                let v = v.into_int_value();
7597                let res = self.trunc_sat_into_int(
7598                    self.intrinsics.f32x4_ty,
7599                    self.intrinsics.i32x4_ty,
7600                    LEF32_GEQ_I32_MIN,
7601                    GEF32_LEQ_I32_MAX,
7602                    i32::MIN as u64,
7603                    i32::MAX as u64,
7604                    v,
7605                )?;
7606                self.state.push1(res);
7607            }
7608            Operator::I32x4TruncSatF32x4U => {
7609                let (v, i) = self.state.pop1_extra()?;
7610                let v = self.apply_pending_canonicalization(v, i)?;
7611                let v = v.into_int_value();
7612                let res = self.trunc_sat_into_int(
7613                    self.intrinsics.f32x4_ty,
7614                    self.intrinsics.i32x4_ty,
7615                    LEF32_GEQ_U32_MIN,
7616                    GEF32_LEQ_U32_MAX,
7617                    u32::MIN as u64,
7618                    u32::MAX as u64,
7619                    v,
7620                )?;
7621                self.state.push1(res);
7622            }
7623            Operator::I32x4TruncSatF64x2SZero | Operator::I32x4TruncSatF64x2UZero => {
7624                let ((min, max), (cmp_min, cmp_max)) = match op {
7625                    Operator::I32x4TruncSatF64x2SZero => (
7626                        (i32::MIN as u64, i32::MAX as u64),
7627                        (LEF64_GEQ_I32_MIN, GEF64_LEQ_I32_MAX),
7628                    ),
7629                    Operator::I32x4TruncSatF64x2UZero => (
7630                        (u32::MIN as u64, u32::MAX as u64),
7631                        (LEF64_GEQ_U32_MIN, GEF64_LEQ_U32_MAX),
7632                    ),
7633                    _ => unreachable!("Unhandled internal variant"),
7634                };
7635                let (v, i) = self.state.pop1_extra()?;
7636                let v = self.apply_pending_canonicalization(v, i)?;
7637                let v = v.into_int_value();
7638                let res = self.trunc_sat(
7639                    self.intrinsics.f64x2_ty,
7640                    self.intrinsics.i32_ty.vec_type(2),
7641                    cmp_min,
7642                    cmp_max,
7643                    min,
7644                    max,
7645                    v,
7646                )?;
7647
7648                let zero = self.intrinsics.i32_consts[0];
7649                let zeros = VectorType::const_vector(&[zero; 2]);
7650                let res = err!(self.builder.build_shuffle_vector(
7651                    res,
7652                    zeros,
7653                    VectorType::const_vector(&[
7654                        self.intrinsics.i32_consts[0],
7655                        self.intrinsics.i32_consts[1],
7656                        self.intrinsics.i32_consts[2],
7657                        self.intrinsics.i32_consts[3],
7658                    ]),
7659                    "",
7660                ));
7661                let res = err!(
7662                    self.builder
7663                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
7664                );
7665                self.state.push1(res);
7666            }
7667            // Operator::I64x2TruncSatF64x2S => {
7668            //     let (v, i) = self.state.pop1_extra()?;
7669            //     let v = self.apply_pending_canonicalization(v, i)?;
7670            //     let v = v.into_int_value();
7671            //     let res = self.trunc_sat_into_int(
7672            //         self.intrinsics.f64x2_ty,
7673            //         self.intrinsics.i64x2_ty,
7674            //         i64::MIN as u64,
7675            //         i64::MAX as u64,
7676            //         i64::MIN as u64,
7677            //         i64::MAX as u64,
7678            //         v,
7679            //     )?;
7680            //     self.state.push1(res);
7681            // }
7682            // Operator::I64x2TruncSatF64x2U => {
7683            //     let (v, i) = self.state.pop1_extra()?;
7684            //     let v = self.apply_pending_canonicalization(v, i)?;
7685            //     let v = v.into_int_value();
7686            //     let res = self.trunc_sat_into_int(
7687            //         self.intrinsics.f64x2_ty,
7688            //         self.intrinsics.i64x2_ty,
7689            //         u64::MIN,
7690            //         u64::MAX,
7691            //         u64::MIN,
7692            //         u64::MAX,
7693            //         v,
7694            //     )?;
7695            //     self.state.push1(res);
7696            // }
7697            Operator::I32TruncF32S => {
7698                let v1 = self.state.pop1()?.into_float_value();
7699                self.trap_if_not_representable_as_int(
7700                    0xcf000000, // -2147483600.0
7701                    0x4effffff, // 2147483500.0
7702                    v1,
7703                )?;
7704                let res = err!(self.builder.build_float_to_signed_int(
7705                    v1,
7706                    self.intrinsics.i32_ty,
7707                    ""
7708                ));
7709                self.state.push1(res);
7710            }
7711            Operator::I32TruncF64S => {
7712                let v1 = self.state.pop1()?.into_float_value();
7713                self.trap_if_not_representable_as_int(
7714                    0xc1e00000001fffff, // -2147483648.9999995
7715                    0x41dfffffffffffff, // 2147483647.9999998
7716                    v1,
7717                )?;
7718                let res = err!(self.builder.build_float_to_signed_int(
7719                    v1,
7720                    self.intrinsics.i32_ty,
7721                    ""
7722                ));
7723                self.state.push1(res);
7724            }
7725            Operator::I32TruncSatF32S => {
7726                let (v, i) = self.state.pop1_extra()?;
7727                let v = self.apply_pending_canonicalization(v, i)?;
7728                let v = v.into_float_value();
7729                let res = self.trunc_sat_scalar(
7730                    self.intrinsics.i32_ty,
7731                    LEF32_GEQ_I32_MIN,
7732                    GEF32_LEQ_I32_MAX,
7733                    i32::MIN as u32 as u64,
7734                    i32::MAX as u32 as u64,
7735                    v,
7736                )?;
7737                self.state.push1(res);
7738            }
7739            Operator::I32TruncSatF64S => {
7740                let (v, i) = self.state.pop1_extra()?;
7741                let v = self.apply_pending_canonicalization(v, i)?;
7742                let v = v.into_float_value();
7743                let res = self.trunc_sat_scalar(
7744                    self.intrinsics.i32_ty,
7745                    LEF64_GEQ_I32_MIN,
7746                    GEF64_LEQ_I32_MAX,
7747                    i32::MIN as u64,
7748                    i32::MAX as u64,
7749                    v,
7750                )?;
7751                self.state.push1(res);
7752            }
7753            Operator::I64TruncF32S => {
7754                let v1 = self.state.pop1()?.into_float_value();
7755                self.trap_if_not_representable_as_int(
7756                    0xdf000000, // -9223372000000000000.0
7757                    0x5effffff, // 9223371500000000000.0
7758                    v1,
7759                )?;
7760                let res = err!(self.builder.build_float_to_signed_int(
7761                    v1,
7762                    self.intrinsics.i64_ty,
7763                    ""
7764                ));
7765                self.state.push1(res);
7766            }
7767            Operator::I64TruncF64S => {
7768                let v1 = self.state.pop1()?.into_float_value();
7769                self.trap_if_not_representable_as_int(
7770                    0xc3e0000000000000, // -9223372036854776000.0
7771                    0x43dfffffffffffff, // 9223372036854775000.0
7772                    v1,
7773                )?;
7774                let res = err!(self.builder.build_float_to_signed_int(
7775                    v1,
7776                    self.intrinsics.i64_ty,
7777                    ""
7778                ));
7779                self.state.push1(res);
7780            }
7781            Operator::I64TruncSatF32S => {
7782                let (v, i) = self.state.pop1_extra()?;
7783                let v = self.apply_pending_canonicalization(v, i)?;
7784                let v = v.into_float_value();
7785                let res = self.trunc_sat_scalar(
7786                    self.intrinsics.i64_ty,
7787                    LEF32_GEQ_I64_MIN,
7788                    GEF32_LEQ_I64_MAX,
7789                    i64::MIN as u64,
7790                    i64::MAX as u64,
7791                    v,
7792                )?;
7793                self.state.push1(res);
7794            }
7795            Operator::I64TruncSatF64S => {
7796                let (v, i) = self.state.pop1_extra()?;
7797                let v = self.apply_pending_canonicalization(v, i)?;
7798                let v = v.into_float_value();
7799                let res = self.trunc_sat_scalar(
7800                    self.intrinsics.i64_ty,
7801                    LEF64_GEQ_I64_MIN,
7802                    GEF64_LEQ_I64_MAX,
7803                    i64::MIN as u64,
7804                    i64::MAX as u64,
7805                    v,
7806                )?;
7807                self.state.push1(res);
7808            }
7809            Operator::I32TruncF32U => {
7810                let v1 = self.state.pop1()?.into_float_value();
7811                self.trap_if_not_representable_as_int(
7812                    0xbf7fffff, // -0.99999994
7813                    0x4f7fffff, // 4294967000.0
7814                    v1,
7815                )?;
7816                let res = err!(self.builder.build_float_to_unsigned_int(
7817                    v1,
7818                    self.intrinsics.i32_ty,
7819                    ""
7820                ));
7821                self.state.push1(res);
7822            }
7823            Operator::I32TruncF64U => {
7824                let v1 = self.state.pop1()?.into_float_value();
7825                self.trap_if_not_representable_as_int(
7826                    0xbfefffffffffffff, // -0.9999999999999999
7827                    0x41efffffffffffff, // 4294967295.9999995
7828                    v1,
7829                )?;
7830                let res = err!(self.builder.build_float_to_unsigned_int(
7831                    v1,
7832                    self.intrinsics.i32_ty,
7833                    ""
7834                ));
7835                self.state.push1(res);
7836            }
7837            Operator::I32TruncSatF32U => {
7838                let (v, i) = self.state.pop1_extra()?;
7839                let v = self.apply_pending_canonicalization(v, i)?;
7840                let v = v.into_float_value();
7841                let res = self.trunc_sat_scalar(
7842                    self.intrinsics.i32_ty,
7843                    LEF32_GEQ_U32_MIN,
7844                    GEF32_LEQ_U32_MAX,
7845                    u32::MIN as u64,
7846                    u32::MAX as u64,
7847                    v,
7848                )?;
7849                self.state.push1(res);
7850            }
7851            Operator::I32TruncSatF64U => {
7852                let (v, i) = self.state.pop1_extra()?;
7853                let v = self.apply_pending_canonicalization(v, i)?;
7854                let v = v.into_float_value();
7855                let res = self.trunc_sat_scalar(
7856                    self.intrinsics.i32_ty,
7857                    LEF64_GEQ_U32_MIN,
7858                    GEF64_LEQ_U32_MAX,
7859                    u32::MIN as u64,
7860                    u32::MAX as u64,
7861                    v,
7862                )?;
7863                self.state.push1(res);
7864            }
7865            Operator::I64TruncF32U => {
7866                let v1 = self.state.pop1()?.into_float_value();
7867                self.trap_if_not_representable_as_int(
7868                    0xbf7fffff, // -0.99999994
7869                    0x5f7fffff, // 18446743000000000000.0
7870                    v1,
7871                )?;
7872                let res = err!(self.builder.build_float_to_unsigned_int(
7873                    v1,
7874                    self.intrinsics.i64_ty,
7875                    ""
7876                ));
7877                self.state.push1(res);
7878            }
7879            Operator::I64TruncF64U => {
7880                let v1 = self.state.pop1()?.into_float_value();
7881                self.trap_if_not_representable_as_int(
7882                    0xbfefffffffffffff, // -0.9999999999999999
7883                    0x43efffffffffffff, // 18446744073709550000.0
7884                    v1,
7885                )?;
7886                let res = err!(self.builder.build_float_to_unsigned_int(
7887                    v1,
7888                    self.intrinsics.i64_ty,
7889                    ""
7890                ));
7891                self.state.push1(res);
7892            }
7893            Operator::I64TruncSatF32U => {
7894                let (v, i) = self.state.pop1_extra()?;
7895                let v = self.apply_pending_canonicalization(v, i)?;
7896                let v = v.into_float_value();
7897                let res = self.trunc_sat_scalar(
7898                    self.intrinsics.i64_ty,
7899                    LEF32_GEQ_U64_MIN,
7900                    GEF32_LEQ_U64_MAX,
7901                    u64::MIN,
7902                    u64::MAX,
7903                    v,
7904                )?;
7905                self.state.push1(res);
7906            }
7907            Operator::I64TruncSatF64U => {
7908                let (v, i) = self.state.pop1_extra()?;
7909                let v = self.apply_pending_canonicalization(v, i)?;
7910                let v = v.into_float_value();
7911                let res = self.trunc_sat_scalar(
7912                    self.intrinsics.i64_ty,
7913                    LEF64_GEQ_U64_MIN,
7914                    GEF64_LEQ_U64_MAX,
7915                    u64::MIN,
7916                    u64::MAX,
7917                    v,
7918                )?;
7919                self.state.push1(res);
7920            }
7921            Operator::F32DemoteF64 => {
7922                let v = self.state.pop1()?;
7923                let v = v.into_float_value();
7924                let res = err!(self.builder.build_call(
7925                    self.intrinsics.fptrunc_f64,
7926                    &[
7927                        v.into(),
7928                        self.intrinsics.fp_rounding_md,
7929                        self.intrinsics.fp_exception_md,
7930                    ],
7931                    "",
7932                ))
7933                .try_as_basic_value()
7934                .unwrap_basic();
7935                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
7936            }
7937            Operator::F64PromoteF32 => {
7938                let v = self.state.pop1()?;
7939                let v = v.into_float_value();
7940                let res = err!(self.builder.build_call(
7941                    self.intrinsics.fpext_f32,
7942                    &[v.into(), self.intrinsics.fp_exception_md],
7943                    "",
7944                ))
7945                .try_as_basic_value()
7946                .unwrap_basic();
7947                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
7948            }
7949            Operator::F32ConvertI32S | Operator::F32ConvertI64S => {
7950                let (v, i) = self.state.pop1_extra()?;
7951                let v = self.apply_pending_canonicalization(v, i)?;
7952                let v = v.into_int_value();
7953                let res = err!(self.builder.build_signed_int_to_float(
7954                    v,
7955                    self.intrinsics.f32_ty,
7956                    ""
7957                ));
7958                self.state.push1(res);
7959            }
7960            Operator::F64ConvertI32S | Operator::F64ConvertI64S => {
7961                let (v, i) = self.state.pop1_extra()?;
7962                let v = self.apply_pending_canonicalization(v, i)?;
7963                let v = v.into_int_value();
7964                let res = err!(self.builder.build_signed_int_to_float(
7965                    v,
7966                    self.intrinsics.f64_ty,
7967                    ""
7968                ));
7969                self.state.push1(res);
7970            }
7971            Operator::F32ConvertI32U | Operator::F32ConvertI64U => {
7972                let (v, i) = self.state.pop1_extra()?;
7973                let v = self.apply_pending_canonicalization(v, i)?;
7974                let v = v.into_int_value();
7975                let res = err!(self.builder.build_unsigned_int_to_float(
7976                    v,
7977                    self.intrinsics.f32_ty,
7978                    ""
7979                ));
7980                self.state.push1(res);
7981            }
7982            Operator::F64ConvertI32U | Operator::F64ConvertI64U => {
7983                let (v, i) = self.state.pop1_extra()?;
7984                let v = self.apply_pending_canonicalization(v, i)?;
7985                let v = v.into_int_value();
7986                let res = err!(self.builder.build_unsigned_int_to_float(
7987                    v,
7988                    self.intrinsics.f64_ty,
7989                    ""
7990                ));
7991                self.state.push1(res);
7992            }
7993            Operator::F32x4ConvertI32x4S => {
7994                let v = self.state.pop1()?;
7995                let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
7996                    .into_vector_value();
7997                let res = err!(self.builder.build_signed_int_to_float(
7998                    v,
7999                    self.intrinsics.f32x4_ty,
8000                    ""
8001                ));
8002                let res = err!(
8003                    self.builder
8004                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8005                );
8006                self.state.push1(res);
8007            }
8008            Operator::F32x4ConvertI32x4U => {
8009                let v = self.state.pop1()?;
8010                let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8011                    .into_vector_value();
8012                let res = err!(self.builder.build_unsigned_int_to_float(
8013                    v,
8014                    self.intrinsics.f32x4_ty,
8015                    ""
8016                ));
8017                let res = err!(
8018                    self.builder
8019                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8020                );
8021                self.state.push1(res);
8022            }
8023            Operator::F64x2ConvertLowI32x4S | Operator::F64x2ConvertLowI32x4U => {
8024                let extend = match op {
8025                    Operator::F64x2ConvertLowI32x4U => {
8026                        |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8027                    }
8028                    Operator::F64x2ConvertLowI32x4S => {
8029                        |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8030                    }
8031                    _ => unreachable!("Unhandled inner case"),
8032                };
8033                let (v, i) = self.state.pop1_extra()?;
8034                let (v, _) = self.v128_into_i32x4(v, i)?;
8035                let low = err!(self.builder.build_shuffle_vector(
8036                    v,
8037                    v.get_type().get_undef(),
8038                    VectorType::const_vector(&[
8039                        self.intrinsics.i32_consts[0],
8040                        self.intrinsics.i32_consts[1],
8041                    ]),
8042                    "",
8043                ));
8044                let res = err!(extend(self, low));
8045                let res = err!(self.builder.build_signed_int_to_float(
8046                    res,
8047                    self.intrinsics.f64x2_ty,
8048                    ""
8049                ));
8050                let res = err!(
8051                    self.builder
8052                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8053                );
8054                self.state.push1(res);
8055            }
8056            Operator::F64x2PromoteLowF32x4 => {
8057                let (v, i) = self.state.pop1_extra()?;
8058                let (v, _) = self.v128_into_f32x4(v, i)?;
8059                let low = err!(self.builder.build_shuffle_vector(
8060                    v,
8061                    v.get_type().get_undef(),
8062                    VectorType::const_vector(&[
8063                        self.intrinsics.i32_consts[0],
8064                        self.intrinsics.i32_consts[1],
8065                    ]),
8066                    "",
8067                ));
8068                let res = err!(
8069                    self.builder
8070                        .build_float_ext(low, self.intrinsics.f64x2_ty, "")
8071                );
8072                let res = err!(
8073                    self.builder
8074                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8075                );
8076                self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8077            }
8078            Operator::F32x4DemoteF64x2Zero => {
8079                let (v, i) = self.state.pop1_extra()?;
8080                let (v, _) = self.v128_into_f64x2(v, i)?;
8081                let f32x2_ty = self.intrinsics.f32_ty.vec_type(2);
8082                let res = err!(self.builder.build_float_trunc(v, f32x2_ty, ""));
8083                let zeros = f32x2_ty.const_zero();
8084                let res = err!(self.builder.build_shuffle_vector(
8085                    res,
8086                    zeros,
8087                    VectorType::const_vector(&[
8088                        self.intrinsics.i32_consts[0],
8089                        self.intrinsics.i32_consts[1],
8090                        self.intrinsics.i32_consts[2],
8091                        self.intrinsics.i32_consts[3],
8092                    ]),
8093                    "",
8094                ));
8095                let res = err!(
8096                    self.builder
8097                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8098                );
8099                self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8100            }
8101            // Operator::F64x2ConvertI64x2S => {
8102            //     let v = self.state.pop1()?;
8103            //     let v = self
8104            //         .builder
8105            //         .build_bit_cast(v, self.intrinsics.i64x2_ty, "")
8106            //         .into_vector_value();
8107            //     let res = self
8108            //         .builder
8109            //         .build_signed_int_to_float(v, self.intrinsics.f64x2_ty, "");
8110            //     let res = chck_err!(self.builder.build_bit_cast(res, self.intrinsics.i128_ty, ""));
8111            //     self.state.push1(res);
8112            // }
8113            // Operator::F64x2ConvertI64x2U => {
8114            //     let v = self.state.pop1()?;
8115            //     let v = self
8116            //         .builder
8117            //         .build_bit_cast(v, self.intrinsics.i64x2_ty, "")
8118            //         .into_vector_value();
8119            //     let res = self
8120            //         .builder
8121            //         .build_unsigned_int_to_float(v, self.intrinsics.f64x2_ty, "");
8122            //     let res = chck_err!(self.builder.build_bit_cast(res, self.intrinsics.i128_ty, ""));
8123            //     self.state.push1(res);
8124            // }
8125            Operator::I32ReinterpretF32 => {
8126                let (v, i) = self.state.pop1_extra()?;
8127                let v = self.apply_pending_canonicalization(v, i)?;
8128                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i32_ty, ""));
8129                self.state.push1_extra(ret, ExtraInfo::arithmetic_f32());
8130            }
8131            Operator::I64ReinterpretF64 => {
8132                let (v, i) = self.state.pop1_extra()?;
8133                let v = self.apply_pending_canonicalization(v, i)?;
8134                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i64_ty, ""));
8135                self.state.push1_extra(ret, ExtraInfo::arithmetic_f64());
8136            }
8137            Operator::F32ReinterpretI32 => {
8138                let (v, i) = self.state.pop1_extra()?;
8139                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f32_ty, ""));
8140                self.state.push1_extra(ret, i);
8141            }
8142            Operator::F64ReinterpretI64 => {
8143                let (v, i) = self.state.pop1_extra()?;
8144                let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f64_ty, ""));
8145                self.state.push1_extra(ret, i);
8146            }
8147
8148            /***************************
8149             * Sign-extension operators.
8150             * https://github.com/WebAssembly/sign-extension-ops/blob/master/proposals/sign-extension-ops/Overview.md
8151             ***************************/
8152            Operator::I32Extend8S => {
8153                let value = self.state.pop1()?.into_int_value();
8154                let narrow_value = err!(self.builder.build_int_truncate(
8155                    value,
8156                    self.intrinsics.i8_ty,
8157                    ""
8158                ));
8159                let extended_value = err!(self.builder.build_int_s_extend(
8160                    narrow_value,
8161                    self.intrinsics.i32_ty,
8162                    ""
8163                ));
8164                self.state.push1(extended_value);
8165            }
8166            Operator::I32Extend16S => {
8167                let value = self.state.pop1()?.into_int_value();
8168                let narrow_value = err!(self.builder.build_int_truncate(
8169                    value,
8170                    self.intrinsics.i16_ty,
8171                    ""
8172                ));
8173                let extended_value = err!(self.builder.build_int_s_extend(
8174                    narrow_value,
8175                    self.intrinsics.i32_ty,
8176                    ""
8177                ));
8178                self.state.push1(extended_value);
8179            }
8180            Operator::I64Extend8S => {
8181                let value = self.state.pop1()?.into_int_value();
8182                let narrow_value = err!(self.builder.build_int_truncate(
8183                    value,
8184                    self.intrinsics.i8_ty,
8185                    ""
8186                ));
8187                let extended_value = err!(self.builder.build_int_s_extend(
8188                    narrow_value,
8189                    self.intrinsics.i64_ty,
8190                    ""
8191                ));
8192                self.state.push1(extended_value);
8193            }
8194            Operator::I64Extend16S => {
8195                let value = self.state.pop1()?.into_int_value();
8196                let narrow_value = err!(self.builder.build_int_truncate(
8197                    value,
8198                    self.intrinsics.i16_ty,
8199                    ""
8200                ));
8201                let extended_value = err!(self.builder.build_int_s_extend(
8202                    narrow_value,
8203                    self.intrinsics.i64_ty,
8204                    ""
8205                ));
8206                self.state.push1(extended_value);
8207            }
8208            Operator::I64Extend32S => {
8209                let value = self.state.pop1()?.into_int_value();
8210                let narrow_value = err!(self.builder.build_int_truncate(
8211                    value,
8212                    self.intrinsics.i32_ty,
8213                    ""
8214                ));
8215                let extended_value = err!(self.builder.build_int_s_extend(
8216                    narrow_value,
8217                    self.intrinsics.i64_ty,
8218                    ""
8219                ));
8220                self.state.push1(extended_value);
8221            }
8222
8223            /***************************
8224             * Load and Store instructions.
8225             * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#load-and-store-instructions
8226             ***************************/
8227            Operator::I32Load { ref memarg } => {
8228                let offset = self.state.pop1()?.into_int_value();
8229                let memory_index = MemoryIndex::from_u32(0);
8230                let effective_address = self.resolve_memory_ptr(
8231                    memory_index,
8232                    memarg,
8233                    self.intrinsics.ptr_ty,
8234                    offset,
8235                    4,
8236                )?;
8237                let result = err!(self.builder.build_load(
8238                    self.intrinsics.i32_ty,
8239                    effective_address,
8240                    ""
8241                ));
8242                self.annotate_user_memaccess(
8243                    memory_index,
8244                    memarg,
8245                    1,
8246                    result.as_instruction_value().unwrap(),
8247                )?;
8248                self.state.push1(result);
8249            }
8250            Operator::I64Load { ref memarg } => {
8251                let offset = self.state.pop1()?.into_int_value();
8252                let memory_index = MemoryIndex::from_u32(0);
8253                let effective_address = self.resolve_memory_ptr(
8254                    memory_index,
8255                    memarg,
8256                    self.intrinsics.ptr_ty,
8257                    offset,
8258                    8,
8259                )?;
8260                let result = err!(self.builder.build_load(
8261                    self.intrinsics.i64_ty,
8262                    effective_address,
8263                    ""
8264                ));
8265                self.annotate_user_memaccess(
8266                    memory_index,
8267                    memarg,
8268                    1,
8269                    result.as_instruction_value().unwrap(),
8270                )?;
8271                self.state.push1(result);
8272            }
8273            Operator::F32Load { ref memarg } => {
8274                let offset = self.state.pop1()?.into_int_value();
8275                let memory_index = MemoryIndex::from_u32(0);
8276                let effective_address = self.resolve_memory_ptr(
8277                    memory_index,
8278                    memarg,
8279                    self.intrinsics.ptr_ty,
8280                    offset,
8281                    4,
8282                )?;
8283                let result = err!(self.builder.build_load(
8284                    self.intrinsics.f32_ty,
8285                    effective_address,
8286                    ""
8287                ));
8288                self.annotate_user_memaccess(
8289                    memory_index,
8290                    memarg,
8291                    1,
8292                    result.as_instruction_value().unwrap(),
8293                )?;
8294                self.state.push1(result);
8295            }
8296            Operator::F64Load { ref memarg } => {
8297                let offset = self.state.pop1()?.into_int_value();
8298                let memory_index = MemoryIndex::from_u32(0);
8299                let effective_address = self.resolve_memory_ptr(
8300                    memory_index,
8301                    memarg,
8302                    self.intrinsics.ptr_ty,
8303                    offset,
8304                    8,
8305                )?;
8306                let result = err!(self.builder.build_load(
8307                    self.intrinsics.f64_ty,
8308                    effective_address,
8309                    ""
8310                ));
8311                self.annotate_user_memaccess(
8312                    memory_index,
8313                    memarg,
8314                    1,
8315                    result.as_instruction_value().unwrap(),
8316                )?;
8317                self.state.push1(result);
8318            }
8319            Operator::V128Load { ref memarg } => {
8320                let offset = self.state.pop1()?.into_int_value();
8321                let memory_index = MemoryIndex::from_u32(0);
8322                let effective_address = self.resolve_memory_ptr(
8323                    memory_index,
8324                    memarg,
8325                    self.intrinsics.ptr_ty,
8326                    offset,
8327                    16,
8328                )?;
8329                let result = err!(self.builder.build_load(
8330                    self.intrinsics.i128_ty,
8331                    effective_address,
8332                    ""
8333                ));
8334                self.annotate_user_memaccess(
8335                    memory_index,
8336                    memarg,
8337                    1,
8338                    result.as_instruction_value().unwrap(),
8339                )?;
8340                self.state.push1(result);
8341            }
8342            Operator::V128Load8Lane { ref memarg, lane } => {
8343                let (v, i) = self.state.pop1_extra()?;
8344                let (v, _i) = self.v128_into_i8x16(v, i)?;
8345                let offset = self.state.pop1()?.into_int_value();
8346                let memory_index = MemoryIndex::from_u32(memarg.memory);
8347                let effective_address = self.resolve_memory_ptr(
8348                    memory_index,
8349                    memarg,
8350                    self.intrinsics.ptr_ty,
8351                    offset,
8352                    1,
8353                )?;
8354                let element = err!(self.builder.build_load(
8355                    self.intrinsics.i8_ty,
8356                    effective_address,
8357                    ""
8358                ));
8359                self.annotate_user_memaccess(
8360                    memory_index,
8361                    memarg,
8362                    1,
8363                    element.as_instruction_value().unwrap(),
8364                )?;
8365                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8366                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8367                let res = err!(
8368                    self.builder
8369                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8370                );
8371                self.state.push1(res);
8372            }
8373            Operator::V128Load16Lane { ref memarg, lane } => {
8374                let (v, i) = self.state.pop1_extra()?;
8375                let (v, i) = self.v128_into_i16x8(v, i)?;
8376                let offset = self.state.pop1()?.into_int_value();
8377                let memory_index = MemoryIndex::from_u32(memarg.memory);
8378                let effective_address = self.resolve_memory_ptr(
8379                    memory_index,
8380                    memarg,
8381                    self.intrinsics.ptr_ty,
8382                    offset,
8383                    2,
8384                )?;
8385                let element = err!(self.builder.build_load(
8386                    self.intrinsics.i16_ty,
8387                    effective_address,
8388                    ""
8389                ));
8390                self.annotate_user_memaccess(
8391                    memory_index,
8392                    memarg,
8393                    1,
8394                    element.as_instruction_value().unwrap(),
8395                )?;
8396                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8397                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8398                let res = err!(
8399                    self.builder
8400                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8401                );
8402                self.state.push1_extra(res, i);
8403            }
8404            Operator::V128Load32Lane { ref memarg, lane } => {
8405                let (v, i) = self.state.pop1_extra()?;
8406                let (v, i) = self.v128_into_i32x4(v, i)?;
8407                let offset = self.state.pop1()?.into_int_value();
8408                let memory_index = MemoryIndex::from_u32(memarg.memory);
8409                let effective_address = self.resolve_memory_ptr(
8410                    memory_index,
8411                    memarg,
8412                    self.intrinsics.ptr_ty,
8413                    offset,
8414                    4,
8415                )?;
8416                let element = err!(self.builder.build_load(
8417                    self.intrinsics.i32_ty,
8418                    effective_address,
8419                    ""
8420                ));
8421                self.annotate_user_memaccess(
8422                    memory_index,
8423                    memarg,
8424                    1,
8425                    element.as_instruction_value().unwrap(),
8426                )?;
8427                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8428                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8429                let res = err!(
8430                    self.builder
8431                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8432                );
8433                self.state.push1_extra(res, i);
8434            }
8435            Operator::V128Load64Lane { ref memarg, lane } => {
8436                let (v, i) = self.state.pop1_extra()?;
8437                let (v, i) = self.v128_into_i64x2(v, i)?;
8438                let offset = self.state.pop1()?.into_int_value();
8439                let memory_index = MemoryIndex::from_u32(memarg.memory);
8440                let effective_address = self.resolve_memory_ptr(
8441                    memory_index,
8442                    memarg,
8443                    self.intrinsics.ptr_ty,
8444                    offset,
8445                    8,
8446                )?;
8447                let element = err!(self.builder.build_load(
8448                    self.intrinsics.i64_ty,
8449                    effective_address,
8450                    ""
8451                ));
8452                self.annotate_user_memaccess(
8453                    memory_index,
8454                    memarg,
8455                    1,
8456                    element.as_instruction_value().unwrap(),
8457                )?;
8458                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8459                let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8460                let res = err!(
8461                    self.builder
8462                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
8463                );
8464                self.state.push1_extra(res, i);
8465            }
8466
8467            Operator::I32Store { ref memarg } => {
8468                let value = self.state.pop1()?;
8469                let offset = self.state.pop1()?.into_int_value();
8470                let memory_index = MemoryIndex::from_u32(0);
8471                let effective_address = self.resolve_memory_ptr(
8472                    memory_index,
8473                    memarg,
8474                    self.intrinsics.ptr_ty,
8475                    offset,
8476                    4,
8477                )?;
8478                let dead_load = err!(self.builder.build_load(
8479                    self.intrinsics.i32_ty,
8480                    effective_address,
8481                    ""
8482                ));
8483                self.annotate_user_memaccess(
8484                    memory_index,
8485                    memarg,
8486                    1,
8487                    dead_load.as_instruction_value().unwrap(),
8488                )?;
8489                let store = err!(self.builder.build_store(effective_address, value));
8490                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8491            }
8492            Operator::I64Store { ref memarg } => {
8493                let value = self.state.pop1()?;
8494                let offset = self.state.pop1()?.into_int_value();
8495                let memory_index = MemoryIndex::from_u32(0);
8496                let effective_address = self.resolve_memory_ptr(
8497                    memory_index,
8498                    memarg,
8499                    self.intrinsics.ptr_ty,
8500                    offset,
8501                    8,
8502                )?;
8503                let dead_load = err!(self.builder.build_load(
8504                    self.intrinsics.i64_ty,
8505                    effective_address,
8506                    ""
8507                ));
8508                self.annotate_user_memaccess(
8509                    memory_index,
8510                    memarg,
8511                    1,
8512                    dead_load.as_instruction_value().unwrap(),
8513                )?;
8514                let store = err!(self.builder.build_store(effective_address, value));
8515                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8516            }
8517            Operator::F32Store { ref memarg } => {
8518                let (v, i) = self.state.pop1_extra()?;
8519                let v = self.apply_pending_canonicalization(v, i)?;
8520                let offset = self.state.pop1()?.into_int_value();
8521                let memory_index = MemoryIndex::from_u32(0);
8522                let effective_address = self.resolve_memory_ptr(
8523                    memory_index,
8524                    memarg,
8525                    self.intrinsics.ptr_ty,
8526                    offset,
8527                    4,
8528                )?;
8529                let dead_load = err!(self.builder.build_load(
8530                    self.intrinsics.f32_ty,
8531                    effective_address,
8532                    ""
8533                ));
8534                self.annotate_user_memaccess(
8535                    memory_index,
8536                    memarg,
8537                    1,
8538                    dead_load.as_instruction_value().unwrap(),
8539                )?;
8540                let store = err!(self.builder.build_store(effective_address, v));
8541                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8542            }
8543            Operator::F64Store { ref memarg } => {
8544                let (v, i) = self.state.pop1_extra()?;
8545                let v = self.apply_pending_canonicalization(v, i)?;
8546                let offset = self.state.pop1()?.into_int_value();
8547                let memory_index = MemoryIndex::from_u32(0);
8548                let effective_address = self.resolve_memory_ptr(
8549                    memory_index,
8550                    memarg,
8551                    self.intrinsics.ptr_ty,
8552                    offset,
8553                    8,
8554                )?;
8555                let dead_load = err!(self.builder.build_load(
8556                    self.intrinsics.f64_ty,
8557                    effective_address,
8558                    ""
8559                ));
8560                self.annotate_user_memaccess(
8561                    memory_index,
8562                    memarg,
8563                    1,
8564                    dead_load.as_instruction_value().unwrap(),
8565                )?;
8566                let store = err!(self.builder.build_store(effective_address, v));
8567                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8568            }
8569            Operator::V128Store { ref memarg } => {
8570                let (v, i) = self.state.pop1_extra()?;
8571                let v = self.apply_pending_canonicalization(v, i)?;
8572                let offset = self.state.pop1()?.into_int_value();
8573                let memory_index = MemoryIndex::from_u32(0);
8574                let effective_address = self.resolve_memory_ptr(
8575                    memory_index,
8576                    memarg,
8577                    self.intrinsics.ptr_ty,
8578                    offset,
8579                    16,
8580                )?;
8581                let dead_load = err!(self.builder.build_load(
8582                    self.intrinsics.i128_ty,
8583                    effective_address,
8584                    ""
8585                ));
8586                self.annotate_user_memaccess(
8587                    memory_index,
8588                    memarg,
8589                    1,
8590                    dead_load.as_instruction_value().unwrap(),
8591                )?;
8592                let store = err!(self.builder.build_store(effective_address, v));
8593                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8594            }
8595            Operator::V128Store8Lane { ref memarg, lane } => {
8596                let (v, i) = self.state.pop1_extra()?;
8597                let (v, _i) = self.v128_into_i8x16(v, i)?;
8598                let offset = self.state.pop1()?.into_int_value();
8599                let memory_index = MemoryIndex::from_u32(memarg.memory);
8600
8601                let effective_address = self.resolve_memory_ptr(
8602                    memory_index,
8603                    memarg,
8604                    self.intrinsics.ptr_ty,
8605                    offset,
8606                    1,
8607                )?;
8608                let dead_load = err!(self.builder.build_load(
8609                    self.intrinsics.i8_ty,
8610                    effective_address,
8611                    ""
8612                ));
8613                self.annotate_user_memaccess(
8614                    memory_index,
8615                    memarg,
8616                    1,
8617                    dead_load.as_instruction_value().unwrap(),
8618                )?;
8619                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8620                let val = err!(self.builder.build_extract_element(v, idx, ""));
8621                let store = err!(self.builder.build_store(effective_address, val));
8622                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8623            }
8624            Operator::V128Store16Lane { ref memarg, lane } => {
8625                let (v, i) = self.state.pop1_extra()?;
8626                let (v, _i) = self.v128_into_i16x8(v, i)?;
8627                let offset = self.state.pop1()?.into_int_value();
8628                let memory_index = MemoryIndex::from_u32(memarg.memory);
8629
8630                let effective_address = self.resolve_memory_ptr(
8631                    memory_index,
8632                    memarg,
8633                    self.intrinsics.ptr_ty,
8634                    offset,
8635                    2,
8636                )?;
8637                let dead_load = err!(self.builder.build_load(
8638                    self.intrinsics.i16_ty,
8639                    effective_address,
8640                    ""
8641                ));
8642                self.annotate_user_memaccess(
8643                    memory_index,
8644                    memarg,
8645                    1,
8646                    dead_load.as_instruction_value().unwrap(),
8647                )?;
8648                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8649                let val = err!(self.builder.build_extract_element(v, idx, ""));
8650                let store = err!(self.builder.build_store(effective_address, val));
8651                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8652            }
8653            Operator::V128Store32Lane { ref memarg, lane } => {
8654                let (v, i) = self.state.pop1_extra()?;
8655                let (v, _i) = self.v128_into_i32x4(v, i)?;
8656                let offset = self.state.pop1()?.into_int_value();
8657                let memory_index = MemoryIndex::from_u32(memarg.memory);
8658
8659                let effective_address = self.resolve_memory_ptr(
8660                    memory_index,
8661                    memarg,
8662                    self.intrinsics.ptr_ty,
8663                    offset,
8664                    4,
8665                )?;
8666                let dead_load = err!(self.builder.build_load(
8667                    self.intrinsics.i32_ty,
8668                    effective_address,
8669                    ""
8670                ));
8671                self.annotate_user_memaccess(
8672                    memory_index,
8673                    memarg,
8674                    1,
8675                    dead_load.as_instruction_value().unwrap(),
8676                )?;
8677                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8678                let val = err!(self.builder.build_extract_element(v, idx, ""));
8679                let store = err!(self.builder.build_store(effective_address, val));
8680                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8681            }
8682            Operator::V128Store64Lane { ref memarg, lane } => {
8683                let (v, i) = self.state.pop1_extra()?;
8684                let (v, _i) = self.v128_into_i64x2(v, i)?;
8685                let offset = self.state.pop1()?.into_int_value();
8686                let memory_index = MemoryIndex::from_u32(memarg.memory);
8687
8688                let effective_address = self.resolve_memory_ptr(
8689                    memory_index,
8690                    memarg,
8691                    self.intrinsics.ptr_ty,
8692                    offset,
8693                    8,
8694                )?;
8695                let dead_load = err!(self.builder.build_load(
8696                    self.intrinsics.i64_ty,
8697                    effective_address,
8698                    ""
8699                ));
8700                self.annotate_user_memaccess(
8701                    memory_index,
8702                    memarg,
8703                    1,
8704                    dead_load.as_instruction_value().unwrap(),
8705                )?;
8706                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8707                let val = err!(self.builder.build_extract_element(v, idx, ""));
8708                let store = err!(self.builder.build_store(effective_address, val));
8709                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8710            }
8711            Operator::I32Load8S { ref memarg } => {
8712                let offset = self.state.pop1()?.into_int_value();
8713                let memory_index = MemoryIndex::from_u32(0);
8714                let effective_address = self.resolve_memory_ptr(
8715                    memory_index,
8716                    memarg,
8717                    self.intrinsics.ptr_ty,
8718                    offset,
8719                    1,
8720                )?;
8721                let narrow_result = err!(self.builder.build_load(
8722                    self.intrinsics.i8_ty,
8723                    effective_address,
8724                    ""
8725                ));
8726                self.annotate_user_memaccess(
8727                    memory_index,
8728                    memarg,
8729                    1,
8730                    narrow_result.as_instruction_value().unwrap(),
8731                )?;
8732                let result = err!(self.builder.build_int_s_extend(
8733                    narrow_result.into_int_value(),
8734                    self.intrinsics.i32_ty,
8735                    "",
8736                ));
8737                self.state.push1(result);
8738            }
8739            Operator::I32Load16S { ref memarg } => {
8740                let offset = self.state.pop1()?.into_int_value();
8741                let memory_index = MemoryIndex::from_u32(0);
8742                let effective_address = self.resolve_memory_ptr(
8743                    memory_index,
8744                    memarg,
8745                    self.intrinsics.ptr_ty,
8746                    offset,
8747                    2,
8748                )?;
8749                let narrow_result = err!(self.builder.build_load(
8750                    self.intrinsics.i16_ty,
8751                    effective_address,
8752                    ""
8753                ));
8754                self.annotate_user_memaccess(
8755                    memory_index,
8756                    memarg,
8757                    1,
8758                    narrow_result.as_instruction_value().unwrap(),
8759                )?;
8760                let result = err!(self.builder.build_int_s_extend(
8761                    narrow_result.into_int_value(),
8762                    self.intrinsics.i32_ty,
8763                    "",
8764                ));
8765                self.state.push1(result);
8766            }
8767            Operator::I64Load8S { ref memarg } => {
8768                let offset = self.state.pop1()?.into_int_value();
8769                let memory_index = MemoryIndex::from_u32(0);
8770                let effective_address = self.resolve_memory_ptr(
8771                    memory_index,
8772                    memarg,
8773                    self.intrinsics.ptr_ty,
8774                    offset,
8775                    1,
8776                )?;
8777                let narrow_result = err!(self.builder.build_load(
8778                    self.intrinsics.i8_ty,
8779                    effective_address,
8780                    ""
8781                ))
8782                .into_int_value();
8783                self.annotate_user_memaccess(
8784                    memory_index,
8785                    memarg,
8786                    1,
8787                    narrow_result.as_instruction_value().unwrap(),
8788                )?;
8789                let result = err!(self.builder.build_int_s_extend(
8790                    narrow_result,
8791                    self.intrinsics.i64_ty,
8792                    ""
8793                ));
8794                self.state.push1(result);
8795            }
8796            Operator::I64Load16S { ref memarg } => {
8797                let offset = self.state.pop1()?.into_int_value();
8798                let memory_index = MemoryIndex::from_u32(0);
8799                let effective_address = self.resolve_memory_ptr(
8800                    memory_index,
8801                    memarg,
8802                    self.intrinsics.ptr_ty,
8803                    offset,
8804                    2,
8805                )?;
8806                let narrow_result = err!(self.builder.build_load(
8807                    self.intrinsics.i16_ty,
8808                    effective_address,
8809                    ""
8810                ))
8811                .into_int_value();
8812                self.annotate_user_memaccess(
8813                    memory_index,
8814                    memarg,
8815                    1,
8816                    narrow_result.as_instruction_value().unwrap(),
8817                )?;
8818                let result = err!(self.builder.build_int_s_extend(
8819                    narrow_result,
8820                    self.intrinsics.i64_ty,
8821                    ""
8822                ));
8823                self.state.push1(result);
8824            }
8825            Operator::I64Load32S { ref memarg } => {
8826                let offset = self.state.pop1()?.into_int_value();
8827                let memory_index = MemoryIndex::from_u32(0);
8828                let effective_address = self.resolve_memory_ptr(
8829                    memory_index,
8830                    memarg,
8831                    self.intrinsics.ptr_ty,
8832                    offset,
8833                    4,
8834                )?;
8835                let narrow_result = err!(self.builder.build_load(
8836                    self.intrinsics.i32_ty,
8837                    effective_address,
8838                    ""
8839                ));
8840                self.annotate_user_memaccess(
8841                    memory_index,
8842                    memarg,
8843                    1,
8844                    narrow_result.as_instruction_value().unwrap(),
8845                )?;
8846                let result = err!(self.builder.build_int_s_extend(
8847                    narrow_result.into_int_value(),
8848                    self.intrinsics.i64_ty,
8849                    "",
8850                ));
8851                self.state.push1(result);
8852            }
8853
8854            Operator::I32Load8U { ref memarg } => {
8855                let offset = self.state.pop1()?.into_int_value();
8856                let memory_index = MemoryIndex::from_u32(0);
8857                let effective_address = self.resolve_memory_ptr(
8858                    memory_index,
8859                    memarg,
8860                    self.intrinsics.ptr_ty,
8861                    offset,
8862                    1,
8863                )?;
8864                let narrow_result = err!(self.builder.build_load(
8865                    self.intrinsics.i8_ty,
8866                    effective_address,
8867                    ""
8868                ));
8869                self.annotate_user_memaccess(
8870                    memory_index,
8871                    memarg,
8872                    1,
8873                    narrow_result.as_instruction_value().unwrap(),
8874                )?;
8875                let result = err!(self.builder.build_int_z_extend(
8876                    narrow_result.into_int_value(),
8877                    self.intrinsics.i32_ty,
8878                    "",
8879                ));
8880                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8881            }
8882            Operator::I32Load16U { ref memarg } => {
8883                let offset = self.state.pop1()?.into_int_value();
8884                let memory_index = MemoryIndex::from_u32(0);
8885                let effective_address = self.resolve_memory_ptr(
8886                    memory_index,
8887                    memarg,
8888                    self.intrinsics.ptr_ty,
8889                    offset,
8890                    2,
8891                )?;
8892                let narrow_result = err!(self.builder.build_load(
8893                    self.intrinsics.i16_ty,
8894                    effective_address,
8895                    ""
8896                ));
8897                self.annotate_user_memaccess(
8898                    memory_index,
8899                    memarg,
8900                    1,
8901                    narrow_result.as_instruction_value().unwrap(),
8902                )?;
8903                let result = err!(self.builder.build_int_z_extend(
8904                    narrow_result.into_int_value(),
8905                    self.intrinsics.i32_ty,
8906                    "",
8907                ));
8908                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8909            }
8910            Operator::I64Load8U { ref memarg } => {
8911                let offset = self.state.pop1()?.into_int_value();
8912                let memory_index = MemoryIndex::from_u32(0);
8913                let effective_address = self.resolve_memory_ptr(
8914                    memory_index,
8915                    memarg,
8916                    self.intrinsics.ptr_ty,
8917                    offset,
8918                    1,
8919                )?;
8920                let narrow_result = err!(self.builder.build_load(
8921                    self.intrinsics.i8_ty,
8922                    effective_address,
8923                    ""
8924                ));
8925                self.annotate_user_memaccess(
8926                    memory_index,
8927                    memarg,
8928                    1,
8929                    narrow_result.as_instruction_value().unwrap(),
8930                )?;
8931                let result = err!(self.builder.build_int_z_extend(
8932                    narrow_result.into_int_value(),
8933                    self.intrinsics.i64_ty,
8934                    "",
8935                ));
8936                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8937            }
8938            Operator::I64Load16U { ref memarg } => {
8939                let offset = self.state.pop1()?.into_int_value();
8940                let memory_index = MemoryIndex::from_u32(0);
8941                let effective_address = self.resolve_memory_ptr(
8942                    memory_index,
8943                    memarg,
8944                    self.intrinsics.ptr_ty,
8945                    offset,
8946                    2,
8947                )?;
8948                let narrow_result = err!(self.builder.build_load(
8949                    self.intrinsics.i16_ty,
8950                    effective_address,
8951                    ""
8952                ));
8953                self.annotate_user_memaccess(
8954                    memory_index,
8955                    memarg,
8956                    1,
8957                    narrow_result.as_instruction_value().unwrap(),
8958                )?;
8959                let result = err!(self.builder.build_int_z_extend(
8960                    narrow_result.into_int_value(),
8961                    self.intrinsics.i64_ty,
8962                    "",
8963                ));
8964                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8965            }
8966            Operator::I64Load32U { ref memarg } => {
8967                let offset = self.state.pop1()?.into_int_value();
8968                let memory_index = MemoryIndex::from_u32(0);
8969                let effective_address = self.resolve_memory_ptr(
8970                    memory_index,
8971                    memarg,
8972                    self.intrinsics.ptr_ty,
8973                    offset,
8974                    4,
8975                )?;
8976                let narrow_result = err!(self.builder.build_load(
8977                    self.intrinsics.i32_ty,
8978                    effective_address,
8979                    ""
8980                ));
8981                self.annotate_user_memaccess(
8982                    memory_index,
8983                    memarg,
8984                    1,
8985                    narrow_result.as_instruction_value().unwrap(),
8986                )?;
8987                let result = err!(self.builder.build_int_z_extend(
8988                    narrow_result.into_int_value(),
8989                    self.intrinsics.i64_ty,
8990                    "",
8991                ));
8992                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8993            }
8994
8995            Operator::I32Store8 { ref memarg } | Operator::I64Store8 { ref memarg } => {
8996                let value = self.state.pop1()?.into_int_value();
8997                let offset = self.state.pop1()?.into_int_value();
8998                let memory_index = MemoryIndex::from_u32(0);
8999                let effective_address = self.resolve_memory_ptr(
9000                    memory_index,
9001                    memarg,
9002                    self.intrinsics.ptr_ty,
9003                    offset,
9004                    1,
9005                )?;
9006                let dead_load = err!(self.builder.build_load(
9007                    self.intrinsics.i8_ty,
9008                    effective_address,
9009                    ""
9010                ));
9011                self.annotate_user_memaccess(
9012                    memory_index,
9013                    memarg,
9014                    1,
9015                    dead_load.as_instruction_value().unwrap(),
9016                )?;
9017                let narrow_value = err!(self.builder.build_int_truncate(
9018                    value,
9019                    self.intrinsics.i8_ty,
9020                    ""
9021                ));
9022                let store = err!(self.builder.build_store(effective_address, narrow_value));
9023                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9024            }
9025            Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
9026                let value = self.state.pop1()?.into_int_value();
9027                let offset = self.state.pop1()?.into_int_value();
9028                let memory_index = MemoryIndex::from_u32(0);
9029                let effective_address = self.resolve_memory_ptr(
9030                    memory_index,
9031                    memarg,
9032                    self.intrinsics.ptr_ty,
9033                    offset,
9034                    2,
9035                )?;
9036                let dead_load = err!(self.builder.build_load(
9037                    self.intrinsics.i16_ty,
9038                    effective_address,
9039                    ""
9040                ));
9041                self.annotate_user_memaccess(
9042                    memory_index,
9043                    memarg,
9044                    1,
9045                    dead_load.as_instruction_value().unwrap(),
9046                )?;
9047                let narrow_value = err!(self.builder.build_int_truncate(
9048                    value,
9049                    self.intrinsics.i16_ty,
9050                    ""
9051                ));
9052                let store = err!(self.builder.build_store(effective_address, narrow_value));
9053                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9054            }
9055            Operator::I64Store32 { ref memarg } => {
9056                let value = self.state.pop1()?.into_int_value();
9057                let offset = self.state.pop1()?.into_int_value();
9058                let memory_index = MemoryIndex::from_u32(0);
9059                let effective_address = self.resolve_memory_ptr(
9060                    memory_index,
9061                    memarg,
9062                    self.intrinsics.ptr_ty,
9063                    offset,
9064                    4,
9065                )?;
9066                let dead_load = err!(self.builder.build_load(
9067                    self.intrinsics.i32_ty,
9068                    effective_address,
9069                    ""
9070                ));
9071                self.annotate_user_memaccess(
9072                    memory_index,
9073                    memarg,
9074                    1,
9075                    dead_load.as_instruction_value().unwrap(),
9076                )?;
9077                let narrow_value = err!(self.builder.build_int_truncate(
9078                    value,
9079                    self.intrinsics.i32_ty,
9080                    ""
9081                ));
9082                let store = err!(self.builder.build_store(effective_address, narrow_value));
9083                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9084            }
9085            Operator::I8x16Neg => {
9086                let (v, i) = self.state.pop1_extra()?;
9087                let (v, _) = self.v128_into_i8x16(v, i)?;
9088                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9089                let res = err!(
9090                    self.builder
9091                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9092                );
9093                self.state.push1(res);
9094            }
9095            Operator::I16x8Neg => {
9096                let (v, i) = self.state.pop1_extra()?;
9097                let (v, _) = self.v128_into_i16x8(v, i)?;
9098                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9099                let res = err!(
9100                    self.builder
9101                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9102                );
9103                self.state.push1(res);
9104            }
9105            Operator::I32x4Neg => {
9106                let (v, i) = self.state.pop1_extra()?;
9107                let (v, _) = self.v128_into_i32x4(v, i)?;
9108                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9109                let res = err!(
9110                    self.builder
9111                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9112                );
9113                self.state.push1(res);
9114            }
9115            Operator::I64x2Neg => {
9116                let (v, i) = self.state.pop1_extra()?;
9117                let (v, _) = self.v128_into_i64x2(v, i)?;
9118                let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9119                let res = err!(
9120                    self.builder
9121                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9122                );
9123                self.state.push1(res);
9124            }
9125            Operator::V128Not => {
9126                let (v, i) = self.state.pop1_extra()?;
9127                let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9128                let res = err!(self.builder.build_not(v, ""));
9129                self.state.push1(res);
9130            }
9131            Operator::V128AnyTrue => {
9132                // | Operator::I64x2AnyTrue
9133                // Skip canonicalization, it never changes non-zero values to zero or vice versa.
9134                let v = self.state.pop1()?.into_int_value();
9135                let res = err!(self.builder.build_int_compare(
9136                    IntPredicate::NE,
9137                    v,
9138                    v.get_type().const_zero(),
9139                    "",
9140                ));
9141                let res = err!(
9142                    self.builder
9143                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9144                );
9145                self.state.push1_extra(
9146                    res,
9147                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9148                );
9149            }
9150            Operator::I8x16AllTrue
9151            | Operator::I16x8AllTrue
9152            | Operator::I32x4AllTrue
9153            | Operator::I64x2AllTrue => {
9154                let vec_ty = match op {
9155                    Operator::I8x16AllTrue => self.intrinsics.i8x16_ty,
9156                    Operator::I16x8AllTrue => self.intrinsics.i16x8_ty,
9157                    Operator::I32x4AllTrue => self.intrinsics.i32x4_ty,
9158                    Operator::I64x2AllTrue => self.intrinsics.i64x2_ty,
9159                    _ => unreachable!(),
9160                };
9161                let (v, i) = self.state.pop1_extra()?;
9162                let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9163                let lane_int_ty = self.context.custom_width_int_type(vec_ty.get_size());
9164                let vec = err!(self.builder.build_bit_cast(v, vec_ty, "vec")).into_vector_value();
9165                let mask = err!(self.builder.build_int_compare(
9166                    IntPredicate::NE,
9167                    vec,
9168                    vec_ty.const_zero(),
9169                    "mask",
9170                ));
9171                let cmask =
9172                    err!(self.builder.build_bit_cast(mask, lane_int_ty, "cmask")).into_int_value();
9173                let res = err!(self.builder.build_int_compare(
9174                    IntPredicate::EQ,
9175                    cmask,
9176                    lane_int_ty.const_int(u64::MAX, true),
9177                    "",
9178                ));
9179                let res = err!(
9180                    self.builder
9181                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9182                );
9183                self.state.push1_extra(
9184                    res,
9185                    (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9186                );
9187            }
9188            Operator::I8x16ExtractLaneS { lane } => {
9189                let (v, i) = self.state.pop1_extra()?;
9190                let (v, _) = self.v128_into_i8x16(v, i)?;
9191                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9192                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9193                let res = err!(
9194                    self.builder
9195                        .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9196                );
9197                self.state.push1(res);
9198            }
9199            Operator::I8x16ExtractLaneU { lane } => {
9200                let (v, i) = self.state.pop1_extra()?;
9201                let (v, _) = self.v128_into_i8x16(v, i)?;
9202                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9203                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9204                let res = err!(
9205                    self.builder
9206                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9207                );
9208                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9209            }
9210            Operator::I16x8ExtractLaneS { lane } => {
9211                let (v, i) = self.state.pop1_extra()?;
9212                let (v, _) = self.v128_into_i16x8(v, i)?;
9213                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9214                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9215                let res = err!(
9216                    self.builder
9217                        .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9218                );
9219                self.state.push1(res);
9220            }
9221            Operator::I16x8ExtractLaneU { lane } => {
9222                let (v, i) = self.state.pop1_extra()?;
9223                let (v, _) = self.v128_into_i16x8(v, i)?;
9224                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9225                let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9226                let res = err!(
9227                    self.builder
9228                        .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9229                );
9230                self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9231            }
9232            Operator::I32x4ExtractLane { lane } => {
9233                let (v, i) = self.state.pop1_extra()?;
9234                let (v, i) = self.v128_into_i32x4(v, i)?;
9235                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9236                let res = err!(self.builder.build_extract_element(v, idx, ""));
9237                self.state.push1_extra(res, i);
9238            }
9239            Operator::I64x2ExtractLane { lane } => {
9240                let (v, i) = self.state.pop1_extra()?;
9241                let (v, i) = self.v128_into_i64x2(v, i)?;
9242                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9243                let res = err!(self.builder.build_extract_element(v, idx, ""));
9244                self.state.push1_extra(res, i);
9245            }
9246            Operator::F32x4ExtractLane { lane } => {
9247                let (v, i) = self.state.pop1_extra()?;
9248                let (v, i) = self.v128_into_f32x4(v, i)?;
9249                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9250                let res = err!(self.builder.build_extract_element(v, idx, ""));
9251                self.state.push1_extra(res, i);
9252            }
9253            Operator::F64x2ExtractLane { lane } => {
9254                let (v, i) = self.state.pop1_extra()?;
9255                let (v, i) = self.v128_into_f64x2(v, i)?;
9256                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9257                let res = err!(self.builder.build_extract_element(v, idx, ""));
9258                self.state.push1_extra(res, i);
9259            }
9260            Operator::I8x16ReplaceLane { lane } => {
9261                let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9262                let (v1, _) = self.v128_into_i8x16(v1, i1)?;
9263                let v2 = v2.into_int_value();
9264                let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i8_ty, ""));
9265                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9266                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9267                let res = err!(
9268                    self.builder
9269                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9270                );
9271                self.state.push1(res);
9272            }
9273            Operator::I16x8ReplaceLane { lane } => {
9274                let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9275                let (v1, _) = self.v128_into_i16x8(v1, i1)?;
9276                let v2 = v2.into_int_value();
9277                let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i16_ty, ""));
9278                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9279                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9280                let res = err!(
9281                    self.builder
9282                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9283                );
9284                self.state.push1(res);
9285            }
9286            Operator::I32x4ReplaceLane { lane } => {
9287                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9288                let (v1, i1) = self.v128_into_i32x4(v1, i1)?;
9289                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9290                let v2 = v2.into_int_value();
9291                let i2 = i2.strip_pending();
9292                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9293                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9294                let res = err!(
9295                    self.builder
9296                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9297                );
9298                self.state
9299                    .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f32())?);
9300            }
9301            Operator::I64x2ReplaceLane { lane } => {
9302                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9303                let (v1, i1) = self.v128_into_i64x2(v1, i1)?;
9304                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9305                let v2 = v2.into_int_value();
9306                let i2 = i2.strip_pending();
9307                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9308                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9309                let res = err!(
9310                    self.builder
9311                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9312                );
9313                self.state
9314                    .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f64())?);
9315            }
9316            Operator::F32x4ReplaceLane { lane } => {
9317                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9318                let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
9319                let push_pending_f32_nan_to_result =
9320                    i1.has_pending_f32_nan() && i2.has_pending_f32_nan();
9321                let (v1, v2) = if !push_pending_f32_nan_to_result {
9322                    (
9323                        self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9324                            .into_vector_value(),
9325                        self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9326                            .into_float_value(),
9327                    )
9328                } else {
9329                    (v1, v2.into_float_value())
9330                };
9331                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9332                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9333                let res = err!(
9334                    self.builder
9335                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9336                );
9337                let info = if push_pending_f32_nan_to_result {
9338                    ExtraInfo::pending_f32_nan()
9339                } else {
9340                    (i1.strip_pending() & i2.strip_pending())?
9341                };
9342                self.state.push1_extra(res, info);
9343            }
9344            Operator::F64x2ReplaceLane { lane } => {
9345                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9346                let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
9347                let push_pending_f64_nan_to_result =
9348                    i1.has_pending_f64_nan() && i2.has_pending_f64_nan();
9349                let (v1, v2) = if !push_pending_f64_nan_to_result {
9350                    (
9351                        self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9352                            .into_vector_value(),
9353                        self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9354                            .into_float_value(),
9355                    )
9356                } else {
9357                    (v1, v2.into_float_value())
9358                };
9359                let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9360                let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9361                let res = err!(
9362                    self.builder
9363                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9364                );
9365                let info = if push_pending_f64_nan_to_result {
9366                    ExtraInfo::pending_f64_nan()
9367                } else {
9368                    (i1.strip_pending() & i2.strip_pending())?
9369                };
9370                self.state.push1_extra(res, info);
9371            }
9372            Operator::I8x16Swizzle => {
9373                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9374                let v1 = self.apply_pending_canonicalization(v1, i1)?;
9375                let v1 = err!(
9376                    self.builder
9377                        .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9378                )
9379                .into_vector_value();
9380                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9381                let v2 = err!(
9382                    self.builder
9383                        .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9384                )
9385                .into_vector_value();
9386                let lanes = self.intrinsics.i8_ty.const_int(16, false);
9387                let lanes =
9388                    self.splat_vector(lanes.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
9389                let mut res = self.intrinsics.i8x16_ty.get_undef();
9390                let idx_out_of_range = err!(self.builder.build_int_compare(
9391                    IntPredicate::UGE,
9392                    v2,
9393                    lanes,
9394                    "idx_out_of_range",
9395                ));
9396                let idx_clamped = err!(self.builder.build_select(
9397                    idx_out_of_range,
9398                    self.intrinsics.i8x16_ty.const_zero(),
9399                    v2,
9400                    "idx_clamped",
9401                ))
9402                .into_vector_value();
9403                for i in 0..16 {
9404                    let idx = err!(self.builder.build_extract_element(
9405                        idx_clamped,
9406                        self.intrinsics.i32_ty.const_int(i, false),
9407                        "idx",
9408                    ))
9409                    .into_int_value();
9410                    let replace_with_zero = err!(self.builder.build_extract_element(
9411                        idx_out_of_range,
9412                        self.intrinsics.i32_ty.const_int(i, false),
9413                        "replace_with_zero",
9414                    ))
9415                    .into_int_value();
9416                    let elem =
9417                        err!(self.builder.build_extract_element(v1, idx, "elem")).into_int_value();
9418                    let elem_or_zero = err!(self.builder.build_select(
9419                        replace_with_zero,
9420                        self.intrinsics.i8_zero,
9421                        elem,
9422                        "elem_or_zero",
9423                    ));
9424                    res = err!(self.builder.build_insert_element(
9425                        res,
9426                        elem_or_zero,
9427                        self.intrinsics.i32_ty.const_int(i, false),
9428                        "",
9429                    ));
9430                }
9431                let res = err!(
9432                    self.builder
9433                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9434                );
9435                self.state.push1(res);
9436            }
9437            Operator::I8x16Shuffle { lanes } => {
9438                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9439                let v1 = self.apply_pending_canonicalization(v1, i1)?;
9440                let v1 = err!(
9441                    self.builder
9442                        .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9443                )
9444                .into_vector_value();
9445                let v2 = self.apply_pending_canonicalization(v2, i2)?;
9446                let v2 = err!(
9447                    self.builder
9448                        .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9449                )
9450                .into_vector_value();
9451                let mask = VectorType::const_vector(
9452                    lanes
9453                        .iter()
9454                        .map(|l| self.intrinsics.i32_ty.const_int((*l).into(), false))
9455                        .collect::<Vec<IntValue>>()
9456                        .as_slice(),
9457                );
9458                let res = err!(self.builder.build_shuffle_vector(v1, v2, mask, ""));
9459                let res = err!(
9460                    self.builder
9461                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9462                );
9463                self.state.push1(res);
9464            }
9465            Operator::V128Load8x8S { ref memarg } => {
9466                let offset = self.state.pop1()?.into_int_value();
9467                let memory_index = MemoryIndex::from_u32(0);
9468                let effective_address = self.resolve_memory_ptr(
9469                    memory_index,
9470                    memarg,
9471                    self.intrinsics.ptr_ty,
9472                    offset,
9473                    8,
9474                )?;
9475                let v = err!(self.builder.build_load(
9476                    self.intrinsics.i64_ty,
9477                    effective_address,
9478                    ""
9479                ));
9480                let v = err!(
9481                    self.builder
9482                        .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9483                )
9484                .into_vector_value();
9485                let res = err!(
9486                    self.builder
9487                        .build_int_s_extend(v, self.intrinsics.i16x8_ty, "")
9488                );
9489                let res = err!(
9490                    self.builder
9491                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9492                );
9493                self.state.push1(res);
9494            }
9495            Operator::V128Load8x8U { 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                    8,
9504                )?;
9505                let v = err!(self.builder.build_load(
9506                    self.intrinsics.i64_ty,
9507                    effective_address,
9508                    ""
9509                ));
9510                let v = err!(
9511                    self.builder
9512                        .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9513                )
9514                .into_vector_value();
9515                let res = err!(
9516                    self.builder
9517                        .build_int_z_extend(v, self.intrinsics.i16x8_ty, "")
9518                );
9519                let res = err!(
9520                    self.builder
9521                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9522                );
9523                self.state.push1(res);
9524            }
9525            Operator::V128Load16x4S { ref memarg } => {
9526                let offset = self.state.pop1()?.into_int_value();
9527                let memory_index = MemoryIndex::from_u32(0);
9528                let effective_address = self.resolve_memory_ptr(
9529                    memory_index,
9530                    memarg,
9531                    self.intrinsics.ptr_ty,
9532                    offset,
9533                    8,
9534                )?;
9535                let v = err!(self.builder.build_load(
9536                    self.intrinsics.i64_ty,
9537                    effective_address,
9538                    ""
9539                ));
9540                let v = err!(self.builder.build_bit_cast(
9541                    v,
9542                    self.intrinsics.i16_ty.vec_type(4),
9543                    ""
9544                ))
9545                .into_vector_value();
9546                let res = err!(
9547                    self.builder
9548                        .build_int_s_extend(v, self.intrinsics.i32x4_ty, "")
9549                );
9550                let res = err!(
9551                    self.builder
9552                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9553                );
9554                self.state.push1(res);
9555            }
9556            Operator::V128Load16x4U { ref memarg } => {
9557                let offset = self.state.pop1()?.into_int_value();
9558                let memory_index = MemoryIndex::from_u32(0);
9559                let effective_address = self.resolve_memory_ptr(
9560                    memory_index,
9561                    memarg,
9562                    self.intrinsics.ptr_ty,
9563                    offset,
9564                    8,
9565                )?;
9566                let v = err!(self.builder.build_load(
9567                    self.intrinsics.i64_ty,
9568                    effective_address,
9569                    ""
9570                ));
9571                let v = err!(self.builder.build_bit_cast(
9572                    v,
9573                    self.intrinsics.i16_ty.vec_type(4),
9574                    ""
9575                ))
9576                .into_vector_value();
9577                let res = err!(
9578                    self.builder
9579                        .build_int_z_extend(v, self.intrinsics.i32x4_ty, "")
9580                );
9581                let res = err!(
9582                    self.builder
9583                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9584                );
9585                self.state.push1(res);
9586            }
9587            Operator::V128Load32x2S { ref memarg } => {
9588                let offset = self.state.pop1()?.into_int_value();
9589                let memory_index = MemoryIndex::from_u32(0);
9590                let effective_address = self.resolve_memory_ptr(
9591                    memory_index,
9592                    memarg,
9593                    self.intrinsics.ptr_ty,
9594                    offset,
9595                    8,
9596                )?;
9597                let v = err!(self.builder.build_load(
9598                    self.intrinsics.i64_ty,
9599                    effective_address,
9600                    ""
9601                ));
9602                let v = err!(self.builder.build_bit_cast(
9603                    v,
9604                    self.intrinsics.i32_ty.vec_type(2),
9605                    ""
9606                ))
9607                .into_vector_value();
9608                let res = err!(
9609                    self.builder
9610                        .build_int_s_extend(v, self.intrinsics.i64x2_ty, "")
9611                );
9612                let res = err!(
9613                    self.builder
9614                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9615                );
9616                self.state.push1(res);
9617            }
9618            Operator::V128Load32x2U { ref memarg } => {
9619                let offset = self.state.pop1()?.into_int_value();
9620                let memory_index = MemoryIndex::from_u32(0);
9621                let effective_address = self.resolve_memory_ptr(
9622                    memory_index,
9623                    memarg,
9624                    self.intrinsics.ptr_ty,
9625                    offset,
9626                    8,
9627                )?;
9628                let v = err!(self.builder.build_load(
9629                    self.intrinsics.i64_ty,
9630                    effective_address,
9631                    ""
9632                ));
9633                let v = err!(self.builder.build_bit_cast(
9634                    v,
9635                    self.intrinsics.i32_ty.vec_type(2),
9636                    ""
9637                ))
9638                .into_vector_value();
9639                let res = err!(
9640                    self.builder
9641                        .build_int_z_extend(v, self.intrinsics.i64x2_ty, "")
9642                );
9643                let res = err!(
9644                    self.builder
9645                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9646                );
9647                self.state.push1(res);
9648            }
9649            Operator::V128Load32Zero { ref memarg } => {
9650                let offset = self.state.pop1()?.into_int_value();
9651                let memory_index = MemoryIndex::from_u32(0);
9652                let effective_address = self.resolve_memory_ptr(
9653                    memory_index,
9654                    memarg,
9655                    self.intrinsics.ptr_ty,
9656                    offset,
9657                    4,
9658                )?;
9659                let elem = err!(self.builder.build_load(
9660                    self.intrinsics.i32_ty,
9661                    effective_address,
9662                    ""
9663                ));
9664                self.annotate_user_memaccess(
9665                    memory_index,
9666                    memarg,
9667                    1,
9668                    elem.as_instruction_value().unwrap(),
9669                )?;
9670                let res = err!(self.builder.build_int_z_extend(
9671                    elem.into_int_value(),
9672                    self.intrinsics.i128_ty,
9673                    "",
9674                ));
9675                self.state.push1(res);
9676            }
9677            Operator::V128Load64Zero { ref memarg } => {
9678                let offset = self.state.pop1()?.into_int_value();
9679                let memory_index = MemoryIndex::from_u32(0);
9680                let effective_address = self.resolve_memory_ptr(
9681                    memory_index,
9682                    memarg,
9683                    self.intrinsics.ptr_ty,
9684                    offset,
9685                    8,
9686                )?;
9687                let elem = err!(self.builder.build_load(
9688                    self.intrinsics.i64_ty,
9689                    effective_address,
9690                    ""
9691                ));
9692                self.annotate_user_memaccess(
9693                    memory_index,
9694                    memarg,
9695                    1,
9696                    elem.as_instruction_value().unwrap(),
9697                )?;
9698                let res = err!(self.builder.build_int_z_extend(
9699                    elem.into_int_value(),
9700                    self.intrinsics.i128_ty,
9701                    "",
9702                ));
9703                self.state.push1(res);
9704            }
9705            Operator::V128Load8Splat { ref memarg } => {
9706                let offset = self.state.pop1()?.into_int_value();
9707                let memory_index = MemoryIndex::from_u32(0);
9708                let effective_address = self.resolve_memory_ptr(
9709                    memory_index,
9710                    memarg,
9711                    self.intrinsics.ptr_ty,
9712                    offset,
9713                    1,
9714                )?;
9715                let elem = err!(self.builder.build_load(
9716                    self.intrinsics.i8_ty,
9717                    effective_address,
9718                    ""
9719                ));
9720                self.annotate_user_memaccess(
9721                    memory_index,
9722                    memarg,
9723                    1,
9724                    elem.as_instruction_value().unwrap(),
9725                )?;
9726                let res = self.splat_vector(elem, self.intrinsics.i8x16_ty)?;
9727                let res = err!(
9728                    self.builder
9729                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9730                );
9731                self.state.push1(res);
9732            }
9733            Operator::V128Load16Splat { ref memarg } => {
9734                let offset = self.state.pop1()?.into_int_value();
9735                let memory_index = MemoryIndex::from_u32(0);
9736                let effective_address = self.resolve_memory_ptr(
9737                    memory_index,
9738                    memarg,
9739                    self.intrinsics.ptr_ty,
9740                    offset,
9741                    2,
9742                )?;
9743                let elem = err!(self.builder.build_load(
9744                    self.intrinsics.i16_ty,
9745                    effective_address,
9746                    ""
9747                ));
9748                self.annotate_user_memaccess(
9749                    memory_index,
9750                    memarg,
9751                    1,
9752                    elem.as_instruction_value().unwrap(),
9753                )?;
9754                let res = self.splat_vector(elem, self.intrinsics.i16x8_ty)?;
9755                let res = err!(
9756                    self.builder
9757                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9758                );
9759                self.state.push1(res);
9760            }
9761            Operator::V128Load32Splat { ref memarg } => {
9762                let offset = self.state.pop1()?.into_int_value();
9763                let memory_index = MemoryIndex::from_u32(0);
9764                let effective_address = self.resolve_memory_ptr(
9765                    memory_index,
9766                    memarg,
9767                    self.intrinsics.ptr_ty,
9768                    offset,
9769                    4,
9770                )?;
9771                let elem = err!(self.builder.build_load(
9772                    self.intrinsics.i32_ty,
9773                    effective_address,
9774                    ""
9775                ));
9776                self.annotate_user_memaccess(
9777                    memory_index,
9778                    memarg,
9779                    1,
9780                    elem.as_instruction_value().unwrap(),
9781                )?;
9782                let res = self.splat_vector(elem, self.intrinsics.i32x4_ty)?;
9783                let res = err!(
9784                    self.builder
9785                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9786                );
9787                self.state.push1(res);
9788            }
9789            Operator::V128Load64Splat { ref memarg } => {
9790                let offset = self.state.pop1()?.into_int_value();
9791                let memory_index = MemoryIndex::from_u32(0);
9792                let effective_address = self.resolve_memory_ptr(
9793                    memory_index,
9794                    memarg,
9795                    self.intrinsics.ptr_ty,
9796                    offset,
9797                    8,
9798                )?;
9799                let elem = err!(self.builder.build_load(
9800                    self.intrinsics.i64_ty,
9801                    effective_address,
9802                    ""
9803                ));
9804                self.annotate_user_memaccess(
9805                    memory_index,
9806                    memarg,
9807                    1,
9808                    elem.as_instruction_value().unwrap(),
9809                )?;
9810                let res = self.splat_vector(elem, self.intrinsics.i64x2_ty)?;
9811                let res = err!(
9812                    self.builder
9813                        .build_bit_cast(res, self.intrinsics.i128_ty, "")
9814                );
9815                self.state.push1(res);
9816            }
9817            Operator::AtomicFence => {
9818                // Fence is a nop.
9819                //
9820                // Fence was added to preserve information about fences from
9821                // source languages. If in the future Wasm extends the memory
9822                // model, and if we hadn't recorded what fences used to be there,
9823                // it would lead to data races that weren't present in the
9824                // original source language.
9825            }
9826            Operator::I32AtomicLoad { ref memarg } => {
9827                let offset = self.state.pop1()?.into_int_value();
9828                let memory_index = MemoryIndex::from_u32(0);
9829                let effective_address = self.resolve_memory_ptr(
9830                    memory_index,
9831                    memarg,
9832                    self.intrinsics.ptr_ty,
9833                    offset,
9834                    4,
9835                )?;
9836                self.trap_if_misaligned(memarg, effective_address, 4)?;
9837                let result = err!(self.builder.build_load(
9838                    self.intrinsics.i32_ty,
9839                    effective_address,
9840                    "atomic_load"
9841                ));
9842                let load = result.as_instruction_value().unwrap();
9843                self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
9844                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9845                    .unwrap();
9846                self.state.push1(result);
9847            }
9848            Operator::I64AtomicLoad { ref memarg } => {
9849                let offset = self.state.pop1()?.into_int_value();
9850                let memory_index = MemoryIndex::from_u32(0);
9851                let effective_address = self.resolve_memory_ptr(
9852                    memory_index,
9853                    memarg,
9854                    self.intrinsics.ptr_ty,
9855                    offset,
9856                    8,
9857                )?;
9858                self.trap_if_misaligned(memarg, effective_address, 8)?;
9859                let result = err!(self.builder.build_load(
9860                    self.intrinsics.i64_ty,
9861                    effective_address,
9862                    ""
9863                ));
9864                let load = result.as_instruction_value().unwrap();
9865                self.annotate_user_memaccess(memory_index, memarg, 8, load)?;
9866                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9867                    .unwrap();
9868                self.state.push1(result);
9869            }
9870            Operator::I32AtomicLoad8U { ref memarg } => {
9871                let offset = self.state.pop1()?.into_int_value();
9872                let memory_index = MemoryIndex::from_u32(0);
9873                let effective_address = self.resolve_memory_ptr(
9874                    memory_index,
9875                    memarg,
9876                    self.intrinsics.ptr_ty,
9877                    offset,
9878                    1,
9879                )?;
9880                self.trap_if_misaligned(memarg, effective_address, 1)?;
9881                let narrow_result = err!(self.builder.build_load(
9882                    self.intrinsics.i8_ty,
9883                    effective_address,
9884                    ""
9885                ))
9886                .into_int_value();
9887                let load = narrow_result.as_instruction_value().unwrap();
9888                self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9889                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9890                    .unwrap();
9891                let result = err!(self.builder.build_int_z_extend(
9892                    narrow_result,
9893                    self.intrinsics.i32_ty,
9894                    ""
9895                ));
9896                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9897            }
9898            Operator::I32AtomicLoad16U { ref memarg } => {
9899                let offset = self.state.pop1()?.into_int_value();
9900                let memory_index = MemoryIndex::from_u32(0);
9901                let effective_address = self.resolve_memory_ptr(
9902                    memory_index,
9903                    memarg,
9904                    self.intrinsics.ptr_ty,
9905                    offset,
9906                    2,
9907                )?;
9908                self.trap_if_misaligned(memarg, effective_address, 2)?;
9909                let narrow_result = err!(self.builder.build_load(
9910                    self.intrinsics.i16_ty,
9911                    effective_address,
9912                    ""
9913                ))
9914                .into_int_value();
9915                let load = narrow_result.as_instruction_value().unwrap();
9916                self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9917                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9918                    .unwrap();
9919                let result = err!(self.builder.build_int_z_extend(
9920                    narrow_result,
9921                    self.intrinsics.i32_ty,
9922                    ""
9923                ));
9924                self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9925            }
9926            Operator::I64AtomicLoad8U { ref memarg } => {
9927                let offset = self.state.pop1()?.into_int_value();
9928                let memory_index = MemoryIndex::from_u32(0);
9929                let effective_address = self.resolve_memory_ptr(
9930                    memory_index,
9931                    memarg,
9932                    self.intrinsics.ptr_ty,
9933                    offset,
9934                    1,
9935                )?;
9936                self.trap_if_misaligned(memarg, effective_address, 1)?;
9937                let narrow_result = err!(self.builder.build_load(
9938                    self.intrinsics.i8_ty,
9939                    effective_address,
9940                    ""
9941                ))
9942                .into_int_value();
9943                let load = narrow_result.as_instruction_value().unwrap();
9944                self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9945                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9946                    .unwrap();
9947                let result = err!(self.builder.build_int_z_extend(
9948                    narrow_result,
9949                    self.intrinsics.i64_ty,
9950                    ""
9951                ));
9952                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9953            }
9954            Operator::I64AtomicLoad16U { ref memarg } => {
9955                let offset = self.state.pop1()?.into_int_value();
9956                let memory_index = MemoryIndex::from_u32(0);
9957                let effective_address = self.resolve_memory_ptr(
9958                    memory_index,
9959                    memarg,
9960                    self.intrinsics.ptr_ty,
9961                    offset,
9962                    2,
9963                )?;
9964                self.trap_if_misaligned(memarg, effective_address, 2)?;
9965                let narrow_result = err!(self.builder.build_load(
9966                    self.intrinsics.i16_ty,
9967                    effective_address,
9968                    ""
9969                ))
9970                .into_int_value();
9971                let load = narrow_result.as_instruction_value().unwrap();
9972                self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9973                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9974                    .unwrap();
9975                let result = err!(self.builder.build_int_z_extend(
9976                    narrow_result,
9977                    self.intrinsics.i64_ty,
9978                    ""
9979                ));
9980                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9981            }
9982            Operator::I64AtomicLoad32U { ref memarg } => {
9983                let offset = self.state.pop1()?.into_int_value();
9984                let memory_index = MemoryIndex::from_u32(0);
9985                let effective_address = self.resolve_memory_ptr(
9986                    memory_index,
9987                    memarg,
9988                    self.intrinsics.ptr_ty,
9989                    offset,
9990                    4,
9991                )?;
9992                self.trap_if_misaligned(memarg, effective_address, 4)?;
9993                let narrow_result = err!(self.builder.build_load(
9994                    self.intrinsics.i32_ty,
9995                    effective_address,
9996                    ""
9997                ))
9998                .into_int_value();
9999                let load = narrow_result.as_instruction_value().unwrap();
10000                self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10001                load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10002                    .unwrap();
10003                let result = err!(self.builder.build_int_z_extend(
10004                    narrow_result,
10005                    self.intrinsics.i64_ty,
10006                    ""
10007                ));
10008                self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10009            }
10010            Operator::I32AtomicStore { ref memarg } => {
10011                let value = self.state.pop1()?;
10012                let offset = self.state.pop1()?.into_int_value();
10013                let memory_index = MemoryIndex::from_u32(0);
10014                let effective_address = self.resolve_memory_ptr(
10015                    memory_index,
10016                    memarg,
10017                    self.intrinsics.ptr_ty,
10018                    offset,
10019                    4,
10020                )?;
10021                self.trap_if_misaligned(memarg, effective_address, 4)?;
10022                let store = err!(self.builder.build_store(effective_address, value));
10023                self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10024                store
10025                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10026                    .unwrap();
10027            }
10028            Operator::I64AtomicStore { ref memarg } => {
10029                let value = self.state.pop1()?;
10030                let offset = self.state.pop1()?.into_int_value();
10031                let memory_index = MemoryIndex::from_u32(0);
10032                let effective_address = self.resolve_memory_ptr(
10033                    memory_index,
10034                    memarg,
10035                    self.intrinsics.ptr_ty,
10036                    offset,
10037                    8,
10038                )?;
10039                self.trap_if_misaligned(memarg, effective_address, 8)?;
10040                let store = err!(self.builder.build_store(effective_address, value));
10041                self.annotate_user_memaccess(memory_index, memarg, 8, store)?;
10042                store
10043                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10044                    .unwrap();
10045            }
10046            Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => {
10047                let value = self.state.pop1()?.into_int_value();
10048                let offset = self.state.pop1()?.into_int_value();
10049                let memory_index = MemoryIndex::from_u32(0);
10050                let effective_address = self.resolve_memory_ptr(
10051                    memory_index,
10052                    memarg,
10053                    self.intrinsics.ptr_ty,
10054                    offset,
10055                    1,
10056                )?;
10057                self.trap_if_misaligned(memarg, effective_address, 1)?;
10058                let narrow_value = err!(self.builder.build_int_truncate(
10059                    value,
10060                    self.intrinsics.i8_ty,
10061                    ""
10062                ));
10063                let store = err!(self.builder.build_store(effective_address, narrow_value));
10064                self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
10065                store
10066                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10067                    .unwrap();
10068            }
10069            Operator::I32AtomicStore16 { ref memarg }
10070            | Operator::I64AtomicStore16 { ref memarg } => {
10071                let value = self.state.pop1()?.into_int_value();
10072                let offset = self.state.pop1()?.into_int_value();
10073                let memory_index = MemoryIndex::from_u32(0);
10074                let effective_address = self.resolve_memory_ptr(
10075                    memory_index,
10076                    memarg,
10077                    self.intrinsics.ptr_ty,
10078                    offset,
10079                    2,
10080                )?;
10081                self.trap_if_misaligned(memarg, effective_address, 2)?;
10082                let narrow_value = err!(self.builder.build_int_truncate(
10083                    value,
10084                    self.intrinsics.i16_ty,
10085                    ""
10086                ));
10087                let store = err!(self.builder.build_store(effective_address, narrow_value));
10088                self.annotate_user_memaccess(memory_index, memarg, 2, store)?;
10089                store
10090                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10091                    .unwrap();
10092            }
10093            Operator::I64AtomicStore32 { ref memarg } => {
10094                let value = self.state.pop1()?.into_int_value();
10095                let offset = self.state.pop1()?.into_int_value();
10096                let memory_index = MemoryIndex::from_u32(0);
10097                let effective_address = self.resolve_memory_ptr(
10098                    memory_index,
10099                    memarg,
10100                    self.intrinsics.ptr_ty,
10101                    offset,
10102                    4,
10103                )?;
10104                self.trap_if_misaligned(memarg, effective_address, 4)?;
10105                let narrow_value = err!(self.builder.build_int_truncate(
10106                    value,
10107                    self.intrinsics.i32_ty,
10108                    ""
10109                ));
10110                let store = err!(self.builder.build_store(effective_address, narrow_value));
10111                self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10112                store
10113                    .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10114                    .unwrap();
10115            }
10116            Operator::I32AtomicRmw8AddU { ref memarg } => {
10117                let value = self.state.pop1()?.into_int_value();
10118                let offset = self.state.pop1()?.into_int_value();
10119                let memory_index = MemoryIndex::from_u32(0);
10120                let effective_address = self.resolve_memory_ptr(
10121                    memory_index,
10122                    memarg,
10123                    self.intrinsics.ptr_ty,
10124                    offset,
10125                    1,
10126                )?;
10127                self.trap_if_misaligned(memarg, effective_address, 1)?;
10128                let narrow_value = err!(self.builder.build_int_truncate(
10129                    value,
10130                    self.intrinsics.i8_ty,
10131                    ""
10132                ));
10133                let old = self
10134                    .builder
10135                    .build_atomicrmw(
10136                        AtomicRMWBinOp::Add,
10137                        effective_address,
10138                        narrow_value,
10139                        AtomicOrdering::SequentiallyConsistent,
10140                    )
10141                    .unwrap();
10142                tbaa_label(
10143                    self.module,
10144                    self.intrinsics,
10145                    format!("memory {}", memory_index.as_u32()),
10146                    old.as_instruction_value().unwrap(),
10147                );
10148                let old = err!(
10149                    self.builder
10150                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10151                );
10152                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10153            }
10154            Operator::I32AtomicRmw16AddU { ref memarg } => {
10155                let value = self.state.pop1()?.into_int_value();
10156                let offset = self.state.pop1()?.into_int_value();
10157                let memory_index = MemoryIndex::from_u32(0);
10158                let effective_address = self.resolve_memory_ptr(
10159                    memory_index,
10160                    memarg,
10161                    self.intrinsics.ptr_ty,
10162                    offset,
10163                    2,
10164                )?;
10165                self.trap_if_misaligned(memarg, effective_address, 2)?;
10166                let narrow_value = err!(self.builder.build_int_truncate(
10167                    value,
10168                    self.intrinsics.i16_ty,
10169                    ""
10170                ));
10171                let old = self
10172                    .builder
10173                    .build_atomicrmw(
10174                        AtomicRMWBinOp::Add,
10175                        effective_address,
10176                        narrow_value,
10177                        AtomicOrdering::SequentiallyConsistent,
10178                    )
10179                    .unwrap();
10180                tbaa_label(
10181                    self.module,
10182                    self.intrinsics,
10183                    format!("memory {}", memory_index.as_u32()),
10184                    old.as_instruction_value().unwrap(),
10185                );
10186                let old = err!(
10187                    self.builder
10188                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10189                );
10190                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10191            }
10192            Operator::I32AtomicRmwAdd { ref memarg } => {
10193                let value = self.state.pop1()?.into_int_value();
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                    4,
10202                )?;
10203                self.trap_if_misaligned(memarg, effective_address, 4)?;
10204                let old = self
10205                    .builder
10206                    .build_atomicrmw(
10207                        AtomicRMWBinOp::Add,
10208                        effective_address,
10209                        value,
10210                        AtomicOrdering::SequentiallyConsistent,
10211                    )
10212                    .unwrap();
10213                tbaa_label(
10214                    self.module,
10215                    self.intrinsics,
10216                    format!("memory {}", memory_index.as_u32()),
10217                    old.as_instruction_value().unwrap(),
10218                );
10219                self.state.push1(old);
10220            }
10221            Operator::I64AtomicRmw8AddU { ref memarg } => {
10222                let value = self.state.pop1()?.into_int_value();
10223                let offset = self.state.pop1()?.into_int_value();
10224                let memory_index = MemoryIndex::from_u32(0);
10225                let effective_address = self.resolve_memory_ptr(
10226                    memory_index,
10227                    memarg,
10228                    self.intrinsics.ptr_ty,
10229                    offset,
10230                    1,
10231                )?;
10232                self.trap_if_misaligned(memarg, effective_address, 1)?;
10233                let narrow_value = err!(self.builder.build_int_truncate(
10234                    value,
10235                    self.intrinsics.i8_ty,
10236                    ""
10237                ));
10238                let old = self
10239                    .builder
10240                    .build_atomicrmw(
10241                        AtomicRMWBinOp::Add,
10242                        effective_address,
10243                        narrow_value,
10244                        AtomicOrdering::SequentiallyConsistent,
10245                    )
10246                    .unwrap();
10247                self.annotate_user_memaccess(
10248                    memory_index,
10249                    memarg,
10250                    0,
10251                    old.as_instruction_value().unwrap(),
10252                )?;
10253                let old = err!(
10254                    self.builder
10255                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10256                );
10257                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10258            }
10259            Operator::I64AtomicRmw16AddU { ref memarg } => {
10260                let value = self.state.pop1()?.into_int_value();
10261                let offset = self.state.pop1()?.into_int_value();
10262                let memory_index = MemoryIndex::from_u32(0);
10263                let effective_address = self.resolve_memory_ptr(
10264                    memory_index,
10265                    memarg,
10266                    self.intrinsics.ptr_ty,
10267                    offset,
10268                    2,
10269                )?;
10270                self.trap_if_misaligned(memarg, effective_address, 2)?;
10271                let narrow_value = err!(self.builder.build_int_truncate(
10272                    value,
10273                    self.intrinsics.i16_ty,
10274                    ""
10275                ));
10276                let old = self
10277                    .builder
10278                    .build_atomicrmw(
10279                        AtomicRMWBinOp::Add,
10280                        effective_address,
10281                        narrow_value,
10282                        AtomicOrdering::SequentiallyConsistent,
10283                    )
10284                    .unwrap();
10285                self.annotate_user_memaccess(
10286                    memory_index,
10287                    memarg,
10288                    0,
10289                    old.as_instruction_value().unwrap(),
10290                )?;
10291                let old = err!(
10292                    self.builder
10293                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10294                );
10295                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10296            }
10297            Operator::I64AtomicRmw32AddU { ref memarg } => {
10298                let value = self.state.pop1()?.into_int_value();
10299                let offset = self.state.pop1()?.into_int_value();
10300                let memory_index = MemoryIndex::from_u32(0);
10301                let effective_address = self.resolve_memory_ptr(
10302                    memory_index,
10303                    memarg,
10304                    self.intrinsics.ptr_ty,
10305                    offset,
10306                    4,
10307                )?;
10308                self.trap_if_misaligned(memarg, effective_address, 4)?;
10309                let narrow_value = err!(self.builder.build_int_truncate(
10310                    value,
10311                    self.intrinsics.i32_ty,
10312                    ""
10313                ));
10314                let old = self
10315                    .builder
10316                    .build_atomicrmw(
10317                        AtomicRMWBinOp::Add,
10318                        effective_address,
10319                        narrow_value,
10320                        AtomicOrdering::SequentiallyConsistent,
10321                    )
10322                    .unwrap();
10323                self.annotate_user_memaccess(
10324                    memory_index,
10325                    memarg,
10326                    0,
10327                    old.as_instruction_value().unwrap(),
10328                )?;
10329                let old = err!(
10330                    self.builder
10331                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10332                );
10333                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10334            }
10335            Operator::I64AtomicRmwAdd { ref memarg } => {
10336                let value = self.state.pop1()?.into_int_value();
10337                let offset = self.state.pop1()?.into_int_value();
10338                let memory_index = MemoryIndex::from_u32(0);
10339                let effective_address = self.resolve_memory_ptr(
10340                    memory_index,
10341                    memarg,
10342                    self.intrinsics.ptr_ty,
10343                    offset,
10344                    8,
10345                )?;
10346                self.trap_if_misaligned(memarg, effective_address, 8)?;
10347                let old = self
10348                    .builder
10349                    .build_atomicrmw(
10350                        AtomicRMWBinOp::Add,
10351                        effective_address,
10352                        value,
10353                        AtomicOrdering::SequentiallyConsistent,
10354                    )
10355                    .unwrap();
10356                self.annotate_user_memaccess(
10357                    memory_index,
10358                    memarg,
10359                    0,
10360                    old.as_instruction_value().unwrap(),
10361                )?;
10362                self.state.push1(old);
10363            }
10364            Operator::I32AtomicRmw8SubU { ref memarg } => {
10365                let value = self.state.pop1()?.into_int_value();
10366                let offset = self.state.pop1()?.into_int_value();
10367                let memory_index = MemoryIndex::from_u32(0);
10368                let effective_address = self.resolve_memory_ptr(
10369                    memory_index,
10370                    memarg,
10371                    self.intrinsics.ptr_ty,
10372                    offset,
10373                    1,
10374                )?;
10375                self.trap_if_misaligned(memarg, effective_address, 1)?;
10376                let narrow_value = err!(self.builder.build_int_truncate(
10377                    value,
10378                    self.intrinsics.i8_ty,
10379                    ""
10380                ));
10381                let old = self
10382                    .builder
10383                    .build_atomicrmw(
10384                        AtomicRMWBinOp::Sub,
10385                        effective_address,
10386                        narrow_value,
10387                        AtomicOrdering::SequentiallyConsistent,
10388                    )
10389                    .unwrap();
10390                self.annotate_user_memaccess(
10391                    memory_index,
10392                    memarg,
10393                    0,
10394                    old.as_instruction_value().unwrap(),
10395                )?;
10396                let old = err!(
10397                    self.builder
10398                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10399                );
10400                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10401            }
10402            Operator::I32AtomicRmw16SubU { ref memarg } => {
10403                let value = self.state.pop1()?.into_int_value();
10404                let offset = self.state.pop1()?.into_int_value();
10405                let memory_index = MemoryIndex::from_u32(0);
10406                let effective_address = self.resolve_memory_ptr(
10407                    memory_index,
10408                    memarg,
10409                    self.intrinsics.ptr_ty,
10410                    offset,
10411                    2,
10412                )?;
10413                self.trap_if_misaligned(memarg, effective_address, 2)?;
10414                let narrow_value = err!(self.builder.build_int_truncate(
10415                    value,
10416                    self.intrinsics.i16_ty,
10417                    ""
10418                ));
10419                let old = self
10420                    .builder
10421                    .build_atomicrmw(
10422                        AtomicRMWBinOp::Sub,
10423                        effective_address,
10424                        narrow_value,
10425                        AtomicOrdering::SequentiallyConsistent,
10426                    )
10427                    .unwrap();
10428                self.annotate_user_memaccess(
10429                    memory_index,
10430                    memarg,
10431                    0,
10432                    old.as_instruction_value().unwrap(),
10433                )?;
10434                let old = err!(
10435                    self.builder
10436                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10437                );
10438                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10439            }
10440            Operator::I32AtomicRmwSub { ref memarg } => {
10441                let value = self.state.pop1()?.into_int_value();
10442                let offset = self.state.pop1()?.into_int_value();
10443                let memory_index = MemoryIndex::from_u32(0);
10444                let effective_address = self.resolve_memory_ptr(
10445                    memory_index,
10446                    memarg,
10447                    self.intrinsics.ptr_ty,
10448                    offset,
10449                    4,
10450                )?;
10451                self.trap_if_misaligned(memarg, effective_address, 4)?;
10452                let old = self
10453                    .builder
10454                    .build_atomicrmw(
10455                        AtomicRMWBinOp::Sub,
10456                        effective_address,
10457                        value,
10458                        AtomicOrdering::SequentiallyConsistent,
10459                    )
10460                    .unwrap();
10461                self.annotate_user_memaccess(
10462                    memory_index,
10463                    memarg,
10464                    0,
10465                    old.as_instruction_value().unwrap(),
10466                )?;
10467                self.state.push1(old);
10468            }
10469            Operator::I64AtomicRmw8SubU { ref memarg } => {
10470                let value = self.state.pop1()?.into_int_value();
10471                let offset = self.state.pop1()?.into_int_value();
10472                let memory_index = MemoryIndex::from_u32(0);
10473                let effective_address = self.resolve_memory_ptr(
10474                    memory_index,
10475                    memarg,
10476                    self.intrinsics.ptr_ty,
10477                    offset,
10478                    1,
10479                )?;
10480                self.trap_if_misaligned(memarg, effective_address, 1)?;
10481                let narrow_value = err!(self.builder.build_int_truncate(
10482                    value,
10483                    self.intrinsics.i8_ty,
10484                    ""
10485                ));
10486                let old = self
10487                    .builder
10488                    .build_atomicrmw(
10489                        AtomicRMWBinOp::Sub,
10490                        effective_address,
10491                        narrow_value,
10492                        AtomicOrdering::SequentiallyConsistent,
10493                    )
10494                    .unwrap();
10495                self.annotate_user_memaccess(
10496                    memory_index,
10497                    memarg,
10498                    0,
10499                    old.as_instruction_value().unwrap(),
10500                )?;
10501                let old = err!(
10502                    self.builder
10503                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10504                );
10505                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10506            }
10507            Operator::I64AtomicRmw16SubU { ref memarg } => {
10508                let value = self.state.pop1()?.into_int_value();
10509                let offset = self.state.pop1()?.into_int_value();
10510                let memory_index = MemoryIndex::from_u32(0);
10511                let effective_address = self.resolve_memory_ptr(
10512                    memory_index,
10513                    memarg,
10514                    self.intrinsics.ptr_ty,
10515                    offset,
10516                    2,
10517                )?;
10518                self.trap_if_misaligned(memarg, effective_address, 2)?;
10519                let narrow_value = err!(self.builder.build_int_truncate(
10520                    value,
10521                    self.intrinsics.i16_ty,
10522                    ""
10523                ));
10524                let old = self
10525                    .builder
10526                    .build_atomicrmw(
10527                        AtomicRMWBinOp::Sub,
10528                        effective_address,
10529                        narrow_value,
10530                        AtomicOrdering::SequentiallyConsistent,
10531                    )
10532                    .unwrap();
10533                self.annotate_user_memaccess(
10534                    memory_index,
10535                    memarg,
10536                    0,
10537                    old.as_instruction_value().unwrap(),
10538                )?;
10539                let old = err!(
10540                    self.builder
10541                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10542                );
10543                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10544            }
10545            Operator::I64AtomicRmw32SubU { ref memarg } => {
10546                let value = self.state.pop1()?.into_int_value();
10547                let offset = self.state.pop1()?.into_int_value();
10548                let memory_index = MemoryIndex::from_u32(0);
10549                let effective_address = self.resolve_memory_ptr(
10550                    memory_index,
10551                    memarg,
10552                    self.intrinsics.ptr_ty,
10553                    offset,
10554                    4,
10555                )?;
10556                self.trap_if_misaligned(memarg, effective_address, 4)?;
10557                let narrow_value = err!(self.builder.build_int_truncate(
10558                    value,
10559                    self.intrinsics.i32_ty,
10560                    ""
10561                ));
10562                let old = self
10563                    .builder
10564                    .build_atomicrmw(
10565                        AtomicRMWBinOp::Sub,
10566                        effective_address,
10567                        narrow_value,
10568                        AtomicOrdering::SequentiallyConsistent,
10569                    )
10570                    .unwrap();
10571                self.annotate_user_memaccess(
10572                    memory_index,
10573                    memarg,
10574                    0,
10575                    old.as_instruction_value().unwrap(),
10576                )?;
10577                let old = err!(
10578                    self.builder
10579                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10580                );
10581                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10582            }
10583            Operator::I64AtomicRmwSub { ref memarg } => {
10584                let value = self.state.pop1()?.into_int_value();
10585                let offset = self.state.pop1()?.into_int_value();
10586                let memory_index = MemoryIndex::from_u32(0);
10587                let effective_address = self.resolve_memory_ptr(
10588                    memory_index,
10589                    memarg,
10590                    self.intrinsics.ptr_ty,
10591                    offset,
10592                    8,
10593                )?;
10594                self.trap_if_misaligned(memarg, effective_address, 8)?;
10595                let old = self
10596                    .builder
10597                    .build_atomicrmw(
10598                        AtomicRMWBinOp::Sub,
10599                        effective_address,
10600                        value,
10601                        AtomicOrdering::SequentiallyConsistent,
10602                    )
10603                    .unwrap();
10604                self.annotate_user_memaccess(
10605                    memory_index,
10606                    memarg,
10607                    0,
10608                    old.as_instruction_value().unwrap(),
10609                )?;
10610                self.state.push1(old);
10611            }
10612            Operator::I32AtomicRmw8AndU { ref memarg } => {
10613                let value = self.state.pop1()?.into_int_value();
10614                let offset = self.state.pop1()?.into_int_value();
10615                let memory_index = MemoryIndex::from_u32(0);
10616                let effective_address = self.resolve_memory_ptr(
10617                    memory_index,
10618                    memarg,
10619                    self.intrinsics.ptr_ty,
10620                    offset,
10621                    1,
10622                )?;
10623                self.trap_if_misaligned(memarg, effective_address, 1)?;
10624                let narrow_value = err!(self.builder.build_int_truncate(
10625                    value,
10626                    self.intrinsics.i8_ty,
10627                    ""
10628                ));
10629                let old = self
10630                    .builder
10631                    .build_atomicrmw(
10632                        AtomicRMWBinOp::And,
10633                        effective_address,
10634                        narrow_value,
10635                        AtomicOrdering::SequentiallyConsistent,
10636                    )
10637                    .unwrap();
10638                self.annotate_user_memaccess(
10639                    memory_index,
10640                    memarg,
10641                    0,
10642                    old.as_instruction_value().unwrap(),
10643                )?;
10644                let old = err!(
10645                    self.builder
10646                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10647                );
10648                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10649            }
10650            Operator::I32AtomicRmw16AndU { ref memarg } => {
10651                let value = self.state.pop1()?.into_int_value();
10652                let offset = self.state.pop1()?.into_int_value();
10653                let memory_index = MemoryIndex::from_u32(0);
10654                let effective_address = self.resolve_memory_ptr(
10655                    memory_index,
10656                    memarg,
10657                    self.intrinsics.ptr_ty,
10658                    offset,
10659                    2,
10660                )?;
10661                self.trap_if_misaligned(memarg, effective_address, 2)?;
10662                let narrow_value = err!(self.builder.build_int_truncate(
10663                    value,
10664                    self.intrinsics.i16_ty,
10665                    ""
10666                ));
10667                let old = self
10668                    .builder
10669                    .build_atomicrmw(
10670                        AtomicRMWBinOp::And,
10671                        effective_address,
10672                        narrow_value,
10673                        AtomicOrdering::SequentiallyConsistent,
10674                    )
10675                    .unwrap();
10676                self.annotate_user_memaccess(
10677                    memory_index,
10678                    memarg,
10679                    0,
10680                    old.as_instruction_value().unwrap(),
10681                )?;
10682                let old = err!(
10683                    self.builder
10684                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10685                );
10686                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10687            }
10688            Operator::I32AtomicRmwAnd { ref memarg } => {
10689                let value = self.state.pop1()?.into_int_value();
10690                let offset = self.state.pop1()?.into_int_value();
10691                let memory_index = MemoryIndex::from_u32(0);
10692                let effective_address = self.resolve_memory_ptr(
10693                    memory_index,
10694                    memarg,
10695                    self.intrinsics.ptr_ty,
10696                    offset,
10697                    4,
10698                )?;
10699                self.trap_if_misaligned(memarg, effective_address, 4)?;
10700                let old = self
10701                    .builder
10702                    .build_atomicrmw(
10703                        AtomicRMWBinOp::And,
10704                        effective_address,
10705                        value,
10706                        AtomicOrdering::SequentiallyConsistent,
10707                    )
10708                    .unwrap();
10709                self.annotate_user_memaccess(
10710                    memory_index,
10711                    memarg,
10712                    0,
10713                    old.as_instruction_value().unwrap(),
10714                )?;
10715                self.state.push1(old);
10716            }
10717            Operator::I64AtomicRmw8AndU { ref memarg } => {
10718                let value = self.state.pop1()?.into_int_value();
10719                let offset = self.state.pop1()?.into_int_value();
10720                let memory_index = MemoryIndex::from_u32(0);
10721                let effective_address = self.resolve_memory_ptr(
10722                    memory_index,
10723                    memarg,
10724                    self.intrinsics.ptr_ty,
10725                    offset,
10726                    1,
10727                )?;
10728                self.trap_if_misaligned(memarg, effective_address, 1)?;
10729                let narrow_value = err!(self.builder.build_int_truncate(
10730                    value,
10731                    self.intrinsics.i8_ty,
10732                    ""
10733                ));
10734                let old = self
10735                    .builder
10736                    .build_atomicrmw(
10737                        AtomicRMWBinOp::And,
10738                        effective_address,
10739                        narrow_value,
10740                        AtomicOrdering::SequentiallyConsistent,
10741                    )
10742                    .unwrap();
10743                self.annotate_user_memaccess(
10744                    memory_index,
10745                    memarg,
10746                    0,
10747                    old.as_instruction_value().unwrap(),
10748                )?;
10749                let old = err!(
10750                    self.builder
10751                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10752                );
10753                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10754            }
10755            Operator::I64AtomicRmw16AndU { ref memarg } => {
10756                let value = self.state.pop1()?.into_int_value();
10757                let offset = self.state.pop1()?.into_int_value();
10758                let memory_index = MemoryIndex::from_u32(0);
10759                let effective_address = self.resolve_memory_ptr(
10760                    memory_index,
10761                    memarg,
10762                    self.intrinsics.ptr_ty,
10763                    offset,
10764                    2,
10765                )?;
10766                self.trap_if_misaligned(memarg, effective_address, 2)?;
10767                let narrow_value = err!(self.builder.build_int_truncate(
10768                    value,
10769                    self.intrinsics.i16_ty,
10770                    ""
10771                ));
10772                let old = self
10773                    .builder
10774                    .build_atomicrmw(
10775                        AtomicRMWBinOp::And,
10776                        effective_address,
10777                        narrow_value,
10778                        AtomicOrdering::SequentiallyConsistent,
10779                    )
10780                    .unwrap();
10781                self.annotate_user_memaccess(
10782                    memory_index,
10783                    memarg,
10784                    0,
10785                    old.as_instruction_value().unwrap(),
10786                )?;
10787                let old = err!(
10788                    self.builder
10789                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10790                );
10791                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10792            }
10793            Operator::I64AtomicRmw32AndU { ref memarg } => {
10794                let value = self.state.pop1()?.into_int_value();
10795                let offset = self.state.pop1()?.into_int_value();
10796                let memory_index = MemoryIndex::from_u32(0);
10797                let effective_address = self.resolve_memory_ptr(
10798                    memory_index,
10799                    memarg,
10800                    self.intrinsics.ptr_ty,
10801                    offset,
10802                    4,
10803                )?;
10804                self.trap_if_misaligned(memarg, effective_address, 4)?;
10805                let narrow_value = err!(self.builder.build_int_truncate(
10806                    value,
10807                    self.intrinsics.i32_ty,
10808                    ""
10809                ));
10810                let old = self
10811                    .builder
10812                    .build_atomicrmw(
10813                        AtomicRMWBinOp::And,
10814                        effective_address,
10815                        narrow_value,
10816                        AtomicOrdering::SequentiallyConsistent,
10817                    )
10818                    .unwrap();
10819                self.annotate_user_memaccess(
10820                    memory_index,
10821                    memarg,
10822                    0,
10823                    old.as_instruction_value().unwrap(),
10824                )?;
10825                let old = err!(
10826                    self.builder
10827                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10828                );
10829                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10830            }
10831            Operator::I64AtomicRmwAnd { ref memarg } => {
10832                let value = self.state.pop1()?.into_int_value();
10833                let offset = self.state.pop1()?.into_int_value();
10834                let memory_index = MemoryIndex::from_u32(0);
10835                let effective_address = self.resolve_memory_ptr(
10836                    memory_index,
10837                    memarg,
10838                    self.intrinsics.ptr_ty,
10839                    offset,
10840                    8,
10841                )?;
10842                self.trap_if_misaligned(memarg, effective_address, 8)?;
10843                let old = self
10844                    .builder
10845                    .build_atomicrmw(
10846                        AtomicRMWBinOp::And,
10847                        effective_address,
10848                        value,
10849                        AtomicOrdering::SequentiallyConsistent,
10850                    )
10851                    .unwrap();
10852                self.annotate_user_memaccess(
10853                    memory_index,
10854                    memarg,
10855                    0,
10856                    old.as_instruction_value().unwrap(),
10857                )?;
10858                self.state.push1(old);
10859            }
10860            Operator::I32AtomicRmw8OrU { ref memarg } => {
10861                let value = self.state.pop1()?.into_int_value();
10862                let offset = self.state.pop1()?.into_int_value();
10863                let memory_index = MemoryIndex::from_u32(0);
10864                let effective_address = self.resolve_memory_ptr(
10865                    memory_index,
10866                    memarg,
10867                    self.intrinsics.ptr_ty,
10868                    offset,
10869                    1,
10870                )?;
10871                self.trap_if_misaligned(memarg, effective_address, 1)?;
10872                let narrow_value = err!(self.builder.build_int_truncate(
10873                    value,
10874                    self.intrinsics.i8_ty,
10875                    ""
10876                ));
10877                let old = self
10878                    .builder
10879                    .build_atomicrmw(
10880                        AtomicRMWBinOp::Or,
10881                        effective_address,
10882                        narrow_value,
10883                        AtomicOrdering::SequentiallyConsistent,
10884                    )
10885                    .unwrap();
10886                self.annotate_user_memaccess(
10887                    memory_index,
10888                    memarg,
10889                    0,
10890                    old.as_instruction_value().unwrap(),
10891                )?;
10892                let old = err!(
10893                    self.builder
10894                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10895                );
10896                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10897            }
10898            Operator::I32AtomicRmw16OrU { ref memarg } => {
10899                let value = self.state.pop1()?.into_int_value();
10900                let offset = self.state.pop1()?.into_int_value();
10901                let memory_index = MemoryIndex::from_u32(0);
10902                let effective_address = self.resolve_memory_ptr(
10903                    memory_index,
10904                    memarg,
10905                    self.intrinsics.ptr_ty,
10906                    offset,
10907                    2,
10908                )?;
10909                self.trap_if_misaligned(memarg, effective_address, 2)?;
10910                let narrow_value = err!(self.builder.build_int_truncate(
10911                    value,
10912                    self.intrinsics.i16_ty,
10913                    ""
10914                ));
10915                let old = self
10916                    .builder
10917                    .build_atomicrmw(
10918                        AtomicRMWBinOp::Or,
10919                        effective_address,
10920                        narrow_value,
10921                        AtomicOrdering::SequentiallyConsistent,
10922                    )
10923                    .unwrap();
10924                self.annotate_user_memaccess(
10925                    memory_index,
10926                    memarg,
10927                    0,
10928                    old.as_instruction_value().unwrap(),
10929                )?;
10930                let old = err!(
10931                    self.builder
10932                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10933                );
10934                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10935            }
10936            Operator::I32AtomicRmwOr { ref memarg } => {
10937                let value = self.state.pop1()?.into_int_value();
10938                let offset = self.state.pop1()?.into_int_value();
10939                let memory_index = MemoryIndex::from_u32(0);
10940                let effective_address = self.resolve_memory_ptr(
10941                    memory_index,
10942                    memarg,
10943                    self.intrinsics.ptr_ty,
10944                    offset,
10945                    4,
10946                )?;
10947                self.trap_if_misaligned(memarg, effective_address, 4)?;
10948                let old = self
10949                    .builder
10950                    .build_atomicrmw(
10951                        AtomicRMWBinOp::Or,
10952                        effective_address,
10953                        value,
10954                        AtomicOrdering::SequentiallyConsistent,
10955                    )
10956                    .unwrap();
10957                self.annotate_user_memaccess(
10958                    memory_index,
10959                    memarg,
10960                    0,
10961                    old.as_instruction_value().unwrap(),
10962                )?;
10963                let old = err!(
10964                    self.builder
10965                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10966                );
10967                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10968            }
10969            Operator::I64AtomicRmw8OrU { ref memarg } => {
10970                let value = self.state.pop1()?.into_int_value();
10971                let offset = self.state.pop1()?.into_int_value();
10972                let memory_index = MemoryIndex::from_u32(0);
10973                let effective_address = self.resolve_memory_ptr(
10974                    memory_index,
10975                    memarg,
10976                    self.intrinsics.ptr_ty,
10977                    offset,
10978                    1,
10979                )?;
10980                self.trap_if_misaligned(memarg, effective_address, 1)?;
10981                let narrow_value = err!(self.builder.build_int_truncate(
10982                    value,
10983                    self.intrinsics.i8_ty,
10984                    ""
10985                ));
10986                let old = self
10987                    .builder
10988                    .build_atomicrmw(
10989                        AtomicRMWBinOp::Or,
10990                        effective_address,
10991                        narrow_value,
10992                        AtomicOrdering::SequentiallyConsistent,
10993                    )
10994                    .unwrap();
10995                self.annotate_user_memaccess(
10996                    memory_index,
10997                    memarg,
10998                    0,
10999                    old.as_instruction_value().unwrap(),
11000                )?;
11001                let old = err!(
11002                    self.builder
11003                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11004                );
11005                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11006            }
11007            Operator::I64AtomicRmw16OrU { ref memarg } => {
11008                let value = self.state.pop1()?.into_int_value();
11009                let offset = self.state.pop1()?.into_int_value();
11010                let memory_index = MemoryIndex::from_u32(0);
11011                let effective_address = self.resolve_memory_ptr(
11012                    memory_index,
11013                    memarg,
11014                    self.intrinsics.ptr_ty,
11015                    offset,
11016                    2,
11017                )?;
11018                self.trap_if_misaligned(memarg, effective_address, 2)?;
11019                let narrow_value = err!(self.builder.build_int_truncate(
11020                    value,
11021                    self.intrinsics.i16_ty,
11022                    ""
11023                ));
11024                let old = self
11025                    .builder
11026                    .build_atomicrmw(
11027                        AtomicRMWBinOp::Or,
11028                        effective_address,
11029                        narrow_value,
11030                        AtomicOrdering::SequentiallyConsistent,
11031                    )
11032                    .unwrap();
11033                self.annotate_user_memaccess(
11034                    memory_index,
11035                    memarg,
11036                    0,
11037                    old.as_instruction_value().unwrap(),
11038                )?;
11039                let old = err!(
11040                    self.builder
11041                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11042                );
11043                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11044            }
11045            Operator::I64AtomicRmw32OrU { ref memarg } => {
11046                let value = self.state.pop1()?.into_int_value();
11047                let offset = self.state.pop1()?.into_int_value();
11048                let memory_index = MemoryIndex::from_u32(0);
11049                let effective_address = self.resolve_memory_ptr(
11050                    memory_index,
11051                    memarg,
11052                    self.intrinsics.ptr_ty,
11053                    offset,
11054                    4,
11055                )?;
11056                self.trap_if_misaligned(memarg, effective_address, 4)?;
11057                let narrow_value = err!(self.builder.build_int_truncate(
11058                    value,
11059                    self.intrinsics.i32_ty,
11060                    ""
11061                ));
11062                let old = self
11063                    .builder
11064                    .build_atomicrmw(
11065                        AtomicRMWBinOp::Or,
11066                        effective_address,
11067                        narrow_value,
11068                        AtomicOrdering::SequentiallyConsistent,
11069                    )
11070                    .unwrap();
11071                self.annotate_user_memaccess(
11072                    memory_index,
11073                    memarg,
11074                    0,
11075                    old.as_instruction_value().unwrap(),
11076                )?;
11077                let old = err!(
11078                    self.builder
11079                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11080                );
11081                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11082            }
11083            Operator::I64AtomicRmwOr { ref memarg } => {
11084                let value = self.state.pop1()?.into_int_value();
11085                let offset = self.state.pop1()?.into_int_value();
11086                let memory_index = MemoryIndex::from_u32(0);
11087                let effective_address = self.resolve_memory_ptr(
11088                    memory_index,
11089                    memarg,
11090                    self.intrinsics.ptr_ty,
11091                    offset,
11092                    8,
11093                )?;
11094                self.trap_if_misaligned(memarg, effective_address, 8)?;
11095                let old = self
11096                    .builder
11097                    .build_atomicrmw(
11098                        AtomicRMWBinOp::Or,
11099                        effective_address,
11100                        value,
11101                        AtomicOrdering::SequentiallyConsistent,
11102                    )
11103                    .unwrap();
11104                self.annotate_user_memaccess(
11105                    memory_index,
11106                    memarg,
11107                    0,
11108                    old.as_instruction_value().unwrap(),
11109                )?;
11110                self.state.push1(old);
11111            }
11112            Operator::I32AtomicRmw8XorU { ref memarg } => {
11113                let value = self.state.pop1()?.into_int_value();
11114                let offset = self.state.pop1()?.into_int_value();
11115                let memory_index = MemoryIndex::from_u32(0);
11116                let effective_address = self.resolve_memory_ptr(
11117                    memory_index,
11118                    memarg,
11119                    self.intrinsics.ptr_ty,
11120                    offset,
11121                    1,
11122                )?;
11123                self.trap_if_misaligned(memarg, effective_address, 2)?;
11124                let narrow_value = err!(self.builder.build_int_truncate(
11125                    value,
11126                    self.intrinsics.i8_ty,
11127                    ""
11128                ));
11129                let old = self
11130                    .builder
11131                    .build_atomicrmw(
11132                        AtomicRMWBinOp::Xor,
11133                        effective_address,
11134                        narrow_value,
11135                        AtomicOrdering::SequentiallyConsistent,
11136                    )
11137                    .unwrap();
11138                self.annotate_user_memaccess(
11139                    memory_index,
11140                    memarg,
11141                    0,
11142                    old.as_instruction_value().unwrap(),
11143                )?;
11144                let old = err!(
11145                    self.builder
11146                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11147                );
11148                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11149            }
11150            Operator::I32AtomicRmw16XorU { ref memarg } => {
11151                let value = self.state.pop1()?.into_int_value();
11152                let offset = self.state.pop1()?.into_int_value();
11153                let memory_index = MemoryIndex::from_u32(0);
11154                let effective_address = self.resolve_memory_ptr(
11155                    memory_index,
11156                    memarg,
11157                    self.intrinsics.ptr_ty,
11158                    offset,
11159                    2,
11160                )?;
11161                self.trap_if_misaligned(memarg, effective_address, 2)?;
11162                let narrow_value = err!(self.builder.build_int_truncate(
11163                    value,
11164                    self.intrinsics.i16_ty,
11165                    ""
11166                ));
11167                let old = self
11168                    .builder
11169                    .build_atomicrmw(
11170                        AtomicRMWBinOp::Xor,
11171                        effective_address,
11172                        narrow_value,
11173                        AtomicOrdering::SequentiallyConsistent,
11174                    )
11175                    .unwrap();
11176                self.annotate_user_memaccess(
11177                    memory_index,
11178                    memarg,
11179                    0,
11180                    old.as_instruction_value().unwrap(),
11181                )?;
11182                let old = err!(
11183                    self.builder
11184                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11185                );
11186                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11187            }
11188            Operator::I32AtomicRmwXor { ref memarg } => {
11189                let value = self.state.pop1()?.into_int_value();
11190                let offset = self.state.pop1()?.into_int_value();
11191                let memory_index = MemoryIndex::from_u32(0);
11192                let effective_address = self.resolve_memory_ptr(
11193                    memory_index,
11194                    memarg,
11195                    self.intrinsics.ptr_ty,
11196                    offset,
11197                    4,
11198                )?;
11199                self.trap_if_misaligned(memarg, effective_address, 4)?;
11200                let old = self
11201                    .builder
11202                    .build_atomicrmw(
11203                        AtomicRMWBinOp::Xor,
11204                        effective_address,
11205                        value,
11206                        AtomicOrdering::SequentiallyConsistent,
11207                    )
11208                    .unwrap();
11209                self.annotate_user_memaccess(
11210                    memory_index,
11211                    memarg,
11212                    0,
11213                    old.as_instruction_value().unwrap(),
11214                )?;
11215                self.state.push1(old);
11216            }
11217            Operator::I64AtomicRmw8XorU { ref memarg } => {
11218                let value = self.state.pop1()?.into_int_value();
11219                let offset = self.state.pop1()?.into_int_value();
11220                let memory_index = MemoryIndex::from_u32(0);
11221                let effective_address = self.resolve_memory_ptr(
11222                    memory_index,
11223                    memarg,
11224                    self.intrinsics.ptr_ty,
11225                    offset,
11226                    1,
11227                )?;
11228                self.trap_if_misaligned(memarg, effective_address, 1)?;
11229                let narrow_value = err!(self.builder.build_int_truncate(
11230                    value,
11231                    self.intrinsics.i8_ty,
11232                    ""
11233                ));
11234                let old = self
11235                    .builder
11236                    .build_atomicrmw(
11237                        AtomicRMWBinOp::Xor,
11238                        effective_address,
11239                        narrow_value,
11240                        AtomicOrdering::SequentiallyConsistent,
11241                    )
11242                    .unwrap();
11243                self.annotate_user_memaccess(
11244                    memory_index,
11245                    memarg,
11246                    0,
11247                    old.as_instruction_value().unwrap(),
11248                )?;
11249                let old = err!(
11250                    self.builder
11251                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11252                );
11253                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11254            }
11255            Operator::I64AtomicRmw16XorU { ref memarg } => {
11256                let value = self.state.pop1()?.into_int_value();
11257                let offset = self.state.pop1()?.into_int_value();
11258                let memory_index = MemoryIndex::from_u32(0);
11259                let effective_address = self.resolve_memory_ptr(
11260                    memory_index,
11261                    memarg,
11262                    self.intrinsics.ptr_ty,
11263                    offset,
11264                    2,
11265                )?;
11266                self.trap_if_misaligned(memarg, effective_address, 2)?;
11267                let narrow_value = err!(self.builder.build_int_truncate(
11268                    value,
11269                    self.intrinsics.i16_ty,
11270                    ""
11271                ));
11272                let old = self
11273                    .builder
11274                    .build_atomicrmw(
11275                        AtomicRMWBinOp::Xor,
11276                        effective_address,
11277                        narrow_value,
11278                        AtomicOrdering::SequentiallyConsistent,
11279                    )
11280                    .unwrap();
11281                self.annotate_user_memaccess(
11282                    memory_index,
11283                    memarg,
11284                    0,
11285                    old.as_instruction_value().unwrap(),
11286                )?;
11287                let old = err!(
11288                    self.builder
11289                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11290                );
11291                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11292            }
11293            Operator::I64AtomicRmw32XorU { ref memarg } => {
11294                let value = self.state.pop1()?.into_int_value();
11295                let offset = self.state.pop1()?.into_int_value();
11296                let memory_index = MemoryIndex::from_u32(0);
11297                let effective_address = self.resolve_memory_ptr(
11298                    memory_index,
11299                    memarg,
11300                    self.intrinsics.ptr_ty,
11301                    offset,
11302                    4,
11303                )?;
11304                self.trap_if_misaligned(memarg, effective_address, 4)?;
11305                let narrow_value = err!(self.builder.build_int_truncate(
11306                    value,
11307                    self.intrinsics.i32_ty,
11308                    ""
11309                ));
11310                let old = self
11311                    .builder
11312                    .build_atomicrmw(
11313                        AtomicRMWBinOp::Xor,
11314                        effective_address,
11315                        narrow_value,
11316                        AtomicOrdering::SequentiallyConsistent,
11317                    )
11318                    .unwrap();
11319                self.annotate_user_memaccess(
11320                    memory_index,
11321                    memarg,
11322                    0,
11323                    old.as_instruction_value().unwrap(),
11324                )?;
11325                let old = err!(
11326                    self.builder
11327                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11328                );
11329                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11330            }
11331            Operator::I64AtomicRmwXor { ref memarg } => {
11332                let value = self.state.pop1()?.into_int_value();
11333                let offset = self.state.pop1()?.into_int_value();
11334                let memory_index = MemoryIndex::from_u32(0);
11335                let effective_address = self.resolve_memory_ptr(
11336                    memory_index,
11337                    memarg,
11338                    self.intrinsics.ptr_ty,
11339                    offset,
11340                    8,
11341                )?;
11342                self.trap_if_misaligned(memarg, effective_address, 8)?;
11343                let old = self
11344                    .builder
11345                    .build_atomicrmw(
11346                        AtomicRMWBinOp::Xor,
11347                        effective_address,
11348                        value,
11349                        AtomicOrdering::SequentiallyConsistent,
11350                    )
11351                    .unwrap();
11352                self.annotate_user_memaccess(
11353                    memory_index,
11354                    memarg,
11355                    0,
11356                    old.as_instruction_value().unwrap(),
11357                )?;
11358                self.state.push1(old);
11359            }
11360            Operator::I32AtomicRmw8XchgU { ref memarg } => {
11361                let value = self.state.pop1()?.into_int_value();
11362                let offset = self.state.pop1()?.into_int_value();
11363                let memory_index = MemoryIndex::from_u32(0);
11364                let effective_address = self.resolve_memory_ptr(
11365                    memory_index,
11366                    memarg,
11367                    self.intrinsics.ptr_ty,
11368                    offset,
11369                    1,
11370                )?;
11371                self.trap_if_misaligned(memarg, effective_address, 1)?;
11372                let narrow_value = err!(self.builder.build_int_truncate(
11373                    value,
11374                    self.intrinsics.i8_ty,
11375                    ""
11376                ));
11377                let old = self
11378                    .builder
11379                    .build_atomicrmw(
11380                        AtomicRMWBinOp::Xchg,
11381                        effective_address,
11382                        narrow_value,
11383                        AtomicOrdering::SequentiallyConsistent,
11384                    )
11385                    .unwrap();
11386                self.annotate_user_memaccess(
11387                    memory_index,
11388                    memarg,
11389                    0,
11390                    old.as_instruction_value().unwrap(),
11391                )?;
11392                let old = err!(
11393                    self.builder
11394                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11395                );
11396                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11397            }
11398            Operator::I32AtomicRmw16XchgU { ref memarg } => {
11399                let value = self.state.pop1()?.into_int_value();
11400                let offset = self.state.pop1()?.into_int_value();
11401                let memory_index = MemoryIndex::from_u32(0);
11402                let effective_address = self.resolve_memory_ptr(
11403                    memory_index,
11404                    memarg,
11405                    self.intrinsics.ptr_ty,
11406                    offset,
11407                    2,
11408                )?;
11409                self.trap_if_misaligned(memarg, effective_address, 2)?;
11410                let narrow_value = err!(self.builder.build_int_truncate(
11411                    value,
11412                    self.intrinsics.i16_ty,
11413                    ""
11414                ));
11415                let old = self
11416                    .builder
11417                    .build_atomicrmw(
11418                        AtomicRMWBinOp::Xchg,
11419                        effective_address,
11420                        narrow_value,
11421                        AtomicOrdering::SequentiallyConsistent,
11422                    )
11423                    .unwrap();
11424                self.annotate_user_memaccess(
11425                    memory_index,
11426                    memarg,
11427                    0,
11428                    old.as_instruction_value().unwrap(),
11429                )?;
11430                let old = err!(
11431                    self.builder
11432                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11433                );
11434                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11435            }
11436            Operator::I32AtomicRmwXchg { ref memarg } => {
11437                let value = self.state.pop1()?.into_int_value();
11438                let offset = self.state.pop1()?.into_int_value();
11439                let memory_index = MemoryIndex::from_u32(0);
11440                let effective_address = self.resolve_memory_ptr(
11441                    memory_index,
11442                    memarg,
11443                    self.intrinsics.ptr_ty,
11444                    offset,
11445                    4,
11446                )?;
11447                self.trap_if_misaligned(memarg, effective_address, 4)?;
11448                let old = self
11449                    .builder
11450                    .build_atomicrmw(
11451                        AtomicRMWBinOp::Xchg,
11452                        effective_address,
11453                        value,
11454                        AtomicOrdering::SequentiallyConsistent,
11455                    )
11456                    .unwrap();
11457                self.annotate_user_memaccess(
11458                    memory_index,
11459                    memarg,
11460                    0,
11461                    old.as_instruction_value().unwrap(),
11462                )?;
11463                self.state.push1(old);
11464            }
11465            Operator::I64AtomicRmw8XchgU { ref memarg } => {
11466                let value = self.state.pop1()?.into_int_value();
11467                let offset = self.state.pop1()?.into_int_value();
11468                let memory_index = MemoryIndex::from_u32(0);
11469                let effective_address = self.resolve_memory_ptr(
11470                    memory_index,
11471                    memarg,
11472                    self.intrinsics.ptr_ty,
11473                    offset,
11474                    1,
11475                )?;
11476                self.trap_if_misaligned(memarg, effective_address, 1)?;
11477                let narrow_value = err!(self.builder.build_int_truncate(
11478                    value,
11479                    self.intrinsics.i8_ty,
11480                    ""
11481                ));
11482                let old = self
11483                    .builder
11484                    .build_atomicrmw(
11485                        AtomicRMWBinOp::Xchg,
11486                        effective_address,
11487                        narrow_value,
11488                        AtomicOrdering::SequentiallyConsistent,
11489                    )
11490                    .unwrap();
11491                self.annotate_user_memaccess(
11492                    memory_index,
11493                    memarg,
11494                    0,
11495                    old.as_instruction_value().unwrap(),
11496                )?;
11497                let old = err!(
11498                    self.builder
11499                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11500                );
11501                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11502            }
11503            Operator::I64AtomicRmw16XchgU { ref memarg } => {
11504                let value = self.state.pop1()?.into_int_value();
11505                let offset = self.state.pop1()?.into_int_value();
11506                let memory_index = MemoryIndex::from_u32(0);
11507                let effective_address = self.resolve_memory_ptr(
11508                    memory_index,
11509                    memarg,
11510                    self.intrinsics.ptr_ty,
11511                    offset,
11512                    2,
11513                )?;
11514                self.trap_if_misaligned(memarg, effective_address, 2)?;
11515                let narrow_value = err!(self.builder.build_int_truncate(
11516                    value,
11517                    self.intrinsics.i16_ty,
11518                    ""
11519                ));
11520                let old = self
11521                    .builder
11522                    .build_atomicrmw(
11523                        AtomicRMWBinOp::Xchg,
11524                        effective_address,
11525                        narrow_value,
11526                        AtomicOrdering::SequentiallyConsistent,
11527                    )
11528                    .unwrap();
11529                self.annotate_user_memaccess(
11530                    memory_index,
11531                    memarg,
11532                    0,
11533                    old.as_instruction_value().unwrap(),
11534                )?;
11535                let old = err!(
11536                    self.builder
11537                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11538                );
11539                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11540            }
11541            Operator::I64AtomicRmw32XchgU { ref memarg } => {
11542                let value = self.state.pop1()?.into_int_value();
11543                let offset = self.state.pop1()?.into_int_value();
11544                let memory_index = MemoryIndex::from_u32(0);
11545                let effective_address = self.resolve_memory_ptr(
11546                    memory_index,
11547                    memarg,
11548                    self.intrinsics.ptr_ty,
11549                    offset,
11550                    4,
11551                )?;
11552                self.trap_if_misaligned(memarg, effective_address, 4)?;
11553                let narrow_value = err!(self.builder.build_int_truncate(
11554                    value,
11555                    self.intrinsics.i32_ty,
11556                    ""
11557                ));
11558                let old = self
11559                    .builder
11560                    .build_atomicrmw(
11561                        AtomicRMWBinOp::Xchg,
11562                        effective_address,
11563                        narrow_value,
11564                        AtomicOrdering::SequentiallyConsistent,
11565                    )
11566                    .unwrap();
11567                self.annotate_user_memaccess(
11568                    memory_index,
11569                    memarg,
11570                    0,
11571                    old.as_instruction_value().unwrap(),
11572                )?;
11573                let old = err!(
11574                    self.builder
11575                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11576                );
11577                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11578            }
11579            Operator::I64AtomicRmwXchg { ref memarg } => {
11580                let value = self.state.pop1()?.into_int_value();
11581                let offset = self.state.pop1()?.into_int_value();
11582                let memory_index = MemoryIndex::from_u32(0);
11583                let effective_address = self.resolve_memory_ptr(
11584                    memory_index,
11585                    memarg,
11586                    self.intrinsics.ptr_ty,
11587                    offset,
11588                    8,
11589                )?;
11590                self.trap_if_misaligned(memarg, effective_address, 8)?;
11591                let old = self
11592                    .builder
11593                    .build_atomicrmw(
11594                        AtomicRMWBinOp::Xchg,
11595                        effective_address,
11596                        value,
11597                        AtomicOrdering::SequentiallyConsistent,
11598                    )
11599                    .unwrap();
11600                self.annotate_user_memaccess(
11601                    memory_index,
11602                    memarg,
11603                    0,
11604                    old.as_instruction_value().unwrap(),
11605                )?;
11606                self.state.push1(old);
11607            }
11608            Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
11609                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11610                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11611                let new = self.apply_pending_canonicalization(new, new_info)?;
11612                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11613                let offset = self.state.pop1()?.into_int_value();
11614                let memory_index = MemoryIndex::from_u32(0);
11615                let effective_address = self.resolve_memory_ptr(
11616                    memory_index,
11617                    memarg,
11618                    self.intrinsics.ptr_ty,
11619                    offset,
11620                    1,
11621                )?;
11622                self.trap_if_misaligned(memarg, effective_address, 1)?;
11623                let narrow_cmp = err!(self.builder.build_int_truncate(
11624                    cmp,
11625                    self.intrinsics.i8_ty,
11626                    ""
11627                ));
11628                let narrow_new = err!(self.builder.build_int_truncate(
11629                    new,
11630                    self.intrinsics.i8_ty,
11631                    ""
11632                ));
11633                let old = self
11634                    .builder
11635                    .build_cmpxchg(
11636                        effective_address,
11637                        narrow_cmp,
11638                        narrow_new,
11639                        AtomicOrdering::SequentiallyConsistent,
11640                        AtomicOrdering::SequentiallyConsistent,
11641                    )
11642                    .unwrap();
11643                self.annotate_user_memaccess(
11644                    memory_index,
11645                    memarg,
11646                    0,
11647                    old.as_instruction_value().unwrap(),
11648                )?;
11649                let old = self
11650                    .builder
11651                    .build_extract_value(old, 0, "")
11652                    .unwrap()
11653                    .into_int_value();
11654                let old = err!(
11655                    self.builder
11656                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11657                );
11658                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11659            }
11660            Operator::I32AtomicRmw16CmpxchgU { ref memarg } => {
11661                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11662                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11663                let new = self.apply_pending_canonicalization(new, new_info)?;
11664                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11665                let offset = self.state.pop1()?.into_int_value();
11666                let memory_index = MemoryIndex::from_u32(0);
11667                let effective_address = self.resolve_memory_ptr(
11668                    memory_index,
11669                    memarg,
11670                    self.intrinsics.ptr_ty,
11671                    offset,
11672                    2,
11673                )?;
11674                self.trap_if_misaligned(memarg, effective_address, 2)?;
11675                let narrow_cmp = err!(self.builder.build_int_truncate(
11676                    cmp,
11677                    self.intrinsics.i16_ty,
11678                    ""
11679                ));
11680                let narrow_new = err!(self.builder.build_int_truncate(
11681                    new,
11682                    self.intrinsics.i16_ty,
11683                    ""
11684                ));
11685                let old = self
11686                    .builder
11687                    .build_cmpxchg(
11688                        effective_address,
11689                        narrow_cmp,
11690                        narrow_new,
11691                        AtomicOrdering::SequentiallyConsistent,
11692                        AtomicOrdering::SequentiallyConsistent,
11693                    )
11694                    .unwrap();
11695                self.annotate_user_memaccess(
11696                    memory_index,
11697                    memarg,
11698                    0,
11699                    old.as_instruction_value().unwrap(),
11700                )?;
11701                let old = self
11702                    .builder
11703                    .build_extract_value(old, 0, "")
11704                    .unwrap()
11705                    .into_int_value();
11706                let old = err!(
11707                    self.builder
11708                        .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11709                );
11710                self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11711            }
11712            Operator::I32AtomicRmwCmpxchg { ref memarg } => {
11713                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11714                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11715                let new = self.apply_pending_canonicalization(new, new_info)?;
11716                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11717                let offset = self.state.pop1()?.into_int_value();
11718                let memory_index = MemoryIndex::from_u32(0);
11719                let effective_address = self.resolve_memory_ptr(
11720                    memory_index,
11721                    memarg,
11722                    self.intrinsics.ptr_ty,
11723                    offset,
11724                    4,
11725                )?;
11726                self.trap_if_misaligned(memarg, effective_address, 4)?;
11727                let old = self
11728                    .builder
11729                    .build_cmpxchg(
11730                        effective_address,
11731                        cmp,
11732                        new,
11733                        AtomicOrdering::SequentiallyConsistent,
11734                        AtomicOrdering::SequentiallyConsistent,
11735                    )
11736                    .unwrap();
11737                self.annotate_user_memaccess(
11738                    memory_index,
11739                    memarg,
11740                    0,
11741                    old.as_instruction_value().unwrap(),
11742                )?;
11743                let old = err!(self.builder.build_extract_value(old, 0, ""));
11744                self.state.push1(old);
11745            }
11746            Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
11747                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11748                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11749                let new = self.apply_pending_canonicalization(new, new_info)?;
11750                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11751                let offset = self.state.pop1()?.into_int_value();
11752                let memory_index = MemoryIndex::from_u32(0);
11753                let effective_address = self.resolve_memory_ptr(
11754                    memory_index,
11755                    memarg,
11756                    self.intrinsics.ptr_ty,
11757                    offset,
11758                    1,
11759                )?;
11760                self.trap_if_misaligned(memarg, effective_address, 1)?;
11761                let narrow_cmp = err!(self.builder.build_int_truncate(
11762                    cmp,
11763                    self.intrinsics.i8_ty,
11764                    ""
11765                ));
11766                let narrow_new = err!(self.builder.build_int_truncate(
11767                    new,
11768                    self.intrinsics.i8_ty,
11769                    ""
11770                ));
11771                let old = self
11772                    .builder
11773                    .build_cmpxchg(
11774                        effective_address,
11775                        narrow_cmp,
11776                        narrow_new,
11777                        AtomicOrdering::SequentiallyConsistent,
11778                        AtomicOrdering::SequentiallyConsistent,
11779                    )
11780                    .unwrap();
11781                self.annotate_user_memaccess(
11782                    memory_index,
11783                    memarg,
11784                    0,
11785                    old.as_instruction_value().unwrap(),
11786                )?;
11787                let old = self
11788                    .builder
11789                    .build_extract_value(old, 0, "")
11790                    .unwrap()
11791                    .into_int_value();
11792                let old = err!(
11793                    self.builder
11794                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11795                );
11796                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11797            }
11798            Operator::I64AtomicRmw16CmpxchgU { ref memarg } => {
11799                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11800                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11801                let new = self.apply_pending_canonicalization(new, new_info)?;
11802                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11803                let offset = self.state.pop1()?.into_int_value();
11804                let memory_index = MemoryIndex::from_u32(0);
11805                let effective_address = self.resolve_memory_ptr(
11806                    memory_index,
11807                    memarg,
11808                    self.intrinsics.ptr_ty,
11809                    offset,
11810                    2,
11811                )?;
11812                self.trap_if_misaligned(memarg, effective_address, 2)?;
11813                let narrow_cmp = err!(self.builder.build_int_truncate(
11814                    cmp,
11815                    self.intrinsics.i16_ty,
11816                    ""
11817                ));
11818                let narrow_new = err!(self.builder.build_int_truncate(
11819                    new,
11820                    self.intrinsics.i16_ty,
11821                    ""
11822                ));
11823                let old = self
11824                    .builder
11825                    .build_cmpxchg(
11826                        effective_address,
11827                        narrow_cmp,
11828                        narrow_new,
11829                        AtomicOrdering::SequentiallyConsistent,
11830                        AtomicOrdering::SequentiallyConsistent,
11831                    )
11832                    .unwrap();
11833                self.annotate_user_memaccess(
11834                    memory_index,
11835                    memarg,
11836                    0,
11837                    old.as_instruction_value().unwrap(),
11838                )?;
11839                let old = self
11840                    .builder
11841                    .build_extract_value(old, 0, "")
11842                    .unwrap()
11843                    .into_int_value();
11844                let old = err!(
11845                    self.builder
11846                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11847                );
11848                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11849            }
11850            Operator::I64AtomicRmw32CmpxchgU { ref memarg } => {
11851                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11852                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11853                let new = self.apply_pending_canonicalization(new, new_info)?;
11854                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11855                let offset = self.state.pop1()?.into_int_value();
11856                let memory_index = MemoryIndex::from_u32(0);
11857                let effective_address = self.resolve_memory_ptr(
11858                    memory_index,
11859                    memarg,
11860                    self.intrinsics.ptr_ty,
11861                    offset,
11862                    4,
11863                )?;
11864                self.trap_if_misaligned(memarg, effective_address, 4)?;
11865                let narrow_cmp = err!(self.builder.build_int_truncate(
11866                    cmp,
11867                    self.intrinsics.i32_ty,
11868                    ""
11869                ));
11870                let narrow_new = err!(self.builder.build_int_truncate(
11871                    new,
11872                    self.intrinsics.i32_ty,
11873                    ""
11874                ));
11875                let old = self
11876                    .builder
11877                    .build_cmpxchg(
11878                        effective_address,
11879                        narrow_cmp,
11880                        narrow_new,
11881                        AtomicOrdering::SequentiallyConsistent,
11882                        AtomicOrdering::SequentiallyConsistent,
11883                    )
11884                    .unwrap();
11885                self.annotate_user_memaccess(
11886                    memory_index,
11887                    memarg,
11888                    0,
11889                    old.as_instruction_value().unwrap(),
11890                )?;
11891                let old = self
11892                    .builder
11893                    .build_extract_value(old, 0, "")
11894                    .unwrap()
11895                    .into_int_value();
11896                let old = err!(
11897                    self.builder
11898                        .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11899                );
11900                self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11901            }
11902            Operator::I64AtomicRmwCmpxchg { ref memarg } => {
11903                let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11904                let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11905                let new = self.apply_pending_canonicalization(new, new_info)?;
11906                let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11907                let offset = self.state.pop1()?.into_int_value();
11908                let memory_index = MemoryIndex::from_u32(0);
11909                let effective_address = self.resolve_memory_ptr(
11910                    memory_index,
11911                    memarg,
11912                    self.intrinsics.ptr_ty,
11913                    offset,
11914                    8,
11915                )?;
11916                self.trap_if_misaligned(memarg, effective_address, 8)?;
11917                let old = self
11918                    .builder
11919                    .build_cmpxchg(
11920                        effective_address,
11921                        cmp,
11922                        new,
11923                        AtomicOrdering::SequentiallyConsistent,
11924                        AtomicOrdering::SequentiallyConsistent,
11925                    )
11926                    .unwrap();
11927                self.annotate_user_memaccess(
11928                    memory_index,
11929                    memarg,
11930                    0,
11931                    old.as_instruction_value().unwrap(),
11932                )?;
11933                let old = err!(self.builder.build_extract_value(old, 0, ""));
11934                self.state.push1(old);
11935            }
11936
11937            Operator::MemoryGrow { mem } => {
11938                let memory_index = MemoryIndex::from_u32(mem);
11939                let delta = self.state.pop1()?;
11940                let grow_fn_ptr = self.ctx.memory_grow(memory_index, self.intrinsics)?;
11941                let grow = err!(self.builder.build_indirect_call(
11942                    self.intrinsics.memory_grow_ty,
11943                    grow_fn_ptr,
11944                    &[
11945                        vmctx.as_basic_value_enum().into(),
11946                        delta.into(),
11947                        self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11948                    ],
11949                    "",
11950                ));
11951                self.state.push1(grow.try_as_basic_value().unwrap_basic());
11952            }
11953            Operator::MemorySize { mem } => {
11954                let memory_index = MemoryIndex::from_u32(mem);
11955                let size_fn_ptr = self.ctx.memory_size(memory_index, self.intrinsics)?;
11956                let size = err!(self.builder.build_indirect_call(
11957                    self.intrinsics.memory_size_ty,
11958                    size_fn_ptr,
11959                    &[
11960                        vmctx.as_basic_value_enum().into(),
11961                        self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11962                    ],
11963                    "",
11964                ));
11965                //size.add_attribute(AttributeLoc::Function, self.intrinsics.readonly);
11966                self.state.push1(size.try_as_basic_value().unwrap_basic());
11967            }
11968            Operator::MemoryInit { data_index, mem } => {
11969                let (dest, src, len) = self.state.pop3()?;
11970                let mem = self.intrinsics.i32_ty.const_int(mem.into(), false);
11971                let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11972                err!(self.builder.build_call(
11973                    self.intrinsics.memory_init,
11974                    &[
11975                        vmctx.as_basic_value_enum().into(),
11976                        mem.into(),
11977                        segment.into(),
11978                        dest.into(),
11979                        src.into(),
11980                        len.into(),
11981                    ],
11982                    "",
11983                ));
11984            }
11985            Operator::DataDrop { data_index } => {
11986                let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11987                err!(self.builder.build_call(
11988                    self.intrinsics.data_drop,
11989                    &[vmctx.as_basic_value_enum().into(), segment.into()],
11990                    "",
11991                ));
11992            }
11993            Operator::MemoryCopy { dst_mem, src_mem } => {
11994                // ignored until we support multiple memories
11995                let _dst = dst_mem;
11996                let (memory_copy, src) = if let Some(local_memory_index) = self
11997                    .wasm_module
11998                    .local_memory_index(MemoryIndex::from_u32(src_mem))
11999                {
12000                    (self.intrinsics.memory_copy, local_memory_index.as_u32())
12001                } else {
12002                    (self.intrinsics.imported_memory_copy, src_mem)
12003                };
12004
12005                let (dest_pos, src_pos, len) = self.state.pop3()?;
12006                let src_index = self.intrinsics.i32_ty.const_int(src.into(), false);
12007                err!(self.builder.build_call(
12008                    memory_copy,
12009                    &[
12010                        vmctx.as_basic_value_enum().into(),
12011                        src_index.into(),
12012                        dest_pos.into(),
12013                        src_pos.into(),
12014                        len.into(),
12015                    ],
12016                    "",
12017                ));
12018            }
12019            Operator::MemoryFill { mem } => {
12020                let (memory_fill, mem) = if let Some(local_memory_index) = self
12021                    .wasm_module
12022                    .local_memory_index(MemoryIndex::from_u32(mem))
12023                {
12024                    (self.intrinsics.memory_fill, local_memory_index.as_u32())
12025                } else {
12026                    (self.intrinsics.imported_memory_fill, mem)
12027                };
12028
12029                let (dst, val, len) = self.state.pop3()?;
12030                let mem_index = self.intrinsics.i32_ty.const_int(mem.into(), false);
12031                err!(self.builder.build_call(
12032                    memory_fill,
12033                    &[
12034                        vmctx.as_basic_value_enum().into(),
12035                        mem_index.into(),
12036                        dst.into(),
12037                        val.into(),
12038                        len.into(),
12039                    ],
12040                    "",
12041                ));
12042            }
12043            /***************************
12044             * Reference types.
12045             * https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md
12046             ***************************/
12047            Operator::RefNull { hty } => {
12048                let ty = err!(wpheaptype_to_type(hty));
12049                let ty = type_to_llvm(self.intrinsics, ty)?;
12050                self.state.push1(ty.const_zero());
12051            }
12052            Operator::RefIsNull => {
12053                let value = self.state.pop1()?.into_pointer_value();
12054                let is_null = err!(self.builder.build_is_null(value, ""));
12055                let is_null = err!(self.builder.build_int_z_extend(
12056                    is_null,
12057                    self.intrinsics.i32_ty,
12058                    ""
12059                ));
12060                self.state.push1(is_null);
12061            }
12062            Operator::RefFunc { function_index } => {
12063                let index = self
12064                    .intrinsics
12065                    .i32_ty
12066                    .const_int(function_index.into(), false);
12067                let value = err!(self.builder.build_call(
12068                    self.intrinsics.func_ref,
12069                    &[self.ctx.basic().into(), index.into()],
12070                    "",
12071                ))
12072                .try_as_basic_value()
12073                .unwrap_basic();
12074                self.state.push1(value);
12075            }
12076            Operator::TableGet { table } => {
12077                let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12078                let elem = self.state.pop1()?;
12079                let table_get = if self
12080                    .wasm_module
12081                    .local_table_index(TableIndex::from_u32(table))
12082                    .is_some()
12083                {
12084                    self.intrinsics.table_get
12085                } else {
12086                    self.intrinsics.imported_table_get
12087                };
12088                let value = err!(self.builder.build_call(
12089                    table_get,
12090                    &[self.ctx.basic().into(), table_index.into(), elem.into()],
12091                    "",
12092                ))
12093                .try_as_basic_value()
12094                .unwrap_basic();
12095                let value = err!(
12096                    self.builder.build_bit_cast(
12097                        value,
12098                        type_to_llvm(
12099                            self.intrinsics,
12100                            self.wasm_module
12101                                .tables
12102                                .get(TableIndex::from_u32(table))
12103                                .unwrap()
12104                                .ty,
12105                        )?,
12106                        "",
12107                    )
12108                );
12109                self.state.push1(value);
12110            }
12111            Operator::TableSet { table } => {
12112                let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12113                let (elem, value) = self.state.pop2()?;
12114                let value = err!(
12115                    self.builder
12116                        .build_bit_cast(value, self.intrinsics.ptr_ty, "")
12117                );
12118                let table_set = if self
12119                    .wasm_module
12120                    .local_table_index(TableIndex::from_u32(table))
12121                    .is_some()
12122                {
12123                    self.intrinsics.table_set
12124                } else {
12125                    self.intrinsics.imported_table_set
12126                };
12127                err!(self.builder.build_call(
12128                    table_set,
12129                    &[
12130                        self.ctx.basic().into(),
12131                        table_index.into(),
12132                        elem.into(),
12133                        value.into(),
12134                    ],
12135                    "",
12136                ));
12137            }
12138            Operator::TableCopy {
12139                dst_table,
12140                src_table,
12141            } => {
12142                let (dst, src, len) = self.state.pop3()?;
12143                let dst_table = self.intrinsics.i32_ty.const_int(dst_table as u64, false);
12144                let src_table = self.intrinsics.i32_ty.const_int(src_table as u64, false);
12145                err!(self.builder.build_call(
12146                    self.intrinsics.table_copy,
12147                    &[
12148                        self.ctx.basic().into(),
12149                        dst_table.into(),
12150                        src_table.into(),
12151                        dst.into(),
12152                        src.into(),
12153                        len.into(),
12154                    ],
12155                    "",
12156                ));
12157            }
12158            Operator::TableInit { elem_index, table } => {
12159                let (dst, src, len) = self.state.pop3()?;
12160                let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12161                let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12162                err!(self.builder.build_call(
12163                    self.intrinsics.table_init,
12164                    &[
12165                        self.ctx.basic().into(),
12166                        table.into(),
12167                        segment.into(),
12168                        dst.into(),
12169                        src.into(),
12170                        len.into(),
12171                    ],
12172                    "",
12173                ));
12174            }
12175            Operator::ElemDrop { elem_index } => {
12176                let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12177                err!(self.builder.build_call(
12178                    self.intrinsics.elem_drop,
12179                    &[self.ctx.basic().into(), segment.into()],
12180                    "",
12181                ));
12182            }
12183            Operator::TableFill { table } => {
12184                let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12185                let (start, elem, len) = self.state.pop3()?;
12186                let elem = err!(
12187                    self.builder
12188                        .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12189                );
12190                err!(self.builder.build_call(
12191                    self.intrinsics.table_fill,
12192                    &[
12193                        self.ctx.basic().into(),
12194                        table.into(),
12195                        start.into(),
12196                        elem.into(),
12197                        len.into(),
12198                    ],
12199                    "",
12200                ));
12201            }
12202            Operator::TableGrow { table } => {
12203                let (elem, delta) = self.state.pop2()?;
12204                let elem = err!(
12205                    self.builder
12206                        .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12207                );
12208                let (table_grow, table_index) = if let Some(local_table_index) = self
12209                    .wasm_module
12210                    .local_table_index(TableIndex::from_u32(table))
12211                {
12212                    (self.intrinsics.table_grow, local_table_index.as_u32())
12213                } else {
12214                    (self.intrinsics.imported_table_grow, table)
12215                };
12216                let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12217                let size = err!(self.builder.build_call(
12218                    table_grow,
12219                    &[
12220                        self.ctx.basic().into(),
12221                        elem.into(),
12222                        delta.into(),
12223                        table_index.into(),
12224                    ],
12225                    "",
12226                ))
12227                .try_as_basic_value()
12228                .unwrap_basic();
12229                self.state.push1(size);
12230            }
12231            Operator::TableSize { table } => {
12232                let (table_size, table_index) = if let Some(local_table_index) = self
12233                    .wasm_module
12234                    .local_table_index(TableIndex::from_u32(table))
12235                {
12236                    (self.intrinsics.table_size, local_table_index.as_u32())
12237                } else {
12238                    (self.intrinsics.imported_table_size, table)
12239                };
12240                let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12241                let size = err!(self.builder.build_call(
12242                    table_size,
12243                    &[self.ctx.basic().into(), table_index.into()],
12244                    "",
12245                ))
12246                .try_as_basic_value()
12247                .unwrap_basic();
12248                self.state.push1(size);
12249            }
12250            Operator::MemoryAtomicWait32 { memarg } => {
12251                let memory_index = MemoryIndex::from_u32(memarg.memory);
12252                let (dst, val, timeout) = self.state.pop3()?;
12253                let wait32_fn_ptr = self.ctx.memory_wait32(memory_index, self.intrinsics)?;
12254                let ret = err!(
12255                    self.builder.build_indirect_call(
12256                        self.intrinsics.memory_wait32_ty,
12257                        wait32_fn_ptr,
12258                        &[
12259                            vmctx.as_basic_value_enum().into(),
12260                            self.intrinsics
12261                                .i32_ty
12262                                .const_int(memarg.memory as u64, false)
12263                                .into(),
12264                            dst.into(),
12265                            val.into(),
12266                            timeout.into(),
12267                        ],
12268                        "",
12269                    )
12270                );
12271                self.state.push1(ret.try_as_basic_value().unwrap_basic());
12272            }
12273            Operator::MemoryAtomicWait64 { memarg } => {
12274                let memory_index = MemoryIndex::from_u32(memarg.memory);
12275                let (dst, val, timeout) = self.state.pop3()?;
12276                let wait64_fn_ptr = self.ctx.memory_wait64(memory_index, self.intrinsics)?;
12277                let ret = err!(
12278                    self.builder.build_indirect_call(
12279                        self.intrinsics.memory_wait64_ty,
12280                        wait64_fn_ptr,
12281                        &[
12282                            vmctx.as_basic_value_enum().into(),
12283                            self.intrinsics
12284                                .i32_ty
12285                                .const_int(memarg.memory as u64, false)
12286                                .into(),
12287                            dst.into(),
12288                            val.into(),
12289                            timeout.into(),
12290                        ],
12291                        "",
12292                    )
12293                );
12294                self.state.push1(ret.try_as_basic_value().unwrap_basic());
12295            }
12296            Operator::MemoryAtomicNotify { memarg } => {
12297                let memory_index = MemoryIndex::from_u32(memarg.memory);
12298                let (dst, count) = self.state.pop2()?;
12299                let notify_fn_ptr = self.ctx.memory_notify(memory_index, self.intrinsics)?;
12300                let cnt = err!(
12301                    self.builder.build_indirect_call(
12302                        self.intrinsics.memory_notify_ty,
12303                        notify_fn_ptr,
12304                        &[
12305                            vmctx.as_basic_value_enum().into(),
12306                            self.intrinsics
12307                                .i32_ty
12308                                .const_int(memarg.memory as u64, false)
12309                                .into(),
12310                            dst.into(),
12311                            count.into(),
12312                        ],
12313                        "",
12314                    )
12315                );
12316                self.state.push1(cnt.try_as_basic_value().unwrap_basic());
12317            }
12318
12319            Operator::TryTable { try_table } => {
12320                let current_block = self
12321                    .builder
12322                    .get_insert_block()
12323                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12324
12325                self.builder.position_at_end(current_block);
12326
12327                let end_block = self.context.append_basic_block(self.function, "try_end");
12328
12329                let end_phis = {
12330                    self.builder.position_at_end(end_block);
12331
12332                    let phis = self
12333                        .module_translation
12334                        .blocktype_params_results(&try_table.ty)?
12335                        .1
12336                        .iter()
12337                        .map(|&wp_ty| {
12338                            err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
12339                                type_to_llvm(self.intrinsics, wasm_ty)
12340                                    .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
12341                            })
12342                        })
12343                        .collect::<Result<_, _>>()?;
12344
12345                    self.builder.position_at_end(current_block);
12346                    phis
12347                };
12348
12349                // Collect unique catches. It is not a "hard" error on the wasm side,
12350                // but LLVM will definitely complain about having the same identifier
12351                // match two different branches in the switch below.
12352                let catches: Vec<_> = try_table
12353                    .catches
12354                    .into_iter()
12355                    .unique_by(|v| match v {
12356                        Catch::One { tag, .. } | Catch::OneRef { tag, .. } => *tag as i32,
12357                        Catch::All { .. } | Catch::AllRef { .. } => CATCH_ALL_TAG_VALUE,
12358                    })
12359                    .collect();
12360
12361                // Build the landing pad.
12362                let null = self.intrinsics.ptr_ty.const_zero();
12363
12364                let mut catch_tag_values = vec![];
12365                let mut lpad_clauses: Vec<BasicValueEnum<'ctx>> = catches
12366                    .iter()
12367                    .map(|catch| match catch {
12368                        Catch::All { .. } | Catch::AllRef { .. } => {
12369                            catch_tag_values.push(CATCH_ALL_TAG_VALUE as u32);
12370                            Ok(null.into())
12371                        }
12372                        Catch::One { tag, .. } | Catch::OneRef { tag, .. } => {
12373                            catch_tag_values.push(*tag);
12374                            Ok(self.get_or_insert_tag_type_info_global(*tag as i32))
12375                        }
12376                    })
12377                    .collect::<Result<Vec<BasicValueEnum<'ctx>>, CompileError>>()?;
12378
12379                // Since jumping between landingpads is not possible, we need to collect
12380                // all tags from outer try_tables as well to build a clause for *every*
12381                // possible tag that might be caught.
12382                let mut outer_catch_blocks = vec![];
12383                for outer_landingpad in self.state.landingpads.iter().rev() {
12384                    for catch_info @ TagCatchInfo { tag, .. } in &outer_landingpad.tags {
12385                        if !catch_tag_values.contains(tag) {
12386                            catch_tag_values.push(*tag);
12387                            lpad_clauses.push(if *tag as i32 == CATCH_ALL_TAG_VALUE {
12388                                null.into()
12389                            } else {
12390                                *self.tags_cache.get(&(*tag as i32)).expect(
12391                                    "If a previous try_table encountered a tag, \
12392                                    it should be in the cache",
12393                                )
12394                            });
12395                            outer_catch_blocks.push(*catch_info);
12396                        }
12397                    }
12398                }
12399
12400                // If there are no catch clauses, we have to skip everything, since
12401                // an lpad without catch clauses is invalid (and won't ever be jumped
12402                // to anyway)
12403                let mut maybe_lpad_block = None;
12404                let mut catch_blocks = vec![];
12405                if !lpad_clauses.is_empty() {
12406                    let lpad_block = self.context.append_basic_block(self.function, "catch");
12407                    let catch_all_block =
12408                        self.context.append_basic_block(self.function, "catch_all");
12409                    let catch_specific_block = self
12410                        .context
12411                        .append_basic_block(self.function, "catch_specific");
12412                    let catch_end_block =
12413                        self.context.append_basic_block(self.function, "catch_end");
12414                    let rethrow_block = self.context.append_basic_block(self.function, "rethrow");
12415
12416                    self.builder.position_at_end(lpad_block);
12417
12418                    let res = err!(self.builder.build_landing_pad(
12419                        self.intrinsics.lpad_exception_ty,
12420                        self.intrinsics.personality,
12421                        &lpad_clauses,
12422                        false,
12423                        "exc_struct",
12424                    ));
12425
12426                    let res = res.into_struct_value();
12427
12428                    let uw_exc = err!(self.builder.build_extract_value(res, 0, "exc_ptr"));
12429                    let pre_selector =
12430                        err!(self.builder.build_extract_value(res, 1, "pre_selector"));
12431
12432                    // The pre-selector can be either 0 (for catch-all) or 1 (for a
12433                    // specific, but as-yet-unknown tag).
12434                    let pre_selector_is_zero = err!(self.builder.build_int_compare(
12435                        IntPredicate::EQ,
12436                        pre_selector.into_int_value(),
12437                        self.intrinsics.i32_zero,
12438                        "pre_selector_is_zero"
12439                    ));
12440                    err!(self.builder.build_conditional_branch(
12441                        pre_selector_is_zero,
12442                        catch_all_block,
12443                        catch_specific_block
12444                    ));
12445
12446                    self.builder.position_at_end(catch_all_block);
12447                    err!(self.builder.build_unconditional_branch(catch_end_block));
12448
12449                    self.builder.position_at_end(catch_specific_block);
12450                    let selector_value = err!(self.builder.build_call(
12451                        self.intrinsics.personality2,
12452                        &[self.ctx.basic().into(), uw_exc.into()],
12453                        "selector"
12454                    ));
12455                    err!(self.builder.build_unconditional_branch(catch_end_block));
12456
12457                    self.builder.position_at_end(catch_end_block);
12458                    let selector = err!(self.builder.build_phi(self.intrinsics.i32_ty, "selector"));
12459                    selector.add_incoming(&[
12460                        (
12461                            &self
12462                                .intrinsics
12463                                .i32_ty
12464                                .const_int(CATCH_ALL_TAG_VALUE as u64, false),
12465                            catch_all_block,
12466                        ),
12467                        (
12468                            &selector_value
12469                                .try_as_basic_value()
12470                                .unwrap_basic()
12471                                .into_int_value(),
12472                            catch_specific_block,
12473                        ),
12474                    ]);
12475
12476                    // Now we're done looking at the exception, it's time to deallocate and get
12477                    // the exnref out of it. When an exception is caught, "rethrowing" simply
12478                    // means starting another unwind by calling _Unwind_RaiseException with the
12479                    // same exception bits. Instead of keeping the same exception around, we
12480                    // deallocate the exception once it's caught, and if we need to rethrow, we
12481                    // just re-allocate a new exception.
12482                    //
12483                    // Note that this is different from how it's done in C++ land, where the
12484                    // exception object is kept around for rethrowing; this discrepency exists
12485                    // because in C++, exception handling is lexical (i.e. there's an implicit
12486                    // "current exception" in catch blocks) whereas in WASM, you rethrow with
12487                    // an exnref that may very well have come from somewhere else; consider this
12488                    // (badly implemented and erroneous) pseudo-module:
12489                    //
12490                    // (module
12491                    //   (global $e (mut exnref) (ref.null exn))
12492                    //   ;; Store the given exnref, return the previous one
12493                    //   (func $delay_exnref (param exnref) (result exnref)
12494                    //     (global.get $e)
12495                    //     (local.get 0)
12496                    //     (global.set $e)
12497                    //   )
12498                    //   (func foo
12499                    //     (block $catch (result exnref)
12500                    //       (try_table (catch_all_ref $catch)
12501                    //         ...
12502                    //       )
12503                    //     )
12504                    //     (call $delay_exnref) ;; store the exnref caught above
12505                    //     throw_ref ;; throw the previous exnref
12506                    //   )
12507                    // )
12508                    //
12509                    // Here, it's impossible to reuse the same exception object since the
12510                    // exnref given to throw_ref is a different one than the one we caught
12511                    // with the try_table.
12512                    //
12513                    // Another difference is that C++ exceptions may well carry lots of data
12514                    // around; a WASM exception is just an exnref, backed by a u32, which is
12515                    // just 4 bytes, and is cheap to reallocate. C++ exceptions may also carry
12516                    // things with dtors around; another thing that doesn't exist in WASM.
12517                    //
12518                    // All of this is to say that putting exception deallocation and exnref
12519                    // retrieval in the same function has been a very deliberate choice.
12520                    let uw_exc = uw_exc.into_pointer_value();
12521                    let exnref = err!(self.builder.build_call(
12522                        self.intrinsics.exception_into_exnref,
12523                        &[uw_exc.into()],
12524                        "exnref"
12525                    ));
12526
12527                    let exnref = exnref.try_as_basic_value().unwrap_basic().into_int_value();
12528                    let selector = selector.as_basic_value().into_int_value();
12529
12530                    for catch in catches.iter() {
12531                        match catch {
12532                            Catch::All { label } => {
12533                                let b = self
12534                                    .context
12535                                    .append_basic_block(self.function, "catch_all_clause");
12536                                self.builder.position_at_end(b);
12537                                let frame = self.state.frame_at_depth(*label)?;
12538
12539                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12540
12541                                self.builder.position_at_end(catch_end_block);
12542                                catch_blocks.push((b, None));
12543                            }
12544                            Catch::One { tag, label } => {
12545                                let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12546                                let signature = &self.wasm_module.signatures[tag_idx];
12547                                let params = signature.params();
12548
12549                                let b = self.context.append_basic_block(
12550                                    self.function,
12551                                    format!("catch_one_clause_{tag}").as_str(),
12552                                );
12553                                self.builder.position_at_end(b);
12554
12555                                let exnref_phi = err!(
12556                                    self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12557                                );
12558                                exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12559
12560                                // Get the payload pointer.
12561                                let exn_payload_ptr = err!(self.builder.build_direct_call(
12562                                    self.intrinsics.read_exnref,
12563                                    &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12564                                    "exn_ptr",
12565                                ));
12566                                let exn_payload_ptr = exn_payload_ptr
12567                                    .try_as_basic_value()
12568                                    .unwrap_basic()
12569                                    .into_pointer_value();
12570
12571                                // Read each value from the data ptr.
12572                                let values = params
12573                                    .iter()
12574                                    .enumerate()
12575                                    .map(|(i, v)| {
12576                                        let name = format!("value_{i}");
12577                                        let ptr = err!(unsafe {
12578                                            self.builder.build_gep(
12579                                                self.intrinsics.i128_ty,
12580                                                exn_payload_ptr,
12581                                                &[self
12582                                                    .intrinsics
12583                                                    .i32_ty
12584                                                    .const_int(i as u64, false)],
12585                                                format!("{name}_ptr").as_str(),
12586                                            )
12587                                        });
12588                                        err_nt!(self.builder.build_load(
12589                                            type_to_llvm(self.intrinsics, *v)?,
12590                                            ptr,
12591                                            &name,
12592                                        ))
12593                                    })
12594                                    .collect::<Result<Vec<_>, CompileError>>()?;
12595
12596                                let frame = self.state.frame_at_depth(*label)?;
12597
12598                                for (phi, value) in frame.phis().iter().zip(values.iter()) {
12599                                    phi.add_incoming(&[(value, b)])
12600                                }
12601
12602                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12603
12604                                self.builder.position_at_end(catch_end_block);
12605                                catch_blocks.push((b, Some(exnref_phi)));
12606                            }
12607                            Catch::OneRef { label, tag } => {
12608                                let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12609                                let signature = &self.wasm_module.signatures[tag_idx];
12610                                let params = signature.params();
12611
12612                                let b = self.context.append_basic_block(
12613                                    self.function,
12614                                    format!("catch_one_ref_clause_{tag}").as_str(),
12615                                );
12616                                self.builder.position_at_end(b);
12617
12618                                let exnref_phi = err!(
12619                                    self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12620                                );
12621                                exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12622
12623                                // Get the payload pointer.
12624                                let exn_payload_ptr = err!(self.builder.build_direct_call(
12625                                    self.intrinsics.read_exnref,
12626                                    &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12627                                    "exn_ptr",
12628                                ));
12629                                let exn_payload_ptr = exn_payload_ptr
12630                                    .try_as_basic_value()
12631                                    .unwrap_basic()
12632                                    .into_pointer_value();
12633
12634                                // Read each value from the data ptr.
12635                                let mut values = params
12636                                    .iter()
12637                                    .enumerate()
12638                                    .map(|(i, v)| {
12639                                        let name = format!("value_{i}");
12640                                        let ptr = err!(unsafe {
12641                                            self.builder.build_gep(
12642                                                self.intrinsics.i128_ty,
12643                                                exn_payload_ptr,
12644                                                &[self
12645                                                    .intrinsics
12646                                                    .i32_ty
12647                                                    .const_int(i as u64, false)],
12648                                                format!("{name}_ptr").as_str(),
12649                                            )
12650                                        });
12651                                        err_nt!(self.builder.build_load(
12652                                            type_to_llvm(self.intrinsics, *v)?,
12653                                            ptr,
12654                                            &name,
12655                                        ))
12656                                    })
12657                                    .collect::<Result<Vec<_>, CompileError>>()?;
12658
12659                                values.push(exnref_phi.as_basic_value());
12660
12661                                let frame = self.state.frame_at_depth(*label)?;
12662
12663                                for (phi, value) in frame.phis().iter().zip(values.iter()) {
12664                                    phi.add_incoming(&[(value, b)])
12665                                }
12666
12667                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12668
12669                                self.builder.position_at_end(catch_end_block);
12670                                catch_blocks.push((b, Some(exnref_phi)));
12671                            }
12672                            Catch::AllRef { label } => {
12673                                let b = self
12674                                    .context
12675                                    .append_basic_block(self.function, "catch_all_ref_clause");
12676                                self.builder.position_at_end(b);
12677
12678                                let exnref_phi = err!(
12679                                    self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12680                                );
12681                                exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12682
12683                                let frame = self.state.frame_at_depth(*label)?;
12684
12685                                let phis = frame.phis();
12686
12687                                assert_eq!(phis.len(), 1);
12688                                phis[0].add_incoming(&[(&exnref_phi.as_basic_value(), b)]);
12689
12690                                err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12691
12692                                self.builder.position_at_end(catch_end_block);
12693                                catch_blocks.push((b, Some(exnref_phi)));
12694                            }
12695                        }
12696                    }
12697
12698                    for catch_info in &outer_catch_blocks {
12699                        if let Some(phi) = catch_info.exnref_phi {
12700                            phi.add_incoming(&[(&exnref, catch_end_block)]);
12701                        }
12702                    }
12703
12704                    err!(
12705                        self.builder.build_switch(
12706                            selector,
12707                            rethrow_block,
12708                            catch_blocks
12709                                .iter()
12710                                .enumerate()
12711                                .map(|(i, v)| (
12712                                    self.intrinsics
12713                                        .i32_ty
12714                                        .const_int(catch_tag_values[i] as _, false),
12715                                    v.0
12716                                ))
12717                                .chain(outer_catch_blocks.iter().map(|catch_info| (
12718                                    self.intrinsics.i32_ty.const_int(catch_info.tag as _, false),
12719                                    catch_info.catch_block
12720                                )))
12721                                .collect::<Vec<_>>()
12722                                .as_slice()
12723                        )
12724                    );
12725
12726                    // -- end
12727
12728                    // -- The rethrow block
12729                    self.builder.position_at_end(rethrow_block);
12730
12731                    err!(self.builder.build_call(
12732                        self.intrinsics.throw,
12733                        &[self.ctx.basic().into(), exnref.into()],
12734                        "rethrow"
12735                    ));
12736                    // can't reach after an explicit throw!
12737                    err!(self.builder.build_unreachable());
12738
12739                    maybe_lpad_block = Some(lpad_block);
12740                }
12741
12742                // Move back to current block
12743                self.builder.position_at_end(current_block);
12744
12745                // Note: catch_tag_values also containes outer tags, but zipping with
12746                // catch_blocks will let us ignore the extra ones.
12747                let catch_tags_and_blocks = catch_tag_values
12748                    .into_iter()
12749                    .zip(catch_blocks)
12750                    .map(|(tag, (block, exnref_phi))| TagCatchInfo {
12751                        tag,
12752                        catch_block: block,
12753                        exnref_phi,
12754                    })
12755                    .collect::<Vec<_>>();
12756                self.state.push_landingpad(
12757                    maybe_lpad_block,
12758                    end_block,
12759                    end_phis,
12760                    &catch_tags_and_blocks,
12761                    self.module_translation
12762                        .blocktype_params_results(&try_table.ty)?
12763                        .0
12764                        .len(),
12765                );
12766            }
12767            Operator::Throw { tag_index } => {
12768                let current_block = self
12769                    .builder
12770                    .get_insert_block()
12771                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12772
12773                let sig_index = self.wasm_module.tags[TagIndex::from_u32(tag_index)];
12774                let signature = &self.wasm_module.signatures[sig_index];
12775                let params = signature.params();
12776                let values = self.state.popn_save_extra(params.len())?;
12777
12778                values.iter().enumerate().try_for_each(|(i, (v, _))| {
12779                    let t = type_to_llvm(self.intrinsics, params[i])?;
12780                    if t != v.get_type() {
12781                        return Err(CompileError::Codegen(format!(
12782                            "Incompatible types: {:?} != {:?}",
12783                            t,
12784                            v.get_type()
12785                        )));
12786                    }
12787
12788                    Ok(())
12789                })?;
12790
12791                // Allocate the necessary bytes for the exception.
12792                let exnref = err!(
12793                    self.builder.build_direct_call(
12794                        self.intrinsics.alloc_exception,
12795                        &[
12796                            self.ctx.basic().into(),
12797                            self.intrinsics
12798                                .i32_ty
12799                                .const_int(tag_index as _, false)
12800                                .into()
12801                        ],
12802                        "exnref",
12803                    )
12804                );
12805                let exnref = exnref.try_as_basic_value().unwrap_basic();
12806
12807                let exn_payload_ptr = err!(self.builder.build_direct_call(
12808                    self.intrinsics.read_exnref,
12809                    &[self.ctx.basic().into(), exnref.into()],
12810                    "exn_ptr",
12811                ));
12812                let exn_payload_ptr = exn_payload_ptr
12813                    .try_as_basic_value()
12814                    .unwrap_basic()
12815                    .into_pointer_value();
12816
12817                for (i, value) in values.into_iter().enumerate() {
12818                    let ptr = err!(unsafe {
12819                        self.builder.build_gep(
12820                            self.intrinsics.i128_ty,
12821                            exn_payload_ptr,
12822                            &[self.intrinsics.i32_ty.const_int(i as u64, false)],
12823                            format!("value_{i}_ptr").as_str(),
12824                        )
12825                    });
12826                    err!(self.builder.build_store(ptr, value.0));
12827                }
12828
12829                if let Some(pad) = self.state.get_innermost_landingpad() {
12830                    let unreachable_block = self
12831                        .context
12832                        .append_basic_block(self.function, "_throw_unreachable");
12833
12834                    err!(self.builder.build_invoke(
12835                        self.intrinsics.throw,
12836                        &[self.ctx.basic(), exnref],
12837                        unreachable_block,
12838                        pad,
12839                        "throw",
12840                    ));
12841
12842                    self.builder.position_at_end(unreachable_block);
12843                    // can't reach after an explicit throw!
12844                    err!(self.builder.build_unreachable());
12845
12846                    self.builder.position_at_end(current_block);
12847                } else {
12848                    err!(self.builder.build_call(
12849                        self.intrinsics.throw,
12850                        &[self.ctx.basic().into(), exnref.into()],
12851                        "throw"
12852                    ));
12853                    // can't reach after an explicit throw!
12854                    err!(self.builder.build_unreachable());
12855                }
12856
12857                self.state.reachable = false;
12858            }
12859            Operator::ThrowRef => {
12860                let current_block = self
12861                    .builder
12862                    .get_insert_block()
12863                    .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12864
12865                let exnref = self.state.pop1()?;
12866
12867                if let Some(pad) = self.state.get_innermost_landingpad() {
12868                    let unreachable_block = self
12869                        .context
12870                        .append_basic_block(self.function, "_rethrow_unreachable");
12871
12872                    err!(self.builder.build_invoke(
12873                        self.intrinsics.throw,
12874                        &[self.ctx.basic(), exnref],
12875                        unreachable_block,
12876                        pad,
12877                        "throw",
12878                    ));
12879
12880                    self.builder.position_at_end(unreachable_block);
12881                    // can't reach after an explicit throw!
12882                    err!(self.builder.build_unreachable());
12883
12884                    self.builder.position_at_end(current_block);
12885                } else {
12886                    err!(self.builder.build_call(
12887                        self.intrinsics.throw,
12888                        &[self.ctx.basic().into(), exnref.into()],
12889                        "throw"
12890                    ));
12891                    // can't reach after an explicit throw!
12892                    err!(self.builder.build_unreachable());
12893                }
12894
12895                self.state.reachable = false;
12896            }
12897            _ => {
12898                return Err(CompileError::Codegen(format!(
12899                    "Operator {op:?} unimplemented",
12900                )));
12901            }
12902        }
12903
12904        Ok(())
12905    }
12906}
12907
12908fn is_f32_arithmetic(bits: u32) -> bool {
12909    // Mask off sign bit.
12910    let bits = bits & 0x7FFF_FFFF;
12911    bits < 0x7FC0_0000
12912}
12913
12914fn is_f64_arithmetic(bits: u64) -> bool {
12915    // Mask off sign bit.
12916    let bits = bits & 0x7FFF_FFFF_FFFF_FFFF;
12917    bits < 0x7FF8_0000_0000_0000
12918}
12919
12920// Constants for the bounds of truncation operations. These are the least or
12921// greatest exact floats in either f32 or f64 representation
12922// greater-than-or-equal-to (for least) or less-than-or-equal-to (for greatest)
12923// the i32 or i64 or u32 or u64 min (for least) or max (for greatest), when
12924// rounding towards zero.
12925
12926/// Least Exact Float (32 bits) greater-than-or-equal-to i32::MIN when rounding towards zero.
12927const LEF32_GEQ_I32_MIN: u64 = i32::MIN as u64;
12928/// Greatest Exact Float (32 bits) less-than-or-equal-to i32::MAX when rounding towards zero.
12929const GEF32_LEQ_I32_MAX: u64 = 2147483520; // bits as f32: 0x4eff_ffff
12930/// Least Exact Float (64 bits) greater-than-or-equal-to i32::MIN when rounding towards zero.
12931const LEF64_GEQ_I32_MIN: u64 = i32::MIN as u64;
12932/// Greatest Exact Float (64 bits) less-than-or-equal-to i32::MAX when rounding towards zero.
12933const GEF64_LEQ_I32_MAX: u64 = i32::MAX as u64;
12934/// Least Exact Float (32 bits) greater-than-or-equal-to u32::MIN when rounding towards zero.
12935const LEF32_GEQ_U32_MIN: u64 = u32::MIN as u64;
12936/// Greatest Exact Float (32 bits) less-than-or-equal-to u32::MAX when rounding towards zero.
12937const GEF32_LEQ_U32_MAX: u64 = 4294967040; // bits as f32: 0x4f7f_ffff
12938/// Least Exact Float (64 bits) greater-than-or-equal-to u32::MIN when rounding towards zero.
12939const LEF64_GEQ_U32_MIN: u64 = u32::MIN as u64;
12940/// Greatest Exact Float (64 bits) less-than-or-equal-to u32::MAX when rounding towards zero.
12941const GEF64_LEQ_U32_MAX: u64 = 4294967295; // bits as f64: 0x41ef_ffff_ffff_ffff
12942/// Least Exact Float (32 bits) greater-than-or-equal-to i64::MIN when rounding towards zero.
12943const LEF32_GEQ_I64_MIN: u64 = i64::MIN as u64;
12944/// Greatest Exact Float (32 bits) less-than-or-equal-to i64::MAX when rounding towards zero.
12945const GEF32_LEQ_I64_MAX: u64 = 9223371487098961920; // bits as f32: 0x5eff_ffff
12946/// Least Exact Float (64 bits) greater-than-or-equal-to i64::MIN when rounding towards zero.
12947const LEF64_GEQ_I64_MIN: u64 = i64::MIN as u64;
12948/// Greatest Exact Float (64 bits) less-than-or-equal-to i64::MAX when rounding towards zero.
12949const GEF64_LEQ_I64_MAX: u64 = 9223372036854774784; // bits as f64: 0x43df_ffff_ffff_ffff
12950/// Least Exact Float (32 bits) greater-than-or-equal-to u64::MIN when rounding towards zero.
12951const LEF32_GEQ_U64_MIN: u64 = u64::MIN;
12952/// Greatest Exact Float (32 bits) less-than-or-equal-to u64::MAX when rounding towards zero.
12953const GEF32_LEQ_U64_MAX: u64 = 18446742974197923840; // bits as f32: 0x5f7f_ffff
12954/// Least Exact Float (64 bits) greater-than-or-equal-to u64::MIN when rounding towards zero.
12955const LEF64_GEQ_U64_MIN: u64 = u64::MIN;
12956/// Greatest Exact Float (64 bits) less-than-or-equal-to u64::MAX when rounding towards zero.
12957const GEF64_LEQ_U64_MAX: u64 = 18446744073709549568; // bits as f64: 0x43ef_ffff_ffff_ffff