1use std::collections::HashMap;
2
3use super::{
4 intrinsics::{
5 CtxType, FunctionCache, GlobalCache, Intrinsics, MemoryCache, tbaa_label, type_to_llvm,
6 },
7 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
57const CATCH_ALL_TAG_VALUE: i32 = i32::MAX;
63
64pub struct FuncTranslator {
65 ctx: Context,
66 target_machine: TargetMachine,
67 abi: Box<dyn Abi>,
68 binary_fmt: BinaryFormat,
69 func_section: String,
70}
71
72impl FuncTranslator {
73 pub fn new(
74 target_machine: TargetMachine,
75 binary_fmt: BinaryFormat,
76 ) -> Result<Self, CompileError> {
77 let abi = get_abi(&target_machine);
78 Ok(Self {
79 ctx: Context::create(),
80 target_machine,
81 abi,
82 func_section: match binary_fmt {
83 BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
84 BinaryFormat::Macho => FUNCTION_SEGMENT_MACHO.to_string(),
85 _ => {
86 return Err(CompileError::UnsupportedTarget(format!(
87 "Unsupported binary format: {binary_fmt:?}"
88 )));
89 }
90 },
91 binary_fmt,
92 })
93 }
94
95 #[allow(clippy::too_many_arguments)]
96 pub fn translate_to_module(
97 &self,
98 wasm_module: &ModuleInfo,
99 module_translation: &ModuleTranslationState,
100 local_func_index: &LocalFunctionIndex,
101 function_body: &FunctionBodyData,
102 config: &LLVM,
103 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
104 _table_styles: &PrimaryMap<TableIndex, TableStyle>,
105 symbol_registry: &dyn SymbolRegistry,
106 target: &Triple,
107 ) -> Result<Module<'_>, CompileError> {
108 let func_index = wasm_module.func_index(*local_func_index);
110 let function =
111 CompiledKind::Local(*local_func_index, wasm_module.get_function_name(func_index));
112 let function_name =
113 symbol_registry.symbol_to_name(Symbol::LocalFunction(*local_func_index));
114
115 let g0m0_is_enabled = config.enable_g0m0_opt;
116 let func_kind = if g0m0_is_enabled {
117 Some(G0M0FunctionKind::Local)
118 } else {
119 None
120 };
121
122 let module_name = match wasm_module.name.as_ref() {
123 None => format!("<anonymous module> function {function_name}"),
124 Some(module_name) => format!("module {module_name} function {function_name}"),
125 };
126 let module = self.ctx.create_module(module_name.as_str());
127
128 let target_machine = &self.target_machine;
129 let target_triple = target_machine.get_triple();
130 let target_data = target_machine.get_target_data();
131 module.set_triple(&target_triple);
132 module.set_data_layout(&target_data.get_data_layout());
133 let wasm_fn_type = wasm_module
134 .signatures
135 .get(wasm_module.functions[func_index])
136 .unwrap();
137
138 let offsets = VMOffsets::new(8, wasm_module);
140 let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data, &self.binary_fmt);
141 let (func_type, func_attrs) = self.abi.func_type_to_llvm(
142 &self.ctx,
143 &intrinsics,
144 Some(&offsets),
145 wasm_fn_type,
146 func_kind,
147 )?;
148
149 let func = module.add_function(&function_name, func_type, Some(Linkage::External));
150 for (attr, attr_loc) in &func_attrs {
151 func.add_attribute(*attr_loc, *attr);
152 }
153
154 if !matches!(target.operating_system, OperatingSystem::Windows) {
155 func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe);
156 }
157
158 func.add_attribute(AttributeLoc::Function, intrinsics.uwtable);
159 func.add_attribute(AttributeLoc::Function, intrinsics.frame_pointer);
160
161 let section = match self.binary_fmt {
162 BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
163 BinaryFormat::Macho => {
164 format!("{FUNCTION_SECTION_MACHO},{FUNCTION_SEGMENT_MACHO}")
165 }
166 _ => {
167 return Err(CompileError::UnsupportedTarget(format!(
168 "Unsupported binary format: {:?}",
169 self.binary_fmt
170 )));
171 }
172 };
173
174 func.set_personality_function(intrinsics.personality);
175 func.as_global_value().set_section(Some(§ion));
176
177 func.set_linkage(Linkage::DLLExport);
178 func.as_global_value()
179 .set_dll_storage_class(DLLStorageClass::Export);
180
181 let entry = self.ctx.append_basic_block(func, "entry");
182 let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
183 let return_ = self.ctx.append_basic_block(func, "return");
184 let alloca_builder = self.ctx.create_builder();
185 let cache_builder = self.ctx.create_builder();
186 let builder = self.ctx.create_builder();
187 cache_builder.position_at_end(entry);
188 let br = err!(cache_builder.build_unconditional_branch(start_of_code));
189 alloca_builder.position_before(&br);
190 cache_builder.position_before(&br);
191 builder.position_at_end(start_of_code);
192
193 let mut state = State::new();
194 builder.position_at_end(return_);
195 let phis: SmallVec<[PhiValue; 1]> = wasm_fn_type
196 .results()
197 .iter()
198 .map(|&wasm_ty| {
199 type_to_llvm(&intrinsics, wasm_ty).map(|ty| builder.build_phi(ty, "").unwrap())
200 })
201 .collect::<Result<_, _>>()?;
202 state.push_block(return_, phis, 0);
203 builder.position_at_end(start_of_code);
204
205 let mut reader = MiddlewareBinaryReader::new_with_offset(
206 function_body.data,
207 function_body.module_offset,
208 );
209 reader.set_middleware_chain(
210 config
211 .middlewares
212 .generate_function_middleware_chain(*local_func_index),
213 );
214
215 let mut params = vec![];
216 let first_param =
217 if func_type.get_return_type().is_none() && wasm_fn_type.results().len() > 1 {
218 if g0m0_is_enabled { 4 } else { 2 }
219 } else if g0m0_is_enabled {
220 3
221 } else {
222 1
223 };
224 let mut is_first_alloca = true;
225 let mut insert_alloca = |ty, name: String| -> Result<PointerValue, CompileError> {
226 let alloca = err!(alloca_builder.build_alloca(ty, &name));
227 if is_first_alloca {
228 alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
229 is_first_alloca = false;
230 }
231 Ok(alloca)
232 };
233
234 for idx in 0..wasm_fn_type.params().len() {
252 let ty = wasm_fn_type.params()[idx];
253 let ty = type_to_llvm(&intrinsics, ty)?;
254 let value = func
255 .get_nth_param((idx as u32).checked_add(first_param).unwrap())
256 .unwrap();
257 let alloca = insert_alloca(ty, format!("param_{idx}"))?;
258 err!(cache_builder.build_store(alloca, value));
259 params.push((ty, alloca));
260 }
261
262 let mut locals = vec![];
263 let num_locals = reader.read_local_count()?;
264 for idx in 0..num_locals {
265 let (count, ty) = reader.read_local_decl()?;
266 let ty = err!(wptype_to_type(ty));
267 let ty = type_to_llvm(&intrinsics, ty)?;
268 for _ in 0..count {
269 let alloca = insert_alloca(ty, format!("local_{idx}"))?;
270 err!(cache_builder.build_store(alloca, ty.const_zero()));
271 locals.push((ty, alloca));
272 }
273 }
274
275 let mut params_locals = params.clone();
276 params_locals.extend(locals.iter().cloned());
277
278 let mut g0m0_params = None;
279
280 if g0m0_is_enabled {
281 let value = self.abi.get_g0_ptr_param(&func);
282 let g0 = insert_alloca(intrinsics.i32_ty.as_basic_type_enum(), "g0".to_string())?;
283 err!(cache_builder.build_store(g0, value));
284 g0.set_name("g0");
285 let m0 = self.abi.get_m0_ptr_param(&func);
286 m0.set_name("m0_base_ptr");
287
288 g0m0_params = Some((g0, m0));
289 }
290
291 let mut fcg = LLVMFunctionCodeGenerator {
292 g0m0: g0m0_params,
293 context: &self.ctx,
294 builder,
295 alloca_builder,
296 intrinsics: &intrinsics,
297 state,
298 function: func,
299 locals: params_locals,
300 ctx: CtxType::new(wasm_module, &func, &cache_builder, &*self.abi, config),
301 unreachable_depth: 0,
302 memory_styles,
303 _table_styles,
304 module: &module,
305 module_translation,
306 wasm_module,
307 symbol_registry,
308 abi: &*self.abi,
309 config,
310 tags_cache: HashMap::new(),
311 binary_fmt: self.binary_fmt,
312 };
313
314 fcg.ctx.add_func(
315 func_index,
316 func.as_global_value().as_pointer_value(),
317 func_type,
318 fcg.ctx.basic(),
319 &func_attrs,
320 );
321
322 while fcg.state.has_control_frames() {
323 let pos = reader.current_position() as u32;
324 let op = reader.read_operator()?;
325 fcg.translate_operator(op, pos)?;
326 }
327
328 fcg.finalize(wasm_fn_type)?;
329
330 if let Some(ref callbacks) = config.callbacks {
331 callbacks.preopt_ir(&function, &module);
332 }
333
334 let mut passes = vec![];
335
336 if config.enable_verifier {
337 passes.push("verify");
338 }
339
340 passes.push("sccp");
341 passes.push("early-cse");
342 passes.push("adce");
344 passes.push("sroa");
345 passes.push("aggressive-instcombine");
346 passes.push("jump-threading");
347 passes.push("simplifycfg");
349 passes.push("reassociate");
350 passes.push("loop-rotate");
351 passes.push("indvars");
352 passes.push("sccp");
356 passes.push("reassociate");
357 passes.push("simplifycfg");
358 passes.push("gvn");
359 passes.push("memcpyopt");
360 passes.push("dse");
361 passes.push("dce");
362 passes.push("reassociate");
364 passes.push("simplifycfg");
365 passes.push("mem2reg");
366
367 module
378 .run_passes(
379 passes.join(",").as_str(),
380 target_machine,
381 PassBuilderOptions::create(),
382 )
383 .unwrap();
384
385 if let Some(ref callbacks) = config.callbacks {
394 callbacks.postopt_ir(&function, &module);
395 }
396
397 Ok(module)
398 }
399
400 #[allow(clippy::too_many_arguments)]
401 pub fn translate(
402 &self,
403 wasm_module: &ModuleInfo,
404 module_translation: &ModuleTranslationState,
405 local_func_index: &LocalFunctionIndex,
406 function_body: &FunctionBodyData,
407 config: &LLVM,
408 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
409 table_styles: &PrimaryMap<TableIndex, TableStyle>,
410 symbol_registry: &dyn SymbolRegistry,
411 target: &Triple,
412 ) -> Result<CompiledFunction, CompileError> {
413 let module = self.translate_to_module(
414 wasm_module,
415 module_translation,
416 local_func_index,
417 function_body,
418 config,
419 memory_styles,
420 table_styles,
421 symbol_registry,
422 target,
423 )?;
424 let function = CompiledKind::Local(
425 *local_func_index,
426 wasm_module.get_function_name(wasm_module.func_index(*local_func_index)),
427 );
428 let target_machine = &self.target_machine;
429 let memory_buffer = target_machine
430 .write_to_memory_buffer(&module, FileType::Object)
431 .unwrap();
432
433 if let Some(ref callbacks) = config.callbacks {
434 callbacks.obj_memory_buffer(&function, &memory_buffer);
435 let asm_buffer = target_machine
436 .write_to_memory_buffer(&module, FileType::Assembly)
437 .unwrap();
438 callbacks.asm_memory_buffer(&function, &asm_buffer)
439 }
440
441 let mem_buf_slice = memory_buffer.as_slice();
442
443 load_object_file(
444 mem_buf_slice,
445 &self.func_section,
446 RelocationTarget::LocalFunc(*local_func_index),
447 |name: &str| {
448 Ok({
449 let name = if matches!(self.binary_fmt, BinaryFormat::Macho) {
450 if name.starts_with("_") {
451 name.replacen("_", "", 1)
452 } else {
453 name.to_string()
454 }
455 } else {
456 name.to_string()
457 };
458 if let Some(Symbol::LocalFunction(local_func_index)) =
459 symbol_registry.name_to_symbol(&name)
460 {
461 Some(RelocationTarget::LocalFunc(local_func_index))
462 } else {
463 None
464 }
465 })
466 },
467 self.binary_fmt,
468 )
469 }
470}
471
472impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
473 fn splat_vector(
475 &self,
476 value: BasicValueEnum<'ctx>,
477 vec_ty: VectorType<'ctx>,
478 ) -> Result<VectorValue<'ctx>, CompileError> {
479 err_nt!(
482 self.builder.build_shuffle_vector(
483 err!(self.builder.build_insert_element(
484 vec_ty.get_undef(),
485 value,
486 self.intrinsics.i32_zero,
487 "",
488 )),
489 vec_ty.get_undef(),
490 self.intrinsics
491 .i32_ty
492 .vec_type(vec_ty.get_size())
493 .const_zero(),
494 "",
495 )
496 )
497 }
498
499 #[allow(clippy::too_many_arguments)]
502 fn trunc_sat<T: FloatMathType<'ctx>>(
503 &self,
504 fvec_ty: T,
505 ivec_ty: T::MathConvType,
506 lower_bound: u64, upper_bound: u64, int_min_value: u64,
509 int_max_value: u64,
510 value: IntValue<'ctx>,
511 ) -> Result<VectorValue<'ctx>, CompileError> {
512 let fvec_ty = fvec_ty.as_basic_type_enum().into_vector_type();
526 let ivec_ty = ivec_ty.as_basic_type_enum().into_vector_type();
527 let fvec_element_ty = fvec_ty.get_element_type().into_float_type();
528 let ivec_element_ty = ivec_ty.get_element_type().into_int_type();
529
530 let is_signed = int_min_value != 0;
531 let int_min_value = self.splat_vector(
532 ivec_element_ty
533 .const_int(int_min_value, is_signed)
534 .as_basic_value_enum(),
535 ivec_ty,
536 )?;
537 let int_max_value = self.splat_vector(
538 ivec_element_ty
539 .const_int(int_max_value, is_signed)
540 .as_basic_value_enum(),
541 ivec_ty,
542 )?;
543 let lower_bound = if is_signed {
544 err!(self.builder.build_signed_int_to_float(
545 ivec_element_ty.const_int(lower_bound, is_signed),
546 fvec_element_ty,
547 "",
548 ))
549 } else {
550 err!(self.builder.build_unsigned_int_to_float(
551 ivec_element_ty.const_int(lower_bound, is_signed),
552 fvec_element_ty,
553 "",
554 ))
555 };
556 let upper_bound = if is_signed {
557 err!(self.builder.build_signed_int_to_float(
558 ivec_element_ty.const_int(upper_bound, is_signed),
559 fvec_element_ty,
560 "",
561 ))
562 } else {
563 err!(self.builder.build_unsigned_int_to_float(
564 ivec_element_ty.const_int(upper_bound, is_signed),
565 fvec_element_ty,
566 "",
567 ))
568 };
569
570 let value = err!(self.builder.build_bit_cast(value, fvec_ty, "")).into_vector_value();
571 let zero = fvec_ty.const_zero();
572 let lower_bound = self.splat_vector(lower_bound.as_basic_value_enum(), fvec_ty)?;
573 let upper_bound = self.splat_vector(upper_bound.as_basic_value_enum(), fvec_ty)?;
574 let nan_cmp =
575 err!(
576 self.builder
577 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
578 );
579 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
580 FloatPredicate::OGT,
581 value,
582 upper_bound,
583 "above_upper_bound",
584 ));
585 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
586 FloatPredicate::OLT,
587 value,
588 lower_bound,
589 "below_lower_bound",
590 ));
591 let not_representable = err!(self.builder.build_or(
592 err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
593 below_lower_bound_cmp,
594 "not_representable_as_int",
595 ));
596 let value =
597 err!(
598 self.builder
599 .build_select(not_representable, zero, value, "safe_to_convert")
600 )
601 .into_vector_value();
602 let value = if is_signed {
603 self.builder
604 .build_float_to_signed_int(value, ivec_ty, "as_int")
605 } else {
606 self.builder
607 .build_float_to_unsigned_int(value, ivec_ty, "as_int")
608 };
609
610 let value = err!(value);
611 let value =
612 err!(
613 self.builder
614 .build_select(above_upper_bound_cmp, int_max_value, value, "")
615 )
616 .into_vector_value();
617 err_nt!(
618 self.builder
619 .build_select(below_lower_bound_cmp, int_min_value, value, "")
620 .map(|v| v.into_vector_value())
621 )
622 }
623
624 #[allow(clippy::too_many_arguments)]
627 fn trunc_sat_into_int<T: FloatMathType<'ctx>>(
628 &self,
629 fvec_ty: T,
630 ivec_ty: T::MathConvType,
631 lower_bound: u64, upper_bound: u64, int_min_value: u64,
634 int_max_value: u64,
635 value: IntValue<'ctx>,
636 ) -> Result<IntValue<'ctx>, CompileError> {
637 let res = self.trunc_sat(
638 fvec_ty,
639 ivec_ty,
640 lower_bound,
641 upper_bound,
642 int_min_value,
643 int_max_value,
644 value,
645 )?;
646 err_nt!(
647 self.builder
648 .build_bit_cast(res, self.intrinsics.i128_ty, "")
649 .map(|v| v.into_int_value())
650 )
651 }
652
653 fn trunc_sat_scalar(
656 &self,
657 int_ty: IntType<'ctx>,
658 lower_bound: u64, upper_bound: u64, int_min_value: u64,
661 int_max_value: u64,
662 value: FloatValue<'ctx>,
663 ) -> Result<IntValue<'ctx>, CompileError> {
664 let is_signed = int_min_value != 0;
680 let int_min_value = int_ty.const_int(int_min_value, is_signed);
681 let int_max_value = int_ty.const_int(int_max_value, is_signed);
682
683 let lower_bound = if is_signed {
684 err!(self.builder.build_signed_int_to_float(
685 int_ty.const_int(lower_bound, is_signed),
686 value.get_type(),
687 "",
688 ))
689 } else {
690 err!(self.builder.build_unsigned_int_to_float(
691 int_ty.const_int(lower_bound, is_signed),
692 value.get_type(),
693 "",
694 ))
695 };
696 let upper_bound = if is_signed {
697 err!(self.builder.build_signed_int_to_float(
698 int_ty.const_int(upper_bound, is_signed),
699 value.get_type(),
700 "",
701 ))
702 } else {
703 err!(self.builder.build_unsigned_int_to_float(
704 int_ty.const_int(upper_bound, is_signed),
705 value.get_type(),
706 "",
707 ))
708 };
709
710 let zero = value.get_type().const_zero();
711
712 let nan_cmp =
713 err!(
714 self.builder
715 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
716 );
717 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
718 FloatPredicate::OGT,
719 value,
720 upper_bound,
721 "above_upper_bound",
722 ));
723 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
724 FloatPredicate::OLT,
725 value,
726 lower_bound,
727 "below_lower_bound",
728 ));
729 let not_representable = err!(self.builder.build_or(
730 err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
731 below_lower_bound_cmp,
732 "not_representable_as_int",
733 ));
734 let value =
735 err!(
736 self.builder
737 .build_select(not_representable, zero, value, "safe_to_convert")
738 )
739 .into_float_value();
740 let value = if is_signed {
741 err!(
742 self.builder
743 .build_float_to_signed_int(value, int_ty, "as_int")
744 )
745 } else {
746 err!(
747 self.builder
748 .build_float_to_unsigned_int(value, int_ty, "as_int")
749 )
750 };
751 let value =
752 err!(
753 self.builder
754 .build_select(above_upper_bound_cmp, int_max_value, value, "")
755 )
756 .into_int_value();
757 let value =
758 err!(
759 self.builder
760 .build_select(below_lower_bound_cmp, int_min_value, value, "")
761 )
762 .into_int_value();
763
764 err_nt!(
765 self.builder
766 .build_bit_cast(value, int_ty, "")
767 .map(|v| v.into_int_value())
768 )
769 }
770
771 fn trap_if_not_representable_as_int(
772 &self,
773 lower_bound: u64, upper_bound: u64, value: FloatValue,
776 ) -> Result<(), CompileError> {
777 let float_ty = value.get_type();
778 let int_ty = if float_ty == self.intrinsics.f32_ty {
779 self.intrinsics.i32_ty
780 } else {
781 self.intrinsics.i64_ty
782 };
783
784 let lower_bound = err!(self.builder.build_bit_cast(
785 int_ty.const_int(lower_bound, false),
786 float_ty,
787 ""
788 ))
789 .into_float_value();
790 let upper_bound = err!(self.builder.build_bit_cast(
791 int_ty.const_int(upper_bound, false),
792 float_ty,
793 ""
794 ))
795 .into_float_value();
796
797 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
801 FloatPredicate::UGT,
802 value,
803 upper_bound,
804 "above_upper_bound",
805 ));
806 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
807 FloatPredicate::ULT,
808 value,
809 lower_bound,
810 "below_lower_bound",
811 ));
812 let out_of_bounds = err!(self.builder.build_or(
813 above_upper_bound_cmp,
814 below_lower_bound_cmp,
815 "out_of_bounds",
816 ));
817
818 let failure_block = self
819 .context
820 .append_basic_block(self.function, "conversion_failure_block");
821 let continue_block = self
822 .context
823 .append_basic_block(self.function, "conversion_success_block");
824
825 err!(
826 self.builder
827 .build_conditional_branch(out_of_bounds, failure_block, continue_block)
828 );
829 self.builder.position_at_end(failure_block);
830 let is_nan =
831 err!(
832 self.builder
833 .build_float_compare(FloatPredicate::UNO, value, value, "is_nan")
834 );
835 let trap_code = err!(self.builder.build_select(
836 is_nan,
837 self.intrinsics.trap_bad_conversion_to_integer,
838 self.intrinsics.trap_illegal_arithmetic,
839 "",
840 ));
841 err!(
842 self.builder
843 .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
844 );
845 err!(self.builder.build_unreachable());
846 self.builder.position_at_end(continue_block);
847
848 Ok(())
849 }
850
851 fn trap_if_zero_or_overflow(
852 &self,
853 left: IntValue,
854 right: IntValue,
855 ) -> Result<(), CompileError> {
856 let int_type = left.get_type();
857
858 let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
859 let min_value = int_type.const_int(i32::MIN as u64, false);
860 let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
861 (min_value, neg_one_value)
862 } else if int_type == self.intrinsics.i64_ty {
863 let min_value = int_type.const_int(i64::MIN as u64, false);
864 let neg_one_value = int_type.const_int(-1i64 as u64, false);
865 (min_value, neg_one_value)
866 } else {
867 unreachable!()
868 };
869
870 let divisor_is_zero = err!(self.builder.build_int_compare(
871 IntPredicate::EQ,
872 right,
873 int_type.const_zero(),
874 "divisor_is_zero",
875 ));
876 let should_trap = err!(self.builder.build_or(
877 divisor_is_zero,
878 err!(self.builder.build_and(
879 err!(self.builder.build_int_compare(
880 IntPredicate::EQ,
881 left,
882 min_value,
883 "left_is_min"
884 )),
885 err!(self.builder.build_int_compare(
886 IntPredicate::EQ,
887 right,
888 neg_one_value,
889 "right_is_neg_one",
890 )),
891 "div_will_overflow",
892 )),
893 "div_should_trap",
894 ));
895
896 let should_trap = err!(self.builder.build_call(
897 self.intrinsics.expect_i1,
898 &[
899 should_trap.into(),
900 self.intrinsics.i1_ty.const_zero().into(),
901 ],
902 "should_trap_expect",
903 ))
904 .try_as_basic_value()
905 .unwrap_basic()
906 .into_int_value();
907
908 let shouldnt_trap_block = self
909 .context
910 .append_basic_block(self.function, "shouldnt_trap_block");
911 let should_trap_block = self
912 .context
913 .append_basic_block(self.function, "should_trap_block");
914 err!(self.builder.build_conditional_branch(
915 should_trap,
916 should_trap_block,
917 shouldnt_trap_block
918 ));
919 self.builder.position_at_end(should_trap_block);
920 let trap_code = err!(self.builder.build_select(
921 divisor_is_zero,
922 self.intrinsics.trap_integer_division_by_zero,
923 self.intrinsics.trap_illegal_arithmetic,
924 "",
925 ));
926 err!(
927 self.builder
928 .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
929 );
930 err!(self.builder.build_unreachable());
931 self.builder.position_at_end(shouldnt_trap_block);
932
933 Ok(())
934 }
935
936 fn trap_if_zero(&self, value: IntValue) -> Result<(), CompileError> {
937 let int_type = value.get_type();
938 let should_trap = err!(self.builder.build_int_compare(
939 IntPredicate::EQ,
940 value,
941 int_type.const_zero(),
942 "divisor_is_zero",
943 ));
944
945 let should_trap = err!(self.builder.build_call(
946 self.intrinsics.expect_i1,
947 &[
948 should_trap.into(),
949 self.intrinsics.i1_ty.const_zero().into(),
950 ],
951 "should_trap_expect",
952 ))
953 .try_as_basic_value()
954 .unwrap_basic()
955 .into_int_value();
956
957 let shouldnt_trap_block = self
958 .context
959 .append_basic_block(self.function, "shouldnt_trap_block");
960 let should_trap_block = self
961 .context
962 .append_basic_block(self.function, "should_trap_block");
963 err!(self.builder.build_conditional_branch(
964 should_trap,
965 should_trap_block,
966 shouldnt_trap_block
967 ));
968 self.builder.position_at_end(should_trap_block);
969 err!(self.builder.build_call(
970 self.intrinsics.throw_trap,
971 &[self.intrinsics.trap_integer_division_by_zero.into()],
972 "throw",
973 ));
974 err!(self.builder.build_unreachable());
975 self.builder.position_at_end(shouldnt_trap_block);
976
977 Ok(())
978 }
979
980 fn v128_into_int_vec(
981 &self,
982 value: BasicValueEnum<'ctx>,
983 info: ExtraInfo,
984 int_vec_ty: VectorType<'ctx>,
985 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
986 let (value, info) = if self.config.enable_nan_canonicalization {
987 if info.has_pending_f32_nan() {
988 let value = err!(
989 self.builder
990 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
991 );
992 (self.canonicalize_nans(value)?, info.strip_pending())
993 } else if info.has_pending_f64_nan() {
994 let value = err!(
995 self.builder
996 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
997 );
998 (self.canonicalize_nans(value)?, info.strip_pending())
999 } else {
1000 (value, info)
1001 }
1002 } else {
1003 (value, info)
1004 };
1005 Ok((
1006 err!(self.builder.build_bit_cast(value, int_vec_ty, "")).into_vector_value(),
1007 info,
1008 ))
1009 }
1010
1011 fn v128_into_i8x16(
1012 &self,
1013 value: BasicValueEnum<'ctx>,
1014 info: ExtraInfo,
1015 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1016 self.v128_into_int_vec(value, info, self.intrinsics.i8x16_ty)
1017 }
1018
1019 fn v128_into_i16x8(
1020 &self,
1021 value: BasicValueEnum<'ctx>,
1022 info: ExtraInfo,
1023 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1024 self.v128_into_int_vec(value, info, self.intrinsics.i16x8_ty)
1025 }
1026
1027 fn v128_into_i32x4(
1028 &self,
1029 value: BasicValueEnum<'ctx>,
1030 info: ExtraInfo,
1031 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1032 self.v128_into_int_vec(value, info, self.intrinsics.i32x4_ty)
1033 }
1034
1035 fn v128_into_i64x2(
1036 &self,
1037 value: BasicValueEnum<'ctx>,
1038 info: ExtraInfo,
1039 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1040 self.v128_into_int_vec(value, info, self.intrinsics.i64x2_ty)
1041 }
1042
1043 fn v128_into_f32x4(
1046 &self,
1047 value: BasicValueEnum<'ctx>,
1048 info: ExtraInfo,
1049 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1050 let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f64_nan()
1051 {
1052 let value = err!(
1053 self.builder
1054 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1055 );
1056 (self.canonicalize_nans(value)?, info.strip_pending())
1057 } else {
1058 (value, info)
1059 };
1060 Ok((
1061 err!(
1062 self.builder
1063 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1064 )
1065 .into_vector_value(),
1066 info,
1067 ))
1068 }
1069
1070 fn v128_into_f64x2(
1073 &self,
1074 value: BasicValueEnum<'ctx>,
1075 info: ExtraInfo,
1076 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1077 let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f32_nan()
1078 {
1079 let value = err!(
1080 self.builder
1081 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1082 );
1083 (self.canonicalize_nans(value)?, info.strip_pending())
1084 } else {
1085 (value, info)
1086 };
1087 Ok((
1088 err!(
1089 self.builder
1090 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1091 )
1092 .into_vector_value(),
1093 info,
1094 ))
1095 }
1096
1097 fn apply_pending_canonicalization(
1098 &self,
1099 value: BasicValueEnum<'ctx>,
1100 info: ExtraInfo,
1101 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1102 if !self.config.enable_nan_canonicalization {
1103 return Ok(value);
1104 }
1105
1106 if info.has_pending_f32_nan() {
1107 if value.get_type().is_vector_type()
1108 || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1109 {
1110 let ty = value.get_type();
1111 let value = err!(
1112 self.builder
1113 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1114 );
1115 let value = self.canonicalize_nans(value)?;
1116 err_nt!(self.builder.build_bit_cast(value, ty, ""))
1117 } else {
1118 self.canonicalize_nans(value)
1119 }
1120 } else if info.has_pending_f64_nan() {
1121 if value.get_type().is_vector_type()
1122 || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1123 {
1124 let ty = value.get_type();
1125 let value = err!(
1126 self.builder
1127 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1128 );
1129 let value = self.canonicalize_nans(value)?;
1130 err_nt!(self.builder.build_bit_cast(value, ty, ""))
1131 } else {
1132 self.canonicalize_nans(value)
1133 }
1134 } else {
1135 Ok(value)
1136 }
1137 }
1138
1139 fn canonicalize_nans(
1141 &self,
1142 value: BasicValueEnum<'ctx>,
1143 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1144 if !self.config.enable_nan_canonicalization {
1145 return Ok(value);
1146 }
1147
1148 let f_ty = value.get_type();
1149 if f_ty.is_vector_type() {
1150 let value = value.into_vector_value();
1151 let f_ty = f_ty.into_vector_type();
1152 let zero = f_ty.const_zero();
1153 let nan_cmp =
1154 err!(
1155 self.builder
1156 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1157 );
1158 let canonical_qnan = f_ty
1159 .get_element_type()
1160 .into_float_type()
1161 .const_float(f64::NAN);
1162 let canonical_qnan = self.splat_vector(canonical_qnan.as_basic_value_enum(), f_ty)?;
1163 err_nt!(
1164 self.builder
1165 .build_select(nan_cmp, canonical_qnan, value, "")
1166 .map(|v| v.as_basic_value_enum())
1167 )
1168 } else {
1169 let value = value.into_float_value();
1170 let f_ty = f_ty.into_float_type();
1171 let zero = f_ty.const_zero();
1172 let nan_cmp =
1173 err!(
1174 self.builder
1175 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1176 );
1177 let canonical_qnan = f_ty.const_float(f64::NAN);
1178 err_nt!(
1179 self.builder
1180 .build_select(nan_cmp, canonical_qnan, value, "")
1181 .map(|v| v.as_basic_value_enum())
1182 )
1183 }
1184 }
1185
1186 fn mark_memaccess_nodelete(
1190 &mut self,
1191 memory_index: MemoryIndex,
1192 memaccess: InstructionValue<'ctx>,
1193 ) -> Result<(), CompileError> {
1194 if let MemoryCache::Static { base_ptr: _ } = self.ctx.memory(
1195 memory_index,
1196 self.intrinsics,
1197 self.module,
1198 self.memory_styles,
1199 )? {
1200 memaccess.set_volatile(true).unwrap();
1203 }
1204 Ok(())
1205 }
1206
1207 fn annotate_user_memaccess(
1208 &mut self,
1209 memory_index: MemoryIndex,
1210 _memarg: &MemArg,
1211 alignment: u32,
1212 memaccess: InstructionValue<'ctx>,
1213 ) -> Result<(), CompileError> {
1214 match memaccess.get_opcode() {
1215 InstructionOpcode::Load | InstructionOpcode::Store => {
1216 memaccess.set_alignment(alignment).unwrap();
1217 }
1218 _ => {}
1219 };
1220 self.mark_memaccess_nodelete(memory_index, memaccess)?;
1221 tbaa_label(
1222 self.module,
1223 self.intrinsics,
1224 format!("memory {}", memory_index.as_u32()),
1225 memaccess,
1226 );
1227 Ok(())
1228 }
1229
1230 fn resolve_memory_ptr(
1231 &mut self,
1232 memory_index: MemoryIndex,
1233 memarg: &MemArg,
1234 ptr_ty: PointerType<'ctx>,
1235 var_offset: IntValue<'ctx>,
1236 value_size: usize,
1237 ) -> Result<PointerValue<'ctx>, CompileError> {
1238 let builder = &self.builder;
1239 let intrinsics = &self.intrinsics;
1240 let context = &self.context;
1241 let function = &self.function;
1242
1243 let imm_offset = intrinsics.i64_ty.const_int(memarg.offset, false);
1245 let var_offset = err!(builder.build_int_z_extend(var_offset, intrinsics.i64_ty, ""));
1246 let offset = err!(builder.build_int_add(var_offset, imm_offset, ""));
1247
1248 let base_ptr = if let Some((_, ref m0)) = self.g0m0 {
1250 *m0
1251 } else {
1252 match self
1253 .ctx
1254 .memory(memory_index, intrinsics, self.module, self.memory_styles)?
1255 {
1256 MemoryCache::Dynamic {
1257 ptr_to_base_ptr,
1258 ptr_to_current_length,
1259 } => {
1260 let minimum = self.wasm_module.memories[memory_index].minimum;
1262 let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
1263 let ptr_in_bounds = if offset.is_const() {
1264 let load_offset_end =
1267 offset.const_add(value_size_v).get_zero_extended_constant();
1268 if load_offset_end.is_some_and(|load_offset_end| {
1269 load_offset_end <= minimum.bytes().0 as u64
1270 }) {
1271 Some(intrinsics.i64_ty.const_int(1, false))
1272 } else {
1273 None
1274 }
1275 } else {
1276 None
1277 };
1278
1279 let ptr_in_bounds = match ptr_in_bounds {
1280 Some(ptr) => ptr,
1281 None => {
1282 let load_offset_end = err!(builder.build_int_add(
1283 offset,
1284 value_size_v,
1285 "load_offset_end"
1286 ));
1287
1288 let current_length = err!(builder.build_load(
1289 self.intrinsics.i32_ty,
1290 ptr_to_current_length,
1291 "current_length"
1292 ))
1293 .into_int_value();
1294 tbaa_label(
1295 self.module,
1296 self.intrinsics,
1297 format!("memory {} length", memory_index.as_u32()),
1298 current_length.as_instruction_value().unwrap(),
1299 );
1300 let current_length = err!(builder.build_int_z_extend(
1301 current_length,
1302 intrinsics.i64_ty,
1303 "current_length_zextd"
1304 ));
1305
1306 err!(builder.build_int_compare(
1307 IntPredicate::ULE,
1308 load_offset_end,
1309 current_length,
1310 "ptr_in_bounds",
1311 ))
1312 }
1313 };
1314
1315 if !ptr_in_bounds.is_constant_int()
1316 || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
1317 {
1318 let ptr_in_bounds = err!(builder.build_call(
1324 intrinsics.expect_i1,
1325 &[
1326 ptr_in_bounds.into(),
1327 intrinsics.i1_ty.const_int(1, true).into(),
1328 ],
1329 "ptr_in_bounds_expect",
1330 ))
1331 .try_as_basic_value()
1332 .unwrap_basic()
1333 .into_int_value();
1334
1335 let in_bounds_continue_block =
1336 context.append_basic_block(*function, "in_bounds_continue_block");
1337 let not_in_bounds_block =
1338 context.append_basic_block(*function, "not_in_bounds_block");
1339 err!(builder.build_conditional_branch(
1340 ptr_in_bounds,
1341 in_bounds_continue_block,
1342 not_in_bounds_block,
1343 ));
1344 builder.position_at_end(not_in_bounds_block);
1345 err!(builder.build_call(
1346 intrinsics.throw_trap,
1347 &[intrinsics.trap_memory_oob.into()],
1348 "throw",
1349 ));
1350 err!(builder.build_unreachable());
1351 builder.position_at_end(in_bounds_continue_block);
1352 }
1353 let ptr_to_base =
1354 err!(builder.build_load(intrinsics.ptr_ty, ptr_to_base_ptr, "ptr_to_base"))
1355 .into_pointer_value();
1356 tbaa_label(
1357 self.module,
1358 self.intrinsics,
1359 format!("memory base_ptr {}", memory_index.as_u32()),
1360 ptr_to_base.as_instruction_value().unwrap(),
1361 );
1362 ptr_to_base
1363 }
1364 MemoryCache::Static { base_ptr } => base_ptr,
1365 }
1366 };
1367 let value_ptr = unsafe {
1368 err!(builder.build_gep(self.intrinsics.i8_ty, base_ptr, &[offset], "mem_value_ptr"))
1369 };
1370 err_nt!(
1371 builder
1372 .build_bit_cast(value_ptr, ptr_ty, "mem_value")
1373 .map(|v| v.into_pointer_value())
1374 )
1375 }
1376
1377 fn trap_if_misaligned(
1378 &self,
1379 _memarg: &MemArg,
1380 ptr: PointerValue<'ctx>,
1381 align: u8,
1382 ) -> Result<(), CompileError> {
1383 if align <= 1 {
1384 return Ok(());
1385 }
1386 let value = err!(self.builder.build_ptr_to_int(
1387 ptr,
1388 self.intrinsics.i64_ty,
1389 "mischeck_value"
1390 ));
1391 let and = err!(self.builder.build_and(
1392 value,
1393 self.intrinsics.i64_ty.const_int((align - 1).into(), false),
1394 "misaligncheck",
1395 ));
1396 let aligned = err!(self.builder.build_int_compare(
1397 IntPredicate::EQ,
1398 and,
1399 self.intrinsics.i64_zero,
1400 "is_aligned"
1401 ));
1402 let aligned = err!(self.builder.build_call(
1403 self.intrinsics.expect_i1,
1404 &[
1405 aligned.into(),
1406 self.intrinsics.i1_ty.const_int(1, false).into(),
1407 ],
1408 "is_aligned_expect",
1409 ))
1410 .try_as_basic_value()
1411 .unwrap_basic()
1412 .into_int_value();
1413
1414 let continue_block = self
1415 .context
1416 .append_basic_block(self.function, "aligned_access_continue_block");
1417 let not_aligned_block = self
1418 .context
1419 .append_basic_block(self.function, "misaligned_trap_block");
1420 err!(
1421 self.builder
1422 .build_conditional_branch(aligned, continue_block, not_aligned_block)
1423 );
1424
1425 self.builder.position_at_end(not_aligned_block);
1426 err!(self.builder.build_call(
1427 self.intrinsics.throw_trap,
1428 &[self.intrinsics.trap_unaligned_atomic.into()],
1429 "throw",
1430 ));
1431 err!(self.builder.build_unreachable());
1432
1433 self.builder.position_at_end(continue_block);
1434 Ok(())
1435 }
1436
1437 fn finalize(&mut self, wasm_fn_type: &FunctionType) -> Result<(), CompileError> {
1438 let func_type = self.function.get_type();
1439
1440 let results = self.state.popn_save_extra(wasm_fn_type.results().len())?;
1441 let results = err!(
1442 results
1443 .into_iter()
1444 .map(|(v, i)| self.apply_pending_canonicalization(v, i))
1445 .collect::<Result<Vec<_>, _>>()
1446 );
1447
1448 if wasm_fn_type.results().is_empty() {
1449 err!(self.builder.build_return(None));
1450 } else if self.abi.is_sret(wasm_fn_type)? {
1451 let sret = self
1452 .function
1453 .get_first_param()
1454 .unwrap()
1455 .into_pointer_value();
1456 let llvm_params: Vec<_> = wasm_fn_type
1457 .results()
1458 .iter()
1459 .map(|x| type_to_llvm(self.intrinsics, *x).unwrap())
1460 .collect();
1461 let mut struct_value = self
1462 .context
1463 .struct_type(llvm_params.as_slice(), false)
1464 .get_undef();
1465 for (idx, value) in results.into_iter().enumerate() {
1466 let value = err!(self.builder.build_bit_cast(
1467 value,
1468 type_to_llvm(self.intrinsics, wasm_fn_type.results()[idx])?,
1469 "",
1470 ));
1471 struct_value =
1472 err!(
1473 self.builder
1474 .build_insert_value(struct_value, value, idx as u32, "")
1475 )
1476 .into_struct_value();
1477 }
1478 err!(self.builder.build_store(sret, struct_value));
1479 err!(self.builder.build_return(None));
1480 } else {
1481 err!(
1482 self.builder
1483 .build_return(Some(&self.abi.pack_values_for_register_return(
1484 self.intrinsics,
1485 &self.builder,
1486 &results,
1487 &func_type,
1488 )?))
1489 );
1490 }
1491 Ok(())
1492 }
1493
1494 fn get_or_insert_tag_type_info_global(&mut self, tag: i32) -> BasicValueEnum<'ctx> {
1497 if let Some(tag) = self.tags_cache.get(&tag) {
1498 return *tag;
1499 }
1500
1501 let tag_ty = self
1502 .context
1503 .struct_type(&[self.intrinsics.i32_ty.into()], false);
1504 let tag_glbl = self.module.add_global(
1505 tag_ty,
1506 Some(AddressSpace::default()),
1507 &format!("__wasmer_eh_type_info_{tag}"),
1508 );
1509 tag_glbl.set_initializer(
1510 &tag_ty
1511 .const_named_struct(&[self.intrinsics.i32_ty.const_int(tag as _, false).into()])
1512 .as_basic_value_enum(),
1513 );
1514
1515 tag_glbl.set_linkage(Linkage::External);
1516 tag_glbl.set_constant(true);
1517 if matches!(self.binary_fmt, target_lexicon::BinaryFormat::Macho) {
1525 tag_glbl.set_section(Some(&format!("{FUNCTION_SECTION_MACHO},_eh_ti_{tag}")));
1526 }
1527
1528 let tag_glbl = tag_glbl.as_basic_value_enum();
1529
1530 self.tags_cache.insert(tag, tag_glbl);
1531 tag_glbl
1532 }
1533
1534 fn build_g0m0_indirect_call(
1535 &mut self,
1536 table_index: u32,
1537 ctx_ptr: PointerValue<'ctx>,
1538 func_type: &FunctionType,
1539 func_ptr: PointerValue<'ctx>,
1540 func_index: IntValue<'ctx>,
1541 ) -> Result<(), CompileError> {
1542 let Some((g0, m0)) = self.g0m0 else {
1543 return Err(CompileError::Codegen(
1544 "Call to build_g0m0_indirect_call without g0m0 parameters!".to_string(),
1545 ));
1546 };
1547
1548 let mut local_func_indices = vec![];
1549 let mut foreign_func_indices = vec![];
1550
1551 for t in &self.wasm_module.table_initializers {
1552 if t.table_index.as_u32() == table_index {
1553 for (func_in_table_idx, func_idx) in t.elements.iter().enumerate() {
1554 if self.wasm_module.local_func_index(*func_idx).is_some() {
1555 local_func_indices.push(func_in_table_idx)
1556 } else {
1557 foreign_func_indices.push(func_in_table_idx)
1558 }
1559 }
1560 break;
1561 }
1562 }
1563
1564 let g0_value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, "g0"));
1567
1568 let needs_switch = self.g0m0.is_some()
1569 && !local_func_indices.is_empty()
1570 && !foreign_func_indices.is_empty();
1571
1572 if needs_switch {
1573 let foreign_idx_block = self
1574 .context
1575 .append_basic_block(self.function, "foreign_call_block");
1576 let local_idx_block = self
1577 .context
1578 .append_basic_block(self.function, "local_call_block");
1579 let unreachable_indirect_call_branch_block = self
1580 .context
1581 .append_basic_block(self.function, "unreachable_indirect_call_branch");
1582
1583 let cont = self.context.append_basic_block(self.function, "cont");
1584
1585 err!(
1586 self.builder.build_switch(
1587 func_index,
1588 unreachable_indirect_call_branch_block,
1589 &local_func_indices
1590 .into_iter()
1591 .map(|v| (
1592 self.intrinsics.i32_ty.const_int(v as _, false),
1593 local_idx_block
1594 ))
1595 .chain(foreign_func_indices.into_iter().map(|v| (
1596 self.intrinsics.i32_ty.const_int(v as _, false),
1597 foreign_idx_block
1598 )))
1599 .collect::<Vec<_>>()
1600 )
1601 );
1602
1603 self.builder
1604 .position_at_end(unreachable_indirect_call_branch_block);
1605 err!(self.builder.build_unreachable());
1606
1607 self.builder.position_at_end(local_idx_block);
1609 let local_call_site = self.build_indirect_call(
1610 ctx_ptr,
1611 func_type,
1612 func_ptr,
1613 Some(G0M0FunctionKind::Local),
1614 Some((g0_value.into_int_value(), m0)),
1615 )?;
1616
1617 let local_rets = self.abi.rets_from_call(
1618 &self.builder,
1619 self.intrinsics,
1620 local_call_site,
1621 func_type,
1622 )?;
1623
1624 err!(self.builder.build_unconditional_branch(cont));
1625
1626 self.builder.position_at_end(foreign_idx_block);
1627 let foreign_call_site = self.build_indirect_call(
1628 ctx_ptr,
1629 func_type,
1630 func_ptr,
1631 Some(G0M0FunctionKind::Imported),
1632 None,
1633 )?;
1634
1635 let foreign_rets = self.abi.rets_from_call(
1636 &self.builder,
1637 self.intrinsics,
1638 foreign_call_site,
1639 func_type,
1640 )?;
1641
1642 err!(self.builder.build_unconditional_branch(cont));
1643
1644 self.builder.position_at_end(cont);
1645
1646 for i in 0..foreign_rets.len() {
1647 let f_i = foreign_rets[i];
1648 let l_i = local_rets[i];
1649 let ty = f_i.get_type();
1650 let v = err!(self.builder.build_phi(ty, ""));
1651 v.add_incoming(&[(&f_i, foreign_idx_block), (&l_i, local_idx_block)]);
1652 self.state.push1(v.as_basic_value());
1653 }
1654 } else if foreign_func_indices.is_empty() {
1655 let call_site = self.build_indirect_call(
1656 ctx_ptr,
1657 func_type,
1658 func_ptr,
1659 Some(G0M0FunctionKind::Local),
1660 Some((g0_value.into_int_value(), m0)),
1661 )?;
1662
1663 self.abi
1664 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1665 .iter()
1666 .for_each(|ret| self.state.push1(*ret));
1667 } else {
1668 let call_site = self.build_indirect_call(
1669 ctx_ptr,
1670 func_type,
1671 func_ptr,
1672 Some(G0M0FunctionKind::Imported),
1673 Some((g0_value.into_int_value(), m0)),
1674 )?;
1675 self.abi
1676 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1677 .iter()
1678 .for_each(|ret| self.state.push1(*ret));
1679 }
1680
1681 Ok(())
1682 }
1683
1684 fn build_indirect_call(
1685 &mut self,
1686 ctx_ptr: PointerValue<'ctx>,
1687 func_type: &FunctionType,
1688 func_ptr: PointerValue<'ctx>,
1689 func_kind: Option<G0M0FunctionKind>,
1690 g0m0_params: LocalFunctionG0M0params<'ctx>,
1691 ) -> Result<CallSiteValue<'ctx>, CompileError> {
1692 let (llvm_func_type, llvm_func_attrs) = self.abi.func_type_to_llvm(
1693 self.context,
1694 self.intrinsics,
1695 Some(self.ctx.get_offsets()),
1696 func_type,
1697 func_kind,
1698 )?;
1699
1700 let params = self.state.popn_save_extra(func_type.params().len())?;
1701
1702 let params = params
1704 .iter()
1705 .zip(func_type.params().iter())
1706 .map(|((v, info), wasm_ty)| match wasm_ty {
1707 Type::F32 => err_nt!(self.builder.build_bit_cast(
1708 self.apply_pending_canonicalization(*v, *info)?,
1709 self.intrinsics.f32_ty,
1710 "",
1711 )),
1712 Type::F64 => err_nt!(self.builder.build_bit_cast(
1713 self.apply_pending_canonicalization(*v, *info)?,
1714 self.intrinsics.f64_ty,
1715 "",
1716 )),
1717 Type::V128 => self.apply_pending_canonicalization(*v, *info),
1718 _ => Ok(*v),
1719 })
1720 .collect::<Result<Vec<_>, _>>()?;
1721
1722 let params = self.abi.args_to_call(
1723 &self.alloca_builder,
1724 func_type,
1725 &llvm_func_type,
1726 ctx_ptr,
1727 params.as_slice(),
1728 self.intrinsics,
1729 g0m0_params,
1730 )?;
1731
1732 let typed_func_ptr = err!(self.builder.build_pointer_cast(
1733 func_ptr,
1734 self.context.ptr_type(AddressSpace::default()),
1735 "typed_func_ptr",
1736 ));
1737
1738 let call_site_local = if let Some(lpad) = self.state.get_innermost_landingpad() {
1759 let then_block = self.context.append_basic_block(self.function, "then_block");
1760
1761 let ret = err!(self.builder.build_indirect_invoke(
1762 llvm_func_type,
1763 typed_func_ptr,
1764 params.as_slice(),
1765 then_block,
1766 lpad,
1767 "",
1768 ));
1769
1770 self.builder.position_at_end(then_block);
1771 ret
1772 } else {
1773 err!(
1774 self.builder.build_indirect_call(
1775 llvm_func_type,
1776 typed_func_ptr,
1777 params
1778 .iter()
1779 .copied()
1780 .map(Into::into)
1781 .collect::<Vec<BasicMetadataValueEnum>>()
1782 .as_slice(),
1783 "indirect_call",
1784 )
1785 )
1786 };
1787 for (attr, attr_loc) in llvm_func_attrs {
1788 call_site_local.add_attribute(attr_loc, attr);
1789 }
1790
1791 Ok(call_site_local)
1792 }
1793}
1794
1795pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
1881 g0m0: Option<(PointerValue<'ctx>, PointerValue<'ctx>)>,
1882 context: &'ctx Context,
1883 builder: Builder<'ctx>,
1884 alloca_builder: Builder<'ctx>,
1885 intrinsics: &'a Intrinsics<'ctx>,
1886 state: State<'ctx>,
1887 function: FunctionValue<'ctx>,
1888 locals: Vec<(BasicTypeEnum<'ctx>, PointerValue<'ctx>)>, ctx: CtxType<'ctx, 'a>,
1890 unreachable_depth: usize,
1891 memory_styles: &'a PrimaryMap<MemoryIndex, MemoryStyle>,
1892 _table_styles: &'a PrimaryMap<TableIndex, TableStyle>,
1893
1894 module: &'a Module<'ctx>,
1902 module_translation: &'a ModuleTranslationState,
1903 wasm_module: &'a ModuleInfo,
1904 symbol_registry: &'a dyn SymbolRegistry,
1905 abi: &'a dyn Abi,
1906 config: &'a LLVM,
1907 tags_cache: HashMap<i32, BasicValueEnum<'ctx>>,
1908 binary_fmt: target_lexicon::BinaryFormat,
1909}
1910
1911impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
1912 fn quiet_nan(&self, value: BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, CompileError> {
1913 let intrinsic = if value
1914 .get_type()
1915 .eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1916 {
1917 Some(self.intrinsics.add_f32)
1918 } else if value
1919 .get_type()
1920 .eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1921 {
1922 Some(self.intrinsics.add_f64)
1923 } else if value
1924 .get_type()
1925 .eq(&self.intrinsics.f32x4_ty.as_basic_type_enum())
1926 {
1927 Some(self.intrinsics.add_f32x4)
1928 } else if value
1929 .get_type()
1930 .eq(&self.intrinsics.f64x2_ty.as_basic_type_enum())
1931 {
1932 Some(self.intrinsics.add_f64x2)
1933 } else {
1934 None
1935 };
1936
1937 match intrinsic {
1938 Some(intrinsic) => err_nt!(
1939 self.builder
1940 .build_call(
1941 intrinsic,
1942 &[
1943 value.into(),
1944 value.get_type().const_zero().into(),
1945 self.intrinsics.fp_rounding_md,
1946 self.intrinsics.fp_exception_md,
1947 ],
1948 "",
1949 )
1950 .map(|v| v.try_as_basic_value().unwrap_basic())
1951 ),
1952 None => Ok(value),
1953 }
1954 }
1955
1956 fn finalize_minmax_result(
1957 &self,
1958 value: BasicValueEnum<'ctx>,
1959 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1960 let ty = value.get_type();
1961 if ty.eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1962 || ty.eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1963 {
1964 let value = value.into_float_value();
1965 let is_nan = err!(self.builder.build_float_compare(
1966 FloatPredicate::UNO,
1967 value,
1968 value,
1969 "res_is_nan"
1970 ));
1971 let quiet = self.quiet_nan(value.as_basic_value_enum())?;
1972 let result =
1973 err!(
1974 self.builder
1975 .build_select(is_nan, quiet, value.as_basic_value_enum(), "")
1976 );
1977 Ok(result.as_basic_value_enum())
1978 } else if ty.eq(&self.intrinsics.f32x4_ty.as_basic_type_enum()) {
1979 let value = value.into_vector_value();
1980 let is_nan = err!(self.builder.build_call(
1981 self.intrinsics.cmp_f32x4,
1982 &[
1983 value.into(),
1984 value.into(),
1985 self.intrinsics.fp_uno_md,
1986 self.intrinsics.fp_exception_md,
1987 ],
1988 "",
1989 ))
1990 .try_as_basic_value()
1991 .unwrap_basic()
1992 .into_vector_value();
1993 let quiet = self
1994 .quiet_nan(value.as_basic_value_enum())?
1995 .into_vector_value();
1996 let result = err!(self.builder.build_select(
1997 is_nan,
1998 quiet.as_basic_value_enum(),
1999 value.as_basic_value_enum(),
2000 "",
2001 ));
2002 Ok(result.as_basic_value_enum())
2003 } else if ty.eq(&self.intrinsics.f64x2_ty.as_basic_type_enum()) {
2004 let value = value.into_vector_value();
2005 let is_nan = err!(self.builder.build_call(
2006 self.intrinsics.cmp_f64x2,
2007 &[
2008 value.into(),
2009 value.into(),
2010 self.intrinsics.fp_uno_md,
2011 self.intrinsics.fp_exception_md,
2012 ],
2013 "",
2014 ))
2015 .try_as_basic_value()
2016 .unwrap_basic()
2017 .into_vector_value();
2018 let quiet = self
2019 .quiet_nan(value.as_basic_value_enum())?
2020 .into_vector_value();
2021 let result = err!(self.builder.build_select(
2022 is_nan,
2023 quiet.as_basic_value_enum(),
2024 value.as_basic_value_enum(),
2025 "",
2026 ));
2027 Ok(result.as_basic_value_enum())
2028 } else {
2029 Ok(value)
2030 }
2031 }
2032
2033 fn translate_operator(&mut self, op: Operator, _source_loc: u32) -> Result<(), CompileError> {
2034 let vmctx = &self.ctx.basic().into_pointer_value();
2037
2038 if !self.state.reachable {
2041 match op {
2042 Operator::Block { blockty: _ }
2043 | Operator::Loop { blockty: _ }
2044 | Operator::If { blockty: _ } => {
2045 self.unreachable_depth += 1;
2046 return Ok(());
2047 }
2048 Operator::Else => {
2049 if self.unreachable_depth != 0 {
2050 return Ok(());
2051 }
2052 }
2053 Operator::End => {
2054 if self.unreachable_depth != 0 {
2055 self.unreachable_depth -= 1;
2056 return Ok(());
2057 }
2058 }
2059 _ => {
2060 return Ok(());
2061 }
2062 }
2063 }
2064
2065 match op {
2066 Operator::Block { blockty } => {
2071 let current_block = self
2072 .builder
2073 .get_insert_block()
2074 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2075
2076 let end_block = self.context.append_basic_block(self.function, "end");
2077 self.builder.position_at_end(end_block);
2078
2079 let phis: SmallVec<[PhiValue<'ctx>; 1]> = self
2080 .module_translation
2081 .blocktype_params_results(&blockty)?
2082 .1
2083 .iter()
2084 .map(|&wp_ty| {
2085 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2086 type_to_llvm(self.intrinsics, wasm_ty)
2087 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2088 })
2089 })
2090 .collect::<Result<_, _>>()?;
2091
2092 self.state.push_block(
2093 end_block,
2094 phis,
2095 self.module_translation
2096 .blocktype_params_results(&blockty)?
2097 .0
2098 .len(),
2099 );
2100 self.builder.position_at_end(current_block);
2101 }
2102 Operator::Loop { blockty } => {
2103 let loop_body = self.context.append_basic_block(self.function, "loop_body");
2104 let loop_next = self.context.append_basic_block(self.function, "loop_outer");
2105 let pre_loop_block = self.builder.get_insert_block().unwrap();
2106
2107 err!(self.builder.build_unconditional_branch(loop_body));
2108
2109 self.builder.position_at_end(loop_next);
2110 let blocktypes = self.module_translation.blocktype_params_results(&blockty)?;
2111 let phis = blocktypes
2112 .1
2113 .iter()
2114 .map(|&wp_ty| {
2115 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2116 type_to_llvm(self.intrinsics, wasm_ty)
2117 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2118 })
2119 })
2120 .collect::<Result<_, _>>()?;
2121 self.builder.position_at_end(loop_body);
2122 let loop_phis: SmallVec<[PhiValue<'ctx>; 1]> = blocktypes
2123 .0
2124 .iter()
2125 .map(|&wp_ty| {
2126 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2127 type_to_llvm(self.intrinsics, wasm_ty)
2128 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2129 })
2130 })
2131 .collect::<Result<_, _>>()?;
2132 for phi in loop_phis.iter().rev() {
2133 let (value, info) = self.state.pop1_extra()?;
2134 let value = self.apply_pending_canonicalization(value, info)?;
2135 phi.add_incoming(&[(&value, pre_loop_block)]);
2136 }
2137 for phi in &loop_phis {
2138 self.state.push1(phi.as_basic_value());
2139 }
2140
2141 let num_inputs = loop_phis.len();
2142 self.state
2143 .push_loop(loop_body, loop_next, loop_phis, phis, num_inputs);
2144 }
2145 Operator::Br { relative_depth } => {
2146 let frame = self.state.frame_at_depth(relative_depth)?;
2147
2148 let current_block = self
2149 .builder
2150 .get_insert_block()
2151 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2152
2153 let phis = if frame.is_loop() {
2154 frame.loop_body_phis()
2155 } else {
2156 frame.phis()
2157 };
2158
2159 let len = phis.len();
2160 let values = self.state.peekn_extra(len)?;
2161 let values = values
2162 .iter()
2163 .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2164 .collect::<Result<Vec<_>, _>>()?;
2165
2166 for (phi, value) in phis.iter().zip(values.into_iter()) {
2170 phi.add_incoming(&[(&value, current_block)]);
2171 }
2172
2173 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2174
2175 self.state.popn(len)?;
2176 self.state.reachable = false;
2177 }
2178 Operator::BrIf { relative_depth } => {
2179 let cond = self.state.pop1()?;
2180 let frame = self.state.frame_at_depth(relative_depth)?;
2181
2182 let current_block = self
2183 .builder
2184 .get_insert_block()
2185 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2186
2187 let phis = if frame.is_loop() {
2188 frame.loop_body_phis()
2189 } else {
2190 frame.phis()
2191 };
2192
2193 let param_stack = self.state.peekn_extra(phis.len())?;
2194 let param_stack = param_stack
2195 .iter()
2196 .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2197 .collect::<Result<Vec<_>, _>>()?;
2198
2199 for (phi, value) in phis.iter().zip(param_stack) {
2200 phi.add_incoming(&[(&value, current_block)]);
2201 }
2202
2203 let else_block = self.context.append_basic_block(self.function, "else");
2204
2205 let cond_value = err!(self.builder.build_int_compare(
2206 IntPredicate::NE,
2207 cond.into_int_value(),
2208 self.intrinsics.i32_zero,
2209 "",
2210 ));
2211 err!(self.builder.build_conditional_branch(
2212 cond_value,
2213 *frame.br_dest(),
2214 else_block
2215 ));
2216 self.builder.position_at_end(else_block);
2217 }
2218 Operator::BrTable { ref targets } => {
2219 let current_block = self
2220 .builder
2221 .get_insert_block()
2222 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2223
2224 let index = self.state.pop1()?;
2225
2226 let default_frame = self.state.frame_at_depth(targets.default())?;
2227
2228 let phis = if default_frame.is_loop() {
2229 default_frame.loop_body_phis()
2230 } else {
2231 default_frame.phis()
2232 };
2233 let args = self.state.peekn(phis.len())?;
2234
2235 for (phi, value) in phis.iter().zip(args.iter()) {
2236 phi.add_incoming(&[(value, current_block)]);
2237 }
2238
2239 let cases: Vec<_> = targets
2240 .targets()
2241 .enumerate()
2242 .map(|(case_index, depth)| {
2243 let depth = depth.map_err(from_binaryreadererror_wasmerror)?;
2244 let frame_result: Result<&ControlFrame, CompileError> =
2245 self.state.frame_at_depth(depth);
2246 let frame = match frame_result {
2247 Ok(v) => v,
2248 Err(e) => return Err(e),
2249 };
2250 let case_index_literal =
2251 self.context.i32_type().const_int(case_index as u64, false);
2252 let phis = if frame.is_loop() {
2253 frame.loop_body_phis()
2254 } else {
2255 frame.phis()
2256 };
2257 for (phi, value) in phis.iter().zip(args.iter()) {
2258 phi.add_incoming(&[(value, current_block)]);
2259 }
2260
2261 Ok((case_index_literal, *frame.br_dest()))
2262 })
2263 .collect::<Result<_, _>>()?;
2264
2265 err!(self.builder.build_switch(
2266 index.into_int_value(),
2267 *default_frame.br_dest(),
2268 &cases[..],
2269 ));
2270
2271 let args_len = args.len();
2272 self.state.popn(args_len)?;
2273 self.state.reachable = false;
2274 }
2275 Operator::If { blockty } => {
2276 let current_block = self
2277 .builder
2278 .get_insert_block()
2279 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2280 let if_then_block = self.context.append_basic_block(self.function, "if_then");
2281 let if_else_block = self.context.append_basic_block(self.function, "if_else");
2282 let end_block = self.context.append_basic_block(self.function, "if_end");
2283
2284 let end_phis = {
2285 self.builder.position_at_end(end_block);
2286
2287 let phis = self
2288 .module_translation
2289 .blocktype_params_results(&blockty)?
2290 .1
2291 .iter()
2292 .map(|&wp_ty| {
2293 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2294 type_to_llvm(self.intrinsics, wasm_ty)
2295 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2296 })
2297 })
2298 .collect::<Result<_, _>>()?;
2299
2300 self.builder.position_at_end(current_block);
2301 phis
2302 };
2303
2304 let cond = self.state.pop1()?;
2305
2306 let cond_value = err!(self.builder.build_int_compare(
2307 IntPredicate::NE,
2308 cond.into_int_value(),
2309 self.intrinsics.i32_zero,
2310 "",
2311 ));
2312
2313 err!(self.builder.build_conditional_branch(
2314 cond_value,
2315 if_then_block,
2316 if_else_block
2317 ));
2318 self.builder.position_at_end(if_else_block);
2319 let block_param_types = self
2320 .module_translation
2321 .blocktype_params_results(&blockty)?
2322 .0
2323 .iter()
2324 .map(|&wp_ty| {
2325 err_nt!(wptype_to_type(wp_ty))
2326 .and_then(|wasm_ty| type_to_llvm(self.intrinsics, wasm_ty))
2327 })
2328 .collect::<Result<Vec<_>, _>>()?;
2329 let else_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2330 .iter()
2331 .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2332 .collect::<Result<SmallVec<_>, _>>()?;
2333 self.builder.position_at_end(if_then_block);
2334 let then_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2335 .iter()
2336 .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2337 .collect::<Result<SmallVec<_>, _>>()?;
2338 for (else_phi, then_phi) in else_phis.iter().rev().zip(then_phis.iter().rev()) {
2339 let (value, info) = self.state.pop1_extra()?;
2340 let value = self.apply_pending_canonicalization(value, info)?;
2341 else_phi.add_incoming(&[(&value, current_block)]);
2342 then_phi.add_incoming(&[(&value, current_block)]);
2343 }
2344 for phi in then_phis.iter() {
2345 self.state.push1(phi.as_basic_value());
2346 }
2347
2348 self.state.push_if(
2349 if_then_block,
2350 if_else_block,
2351 end_block,
2352 then_phis,
2353 else_phis,
2354 end_phis,
2355 block_param_types.len(),
2356 );
2357 }
2358 Operator::Else => {
2359 if self.state.reachable {
2360 let frame = self.state.frame_at_depth(0)?;
2361 let current_block = self.builder.get_insert_block().ok_or_else(|| {
2362 CompileError::Codegen("not currently in a block".to_string())
2363 })?;
2364
2365 for phi in frame.phis().to_vec().iter().rev() {
2366 let (value, info) = self.state.pop1_extra()?;
2367 let value = self.apply_pending_canonicalization(value, info)?;
2368 phi.add_incoming(&[(&value, current_block)])
2369 }
2370
2371 let frame = self.state.frame_at_depth(0)?;
2372 err!(self.builder.build_unconditional_branch(*frame.code_after()));
2373 }
2374
2375 let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
2376 if_else,
2377 if_else_state,
2378 ..
2379 } = self.state.frame_at_depth_mut(0)?
2380 {
2381 (if_else, if_else_state)
2382 } else {
2383 unreachable!()
2384 };
2385
2386 *if_else_state = IfElseState::Else;
2387
2388 self.builder.position_at_end(*if_else_block);
2389 self.state.reachable = true;
2390
2391 if let ControlFrame::IfElse { else_phis, .. } = self.state.frame_at_depth(0)? {
2392 for phi in else_phis.clone().iter() {
2394 self.state.push1(phi.as_basic_value());
2395 }
2396 };
2397 }
2398
2399 Operator::End => {
2400 let frame = self.state.pop_frame()?;
2401 let current_block = self
2402 .builder
2403 .get_insert_block()
2404 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2405
2406 if self.state.reachable {
2407 for phi in frame.phis().iter().rev() {
2408 let (value, info) = self.state.pop1_extra()?;
2409 let value = self.apply_pending_canonicalization(value, info)?;
2410 phi.add_incoming(&[(&value, current_block)]);
2411 }
2412
2413 err!(self.builder.build_unconditional_branch(*frame.code_after()));
2414 }
2415
2416 if let ControlFrame::IfElse {
2417 if_else,
2418 next,
2419 if_else_state: IfElseState::If,
2420 else_phis,
2421 ..
2422 } = &frame
2423 {
2424 for (phi, else_phi) in frame.phis().iter().zip(else_phis.iter()) {
2425 phi.add_incoming(&[(&else_phi.as_basic_value(), *if_else)]);
2426 }
2427 self.builder.position_at_end(*if_else);
2428 err!(self.builder.build_unconditional_branch(*next));
2429 } else if let ControlFrame::Landingpad { .. } = &frame {
2430 self.state.pop_landingpad();
2431 };
2432
2433 self.builder.position_at_end(*frame.code_after());
2434 self.state.reset_stack(&frame);
2435
2436 self.state.reachable = true;
2437
2438 for phi in frame.phis() {
2440 if phi.count_incoming() != 0 {
2441 self.state.push1(phi.as_basic_value());
2442 } else {
2443 let basic_ty = phi.as_basic_value().get_type();
2450 let placeholder_value = basic_ty.const_zero();
2451 self.state.push1(placeholder_value);
2452 phi.as_instruction().erase_from_basic_block();
2453 }
2454 }
2455 }
2456 Operator::Return => {
2457 let current_block = self
2458 .builder
2459 .get_insert_block()
2460 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2461
2462 let frame = self.state.outermost_frame()?;
2463 for phi in frame.phis().to_vec().iter().rev() {
2464 let (arg, info) = self.state.pop1_extra()?;
2465 let arg = self.apply_pending_canonicalization(arg, info)?;
2466 phi.add_incoming(&[(&arg, current_block)]);
2467 }
2468 let frame = self.state.outermost_frame()?;
2469 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2470
2471 self.state.reachable = false;
2472 }
2473
2474 Operator::Unreachable => {
2475 err!(self.builder.build_call(
2476 self.intrinsics.throw_trap,
2477 &[self.intrinsics.trap_unreachable.into()],
2478 "throw",
2479 ));
2480 err!(self.builder.build_unreachable());
2481
2482 self.state.reachable = false;
2483 }
2484
2485 Operator::Nop => {
2490 }
2492 Operator::Drop => {
2493 self.state.pop1()?;
2494 }
2495
2496 Operator::I32Const { value } => {
2498 let i = self.intrinsics.i32_ty.const_int(value as u64, false);
2499 let info = if is_f32_arithmetic(value as u32) {
2500 ExtraInfo::arithmetic_f32()
2501 } else {
2502 Default::default()
2503 };
2504 self.state.push1_extra(i, info);
2505 }
2506 Operator::I64Const { value } => {
2507 let i = self.intrinsics.i64_ty.const_int(value as u64, false);
2508 let info = if is_f64_arithmetic(value as u64) {
2509 ExtraInfo::arithmetic_f64()
2510 } else {
2511 Default::default()
2512 };
2513 self.state.push1_extra(i, info);
2514 }
2515 Operator::F32Const { value } => {
2516 let bits = self.intrinsics.i32_ty.const_int(value.bits() as u64, false);
2517 let info = if is_f32_arithmetic(value.bits()) {
2518 ExtraInfo::arithmetic_f32()
2519 } else {
2520 Default::default()
2521 };
2522 let f = err!(
2523 self.builder
2524 .build_bit_cast(bits, self.intrinsics.f32_ty, "f")
2525 );
2526 self.state.push1_extra(f, info);
2527 }
2528 Operator::F64Const { value } => {
2529 let bits = self.intrinsics.i64_ty.const_int(value.bits(), false);
2530 let info = if is_f64_arithmetic(value.bits()) {
2531 ExtraInfo::arithmetic_f64()
2532 } else {
2533 Default::default()
2534 };
2535 let f = err!(
2536 self.builder
2537 .build_bit_cast(bits, self.intrinsics.f64_ty, "f")
2538 );
2539 self.state.push1_extra(f, info);
2540 }
2541 Operator::V128Const { value } => {
2542 let mut hi: [u8; 8] = Default::default();
2543 let mut lo: [u8; 8] = Default::default();
2544 hi.copy_from_slice(&value.bytes()[0..8]);
2545 lo.copy_from_slice(&value.bytes()[8..16]);
2546 let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
2547 let i = self
2548 .intrinsics
2549 .i128_ty
2550 .const_int_arbitrary_precision(&packed);
2551 let mut quad1: [u8; 4] = Default::default();
2552 let mut quad2: [u8; 4] = Default::default();
2553 let mut quad3: [u8; 4] = Default::default();
2554 let mut quad4: [u8; 4] = Default::default();
2555 quad1.copy_from_slice(&value.bytes()[0..4]);
2556 quad2.copy_from_slice(&value.bytes()[4..8]);
2557 quad3.copy_from_slice(&value.bytes()[8..12]);
2558 quad4.copy_from_slice(&value.bytes()[12..16]);
2559 let mut info: ExtraInfo = Default::default();
2560 if is_f32_arithmetic(u32::from_le_bytes(quad1))
2561 && is_f32_arithmetic(u32::from_le_bytes(quad2))
2562 && is_f32_arithmetic(u32::from_le_bytes(quad3))
2563 && is_f32_arithmetic(u32::from_le_bytes(quad4))
2564 {
2565 info |= ExtraInfo::arithmetic_f32();
2566 }
2567 if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
2568 info |= ExtraInfo::arithmetic_f64();
2569 }
2570 self.state.push1_extra(i, info);
2571 }
2572
2573 Operator::I8x16Splat => {
2574 let (v, i) = self.state.pop1_extra()?;
2575 let v = v.into_int_value();
2576 let v = err!(
2577 self.builder
2578 .build_int_truncate(v, self.intrinsics.i8_ty, "")
2579 );
2580 let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
2581 let res = err!(
2582 self.builder
2583 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2584 );
2585 self.state.push1_extra(res, i);
2586 }
2587 Operator::I16x8Splat => {
2588 let (v, i) = self.state.pop1_extra()?;
2589 let v = v.into_int_value();
2590 let v = err!(
2591 self.builder
2592 .build_int_truncate(v, self.intrinsics.i16_ty, "")
2593 );
2594 let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
2595 let res = err!(
2596 self.builder
2597 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2598 );
2599 self.state.push1_extra(res, i);
2600 }
2601 Operator::I32x4Splat => {
2602 let (v, i) = self.state.pop1_extra()?;
2603 let res = self.splat_vector(v, self.intrinsics.i32x4_ty)?;
2604 let res = err!(
2605 self.builder
2606 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2607 );
2608 self.state.push1_extra(res, i);
2609 }
2610 Operator::I64x2Splat => {
2611 let (v, i) = self.state.pop1_extra()?;
2612 let res = self.splat_vector(v, self.intrinsics.i64x2_ty)?;
2613 let res = err!(
2614 self.builder
2615 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2616 );
2617 self.state.push1_extra(res, i);
2618 }
2619 Operator::F32x4Splat => {
2620 let (v, i) = self.state.pop1_extra()?;
2621 let res = self.splat_vector(v, self.intrinsics.f32x4_ty)?;
2622 let res = err!(
2623 self.builder
2624 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2625 );
2626 self.state.push1_extra(res, i);
2629 }
2630 Operator::F64x2Splat => {
2631 let (v, i) = self.state.pop1_extra()?;
2632 let res = self.splat_vector(v, self.intrinsics.f64x2_ty)?;
2633 let res = err!(
2634 self.builder
2635 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2636 );
2637 self.state.push1_extra(res, i);
2640 }
2641
2642 Operator::LocalGet { local_index } => {
2644 let (type_value, pointer_value) = self.locals[local_index as usize];
2645 let v = err!(self.builder.build_load(
2646 type_value,
2647 pointer_value,
2648 &format!("local_{local_index}_get")
2649 ));
2650 tbaa_label(
2651 self.module,
2652 self.intrinsics,
2653 format!("local {local_index}"),
2654 v.as_instruction_value().unwrap(),
2655 );
2656 self.state.push1(v);
2657 }
2658 Operator::LocalSet { local_index } => {
2659 let pointer_value = self.locals[local_index as usize].1;
2660 let (v, i) = self.state.pop1_extra()?;
2661 let v = self.apply_pending_canonicalization(v, i)?;
2662 let store = err!(self.builder.build_store(pointer_value, v));
2663 tbaa_label(
2664 self.module,
2665 self.intrinsics,
2666 format!("local {local_index}"),
2667 store,
2668 );
2669 }
2670 Operator::LocalTee { local_index } => {
2671 let pointer_value = self.locals[local_index as usize].1;
2672 let (v, i) = self.state.peek1_extra()?;
2673 let v = self.apply_pending_canonicalization(v, i)?;
2674 let store = err!(self.builder.build_store(pointer_value, v));
2675 tbaa_label(
2676 self.module,
2677 self.intrinsics,
2678 format!("local {local_index}"),
2679 store,
2680 );
2681 }
2682
2683 Operator::GlobalGet { global_index } => {
2684 if self.g0m0.is_some() && global_index == 0 {
2685 let Some((g0, _)) = self.g0m0 else {
2686 unreachable!()
2687 };
2688
2689 let value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, ""));
2691
2692 self.state.push1(value);
2693 } else {
2694 let global_index = GlobalIndex::from_u32(global_index);
2695 match self
2696 .ctx
2697 .global(global_index, self.intrinsics, self.module)?
2698 {
2699 GlobalCache::Const { value } => {
2700 self.state.push1(*value);
2701 }
2702 GlobalCache::Mut {
2703 ptr_to_value,
2704 value_type,
2705 } => {
2706 let value =
2707 err!(self.builder.build_load(*value_type, *ptr_to_value, ""));
2708 tbaa_label(
2709 self.module,
2710 self.intrinsics,
2711 format!("global {}", global_index.as_u32()),
2712 value.as_instruction_value().unwrap(),
2713 );
2714 self.state.push1(value);
2715 }
2716 }
2717 }
2718 }
2719 Operator::GlobalSet { global_index } => {
2720 if self.g0m0.is_some() && global_index == 0 {
2721 let Some((g0, _)) = self.g0m0 else {
2722 unreachable!()
2723 };
2724 let ptr_to_value = g0;
2725 let (value, info) = self.state.pop1_extra()?;
2726 let value = self.apply_pending_canonicalization(value, info)?;
2727 let store = err!(self.builder.build_store(ptr_to_value, value));
2728 tbaa_label(self.module, self.intrinsics, "global 0".to_string(), store);
2729 } else {
2730 let global_index = GlobalIndex::from_u32(global_index);
2731 match self
2732 .ctx
2733 .global(global_index, self.intrinsics, self.module)?
2734 {
2735 GlobalCache::Const { value: _ } => {
2736 return Err(CompileError::Codegen(format!(
2737 "global.set on immutable global index {}",
2738 global_index.as_u32()
2739 )));
2740 }
2741 GlobalCache::Mut { ptr_to_value, .. } => {
2742 let ptr_to_value = *ptr_to_value;
2743 let (value, info) = self.state.pop1_extra()?;
2744 let value = self.apply_pending_canonicalization(value, info)?;
2745 let store = err!(self.builder.build_store(ptr_to_value, value));
2746 tbaa_label(
2747 self.module,
2748 self.intrinsics,
2749 format!("global {}", global_index.as_u32()),
2750 store,
2751 );
2752 }
2753 }
2754 }
2755 }
2756
2757 Operator::TypedSelect { .. } | Operator::Select => {
2760 let ((v1, i1), (v2, i2), (cond, _)) = self.state.pop3_extra()?;
2761 let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
2769 || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
2770 {
2771 (
2772 self.apply_pending_canonicalization(v1, i1)?,
2773 i1.strip_pending(),
2774 self.apply_pending_canonicalization(v2, i2)?,
2775 i2.strip_pending(),
2776 )
2777 } else {
2778 (v1, i1, v2, i2)
2779 };
2780 let cond_value = err!(self.builder.build_int_compare(
2781 IntPredicate::NE,
2782 cond.into_int_value(),
2783 self.intrinsics.i32_zero,
2784 "",
2785 ));
2786 let res = err!(self.builder.build_select(cond_value, v1, v2, ""));
2787 let info = {
2788 let mut info = (i1.strip_pending() & i2.strip_pending())?;
2789 if i1.has_pending_f32_nan() {
2790 debug_assert!(i2.has_pending_f32_nan());
2791 info = (info | ExtraInfo::pending_f32_nan())?;
2792 }
2793 if i1.has_pending_f64_nan() {
2794 debug_assert!(i2.has_pending_f64_nan());
2795 info = (info | ExtraInfo::pending_f64_nan())?;
2796 }
2797 info
2798 };
2799 self.state.push1_extra(res, info);
2800 }
2801 Operator::Call { function_index } => {
2802 let func_index = FunctionIndex::from_u32(function_index);
2803 let sigindex = &self.wasm_module.functions[func_index];
2804 let func_type = &self.wasm_module.signatures[*sigindex];
2805
2806 let mut g0m0_params = None;
2807
2808 let FunctionCache {
2809 func,
2810 llvm_func_type,
2811 vmctx: callee_vmctx,
2812 attrs,
2813 } = if let Some(local_func_index) = self.wasm_module.local_func_index(func_index) {
2814 if let Some((g0, m0)) = &self.g0m0 {
2815 let value = err!(self.builder.build_load(self.intrinsics.i32_ty, *g0, ""));
2817
2818 g0m0_params = Some((value.into_int_value(), *m0));
2819 }
2820
2821 let function_name = self
2822 .symbol_registry
2823 .symbol_to_name(Symbol::LocalFunction(local_func_index));
2824
2825 self.ctx.local_func(
2826 local_func_index,
2827 func_index,
2828 self.intrinsics,
2829 self.module,
2830 self.context,
2831 func_type,
2832 &function_name,
2833 )?
2834 } else {
2835 self.ctx
2836 .func(func_index, self.intrinsics, self.context, func_type)?
2837 };
2838 let llvm_func_type = *llvm_func_type;
2839 let func = *func;
2840 let callee_vmctx = *callee_vmctx;
2841 let attrs = attrs.clone();
2842
2843 let params = self.state.popn_save_extra(func_type.params().len())?;
2849
2850 let params = params
2852 .iter()
2853 .zip(func_type.params().iter())
2854 .map(|((v, info), wasm_ty)| match wasm_ty {
2855 Type::F32 => err_nt!(self.builder.build_bit_cast(
2856 self.apply_pending_canonicalization(*v, *info)?,
2857 self.intrinsics.f32_ty,
2858 "",
2859 )),
2860 Type::F64 => err_nt!(self.builder.build_bit_cast(
2861 self.apply_pending_canonicalization(*v, *info)?,
2862 self.intrinsics.f64_ty,
2863 "",
2864 )),
2865 Type::V128 => self.apply_pending_canonicalization(*v, *info),
2866 _ => Ok(*v),
2867 })
2868 .collect::<Result<Vec<_>, _>>()?;
2869
2870 let params = self.abi.args_to_call(
2871 &self.alloca_builder,
2872 func_type,
2873 &llvm_func_type,
2874 callee_vmctx.into_pointer_value(),
2875 params.as_slice(),
2876 self.intrinsics,
2877 g0m0_params,
2878 )?;
2879
2880 let call_site = if let Some(lpad) = self.state.get_innermost_landingpad() {
2900 let then_block = self.context.append_basic_block(self.function, "then_block");
2901
2902 let ret = err!(self.builder.build_indirect_invoke(
2903 llvm_func_type,
2904 func,
2905 params.as_slice(),
2906 then_block,
2907 lpad,
2908 "",
2909 ));
2910
2911 self.builder.position_at_end(then_block);
2912 ret
2913 } else {
2914 err!(
2915 self.builder.build_indirect_call(
2916 llvm_func_type,
2917 func,
2918 params
2919 .iter()
2920 .copied()
2921 .map(Into::into)
2922 .collect::<Vec<BasicMetadataValueEnum>>()
2923 .as_slice(),
2924 "",
2925 )
2926 )
2927 };
2928 for (attr, attr_loc) in attrs {
2929 call_site.add_attribute(attr_loc, attr);
2930 }
2931 self.abi
2948 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
2949 .iter()
2950 .for_each(|ret| self.state.push1(*ret));
2951 }
2952 Operator::CallIndirect {
2953 type_index,
2954 table_index,
2955 } => {
2956 let sigindex = SignatureIndex::from_u32(type_index);
2957 let func_type = &self.wasm_module.signatures[sigindex];
2958 let expected_dynamic_sigindex =
2959 self.ctx
2960 .dynamic_sigindex(sigindex, self.intrinsics, self.module)?;
2961 let (table_base, table_bound) = self.ctx.table(
2962 TableIndex::from_u32(table_index),
2963 self.intrinsics,
2964 self.module,
2965 &self.builder,
2966 )?;
2967 let func_index = self.state.pop1()?.into_int_value();
2968
2969 let truncated_table_bounds = err!(self.builder.build_int_truncate(
2970 table_bound,
2971 self.intrinsics.i32_ty,
2972 "truncated_table_bounds",
2973 ));
2974
2975 let index_in_bounds = err!(self.builder.build_int_compare(
2977 IntPredicate::ULT,
2978 func_index,
2979 truncated_table_bounds,
2980 "index_in_bounds",
2981 ));
2982
2983 let index_in_bounds = err!(self.builder.build_call(
2984 self.intrinsics.expect_i1,
2985 &[
2986 index_in_bounds.into(),
2987 self.intrinsics.i1_ty.const_int(1, false).into(),
2988 ],
2989 "index_in_bounds_expect",
2990 ))
2991 .try_as_basic_value()
2992 .unwrap_basic()
2993 .into_int_value();
2994
2995 let in_bounds_continue_block = self
2996 .context
2997 .append_basic_block(self.function, "in_bounds_continue_block");
2998 let not_in_bounds_block = self
2999 .context
3000 .append_basic_block(self.function, "not_in_bounds_block");
3001 err!(self.builder.build_conditional_branch(
3002 index_in_bounds,
3003 in_bounds_continue_block,
3004 not_in_bounds_block,
3005 ));
3006 self.builder.position_at_end(not_in_bounds_block);
3007 err!(self.builder.build_call(
3008 self.intrinsics.throw_trap,
3009 &[self.intrinsics.trap_table_access_oob.into()],
3010 "throw",
3011 ));
3012 err!(self.builder.build_unreachable());
3013 self.builder.position_at_end(in_bounds_continue_block);
3014
3015 let casted_table_base = err!(self.builder.build_pointer_cast(
3018 table_base,
3019 self.context.ptr_type(AddressSpace::default()),
3020 "casted_table_base",
3021 ));
3022
3023 let funcref_ptr = unsafe {
3024 err!(self.builder.build_in_bounds_gep(
3025 self.intrinsics.ptr_ty,
3026 casted_table_base,
3027 &[func_index],
3028 "funcref_ptr",
3029 ))
3030 };
3031
3032 let anyfunc_struct_ptr = err!(self.builder.build_load(
3034 self.intrinsics.ptr_ty,
3035 funcref_ptr,
3036 "anyfunc_struct_ptr",
3037 ))
3038 .into_pointer_value();
3039
3040 {
3042 let funcref_not_null = err!(
3043 self.builder
3044 .build_is_not_null(anyfunc_struct_ptr, "null funcref check")
3045 );
3046
3047 let funcref_continue_deref_block = self
3048 .context
3049 .append_basic_block(self.function, "funcref_continue deref_block");
3050
3051 let funcref_is_null_block = self
3052 .context
3053 .append_basic_block(self.function, "funcref_is_null_block");
3054 err!(self.builder.build_conditional_branch(
3055 funcref_not_null,
3056 funcref_continue_deref_block,
3057 funcref_is_null_block,
3058 ));
3059 self.builder.position_at_end(funcref_is_null_block);
3060 err!(self.builder.build_call(
3061 self.intrinsics.throw_trap,
3062 &[self.intrinsics.trap_call_indirect_null.into()],
3063 "throw",
3064 ));
3065 err!(self.builder.build_unreachable());
3066 self.builder.position_at_end(funcref_continue_deref_block);
3067 }
3068
3069 let func_ptr_ptr = self
3071 .builder
3072 .build_struct_gep(
3073 self.intrinsics.anyfunc_ty,
3074 anyfunc_struct_ptr,
3075 0,
3076 "func_ptr_ptr",
3077 )
3078 .unwrap();
3079 let sigindex_ptr = self
3080 .builder
3081 .build_struct_gep(
3082 self.intrinsics.anyfunc_ty,
3083 anyfunc_struct_ptr,
3084 1,
3085 "sigindex_ptr",
3086 )
3087 .unwrap();
3088 let ctx_ptr_ptr = self
3089 .builder
3090 .build_struct_gep(
3091 self.intrinsics.anyfunc_ty,
3092 anyfunc_struct_ptr,
3093 2,
3094 "ctx_ptr_ptr",
3095 )
3096 .unwrap();
3097 let (func_ptr, found_dynamic_sigindex, ctx_ptr) = (
3098 err!(
3099 self.builder
3100 .build_load(self.intrinsics.ptr_ty, func_ptr_ptr, "func_ptr")
3101 )
3102 .into_pointer_value(),
3103 err!(
3104 self.builder
3105 .build_load(self.intrinsics.i32_ty, sigindex_ptr, "sigindex")
3106 )
3107 .into_int_value(),
3108 err!(
3109 self.builder
3110 .build_load(self.intrinsics.ptr_ty, ctx_ptr_ptr, "ctx_ptr")
3111 ),
3112 );
3113
3114 let elem_initialized = err!(self.builder.build_is_not_null(func_ptr, ""));
3118
3119 let sigindices_equal = err!(self.builder.build_int_compare(
3122 IntPredicate::EQ,
3123 expected_dynamic_sigindex,
3124 found_dynamic_sigindex,
3125 "sigindices_equal",
3126 ));
3127
3128 let initialized_and_sigindices_match = err!(self.builder.build_and(
3129 elem_initialized,
3130 sigindices_equal,
3131 ""
3132 ));
3133
3134 let initialized_and_sigindices_match = err!(self.builder.build_call(
3136 self.intrinsics.expect_i1,
3137 &[
3138 initialized_and_sigindices_match.into(),
3139 self.intrinsics.i1_ty.const_int(1, false).into(),
3140 ],
3141 "initialized_and_sigindices_match_expect",
3142 ))
3143 .try_as_basic_value()
3144 .unwrap_basic()
3145 .into_int_value();
3146
3147 let continue_block = self
3148 .context
3149 .append_basic_block(self.function, "continue_block");
3150 let sigindices_notequal_block = self
3151 .context
3152 .append_basic_block(self.function, "sigindices_notequal_block");
3153 err!(self.builder.build_conditional_branch(
3154 initialized_and_sigindices_match,
3155 continue_block,
3156 sigindices_notequal_block,
3157 ));
3158
3159 self.builder.position_at_end(sigindices_notequal_block);
3160 let trap_code = err!(self.builder.build_select(
3161 elem_initialized,
3162 self.intrinsics.trap_call_indirect_sig,
3163 self.intrinsics.trap_call_indirect_null,
3164 "",
3165 ));
3166 err!(self.builder.build_call(
3167 self.intrinsics.throw_trap,
3168 &[trap_code.into()],
3169 "throw"
3170 ));
3171 err!(self.builder.build_unreachable());
3172 self.builder.position_at_end(continue_block);
3173
3174 if self.g0m0.is_some() {
3175 self.build_g0m0_indirect_call(
3176 table_index,
3177 ctx_ptr.into_pointer_value(),
3178 func_type,
3179 func_ptr,
3180 func_index,
3181 )?;
3182 } else {
3183 let call_site = self.build_indirect_call(
3184 ctx_ptr.into_pointer_value(),
3185 func_type,
3186 func_ptr,
3187 None,
3188 None,
3189 )?;
3190
3191 self.abi
3192 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
3193 .iter()
3194 .for_each(|ret| self.state.push1(*ret));
3195 }
3196 }
3197
3198 Operator::I32Add | Operator::I64Add => {
3203 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3204 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3205 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3206 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3207 let res = err!(self.builder.build_int_add(v1, v2, ""));
3208 self.state.push1(res);
3209 }
3210 Operator::I8x16Add => {
3211 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3212 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3213 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3214 let res = err!(self.builder.build_int_add(v1, v2, ""));
3215 let res = err!(
3216 self.builder
3217 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3218 );
3219 self.state.push1(res);
3220 }
3221 Operator::I16x8Add => {
3222 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3223 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3224 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3225 let res = err!(self.builder.build_int_add(v1, v2, ""));
3226 let res = err!(
3227 self.builder
3228 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3229 );
3230 self.state.push1(res);
3231 }
3232 Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U => {
3233 let extend_op = match op {
3234 Operator::I16x8ExtAddPairwiseI8x16S => {
3235 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, "")
3236 }
3237 Operator::I16x8ExtAddPairwiseI8x16U => {
3238 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, "")
3239 }
3240 _ => unreachable!("Unhandled internal variant"),
3241 };
3242 let (v, i) = self.state.pop1_extra()?;
3243 let (v, _) = self.v128_into_i8x16(v, i)?;
3244
3245 let left = err!(self.builder.build_shuffle_vector(
3246 v,
3247 v.get_type().get_undef(),
3248 VectorType::const_vector(&[
3249 self.intrinsics.i32_consts[0],
3250 self.intrinsics.i32_consts[2],
3251 self.intrinsics.i32_consts[4],
3252 self.intrinsics.i32_consts[6],
3253 self.intrinsics.i32_consts[8],
3254 self.intrinsics.i32_consts[10],
3255 self.intrinsics.i32_consts[12],
3256 self.intrinsics.i32_consts[14],
3257 ]),
3258 "",
3259 ));
3260 let left = err!(extend_op(self, left));
3261 let right = err!(self.builder.build_shuffle_vector(
3262 v,
3263 v.get_type().get_undef(),
3264 VectorType::const_vector(&[
3265 self.intrinsics.i32_consts[1],
3266 self.intrinsics.i32_consts[3],
3267 self.intrinsics.i32_consts[5],
3268 self.intrinsics.i32_consts[7],
3269 self.intrinsics.i32_consts[9],
3270 self.intrinsics.i32_consts[11],
3271 self.intrinsics.i32_consts[13],
3272 self.intrinsics.i32_consts[15],
3273 ]),
3274 "",
3275 ));
3276 let right = err!(extend_op(self, right));
3277
3278 let res = err!(self.builder.build_int_add(left, right, ""));
3279 let res = err!(
3280 self.builder
3281 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3282 );
3283 self.state.push1(res);
3284 }
3285 Operator::I32x4Add => {
3286 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3287 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3288 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3289 let res = err!(self.builder.build_int_add(v1, v2, ""));
3290 let res = err!(
3291 self.builder
3292 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3293 );
3294 self.state.push1(res);
3295 }
3296 Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
3297 let extend_op = match op {
3298 Operator::I32x4ExtAddPairwiseI16x8S => {
3299 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3300 }
3301 Operator::I32x4ExtAddPairwiseI16x8U => {
3302 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3303 }
3304 _ => unreachable!("Unhandled internal variant"),
3305 };
3306 let (v, i) = self.state.pop1_extra()?;
3307 let (v, _) = self.v128_into_i16x8(v, i)?;
3308
3309 let left = err!(self.builder.build_shuffle_vector(
3310 v,
3311 v.get_type().get_undef(),
3312 VectorType::const_vector(&[
3313 self.intrinsics.i32_consts[0],
3314 self.intrinsics.i32_consts[2],
3315 self.intrinsics.i32_consts[4],
3316 self.intrinsics.i32_consts[6],
3317 ]),
3318 "",
3319 ));
3320 let left = err!(extend_op(self, left));
3321 let right = err!(self.builder.build_shuffle_vector(
3322 v,
3323 v.get_type().get_undef(),
3324 VectorType::const_vector(&[
3325 self.intrinsics.i32_consts[1],
3326 self.intrinsics.i32_consts[3],
3327 self.intrinsics.i32_consts[5],
3328 self.intrinsics.i32_consts[7],
3329 ]),
3330 "",
3331 ));
3332 let right = err!(extend_op(self, right));
3333
3334 let res = err!(self.builder.build_int_add(left, right, ""));
3335 let res = err!(
3336 self.builder
3337 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3338 );
3339 self.state.push1(res);
3340 }
3341 Operator::I64x2Add => {
3342 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3343 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3344 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3345 let res = err!(self.builder.build_int_add(v1, v2, ""));
3346 let res = err!(
3347 self.builder
3348 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3349 );
3350 self.state.push1(res);
3351 }
3352 Operator::I8x16AddSatS => {
3353 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3354 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3355 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3356 let res = err!(self.builder.build_call(
3357 self.intrinsics.sadd_sat_i8x16,
3358 &[v1.into(), v2.into()],
3359 ""
3360 ))
3361 .try_as_basic_value()
3362 .unwrap_basic();
3363 let res = err!(
3364 self.builder
3365 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3366 );
3367 self.state.push1(res);
3368 }
3369 Operator::I16x8AddSatS => {
3370 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3371 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3372 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3373 let res = err!(self.builder.build_call(
3374 self.intrinsics.sadd_sat_i16x8,
3375 &[v1.into(), v2.into()],
3376 ""
3377 ))
3378 .try_as_basic_value()
3379 .unwrap_basic();
3380 let res = err!(
3381 self.builder
3382 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3383 );
3384 self.state.push1(res);
3385 }
3386 Operator::I8x16AddSatU => {
3387 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3388 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3389 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3390 let res = err!(self.builder.build_call(
3391 self.intrinsics.uadd_sat_i8x16,
3392 &[v1.into(), v2.into()],
3393 ""
3394 ))
3395 .try_as_basic_value()
3396 .unwrap_basic();
3397 let res = err!(
3398 self.builder
3399 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3400 );
3401 self.state.push1(res);
3402 }
3403 Operator::I16x8AddSatU => {
3404 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3405 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3406 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3407 let res = err!(self.builder.build_call(
3408 self.intrinsics.uadd_sat_i16x8,
3409 &[v1.into(), v2.into()],
3410 ""
3411 ))
3412 .try_as_basic_value()
3413 .unwrap_basic();
3414 let res = err!(
3415 self.builder
3416 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3417 );
3418 self.state.push1(res);
3419 }
3420 Operator::I32Sub | Operator::I64Sub => {
3421 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3422 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3423 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3424 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3425 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3426 self.state.push1(res);
3427 }
3428 Operator::I8x16Sub => {
3429 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3430 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3431 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3432 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3433 let res = err!(
3434 self.builder
3435 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3436 );
3437 self.state.push1(res);
3438 }
3439 Operator::I16x8Sub => {
3440 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3441 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3442 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3443 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3444 let res = err!(
3445 self.builder
3446 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3447 );
3448 self.state.push1(res);
3449 }
3450 Operator::I32x4Sub => {
3451 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3452 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3453 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3454 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3455 let res = err!(
3456 self.builder
3457 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3458 );
3459 self.state.push1(res);
3460 }
3461 Operator::I64x2Sub => {
3462 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3463 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3464 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3465 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3466 let res = err!(
3467 self.builder
3468 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3469 );
3470 self.state.push1(res);
3471 }
3472 Operator::I8x16SubSatS => {
3473 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3474 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3475 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3476 let res = err!(self.builder.build_call(
3477 self.intrinsics.ssub_sat_i8x16,
3478 &[v1.into(), v2.into()],
3479 ""
3480 ))
3481 .try_as_basic_value()
3482 .unwrap_basic();
3483 let res = err!(
3484 self.builder
3485 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3486 );
3487 self.state.push1(res);
3488 }
3489 Operator::I16x8SubSatS => {
3490 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3491 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3492 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3493 let res = err!(self.builder.build_call(
3494 self.intrinsics.ssub_sat_i16x8,
3495 &[v1.into(), v2.into()],
3496 ""
3497 ))
3498 .try_as_basic_value()
3499 .unwrap_basic();
3500 let res = err!(
3501 self.builder
3502 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3503 );
3504 self.state.push1(res);
3505 }
3506 Operator::I8x16SubSatU => {
3507 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3508 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3509 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3510 let res = err!(self.builder.build_call(
3511 self.intrinsics.usub_sat_i8x16,
3512 &[v1.into(), v2.into()],
3513 ""
3514 ))
3515 .try_as_basic_value()
3516 .unwrap_basic();
3517 let res = err!(
3518 self.builder
3519 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3520 );
3521 self.state.push1(res);
3522 }
3523 Operator::I16x8SubSatU => {
3524 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3525 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3526 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3527 let res = err!(self.builder.build_call(
3528 self.intrinsics.usub_sat_i16x8,
3529 &[v1.into(), v2.into()],
3530 ""
3531 ))
3532 .try_as_basic_value()
3533 .unwrap_basic();
3534 let res = err!(
3535 self.builder
3536 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3537 );
3538 self.state.push1(res);
3539 }
3540 Operator::I32Mul | Operator::I64Mul => {
3541 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3542 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3543 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3544 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3545 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3546 self.state.push1(res);
3547 }
3548 Operator::I16x8Mul => {
3549 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3550 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3551 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3552 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3553 let res = err!(
3554 self.builder
3555 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3556 );
3557 self.state.push1(res);
3558 }
3559 Operator::I32x4Mul => {
3560 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3561 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3562 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3563 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3564 let res = err!(
3565 self.builder
3566 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3567 );
3568 self.state.push1(res);
3569 }
3570 Operator::I64x2Mul => {
3571 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3572 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3573 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3574 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3575 let res = err!(
3576 self.builder
3577 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3578 );
3579 self.state.push1(res);
3580 }
3581 Operator::I16x8Q15MulrSatS => {
3582 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3583 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3584 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3585
3586 let max_value = self.intrinsics.i16_ty.const_int(i16::MAX as u64, false);
3587 let max_values = VectorType::const_vector(&[max_value; 8]);
3588
3589 let v1 = err!(
3590 self.builder
3591 .build_int_s_extend(v1, self.intrinsics.i32x8_ty, "")
3592 );
3593 let v2 = err!(
3594 self.builder
3595 .build_int_s_extend(v2, self.intrinsics.i32x8_ty, "")
3596 );
3597 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3598
3599 let bit = self.intrinsics.i32_ty.const_int(0x4000, false);
3601 let bits = VectorType::const_vector(&[bit; 8]);
3602
3603 let res = err!(self.builder.build_int_add(res, bits, ""));
3604
3605 let fifteen = self.intrinsics.i32_consts[15];
3606 let fifteens = VectorType::const_vector(&[fifteen; 8]);
3607
3608 let res = err!(self.builder.build_right_shift(res, fifteens, true, ""));
3609 let saturate_up = {
3610 let max_values = err!(self.builder.build_int_s_extend(
3611 max_values,
3612 self.intrinsics.i32x8_ty,
3613 ""
3614 ));
3615 err!(
3616 self.builder
3617 .build_int_compare(IntPredicate::SGT, res, max_values, "")
3618 )
3619 };
3620
3621 let res = err!(
3622 self.builder
3623 .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
3624 );
3625
3626 let res = err!(self.builder.build_select(saturate_up, max_values, res, ""))
3627 .into_vector_value();
3628 let res = err!(
3629 self.builder
3630 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3631 );
3632 self.state.push1(res);
3633 }
3634 Operator::I16x8ExtMulLowI8x16S
3635 | Operator::I16x8ExtMulLowI8x16U
3636 | Operator::I16x8ExtMulHighI8x16S
3637 | Operator::I16x8ExtMulHighI8x16U => {
3638 let extend_op = match op {
3639 Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulHighI8x16S => {
3640 |s: &Self, v| -> Result<VectorValue, CompileError> {
3641 err_nt!(s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, ""))
3642 }
3643 }
3644 Operator::I16x8ExtMulLowI8x16U | Operator::I16x8ExtMulHighI8x16U => {
3645 |s: &Self, v| -> Result<VectorValue, CompileError> {
3646 err_nt!(s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, ""))
3647 }
3648 }
3649 _ => unreachable!("Unhandled internal variant"),
3650 };
3651 let shuffle_array = match op {
3652 Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulLowI8x16U => [
3653 self.intrinsics.i32_consts[0],
3654 self.intrinsics.i32_consts[2],
3655 self.intrinsics.i32_consts[4],
3656 self.intrinsics.i32_consts[6],
3657 self.intrinsics.i32_consts[8],
3658 self.intrinsics.i32_consts[10],
3659 self.intrinsics.i32_consts[12],
3660 self.intrinsics.i32_consts[14],
3661 ],
3662 Operator::I16x8ExtMulHighI8x16S | Operator::I16x8ExtMulHighI8x16U => [
3663 self.intrinsics.i32_consts[1],
3664 self.intrinsics.i32_consts[3],
3665 self.intrinsics.i32_consts[5],
3666 self.intrinsics.i32_consts[7],
3667 self.intrinsics.i32_consts[9],
3668 self.intrinsics.i32_consts[11],
3669 self.intrinsics.i32_consts[13],
3670 self.intrinsics.i32_consts[15],
3671 ],
3672 _ => unreachable!("Unhandled internal variant"),
3673 };
3674 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3675 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3676 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3677 let val1 = err!(self.builder.build_shuffle_vector(
3678 v1,
3679 v1.get_type().get_undef(),
3680 VectorType::const_vector(&shuffle_array),
3681 "",
3682 ));
3683 let val1 = err!(extend_op(self, val1));
3684 let val2 = err!(self.builder.build_shuffle_vector(
3685 v2,
3686 v2.get_type().get_undef(),
3687 VectorType::const_vector(&shuffle_array),
3688 "",
3689 ));
3690 let val2 = err!(extend_op(self, val2));
3691 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3692 let res = err!(
3693 self.builder
3694 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3695 );
3696 self.state.push1(res);
3697 }
3698 Operator::I32x4ExtMulLowI16x8S
3699 | Operator::I32x4ExtMulLowI16x8U
3700 | Operator::I32x4ExtMulHighI16x8S
3701 | Operator::I32x4ExtMulHighI16x8U => {
3702 let extend_op = match op {
3703 Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulHighI16x8S => {
3704 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3705 }
3706 Operator::I32x4ExtMulLowI16x8U | Operator::I32x4ExtMulHighI16x8U => {
3707 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3708 }
3709 _ => unreachable!("Unhandled internal variant"),
3710 };
3711 let shuffle_array = match op {
3712 Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulLowI16x8U => [
3713 self.intrinsics.i32_consts[0],
3714 self.intrinsics.i32_consts[2],
3715 self.intrinsics.i32_consts[4],
3716 self.intrinsics.i32_consts[6],
3717 ],
3718 Operator::I32x4ExtMulHighI16x8S | Operator::I32x4ExtMulHighI16x8U => [
3719 self.intrinsics.i32_consts[1],
3720 self.intrinsics.i32_consts[3],
3721 self.intrinsics.i32_consts[5],
3722 self.intrinsics.i32_consts[7],
3723 ],
3724 _ => unreachable!("Unhandled internal variant"),
3725 };
3726 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3727 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3728 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3729 let val1 = err!(self.builder.build_shuffle_vector(
3730 v1,
3731 v1.get_type().get_undef(),
3732 VectorType::const_vector(&shuffle_array),
3733 "",
3734 ));
3735 let val1 = err!(extend_op(self, val1));
3736 let val2 = err!(self.builder.build_shuffle_vector(
3737 v2,
3738 v2.get_type().get_undef(),
3739 VectorType::const_vector(&shuffle_array),
3740 "",
3741 ));
3742 let val2 = err!(extend_op(self, val2));
3743 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3744 let res = err!(
3745 self.builder
3746 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3747 );
3748 self.state.push1(res);
3749 }
3750 Operator::I64x2ExtMulLowI32x4S
3751 | Operator::I64x2ExtMulLowI32x4U
3752 | Operator::I64x2ExtMulHighI32x4S
3753 | Operator::I64x2ExtMulHighI32x4U => {
3754 let extend_op = match op {
3755 Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulHighI32x4S => {
3756 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
3757 }
3758 Operator::I64x2ExtMulLowI32x4U | Operator::I64x2ExtMulHighI32x4U => {
3759 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
3760 }
3761 _ => unreachable!("Unhandled internal variant"),
3762 };
3763 let shuffle_array = match op {
3764 Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulLowI32x4U => {
3765 [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[2]]
3766 }
3767 Operator::I64x2ExtMulHighI32x4S | Operator::I64x2ExtMulHighI32x4U => {
3768 [self.intrinsics.i32_consts[1], self.intrinsics.i32_consts[3]]
3769 }
3770 _ => unreachable!("Unhandled internal variant"),
3771 };
3772 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3773 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3774 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3775 let val1 = err!(self.builder.build_shuffle_vector(
3776 v1,
3777 v1.get_type().get_undef(),
3778 VectorType::const_vector(&shuffle_array),
3779 "",
3780 ));
3781 let val1 = err!(extend_op(self, val1));
3782 let val2 = err!(self.builder.build_shuffle_vector(
3783 v2,
3784 v2.get_type().get_undef(),
3785 VectorType::const_vector(&shuffle_array),
3786 "",
3787 ));
3788 let val2 = err!(extend_op(self, val2));
3789 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3790 let res = err!(
3791 self.builder
3792 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3793 );
3794 self.state.push1(res);
3795 }
3796 Operator::I32x4DotI16x8S => {
3797 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3798 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3799 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3800 let low_i16 = [
3801 self.intrinsics.i32_consts[0],
3802 self.intrinsics.i32_consts[2],
3803 self.intrinsics.i32_consts[4],
3804 self.intrinsics.i32_consts[6],
3805 ];
3806 let high_i16 = [
3807 self.intrinsics.i32_consts[1],
3808 self.intrinsics.i32_consts[3],
3809 self.intrinsics.i32_consts[5],
3810 self.intrinsics.i32_consts[7],
3811 ];
3812 let v1_low = err!(self.builder.build_shuffle_vector(
3813 v1,
3814 v1.get_type().get_undef(),
3815 VectorType::const_vector(&low_i16),
3816 "",
3817 ));
3818 let v1_low = err!(self.builder.build_int_s_extend(
3819 v1_low,
3820 self.intrinsics.i32x4_ty,
3821 ""
3822 ));
3823 let v1_high = err!(self.builder.build_shuffle_vector(
3824 v1,
3825 v1.get_type().get_undef(),
3826 VectorType::const_vector(&high_i16),
3827 "",
3828 ));
3829 let v1_high = err!(self.builder.build_int_s_extend(
3830 v1_high,
3831 self.intrinsics.i32x4_ty,
3832 ""
3833 ));
3834 let v2_low = err!(self.builder.build_shuffle_vector(
3835 v2,
3836 v2.get_type().get_undef(),
3837 VectorType::const_vector(&low_i16),
3838 "",
3839 ));
3840 let v2_low = err!(self.builder.build_int_s_extend(
3841 v2_low,
3842 self.intrinsics.i32x4_ty,
3843 ""
3844 ));
3845 let v2_high = err!(self.builder.build_shuffle_vector(
3846 v2,
3847 v2.get_type().get_undef(),
3848 VectorType::const_vector(&high_i16),
3849 "",
3850 ));
3851 let v2_high = err!(self.builder.build_int_s_extend(
3852 v2_high,
3853 self.intrinsics.i32x4_ty,
3854 ""
3855 ));
3856 let low_product = err!(self.builder.build_int_mul(v1_low, v2_low, ""));
3857 let high_product = err!(self.builder.build_int_mul(v1_high, v2_high, ""));
3858
3859 let res = err!(self.builder.build_int_add(low_product, high_product, ""));
3860 let res = err!(
3861 self.builder
3862 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3863 );
3864 self.state.push1(res);
3865 }
3866 Operator::I32DivS | Operator::I64DivS => {
3867 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3868 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3869 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3870 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3871
3872 self.trap_if_zero_or_overflow(v1, v2)?;
3873
3874 let res = err!(self.builder.build_int_signed_div(v1, v2, ""));
3875 self.state.push1(res);
3876 }
3877 Operator::I32DivU | Operator::I64DivU => {
3878 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3879 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3880 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3881 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3882
3883 self.trap_if_zero(v2)?;
3884
3885 let res = err!(self.builder.build_int_unsigned_div(v1, v2, ""));
3886 self.state.push1(res);
3887 }
3888 Operator::I32RemS | Operator::I64RemS => {
3889 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3890 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3891 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3892 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3893 let int_type = v1.get_type();
3894 let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
3895 let min_value = int_type.const_int(i32::MIN as u64, false);
3896 let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
3897 (min_value, neg_one_value)
3898 } else if int_type == self.intrinsics.i64_ty {
3899 let min_value = int_type.const_int(i64::MIN as u64, false);
3900 let neg_one_value = int_type.const_int(-1i64 as u64, false);
3901 (min_value, neg_one_value)
3902 } else {
3903 unreachable!()
3904 };
3905
3906 self.trap_if_zero(v2)?;
3907
3908 let will_overflow = err!(self.builder.build_and(
3920 err!(self.builder.build_int_compare(
3921 IntPredicate::EQ,
3922 v1,
3923 min_value,
3924 "left_is_min"
3925 )),
3926 err!(self.builder.build_int_compare(
3927 IntPredicate::EQ,
3928 v2,
3929 neg_one_value,
3930 "right_is_neg_one",
3931 )),
3932 "srem_will_overflow",
3933 ));
3934 let v1 =
3935 err!(
3936 self.builder
3937 .build_select(will_overflow, int_type.const_zero(), v1, "")
3938 )
3939 .into_int_value();
3940 let res = err!(self.builder.build_int_signed_rem(v1, v2, ""));
3941 self.state.push1(res);
3942 }
3943 Operator::I32RemU | Operator::I64RemU => {
3944 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3945 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3946 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3947 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3948
3949 self.trap_if_zero(v2)?;
3950
3951 let res = err!(self.builder.build_int_unsigned_rem(v1, v2, ""));
3952 self.state.push1(res);
3953 }
3954 Operator::I32And | Operator::I64And | Operator::V128And => {
3955 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3956 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3957 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3958 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3959 let res = err!(self.builder.build_and(v1, v2, ""));
3960 self.state.push1(res);
3961 }
3962 Operator::I32Or | Operator::I64Or | Operator::V128Or => {
3963 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3964 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3965 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3966 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3967 let res = err!(self.builder.build_or(v1, v2, ""));
3968 self.state.push1(res);
3969 }
3970 Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
3971 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3972 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3973 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3974 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3975 let res = err!(self.builder.build_xor(v1, v2, ""));
3976 self.state.push1(res);
3977 }
3978 Operator::V128AndNot => {
3979 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3980 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3981 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3982 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3983 let v2 = err!(self.builder.build_not(v2, ""));
3984 let res = err!(self.builder.build_and(v1, v2, ""));
3985 self.state.push1(res);
3986 }
3987 Operator::V128Bitselect => {
3988 let ((v1, i1), (v2, i2), (cond, cond_info)) = self.state.pop3_extra()?;
3989 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3990 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3991 let cond = self.apply_pending_canonicalization(cond, cond_info)?;
3992 let v1 = err!(
3993 self.builder
3994 .build_bit_cast(v1, self.intrinsics.i1x128_ty, "")
3995 )
3996 .into_vector_value();
3997 let v2 = err!(
3998 self.builder
3999 .build_bit_cast(v2, self.intrinsics.i1x128_ty, "")
4000 )
4001 .into_vector_value();
4002 let cond = err!(
4003 self.builder
4004 .build_bit_cast(cond, self.intrinsics.i1x128_ty, "")
4005 )
4006 .into_vector_value();
4007 let res = err!(self.builder.build_select(cond, v1, v2, ""));
4008 let res = err!(
4009 self.builder
4010 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4011 );
4012 self.state.push1(res);
4013 }
4014 Operator::I8x16Bitmask => {
4015 let (v, i) = self.state.pop1_extra()?;
4016 let (v, _) = self.v128_into_i8x16(v, i)?;
4017
4018 let zeros = self.intrinsics.i8x16_ty.const_zero();
4019 let res = err!(
4020 self.builder
4021 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4022 );
4023 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i16_ty, ""))
4024 .into_int_value();
4025 let res = err!(
4026 self.builder
4027 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4028 );
4029 self.state.push1(res);
4030 }
4031 Operator::I16x8Bitmask => {
4032 let (v, i) = self.state.pop1_extra()?;
4033 let (v, _) = self.v128_into_i16x8(v, i)?;
4034
4035 let zeros = self.intrinsics.i16x8_ty.const_zero();
4036 let res = err!(
4037 self.builder
4038 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4039 );
4040 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i8_ty, ""))
4041 .into_int_value();
4042 let res = err!(
4043 self.builder
4044 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4045 );
4046 self.state.push1(res);
4047 }
4048 Operator::I32x4Bitmask => {
4049 let (v, i) = self.state.pop1_extra()?;
4050 let (v, _) = self.v128_into_i32x4(v, i)?;
4051
4052 let zeros = self.intrinsics.i32x4_ty.const_zero();
4053 let res = err!(
4054 self.builder
4055 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4056 );
4057 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i4_ty, ""))
4058 .into_int_value();
4059 let res = err!(
4060 self.builder
4061 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4062 );
4063 self.state.push1(res);
4064 }
4065 Operator::I64x2Bitmask => {
4066 let (v, i) = self.state.pop1_extra()?;
4067 let (v, _) = self.v128_into_i64x2(v, i)?;
4068
4069 let zeros = self.intrinsics.i64x2_ty.const_zero();
4070 let res = err!(
4071 self.builder
4072 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4073 );
4074 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i2_ty, ""))
4075 .into_int_value();
4076 let res = err!(
4077 self.builder
4078 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4079 );
4080 self.state.push1(res);
4081 }
4082 Operator::I32Shl => {
4083 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4084 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4085 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4086 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4087 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4088 let v2 = err!(self.builder.build_and(v2, mask, ""));
4089 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4090 self.state.push1(res);
4091 }
4092 Operator::I64Shl => {
4093 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4094 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4095 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4096 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4097 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4098 let v2 = err!(self.builder.build_and(v2, mask, ""));
4099 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4100 self.state.push1(res);
4101 }
4102 Operator::I8x16Shl => {
4103 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4104 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4105 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4106 let v2 = v2.into_int_value();
4107 let v2 = err!(
4108 self.builder
4109 .build_and(v2, self.intrinsics.i32_consts[7], "")
4110 );
4111 let v2 = err!(
4112 self.builder
4113 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4114 );
4115 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4116 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4117 let res = err!(
4118 self.builder
4119 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4120 );
4121 self.state.push1(res);
4122 }
4123 Operator::I16x8Shl => {
4124 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4125 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4126 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4127 let v2 = v2.into_int_value();
4128 let v2 = err!(
4129 self.builder
4130 .build_and(v2, self.intrinsics.i32_consts[15], "")
4131 );
4132 let v2 = err!(
4133 self.builder
4134 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4135 );
4136 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4137 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4138 let res = err!(
4139 self.builder
4140 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4141 );
4142 self.state.push1(res);
4143 }
4144 Operator::I32x4Shl => {
4145 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4146 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4147 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4148 let v2 = v2.into_int_value();
4149 let v2 = err!(self.builder.build_and(
4150 v2,
4151 self.intrinsics.i32_ty.const_int(31, false),
4152 ""
4153 ));
4154 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4155 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4156 let res = err!(
4157 self.builder
4158 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4159 );
4160 self.state.push1(res);
4161 }
4162 Operator::I64x2Shl => {
4163 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4164 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4165 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4166 let v2 = v2.into_int_value();
4167 let v2 = err!(self.builder.build_and(
4168 v2,
4169 self.intrinsics.i32_ty.const_int(63, false),
4170 ""
4171 ));
4172 let v2 = err!(
4173 self.builder
4174 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4175 );
4176 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4177 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4178 let res = err!(
4179 self.builder
4180 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4181 );
4182 self.state.push1(res);
4183 }
4184 Operator::I32ShrS => {
4185 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4186 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4187 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4188 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4189 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4190 let v2 = err!(self.builder.build_and(v2, mask, ""));
4191 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4192 self.state.push1(res);
4193 }
4194 Operator::I64ShrS => {
4195 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4196 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4197 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4198 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4199 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4200 let v2 = err!(self.builder.build_and(v2, mask, ""));
4201 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4202 self.state.push1(res);
4203 }
4204 Operator::I8x16ShrS => {
4205 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4206 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4207 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4208 let v2 = v2.into_int_value();
4209 let v2 = err!(
4210 self.builder
4211 .build_and(v2, self.intrinsics.i32_consts[7], "")
4212 );
4213 let v2 = err!(
4214 self.builder
4215 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4216 );
4217 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4218 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4219 let res = err!(
4220 self.builder
4221 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4222 );
4223 self.state.push1(res);
4224 }
4225 Operator::I16x8ShrS => {
4226 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4227 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4228 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4229 let v2 = v2.into_int_value();
4230 let v2 = err!(
4231 self.builder
4232 .build_and(v2, self.intrinsics.i32_consts[15], "")
4233 );
4234 let v2 = err!(
4235 self.builder
4236 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4237 );
4238 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4239 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4240 let res = err!(
4241 self.builder
4242 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4243 );
4244 self.state.push1(res);
4245 }
4246 Operator::I32x4ShrS => {
4247 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4248 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4249 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4250 let v2 = v2.into_int_value();
4251 let v2 = err!(self.builder.build_and(
4252 v2,
4253 self.intrinsics.i32_ty.const_int(31, false),
4254 ""
4255 ));
4256 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4257 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4258 let res = err!(
4259 self.builder
4260 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4261 );
4262 self.state.push1(res);
4263 }
4264 Operator::I64x2ShrS => {
4265 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4266 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4267 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4268 let v2 = v2.into_int_value();
4269 let v2 = err!(self.builder.build_and(
4270 v2,
4271 self.intrinsics.i32_ty.const_int(63, false),
4272 ""
4273 ));
4274 let v2 = err!(
4275 self.builder
4276 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4277 );
4278 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4279 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4280 let res = err!(
4281 self.builder
4282 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4283 );
4284 self.state.push1(res);
4285 }
4286 Operator::I32ShrU => {
4287 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4288 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4289 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4290 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4291 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4292 let v2 = err!(self.builder.build_and(v2, mask, ""));
4293 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4294 self.state.push1(res);
4295 }
4296 Operator::I64ShrU => {
4297 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4298 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4299 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4300 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4301 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4302 let v2 = err!(self.builder.build_and(v2, mask, ""));
4303 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4304 self.state.push1(res);
4305 }
4306 Operator::I8x16ShrU => {
4307 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4308 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4309 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4310 let v2 = v2.into_int_value();
4311 let v2 = err!(
4312 self.builder
4313 .build_and(v2, self.intrinsics.i32_consts[7], "")
4314 );
4315 let v2 = err!(
4316 self.builder
4317 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4318 );
4319 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4320 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4321 let res = err!(
4322 self.builder
4323 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4324 );
4325 self.state.push1(res);
4326 }
4327 Operator::I16x8ShrU => {
4328 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4329 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4330 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4331 let v2 = v2.into_int_value();
4332 let v2 = err!(
4333 self.builder
4334 .build_and(v2, self.intrinsics.i32_consts[15], "")
4335 );
4336 let v2 = err!(
4337 self.builder
4338 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4339 );
4340 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4341 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4342 let res = err!(
4343 self.builder
4344 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4345 );
4346 self.state.push1(res);
4347 }
4348 Operator::I32x4ShrU => {
4349 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4350 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4351 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4352 let v2 = v2.into_int_value();
4353 let v2 = err!(self.builder.build_and(
4354 v2,
4355 self.intrinsics.i32_ty.const_int(31, false),
4356 ""
4357 ));
4358 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4359 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4360 let res = err!(
4361 self.builder
4362 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4363 );
4364 self.state.push1(res);
4365 }
4366 Operator::I64x2ShrU => {
4367 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4368 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4369 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4370 let v2 = v2.into_int_value();
4371 let v2 = err!(self.builder.build_and(
4372 v2,
4373 self.intrinsics.i32_ty.const_int(63, false),
4374 ""
4375 ));
4376 let v2 = err!(
4377 self.builder
4378 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4379 );
4380 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4381 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4382 let res = err!(
4383 self.builder
4384 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4385 );
4386 self.state.push1(res);
4387 }
4388 Operator::I32Rotl => {
4389 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4390 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4391 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4392 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4393 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4394 let v2 = err!(self.builder.build_and(v2, mask, ""));
4395 let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4396 let rhs = {
4397 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4398 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4399 err!(self.builder.build_right_shift(v1, rhs, false, ""))
4400 };
4401 let res = err!(self.builder.build_or(lhs, rhs, ""));
4402 self.state.push1(res);
4403 }
4404 Operator::I64Rotl => {
4405 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4406 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4407 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4408 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4409 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4410 let v2 = err!(self.builder.build_and(v2, mask, ""));
4411 let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4412 let rhs = {
4413 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4414 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4415 err!(self.builder.build_right_shift(v1, rhs, false, ""))
4416 };
4417 let res = err!(self.builder.build_or(lhs, rhs, ""));
4418 self.state.push1(res);
4419 }
4420 Operator::I32Rotr => {
4421 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4422 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4423 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4424 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4425 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4426 let v2 = err!(self.builder.build_and(v2, mask, ""));
4427 let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4428 let rhs = {
4429 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4430 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4431 err!(self.builder.build_left_shift(v1, rhs, ""))
4432 };
4433 let res = err!(self.builder.build_or(lhs, rhs, ""));
4434 self.state.push1(res);
4435 }
4436 Operator::I64Rotr => {
4437 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4438 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4439 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4440 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4441 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4442 let v2 = err!(self.builder.build_and(v2, mask, ""));
4443 let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4444 let rhs = {
4445 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4446 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4447 err!(self.builder.build_left_shift(v1, rhs, ""))
4448 };
4449 let res = err!(self.builder.build_or(lhs, rhs, ""));
4450 self.state.push1(res);
4451 }
4452 Operator::I32Clz => {
4453 let (input, info) = self.state.pop1_extra()?;
4454 let input = self.apply_pending_canonicalization(input, info)?;
4455 let is_zero_undef = self.intrinsics.i1_zero;
4456 let res = err!(self.builder.build_call(
4457 self.intrinsics.ctlz_i32,
4458 &[input.into(), is_zero_undef.into()],
4459 "",
4460 ))
4461 .try_as_basic_value()
4462 .unwrap_basic();
4463 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4464 }
4465 Operator::I64Clz => {
4466 let (input, info) = self.state.pop1_extra()?;
4467 let input = self.apply_pending_canonicalization(input, info)?;
4468 let is_zero_undef = self.intrinsics.i1_zero;
4469 let res = err!(self.builder.build_call(
4470 self.intrinsics.ctlz_i64,
4471 &[input.into(), is_zero_undef.into()],
4472 "",
4473 ))
4474 .try_as_basic_value()
4475 .unwrap_basic();
4476 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4477 }
4478 Operator::I32Ctz => {
4479 let (input, info) = self.state.pop1_extra()?;
4480 let input = self.apply_pending_canonicalization(input, info)?;
4481 let is_zero_undef = self.intrinsics.i1_zero;
4482 let res = err!(self.builder.build_call(
4483 self.intrinsics.cttz_i32,
4484 &[input.into(), is_zero_undef.into()],
4485 "",
4486 ))
4487 .try_as_basic_value()
4488 .unwrap_basic();
4489 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4490 }
4491 Operator::I64Ctz => {
4492 let (input, info) = self.state.pop1_extra()?;
4493 let input = self.apply_pending_canonicalization(input, info)?;
4494 let is_zero_undef = self.intrinsics.i1_zero;
4495 let res = err!(self.builder.build_call(
4496 self.intrinsics.cttz_i64,
4497 &[input.into(), is_zero_undef.into()],
4498 "",
4499 ))
4500 .try_as_basic_value()
4501 .unwrap_basic();
4502 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4503 }
4504 Operator::I8x16Popcnt => {
4505 let (v, i) = self.state.pop1_extra()?;
4506 let (v, _) = self.v128_into_i8x16(v, i)?;
4507 let res = err!(self.builder.build_call(
4508 self.intrinsics.ctpop_i8x16,
4509 &[v.into()],
4510 ""
4511 ))
4512 .try_as_basic_value()
4513 .unwrap_basic();
4514 let res = err!(
4515 self.builder
4516 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4517 );
4518 self.state.push1(res);
4519 }
4520 Operator::I32Popcnt => {
4521 let (input, info) = self.state.pop1_extra()?;
4522 let input = self.apply_pending_canonicalization(input, info)?;
4523 let res = err!(self.builder.build_call(
4524 self.intrinsics.ctpop_i32,
4525 &[input.into()],
4526 ""
4527 ))
4528 .try_as_basic_value()
4529 .unwrap_basic();
4530 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4531 }
4532 Operator::I64Popcnt => {
4533 let (input, info) = self.state.pop1_extra()?;
4534 let input = self.apply_pending_canonicalization(input, info)?;
4535 let res = err!(self.builder.build_call(
4536 self.intrinsics.ctpop_i64,
4537 &[input.into()],
4538 ""
4539 ))
4540 .try_as_basic_value()
4541 .unwrap_basic();
4542 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4543 }
4544 Operator::I32Eqz => {
4545 let input = self.state.pop1()?.into_int_value();
4546 let cond = err!(self.builder.build_int_compare(
4547 IntPredicate::EQ,
4548 input,
4549 self.intrinsics.i32_zero,
4550 "",
4551 ));
4552 let res = err!(
4553 self.builder
4554 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4555 );
4556 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4557 }
4558 Operator::I64Eqz => {
4559 let input = self.state.pop1()?.into_int_value();
4560 let cond = err!(self.builder.build_int_compare(
4561 IntPredicate::EQ,
4562 input,
4563 self.intrinsics.i64_zero,
4564 "",
4565 ));
4566 let res = err!(
4567 self.builder
4568 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4569 );
4570 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4571 }
4572 Operator::I8x16Abs => {
4573 let (v, i) = self.state.pop1_extra()?;
4574 let (v, _) = self.v128_into_i8x16(v, i)?;
4575
4576 let seven = self.intrinsics.i8_ty.const_int(7, false);
4577 let seven = VectorType::const_vector(&[seven; 16]);
4578 let all_sign_bits = err!(self.builder.build_right_shift(v, seven, true, ""));
4579 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4580 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4581 let res = err!(
4582 self.builder
4583 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4584 );
4585 self.state.push1(res);
4586 }
4587 Operator::I16x8Abs => {
4588 let (v, i) = self.state.pop1_extra()?;
4589 let (v, _) = self.v128_into_i16x8(v, i)?;
4590
4591 let fifteen = self.intrinsics.i16_ty.const_int(15, false);
4592 let fifteen = VectorType::const_vector(&[fifteen; 8]);
4593 let all_sign_bits = err!(self.builder.build_right_shift(v, fifteen, true, ""));
4594 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4595 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4596 let res = err!(
4597 self.builder
4598 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4599 );
4600 self.state.push1(res);
4601 }
4602 Operator::I32x4Abs => {
4603 let (v, i) = self.state.pop1_extra()?;
4604 let (v, _) = self.v128_into_i32x4(v, i)?;
4605
4606 let thirtyone = self.intrinsics.i32_ty.const_int(31, false);
4607 let thirtyone = VectorType::const_vector(&[thirtyone; 4]);
4608 let all_sign_bits = err!(self.builder.build_right_shift(v, thirtyone, true, ""));
4609 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4610 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4611 let res = err!(
4612 self.builder
4613 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4614 );
4615 self.state.push1(res);
4616 }
4617 Operator::I64x2Abs => {
4618 let (v, i) = self.state.pop1_extra()?;
4619 let (v, _) = self.v128_into_i64x2(v, i)?;
4620
4621 let sixtythree = self.intrinsics.i64_ty.const_int(63, false);
4622 let sixtythree = VectorType::const_vector(&[sixtythree; 2]);
4623 let all_sign_bits = err!(self.builder.build_right_shift(v, sixtythree, true, ""));
4624 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4625 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4626 let res = err!(
4627 self.builder
4628 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4629 );
4630 self.state.push1(res);
4631 }
4632 Operator::I8x16MinS => {
4633 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4634 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4635 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4636 let cmp = err!(
4637 self.builder
4638 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4639 );
4640 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4641 let res = err!(
4642 self.builder
4643 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4644 );
4645 self.state.push1(res);
4646 }
4647 Operator::I8x16MinU => {
4648 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4649 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4650 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4651 let cmp = err!(
4652 self.builder
4653 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4654 );
4655 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4656 let res = err!(
4657 self.builder
4658 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4659 );
4660 self.state.push1(res);
4661 }
4662 Operator::I8x16MaxS => {
4663 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4664 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4665 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4666 let cmp = err!(
4667 self.builder
4668 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4669 );
4670 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4671 let res = err!(
4672 self.builder
4673 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4674 );
4675 self.state.push1(res);
4676 }
4677 Operator::I8x16MaxU => {
4678 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4679 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4680 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4681 let cmp = err!(
4682 self.builder
4683 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4684 );
4685 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4686 let res = err!(
4687 self.builder
4688 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4689 );
4690 self.state.push1(res);
4691 }
4692 Operator::I16x8MinS => {
4693 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4694 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4695 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4696 let cmp = err!(
4697 self.builder
4698 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4699 );
4700 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4701 let res = err!(
4702 self.builder
4703 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4704 );
4705 self.state.push1(res);
4706 }
4707 Operator::I16x8MinU => {
4708 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4709 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4710 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4711 let cmp = err!(
4712 self.builder
4713 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4714 );
4715 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4716 let res = err!(
4717 self.builder
4718 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4719 );
4720 self.state.push1(res);
4721 }
4722 Operator::I16x8MaxS => {
4723 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4724 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4725 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4726 let cmp = err!(
4727 self.builder
4728 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4729 );
4730 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4731 let res = err!(
4732 self.builder
4733 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4734 );
4735 self.state.push1(res);
4736 }
4737 Operator::I16x8MaxU => {
4738 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4739 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4740 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4741 let cmp = err!(
4742 self.builder
4743 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4744 );
4745 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4746 let res = err!(
4747 self.builder
4748 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4749 );
4750 self.state.push1(res);
4751 }
4752 Operator::I32x4MinS => {
4753 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4754 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4755 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4756 let cmp = err!(
4757 self.builder
4758 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4759 );
4760 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4761 let res = err!(
4762 self.builder
4763 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4764 );
4765 self.state.push1(res);
4766 }
4767 Operator::I32x4MinU => {
4768 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4769 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4770 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4771 let cmp = err!(
4772 self.builder
4773 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4774 );
4775 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4776 let res = err!(
4777 self.builder
4778 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4779 );
4780 self.state.push1(res);
4781 }
4782 Operator::I32x4MaxS => {
4783 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4784 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4785 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4786 let cmp = err!(
4787 self.builder
4788 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4789 );
4790 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4791 let res = err!(
4792 self.builder
4793 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4794 );
4795 self.state.push1(res);
4796 }
4797 Operator::I32x4MaxU => {
4798 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4799 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4800 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4801 let cmp = err!(
4802 self.builder
4803 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4804 );
4805 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4806 let res = err!(
4807 self.builder
4808 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4809 );
4810 self.state.push1(res);
4811 }
4812 Operator::I8x16AvgrU => {
4813 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4814 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4815 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4816
4817 let ext_ty = self.intrinsics.i16_ty.vec_type(16);
4828 let one = self.intrinsics.i16_ty.const_int(1, false);
4829 let one = VectorType::const_vector(&[one; 16]);
4830
4831 let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4832 let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4833 let res = err!(self.builder.build_int_add(
4834 err!(self.builder.build_int_add(one, v1, "")),
4835 v2,
4836 ""
4837 ));
4838 let res = err!(self.builder.build_right_shift(res, one, false, ""));
4839 let res = err!(
4840 self.builder
4841 .build_int_truncate(res, self.intrinsics.i8x16_ty, "")
4842 );
4843 let res = err!(
4844 self.builder
4845 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4846 );
4847 self.state.push1(res);
4848 }
4849 Operator::I16x8AvgrU => {
4850 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4851 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4852 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4853
4854 let ext_ty = self.intrinsics.i32_ty.vec_type(8);
4865 let one = self.intrinsics.i32_consts[1];
4866 let one = VectorType::const_vector(&[one; 8]);
4867
4868 let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4869 let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4870 let res = err!(self.builder.build_int_add(
4871 err!(self.builder.build_int_add(one, v1, "")),
4872 v2,
4873 ""
4874 ));
4875 let res = err!(self.builder.build_right_shift(res, one, false, ""));
4876 let res = err!(
4877 self.builder
4878 .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
4879 );
4880 let res = err!(
4881 self.builder
4882 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4883 );
4884 self.state.push1(res);
4885 }
4886
4887 Operator::F32Add => {
4892 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4893 let res = err!(self.builder.build_call(
4894 self.intrinsics.add_f32,
4895 &[
4896 v1.into(),
4897 v2.into(),
4898 self.intrinsics.fp_rounding_md,
4899 self.intrinsics.fp_exception_md,
4900 ],
4901 "",
4902 ))
4903 .try_as_basic_value()
4904 .unwrap_basic();
4905 self.state.push1_extra(
4906 res,
4907 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4908 );
4909 }
4910 Operator::F64Add => {
4911 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4912 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4913 let res = err!(self.builder.build_call(
4914 self.intrinsics.add_f64,
4915 &[
4916 v1.into(),
4917 v2.into(),
4918 self.intrinsics.fp_rounding_md,
4919 self.intrinsics.fp_exception_md,
4920 ],
4921 "",
4922 ))
4923 .try_as_basic_value()
4924 .unwrap_basic();
4925 self.state.push1_extra(
4926 res,
4927 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4928 );
4929 }
4930 Operator::F32x4Add => {
4931 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4932 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4933 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4934 let res = err!(self.builder.build_call(
4935 self.intrinsics.add_f32x4,
4936 &[
4937 v1.into(),
4938 v2.into(),
4939 self.intrinsics.fp_rounding_md,
4940 self.intrinsics.fp_exception_md,
4941 ],
4942 "",
4943 ))
4944 .try_as_basic_value()
4945 .unwrap_basic();
4946 let res = err!(
4947 self.builder
4948 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4949 );
4950 self.state.push1_extra(
4951 res,
4952 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4953 );
4954 }
4955 Operator::F64x2Add => {
4956 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4957 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
4958 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
4959 let res = err!(self.builder.build_call(
4960 self.intrinsics.add_f64x2,
4961 &[
4962 v1.into(),
4963 v2.into(),
4964 self.intrinsics.fp_rounding_md,
4965 self.intrinsics.fp_exception_md,
4966 ],
4967 "",
4968 ))
4969 .try_as_basic_value()
4970 .unwrap_basic();
4971 let res = err!(
4972 self.builder
4973 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4974 );
4975 self.state.push1_extra(
4976 res,
4977 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4978 );
4979 }
4980 Operator::F32Sub => {
4981 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4982 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4983 let res = err!(self.builder.build_call(
4984 self.intrinsics.sub_f32,
4985 &[
4986 v1.into(),
4987 v2.into(),
4988 self.intrinsics.fp_rounding_md,
4989 self.intrinsics.fp_exception_md,
4990 ],
4991 "",
4992 ))
4993 .try_as_basic_value()
4994 .unwrap_basic();
4995 self.state.push1_extra(
4996 res,
4997 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4998 );
4999 }
5000 Operator::F64Sub => {
5001 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5002 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5003 let res = err!(self.builder.build_call(
5004 self.intrinsics.sub_f64,
5005 &[
5006 v1.into(),
5007 v2.into(),
5008 self.intrinsics.fp_rounding_md,
5009 self.intrinsics.fp_exception_md,
5010 ],
5011 "",
5012 ))
5013 .try_as_basic_value()
5014 .unwrap_basic();
5015 self.state.push1_extra(
5016 res,
5017 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5018 );
5019 }
5020 Operator::F32x4Sub => {
5021 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5022 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5023 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5024 let res = err!(self.builder.build_call(
5025 self.intrinsics.sub_f32x4,
5026 &[
5027 v1.into(),
5028 v2.into(),
5029 self.intrinsics.fp_rounding_md,
5030 self.intrinsics.fp_exception_md,
5031 ],
5032 "",
5033 ))
5034 .try_as_basic_value()
5035 .unwrap_basic();
5036 let res = err!(
5037 self.builder
5038 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5039 );
5040 self.state.push1_extra(
5041 res,
5042 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5043 );
5044 }
5045 Operator::F64x2Sub => {
5046 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5047 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5048 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5049 let res = err!(self.builder.build_call(
5050 self.intrinsics.sub_f64x2,
5051 &[
5052 v1.into(),
5053 v2.into(),
5054 self.intrinsics.fp_rounding_md,
5055 self.intrinsics.fp_exception_md,
5056 ],
5057 "",
5058 ))
5059 .try_as_basic_value()
5060 .unwrap_basic();
5061 let res = err!(
5062 self.builder
5063 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5064 );
5065 self.state.push1_extra(
5066 res,
5067 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5068 );
5069 }
5070 Operator::F32Mul => {
5071 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5072 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5073 let res = err!(self.builder.build_call(
5074 self.intrinsics.mul_f32,
5075 &[
5076 v1.into(),
5077 v2.into(),
5078 self.intrinsics.fp_rounding_md,
5079 self.intrinsics.fp_exception_md,
5080 ],
5081 "",
5082 ))
5083 .try_as_basic_value()
5084 .unwrap_basic();
5085 self.state.push1_extra(
5086 res,
5087 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5088 );
5089 }
5090 Operator::F64Mul => {
5091 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5092 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5093 let res = err!(self.builder.build_call(
5094 self.intrinsics.mul_f64,
5095 &[
5096 v1.into(),
5097 v2.into(),
5098 self.intrinsics.fp_rounding_md,
5099 self.intrinsics.fp_exception_md,
5100 ],
5101 "",
5102 ))
5103 .try_as_basic_value()
5104 .unwrap_basic();
5105 self.state.push1_extra(
5106 res,
5107 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5108 );
5109 }
5110 Operator::F32x4Mul => {
5111 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5112 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5113 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5114 let res = err!(self.builder.build_call(
5115 self.intrinsics.mul_f32x4,
5116 &[
5117 v1.into(),
5118 v2.into(),
5119 self.intrinsics.fp_rounding_md,
5120 self.intrinsics.fp_exception_md,
5121 ],
5122 "",
5123 ))
5124 .try_as_basic_value()
5125 .unwrap_basic();
5126 let res = err!(
5127 self.builder
5128 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5129 );
5130 self.state.push1_extra(
5131 res,
5132 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5133 );
5134 }
5135 Operator::F64x2Mul => {
5136 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5137 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5138 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5139 let res = err!(self.builder.build_call(
5140 self.intrinsics.mul_f64x2,
5141 &[
5142 v1.into(),
5143 v2.into(),
5144 self.intrinsics.fp_rounding_md,
5145 self.intrinsics.fp_exception_md,
5146 ],
5147 "",
5148 ))
5149 .try_as_basic_value()
5150 .unwrap_basic();
5151 let res = err!(
5152 self.builder
5153 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5154 );
5155 self.state.push1_extra(
5156 res,
5157 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5158 );
5159 }
5160 Operator::F32Div => {
5161 let (v1, v2) = self.state.pop2()?;
5162 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5163 let res = err!(self.builder.build_call(
5164 self.intrinsics.div_f32,
5165 &[
5166 v1.into(),
5167 v2.into(),
5168 self.intrinsics.fp_rounding_md,
5169 self.intrinsics.fp_exception_md,
5170 ],
5171 "",
5172 ))
5173 .try_as_basic_value()
5174 .unwrap_basic();
5175 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5176 }
5177 Operator::F64Div => {
5178 let (v1, v2) = self.state.pop2()?;
5179 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5180 let res = err!(self.builder.build_call(
5181 self.intrinsics.div_f64,
5182 &[
5183 v1.into(),
5184 v2.into(),
5185 self.intrinsics.fp_rounding_md,
5186 self.intrinsics.fp_exception_md,
5187 ],
5188 "",
5189 ))
5190 .try_as_basic_value()
5191 .unwrap_basic();
5192 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5193 }
5194 Operator::F32x4Div => {
5195 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5196 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5197 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5198 let res = err!(self.builder.build_call(
5199 self.intrinsics.div_f32x4,
5200 &[
5201 v1.into(),
5202 v2.into(),
5203 self.intrinsics.fp_rounding_md,
5204 self.intrinsics.fp_exception_md,
5205 ],
5206 "",
5207 ))
5208 .try_as_basic_value()
5209 .unwrap_basic();
5210 let res = err!(
5211 self.builder
5212 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5213 );
5214 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5215 }
5216 Operator::F64x2Div => {
5217 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5218 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5219 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5220 let res = err!(self.builder.build_call(
5221 self.intrinsics.div_f64x2,
5222 &[
5223 v1.into(),
5224 v2.into(),
5225 self.intrinsics.fp_rounding_md,
5226 self.intrinsics.fp_exception_md,
5227 ],
5228 "",
5229 ))
5230 .try_as_basic_value()
5231 .unwrap_basic();
5232 let res = err!(
5233 self.builder
5234 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5235 );
5236 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5237 }
5238 Operator::F32Sqrt => {
5239 let input = self.state.pop1()?;
5240 let res = err!(self.builder.build_call(
5241 self.intrinsics.sqrt_f32,
5242 &[input.into()],
5243 ""
5244 ))
5245 .try_as_basic_value()
5246 .unwrap_basic();
5247 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5248 }
5249 Operator::F64Sqrt => {
5250 let input = self.state.pop1()?;
5251 let res = err!(self.builder.build_call(
5252 self.intrinsics.sqrt_f64,
5253 &[input.into()],
5254 ""
5255 ))
5256 .try_as_basic_value()
5257 .unwrap_basic();
5258 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5259 }
5260 Operator::F32x4Sqrt => {
5261 let (v, i) = self.state.pop1_extra()?;
5262 let (v, _) = self.v128_into_f32x4(v, i)?;
5263 let res = err!(self.builder.build_call(
5264 self.intrinsics.sqrt_f32x4,
5265 &[v.into()],
5266 ""
5267 ))
5268 .try_as_basic_value()
5269 .unwrap_basic();
5270 let bits = err!(
5271 self.builder
5272 .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5273 );
5274 self.state.push1_extra(bits, ExtraInfo::pending_f32_nan());
5275 }
5276 Operator::F64x2Sqrt => {
5277 let (v, i) = self.state.pop1_extra()?;
5278 let (v, _) = self.v128_into_f64x2(v, i)?;
5279 let res = err!(self.builder.build_call(
5280 self.intrinsics.sqrt_f64x2,
5281 &[v.into()],
5282 ""
5283 ))
5284 .try_as_basic_value()
5285 .unwrap_basic();
5286 let bits = err!(
5287 self.builder
5288 .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5289 );
5290 self.state.push1(bits);
5291 }
5292 Operator::F32Min => {
5293 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5294 let lhs = self
5295 .apply_pending_canonicalization(lhs, lhs_info)?
5296 .into_float_value();
5297 let rhs = self
5298 .apply_pending_canonicalization(rhs, rhs_info)?
5299 .into_float_value();
5300
5301 let res = err!(self.builder.build_call(
5302 self.intrinsics.minimum_f32,
5303 &[lhs.into(), rhs.into()],
5304 "",
5305 ))
5306 .try_as_basic_value()
5307 .unwrap_basic();
5308
5309 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5310 let res = res.into_float_value();
5311
5312 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5313 }
5314 Operator::F64Min => {
5315 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5316 let lhs = self
5317 .apply_pending_canonicalization(lhs, lhs_info)?
5318 .into_float_value();
5319 let rhs = self
5320 .apply_pending_canonicalization(rhs, rhs_info)?
5321 .into_float_value();
5322
5323 let res = err!(self.builder.build_call(
5324 self.intrinsics.minimum_f64,
5325 &[lhs.into(), rhs.into()],
5326 "",
5327 ))
5328 .try_as_basic_value()
5329 .unwrap_basic();
5330
5331 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5332 let res = res.into_float_value();
5333
5334 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5335 }
5336 Operator::F32x4Min => {
5337 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5338 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5339 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5340 let res = err!(self.builder.build_call(
5341 self.intrinsics.minimum_f32x4,
5342 &[v1.into(), v2.into()],
5343 "",
5344 ))
5345 .try_as_basic_value()
5346 .unwrap_basic();
5347
5348 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5349 let res = res.into_vector_value();
5350
5351 let res = err!(
5352 self.builder
5353 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5354 );
5355 self.state.push1_extra(
5356 res,
5357 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5358 );
5359 }
5360 Operator::F32x4PMin => {
5361 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5363 let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5364 let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5365 let cmp = err!(
5366 self.builder
5367 .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5368 );
5369 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5370 let res = err!(
5371 self.builder
5372 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5373 );
5374 self.state.push1(res);
5375 }
5376 Operator::F64x2Min => {
5377 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5378 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5379 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5380 let res = err!(self.builder.build_call(
5381 self.intrinsics.minimum_f64x2,
5382 &[v1.into(), v2.into()],
5383 "",
5384 ))
5385 .try_as_basic_value()
5386 .unwrap_basic();
5387
5388 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5389 let res = res.into_vector_value();
5390
5391 let res = err!(
5392 self.builder
5393 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5394 );
5395 self.state.push1_extra(
5396 res,
5397 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5398 );
5399 }
5400 Operator::F64x2PMin => {
5401 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5403 let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5404 let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5405 let cmp = err!(
5406 self.builder
5407 .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5408 );
5409 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5410 let res = err!(
5411 self.builder
5412 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5413 );
5414 self.state.push1(res);
5415 }
5416 Operator::F32Max => {
5417 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5418 let lhs = self
5419 .apply_pending_canonicalization(lhs, lhs_info)?
5420 .into_float_value();
5421 let rhs = self
5422 .apply_pending_canonicalization(rhs, rhs_info)?
5423 .into_float_value();
5424
5425 let res = err!(self.builder.build_call(
5426 self.intrinsics.maximum_f32,
5427 &[lhs.into(), rhs.into()],
5428 "",
5429 ))
5430 .try_as_basic_value()
5431 .unwrap_basic();
5432
5433 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5434 let res = res.into_float_value();
5435
5436 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5437 }
5438 Operator::F64Max => {
5439 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5440 let lhs = self
5441 .apply_pending_canonicalization(lhs, lhs_info)?
5442 .into_float_value();
5443 let rhs = self
5444 .apply_pending_canonicalization(rhs, rhs_info)?
5445 .into_float_value();
5446
5447 let res = err!(self.builder.build_call(
5448 self.intrinsics.maximum_f64,
5449 &[lhs.into(), rhs.into()],
5450 "",
5451 ))
5452 .try_as_basic_value()
5453 .unwrap_basic();
5454
5455 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5456 let res = res.into_float_value();
5457
5458 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5459 }
5460 Operator::F32x4Max => {
5461 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5462 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5463 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5464 let res = err!(self.builder.build_call(
5465 self.intrinsics.maximum_f32x4,
5466 &[v1.into(), v2.into()],
5467 "",
5468 ))
5469 .try_as_basic_value()
5470 .unwrap_basic();
5471
5472 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5473 let res = res.into_vector_value();
5474
5475 let res = err!(
5476 self.builder
5477 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5478 );
5479 self.state.push1_extra(
5480 res,
5481 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5482 );
5483 }
5484 Operator::F32x4PMax => {
5485 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5487 let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5488 let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5489 let cmp = err!(
5490 self.builder
5491 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5492 );
5493 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5494
5495 let res = err!(
5496 self.builder
5497 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5498 );
5499 self.state.push1(res);
5500 }
5501 Operator::F64x2Max => {
5502 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5503 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5504 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5505 let res = err!(self.builder.build_call(
5506 self.intrinsics.maximum_f64x2,
5507 &[v1.into(), v2.into()],
5508 "",
5509 ))
5510 .try_as_basic_value()
5511 .unwrap_basic();
5512
5513 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5514 let res = res.into_vector_value();
5515
5516 let res = err!(
5517 self.builder
5518 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5519 );
5520 self.state.push1_extra(
5521 res,
5522 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5523 );
5524 }
5525 Operator::F64x2PMax => {
5526 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5528 let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5529 let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5530 let cmp = err!(
5531 self.builder
5532 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5533 );
5534 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5535 let res = err!(
5536 self.builder
5537 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5538 );
5539 self.state.push1(res);
5540 }
5541 Operator::F32Ceil => {
5542 let (input, info) = self.state.pop1_extra()?;
5543 let res = err!(self.builder.build_call(
5544 self.intrinsics.ceil_f32,
5545 &[input.into()],
5546 ""
5547 ))
5548 .try_as_basic_value()
5549 .unwrap_basic();
5550 self.state
5551 .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5552 }
5553 Operator::F32x4Ceil => {
5554 let (v, i) = self.state.pop1_extra()?;
5555 let (v, _) = self.v128_into_f32x4(v, i)?;
5556 let res = err!(self.builder.build_call(
5557 self.intrinsics.ceil_f32x4,
5558 &[v.into()],
5559 ""
5560 ))
5561 .try_as_basic_value()
5562 .unwrap_basic();
5563 let res = err!(
5564 self.builder
5565 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5566 );
5567 self.state
5568 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5569 }
5570 Operator::F64Ceil => {
5571 let (input, info) = self.state.pop1_extra()?;
5572 let res = err!(self.builder.build_call(
5573 self.intrinsics.ceil_f64,
5574 &[input.into()],
5575 ""
5576 ))
5577 .try_as_basic_value()
5578 .unwrap_basic();
5579 self.state
5580 .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5581 }
5582 Operator::F64x2Ceil => {
5583 let (v, i) = self.state.pop1_extra()?;
5584 let (v, _) = self.v128_into_f64x2(v, i)?;
5585 let res = err!(self.builder.build_call(
5586 self.intrinsics.ceil_f64x2,
5587 &[v.into()],
5588 ""
5589 ))
5590 .try_as_basic_value()
5591 .unwrap_basic();
5592 let res = err!(
5593 self.builder
5594 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5595 );
5596 self.state
5597 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5598 }
5599 Operator::F32Floor => {
5600 let (input, info) = self.state.pop1_extra()?;
5601 let res = err!(self.builder.build_call(
5602 self.intrinsics.floor_f32,
5603 &[input.into()],
5604 ""
5605 ))
5606 .try_as_basic_value()
5607 .unwrap_basic();
5608 self.state
5609 .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5610 }
5611 Operator::F32x4Floor => {
5612 let (v, i) = self.state.pop1_extra()?;
5613 let (v, _) = self.v128_into_f32x4(v, i)?;
5614 let res = err!(self.builder.build_call(
5615 self.intrinsics.floor_f32x4,
5616 &[v.into()],
5617 ""
5618 ))
5619 .try_as_basic_value()
5620 .unwrap_basic();
5621 let res = err!(
5622 self.builder
5623 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5624 );
5625 self.state
5626 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5627 }
5628 Operator::F64Floor => {
5629 let (input, info) = self.state.pop1_extra()?;
5630 let res = err!(self.builder.build_call(
5631 self.intrinsics.floor_f64,
5632 &[input.into()],
5633 ""
5634 ))
5635 .try_as_basic_value()
5636 .unwrap_basic();
5637 self.state
5638 .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5639 }
5640 Operator::F64x2Floor => {
5641 let (v, i) = self.state.pop1_extra()?;
5642 let (v, _) = self.v128_into_f64x2(v, i)?;
5643 let res = err!(self.builder.build_call(
5644 self.intrinsics.floor_f64x2,
5645 &[v.into()],
5646 ""
5647 ))
5648 .try_as_basic_value()
5649 .unwrap_basic();
5650 let res = err!(
5651 self.builder
5652 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5653 );
5654 self.state
5655 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5656 }
5657 Operator::F32Trunc => {
5658 let (v, i) = self.state.pop1_extra()?;
5659 let res = err!(
5660 self.builder
5661 .build_call(self.intrinsics.trunc_f32, &[v.into()], "")
5662 )
5663 .try_as_basic_value()
5664 .unwrap_basic();
5665 self.state
5666 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5667 }
5668 Operator::F32x4Trunc => {
5669 let (v, i) = self.state.pop1_extra()?;
5670 let (v, _) = self.v128_into_f32x4(v, i)?;
5671 let res = err!(self.builder.build_call(
5672 self.intrinsics.trunc_f32x4,
5673 &[v.into()],
5674 ""
5675 ))
5676 .try_as_basic_value()
5677 .unwrap_basic();
5678 let res = err!(
5679 self.builder
5680 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5681 );
5682 self.state
5683 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5684 }
5685 Operator::F64Trunc => {
5686 let (v, i) = self.state.pop1_extra()?;
5687 let res = err!(
5688 self.builder
5689 .build_call(self.intrinsics.trunc_f64, &[v.into()], "")
5690 )
5691 .try_as_basic_value()
5692 .unwrap_basic();
5693 self.state
5694 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5695 }
5696 Operator::F64x2Trunc => {
5697 let (v, i) = self.state.pop1_extra()?;
5698 let (v, _) = self.v128_into_f64x2(v, i)?;
5699 let res = err!(self.builder.build_call(
5700 self.intrinsics.trunc_f64x2,
5701 &[v.into()],
5702 ""
5703 ))
5704 .try_as_basic_value()
5705 .unwrap_basic();
5706 let res = err!(
5707 self.builder
5708 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5709 );
5710 self.state
5711 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5712 }
5713 Operator::F32Nearest => {
5714 let (v, i) = self.state.pop1_extra()?;
5715 let res = err!(self.builder.build_call(
5716 self.intrinsics.nearbyint_f32,
5717 &[v.into()],
5718 ""
5719 ))
5720 .try_as_basic_value()
5721 .unwrap_basic();
5722 self.state
5723 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5724 }
5725 Operator::F32x4Nearest => {
5726 let (v, i) = self.state.pop1_extra()?;
5727 let (v, _) = self.v128_into_f32x4(v, i)?;
5728 let res = err!(self.builder.build_call(
5729 self.intrinsics.nearbyint_f32x4,
5730 &[v.into()],
5731 ""
5732 ))
5733 .try_as_basic_value()
5734 .unwrap_basic();
5735 let res = err!(
5736 self.builder
5737 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5738 );
5739 self.state
5740 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5741 }
5742 Operator::F64Nearest => {
5743 let (v, i) = self.state.pop1_extra()?;
5744 let res = err!(self.builder.build_call(
5745 self.intrinsics.nearbyint_f64,
5746 &[v.into()],
5747 ""
5748 ))
5749 .try_as_basic_value()
5750 .unwrap_basic();
5751 self.state
5752 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5753 }
5754 Operator::F64x2Nearest => {
5755 let (v, i) = self.state.pop1_extra()?;
5756 let (v, _) = self.v128_into_f64x2(v, i)?;
5757 let res = err!(self.builder.build_call(
5758 self.intrinsics.nearbyint_f64x2,
5759 &[v.into()],
5760 ""
5761 ))
5762 .try_as_basic_value()
5763 .unwrap_basic();
5764 let res = err!(
5765 self.builder
5766 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5767 );
5768 self.state
5769 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5770 }
5771 Operator::F32Abs => {
5772 let (v, i) = self.state.pop1_extra()?;
5773 let v = self.apply_pending_canonicalization(v, i)?;
5774 let res = err!(
5775 self.builder
5776 .build_call(self.intrinsics.fabs_f32, &[v.into()], "")
5777 )
5778 .try_as_basic_value()
5779 .unwrap_basic();
5780 self.state.push1_extra(res, i.strip_pending());
5783 }
5784 Operator::F64Abs => {
5785 let (v, i) = self.state.pop1_extra()?;
5786 let v = self.apply_pending_canonicalization(v, i)?;
5787 let res = err!(
5788 self.builder
5789 .build_call(self.intrinsics.fabs_f64, &[v.into()], "")
5790 )
5791 .try_as_basic_value()
5792 .unwrap_basic();
5793 self.state.push1_extra(res, i.strip_pending());
5796 }
5797 Operator::F32x4Abs => {
5798 let (v, i) = self.state.pop1_extra()?;
5799 let v = err!(self.builder.build_bit_cast(
5800 v.into_int_value(),
5801 self.intrinsics.f32x4_ty,
5802 ""
5803 ));
5804 let v = self.apply_pending_canonicalization(v, i)?;
5805 let res = err!(self.builder.build_call(
5806 self.intrinsics.fabs_f32x4,
5807 &[v.into()],
5808 ""
5809 ))
5810 .try_as_basic_value()
5811 .unwrap_basic();
5812 let res = err!(
5813 self.builder
5814 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5815 );
5816 self.state.push1_extra(res, i.strip_pending());
5819 }
5820 Operator::F64x2Abs => {
5821 let (v, i) = self.state.pop1_extra()?;
5822 let v = err!(self.builder.build_bit_cast(
5823 v.into_int_value(),
5824 self.intrinsics.f64x2_ty,
5825 ""
5826 ));
5827 let v = self.apply_pending_canonicalization(v, i)?;
5828 let res = err!(self.builder.build_call(
5829 self.intrinsics.fabs_f64x2,
5830 &[v.into()],
5831 ""
5832 ))
5833 .try_as_basic_value()
5834 .unwrap_basic();
5835 let res = err!(
5836 self.builder
5837 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5838 );
5839 self.state.push1_extra(res, i.strip_pending());
5842 }
5843 Operator::F32x4Neg => {
5844 let (v, i) = self.state.pop1_extra()?;
5845 let v = err!(self.builder.build_bit_cast(
5846 v.into_int_value(),
5847 self.intrinsics.f32x4_ty,
5848 ""
5849 ));
5850 let v = self
5851 .apply_pending_canonicalization(v, i)?
5852 .into_vector_value();
5853 let res = err!(self.builder.build_float_neg(v, ""));
5854 let res = err!(
5855 self.builder
5856 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5857 );
5858 self.state.push1_extra(res, i.strip_pending());
5861 }
5862 Operator::F64x2Neg => {
5863 let (v, i) = self.state.pop1_extra()?;
5864 let v = err!(self.builder.build_bit_cast(
5865 v.into_int_value(),
5866 self.intrinsics.f64x2_ty,
5867 ""
5868 ));
5869 let v = self
5870 .apply_pending_canonicalization(v, i)?
5871 .into_vector_value();
5872 let res = err!(self.builder.build_float_neg(v, ""));
5873 let res = err!(
5874 self.builder
5875 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5876 );
5877 self.state.push1_extra(res, i.strip_pending());
5880 }
5881 Operator::F32Neg | Operator::F64Neg => {
5882 let (v, i) = self.state.pop1_extra()?;
5883 let v = self
5884 .apply_pending_canonicalization(v, i)?
5885 .into_float_value();
5886 let res = err!(self.builder.build_float_neg(v, ""));
5887 self.state.push1_extra(res, i.strip_pending());
5890 }
5891 Operator::F32Copysign => {
5892 let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5893 let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5894 let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5895 let res = err!(self.builder.build_call(
5896 self.intrinsics.copysign_f32,
5897 &[mag.into(), sgn.into()],
5898 ""
5899 ))
5900 .try_as_basic_value()
5901 .unwrap_basic();
5902 self.state.push1_extra(res, mag_info.strip_pending());
5905 }
5906 Operator::F64Copysign => {
5907 let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5908 let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5909 let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5910 let res = err!(self.builder.build_call(
5911 self.intrinsics.copysign_f64,
5912 &[mag.into(), sgn.into()],
5913 ""
5914 ))
5915 .try_as_basic_value()
5916 .unwrap_basic();
5917 self.state.push1_extra(res, mag_info.strip_pending());
5920 }
5921
5922 Operator::I32Eq | Operator::I64Eq => {
5927 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5928 let v1 = self.apply_pending_canonicalization(v1, i1)?;
5929 let v2 = self.apply_pending_canonicalization(v2, i2)?;
5930 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
5931 let cond = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5932 let res = err!(
5933 self.builder
5934 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
5935 );
5936 self.state.push1_extra(
5937 res,
5938 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
5939 );
5940 }
5941 Operator::I8x16Eq => {
5942 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5943 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
5944 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
5945 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5946 let res = err!(
5947 self.builder
5948 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
5949 );
5950 let res = err!(
5951 self.builder
5952 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5953 );
5954 self.state.push1(res);
5955 }
5956 Operator::I16x8Eq => {
5957 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5958 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
5959 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
5960 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5961 let res = err!(
5962 self.builder
5963 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
5964 );
5965 let res = err!(
5966 self.builder
5967 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5968 );
5969 self.state.push1(res);
5970 }
5971 Operator::I32x4Eq => {
5972 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5973 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
5974 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
5975 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5976 let res = err!(
5977 self.builder
5978 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
5979 );
5980 let res = err!(
5981 self.builder
5982 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5983 );
5984 self.state.push1(res);
5985 }
5986 Operator::I64x2Eq => {
5987 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5988 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
5989 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
5990 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5991 let res = err!(
5992 self.builder
5993 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
5994 );
5995 let res = err!(
5996 self.builder
5997 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5998 );
5999 self.state.push1(res);
6000 }
6001 Operator::I32Ne | Operator::I64Ne => {
6002 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6003 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6004 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6005 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6006 let cond = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6007 let res = err!(
6008 self.builder
6009 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6010 );
6011 self.state.push1_extra(
6012 res,
6013 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6014 );
6015 }
6016 Operator::I8x16Ne => {
6017 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6018 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6019 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6020 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6021 let res = err!(
6022 self.builder
6023 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6024 );
6025 let res = err!(
6026 self.builder
6027 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6028 );
6029 self.state.push1(res);
6030 }
6031 Operator::I16x8Ne => {
6032 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6033 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6034 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6035 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6036 let res = err!(
6037 self.builder
6038 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6039 );
6040 let res = err!(
6041 self.builder
6042 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6043 );
6044 self.state.push1(res);
6045 }
6046 Operator::I32x4Ne => {
6047 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6048 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6049 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6050 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6051 let res = err!(
6052 self.builder
6053 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6054 );
6055 let res = err!(
6056 self.builder
6057 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6058 );
6059 self.state.push1(res);
6060 }
6061 Operator::I64x2Ne => {
6062 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6063 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6064 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6065 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6066 let res = err!(
6067 self.builder
6068 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6069 );
6070 let res = err!(
6071 self.builder
6072 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6073 );
6074 self.state.push1(res);
6075 }
6076 Operator::I32LtS | Operator::I64LtS => {
6077 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6078 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6079 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6080 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6081 let cond = err!(
6082 self.builder
6083 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6084 );
6085 let res = err!(
6086 self.builder
6087 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6088 );
6089 self.state.push1_extra(
6090 res,
6091 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6092 );
6093 }
6094 Operator::I8x16LtS => {
6095 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6096 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6097 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6098 let res = err!(
6099 self.builder
6100 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6101 );
6102 let res = err!(
6103 self.builder
6104 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6105 );
6106 let res = err!(
6107 self.builder
6108 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6109 );
6110 self.state.push1(res);
6111 }
6112 Operator::I16x8LtS => {
6113 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6114 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6115 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6116 let res = err!(
6117 self.builder
6118 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6119 );
6120 let res = err!(
6121 self.builder
6122 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6123 );
6124 let res = err!(
6125 self.builder
6126 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6127 );
6128 self.state.push1(res);
6129 }
6130 Operator::I32x4LtS => {
6131 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6132 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6133 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6134 let res = err!(
6135 self.builder
6136 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6137 );
6138 let res = err!(
6139 self.builder
6140 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6141 );
6142 let res = err!(
6143 self.builder
6144 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6145 );
6146 self.state.push1(res);
6147 }
6148 Operator::I64x2LtS => {
6149 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6150 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6151 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6152 let res = err!(
6153 self.builder
6154 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6155 );
6156 let res = err!(
6157 self.builder
6158 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6159 );
6160 let res = err!(
6161 self.builder
6162 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6163 );
6164 self.state.push1(res);
6165 }
6166 Operator::I32LtU | Operator::I64LtU => {
6167 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6168 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6169 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6170 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6171 let cond = err!(
6172 self.builder
6173 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6174 );
6175 let res = err!(
6176 self.builder
6177 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6178 );
6179 self.state.push1(res);
6180 }
6181 Operator::I8x16LtU => {
6182 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6183 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6184 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6185 let res = err!(
6186 self.builder
6187 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6188 );
6189 let res = err!(
6190 self.builder
6191 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6192 );
6193 let res = err!(
6194 self.builder
6195 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6196 );
6197 self.state.push1(res);
6198 }
6199 Operator::I16x8LtU => {
6200 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6201 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6202 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6203 let res = err!(
6204 self.builder
6205 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6206 );
6207 let res = err!(
6208 self.builder
6209 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6210 );
6211 let res = err!(
6212 self.builder
6213 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6214 );
6215 self.state.push1(res);
6216 }
6217 Operator::I32x4LtU => {
6218 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6219 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6220 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6221 let res = err!(
6222 self.builder
6223 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6224 );
6225 let res = err!(
6226 self.builder
6227 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6228 );
6229 let res = err!(
6230 self.builder
6231 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6232 );
6233 self.state.push1(res);
6234 }
6235 Operator::I32LeS | Operator::I64LeS => {
6236 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6237 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6238 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6239 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6240 let cond = err!(
6241 self.builder
6242 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6243 );
6244 let res = err!(
6245 self.builder
6246 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6247 );
6248 self.state.push1_extra(
6249 res,
6250 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6251 );
6252 }
6253 Operator::I8x16LeS => {
6254 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6255 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6256 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6257 let res = err!(
6258 self.builder
6259 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6260 );
6261 let res = err!(
6262 self.builder
6263 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6264 );
6265 let res = err!(
6266 self.builder
6267 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6268 );
6269 self.state.push1(res);
6270 }
6271 Operator::I16x8LeS => {
6272 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6273 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6274 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6275 let res = err!(
6276 self.builder
6277 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6278 );
6279 let res = err!(
6280 self.builder
6281 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6282 );
6283 let res = err!(
6284 self.builder
6285 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6286 );
6287 self.state.push1(res);
6288 }
6289 Operator::I32x4LeS => {
6290 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6291 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6292 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6293 let res = err!(
6294 self.builder
6295 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6296 );
6297 let res = err!(
6298 self.builder
6299 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6300 );
6301 let res = err!(
6302 self.builder
6303 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6304 );
6305 self.state.push1(res);
6306 }
6307 Operator::I64x2LeS => {
6308 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6309 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6310 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6311 let res = err!(
6312 self.builder
6313 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6314 );
6315 let res = err!(
6316 self.builder
6317 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6318 );
6319 let res = err!(
6320 self.builder
6321 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6322 );
6323 self.state.push1(res);
6324 }
6325 Operator::I32LeU | Operator::I64LeU => {
6326 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6327 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6328 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6329 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6330 let cond = err!(
6331 self.builder
6332 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6333 );
6334 let res = err!(
6335 self.builder
6336 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6337 );
6338 self.state.push1_extra(
6339 res,
6340 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6341 );
6342 }
6343 Operator::I8x16LeU => {
6344 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6345 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6346 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6347 let res = err!(
6348 self.builder
6349 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6350 );
6351 let res = err!(
6352 self.builder
6353 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6354 );
6355 let res = err!(
6356 self.builder
6357 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6358 );
6359 self.state.push1(res);
6360 }
6361 Operator::I16x8LeU => {
6362 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6363 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6364 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6365 let res = err!(
6366 self.builder
6367 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6368 );
6369 let res = err!(
6370 self.builder
6371 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6372 );
6373 let res = err!(
6374 self.builder
6375 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6376 );
6377 self.state.push1(res);
6378 }
6379 Operator::I32x4LeU => {
6380 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6381 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6382 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6383 let res = err!(
6384 self.builder
6385 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6386 );
6387 let res = err!(
6388 self.builder
6389 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6390 );
6391 let res = err!(
6392 self.builder
6393 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6394 );
6395 self.state.push1(res);
6396 }
6397 Operator::I32GtS | Operator::I64GtS => {
6398 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6399 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6400 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6401 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6402 let cond = err!(
6403 self.builder
6404 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6405 );
6406 let res = err!(
6407 self.builder
6408 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6409 );
6410 self.state.push1_extra(
6411 res,
6412 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6413 );
6414 }
6415 Operator::I8x16GtS => {
6416 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6417 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6418 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6419 let res = err!(
6420 self.builder
6421 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6422 );
6423 let res = err!(
6424 self.builder
6425 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6426 );
6427 let res = err!(
6428 self.builder
6429 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6430 );
6431 self.state.push1(res);
6432 }
6433 Operator::I16x8GtS => {
6434 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6435 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6436 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6437 let res = err!(
6438 self.builder
6439 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6440 );
6441 let res = err!(
6442 self.builder
6443 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6444 );
6445 let res = err!(
6446 self.builder
6447 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6448 );
6449 self.state.push1(res);
6450 }
6451 Operator::I32x4GtS => {
6452 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6453 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6454 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6455 let res = err!(
6456 self.builder
6457 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6458 );
6459 let res = err!(
6460 self.builder
6461 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6462 );
6463 let res = err!(
6464 self.builder
6465 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6466 );
6467 self.state.push1(res);
6468 }
6469 Operator::I64x2GtS => {
6470 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6471 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6472 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6473 let res = err!(
6474 self.builder
6475 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6476 );
6477 let res = err!(
6478 self.builder
6479 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6480 );
6481 let res = err!(
6482 self.builder
6483 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6484 );
6485 self.state.push1(res);
6486 }
6487 Operator::I32GtU | Operator::I64GtU => {
6488 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6489 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6490 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6491 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6492 let cond = err!(
6493 self.builder
6494 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6495 );
6496 let res = err!(
6497 self.builder
6498 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6499 );
6500 self.state.push1_extra(
6501 res,
6502 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6503 );
6504 }
6505 Operator::I8x16GtU => {
6506 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6507 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6508 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6509 let res = err!(
6510 self.builder
6511 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6512 );
6513 let res = err!(
6514 self.builder
6515 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6516 );
6517 let res = err!(
6518 self.builder
6519 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6520 );
6521 self.state.push1(res);
6522 }
6523 Operator::I16x8GtU => {
6524 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6525 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6526 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6527 let res = err!(
6528 self.builder
6529 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6530 );
6531 let res = err!(
6532 self.builder
6533 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6534 );
6535 let res = err!(
6536 self.builder
6537 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6538 );
6539 self.state.push1(res);
6540 }
6541 Operator::I32x4GtU => {
6542 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6543 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6544 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6545 let res = err!(
6546 self.builder
6547 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6548 );
6549 let res = err!(
6550 self.builder
6551 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6552 );
6553 let res = err!(
6554 self.builder
6555 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6556 );
6557 self.state.push1(res);
6558 }
6559 Operator::I32GeS | Operator::I64GeS => {
6560 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6561 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6562 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6563 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6564 let cond = err!(
6565 self.builder
6566 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6567 );
6568 let res = err!(
6569 self.builder
6570 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6571 );
6572 self.state.push1(res);
6573 }
6574 Operator::I8x16GeS => {
6575 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6576 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6577 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6578 let res = err!(
6579 self.builder
6580 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6581 );
6582 let res = err!(
6583 self.builder
6584 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6585 );
6586 let res = err!(
6587 self.builder
6588 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6589 );
6590 self.state.push1(res);
6591 }
6592 Operator::I16x8GeS => {
6593 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6594 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6595 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6596 let res = err!(
6597 self.builder
6598 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6599 );
6600 let res = err!(
6601 self.builder
6602 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6603 );
6604 let res = err!(
6605 self.builder
6606 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6607 );
6608 self.state.push1(res);
6609 }
6610 Operator::I32x4GeS => {
6611 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6612 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6613 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6614 let res = err!(
6615 self.builder
6616 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6617 );
6618 let res = err!(
6619 self.builder
6620 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6621 );
6622 let res = err!(
6623 self.builder
6624 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6625 );
6626 self.state.push1(res);
6627 }
6628 Operator::I64x2GeS => {
6629 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6630 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6631 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6632 let res = err!(
6633 self.builder
6634 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6635 );
6636 let res = err!(
6637 self.builder
6638 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6639 );
6640 let res = err!(
6641 self.builder
6642 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6643 );
6644 self.state.push1(res);
6645 }
6646 Operator::I32GeU | Operator::I64GeU => {
6647 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6648 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6649 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6650 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6651 let cond = err!(
6652 self.builder
6653 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6654 );
6655 let res = err!(
6656 self.builder
6657 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6658 );
6659 self.state.push1_extra(
6660 res,
6661 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6662 );
6663 }
6664 Operator::I8x16GeU => {
6665 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6666 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6667 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6668 let res = err!(
6669 self.builder
6670 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6671 );
6672 let res = err!(
6673 self.builder
6674 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6675 );
6676 let res = err!(
6677 self.builder
6678 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6679 );
6680 self.state.push1(res);
6681 }
6682 Operator::I16x8GeU => {
6683 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6684 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6685 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6686 let res = err!(
6687 self.builder
6688 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6689 );
6690 let res = err!(
6691 self.builder
6692 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6693 );
6694 let res = err!(
6695 self.builder
6696 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6697 );
6698 self.state.push1(res);
6699 }
6700 Operator::I32x4GeU => {
6701 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6702 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6703 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6704 let res = err!(
6705 self.builder
6706 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6707 );
6708 let res = err!(
6709 self.builder
6710 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6711 );
6712 let res = err!(
6713 self.builder
6714 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6715 );
6716 self.state.push1(res);
6717 }
6718
6719 Operator::F32Eq | Operator::F64Eq => {
6724 let (v1, v2) = self.state.pop2()?;
6725 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6726 let cond = err!(
6727 self.builder
6728 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6729 );
6730 let res = err!(
6731 self.builder
6732 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6733 );
6734 self.state.push1_extra(
6735 res,
6736 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6737 );
6738 }
6739 Operator::F32x4Eq => {
6740 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6741 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6742 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6743 let res = err!(
6744 self.builder
6745 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6746 );
6747 let res = err!(
6748 self.builder
6749 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6750 );
6751 let res = err!(
6752 self.builder
6753 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6754 );
6755 self.state.push1(res);
6756 }
6757 Operator::F64x2Eq => {
6758 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6759 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6760 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6761 let res = err!(
6762 self.builder
6763 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6764 );
6765 let res = err!(
6766 self.builder
6767 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6768 );
6769 let res = err!(
6770 self.builder
6771 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6772 );
6773 self.state.push1(res);
6774 }
6775 Operator::F32Ne | Operator::F64Ne => {
6776 let (v1, v2) = self.state.pop2()?;
6777 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6778 let cond = err!(
6779 self.builder
6780 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6781 );
6782 let res = err!(
6783 self.builder
6784 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6785 );
6786 self.state.push1_extra(
6787 res,
6788 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6789 );
6790 }
6791 Operator::F32x4Ne => {
6792 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6793 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6794 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6795 let res = err!(
6796 self.builder
6797 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6798 );
6799 let res = err!(
6800 self.builder
6801 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6802 );
6803 let res = err!(
6804 self.builder
6805 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6806 );
6807 self.state.push1(res);
6808 }
6809 Operator::F64x2Ne => {
6810 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6811 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6812 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6813 let res = err!(
6814 self.builder
6815 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6816 );
6817 let res = err!(
6818 self.builder
6819 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6820 );
6821 let res = err!(
6822 self.builder
6823 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6824 );
6825 self.state.push1(res);
6826 }
6827 Operator::F32Lt | Operator::F64Lt => {
6828 let (v1, v2) = self.state.pop2()?;
6829 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6830 let cond = err!(
6831 self.builder
6832 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6833 );
6834 let res = err!(
6835 self.builder
6836 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6837 );
6838 self.state.push1_extra(
6839 res,
6840 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6841 );
6842 }
6843 Operator::F32x4Lt => {
6844 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6845 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6846 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6847 let res = err!(
6848 self.builder
6849 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6850 );
6851 let res = err!(
6852 self.builder
6853 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6854 );
6855 let res = err!(
6856 self.builder
6857 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6858 );
6859 self.state.push1(res);
6860 }
6861 Operator::F64x2Lt => {
6862 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6863 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6864 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6865 let res = err!(
6866 self.builder
6867 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6868 );
6869 let res = err!(
6870 self.builder
6871 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6872 );
6873 let res = err!(
6874 self.builder
6875 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6876 );
6877 self.state.push1(res);
6878 }
6879 Operator::F32Le | Operator::F64Le => {
6880 let (v1, v2) = self.state.pop2()?;
6881 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6882 let cond = err!(
6883 self.builder
6884 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6885 );
6886 let res = err!(
6887 self.builder
6888 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6889 );
6890 self.state.push1_extra(
6891 res,
6892 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6893 );
6894 }
6895 Operator::F32x4Le => {
6896 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6897 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6898 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6899 let res = err!(
6900 self.builder
6901 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6902 );
6903 let res = err!(
6904 self.builder
6905 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6906 );
6907 let res = err!(
6908 self.builder
6909 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6910 );
6911 self.state.push1(res);
6912 }
6913 Operator::F64x2Le => {
6914 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6915 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6916 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6917 let res = err!(
6918 self.builder
6919 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6920 );
6921 let res = err!(
6922 self.builder
6923 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6924 );
6925 let res = err!(
6926 self.builder
6927 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6928 );
6929 self.state.push1(res);
6930 }
6931 Operator::F32Gt | Operator::F64Gt => {
6932 let (v1, v2) = self.state.pop2()?;
6933 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6934 let cond = err!(
6935 self.builder
6936 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6937 );
6938 let res = err!(
6939 self.builder
6940 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6941 );
6942 self.state.push1_extra(
6943 res,
6944 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6945 );
6946 }
6947 Operator::F32x4Gt => {
6948 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6949 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6950 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6951 let res = err!(
6952 self.builder
6953 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6954 );
6955 let res = err!(
6956 self.builder
6957 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6958 );
6959 let res = err!(
6960 self.builder
6961 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6962 );
6963 self.state.push1(res);
6964 }
6965 Operator::F64x2Gt => {
6966 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6967 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6968 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6969 let res = err!(
6970 self.builder
6971 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6972 );
6973 let res = err!(
6974 self.builder
6975 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6976 );
6977 let res = err!(
6978 self.builder
6979 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6980 );
6981 self.state.push1(res);
6982 }
6983 Operator::F32Ge | Operator::F64Ge => {
6984 let (v1, v2) = self.state.pop2()?;
6985 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6986 let cond = err!(
6987 self.builder
6988 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
6989 );
6990 let res = err!(
6991 self.builder
6992 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6993 );
6994 self.state.push1_extra(
6995 res,
6996 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6997 );
6998 }
6999 Operator::F32x4Ge => {
7000 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7001 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7002 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7003 let res = err!(
7004 self.builder
7005 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7006 );
7007 let res = err!(
7008 self.builder
7009 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7010 );
7011 let res = err!(
7012 self.builder
7013 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7014 );
7015 self.state.push1(res);
7016 }
7017 Operator::F64x2Ge => {
7018 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7019 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7020 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7021 let res = err!(
7022 self.builder
7023 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7024 );
7025 let res = err!(
7026 self.builder
7027 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7028 );
7029 let res = err!(
7030 self.builder
7031 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7032 );
7033 self.state.push1(res);
7034 }
7035
7036 Operator::I32WrapI64 => {
7041 let (v, i) = self.state.pop1_extra()?;
7042 let v = self.apply_pending_canonicalization(v, i)?;
7043 let v = v.into_int_value();
7044 let res = err!(
7045 self.builder
7046 .build_int_truncate(v, self.intrinsics.i32_ty, "")
7047 );
7048 self.state.push1(res);
7049 }
7050 Operator::I64ExtendI32S => {
7051 let (v, i) = self.state.pop1_extra()?;
7052 let v = self.apply_pending_canonicalization(v, i)?;
7053 let v = v.into_int_value();
7054 let res = err!(
7055 self.builder
7056 .build_int_s_extend(v, self.intrinsics.i64_ty, "")
7057 );
7058 self.state.push1(res);
7059 }
7060 Operator::I64ExtendI32U => {
7061 let (v, i) = self.state.pop1_extra()?;
7062 let v = self.apply_pending_canonicalization(v, i)?;
7063 let v = v.into_int_value();
7064 let res = err!(
7065 self.builder
7066 .build_int_z_extend(v, self.intrinsics.i64_ty, "")
7067 );
7068 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
7069 }
7070 Operator::I16x8ExtendLowI8x16S => {
7071 let (v, i) = self.state.pop1_extra()?;
7072 let (v, _) = self.v128_into_i8x16(v, i)?;
7073 let low = err!(self.builder.build_shuffle_vector(
7074 v,
7075 v.get_type().get_undef(),
7076 VectorType::const_vector(&[
7077 self.intrinsics.i32_consts[0],
7078 self.intrinsics.i32_consts[1],
7079 self.intrinsics.i32_consts[2],
7080 self.intrinsics.i32_consts[3],
7081 self.intrinsics.i32_consts[4],
7082 self.intrinsics.i32_consts[5],
7083 self.intrinsics.i32_consts[6],
7084 self.intrinsics.i32_consts[7],
7085 ]),
7086 "",
7087 ));
7088 let res = err!(
7089 self.builder
7090 .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7091 );
7092 let res = err!(
7093 self.builder
7094 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7095 );
7096 self.state.push1(res);
7097 }
7098 Operator::I16x8ExtendHighI8x16S => {
7099 let (v, i) = self.state.pop1_extra()?;
7100 let (v, _) = self.v128_into_i8x16(v, i)?;
7101 let low = err!(self.builder.build_shuffle_vector(
7102 v,
7103 v.get_type().get_undef(),
7104 VectorType::const_vector(&[
7105 self.intrinsics.i32_consts[8],
7106 self.intrinsics.i32_consts[9],
7107 self.intrinsics.i32_consts[10],
7108 self.intrinsics.i32_consts[11],
7109 self.intrinsics.i32_consts[12],
7110 self.intrinsics.i32_consts[13],
7111 self.intrinsics.i32_consts[14],
7112 self.intrinsics.i32_consts[15],
7113 ]),
7114 "",
7115 ));
7116 let res = err!(
7117 self.builder
7118 .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7119 );
7120 let res = err!(
7121 self.builder
7122 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7123 );
7124 self.state.push1(res);
7125 }
7126 Operator::I16x8ExtendLowI8x16U => {
7127 let (v, i) = self.state.pop1_extra()?;
7128 let (v, _) = self.v128_into_i8x16(v, i)?;
7129 let low = err!(self.builder.build_shuffle_vector(
7130 v,
7131 v.get_type().get_undef(),
7132 VectorType::const_vector(&[
7133 self.intrinsics.i32_consts[0],
7134 self.intrinsics.i32_consts[1],
7135 self.intrinsics.i32_consts[2],
7136 self.intrinsics.i32_consts[3],
7137 self.intrinsics.i32_consts[4],
7138 self.intrinsics.i32_consts[5],
7139 self.intrinsics.i32_consts[6],
7140 self.intrinsics.i32_consts[7],
7141 ]),
7142 "",
7143 ));
7144 let res = err!(
7145 self.builder
7146 .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7147 );
7148 let res = err!(
7149 self.builder
7150 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7151 );
7152 self.state.push1(res);
7153 }
7154 Operator::I16x8ExtendHighI8x16U => {
7155 let (v, i) = self.state.pop1_extra()?;
7156 let (v, _) = self.v128_into_i8x16(v, i)?;
7157 let low = err!(self.builder.build_shuffle_vector(
7158 v,
7159 v.get_type().get_undef(),
7160 VectorType::const_vector(&[
7161 self.intrinsics.i32_consts[8],
7162 self.intrinsics.i32_consts[9],
7163 self.intrinsics.i32_consts[10],
7164 self.intrinsics.i32_consts[11],
7165 self.intrinsics.i32_consts[12],
7166 self.intrinsics.i32_consts[13],
7167 self.intrinsics.i32_consts[14],
7168 self.intrinsics.i32_consts[15],
7169 ]),
7170 "",
7171 ));
7172 let res = err!(
7173 self.builder
7174 .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7175 );
7176 let res = err!(
7177 self.builder
7178 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7179 );
7180 self.state.push1(res);
7181 }
7182 Operator::I32x4ExtendLowI16x8S => {
7183 let (v, i) = self.state.pop1_extra()?;
7184 let (v, _) = self.v128_into_i16x8(v, i)?;
7185 let low = err!(self.builder.build_shuffle_vector(
7186 v,
7187 v.get_type().get_undef(),
7188 VectorType::const_vector(&[
7189 self.intrinsics.i32_consts[0],
7190 self.intrinsics.i32_consts[1],
7191 self.intrinsics.i32_consts[2],
7192 self.intrinsics.i32_consts[3],
7193 ]),
7194 "",
7195 ));
7196 let res = err!(
7197 self.builder
7198 .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7199 );
7200 let res = err!(
7201 self.builder
7202 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7203 );
7204 self.state.push1(res);
7205 }
7206 Operator::I32x4ExtendHighI16x8S => {
7207 let (v, i) = self.state.pop1_extra()?;
7208 let (v, _) = self.v128_into_i16x8(v, i)?;
7209 let low = err!(self.builder.build_shuffle_vector(
7210 v,
7211 v.get_type().get_undef(),
7212 VectorType::const_vector(&[
7213 self.intrinsics.i32_consts[4],
7214 self.intrinsics.i32_consts[5],
7215 self.intrinsics.i32_consts[6],
7216 self.intrinsics.i32_consts[7],
7217 ]),
7218 "",
7219 ));
7220 let res = err!(
7221 self.builder
7222 .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7223 );
7224 let res = err!(
7225 self.builder
7226 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7227 );
7228 self.state.push1(res);
7229 }
7230 Operator::I32x4ExtendLowI16x8U => {
7231 let (v, i) = self.state.pop1_extra()?;
7232 let (v, _) = self.v128_into_i16x8(v, i)?;
7233 let low = err!(self.builder.build_shuffle_vector(
7234 v,
7235 v.get_type().get_undef(),
7236 VectorType::const_vector(&[
7237 self.intrinsics.i32_consts[0],
7238 self.intrinsics.i32_consts[1],
7239 self.intrinsics.i32_consts[2],
7240 self.intrinsics.i32_consts[3],
7241 ]),
7242 "",
7243 ));
7244 let res = err!(
7245 self.builder
7246 .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7247 );
7248 let res = err!(
7249 self.builder
7250 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7251 );
7252 self.state.push1(res);
7253 }
7254 Operator::I32x4ExtendHighI16x8U => {
7255 let (v, i) = self.state.pop1_extra()?;
7256 let (v, _) = self.v128_into_i16x8(v, i)?;
7257 let low = err!(self.builder.build_shuffle_vector(
7258 v,
7259 v.get_type().get_undef(),
7260 VectorType::const_vector(&[
7261 self.intrinsics.i32_consts[4],
7262 self.intrinsics.i32_consts[5],
7263 self.intrinsics.i32_consts[6],
7264 self.intrinsics.i32_consts[7],
7265 ]),
7266 "",
7267 ));
7268 let res = err!(
7269 self.builder
7270 .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7271 );
7272 let res = err!(
7273 self.builder
7274 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7275 );
7276 self.state.push1(res);
7277 }
7278 Operator::I64x2ExtendLowI32x4U
7279 | Operator::I64x2ExtendLowI32x4S
7280 | Operator::I64x2ExtendHighI32x4U
7281 | Operator::I64x2ExtendHighI32x4S => {
7282 let extend = match op {
7283 Operator::I64x2ExtendLowI32x4U | Operator::I64x2ExtendHighI32x4U => {
7284 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
7285 }
7286 Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendHighI32x4S => {
7287 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
7288 }
7289 _ => unreachable!("Unhandled inner case"),
7290 };
7291 let indices = match op {
7292 Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendLowI32x4U => {
7293 [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[1]]
7294 }
7295 Operator::I64x2ExtendHighI32x4S | Operator::I64x2ExtendHighI32x4U => {
7296 [self.intrinsics.i32_consts[2], self.intrinsics.i32_consts[3]]
7297 }
7298 _ => unreachable!("Unhandled inner case"),
7299 };
7300 let (v, i) = self.state.pop1_extra()?;
7301 let (v, _) = self.v128_into_i32x4(v, i)?;
7302 let low = err!(self.builder.build_shuffle_vector(
7303 v,
7304 v.get_type().get_undef(),
7305 VectorType::const_vector(&indices),
7306 "",
7307 ));
7308 let res = err!(extend(self, low));
7309 let res = err!(
7310 self.builder
7311 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7312 );
7313 self.state.push1(res);
7314 }
7315 Operator::I8x16NarrowI16x8S => {
7316 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7317 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7318 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7319 let min = self.intrinsics.i16_ty.const_int(0xff80, false);
7320 let max = self.intrinsics.i16_ty.const_int(0x007f, false);
7321 let min = VectorType::const_vector(&[min; 8]);
7322 let max = VectorType::const_vector(&[max; 8]);
7323 let apply_min_clamp_v1 =
7324 err!(
7325 self.builder
7326 .build_int_compare(IntPredicate::SLT, v1, min, "")
7327 );
7328 let apply_max_clamp_v1 =
7329 err!(
7330 self.builder
7331 .build_int_compare(IntPredicate::SGT, v1, max, "")
7332 );
7333 let apply_min_clamp_v2 =
7334 err!(
7335 self.builder
7336 .build_int_compare(IntPredicate::SLT, v2, min, "")
7337 );
7338 let apply_max_clamp_v2 =
7339 err!(
7340 self.builder
7341 .build_int_compare(IntPredicate::SGT, v2, max, "")
7342 );
7343 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7344 .into_vector_value();
7345 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7346 .into_vector_value();
7347 let v1 = err!(self.builder.build_int_truncate(
7348 v1,
7349 self.intrinsics.i8_ty.vec_type(8),
7350 ""
7351 ));
7352 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7353 .into_vector_value();
7354 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7355 .into_vector_value();
7356 let v2 = err!(self.builder.build_int_truncate(
7357 v2,
7358 self.intrinsics.i8_ty.vec_type(8),
7359 ""
7360 ));
7361 let res = err!(self.builder.build_shuffle_vector(
7362 v1,
7363 v2,
7364 VectorType::const_vector(&[
7365 self.intrinsics.i32_consts[0],
7366 self.intrinsics.i32_consts[1],
7367 self.intrinsics.i32_consts[2],
7368 self.intrinsics.i32_consts[3],
7369 self.intrinsics.i32_consts[4],
7370 self.intrinsics.i32_consts[5],
7371 self.intrinsics.i32_consts[6],
7372 self.intrinsics.i32_consts[7],
7373 self.intrinsics.i32_consts[8],
7374 self.intrinsics.i32_consts[9],
7375 self.intrinsics.i32_consts[10],
7376 self.intrinsics.i32_consts[11],
7377 self.intrinsics.i32_consts[12],
7378 self.intrinsics.i32_consts[13],
7379 self.intrinsics.i32_consts[14],
7380 self.intrinsics.i32_consts[15],
7381 ]),
7382 "",
7383 ));
7384 let res = err!(
7385 self.builder
7386 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7387 );
7388 self.state.push1(res);
7389 }
7390 Operator::I8x16NarrowI16x8U => {
7391 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7392 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7393 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7394 let min = self.intrinsics.i16x8_ty.const_zero();
7395 let max = self.intrinsics.i16_ty.const_int(0x00ff, false);
7396 let max = VectorType::const_vector(&[max; 8]);
7397 let apply_min_clamp_v1 =
7398 err!(
7399 self.builder
7400 .build_int_compare(IntPredicate::SLT, v1, min, "")
7401 );
7402 let apply_max_clamp_v1 =
7403 err!(
7404 self.builder
7405 .build_int_compare(IntPredicate::SGT, v1, max, "")
7406 );
7407 let apply_min_clamp_v2 =
7408 err!(
7409 self.builder
7410 .build_int_compare(IntPredicate::SLT, v2, min, "")
7411 );
7412 let apply_max_clamp_v2 =
7413 err!(
7414 self.builder
7415 .build_int_compare(IntPredicate::SGT, v2, max, "")
7416 );
7417 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7418 .into_vector_value();
7419 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7420 .into_vector_value();
7421 let v1 = err!(self.builder.build_int_truncate(
7422 v1,
7423 self.intrinsics.i8_ty.vec_type(8),
7424 ""
7425 ));
7426 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7427 .into_vector_value();
7428 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7429 .into_vector_value();
7430 let v2 = err!(self.builder.build_int_truncate(
7431 v2,
7432 self.intrinsics.i8_ty.vec_type(8),
7433 ""
7434 ));
7435 let res = err!(self.builder.build_shuffle_vector(
7436 v1,
7437 v2,
7438 VectorType::const_vector(&[
7439 self.intrinsics.i32_consts[0],
7440 self.intrinsics.i32_consts[1],
7441 self.intrinsics.i32_consts[2],
7442 self.intrinsics.i32_consts[3],
7443 self.intrinsics.i32_consts[4],
7444 self.intrinsics.i32_consts[5],
7445 self.intrinsics.i32_consts[6],
7446 self.intrinsics.i32_consts[7],
7447 self.intrinsics.i32_consts[8],
7448 self.intrinsics.i32_consts[9],
7449 self.intrinsics.i32_consts[10],
7450 self.intrinsics.i32_consts[11],
7451 self.intrinsics.i32_consts[12],
7452 self.intrinsics.i32_consts[13],
7453 self.intrinsics.i32_consts[14],
7454 self.intrinsics.i32_consts[15],
7455 ]),
7456 "",
7457 ));
7458 let res = err!(
7459 self.builder
7460 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7461 );
7462 self.state.push1(res);
7463 }
7464 Operator::I16x8NarrowI32x4S => {
7465 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7466 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7467 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7468 let min = self.intrinsics.i32_ty.const_int(0xffff8000, false);
7469 let max = self.intrinsics.i32_ty.const_int(0x00007fff, false);
7470 let min = VectorType::const_vector(&[min; 4]);
7471 let max = VectorType::const_vector(&[max; 4]);
7472 let apply_min_clamp_v1 =
7473 err!(
7474 self.builder
7475 .build_int_compare(IntPredicate::SLT, v1, min, "")
7476 );
7477 let apply_max_clamp_v1 =
7478 err!(
7479 self.builder
7480 .build_int_compare(IntPredicate::SGT, v1, max, "")
7481 );
7482 let apply_min_clamp_v2 =
7483 err!(
7484 self.builder
7485 .build_int_compare(IntPredicate::SLT, v2, min, "")
7486 );
7487 let apply_max_clamp_v2 =
7488 err!(
7489 self.builder
7490 .build_int_compare(IntPredicate::SGT, v2, max, "")
7491 );
7492 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7493 .into_vector_value();
7494 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7495 .into_vector_value();
7496 let v1 = err!(self.builder.build_int_truncate(
7497 v1,
7498 self.intrinsics.i16_ty.vec_type(4),
7499 ""
7500 ));
7501 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7502 .into_vector_value();
7503 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7504 .into_vector_value();
7505 let v2 = err!(self.builder.build_int_truncate(
7506 v2,
7507 self.intrinsics.i16_ty.vec_type(4),
7508 ""
7509 ));
7510 let res = err!(self.builder.build_shuffle_vector(
7511 v1,
7512 v2,
7513 VectorType::const_vector(&[
7514 self.intrinsics.i32_consts[0],
7515 self.intrinsics.i32_consts[1],
7516 self.intrinsics.i32_consts[2],
7517 self.intrinsics.i32_consts[3],
7518 self.intrinsics.i32_consts[4],
7519 self.intrinsics.i32_consts[5],
7520 self.intrinsics.i32_consts[6],
7521 self.intrinsics.i32_consts[7],
7522 ]),
7523 "",
7524 ));
7525 let res = err!(
7526 self.builder
7527 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7528 );
7529 self.state.push1(res);
7530 }
7531 Operator::I16x8NarrowI32x4U => {
7532 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7533 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7534 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7535 let min = self.intrinsics.i32x4_ty.const_zero();
7536 let max = self.intrinsics.i32_ty.const_int(0xffff, false);
7537 let max = VectorType::const_vector(&[max; 4]);
7538 let apply_min_clamp_v1 =
7539 err!(
7540 self.builder
7541 .build_int_compare(IntPredicate::SLT, v1, min, "")
7542 );
7543 let apply_max_clamp_v1 =
7544 err!(
7545 self.builder
7546 .build_int_compare(IntPredicate::SGT, v1, max, "")
7547 );
7548 let apply_min_clamp_v2 =
7549 err!(
7550 self.builder
7551 .build_int_compare(IntPredicate::SLT, v2, min, "")
7552 );
7553 let apply_max_clamp_v2 =
7554 err!(
7555 self.builder
7556 .build_int_compare(IntPredicate::SGT, v2, max, "")
7557 );
7558 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7559 .into_vector_value();
7560 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7561 .into_vector_value();
7562 let v1 = err!(self.builder.build_int_truncate(
7563 v1,
7564 self.intrinsics.i16_ty.vec_type(4),
7565 ""
7566 ));
7567 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7568 .into_vector_value();
7569 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7570 .into_vector_value();
7571 let v2 = err!(self.builder.build_int_truncate(
7572 v2,
7573 self.intrinsics.i16_ty.vec_type(4),
7574 ""
7575 ));
7576 let res = err!(self.builder.build_shuffle_vector(
7577 v1,
7578 v2,
7579 VectorType::const_vector(&[
7580 self.intrinsics.i32_consts[0],
7581 self.intrinsics.i32_consts[1],
7582 self.intrinsics.i32_consts[2],
7583 self.intrinsics.i32_consts[3],
7584 self.intrinsics.i32_consts[4],
7585 self.intrinsics.i32_consts[5],
7586 self.intrinsics.i32_consts[6],
7587 self.intrinsics.i32_consts[7],
7588 ]),
7589 "",
7590 ));
7591 let res = err!(
7592 self.builder
7593 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7594 );
7595 self.state.push1(res);
7596 }
7597 Operator::I32x4TruncSatF32x4S => {
7598 let (v, i) = self.state.pop1_extra()?;
7599 let v = self.apply_pending_canonicalization(v, i)?;
7600 let v = v.into_int_value();
7601 let res = self.trunc_sat_into_int(
7602 self.intrinsics.f32x4_ty,
7603 self.intrinsics.i32x4_ty,
7604 LEF32_GEQ_I32_MIN,
7605 GEF32_LEQ_I32_MAX,
7606 i32::MIN as u64,
7607 i32::MAX as u64,
7608 v,
7609 )?;
7610 self.state.push1(res);
7611 }
7612 Operator::I32x4TruncSatF32x4U => {
7613 let (v, i) = self.state.pop1_extra()?;
7614 let v = self.apply_pending_canonicalization(v, i)?;
7615 let v = v.into_int_value();
7616 let res = self.trunc_sat_into_int(
7617 self.intrinsics.f32x4_ty,
7618 self.intrinsics.i32x4_ty,
7619 LEF32_GEQ_U32_MIN,
7620 GEF32_LEQ_U32_MAX,
7621 u32::MIN as u64,
7622 u32::MAX as u64,
7623 v,
7624 )?;
7625 self.state.push1(res);
7626 }
7627 Operator::I32x4TruncSatF64x2SZero | Operator::I32x4TruncSatF64x2UZero => {
7628 let ((min, max), (cmp_min, cmp_max)) = match op {
7629 Operator::I32x4TruncSatF64x2SZero => (
7630 (i32::MIN as u64, i32::MAX as u64),
7631 (LEF64_GEQ_I32_MIN, GEF64_LEQ_I32_MAX),
7632 ),
7633 Operator::I32x4TruncSatF64x2UZero => (
7634 (u32::MIN as u64, u32::MAX as u64),
7635 (LEF64_GEQ_U32_MIN, GEF64_LEQ_U32_MAX),
7636 ),
7637 _ => unreachable!("Unhandled internal variant"),
7638 };
7639 let (v, i) = self.state.pop1_extra()?;
7640 let v = self.apply_pending_canonicalization(v, i)?;
7641 let v = v.into_int_value();
7642 let res = self.trunc_sat(
7643 self.intrinsics.f64x2_ty,
7644 self.intrinsics.i32_ty.vec_type(2),
7645 cmp_min,
7646 cmp_max,
7647 min,
7648 max,
7649 v,
7650 )?;
7651
7652 let zero = self.intrinsics.i32_consts[0];
7653 let zeros = VectorType::const_vector(&[zero; 2]);
7654 let res = err!(self.builder.build_shuffle_vector(
7655 res,
7656 zeros,
7657 VectorType::const_vector(&[
7658 self.intrinsics.i32_consts[0],
7659 self.intrinsics.i32_consts[1],
7660 self.intrinsics.i32_consts[2],
7661 self.intrinsics.i32_consts[3],
7662 ]),
7663 "",
7664 ));
7665 let res = err!(
7666 self.builder
7667 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7668 );
7669 self.state.push1(res);
7670 }
7671 Operator::I32TruncF32S => {
7702 let v1 = self.state.pop1()?.into_float_value();
7703 self.trap_if_not_representable_as_int(
7704 0xcf000000, 0x4effffff, v1,
7707 )?;
7708 let res = err!(self.builder.build_float_to_signed_int(
7709 v1,
7710 self.intrinsics.i32_ty,
7711 ""
7712 ));
7713 self.state.push1(res);
7714 }
7715 Operator::I32TruncF64S => {
7716 let v1 = self.state.pop1()?.into_float_value();
7717 self.trap_if_not_representable_as_int(
7718 0xc1e00000001fffff, 0x41dfffffffffffff, v1,
7721 )?;
7722 let res = err!(self.builder.build_float_to_signed_int(
7723 v1,
7724 self.intrinsics.i32_ty,
7725 ""
7726 ));
7727 self.state.push1(res);
7728 }
7729 Operator::I32TruncSatF32S => {
7730 let (v, i) = self.state.pop1_extra()?;
7731 let v = self.apply_pending_canonicalization(v, i)?;
7732 let v = v.into_float_value();
7733 let res = self.trunc_sat_scalar(
7734 self.intrinsics.i32_ty,
7735 LEF32_GEQ_I32_MIN,
7736 GEF32_LEQ_I32_MAX,
7737 i32::MIN as u32 as u64,
7738 i32::MAX as u32 as u64,
7739 v,
7740 )?;
7741 self.state.push1(res);
7742 }
7743 Operator::I32TruncSatF64S => {
7744 let (v, i) = self.state.pop1_extra()?;
7745 let v = self.apply_pending_canonicalization(v, i)?;
7746 let v = v.into_float_value();
7747 let res = self.trunc_sat_scalar(
7748 self.intrinsics.i32_ty,
7749 LEF64_GEQ_I32_MIN,
7750 GEF64_LEQ_I32_MAX,
7751 i32::MIN as u64,
7752 i32::MAX as u64,
7753 v,
7754 )?;
7755 self.state.push1(res);
7756 }
7757 Operator::I64TruncF32S => {
7758 let v1 = self.state.pop1()?.into_float_value();
7759 self.trap_if_not_representable_as_int(
7760 0xdf000000, 0x5effffff, v1,
7763 )?;
7764 let res = err!(self.builder.build_float_to_signed_int(
7765 v1,
7766 self.intrinsics.i64_ty,
7767 ""
7768 ));
7769 self.state.push1(res);
7770 }
7771 Operator::I64TruncF64S => {
7772 let v1 = self.state.pop1()?.into_float_value();
7773 self.trap_if_not_representable_as_int(
7774 0xc3e0000000000000, 0x43dfffffffffffff, v1,
7777 )?;
7778 let res = err!(self.builder.build_float_to_signed_int(
7779 v1,
7780 self.intrinsics.i64_ty,
7781 ""
7782 ));
7783 self.state.push1(res);
7784 }
7785 Operator::I64TruncSatF32S => {
7786 let (v, i) = self.state.pop1_extra()?;
7787 let v = self.apply_pending_canonicalization(v, i)?;
7788 let v = v.into_float_value();
7789 let res = self.trunc_sat_scalar(
7790 self.intrinsics.i64_ty,
7791 LEF32_GEQ_I64_MIN,
7792 GEF32_LEQ_I64_MAX,
7793 i64::MIN as u64,
7794 i64::MAX as u64,
7795 v,
7796 )?;
7797 self.state.push1(res);
7798 }
7799 Operator::I64TruncSatF64S => {
7800 let (v, i) = self.state.pop1_extra()?;
7801 let v = self.apply_pending_canonicalization(v, i)?;
7802 let v = v.into_float_value();
7803 let res = self.trunc_sat_scalar(
7804 self.intrinsics.i64_ty,
7805 LEF64_GEQ_I64_MIN,
7806 GEF64_LEQ_I64_MAX,
7807 i64::MIN as u64,
7808 i64::MAX as u64,
7809 v,
7810 )?;
7811 self.state.push1(res);
7812 }
7813 Operator::I32TruncF32U => {
7814 let v1 = self.state.pop1()?.into_float_value();
7815 self.trap_if_not_representable_as_int(
7816 0xbf7fffff, 0x4f7fffff, v1,
7819 )?;
7820 let res = err!(self.builder.build_float_to_unsigned_int(
7821 v1,
7822 self.intrinsics.i32_ty,
7823 ""
7824 ));
7825 self.state.push1(res);
7826 }
7827 Operator::I32TruncF64U => {
7828 let v1 = self.state.pop1()?.into_float_value();
7829 self.trap_if_not_representable_as_int(
7830 0xbfefffffffffffff, 0x41efffffffffffff, v1,
7833 )?;
7834 let res = err!(self.builder.build_float_to_unsigned_int(
7835 v1,
7836 self.intrinsics.i32_ty,
7837 ""
7838 ));
7839 self.state.push1(res);
7840 }
7841 Operator::I32TruncSatF32U => {
7842 let (v, i) = self.state.pop1_extra()?;
7843 let v = self.apply_pending_canonicalization(v, i)?;
7844 let v = v.into_float_value();
7845 let res = self.trunc_sat_scalar(
7846 self.intrinsics.i32_ty,
7847 LEF32_GEQ_U32_MIN,
7848 GEF32_LEQ_U32_MAX,
7849 u32::MIN as u64,
7850 u32::MAX as u64,
7851 v,
7852 )?;
7853 self.state.push1(res);
7854 }
7855 Operator::I32TruncSatF64U => {
7856 let (v, i) = self.state.pop1_extra()?;
7857 let v = self.apply_pending_canonicalization(v, i)?;
7858 let v = v.into_float_value();
7859 let res = self.trunc_sat_scalar(
7860 self.intrinsics.i32_ty,
7861 LEF64_GEQ_U32_MIN,
7862 GEF64_LEQ_U32_MAX,
7863 u32::MIN as u64,
7864 u32::MAX as u64,
7865 v,
7866 )?;
7867 self.state.push1(res);
7868 }
7869 Operator::I64TruncF32U => {
7870 let v1 = self.state.pop1()?.into_float_value();
7871 self.trap_if_not_representable_as_int(
7872 0xbf7fffff, 0x5f7fffff, v1,
7875 )?;
7876 let res = err!(self.builder.build_float_to_unsigned_int(
7877 v1,
7878 self.intrinsics.i64_ty,
7879 ""
7880 ));
7881 self.state.push1(res);
7882 }
7883 Operator::I64TruncF64U => {
7884 let v1 = self.state.pop1()?.into_float_value();
7885 self.trap_if_not_representable_as_int(
7886 0xbfefffffffffffff, 0x43efffffffffffff, v1,
7889 )?;
7890 let res = err!(self.builder.build_float_to_unsigned_int(
7891 v1,
7892 self.intrinsics.i64_ty,
7893 ""
7894 ));
7895 self.state.push1(res);
7896 }
7897 Operator::I64TruncSatF32U => {
7898 let (v, i) = self.state.pop1_extra()?;
7899 let v = self.apply_pending_canonicalization(v, i)?;
7900 let v = v.into_float_value();
7901 let res = self.trunc_sat_scalar(
7902 self.intrinsics.i64_ty,
7903 LEF32_GEQ_U64_MIN,
7904 GEF32_LEQ_U64_MAX,
7905 u64::MIN,
7906 u64::MAX,
7907 v,
7908 )?;
7909 self.state.push1(res);
7910 }
7911 Operator::I64TruncSatF64U => {
7912 let (v, i) = self.state.pop1_extra()?;
7913 let v = self.apply_pending_canonicalization(v, i)?;
7914 let v = v.into_float_value();
7915 let res = self.trunc_sat_scalar(
7916 self.intrinsics.i64_ty,
7917 LEF64_GEQ_U64_MIN,
7918 GEF64_LEQ_U64_MAX,
7919 u64::MIN,
7920 u64::MAX,
7921 v,
7922 )?;
7923 self.state.push1(res);
7924 }
7925 Operator::F32DemoteF64 => {
7926 let v = self.state.pop1()?;
7927 let v = v.into_float_value();
7928 let res = err!(self.builder.build_call(
7929 self.intrinsics.fptrunc_f64,
7930 &[
7931 v.into(),
7932 self.intrinsics.fp_rounding_md,
7933 self.intrinsics.fp_exception_md,
7934 ],
7935 "",
7936 ))
7937 .try_as_basic_value()
7938 .unwrap_basic();
7939 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
7940 }
7941 Operator::F64PromoteF32 => {
7942 let v = self.state.pop1()?;
7943 let v = v.into_float_value();
7944 let res = err!(self.builder.build_call(
7945 self.intrinsics.fpext_f32,
7946 &[v.into(), self.intrinsics.fp_exception_md],
7947 "",
7948 ))
7949 .try_as_basic_value()
7950 .unwrap_basic();
7951 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
7952 }
7953 Operator::F32ConvertI32S | Operator::F32ConvertI64S => {
7954 let (v, i) = self.state.pop1_extra()?;
7955 let v = self.apply_pending_canonicalization(v, i)?;
7956 let v = v.into_int_value();
7957 let res = err!(self.builder.build_signed_int_to_float(
7958 v,
7959 self.intrinsics.f32_ty,
7960 ""
7961 ));
7962 self.state.push1(res);
7963 }
7964 Operator::F64ConvertI32S | Operator::F64ConvertI64S => {
7965 let (v, i) = self.state.pop1_extra()?;
7966 let v = self.apply_pending_canonicalization(v, i)?;
7967 let v = v.into_int_value();
7968 let res = err!(self.builder.build_signed_int_to_float(
7969 v,
7970 self.intrinsics.f64_ty,
7971 ""
7972 ));
7973 self.state.push1(res);
7974 }
7975 Operator::F32ConvertI32U | Operator::F32ConvertI64U => {
7976 let (v, i) = self.state.pop1_extra()?;
7977 let v = self.apply_pending_canonicalization(v, i)?;
7978 let v = v.into_int_value();
7979 let res = err!(self.builder.build_unsigned_int_to_float(
7980 v,
7981 self.intrinsics.f32_ty,
7982 ""
7983 ));
7984 self.state.push1(res);
7985 }
7986 Operator::F64ConvertI32U | Operator::F64ConvertI64U => {
7987 let (v, i) = self.state.pop1_extra()?;
7988 let v = self.apply_pending_canonicalization(v, i)?;
7989 let v = v.into_int_value();
7990 let res = err!(self.builder.build_unsigned_int_to_float(
7991 v,
7992 self.intrinsics.f64_ty,
7993 ""
7994 ));
7995 self.state.push1(res);
7996 }
7997 Operator::F32x4ConvertI32x4S => {
7998 let v = self.state.pop1()?;
7999 let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8000 .into_vector_value();
8001 let res = err!(self.builder.build_signed_int_to_float(
8002 v,
8003 self.intrinsics.f32x4_ty,
8004 ""
8005 ));
8006 let res = err!(
8007 self.builder
8008 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8009 );
8010 self.state.push1(res);
8011 }
8012 Operator::F32x4ConvertI32x4U => {
8013 let v = self.state.pop1()?;
8014 let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8015 .into_vector_value();
8016 let res = err!(self.builder.build_unsigned_int_to_float(
8017 v,
8018 self.intrinsics.f32x4_ty,
8019 ""
8020 ));
8021 let res = err!(
8022 self.builder
8023 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8024 );
8025 self.state.push1(res);
8026 }
8027 Operator::F64x2ConvertLowI32x4S | Operator::F64x2ConvertLowI32x4U => {
8028 let extend = match op {
8029 Operator::F64x2ConvertLowI32x4U => {
8030 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8031 }
8032 Operator::F64x2ConvertLowI32x4S => {
8033 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8034 }
8035 _ => unreachable!("Unhandled inner case"),
8036 };
8037 let (v, i) = self.state.pop1_extra()?;
8038 let (v, _) = self.v128_into_i32x4(v, i)?;
8039 let low = err!(self.builder.build_shuffle_vector(
8040 v,
8041 v.get_type().get_undef(),
8042 VectorType::const_vector(&[
8043 self.intrinsics.i32_consts[0],
8044 self.intrinsics.i32_consts[1],
8045 ]),
8046 "",
8047 ));
8048 let res = err!(extend(self, low));
8049 let res = err!(self.builder.build_signed_int_to_float(
8050 res,
8051 self.intrinsics.f64x2_ty,
8052 ""
8053 ));
8054 let res = err!(
8055 self.builder
8056 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8057 );
8058 self.state.push1(res);
8059 }
8060 Operator::F64x2PromoteLowF32x4 => {
8061 let (v, i) = self.state.pop1_extra()?;
8062 let (v, _) = self.v128_into_f32x4(v, i)?;
8063 let low = err!(self.builder.build_shuffle_vector(
8064 v,
8065 v.get_type().get_undef(),
8066 VectorType::const_vector(&[
8067 self.intrinsics.i32_consts[0],
8068 self.intrinsics.i32_consts[1],
8069 ]),
8070 "",
8071 ));
8072 let res = err!(
8073 self.builder
8074 .build_float_ext(low, self.intrinsics.f64x2_ty, "")
8075 );
8076 let res = err!(
8077 self.builder
8078 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8079 );
8080 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8081 }
8082 Operator::F32x4DemoteF64x2Zero => {
8083 let (v, i) = self.state.pop1_extra()?;
8084 let (v, _) = self.v128_into_f64x2(v, i)?;
8085 let f32x2_ty = self.intrinsics.f32_ty.vec_type(2);
8086 let res = err!(self.builder.build_float_trunc(v, f32x2_ty, ""));
8087 let zeros = f32x2_ty.const_zero();
8088 let res = err!(self.builder.build_shuffle_vector(
8089 res,
8090 zeros,
8091 VectorType::const_vector(&[
8092 self.intrinsics.i32_consts[0],
8093 self.intrinsics.i32_consts[1],
8094 self.intrinsics.i32_consts[2],
8095 self.intrinsics.i32_consts[3],
8096 ]),
8097 "",
8098 ));
8099 let res = err!(
8100 self.builder
8101 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8102 );
8103 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8104 }
8105 Operator::I32ReinterpretF32 => {
8130 let (v, i) = self.state.pop1_extra()?;
8131 let v = self.apply_pending_canonicalization(v, i)?;
8132 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i32_ty, ""));
8133 self.state.push1_extra(ret, ExtraInfo::arithmetic_f32());
8134 }
8135 Operator::I64ReinterpretF64 => {
8136 let (v, i) = self.state.pop1_extra()?;
8137 let v = self.apply_pending_canonicalization(v, i)?;
8138 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i64_ty, ""));
8139 self.state.push1_extra(ret, ExtraInfo::arithmetic_f64());
8140 }
8141 Operator::F32ReinterpretI32 => {
8142 let (v, i) = self.state.pop1_extra()?;
8143 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f32_ty, ""));
8144 self.state.push1_extra(ret, i);
8145 }
8146 Operator::F64ReinterpretI64 => {
8147 let (v, i) = self.state.pop1_extra()?;
8148 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f64_ty, ""));
8149 self.state.push1_extra(ret, i);
8150 }
8151
8152 Operator::I32Extend8S => {
8157 let value = self.state.pop1()?.into_int_value();
8158 let narrow_value = err!(self.builder.build_int_truncate(
8159 value,
8160 self.intrinsics.i8_ty,
8161 ""
8162 ));
8163 let extended_value = err!(self.builder.build_int_s_extend(
8164 narrow_value,
8165 self.intrinsics.i32_ty,
8166 ""
8167 ));
8168 self.state.push1(extended_value);
8169 }
8170 Operator::I32Extend16S => {
8171 let value = self.state.pop1()?.into_int_value();
8172 let narrow_value = err!(self.builder.build_int_truncate(
8173 value,
8174 self.intrinsics.i16_ty,
8175 ""
8176 ));
8177 let extended_value = err!(self.builder.build_int_s_extend(
8178 narrow_value,
8179 self.intrinsics.i32_ty,
8180 ""
8181 ));
8182 self.state.push1(extended_value);
8183 }
8184 Operator::I64Extend8S => {
8185 let value = self.state.pop1()?.into_int_value();
8186 let narrow_value = err!(self.builder.build_int_truncate(
8187 value,
8188 self.intrinsics.i8_ty,
8189 ""
8190 ));
8191 let extended_value = err!(self.builder.build_int_s_extend(
8192 narrow_value,
8193 self.intrinsics.i64_ty,
8194 ""
8195 ));
8196 self.state.push1(extended_value);
8197 }
8198 Operator::I64Extend16S => {
8199 let value = self.state.pop1()?.into_int_value();
8200 let narrow_value = err!(self.builder.build_int_truncate(
8201 value,
8202 self.intrinsics.i16_ty,
8203 ""
8204 ));
8205 let extended_value = err!(self.builder.build_int_s_extend(
8206 narrow_value,
8207 self.intrinsics.i64_ty,
8208 ""
8209 ));
8210 self.state.push1(extended_value);
8211 }
8212 Operator::I64Extend32S => {
8213 let value = self.state.pop1()?.into_int_value();
8214 let narrow_value = err!(self.builder.build_int_truncate(
8215 value,
8216 self.intrinsics.i32_ty,
8217 ""
8218 ));
8219 let extended_value = err!(self.builder.build_int_s_extend(
8220 narrow_value,
8221 self.intrinsics.i64_ty,
8222 ""
8223 ));
8224 self.state.push1(extended_value);
8225 }
8226
8227 Operator::I32Load { ref memarg } => {
8232 let offset = self.state.pop1()?.into_int_value();
8233 let memory_index = MemoryIndex::from_u32(0);
8234 let effective_address = self.resolve_memory_ptr(
8235 memory_index,
8236 memarg,
8237 self.intrinsics.ptr_ty,
8238 offset,
8239 4,
8240 )?;
8241 let result = err!(self.builder.build_load(
8242 self.intrinsics.i32_ty,
8243 effective_address,
8244 ""
8245 ));
8246 self.annotate_user_memaccess(
8247 memory_index,
8248 memarg,
8249 1,
8250 result.as_instruction_value().unwrap(),
8251 )?;
8252 self.state.push1(result);
8253 }
8254 Operator::I64Load { ref memarg } => {
8255 let offset = self.state.pop1()?.into_int_value();
8256 let memory_index = MemoryIndex::from_u32(0);
8257 let effective_address = self.resolve_memory_ptr(
8258 memory_index,
8259 memarg,
8260 self.intrinsics.ptr_ty,
8261 offset,
8262 8,
8263 )?;
8264 let result = err!(self.builder.build_load(
8265 self.intrinsics.i64_ty,
8266 effective_address,
8267 ""
8268 ));
8269 self.annotate_user_memaccess(
8270 memory_index,
8271 memarg,
8272 1,
8273 result.as_instruction_value().unwrap(),
8274 )?;
8275 self.state.push1(result);
8276 }
8277 Operator::F32Load { ref memarg } => {
8278 let offset = self.state.pop1()?.into_int_value();
8279 let memory_index = MemoryIndex::from_u32(0);
8280 let effective_address = self.resolve_memory_ptr(
8281 memory_index,
8282 memarg,
8283 self.intrinsics.ptr_ty,
8284 offset,
8285 4,
8286 )?;
8287 let result = err!(self.builder.build_load(
8288 self.intrinsics.f32_ty,
8289 effective_address,
8290 ""
8291 ));
8292 self.annotate_user_memaccess(
8293 memory_index,
8294 memarg,
8295 1,
8296 result.as_instruction_value().unwrap(),
8297 )?;
8298 self.state.push1(result);
8299 }
8300 Operator::F64Load { ref memarg } => {
8301 let offset = self.state.pop1()?.into_int_value();
8302 let memory_index = MemoryIndex::from_u32(0);
8303 let effective_address = self.resolve_memory_ptr(
8304 memory_index,
8305 memarg,
8306 self.intrinsics.ptr_ty,
8307 offset,
8308 8,
8309 )?;
8310 let result = err!(self.builder.build_load(
8311 self.intrinsics.f64_ty,
8312 effective_address,
8313 ""
8314 ));
8315 self.annotate_user_memaccess(
8316 memory_index,
8317 memarg,
8318 1,
8319 result.as_instruction_value().unwrap(),
8320 )?;
8321 self.state.push1(result);
8322 }
8323 Operator::V128Load { ref memarg } => {
8324 let offset = self.state.pop1()?.into_int_value();
8325 let memory_index = MemoryIndex::from_u32(0);
8326 let effective_address = self.resolve_memory_ptr(
8327 memory_index,
8328 memarg,
8329 self.intrinsics.ptr_ty,
8330 offset,
8331 16,
8332 )?;
8333 let result = err!(self.builder.build_load(
8334 self.intrinsics.i128_ty,
8335 effective_address,
8336 ""
8337 ));
8338 self.annotate_user_memaccess(
8339 memory_index,
8340 memarg,
8341 1,
8342 result.as_instruction_value().unwrap(),
8343 )?;
8344 self.state.push1(result);
8345 }
8346 Operator::V128Load8Lane { ref memarg, lane } => {
8347 let (v, i) = self.state.pop1_extra()?;
8348 let (v, _i) = self.v128_into_i8x16(v, i)?;
8349 let offset = self.state.pop1()?.into_int_value();
8350 let memory_index = MemoryIndex::from_u32(memarg.memory);
8351 let effective_address = self.resolve_memory_ptr(
8352 memory_index,
8353 memarg,
8354 self.intrinsics.ptr_ty,
8355 offset,
8356 1,
8357 )?;
8358 let element = err!(self.builder.build_load(
8359 self.intrinsics.i8_ty,
8360 effective_address,
8361 ""
8362 ));
8363 self.annotate_user_memaccess(
8364 memory_index,
8365 memarg,
8366 1,
8367 element.as_instruction_value().unwrap(),
8368 )?;
8369 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8370 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8371 let res = err!(
8372 self.builder
8373 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8374 );
8375 self.state.push1(res);
8376 }
8377 Operator::V128Load16Lane { ref memarg, lane } => {
8378 let (v, i) = self.state.pop1_extra()?;
8379 let (v, i) = self.v128_into_i16x8(v, i)?;
8380 let offset = self.state.pop1()?.into_int_value();
8381 let memory_index = MemoryIndex::from_u32(memarg.memory);
8382 let effective_address = self.resolve_memory_ptr(
8383 memory_index,
8384 memarg,
8385 self.intrinsics.ptr_ty,
8386 offset,
8387 2,
8388 )?;
8389 let element = err!(self.builder.build_load(
8390 self.intrinsics.i16_ty,
8391 effective_address,
8392 ""
8393 ));
8394 self.annotate_user_memaccess(
8395 memory_index,
8396 memarg,
8397 1,
8398 element.as_instruction_value().unwrap(),
8399 )?;
8400 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8401 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8402 let res = err!(
8403 self.builder
8404 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8405 );
8406 self.state.push1_extra(res, i);
8407 }
8408 Operator::V128Load32Lane { ref memarg, lane } => {
8409 let (v, i) = self.state.pop1_extra()?;
8410 let (v, i) = self.v128_into_i32x4(v, i)?;
8411 let offset = self.state.pop1()?.into_int_value();
8412 let memory_index = MemoryIndex::from_u32(memarg.memory);
8413 let effective_address = self.resolve_memory_ptr(
8414 memory_index,
8415 memarg,
8416 self.intrinsics.ptr_ty,
8417 offset,
8418 4,
8419 )?;
8420 let element = err!(self.builder.build_load(
8421 self.intrinsics.i32_ty,
8422 effective_address,
8423 ""
8424 ));
8425 self.annotate_user_memaccess(
8426 memory_index,
8427 memarg,
8428 1,
8429 element.as_instruction_value().unwrap(),
8430 )?;
8431 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8432 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8433 let res = err!(
8434 self.builder
8435 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8436 );
8437 self.state.push1_extra(res, i);
8438 }
8439 Operator::V128Load64Lane { ref memarg, lane } => {
8440 let (v, i) = self.state.pop1_extra()?;
8441 let (v, i) = self.v128_into_i64x2(v, i)?;
8442 let offset = self.state.pop1()?.into_int_value();
8443 let memory_index = MemoryIndex::from_u32(memarg.memory);
8444 let effective_address = self.resolve_memory_ptr(
8445 memory_index,
8446 memarg,
8447 self.intrinsics.ptr_ty,
8448 offset,
8449 8,
8450 )?;
8451 let element = err!(self.builder.build_load(
8452 self.intrinsics.i64_ty,
8453 effective_address,
8454 ""
8455 ));
8456 self.annotate_user_memaccess(
8457 memory_index,
8458 memarg,
8459 1,
8460 element.as_instruction_value().unwrap(),
8461 )?;
8462 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8463 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8464 let res = err!(
8465 self.builder
8466 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8467 );
8468 self.state.push1_extra(res, i);
8469 }
8470
8471 Operator::I32Store { ref memarg } => {
8472 let value = self.state.pop1()?;
8473 let offset = self.state.pop1()?.into_int_value();
8474 let memory_index = MemoryIndex::from_u32(0);
8475 let effective_address = self.resolve_memory_ptr(
8476 memory_index,
8477 memarg,
8478 self.intrinsics.ptr_ty,
8479 offset,
8480 4,
8481 )?;
8482 let dead_load = err!(self.builder.build_load(
8483 self.intrinsics.i32_ty,
8484 effective_address,
8485 ""
8486 ));
8487 self.annotate_user_memaccess(
8488 memory_index,
8489 memarg,
8490 1,
8491 dead_load.as_instruction_value().unwrap(),
8492 )?;
8493 let store = err!(self.builder.build_store(effective_address, value));
8494 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8495 }
8496 Operator::I64Store { ref memarg } => {
8497 let value = self.state.pop1()?;
8498 let offset = self.state.pop1()?.into_int_value();
8499 let memory_index = MemoryIndex::from_u32(0);
8500 let effective_address = self.resolve_memory_ptr(
8501 memory_index,
8502 memarg,
8503 self.intrinsics.ptr_ty,
8504 offset,
8505 8,
8506 )?;
8507 let dead_load = err!(self.builder.build_load(
8508 self.intrinsics.i64_ty,
8509 effective_address,
8510 ""
8511 ));
8512 self.annotate_user_memaccess(
8513 memory_index,
8514 memarg,
8515 1,
8516 dead_load.as_instruction_value().unwrap(),
8517 )?;
8518 let store = err!(self.builder.build_store(effective_address, value));
8519 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8520 }
8521 Operator::F32Store { ref memarg } => {
8522 let (v, i) = self.state.pop1_extra()?;
8523 let v = self.apply_pending_canonicalization(v, i)?;
8524 let offset = self.state.pop1()?.into_int_value();
8525 let memory_index = MemoryIndex::from_u32(0);
8526 let effective_address = self.resolve_memory_ptr(
8527 memory_index,
8528 memarg,
8529 self.intrinsics.ptr_ty,
8530 offset,
8531 4,
8532 )?;
8533 let dead_load = err!(self.builder.build_load(
8534 self.intrinsics.f32_ty,
8535 effective_address,
8536 ""
8537 ));
8538 self.annotate_user_memaccess(
8539 memory_index,
8540 memarg,
8541 1,
8542 dead_load.as_instruction_value().unwrap(),
8543 )?;
8544 let store = err!(self.builder.build_store(effective_address, v));
8545 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8546 }
8547 Operator::F64Store { ref memarg } => {
8548 let (v, i) = self.state.pop1_extra()?;
8549 let v = self.apply_pending_canonicalization(v, i)?;
8550 let offset = self.state.pop1()?.into_int_value();
8551 let memory_index = MemoryIndex::from_u32(0);
8552 let effective_address = self.resolve_memory_ptr(
8553 memory_index,
8554 memarg,
8555 self.intrinsics.ptr_ty,
8556 offset,
8557 8,
8558 )?;
8559 let dead_load = err!(self.builder.build_load(
8560 self.intrinsics.f64_ty,
8561 effective_address,
8562 ""
8563 ));
8564 self.annotate_user_memaccess(
8565 memory_index,
8566 memarg,
8567 1,
8568 dead_load.as_instruction_value().unwrap(),
8569 )?;
8570 let store = err!(self.builder.build_store(effective_address, v));
8571 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8572 }
8573 Operator::V128Store { ref memarg } => {
8574 let (v, i) = self.state.pop1_extra()?;
8575 let v = self.apply_pending_canonicalization(v, i)?;
8576 let offset = self.state.pop1()?.into_int_value();
8577 let memory_index = MemoryIndex::from_u32(0);
8578 let effective_address = self.resolve_memory_ptr(
8579 memory_index,
8580 memarg,
8581 self.intrinsics.ptr_ty,
8582 offset,
8583 16,
8584 )?;
8585 let dead_load = err!(self.builder.build_load(
8586 self.intrinsics.i128_ty,
8587 effective_address,
8588 ""
8589 ));
8590 self.annotate_user_memaccess(
8591 memory_index,
8592 memarg,
8593 1,
8594 dead_load.as_instruction_value().unwrap(),
8595 )?;
8596 let store = err!(self.builder.build_store(effective_address, v));
8597 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8598 }
8599 Operator::V128Store8Lane { ref memarg, lane } => {
8600 let (v, i) = self.state.pop1_extra()?;
8601 let (v, _i) = self.v128_into_i8x16(v, i)?;
8602 let offset = self.state.pop1()?.into_int_value();
8603 let memory_index = MemoryIndex::from_u32(memarg.memory);
8604
8605 let effective_address = self.resolve_memory_ptr(
8606 memory_index,
8607 memarg,
8608 self.intrinsics.ptr_ty,
8609 offset,
8610 1,
8611 )?;
8612 let dead_load = err!(self.builder.build_load(
8613 self.intrinsics.i8_ty,
8614 effective_address,
8615 ""
8616 ));
8617 self.annotate_user_memaccess(
8618 memory_index,
8619 memarg,
8620 1,
8621 dead_load.as_instruction_value().unwrap(),
8622 )?;
8623 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8624 let val = err!(self.builder.build_extract_element(v, idx, ""));
8625 let store = err!(self.builder.build_store(effective_address, val));
8626 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8627 }
8628 Operator::V128Store16Lane { ref memarg, lane } => {
8629 let (v, i) = self.state.pop1_extra()?;
8630 let (v, _i) = self.v128_into_i16x8(v, i)?;
8631 let offset = self.state.pop1()?.into_int_value();
8632 let memory_index = MemoryIndex::from_u32(memarg.memory);
8633
8634 let effective_address = self.resolve_memory_ptr(
8635 memory_index,
8636 memarg,
8637 self.intrinsics.ptr_ty,
8638 offset,
8639 2,
8640 )?;
8641 let dead_load = err!(self.builder.build_load(
8642 self.intrinsics.i16_ty,
8643 effective_address,
8644 ""
8645 ));
8646 self.annotate_user_memaccess(
8647 memory_index,
8648 memarg,
8649 1,
8650 dead_load.as_instruction_value().unwrap(),
8651 )?;
8652 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8653 let val = err!(self.builder.build_extract_element(v, idx, ""));
8654 let store = err!(self.builder.build_store(effective_address, val));
8655 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8656 }
8657 Operator::V128Store32Lane { ref memarg, lane } => {
8658 let (v, i) = self.state.pop1_extra()?;
8659 let (v, _i) = self.v128_into_i32x4(v, i)?;
8660 let offset = self.state.pop1()?.into_int_value();
8661 let memory_index = MemoryIndex::from_u32(memarg.memory);
8662
8663 let effective_address = self.resolve_memory_ptr(
8664 memory_index,
8665 memarg,
8666 self.intrinsics.ptr_ty,
8667 offset,
8668 4,
8669 )?;
8670 let dead_load = err!(self.builder.build_load(
8671 self.intrinsics.i32_ty,
8672 effective_address,
8673 ""
8674 ));
8675 self.annotate_user_memaccess(
8676 memory_index,
8677 memarg,
8678 1,
8679 dead_load.as_instruction_value().unwrap(),
8680 )?;
8681 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8682 let val = err!(self.builder.build_extract_element(v, idx, ""));
8683 let store = err!(self.builder.build_store(effective_address, val));
8684 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8685 }
8686 Operator::V128Store64Lane { ref memarg, lane } => {
8687 let (v, i) = self.state.pop1_extra()?;
8688 let (v, _i) = self.v128_into_i64x2(v, i)?;
8689 let offset = self.state.pop1()?.into_int_value();
8690 let memory_index = MemoryIndex::from_u32(memarg.memory);
8691
8692 let effective_address = self.resolve_memory_ptr(
8693 memory_index,
8694 memarg,
8695 self.intrinsics.ptr_ty,
8696 offset,
8697 8,
8698 )?;
8699 let dead_load = err!(self.builder.build_load(
8700 self.intrinsics.i64_ty,
8701 effective_address,
8702 ""
8703 ));
8704 self.annotate_user_memaccess(
8705 memory_index,
8706 memarg,
8707 1,
8708 dead_load.as_instruction_value().unwrap(),
8709 )?;
8710 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8711 let val = err!(self.builder.build_extract_element(v, idx, ""));
8712 let store = err!(self.builder.build_store(effective_address, val));
8713 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8714 }
8715 Operator::I32Load8S { ref memarg } => {
8716 let offset = self.state.pop1()?.into_int_value();
8717 let memory_index = MemoryIndex::from_u32(0);
8718 let effective_address = self.resolve_memory_ptr(
8719 memory_index,
8720 memarg,
8721 self.intrinsics.ptr_ty,
8722 offset,
8723 1,
8724 )?;
8725 let narrow_result = err!(self.builder.build_load(
8726 self.intrinsics.i8_ty,
8727 effective_address,
8728 ""
8729 ));
8730 self.annotate_user_memaccess(
8731 memory_index,
8732 memarg,
8733 1,
8734 narrow_result.as_instruction_value().unwrap(),
8735 )?;
8736 let result = err!(self.builder.build_int_s_extend(
8737 narrow_result.into_int_value(),
8738 self.intrinsics.i32_ty,
8739 "",
8740 ));
8741 self.state.push1(result);
8742 }
8743 Operator::I32Load16S { ref memarg } => {
8744 let offset = self.state.pop1()?.into_int_value();
8745 let memory_index = MemoryIndex::from_u32(0);
8746 let effective_address = self.resolve_memory_ptr(
8747 memory_index,
8748 memarg,
8749 self.intrinsics.ptr_ty,
8750 offset,
8751 2,
8752 )?;
8753 let narrow_result = err!(self.builder.build_load(
8754 self.intrinsics.i16_ty,
8755 effective_address,
8756 ""
8757 ));
8758 self.annotate_user_memaccess(
8759 memory_index,
8760 memarg,
8761 1,
8762 narrow_result.as_instruction_value().unwrap(),
8763 )?;
8764 let result = err!(self.builder.build_int_s_extend(
8765 narrow_result.into_int_value(),
8766 self.intrinsics.i32_ty,
8767 "",
8768 ));
8769 self.state.push1(result);
8770 }
8771 Operator::I64Load8S { ref memarg } => {
8772 let offset = self.state.pop1()?.into_int_value();
8773 let memory_index = MemoryIndex::from_u32(0);
8774 let effective_address = self.resolve_memory_ptr(
8775 memory_index,
8776 memarg,
8777 self.intrinsics.ptr_ty,
8778 offset,
8779 1,
8780 )?;
8781 let narrow_result = err!(self.builder.build_load(
8782 self.intrinsics.i8_ty,
8783 effective_address,
8784 ""
8785 ))
8786 .into_int_value();
8787 self.annotate_user_memaccess(
8788 memory_index,
8789 memarg,
8790 1,
8791 narrow_result.as_instruction_value().unwrap(),
8792 )?;
8793 let result = err!(self.builder.build_int_s_extend(
8794 narrow_result,
8795 self.intrinsics.i64_ty,
8796 ""
8797 ));
8798 self.state.push1(result);
8799 }
8800 Operator::I64Load16S { ref memarg } => {
8801 let offset = self.state.pop1()?.into_int_value();
8802 let memory_index = MemoryIndex::from_u32(0);
8803 let effective_address = self.resolve_memory_ptr(
8804 memory_index,
8805 memarg,
8806 self.intrinsics.ptr_ty,
8807 offset,
8808 2,
8809 )?;
8810 let narrow_result = err!(self.builder.build_load(
8811 self.intrinsics.i16_ty,
8812 effective_address,
8813 ""
8814 ))
8815 .into_int_value();
8816 self.annotate_user_memaccess(
8817 memory_index,
8818 memarg,
8819 1,
8820 narrow_result.as_instruction_value().unwrap(),
8821 )?;
8822 let result = err!(self.builder.build_int_s_extend(
8823 narrow_result,
8824 self.intrinsics.i64_ty,
8825 ""
8826 ));
8827 self.state.push1(result);
8828 }
8829 Operator::I64Load32S { ref memarg } => {
8830 let offset = self.state.pop1()?.into_int_value();
8831 let memory_index = MemoryIndex::from_u32(0);
8832 let effective_address = self.resolve_memory_ptr(
8833 memory_index,
8834 memarg,
8835 self.intrinsics.ptr_ty,
8836 offset,
8837 4,
8838 )?;
8839 let narrow_result = err!(self.builder.build_load(
8840 self.intrinsics.i32_ty,
8841 effective_address,
8842 ""
8843 ));
8844 self.annotate_user_memaccess(
8845 memory_index,
8846 memarg,
8847 1,
8848 narrow_result.as_instruction_value().unwrap(),
8849 )?;
8850 let result = err!(self.builder.build_int_s_extend(
8851 narrow_result.into_int_value(),
8852 self.intrinsics.i64_ty,
8853 "",
8854 ));
8855 self.state.push1(result);
8856 }
8857
8858 Operator::I32Load8U { ref memarg } => {
8859 let offset = self.state.pop1()?.into_int_value();
8860 let memory_index = MemoryIndex::from_u32(0);
8861 let effective_address = self.resolve_memory_ptr(
8862 memory_index,
8863 memarg,
8864 self.intrinsics.ptr_ty,
8865 offset,
8866 1,
8867 )?;
8868 let narrow_result = err!(self.builder.build_load(
8869 self.intrinsics.i8_ty,
8870 effective_address,
8871 ""
8872 ));
8873 self.annotate_user_memaccess(
8874 memory_index,
8875 memarg,
8876 1,
8877 narrow_result.as_instruction_value().unwrap(),
8878 )?;
8879 let result = err!(self.builder.build_int_z_extend(
8880 narrow_result.into_int_value(),
8881 self.intrinsics.i32_ty,
8882 "",
8883 ));
8884 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8885 }
8886 Operator::I32Load16U { ref memarg } => {
8887 let offset = self.state.pop1()?.into_int_value();
8888 let memory_index = MemoryIndex::from_u32(0);
8889 let effective_address = self.resolve_memory_ptr(
8890 memory_index,
8891 memarg,
8892 self.intrinsics.ptr_ty,
8893 offset,
8894 2,
8895 )?;
8896 let narrow_result = err!(self.builder.build_load(
8897 self.intrinsics.i16_ty,
8898 effective_address,
8899 ""
8900 ));
8901 self.annotate_user_memaccess(
8902 memory_index,
8903 memarg,
8904 1,
8905 narrow_result.as_instruction_value().unwrap(),
8906 )?;
8907 let result = err!(self.builder.build_int_z_extend(
8908 narrow_result.into_int_value(),
8909 self.intrinsics.i32_ty,
8910 "",
8911 ));
8912 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8913 }
8914 Operator::I64Load8U { ref memarg } => {
8915 let offset = self.state.pop1()?.into_int_value();
8916 let memory_index = MemoryIndex::from_u32(0);
8917 let effective_address = self.resolve_memory_ptr(
8918 memory_index,
8919 memarg,
8920 self.intrinsics.ptr_ty,
8921 offset,
8922 1,
8923 )?;
8924 let narrow_result = err!(self.builder.build_load(
8925 self.intrinsics.i8_ty,
8926 effective_address,
8927 ""
8928 ));
8929 self.annotate_user_memaccess(
8930 memory_index,
8931 memarg,
8932 1,
8933 narrow_result.as_instruction_value().unwrap(),
8934 )?;
8935 let result = err!(self.builder.build_int_z_extend(
8936 narrow_result.into_int_value(),
8937 self.intrinsics.i64_ty,
8938 "",
8939 ));
8940 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8941 }
8942 Operator::I64Load16U { ref memarg } => {
8943 let offset = self.state.pop1()?.into_int_value();
8944 let memory_index = MemoryIndex::from_u32(0);
8945 let effective_address = self.resolve_memory_ptr(
8946 memory_index,
8947 memarg,
8948 self.intrinsics.ptr_ty,
8949 offset,
8950 2,
8951 )?;
8952 let narrow_result = err!(self.builder.build_load(
8953 self.intrinsics.i16_ty,
8954 effective_address,
8955 ""
8956 ));
8957 self.annotate_user_memaccess(
8958 memory_index,
8959 memarg,
8960 1,
8961 narrow_result.as_instruction_value().unwrap(),
8962 )?;
8963 let result = err!(self.builder.build_int_z_extend(
8964 narrow_result.into_int_value(),
8965 self.intrinsics.i64_ty,
8966 "",
8967 ));
8968 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8969 }
8970 Operator::I64Load32U { ref memarg } => {
8971 let offset = self.state.pop1()?.into_int_value();
8972 let memory_index = MemoryIndex::from_u32(0);
8973 let effective_address = self.resolve_memory_ptr(
8974 memory_index,
8975 memarg,
8976 self.intrinsics.ptr_ty,
8977 offset,
8978 4,
8979 )?;
8980 let narrow_result = err!(self.builder.build_load(
8981 self.intrinsics.i32_ty,
8982 effective_address,
8983 ""
8984 ));
8985 self.annotate_user_memaccess(
8986 memory_index,
8987 memarg,
8988 1,
8989 narrow_result.as_instruction_value().unwrap(),
8990 )?;
8991 let result = err!(self.builder.build_int_z_extend(
8992 narrow_result.into_int_value(),
8993 self.intrinsics.i64_ty,
8994 "",
8995 ));
8996 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8997 }
8998
8999 Operator::I32Store8 { ref memarg } | Operator::I64Store8 { ref memarg } => {
9000 let value = self.state.pop1()?.into_int_value();
9001 let offset = self.state.pop1()?.into_int_value();
9002 let memory_index = MemoryIndex::from_u32(0);
9003 let effective_address = self.resolve_memory_ptr(
9004 memory_index,
9005 memarg,
9006 self.intrinsics.ptr_ty,
9007 offset,
9008 1,
9009 )?;
9010 let dead_load = err!(self.builder.build_load(
9011 self.intrinsics.i8_ty,
9012 effective_address,
9013 ""
9014 ));
9015 self.annotate_user_memaccess(
9016 memory_index,
9017 memarg,
9018 1,
9019 dead_load.as_instruction_value().unwrap(),
9020 )?;
9021 let narrow_value = err!(self.builder.build_int_truncate(
9022 value,
9023 self.intrinsics.i8_ty,
9024 ""
9025 ));
9026 let store = err!(self.builder.build_store(effective_address, narrow_value));
9027 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9028 }
9029 Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
9030 let value = self.state.pop1()?.into_int_value();
9031 let offset = self.state.pop1()?.into_int_value();
9032 let memory_index = MemoryIndex::from_u32(0);
9033 let effective_address = self.resolve_memory_ptr(
9034 memory_index,
9035 memarg,
9036 self.intrinsics.ptr_ty,
9037 offset,
9038 2,
9039 )?;
9040 let dead_load = err!(self.builder.build_load(
9041 self.intrinsics.i16_ty,
9042 effective_address,
9043 ""
9044 ));
9045 self.annotate_user_memaccess(
9046 memory_index,
9047 memarg,
9048 1,
9049 dead_load.as_instruction_value().unwrap(),
9050 )?;
9051 let narrow_value = err!(self.builder.build_int_truncate(
9052 value,
9053 self.intrinsics.i16_ty,
9054 ""
9055 ));
9056 let store = err!(self.builder.build_store(effective_address, narrow_value));
9057 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9058 }
9059 Operator::I64Store32 { ref memarg } => {
9060 let value = self.state.pop1()?.into_int_value();
9061 let offset = self.state.pop1()?.into_int_value();
9062 let memory_index = MemoryIndex::from_u32(0);
9063 let effective_address = self.resolve_memory_ptr(
9064 memory_index,
9065 memarg,
9066 self.intrinsics.ptr_ty,
9067 offset,
9068 4,
9069 )?;
9070 let dead_load = err!(self.builder.build_load(
9071 self.intrinsics.i32_ty,
9072 effective_address,
9073 ""
9074 ));
9075 self.annotate_user_memaccess(
9076 memory_index,
9077 memarg,
9078 1,
9079 dead_load.as_instruction_value().unwrap(),
9080 )?;
9081 let narrow_value = err!(self.builder.build_int_truncate(
9082 value,
9083 self.intrinsics.i32_ty,
9084 ""
9085 ));
9086 let store = err!(self.builder.build_store(effective_address, narrow_value));
9087 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9088 }
9089 Operator::I8x16Neg => {
9090 let (v, i) = self.state.pop1_extra()?;
9091 let (v, _) = self.v128_into_i8x16(v, i)?;
9092 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9093 let res = err!(
9094 self.builder
9095 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9096 );
9097 self.state.push1(res);
9098 }
9099 Operator::I16x8Neg => {
9100 let (v, i) = self.state.pop1_extra()?;
9101 let (v, _) = self.v128_into_i16x8(v, i)?;
9102 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9103 let res = err!(
9104 self.builder
9105 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9106 );
9107 self.state.push1(res);
9108 }
9109 Operator::I32x4Neg => {
9110 let (v, i) = self.state.pop1_extra()?;
9111 let (v, _) = self.v128_into_i32x4(v, i)?;
9112 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9113 let res = err!(
9114 self.builder
9115 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9116 );
9117 self.state.push1(res);
9118 }
9119 Operator::I64x2Neg => {
9120 let (v, i) = self.state.pop1_extra()?;
9121 let (v, _) = self.v128_into_i64x2(v, i)?;
9122 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9123 let res = err!(
9124 self.builder
9125 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9126 );
9127 self.state.push1(res);
9128 }
9129 Operator::V128Not => {
9130 let (v, i) = self.state.pop1_extra()?;
9131 let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9132 let res = err!(self.builder.build_not(v, ""));
9133 self.state.push1(res);
9134 }
9135 Operator::V128AnyTrue => {
9136 let v = self.state.pop1()?.into_int_value();
9139 let res = err!(self.builder.build_int_compare(
9140 IntPredicate::NE,
9141 v,
9142 v.get_type().const_zero(),
9143 "",
9144 ));
9145 let res = err!(
9146 self.builder
9147 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9148 );
9149 self.state.push1_extra(
9150 res,
9151 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9152 );
9153 }
9154 Operator::I8x16AllTrue
9155 | Operator::I16x8AllTrue
9156 | Operator::I32x4AllTrue
9157 | Operator::I64x2AllTrue => {
9158 let vec_ty = match op {
9159 Operator::I8x16AllTrue => self.intrinsics.i8x16_ty,
9160 Operator::I16x8AllTrue => self.intrinsics.i16x8_ty,
9161 Operator::I32x4AllTrue => self.intrinsics.i32x4_ty,
9162 Operator::I64x2AllTrue => self.intrinsics.i64x2_ty,
9163 _ => unreachable!(),
9164 };
9165 let (v, i) = self.state.pop1_extra()?;
9166 let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9167 let lane_int_ty = self.context.custom_width_int_type(vec_ty.get_size());
9168 let vec = err!(self.builder.build_bit_cast(v, vec_ty, "vec")).into_vector_value();
9169 let mask = err!(self.builder.build_int_compare(
9170 IntPredicate::NE,
9171 vec,
9172 vec_ty.const_zero(),
9173 "mask",
9174 ));
9175 let cmask =
9176 err!(self.builder.build_bit_cast(mask, lane_int_ty, "cmask")).into_int_value();
9177 let res = err!(self.builder.build_int_compare(
9178 IntPredicate::EQ,
9179 cmask,
9180 lane_int_ty.const_int(u64::MAX, true),
9181 "",
9182 ));
9183 let res = err!(
9184 self.builder
9185 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9186 );
9187 self.state.push1_extra(
9188 res,
9189 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9190 );
9191 }
9192 Operator::I8x16ExtractLaneS { lane } => {
9193 let (v, i) = self.state.pop1_extra()?;
9194 let (v, _) = self.v128_into_i8x16(v, i)?;
9195 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9196 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9197 let res = err!(
9198 self.builder
9199 .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9200 );
9201 self.state.push1(res);
9202 }
9203 Operator::I8x16ExtractLaneU { lane } => {
9204 let (v, i) = self.state.pop1_extra()?;
9205 let (v, _) = self.v128_into_i8x16(v, i)?;
9206 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9207 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9208 let res = err!(
9209 self.builder
9210 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9211 );
9212 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9213 }
9214 Operator::I16x8ExtractLaneS { lane } => {
9215 let (v, i) = self.state.pop1_extra()?;
9216 let (v, _) = self.v128_into_i16x8(v, i)?;
9217 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9218 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9219 let res = err!(
9220 self.builder
9221 .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9222 );
9223 self.state.push1(res);
9224 }
9225 Operator::I16x8ExtractLaneU { lane } => {
9226 let (v, i) = self.state.pop1_extra()?;
9227 let (v, _) = self.v128_into_i16x8(v, i)?;
9228 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9229 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9230 let res = err!(
9231 self.builder
9232 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9233 );
9234 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9235 }
9236 Operator::I32x4ExtractLane { lane } => {
9237 let (v, i) = self.state.pop1_extra()?;
9238 let (v, i) = self.v128_into_i32x4(v, i)?;
9239 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9240 let res = err!(self.builder.build_extract_element(v, idx, ""));
9241 self.state.push1_extra(res, i);
9242 }
9243 Operator::I64x2ExtractLane { lane } => {
9244 let (v, i) = self.state.pop1_extra()?;
9245 let (v, i) = self.v128_into_i64x2(v, i)?;
9246 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9247 let res = err!(self.builder.build_extract_element(v, idx, ""));
9248 self.state.push1_extra(res, i);
9249 }
9250 Operator::F32x4ExtractLane { lane } => {
9251 let (v, i) = self.state.pop1_extra()?;
9252 let (v, i) = self.v128_into_f32x4(v, i)?;
9253 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9254 let res = err!(self.builder.build_extract_element(v, idx, ""));
9255 self.state.push1_extra(res, i);
9256 }
9257 Operator::F64x2ExtractLane { lane } => {
9258 let (v, i) = self.state.pop1_extra()?;
9259 let (v, i) = self.v128_into_f64x2(v, i)?;
9260 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9261 let res = err!(self.builder.build_extract_element(v, idx, ""));
9262 self.state.push1_extra(res, i);
9263 }
9264 Operator::I8x16ReplaceLane { lane } => {
9265 let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9266 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
9267 let v2 = v2.into_int_value();
9268 let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i8_ty, ""));
9269 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9270 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9271 let res = err!(
9272 self.builder
9273 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9274 );
9275 self.state.push1(res);
9276 }
9277 Operator::I16x8ReplaceLane { lane } => {
9278 let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9279 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
9280 let v2 = v2.into_int_value();
9281 let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i16_ty, ""));
9282 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9283 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9284 let res = err!(
9285 self.builder
9286 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9287 );
9288 self.state.push1(res);
9289 }
9290 Operator::I32x4ReplaceLane { lane } => {
9291 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9292 let (v1, i1) = self.v128_into_i32x4(v1, i1)?;
9293 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9294 let v2 = v2.into_int_value();
9295 let i2 = i2.strip_pending();
9296 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9297 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9298 let res = err!(
9299 self.builder
9300 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9301 );
9302 self.state
9303 .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f32())?);
9304 }
9305 Operator::I64x2ReplaceLane { lane } => {
9306 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9307 let (v1, i1) = self.v128_into_i64x2(v1, i1)?;
9308 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9309 let v2 = v2.into_int_value();
9310 let i2 = i2.strip_pending();
9311 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9312 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9313 let res = err!(
9314 self.builder
9315 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9316 );
9317 self.state
9318 .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f64())?);
9319 }
9320 Operator::F32x4ReplaceLane { lane } => {
9321 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9322 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
9323 let push_pending_f32_nan_to_result =
9324 i1.has_pending_f32_nan() && i2.has_pending_f32_nan();
9325 let (v1, v2) = if !push_pending_f32_nan_to_result {
9326 (
9327 self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9328 .into_vector_value(),
9329 self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9330 .into_float_value(),
9331 )
9332 } else {
9333 (v1, v2.into_float_value())
9334 };
9335 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9336 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9337 let res = err!(
9338 self.builder
9339 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9340 );
9341 let info = if push_pending_f32_nan_to_result {
9342 ExtraInfo::pending_f32_nan()
9343 } else {
9344 (i1.strip_pending() & i2.strip_pending())?
9345 };
9346 self.state.push1_extra(res, info);
9347 }
9348 Operator::F64x2ReplaceLane { lane } => {
9349 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9350 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
9351 let push_pending_f64_nan_to_result =
9352 i1.has_pending_f64_nan() && i2.has_pending_f64_nan();
9353 let (v1, v2) = if !push_pending_f64_nan_to_result {
9354 (
9355 self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9356 .into_vector_value(),
9357 self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9358 .into_float_value(),
9359 )
9360 } else {
9361 (v1, v2.into_float_value())
9362 };
9363 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9364 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9365 let res = err!(
9366 self.builder
9367 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9368 );
9369 let info = if push_pending_f64_nan_to_result {
9370 ExtraInfo::pending_f64_nan()
9371 } else {
9372 (i1.strip_pending() & i2.strip_pending())?
9373 };
9374 self.state.push1_extra(res, info);
9375 }
9376 Operator::I8x16Swizzle => {
9377 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9378 let v1 = self.apply_pending_canonicalization(v1, i1)?;
9379 let v1 = err!(
9380 self.builder
9381 .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9382 )
9383 .into_vector_value();
9384 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9385 let v2 = err!(
9386 self.builder
9387 .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9388 )
9389 .into_vector_value();
9390 let lanes = self.intrinsics.i8_ty.const_int(16, false);
9391 let lanes =
9392 self.splat_vector(lanes.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
9393 let mut res = self.intrinsics.i8x16_ty.get_undef();
9394 let idx_out_of_range = err!(self.builder.build_int_compare(
9395 IntPredicate::UGE,
9396 v2,
9397 lanes,
9398 "idx_out_of_range",
9399 ));
9400 let idx_clamped = err!(self.builder.build_select(
9401 idx_out_of_range,
9402 self.intrinsics.i8x16_ty.const_zero(),
9403 v2,
9404 "idx_clamped",
9405 ))
9406 .into_vector_value();
9407 for i in 0..16 {
9408 let idx = err!(self.builder.build_extract_element(
9409 idx_clamped,
9410 self.intrinsics.i32_ty.const_int(i, false),
9411 "idx",
9412 ))
9413 .into_int_value();
9414 let replace_with_zero = err!(self.builder.build_extract_element(
9415 idx_out_of_range,
9416 self.intrinsics.i32_ty.const_int(i, false),
9417 "replace_with_zero",
9418 ))
9419 .into_int_value();
9420 let elem =
9421 err!(self.builder.build_extract_element(v1, idx, "elem")).into_int_value();
9422 let elem_or_zero = err!(self.builder.build_select(
9423 replace_with_zero,
9424 self.intrinsics.i8_zero,
9425 elem,
9426 "elem_or_zero",
9427 ));
9428 res = err!(self.builder.build_insert_element(
9429 res,
9430 elem_or_zero,
9431 self.intrinsics.i32_ty.const_int(i, false),
9432 "",
9433 ));
9434 }
9435 let res = err!(
9436 self.builder
9437 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9438 );
9439 self.state.push1(res);
9440 }
9441 Operator::I8x16Shuffle { lanes } => {
9442 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9443 let v1 = self.apply_pending_canonicalization(v1, i1)?;
9444 let v1 = err!(
9445 self.builder
9446 .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9447 )
9448 .into_vector_value();
9449 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9450 let v2 = err!(
9451 self.builder
9452 .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9453 )
9454 .into_vector_value();
9455 let mask = VectorType::const_vector(
9456 lanes
9457 .iter()
9458 .map(|l| self.intrinsics.i32_ty.const_int((*l).into(), false))
9459 .collect::<Vec<IntValue>>()
9460 .as_slice(),
9461 );
9462 let res = err!(self.builder.build_shuffle_vector(v1, v2, mask, ""));
9463 let res = err!(
9464 self.builder
9465 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9466 );
9467 self.state.push1(res);
9468 }
9469 Operator::V128Load8x8S { ref memarg } => {
9470 let offset = self.state.pop1()?.into_int_value();
9471 let memory_index = MemoryIndex::from_u32(0);
9472 let effective_address = self.resolve_memory_ptr(
9473 memory_index,
9474 memarg,
9475 self.intrinsics.ptr_ty,
9476 offset,
9477 8,
9478 )?;
9479 let v = err!(self.builder.build_load(
9480 self.intrinsics.i64_ty,
9481 effective_address,
9482 ""
9483 ));
9484 let v = err!(
9485 self.builder
9486 .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9487 )
9488 .into_vector_value();
9489 let res = err!(
9490 self.builder
9491 .build_int_s_extend(v, self.intrinsics.i16x8_ty, "")
9492 );
9493 let res = err!(
9494 self.builder
9495 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9496 );
9497 self.state.push1(res);
9498 }
9499 Operator::V128Load8x8U { ref memarg } => {
9500 let offset = self.state.pop1()?.into_int_value();
9501 let memory_index = MemoryIndex::from_u32(0);
9502 let effective_address = self.resolve_memory_ptr(
9503 memory_index,
9504 memarg,
9505 self.intrinsics.ptr_ty,
9506 offset,
9507 8,
9508 )?;
9509 let v = err!(self.builder.build_load(
9510 self.intrinsics.i64_ty,
9511 effective_address,
9512 ""
9513 ));
9514 let v = err!(
9515 self.builder
9516 .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9517 )
9518 .into_vector_value();
9519 let res = err!(
9520 self.builder
9521 .build_int_z_extend(v, self.intrinsics.i16x8_ty, "")
9522 );
9523 let res = err!(
9524 self.builder
9525 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9526 );
9527 self.state.push1(res);
9528 }
9529 Operator::V128Load16x4S { ref memarg } => {
9530 let offset = self.state.pop1()?.into_int_value();
9531 let memory_index = MemoryIndex::from_u32(0);
9532 let effective_address = self.resolve_memory_ptr(
9533 memory_index,
9534 memarg,
9535 self.intrinsics.ptr_ty,
9536 offset,
9537 8,
9538 )?;
9539 let v = err!(self.builder.build_load(
9540 self.intrinsics.i64_ty,
9541 effective_address,
9542 ""
9543 ));
9544 let v = err!(self.builder.build_bit_cast(
9545 v,
9546 self.intrinsics.i16_ty.vec_type(4),
9547 ""
9548 ))
9549 .into_vector_value();
9550 let res = err!(
9551 self.builder
9552 .build_int_s_extend(v, self.intrinsics.i32x4_ty, "")
9553 );
9554 let res = err!(
9555 self.builder
9556 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9557 );
9558 self.state.push1(res);
9559 }
9560 Operator::V128Load16x4U { ref memarg } => {
9561 let offset = self.state.pop1()?.into_int_value();
9562 let memory_index = MemoryIndex::from_u32(0);
9563 let effective_address = self.resolve_memory_ptr(
9564 memory_index,
9565 memarg,
9566 self.intrinsics.ptr_ty,
9567 offset,
9568 8,
9569 )?;
9570 let v = err!(self.builder.build_load(
9571 self.intrinsics.i64_ty,
9572 effective_address,
9573 ""
9574 ));
9575 let v = err!(self.builder.build_bit_cast(
9576 v,
9577 self.intrinsics.i16_ty.vec_type(4),
9578 ""
9579 ))
9580 .into_vector_value();
9581 let res = err!(
9582 self.builder
9583 .build_int_z_extend(v, self.intrinsics.i32x4_ty, "")
9584 );
9585 let res = err!(
9586 self.builder
9587 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9588 );
9589 self.state.push1(res);
9590 }
9591 Operator::V128Load32x2S { ref memarg } => {
9592 let offset = self.state.pop1()?.into_int_value();
9593 let memory_index = MemoryIndex::from_u32(0);
9594 let effective_address = self.resolve_memory_ptr(
9595 memory_index,
9596 memarg,
9597 self.intrinsics.ptr_ty,
9598 offset,
9599 8,
9600 )?;
9601 let v = err!(self.builder.build_load(
9602 self.intrinsics.i64_ty,
9603 effective_address,
9604 ""
9605 ));
9606 let v = err!(self.builder.build_bit_cast(
9607 v,
9608 self.intrinsics.i32_ty.vec_type(2),
9609 ""
9610 ))
9611 .into_vector_value();
9612 let res = err!(
9613 self.builder
9614 .build_int_s_extend(v, self.intrinsics.i64x2_ty, "")
9615 );
9616 let res = err!(
9617 self.builder
9618 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9619 );
9620 self.state.push1(res);
9621 }
9622 Operator::V128Load32x2U { ref memarg } => {
9623 let offset = self.state.pop1()?.into_int_value();
9624 let memory_index = MemoryIndex::from_u32(0);
9625 let effective_address = self.resolve_memory_ptr(
9626 memory_index,
9627 memarg,
9628 self.intrinsics.ptr_ty,
9629 offset,
9630 8,
9631 )?;
9632 let v = err!(self.builder.build_load(
9633 self.intrinsics.i64_ty,
9634 effective_address,
9635 ""
9636 ));
9637 let v = err!(self.builder.build_bit_cast(
9638 v,
9639 self.intrinsics.i32_ty.vec_type(2),
9640 ""
9641 ))
9642 .into_vector_value();
9643 let res = err!(
9644 self.builder
9645 .build_int_z_extend(v, self.intrinsics.i64x2_ty, "")
9646 );
9647 let res = err!(
9648 self.builder
9649 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9650 );
9651 self.state.push1(res);
9652 }
9653 Operator::V128Load32Zero { ref memarg } => {
9654 let offset = self.state.pop1()?.into_int_value();
9655 let memory_index = MemoryIndex::from_u32(0);
9656 let effective_address = self.resolve_memory_ptr(
9657 memory_index,
9658 memarg,
9659 self.intrinsics.ptr_ty,
9660 offset,
9661 4,
9662 )?;
9663 let elem = err!(self.builder.build_load(
9664 self.intrinsics.i32_ty,
9665 effective_address,
9666 ""
9667 ));
9668 self.annotate_user_memaccess(
9669 memory_index,
9670 memarg,
9671 1,
9672 elem.as_instruction_value().unwrap(),
9673 )?;
9674 let res = err!(self.builder.build_int_z_extend(
9675 elem.into_int_value(),
9676 self.intrinsics.i128_ty,
9677 "",
9678 ));
9679 self.state.push1(res);
9680 }
9681 Operator::V128Load64Zero { ref memarg } => {
9682 let offset = self.state.pop1()?.into_int_value();
9683 let memory_index = MemoryIndex::from_u32(0);
9684 let effective_address = self.resolve_memory_ptr(
9685 memory_index,
9686 memarg,
9687 self.intrinsics.ptr_ty,
9688 offset,
9689 8,
9690 )?;
9691 let elem = err!(self.builder.build_load(
9692 self.intrinsics.i64_ty,
9693 effective_address,
9694 ""
9695 ));
9696 self.annotate_user_memaccess(
9697 memory_index,
9698 memarg,
9699 1,
9700 elem.as_instruction_value().unwrap(),
9701 )?;
9702 let res = err!(self.builder.build_int_z_extend(
9703 elem.into_int_value(),
9704 self.intrinsics.i128_ty,
9705 "",
9706 ));
9707 self.state.push1(res);
9708 }
9709 Operator::V128Load8Splat { ref memarg } => {
9710 let offset = self.state.pop1()?.into_int_value();
9711 let memory_index = MemoryIndex::from_u32(0);
9712 let effective_address = self.resolve_memory_ptr(
9713 memory_index,
9714 memarg,
9715 self.intrinsics.ptr_ty,
9716 offset,
9717 1,
9718 )?;
9719 let elem = err!(self.builder.build_load(
9720 self.intrinsics.i8_ty,
9721 effective_address,
9722 ""
9723 ));
9724 self.annotate_user_memaccess(
9725 memory_index,
9726 memarg,
9727 1,
9728 elem.as_instruction_value().unwrap(),
9729 )?;
9730 let res = self.splat_vector(elem, self.intrinsics.i8x16_ty)?;
9731 let res = err!(
9732 self.builder
9733 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9734 );
9735 self.state.push1(res);
9736 }
9737 Operator::V128Load16Splat { ref memarg } => {
9738 let offset = self.state.pop1()?.into_int_value();
9739 let memory_index = MemoryIndex::from_u32(0);
9740 let effective_address = self.resolve_memory_ptr(
9741 memory_index,
9742 memarg,
9743 self.intrinsics.ptr_ty,
9744 offset,
9745 2,
9746 )?;
9747 let elem = err!(self.builder.build_load(
9748 self.intrinsics.i16_ty,
9749 effective_address,
9750 ""
9751 ));
9752 self.annotate_user_memaccess(
9753 memory_index,
9754 memarg,
9755 1,
9756 elem.as_instruction_value().unwrap(),
9757 )?;
9758 let res = self.splat_vector(elem, self.intrinsics.i16x8_ty)?;
9759 let res = err!(
9760 self.builder
9761 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9762 );
9763 self.state.push1(res);
9764 }
9765 Operator::V128Load32Splat { ref memarg } => {
9766 let offset = self.state.pop1()?.into_int_value();
9767 let memory_index = MemoryIndex::from_u32(0);
9768 let effective_address = self.resolve_memory_ptr(
9769 memory_index,
9770 memarg,
9771 self.intrinsics.ptr_ty,
9772 offset,
9773 4,
9774 )?;
9775 let elem = err!(self.builder.build_load(
9776 self.intrinsics.i32_ty,
9777 effective_address,
9778 ""
9779 ));
9780 self.annotate_user_memaccess(
9781 memory_index,
9782 memarg,
9783 1,
9784 elem.as_instruction_value().unwrap(),
9785 )?;
9786 let res = self.splat_vector(elem, self.intrinsics.i32x4_ty)?;
9787 let res = err!(
9788 self.builder
9789 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9790 );
9791 self.state.push1(res);
9792 }
9793 Operator::V128Load64Splat { ref memarg } => {
9794 let offset = self.state.pop1()?.into_int_value();
9795 let memory_index = MemoryIndex::from_u32(0);
9796 let effective_address = self.resolve_memory_ptr(
9797 memory_index,
9798 memarg,
9799 self.intrinsics.ptr_ty,
9800 offset,
9801 8,
9802 )?;
9803 let elem = err!(self.builder.build_load(
9804 self.intrinsics.i64_ty,
9805 effective_address,
9806 ""
9807 ));
9808 self.annotate_user_memaccess(
9809 memory_index,
9810 memarg,
9811 1,
9812 elem.as_instruction_value().unwrap(),
9813 )?;
9814 let res = self.splat_vector(elem, self.intrinsics.i64x2_ty)?;
9815 let res = err!(
9816 self.builder
9817 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9818 );
9819 self.state.push1(res);
9820 }
9821 Operator::AtomicFence => {
9822 }
9830 Operator::I32AtomicLoad { ref memarg } => {
9831 let offset = self.state.pop1()?.into_int_value();
9832 let memory_index = MemoryIndex::from_u32(0);
9833 let effective_address = self.resolve_memory_ptr(
9834 memory_index,
9835 memarg,
9836 self.intrinsics.ptr_ty,
9837 offset,
9838 4,
9839 )?;
9840 self.trap_if_misaligned(memarg, effective_address, 4)?;
9841 let result = err!(self.builder.build_load(
9842 self.intrinsics.i32_ty,
9843 effective_address,
9844 "atomic_load"
9845 ));
9846 let load = result.as_instruction_value().unwrap();
9847 self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
9848 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9849 .unwrap();
9850 self.state.push1(result);
9851 }
9852 Operator::I64AtomicLoad { ref memarg } => {
9853 let offset = self.state.pop1()?.into_int_value();
9854 let memory_index = MemoryIndex::from_u32(0);
9855 let effective_address = self.resolve_memory_ptr(
9856 memory_index,
9857 memarg,
9858 self.intrinsics.ptr_ty,
9859 offset,
9860 8,
9861 )?;
9862 self.trap_if_misaligned(memarg, effective_address, 8)?;
9863 let result = err!(self.builder.build_load(
9864 self.intrinsics.i64_ty,
9865 effective_address,
9866 ""
9867 ));
9868 let load = result.as_instruction_value().unwrap();
9869 self.annotate_user_memaccess(memory_index, memarg, 8, load)?;
9870 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9871 .unwrap();
9872 self.state.push1(result);
9873 }
9874 Operator::I32AtomicLoad8U { ref memarg } => {
9875 let offset = self.state.pop1()?.into_int_value();
9876 let memory_index = MemoryIndex::from_u32(0);
9877 let effective_address = self.resolve_memory_ptr(
9878 memory_index,
9879 memarg,
9880 self.intrinsics.ptr_ty,
9881 offset,
9882 1,
9883 )?;
9884 self.trap_if_misaligned(memarg, effective_address, 1)?;
9885 let narrow_result = err!(self.builder.build_load(
9886 self.intrinsics.i8_ty,
9887 effective_address,
9888 ""
9889 ))
9890 .into_int_value();
9891 let load = narrow_result.as_instruction_value().unwrap();
9892 self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9893 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9894 .unwrap();
9895 let result = err!(self.builder.build_int_z_extend(
9896 narrow_result,
9897 self.intrinsics.i32_ty,
9898 ""
9899 ));
9900 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9901 }
9902 Operator::I32AtomicLoad16U { ref memarg } => {
9903 let offset = self.state.pop1()?.into_int_value();
9904 let memory_index = MemoryIndex::from_u32(0);
9905 let effective_address = self.resolve_memory_ptr(
9906 memory_index,
9907 memarg,
9908 self.intrinsics.ptr_ty,
9909 offset,
9910 2,
9911 )?;
9912 self.trap_if_misaligned(memarg, effective_address, 2)?;
9913 let narrow_result = err!(self.builder.build_load(
9914 self.intrinsics.i16_ty,
9915 effective_address,
9916 ""
9917 ))
9918 .into_int_value();
9919 let load = narrow_result.as_instruction_value().unwrap();
9920 self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9921 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9922 .unwrap();
9923 let result = err!(self.builder.build_int_z_extend(
9924 narrow_result,
9925 self.intrinsics.i32_ty,
9926 ""
9927 ));
9928 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9929 }
9930 Operator::I64AtomicLoad8U { ref memarg } => {
9931 let offset = self.state.pop1()?.into_int_value();
9932 let memory_index = MemoryIndex::from_u32(0);
9933 let effective_address = self.resolve_memory_ptr(
9934 memory_index,
9935 memarg,
9936 self.intrinsics.ptr_ty,
9937 offset,
9938 1,
9939 )?;
9940 self.trap_if_misaligned(memarg, effective_address, 1)?;
9941 let narrow_result = err!(self.builder.build_load(
9942 self.intrinsics.i8_ty,
9943 effective_address,
9944 ""
9945 ))
9946 .into_int_value();
9947 let load = narrow_result.as_instruction_value().unwrap();
9948 self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9949 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9950 .unwrap();
9951 let result = err!(self.builder.build_int_z_extend(
9952 narrow_result,
9953 self.intrinsics.i64_ty,
9954 ""
9955 ));
9956 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9957 }
9958 Operator::I64AtomicLoad16U { ref memarg } => {
9959 let offset = self.state.pop1()?.into_int_value();
9960 let memory_index = MemoryIndex::from_u32(0);
9961 let effective_address = self.resolve_memory_ptr(
9962 memory_index,
9963 memarg,
9964 self.intrinsics.ptr_ty,
9965 offset,
9966 2,
9967 )?;
9968 self.trap_if_misaligned(memarg, effective_address, 2)?;
9969 let narrow_result = err!(self.builder.build_load(
9970 self.intrinsics.i16_ty,
9971 effective_address,
9972 ""
9973 ))
9974 .into_int_value();
9975 let load = narrow_result.as_instruction_value().unwrap();
9976 self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9977 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9978 .unwrap();
9979 let result = err!(self.builder.build_int_z_extend(
9980 narrow_result,
9981 self.intrinsics.i64_ty,
9982 ""
9983 ));
9984 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9985 }
9986 Operator::I64AtomicLoad32U { ref memarg } => {
9987 let offset = self.state.pop1()?.into_int_value();
9988 let memory_index = MemoryIndex::from_u32(0);
9989 let effective_address = self.resolve_memory_ptr(
9990 memory_index,
9991 memarg,
9992 self.intrinsics.ptr_ty,
9993 offset,
9994 4,
9995 )?;
9996 self.trap_if_misaligned(memarg, effective_address, 4)?;
9997 let narrow_result = err!(self.builder.build_load(
9998 self.intrinsics.i32_ty,
9999 effective_address,
10000 ""
10001 ))
10002 .into_int_value();
10003 let load = narrow_result.as_instruction_value().unwrap();
10004 self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10005 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10006 .unwrap();
10007 let result = err!(self.builder.build_int_z_extend(
10008 narrow_result,
10009 self.intrinsics.i64_ty,
10010 ""
10011 ));
10012 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10013 }
10014 Operator::I32AtomicStore { ref memarg } => {
10015 let value = self.state.pop1()?;
10016 let offset = self.state.pop1()?.into_int_value();
10017 let memory_index = MemoryIndex::from_u32(0);
10018 let effective_address = self.resolve_memory_ptr(
10019 memory_index,
10020 memarg,
10021 self.intrinsics.ptr_ty,
10022 offset,
10023 4,
10024 )?;
10025 self.trap_if_misaligned(memarg, effective_address, 4)?;
10026 let store = err!(self.builder.build_store(effective_address, value));
10027 self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10028 store
10029 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10030 .unwrap();
10031 }
10032 Operator::I64AtomicStore { ref memarg } => {
10033 let value = self.state.pop1()?;
10034 let offset = self.state.pop1()?.into_int_value();
10035 let memory_index = MemoryIndex::from_u32(0);
10036 let effective_address = self.resolve_memory_ptr(
10037 memory_index,
10038 memarg,
10039 self.intrinsics.ptr_ty,
10040 offset,
10041 8,
10042 )?;
10043 self.trap_if_misaligned(memarg, effective_address, 8)?;
10044 let store = err!(self.builder.build_store(effective_address, value));
10045 self.annotate_user_memaccess(memory_index, memarg, 8, store)?;
10046 store
10047 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10048 .unwrap();
10049 }
10050 Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => {
10051 let value = self.state.pop1()?.into_int_value();
10052 let offset = self.state.pop1()?.into_int_value();
10053 let memory_index = MemoryIndex::from_u32(0);
10054 let effective_address = self.resolve_memory_ptr(
10055 memory_index,
10056 memarg,
10057 self.intrinsics.ptr_ty,
10058 offset,
10059 1,
10060 )?;
10061 self.trap_if_misaligned(memarg, effective_address, 1)?;
10062 let narrow_value = err!(self.builder.build_int_truncate(
10063 value,
10064 self.intrinsics.i8_ty,
10065 ""
10066 ));
10067 let store = err!(self.builder.build_store(effective_address, narrow_value));
10068 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
10069 store
10070 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10071 .unwrap();
10072 }
10073 Operator::I32AtomicStore16 { ref memarg }
10074 | Operator::I64AtomicStore16 { ref memarg } => {
10075 let value = self.state.pop1()?.into_int_value();
10076 let offset = self.state.pop1()?.into_int_value();
10077 let memory_index = MemoryIndex::from_u32(0);
10078 let effective_address = self.resolve_memory_ptr(
10079 memory_index,
10080 memarg,
10081 self.intrinsics.ptr_ty,
10082 offset,
10083 2,
10084 )?;
10085 self.trap_if_misaligned(memarg, effective_address, 2)?;
10086 let narrow_value = err!(self.builder.build_int_truncate(
10087 value,
10088 self.intrinsics.i16_ty,
10089 ""
10090 ));
10091 let store = err!(self.builder.build_store(effective_address, narrow_value));
10092 self.annotate_user_memaccess(memory_index, memarg, 2, store)?;
10093 store
10094 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10095 .unwrap();
10096 }
10097 Operator::I64AtomicStore32 { ref memarg } => {
10098 let value = self.state.pop1()?.into_int_value();
10099 let offset = self.state.pop1()?.into_int_value();
10100 let memory_index = MemoryIndex::from_u32(0);
10101 let effective_address = self.resolve_memory_ptr(
10102 memory_index,
10103 memarg,
10104 self.intrinsics.ptr_ty,
10105 offset,
10106 4,
10107 )?;
10108 self.trap_if_misaligned(memarg, effective_address, 4)?;
10109 let narrow_value = err!(self.builder.build_int_truncate(
10110 value,
10111 self.intrinsics.i32_ty,
10112 ""
10113 ));
10114 let store = err!(self.builder.build_store(effective_address, narrow_value));
10115 self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10116 store
10117 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10118 .unwrap();
10119 }
10120 Operator::I32AtomicRmw8AddU { ref memarg } => {
10121 let value = self.state.pop1()?.into_int_value();
10122 let offset = self.state.pop1()?.into_int_value();
10123 let memory_index = MemoryIndex::from_u32(0);
10124 let effective_address = self.resolve_memory_ptr(
10125 memory_index,
10126 memarg,
10127 self.intrinsics.ptr_ty,
10128 offset,
10129 1,
10130 )?;
10131 self.trap_if_misaligned(memarg, effective_address, 1)?;
10132 let narrow_value = err!(self.builder.build_int_truncate(
10133 value,
10134 self.intrinsics.i8_ty,
10135 ""
10136 ));
10137 let old = self
10138 .builder
10139 .build_atomicrmw(
10140 AtomicRMWBinOp::Add,
10141 effective_address,
10142 narrow_value,
10143 AtomicOrdering::SequentiallyConsistent,
10144 )
10145 .unwrap();
10146 tbaa_label(
10147 self.module,
10148 self.intrinsics,
10149 format!("memory {}", memory_index.as_u32()),
10150 old.as_instruction_value().unwrap(),
10151 );
10152 let old = err!(
10153 self.builder
10154 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10155 );
10156 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10157 }
10158 Operator::I32AtomicRmw16AddU { ref memarg } => {
10159 let value = self.state.pop1()?.into_int_value();
10160 let offset = self.state.pop1()?.into_int_value();
10161 let memory_index = MemoryIndex::from_u32(0);
10162 let effective_address = self.resolve_memory_ptr(
10163 memory_index,
10164 memarg,
10165 self.intrinsics.ptr_ty,
10166 offset,
10167 2,
10168 )?;
10169 self.trap_if_misaligned(memarg, effective_address, 2)?;
10170 let narrow_value = err!(self.builder.build_int_truncate(
10171 value,
10172 self.intrinsics.i16_ty,
10173 ""
10174 ));
10175 let old = self
10176 .builder
10177 .build_atomicrmw(
10178 AtomicRMWBinOp::Add,
10179 effective_address,
10180 narrow_value,
10181 AtomicOrdering::SequentiallyConsistent,
10182 )
10183 .unwrap();
10184 tbaa_label(
10185 self.module,
10186 self.intrinsics,
10187 format!("memory {}", memory_index.as_u32()),
10188 old.as_instruction_value().unwrap(),
10189 );
10190 let old = err!(
10191 self.builder
10192 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10193 );
10194 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10195 }
10196 Operator::I32AtomicRmwAdd { ref memarg } => {
10197 let value = self.state.pop1()?.into_int_value();
10198 let offset = self.state.pop1()?.into_int_value();
10199 let memory_index = MemoryIndex::from_u32(0);
10200 let effective_address = self.resolve_memory_ptr(
10201 memory_index,
10202 memarg,
10203 self.intrinsics.ptr_ty,
10204 offset,
10205 4,
10206 )?;
10207 self.trap_if_misaligned(memarg, effective_address, 4)?;
10208 let old = self
10209 .builder
10210 .build_atomicrmw(
10211 AtomicRMWBinOp::Add,
10212 effective_address,
10213 value,
10214 AtomicOrdering::SequentiallyConsistent,
10215 )
10216 .unwrap();
10217 tbaa_label(
10218 self.module,
10219 self.intrinsics,
10220 format!("memory {}", memory_index.as_u32()),
10221 old.as_instruction_value().unwrap(),
10222 );
10223 self.state.push1(old);
10224 }
10225 Operator::I64AtomicRmw8AddU { ref memarg } => {
10226 let value = self.state.pop1()?.into_int_value();
10227 let offset = self.state.pop1()?.into_int_value();
10228 let memory_index = MemoryIndex::from_u32(0);
10229 let effective_address = self.resolve_memory_ptr(
10230 memory_index,
10231 memarg,
10232 self.intrinsics.ptr_ty,
10233 offset,
10234 1,
10235 )?;
10236 self.trap_if_misaligned(memarg, effective_address, 1)?;
10237 let narrow_value = err!(self.builder.build_int_truncate(
10238 value,
10239 self.intrinsics.i8_ty,
10240 ""
10241 ));
10242 let old = self
10243 .builder
10244 .build_atomicrmw(
10245 AtomicRMWBinOp::Add,
10246 effective_address,
10247 narrow_value,
10248 AtomicOrdering::SequentiallyConsistent,
10249 )
10250 .unwrap();
10251 self.annotate_user_memaccess(
10252 memory_index,
10253 memarg,
10254 0,
10255 old.as_instruction_value().unwrap(),
10256 )?;
10257 let old = err!(
10258 self.builder
10259 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10260 );
10261 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10262 }
10263 Operator::I64AtomicRmw16AddU { ref memarg } => {
10264 let value = self.state.pop1()?.into_int_value();
10265 let offset = self.state.pop1()?.into_int_value();
10266 let memory_index = MemoryIndex::from_u32(0);
10267 let effective_address = self.resolve_memory_ptr(
10268 memory_index,
10269 memarg,
10270 self.intrinsics.ptr_ty,
10271 offset,
10272 2,
10273 )?;
10274 self.trap_if_misaligned(memarg, effective_address, 2)?;
10275 let narrow_value = err!(self.builder.build_int_truncate(
10276 value,
10277 self.intrinsics.i16_ty,
10278 ""
10279 ));
10280 let old = self
10281 .builder
10282 .build_atomicrmw(
10283 AtomicRMWBinOp::Add,
10284 effective_address,
10285 narrow_value,
10286 AtomicOrdering::SequentiallyConsistent,
10287 )
10288 .unwrap();
10289 self.annotate_user_memaccess(
10290 memory_index,
10291 memarg,
10292 0,
10293 old.as_instruction_value().unwrap(),
10294 )?;
10295 let old = err!(
10296 self.builder
10297 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10298 );
10299 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10300 }
10301 Operator::I64AtomicRmw32AddU { ref memarg } => {
10302 let value = self.state.pop1()?.into_int_value();
10303 let offset = self.state.pop1()?.into_int_value();
10304 let memory_index = MemoryIndex::from_u32(0);
10305 let effective_address = self.resolve_memory_ptr(
10306 memory_index,
10307 memarg,
10308 self.intrinsics.ptr_ty,
10309 offset,
10310 4,
10311 )?;
10312 self.trap_if_misaligned(memarg, effective_address, 4)?;
10313 let narrow_value = err!(self.builder.build_int_truncate(
10314 value,
10315 self.intrinsics.i32_ty,
10316 ""
10317 ));
10318 let old = self
10319 .builder
10320 .build_atomicrmw(
10321 AtomicRMWBinOp::Add,
10322 effective_address,
10323 narrow_value,
10324 AtomicOrdering::SequentiallyConsistent,
10325 )
10326 .unwrap();
10327 self.annotate_user_memaccess(
10328 memory_index,
10329 memarg,
10330 0,
10331 old.as_instruction_value().unwrap(),
10332 )?;
10333 let old = err!(
10334 self.builder
10335 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10336 );
10337 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10338 }
10339 Operator::I64AtomicRmwAdd { ref memarg } => {
10340 let value = self.state.pop1()?.into_int_value();
10341 let offset = self.state.pop1()?.into_int_value();
10342 let memory_index = MemoryIndex::from_u32(0);
10343 let effective_address = self.resolve_memory_ptr(
10344 memory_index,
10345 memarg,
10346 self.intrinsics.ptr_ty,
10347 offset,
10348 8,
10349 )?;
10350 self.trap_if_misaligned(memarg, effective_address, 8)?;
10351 let old = self
10352 .builder
10353 .build_atomicrmw(
10354 AtomicRMWBinOp::Add,
10355 effective_address,
10356 value,
10357 AtomicOrdering::SequentiallyConsistent,
10358 )
10359 .unwrap();
10360 self.annotate_user_memaccess(
10361 memory_index,
10362 memarg,
10363 0,
10364 old.as_instruction_value().unwrap(),
10365 )?;
10366 self.state.push1(old);
10367 }
10368 Operator::I32AtomicRmw8SubU { ref memarg } => {
10369 let value = self.state.pop1()?.into_int_value();
10370 let offset = self.state.pop1()?.into_int_value();
10371 let memory_index = MemoryIndex::from_u32(0);
10372 let effective_address = self.resolve_memory_ptr(
10373 memory_index,
10374 memarg,
10375 self.intrinsics.ptr_ty,
10376 offset,
10377 1,
10378 )?;
10379 self.trap_if_misaligned(memarg, effective_address, 1)?;
10380 let narrow_value = err!(self.builder.build_int_truncate(
10381 value,
10382 self.intrinsics.i8_ty,
10383 ""
10384 ));
10385 let old = self
10386 .builder
10387 .build_atomicrmw(
10388 AtomicRMWBinOp::Sub,
10389 effective_address,
10390 narrow_value,
10391 AtomicOrdering::SequentiallyConsistent,
10392 )
10393 .unwrap();
10394 self.annotate_user_memaccess(
10395 memory_index,
10396 memarg,
10397 0,
10398 old.as_instruction_value().unwrap(),
10399 )?;
10400 let old = err!(
10401 self.builder
10402 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10403 );
10404 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10405 }
10406 Operator::I32AtomicRmw16SubU { ref memarg } => {
10407 let value = self.state.pop1()?.into_int_value();
10408 let offset = self.state.pop1()?.into_int_value();
10409 let memory_index = MemoryIndex::from_u32(0);
10410 let effective_address = self.resolve_memory_ptr(
10411 memory_index,
10412 memarg,
10413 self.intrinsics.ptr_ty,
10414 offset,
10415 2,
10416 )?;
10417 self.trap_if_misaligned(memarg, effective_address, 2)?;
10418 let narrow_value = err!(self.builder.build_int_truncate(
10419 value,
10420 self.intrinsics.i16_ty,
10421 ""
10422 ));
10423 let old = self
10424 .builder
10425 .build_atomicrmw(
10426 AtomicRMWBinOp::Sub,
10427 effective_address,
10428 narrow_value,
10429 AtomicOrdering::SequentiallyConsistent,
10430 )
10431 .unwrap();
10432 self.annotate_user_memaccess(
10433 memory_index,
10434 memarg,
10435 0,
10436 old.as_instruction_value().unwrap(),
10437 )?;
10438 let old = err!(
10439 self.builder
10440 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10441 );
10442 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10443 }
10444 Operator::I32AtomicRmwSub { ref memarg } => {
10445 let value = self.state.pop1()?.into_int_value();
10446 let offset = self.state.pop1()?.into_int_value();
10447 let memory_index = MemoryIndex::from_u32(0);
10448 let effective_address = self.resolve_memory_ptr(
10449 memory_index,
10450 memarg,
10451 self.intrinsics.ptr_ty,
10452 offset,
10453 4,
10454 )?;
10455 self.trap_if_misaligned(memarg, effective_address, 4)?;
10456 let old = self
10457 .builder
10458 .build_atomicrmw(
10459 AtomicRMWBinOp::Sub,
10460 effective_address,
10461 value,
10462 AtomicOrdering::SequentiallyConsistent,
10463 )
10464 .unwrap();
10465 self.annotate_user_memaccess(
10466 memory_index,
10467 memarg,
10468 0,
10469 old.as_instruction_value().unwrap(),
10470 )?;
10471 self.state.push1(old);
10472 }
10473 Operator::I64AtomicRmw8SubU { ref memarg } => {
10474 let value = self.state.pop1()?.into_int_value();
10475 let offset = self.state.pop1()?.into_int_value();
10476 let memory_index = MemoryIndex::from_u32(0);
10477 let effective_address = self.resolve_memory_ptr(
10478 memory_index,
10479 memarg,
10480 self.intrinsics.ptr_ty,
10481 offset,
10482 1,
10483 )?;
10484 self.trap_if_misaligned(memarg, effective_address, 1)?;
10485 let narrow_value = err!(self.builder.build_int_truncate(
10486 value,
10487 self.intrinsics.i8_ty,
10488 ""
10489 ));
10490 let old = self
10491 .builder
10492 .build_atomicrmw(
10493 AtomicRMWBinOp::Sub,
10494 effective_address,
10495 narrow_value,
10496 AtomicOrdering::SequentiallyConsistent,
10497 )
10498 .unwrap();
10499 self.annotate_user_memaccess(
10500 memory_index,
10501 memarg,
10502 0,
10503 old.as_instruction_value().unwrap(),
10504 )?;
10505 let old = err!(
10506 self.builder
10507 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10508 );
10509 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10510 }
10511 Operator::I64AtomicRmw16SubU { ref memarg } => {
10512 let value = self.state.pop1()?.into_int_value();
10513 let offset = self.state.pop1()?.into_int_value();
10514 let memory_index = MemoryIndex::from_u32(0);
10515 let effective_address = self.resolve_memory_ptr(
10516 memory_index,
10517 memarg,
10518 self.intrinsics.ptr_ty,
10519 offset,
10520 2,
10521 )?;
10522 self.trap_if_misaligned(memarg, effective_address, 2)?;
10523 let narrow_value = err!(self.builder.build_int_truncate(
10524 value,
10525 self.intrinsics.i16_ty,
10526 ""
10527 ));
10528 let old = self
10529 .builder
10530 .build_atomicrmw(
10531 AtomicRMWBinOp::Sub,
10532 effective_address,
10533 narrow_value,
10534 AtomicOrdering::SequentiallyConsistent,
10535 )
10536 .unwrap();
10537 self.annotate_user_memaccess(
10538 memory_index,
10539 memarg,
10540 0,
10541 old.as_instruction_value().unwrap(),
10542 )?;
10543 let old = err!(
10544 self.builder
10545 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10546 );
10547 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10548 }
10549 Operator::I64AtomicRmw32SubU { ref memarg } => {
10550 let value = self.state.pop1()?.into_int_value();
10551 let offset = self.state.pop1()?.into_int_value();
10552 let memory_index = MemoryIndex::from_u32(0);
10553 let effective_address = self.resolve_memory_ptr(
10554 memory_index,
10555 memarg,
10556 self.intrinsics.ptr_ty,
10557 offset,
10558 4,
10559 )?;
10560 self.trap_if_misaligned(memarg, effective_address, 4)?;
10561 let narrow_value = err!(self.builder.build_int_truncate(
10562 value,
10563 self.intrinsics.i32_ty,
10564 ""
10565 ));
10566 let old = self
10567 .builder
10568 .build_atomicrmw(
10569 AtomicRMWBinOp::Sub,
10570 effective_address,
10571 narrow_value,
10572 AtomicOrdering::SequentiallyConsistent,
10573 )
10574 .unwrap();
10575 self.annotate_user_memaccess(
10576 memory_index,
10577 memarg,
10578 0,
10579 old.as_instruction_value().unwrap(),
10580 )?;
10581 let old = err!(
10582 self.builder
10583 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10584 );
10585 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10586 }
10587 Operator::I64AtomicRmwSub { ref memarg } => {
10588 let value = self.state.pop1()?.into_int_value();
10589 let offset = self.state.pop1()?.into_int_value();
10590 let memory_index = MemoryIndex::from_u32(0);
10591 let effective_address = self.resolve_memory_ptr(
10592 memory_index,
10593 memarg,
10594 self.intrinsics.ptr_ty,
10595 offset,
10596 8,
10597 )?;
10598 self.trap_if_misaligned(memarg, effective_address, 8)?;
10599 let old = self
10600 .builder
10601 .build_atomicrmw(
10602 AtomicRMWBinOp::Sub,
10603 effective_address,
10604 value,
10605 AtomicOrdering::SequentiallyConsistent,
10606 )
10607 .unwrap();
10608 self.annotate_user_memaccess(
10609 memory_index,
10610 memarg,
10611 0,
10612 old.as_instruction_value().unwrap(),
10613 )?;
10614 self.state.push1(old);
10615 }
10616 Operator::I32AtomicRmw8AndU { ref memarg } => {
10617 let value = self.state.pop1()?.into_int_value();
10618 let offset = self.state.pop1()?.into_int_value();
10619 let memory_index = MemoryIndex::from_u32(0);
10620 let effective_address = self.resolve_memory_ptr(
10621 memory_index,
10622 memarg,
10623 self.intrinsics.ptr_ty,
10624 offset,
10625 1,
10626 )?;
10627 self.trap_if_misaligned(memarg, effective_address, 1)?;
10628 let narrow_value = err!(self.builder.build_int_truncate(
10629 value,
10630 self.intrinsics.i8_ty,
10631 ""
10632 ));
10633 let old = self
10634 .builder
10635 .build_atomicrmw(
10636 AtomicRMWBinOp::And,
10637 effective_address,
10638 narrow_value,
10639 AtomicOrdering::SequentiallyConsistent,
10640 )
10641 .unwrap();
10642 self.annotate_user_memaccess(
10643 memory_index,
10644 memarg,
10645 0,
10646 old.as_instruction_value().unwrap(),
10647 )?;
10648 let old = err!(
10649 self.builder
10650 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10651 );
10652 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10653 }
10654 Operator::I32AtomicRmw16AndU { ref memarg } => {
10655 let value = self.state.pop1()?.into_int_value();
10656 let offset = self.state.pop1()?.into_int_value();
10657 let memory_index = MemoryIndex::from_u32(0);
10658 let effective_address = self.resolve_memory_ptr(
10659 memory_index,
10660 memarg,
10661 self.intrinsics.ptr_ty,
10662 offset,
10663 2,
10664 )?;
10665 self.trap_if_misaligned(memarg, effective_address, 2)?;
10666 let narrow_value = err!(self.builder.build_int_truncate(
10667 value,
10668 self.intrinsics.i16_ty,
10669 ""
10670 ));
10671 let old = self
10672 .builder
10673 .build_atomicrmw(
10674 AtomicRMWBinOp::And,
10675 effective_address,
10676 narrow_value,
10677 AtomicOrdering::SequentiallyConsistent,
10678 )
10679 .unwrap();
10680 self.annotate_user_memaccess(
10681 memory_index,
10682 memarg,
10683 0,
10684 old.as_instruction_value().unwrap(),
10685 )?;
10686 let old = err!(
10687 self.builder
10688 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10689 );
10690 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10691 }
10692 Operator::I32AtomicRmwAnd { ref memarg } => {
10693 let value = self.state.pop1()?.into_int_value();
10694 let offset = self.state.pop1()?.into_int_value();
10695 let memory_index = MemoryIndex::from_u32(0);
10696 let effective_address = self.resolve_memory_ptr(
10697 memory_index,
10698 memarg,
10699 self.intrinsics.ptr_ty,
10700 offset,
10701 4,
10702 )?;
10703 self.trap_if_misaligned(memarg, effective_address, 4)?;
10704 let old = self
10705 .builder
10706 .build_atomicrmw(
10707 AtomicRMWBinOp::And,
10708 effective_address,
10709 value,
10710 AtomicOrdering::SequentiallyConsistent,
10711 )
10712 .unwrap();
10713 self.annotate_user_memaccess(
10714 memory_index,
10715 memarg,
10716 0,
10717 old.as_instruction_value().unwrap(),
10718 )?;
10719 self.state.push1(old);
10720 }
10721 Operator::I64AtomicRmw8AndU { ref memarg } => {
10722 let value = self.state.pop1()?.into_int_value();
10723 let offset = self.state.pop1()?.into_int_value();
10724 let memory_index = MemoryIndex::from_u32(0);
10725 let effective_address = self.resolve_memory_ptr(
10726 memory_index,
10727 memarg,
10728 self.intrinsics.ptr_ty,
10729 offset,
10730 1,
10731 )?;
10732 self.trap_if_misaligned(memarg, effective_address, 1)?;
10733 let narrow_value = err!(self.builder.build_int_truncate(
10734 value,
10735 self.intrinsics.i8_ty,
10736 ""
10737 ));
10738 let old = self
10739 .builder
10740 .build_atomicrmw(
10741 AtomicRMWBinOp::And,
10742 effective_address,
10743 narrow_value,
10744 AtomicOrdering::SequentiallyConsistent,
10745 )
10746 .unwrap();
10747 self.annotate_user_memaccess(
10748 memory_index,
10749 memarg,
10750 0,
10751 old.as_instruction_value().unwrap(),
10752 )?;
10753 let old = err!(
10754 self.builder
10755 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10756 );
10757 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10758 }
10759 Operator::I64AtomicRmw16AndU { ref memarg } => {
10760 let value = self.state.pop1()?.into_int_value();
10761 let offset = self.state.pop1()?.into_int_value();
10762 let memory_index = MemoryIndex::from_u32(0);
10763 let effective_address = self.resolve_memory_ptr(
10764 memory_index,
10765 memarg,
10766 self.intrinsics.ptr_ty,
10767 offset,
10768 2,
10769 )?;
10770 self.trap_if_misaligned(memarg, effective_address, 2)?;
10771 let narrow_value = err!(self.builder.build_int_truncate(
10772 value,
10773 self.intrinsics.i16_ty,
10774 ""
10775 ));
10776 let old = self
10777 .builder
10778 .build_atomicrmw(
10779 AtomicRMWBinOp::And,
10780 effective_address,
10781 narrow_value,
10782 AtomicOrdering::SequentiallyConsistent,
10783 )
10784 .unwrap();
10785 self.annotate_user_memaccess(
10786 memory_index,
10787 memarg,
10788 0,
10789 old.as_instruction_value().unwrap(),
10790 )?;
10791 let old = err!(
10792 self.builder
10793 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10794 );
10795 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10796 }
10797 Operator::I64AtomicRmw32AndU { ref memarg } => {
10798 let value = self.state.pop1()?.into_int_value();
10799 let offset = self.state.pop1()?.into_int_value();
10800 let memory_index = MemoryIndex::from_u32(0);
10801 let effective_address = self.resolve_memory_ptr(
10802 memory_index,
10803 memarg,
10804 self.intrinsics.ptr_ty,
10805 offset,
10806 4,
10807 )?;
10808 self.trap_if_misaligned(memarg, effective_address, 4)?;
10809 let narrow_value = err!(self.builder.build_int_truncate(
10810 value,
10811 self.intrinsics.i32_ty,
10812 ""
10813 ));
10814 let old = self
10815 .builder
10816 .build_atomicrmw(
10817 AtomicRMWBinOp::And,
10818 effective_address,
10819 narrow_value,
10820 AtomicOrdering::SequentiallyConsistent,
10821 )
10822 .unwrap();
10823 self.annotate_user_memaccess(
10824 memory_index,
10825 memarg,
10826 0,
10827 old.as_instruction_value().unwrap(),
10828 )?;
10829 let old = err!(
10830 self.builder
10831 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10832 );
10833 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10834 }
10835 Operator::I64AtomicRmwAnd { ref memarg } => {
10836 let value = self.state.pop1()?.into_int_value();
10837 let offset = self.state.pop1()?.into_int_value();
10838 let memory_index = MemoryIndex::from_u32(0);
10839 let effective_address = self.resolve_memory_ptr(
10840 memory_index,
10841 memarg,
10842 self.intrinsics.ptr_ty,
10843 offset,
10844 8,
10845 )?;
10846 self.trap_if_misaligned(memarg, effective_address, 8)?;
10847 let old = self
10848 .builder
10849 .build_atomicrmw(
10850 AtomicRMWBinOp::And,
10851 effective_address,
10852 value,
10853 AtomicOrdering::SequentiallyConsistent,
10854 )
10855 .unwrap();
10856 self.annotate_user_memaccess(
10857 memory_index,
10858 memarg,
10859 0,
10860 old.as_instruction_value().unwrap(),
10861 )?;
10862 self.state.push1(old);
10863 }
10864 Operator::I32AtomicRmw8OrU { ref memarg } => {
10865 let value = self.state.pop1()?.into_int_value();
10866 let offset = self.state.pop1()?.into_int_value();
10867 let memory_index = MemoryIndex::from_u32(0);
10868 let effective_address = self.resolve_memory_ptr(
10869 memory_index,
10870 memarg,
10871 self.intrinsics.ptr_ty,
10872 offset,
10873 1,
10874 )?;
10875 self.trap_if_misaligned(memarg, effective_address, 1)?;
10876 let narrow_value = err!(self.builder.build_int_truncate(
10877 value,
10878 self.intrinsics.i8_ty,
10879 ""
10880 ));
10881 let old = self
10882 .builder
10883 .build_atomicrmw(
10884 AtomicRMWBinOp::Or,
10885 effective_address,
10886 narrow_value,
10887 AtomicOrdering::SequentiallyConsistent,
10888 )
10889 .unwrap();
10890 self.annotate_user_memaccess(
10891 memory_index,
10892 memarg,
10893 0,
10894 old.as_instruction_value().unwrap(),
10895 )?;
10896 let old = err!(
10897 self.builder
10898 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10899 );
10900 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10901 }
10902 Operator::I32AtomicRmw16OrU { ref memarg } => {
10903 let value = self.state.pop1()?.into_int_value();
10904 let offset = self.state.pop1()?.into_int_value();
10905 let memory_index = MemoryIndex::from_u32(0);
10906 let effective_address = self.resolve_memory_ptr(
10907 memory_index,
10908 memarg,
10909 self.intrinsics.ptr_ty,
10910 offset,
10911 2,
10912 )?;
10913 self.trap_if_misaligned(memarg, effective_address, 2)?;
10914 let narrow_value = err!(self.builder.build_int_truncate(
10915 value,
10916 self.intrinsics.i16_ty,
10917 ""
10918 ));
10919 let old = self
10920 .builder
10921 .build_atomicrmw(
10922 AtomicRMWBinOp::Or,
10923 effective_address,
10924 narrow_value,
10925 AtomicOrdering::SequentiallyConsistent,
10926 )
10927 .unwrap();
10928 self.annotate_user_memaccess(
10929 memory_index,
10930 memarg,
10931 0,
10932 old.as_instruction_value().unwrap(),
10933 )?;
10934 let old = err!(
10935 self.builder
10936 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10937 );
10938 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10939 }
10940 Operator::I32AtomicRmwOr { ref memarg } => {
10941 let value = self.state.pop1()?.into_int_value();
10942 let offset = self.state.pop1()?.into_int_value();
10943 let memory_index = MemoryIndex::from_u32(0);
10944 let effective_address = self.resolve_memory_ptr(
10945 memory_index,
10946 memarg,
10947 self.intrinsics.ptr_ty,
10948 offset,
10949 4,
10950 )?;
10951 self.trap_if_misaligned(memarg, effective_address, 4)?;
10952 let old = self
10953 .builder
10954 .build_atomicrmw(
10955 AtomicRMWBinOp::Or,
10956 effective_address,
10957 value,
10958 AtomicOrdering::SequentiallyConsistent,
10959 )
10960 .unwrap();
10961 self.annotate_user_memaccess(
10962 memory_index,
10963 memarg,
10964 0,
10965 old.as_instruction_value().unwrap(),
10966 )?;
10967 let old = err!(
10968 self.builder
10969 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10970 );
10971 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10972 }
10973 Operator::I64AtomicRmw8OrU { ref memarg } => {
10974 let value = self.state.pop1()?.into_int_value();
10975 let offset = self.state.pop1()?.into_int_value();
10976 let memory_index = MemoryIndex::from_u32(0);
10977 let effective_address = self.resolve_memory_ptr(
10978 memory_index,
10979 memarg,
10980 self.intrinsics.ptr_ty,
10981 offset,
10982 1,
10983 )?;
10984 self.trap_if_misaligned(memarg, effective_address, 1)?;
10985 let narrow_value = err!(self.builder.build_int_truncate(
10986 value,
10987 self.intrinsics.i8_ty,
10988 ""
10989 ));
10990 let old = self
10991 .builder
10992 .build_atomicrmw(
10993 AtomicRMWBinOp::Or,
10994 effective_address,
10995 narrow_value,
10996 AtomicOrdering::SequentiallyConsistent,
10997 )
10998 .unwrap();
10999 self.annotate_user_memaccess(
11000 memory_index,
11001 memarg,
11002 0,
11003 old.as_instruction_value().unwrap(),
11004 )?;
11005 let old = err!(
11006 self.builder
11007 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11008 );
11009 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11010 }
11011 Operator::I64AtomicRmw16OrU { ref memarg } => {
11012 let value = self.state.pop1()?.into_int_value();
11013 let offset = self.state.pop1()?.into_int_value();
11014 let memory_index = MemoryIndex::from_u32(0);
11015 let effective_address = self.resolve_memory_ptr(
11016 memory_index,
11017 memarg,
11018 self.intrinsics.ptr_ty,
11019 offset,
11020 2,
11021 )?;
11022 self.trap_if_misaligned(memarg, effective_address, 2)?;
11023 let narrow_value = err!(self.builder.build_int_truncate(
11024 value,
11025 self.intrinsics.i16_ty,
11026 ""
11027 ));
11028 let old = self
11029 .builder
11030 .build_atomicrmw(
11031 AtomicRMWBinOp::Or,
11032 effective_address,
11033 narrow_value,
11034 AtomicOrdering::SequentiallyConsistent,
11035 )
11036 .unwrap();
11037 self.annotate_user_memaccess(
11038 memory_index,
11039 memarg,
11040 0,
11041 old.as_instruction_value().unwrap(),
11042 )?;
11043 let old = err!(
11044 self.builder
11045 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11046 );
11047 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11048 }
11049 Operator::I64AtomicRmw32OrU { ref memarg } => {
11050 let value = self.state.pop1()?.into_int_value();
11051 let offset = self.state.pop1()?.into_int_value();
11052 let memory_index = MemoryIndex::from_u32(0);
11053 let effective_address = self.resolve_memory_ptr(
11054 memory_index,
11055 memarg,
11056 self.intrinsics.ptr_ty,
11057 offset,
11058 4,
11059 )?;
11060 self.trap_if_misaligned(memarg, effective_address, 4)?;
11061 let narrow_value = err!(self.builder.build_int_truncate(
11062 value,
11063 self.intrinsics.i32_ty,
11064 ""
11065 ));
11066 let old = self
11067 .builder
11068 .build_atomicrmw(
11069 AtomicRMWBinOp::Or,
11070 effective_address,
11071 narrow_value,
11072 AtomicOrdering::SequentiallyConsistent,
11073 )
11074 .unwrap();
11075 self.annotate_user_memaccess(
11076 memory_index,
11077 memarg,
11078 0,
11079 old.as_instruction_value().unwrap(),
11080 )?;
11081 let old = err!(
11082 self.builder
11083 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11084 );
11085 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11086 }
11087 Operator::I64AtomicRmwOr { ref memarg } => {
11088 let value = self.state.pop1()?.into_int_value();
11089 let offset = self.state.pop1()?.into_int_value();
11090 let memory_index = MemoryIndex::from_u32(0);
11091 let effective_address = self.resolve_memory_ptr(
11092 memory_index,
11093 memarg,
11094 self.intrinsics.ptr_ty,
11095 offset,
11096 8,
11097 )?;
11098 self.trap_if_misaligned(memarg, effective_address, 8)?;
11099 let old = self
11100 .builder
11101 .build_atomicrmw(
11102 AtomicRMWBinOp::Or,
11103 effective_address,
11104 value,
11105 AtomicOrdering::SequentiallyConsistent,
11106 )
11107 .unwrap();
11108 self.annotate_user_memaccess(
11109 memory_index,
11110 memarg,
11111 0,
11112 old.as_instruction_value().unwrap(),
11113 )?;
11114 self.state.push1(old);
11115 }
11116 Operator::I32AtomicRmw8XorU { ref memarg } => {
11117 let value = self.state.pop1()?.into_int_value();
11118 let offset = self.state.pop1()?.into_int_value();
11119 let memory_index = MemoryIndex::from_u32(0);
11120 let effective_address = self.resolve_memory_ptr(
11121 memory_index,
11122 memarg,
11123 self.intrinsics.ptr_ty,
11124 offset,
11125 1,
11126 )?;
11127 self.trap_if_misaligned(memarg, effective_address, 2)?;
11128 let narrow_value = err!(self.builder.build_int_truncate(
11129 value,
11130 self.intrinsics.i8_ty,
11131 ""
11132 ));
11133 let old = self
11134 .builder
11135 .build_atomicrmw(
11136 AtomicRMWBinOp::Xor,
11137 effective_address,
11138 narrow_value,
11139 AtomicOrdering::SequentiallyConsistent,
11140 )
11141 .unwrap();
11142 self.annotate_user_memaccess(
11143 memory_index,
11144 memarg,
11145 0,
11146 old.as_instruction_value().unwrap(),
11147 )?;
11148 let old = err!(
11149 self.builder
11150 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11151 );
11152 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11153 }
11154 Operator::I32AtomicRmw16XorU { ref memarg } => {
11155 let value = self.state.pop1()?.into_int_value();
11156 let offset = self.state.pop1()?.into_int_value();
11157 let memory_index = MemoryIndex::from_u32(0);
11158 let effective_address = self.resolve_memory_ptr(
11159 memory_index,
11160 memarg,
11161 self.intrinsics.ptr_ty,
11162 offset,
11163 2,
11164 )?;
11165 self.trap_if_misaligned(memarg, effective_address, 2)?;
11166 let narrow_value = err!(self.builder.build_int_truncate(
11167 value,
11168 self.intrinsics.i16_ty,
11169 ""
11170 ));
11171 let old = self
11172 .builder
11173 .build_atomicrmw(
11174 AtomicRMWBinOp::Xor,
11175 effective_address,
11176 narrow_value,
11177 AtomicOrdering::SequentiallyConsistent,
11178 )
11179 .unwrap();
11180 self.annotate_user_memaccess(
11181 memory_index,
11182 memarg,
11183 0,
11184 old.as_instruction_value().unwrap(),
11185 )?;
11186 let old = err!(
11187 self.builder
11188 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11189 );
11190 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11191 }
11192 Operator::I32AtomicRmwXor { ref memarg } => {
11193 let value = self.state.pop1()?.into_int_value();
11194 let offset = self.state.pop1()?.into_int_value();
11195 let memory_index = MemoryIndex::from_u32(0);
11196 let effective_address = self.resolve_memory_ptr(
11197 memory_index,
11198 memarg,
11199 self.intrinsics.ptr_ty,
11200 offset,
11201 4,
11202 )?;
11203 self.trap_if_misaligned(memarg, effective_address, 4)?;
11204 let old = self
11205 .builder
11206 .build_atomicrmw(
11207 AtomicRMWBinOp::Xor,
11208 effective_address,
11209 value,
11210 AtomicOrdering::SequentiallyConsistent,
11211 )
11212 .unwrap();
11213 self.annotate_user_memaccess(
11214 memory_index,
11215 memarg,
11216 0,
11217 old.as_instruction_value().unwrap(),
11218 )?;
11219 self.state.push1(old);
11220 }
11221 Operator::I64AtomicRmw8XorU { ref memarg } => {
11222 let value = self.state.pop1()?.into_int_value();
11223 let offset = self.state.pop1()?.into_int_value();
11224 let memory_index = MemoryIndex::from_u32(0);
11225 let effective_address = self.resolve_memory_ptr(
11226 memory_index,
11227 memarg,
11228 self.intrinsics.ptr_ty,
11229 offset,
11230 1,
11231 )?;
11232 self.trap_if_misaligned(memarg, effective_address, 1)?;
11233 let narrow_value = err!(self.builder.build_int_truncate(
11234 value,
11235 self.intrinsics.i8_ty,
11236 ""
11237 ));
11238 let old = self
11239 .builder
11240 .build_atomicrmw(
11241 AtomicRMWBinOp::Xor,
11242 effective_address,
11243 narrow_value,
11244 AtomicOrdering::SequentiallyConsistent,
11245 )
11246 .unwrap();
11247 self.annotate_user_memaccess(
11248 memory_index,
11249 memarg,
11250 0,
11251 old.as_instruction_value().unwrap(),
11252 )?;
11253 let old = err!(
11254 self.builder
11255 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11256 );
11257 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11258 }
11259 Operator::I64AtomicRmw16XorU { ref memarg } => {
11260 let value = self.state.pop1()?.into_int_value();
11261 let offset = self.state.pop1()?.into_int_value();
11262 let memory_index = MemoryIndex::from_u32(0);
11263 let effective_address = self.resolve_memory_ptr(
11264 memory_index,
11265 memarg,
11266 self.intrinsics.ptr_ty,
11267 offset,
11268 2,
11269 )?;
11270 self.trap_if_misaligned(memarg, effective_address, 2)?;
11271 let narrow_value = err!(self.builder.build_int_truncate(
11272 value,
11273 self.intrinsics.i16_ty,
11274 ""
11275 ));
11276 let old = self
11277 .builder
11278 .build_atomicrmw(
11279 AtomicRMWBinOp::Xor,
11280 effective_address,
11281 narrow_value,
11282 AtomicOrdering::SequentiallyConsistent,
11283 )
11284 .unwrap();
11285 self.annotate_user_memaccess(
11286 memory_index,
11287 memarg,
11288 0,
11289 old.as_instruction_value().unwrap(),
11290 )?;
11291 let old = err!(
11292 self.builder
11293 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11294 );
11295 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11296 }
11297 Operator::I64AtomicRmw32XorU { ref memarg } => {
11298 let value = self.state.pop1()?.into_int_value();
11299 let offset = self.state.pop1()?.into_int_value();
11300 let memory_index = MemoryIndex::from_u32(0);
11301 let effective_address = self.resolve_memory_ptr(
11302 memory_index,
11303 memarg,
11304 self.intrinsics.ptr_ty,
11305 offset,
11306 4,
11307 )?;
11308 self.trap_if_misaligned(memarg, effective_address, 4)?;
11309 let narrow_value = err!(self.builder.build_int_truncate(
11310 value,
11311 self.intrinsics.i32_ty,
11312 ""
11313 ));
11314 let old = self
11315 .builder
11316 .build_atomicrmw(
11317 AtomicRMWBinOp::Xor,
11318 effective_address,
11319 narrow_value,
11320 AtomicOrdering::SequentiallyConsistent,
11321 )
11322 .unwrap();
11323 self.annotate_user_memaccess(
11324 memory_index,
11325 memarg,
11326 0,
11327 old.as_instruction_value().unwrap(),
11328 )?;
11329 let old = err!(
11330 self.builder
11331 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11332 );
11333 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11334 }
11335 Operator::I64AtomicRmwXor { ref memarg } => {
11336 let value = self.state.pop1()?.into_int_value();
11337 let offset = self.state.pop1()?.into_int_value();
11338 let memory_index = MemoryIndex::from_u32(0);
11339 let effective_address = self.resolve_memory_ptr(
11340 memory_index,
11341 memarg,
11342 self.intrinsics.ptr_ty,
11343 offset,
11344 8,
11345 )?;
11346 self.trap_if_misaligned(memarg, effective_address, 8)?;
11347 let old = self
11348 .builder
11349 .build_atomicrmw(
11350 AtomicRMWBinOp::Xor,
11351 effective_address,
11352 value,
11353 AtomicOrdering::SequentiallyConsistent,
11354 )
11355 .unwrap();
11356 self.annotate_user_memaccess(
11357 memory_index,
11358 memarg,
11359 0,
11360 old.as_instruction_value().unwrap(),
11361 )?;
11362 self.state.push1(old);
11363 }
11364 Operator::I32AtomicRmw8XchgU { ref memarg } => {
11365 let value = self.state.pop1()?.into_int_value();
11366 let offset = self.state.pop1()?.into_int_value();
11367 let memory_index = MemoryIndex::from_u32(0);
11368 let effective_address = self.resolve_memory_ptr(
11369 memory_index,
11370 memarg,
11371 self.intrinsics.ptr_ty,
11372 offset,
11373 1,
11374 )?;
11375 self.trap_if_misaligned(memarg, effective_address, 1)?;
11376 let narrow_value = err!(self.builder.build_int_truncate(
11377 value,
11378 self.intrinsics.i8_ty,
11379 ""
11380 ));
11381 let old = self
11382 .builder
11383 .build_atomicrmw(
11384 AtomicRMWBinOp::Xchg,
11385 effective_address,
11386 narrow_value,
11387 AtomicOrdering::SequentiallyConsistent,
11388 )
11389 .unwrap();
11390 self.annotate_user_memaccess(
11391 memory_index,
11392 memarg,
11393 0,
11394 old.as_instruction_value().unwrap(),
11395 )?;
11396 let old = err!(
11397 self.builder
11398 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11399 );
11400 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11401 }
11402 Operator::I32AtomicRmw16XchgU { ref memarg } => {
11403 let value = self.state.pop1()?.into_int_value();
11404 let offset = self.state.pop1()?.into_int_value();
11405 let memory_index = MemoryIndex::from_u32(0);
11406 let effective_address = self.resolve_memory_ptr(
11407 memory_index,
11408 memarg,
11409 self.intrinsics.ptr_ty,
11410 offset,
11411 2,
11412 )?;
11413 self.trap_if_misaligned(memarg, effective_address, 2)?;
11414 let narrow_value = err!(self.builder.build_int_truncate(
11415 value,
11416 self.intrinsics.i16_ty,
11417 ""
11418 ));
11419 let old = self
11420 .builder
11421 .build_atomicrmw(
11422 AtomicRMWBinOp::Xchg,
11423 effective_address,
11424 narrow_value,
11425 AtomicOrdering::SequentiallyConsistent,
11426 )
11427 .unwrap();
11428 self.annotate_user_memaccess(
11429 memory_index,
11430 memarg,
11431 0,
11432 old.as_instruction_value().unwrap(),
11433 )?;
11434 let old = err!(
11435 self.builder
11436 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11437 );
11438 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11439 }
11440 Operator::I32AtomicRmwXchg { ref memarg } => {
11441 let value = self.state.pop1()?.into_int_value();
11442 let offset = self.state.pop1()?.into_int_value();
11443 let memory_index = MemoryIndex::from_u32(0);
11444 let effective_address = self.resolve_memory_ptr(
11445 memory_index,
11446 memarg,
11447 self.intrinsics.ptr_ty,
11448 offset,
11449 4,
11450 )?;
11451 self.trap_if_misaligned(memarg, effective_address, 4)?;
11452 let old = self
11453 .builder
11454 .build_atomicrmw(
11455 AtomicRMWBinOp::Xchg,
11456 effective_address,
11457 value,
11458 AtomicOrdering::SequentiallyConsistent,
11459 )
11460 .unwrap();
11461 self.annotate_user_memaccess(
11462 memory_index,
11463 memarg,
11464 0,
11465 old.as_instruction_value().unwrap(),
11466 )?;
11467 self.state.push1(old);
11468 }
11469 Operator::I64AtomicRmw8XchgU { ref memarg } => {
11470 let value = self.state.pop1()?.into_int_value();
11471 let offset = self.state.pop1()?.into_int_value();
11472 let memory_index = MemoryIndex::from_u32(0);
11473 let effective_address = self.resolve_memory_ptr(
11474 memory_index,
11475 memarg,
11476 self.intrinsics.ptr_ty,
11477 offset,
11478 1,
11479 )?;
11480 self.trap_if_misaligned(memarg, effective_address, 1)?;
11481 let narrow_value = err!(self.builder.build_int_truncate(
11482 value,
11483 self.intrinsics.i8_ty,
11484 ""
11485 ));
11486 let old = self
11487 .builder
11488 .build_atomicrmw(
11489 AtomicRMWBinOp::Xchg,
11490 effective_address,
11491 narrow_value,
11492 AtomicOrdering::SequentiallyConsistent,
11493 )
11494 .unwrap();
11495 self.annotate_user_memaccess(
11496 memory_index,
11497 memarg,
11498 0,
11499 old.as_instruction_value().unwrap(),
11500 )?;
11501 let old = err!(
11502 self.builder
11503 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11504 );
11505 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11506 }
11507 Operator::I64AtomicRmw16XchgU { ref memarg } => {
11508 let value = self.state.pop1()?.into_int_value();
11509 let offset = self.state.pop1()?.into_int_value();
11510 let memory_index = MemoryIndex::from_u32(0);
11511 let effective_address = self.resolve_memory_ptr(
11512 memory_index,
11513 memarg,
11514 self.intrinsics.ptr_ty,
11515 offset,
11516 2,
11517 )?;
11518 self.trap_if_misaligned(memarg, effective_address, 2)?;
11519 let narrow_value = err!(self.builder.build_int_truncate(
11520 value,
11521 self.intrinsics.i16_ty,
11522 ""
11523 ));
11524 let old = self
11525 .builder
11526 .build_atomicrmw(
11527 AtomicRMWBinOp::Xchg,
11528 effective_address,
11529 narrow_value,
11530 AtomicOrdering::SequentiallyConsistent,
11531 )
11532 .unwrap();
11533 self.annotate_user_memaccess(
11534 memory_index,
11535 memarg,
11536 0,
11537 old.as_instruction_value().unwrap(),
11538 )?;
11539 let old = err!(
11540 self.builder
11541 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11542 );
11543 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11544 }
11545 Operator::I64AtomicRmw32XchgU { ref memarg } => {
11546 let value = self.state.pop1()?.into_int_value();
11547 let offset = self.state.pop1()?.into_int_value();
11548 let memory_index = MemoryIndex::from_u32(0);
11549 let effective_address = self.resolve_memory_ptr(
11550 memory_index,
11551 memarg,
11552 self.intrinsics.ptr_ty,
11553 offset,
11554 4,
11555 )?;
11556 self.trap_if_misaligned(memarg, effective_address, 4)?;
11557 let narrow_value = err!(self.builder.build_int_truncate(
11558 value,
11559 self.intrinsics.i32_ty,
11560 ""
11561 ));
11562 let old = self
11563 .builder
11564 .build_atomicrmw(
11565 AtomicRMWBinOp::Xchg,
11566 effective_address,
11567 narrow_value,
11568 AtomicOrdering::SequentiallyConsistent,
11569 )
11570 .unwrap();
11571 self.annotate_user_memaccess(
11572 memory_index,
11573 memarg,
11574 0,
11575 old.as_instruction_value().unwrap(),
11576 )?;
11577 let old = err!(
11578 self.builder
11579 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11580 );
11581 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11582 }
11583 Operator::I64AtomicRmwXchg { ref memarg } => {
11584 let value = self.state.pop1()?.into_int_value();
11585 let offset = self.state.pop1()?.into_int_value();
11586 let memory_index = MemoryIndex::from_u32(0);
11587 let effective_address = self.resolve_memory_ptr(
11588 memory_index,
11589 memarg,
11590 self.intrinsics.ptr_ty,
11591 offset,
11592 8,
11593 )?;
11594 self.trap_if_misaligned(memarg, effective_address, 8)?;
11595 let old = self
11596 .builder
11597 .build_atomicrmw(
11598 AtomicRMWBinOp::Xchg,
11599 effective_address,
11600 value,
11601 AtomicOrdering::SequentiallyConsistent,
11602 )
11603 .unwrap();
11604 self.annotate_user_memaccess(
11605 memory_index,
11606 memarg,
11607 0,
11608 old.as_instruction_value().unwrap(),
11609 )?;
11610 self.state.push1(old);
11611 }
11612 Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
11613 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11614 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11615 let new = self.apply_pending_canonicalization(new, new_info)?;
11616 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11617 let offset = self.state.pop1()?.into_int_value();
11618 let memory_index = MemoryIndex::from_u32(0);
11619 let effective_address = self.resolve_memory_ptr(
11620 memory_index,
11621 memarg,
11622 self.intrinsics.ptr_ty,
11623 offset,
11624 1,
11625 )?;
11626 self.trap_if_misaligned(memarg, effective_address, 1)?;
11627 let narrow_cmp = err!(self.builder.build_int_truncate(
11628 cmp,
11629 self.intrinsics.i8_ty,
11630 ""
11631 ));
11632 let narrow_new = err!(self.builder.build_int_truncate(
11633 new,
11634 self.intrinsics.i8_ty,
11635 ""
11636 ));
11637 let old = self
11638 .builder
11639 .build_cmpxchg(
11640 effective_address,
11641 narrow_cmp,
11642 narrow_new,
11643 AtomicOrdering::SequentiallyConsistent,
11644 AtomicOrdering::SequentiallyConsistent,
11645 )
11646 .unwrap();
11647 self.annotate_user_memaccess(
11648 memory_index,
11649 memarg,
11650 0,
11651 old.as_instruction_value().unwrap(),
11652 )?;
11653 let old = self
11654 .builder
11655 .build_extract_value(old, 0, "")
11656 .unwrap()
11657 .into_int_value();
11658 let old = err!(
11659 self.builder
11660 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11661 );
11662 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11663 }
11664 Operator::I32AtomicRmw16CmpxchgU { ref memarg } => {
11665 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11666 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11667 let new = self.apply_pending_canonicalization(new, new_info)?;
11668 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11669 let offset = self.state.pop1()?.into_int_value();
11670 let memory_index = MemoryIndex::from_u32(0);
11671 let effective_address = self.resolve_memory_ptr(
11672 memory_index,
11673 memarg,
11674 self.intrinsics.ptr_ty,
11675 offset,
11676 2,
11677 )?;
11678 self.trap_if_misaligned(memarg, effective_address, 2)?;
11679 let narrow_cmp = err!(self.builder.build_int_truncate(
11680 cmp,
11681 self.intrinsics.i16_ty,
11682 ""
11683 ));
11684 let narrow_new = err!(self.builder.build_int_truncate(
11685 new,
11686 self.intrinsics.i16_ty,
11687 ""
11688 ));
11689 let old = self
11690 .builder
11691 .build_cmpxchg(
11692 effective_address,
11693 narrow_cmp,
11694 narrow_new,
11695 AtomicOrdering::SequentiallyConsistent,
11696 AtomicOrdering::SequentiallyConsistent,
11697 )
11698 .unwrap();
11699 self.annotate_user_memaccess(
11700 memory_index,
11701 memarg,
11702 0,
11703 old.as_instruction_value().unwrap(),
11704 )?;
11705 let old = self
11706 .builder
11707 .build_extract_value(old, 0, "")
11708 .unwrap()
11709 .into_int_value();
11710 let old = err!(
11711 self.builder
11712 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11713 );
11714 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11715 }
11716 Operator::I32AtomicRmwCmpxchg { ref memarg } => {
11717 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11718 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11719 let new = self.apply_pending_canonicalization(new, new_info)?;
11720 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11721 let offset = self.state.pop1()?.into_int_value();
11722 let memory_index = MemoryIndex::from_u32(0);
11723 let effective_address = self.resolve_memory_ptr(
11724 memory_index,
11725 memarg,
11726 self.intrinsics.ptr_ty,
11727 offset,
11728 4,
11729 )?;
11730 self.trap_if_misaligned(memarg, effective_address, 4)?;
11731 let old = self
11732 .builder
11733 .build_cmpxchg(
11734 effective_address,
11735 cmp,
11736 new,
11737 AtomicOrdering::SequentiallyConsistent,
11738 AtomicOrdering::SequentiallyConsistent,
11739 )
11740 .unwrap();
11741 self.annotate_user_memaccess(
11742 memory_index,
11743 memarg,
11744 0,
11745 old.as_instruction_value().unwrap(),
11746 )?;
11747 let old = err!(self.builder.build_extract_value(old, 0, ""));
11748 self.state.push1(old);
11749 }
11750 Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
11751 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11752 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11753 let new = self.apply_pending_canonicalization(new, new_info)?;
11754 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11755 let offset = self.state.pop1()?.into_int_value();
11756 let memory_index = MemoryIndex::from_u32(0);
11757 let effective_address = self.resolve_memory_ptr(
11758 memory_index,
11759 memarg,
11760 self.intrinsics.ptr_ty,
11761 offset,
11762 1,
11763 )?;
11764 self.trap_if_misaligned(memarg, effective_address, 1)?;
11765 let narrow_cmp = err!(self.builder.build_int_truncate(
11766 cmp,
11767 self.intrinsics.i8_ty,
11768 ""
11769 ));
11770 let narrow_new = err!(self.builder.build_int_truncate(
11771 new,
11772 self.intrinsics.i8_ty,
11773 ""
11774 ));
11775 let old = self
11776 .builder
11777 .build_cmpxchg(
11778 effective_address,
11779 narrow_cmp,
11780 narrow_new,
11781 AtomicOrdering::SequentiallyConsistent,
11782 AtomicOrdering::SequentiallyConsistent,
11783 )
11784 .unwrap();
11785 self.annotate_user_memaccess(
11786 memory_index,
11787 memarg,
11788 0,
11789 old.as_instruction_value().unwrap(),
11790 )?;
11791 let old = self
11792 .builder
11793 .build_extract_value(old, 0, "")
11794 .unwrap()
11795 .into_int_value();
11796 let old = err!(
11797 self.builder
11798 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11799 );
11800 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11801 }
11802 Operator::I64AtomicRmw16CmpxchgU { ref memarg } => {
11803 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11804 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11805 let new = self.apply_pending_canonicalization(new, new_info)?;
11806 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11807 let offset = self.state.pop1()?.into_int_value();
11808 let memory_index = MemoryIndex::from_u32(0);
11809 let effective_address = self.resolve_memory_ptr(
11810 memory_index,
11811 memarg,
11812 self.intrinsics.ptr_ty,
11813 offset,
11814 2,
11815 )?;
11816 self.trap_if_misaligned(memarg, effective_address, 2)?;
11817 let narrow_cmp = err!(self.builder.build_int_truncate(
11818 cmp,
11819 self.intrinsics.i16_ty,
11820 ""
11821 ));
11822 let narrow_new = err!(self.builder.build_int_truncate(
11823 new,
11824 self.intrinsics.i16_ty,
11825 ""
11826 ));
11827 let old = self
11828 .builder
11829 .build_cmpxchg(
11830 effective_address,
11831 narrow_cmp,
11832 narrow_new,
11833 AtomicOrdering::SequentiallyConsistent,
11834 AtomicOrdering::SequentiallyConsistent,
11835 )
11836 .unwrap();
11837 self.annotate_user_memaccess(
11838 memory_index,
11839 memarg,
11840 0,
11841 old.as_instruction_value().unwrap(),
11842 )?;
11843 let old = self
11844 .builder
11845 .build_extract_value(old, 0, "")
11846 .unwrap()
11847 .into_int_value();
11848 let old = err!(
11849 self.builder
11850 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11851 );
11852 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11853 }
11854 Operator::I64AtomicRmw32CmpxchgU { ref memarg } => {
11855 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11856 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11857 let new = self.apply_pending_canonicalization(new, new_info)?;
11858 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11859 let offset = self.state.pop1()?.into_int_value();
11860 let memory_index = MemoryIndex::from_u32(0);
11861 let effective_address = self.resolve_memory_ptr(
11862 memory_index,
11863 memarg,
11864 self.intrinsics.ptr_ty,
11865 offset,
11866 4,
11867 )?;
11868 self.trap_if_misaligned(memarg, effective_address, 4)?;
11869 let narrow_cmp = err!(self.builder.build_int_truncate(
11870 cmp,
11871 self.intrinsics.i32_ty,
11872 ""
11873 ));
11874 let narrow_new = err!(self.builder.build_int_truncate(
11875 new,
11876 self.intrinsics.i32_ty,
11877 ""
11878 ));
11879 let old = self
11880 .builder
11881 .build_cmpxchg(
11882 effective_address,
11883 narrow_cmp,
11884 narrow_new,
11885 AtomicOrdering::SequentiallyConsistent,
11886 AtomicOrdering::SequentiallyConsistent,
11887 )
11888 .unwrap();
11889 self.annotate_user_memaccess(
11890 memory_index,
11891 memarg,
11892 0,
11893 old.as_instruction_value().unwrap(),
11894 )?;
11895 let old = self
11896 .builder
11897 .build_extract_value(old, 0, "")
11898 .unwrap()
11899 .into_int_value();
11900 let old = err!(
11901 self.builder
11902 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11903 );
11904 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11905 }
11906 Operator::I64AtomicRmwCmpxchg { ref memarg } => {
11907 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11908 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11909 let new = self.apply_pending_canonicalization(new, new_info)?;
11910 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11911 let offset = self.state.pop1()?.into_int_value();
11912 let memory_index = MemoryIndex::from_u32(0);
11913 let effective_address = self.resolve_memory_ptr(
11914 memory_index,
11915 memarg,
11916 self.intrinsics.ptr_ty,
11917 offset,
11918 8,
11919 )?;
11920 self.trap_if_misaligned(memarg, effective_address, 8)?;
11921 let old = self
11922 .builder
11923 .build_cmpxchg(
11924 effective_address,
11925 cmp,
11926 new,
11927 AtomicOrdering::SequentiallyConsistent,
11928 AtomicOrdering::SequentiallyConsistent,
11929 )
11930 .unwrap();
11931 self.annotate_user_memaccess(
11932 memory_index,
11933 memarg,
11934 0,
11935 old.as_instruction_value().unwrap(),
11936 )?;
11937 let old = err!(self.builder.build_extract_value(old, 0, ""));
11938 self.state.push1(old);
11939 }
11940
11941 Operator::MemoryGrow { mem } => {
11942 let memory_index = MemoryIndex::from_u32(mem);
11943 let delta = self.state.pop1()?;
11944 let grow_fn_ptr = self.ctx.memory_grow(memory_index, self.intrinsics)?;
11945 let grow = err!(self.builder.build_indirect_call(
11946 self.intrinsics.memory_grow_ty,
11947 grow_fn_ptr,
11948 &[
11949 vmctx.as_basic_value_enum().into(),
11950 delta.into(),
11951 self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11952 ],
11953 "",
11954 ));
11955 self.state.push1(grow.try_as_basic_value().unwrap_basic());
11956 }
11957 Operator::MemorySize { mem } => {
11958 let memory_index = MemoryIndex::from_u32(mem);
11959 let size_fn_ptr = self.ctx.memory_size(memory_index, self.intrinsics)?;
11960 let size = err!(self.builder.build_indirect_call(
11961 self.intrinsics.memory_size_ty,
11962 size_fn_ptr,
11963 &[
11964 vmctx.as_basic_value_enum().into(),
11965 self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11966 ],
11967 "",
11968 ));
11969 self.state.push1(size.try_as_basic_value().unwrap_basic());
11971 }
11972 Operator::MemoryInit { data_index, mem } => {
11973 let (dest, src, len) = self.state.pop3()?;
11974 let mem = self.intrinsics.i32_ty.const_int(mem.into(), false);
11975 let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11976 err!(self.builder.build_call(
11977 self.intrinsics.memory_init,
11978 &[
11979 vmctx.as_basic_value_enum().into(),
11980 mem.into(),
11981 segment.into(),
11982 dest.into(),
11983 src.into(),
11984 len.into(),
11985 ],
11986 "",
11987 ));
11988 }
11989 Operator::DataDrop { data_index } => {
11990 let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11991 err!(self.builder.build_call(
11992 self.intrinsics.data_drop,
11993 &[vmctx.as_basic_value_enum().into(), segment.into()],
11994 "",
11995 ));
11996 }
11997 Operator::MemoryCopy { dst_mem, src_mem } => {
11998 let _dst = dst_mem;
12000 let (memory_copy, src) = if let Some(local_memory_index) = self
12001 .wasm_module
12002 .local_memory_index(MemoryIndex::from_u32(src_mem))
12003 {
12004 (self.intrinsics.memory_copy, local_memory_index.as_u32())
12005 } else {
12006 (self.intrinsics.imported_memory_copy, src_mem)
12007 };
12008
12009 let (dest_pos, src_pos, len) = self.state.pop3()?;
12010 let src_index = self.intrinsics.i32_ty.const_int(src.into(), false);
12011 err!(self.builder.build_call(
12012 memory_copy,
12013 &[
12014 vmctx.as_basic_value_enum().into(),
12015 src_index.into(),
12016 dest_pos.into(),
12017 src_pos.into(),
12018 len.into(),
12019 ],
12020 "",
12021 ));
12022 }
12023 Operator::MemoryFill { mem } => {
12024 let (memory_fill, mem) = if let Some(local_memory_index) = self
12025 .wasm_module
12026 .local_memory_index(MemoryIndex::from_u32(mem))
12027 {
12028 (self.intrinsics.memory_fill, local_memory_index.as_u32())
12029 } else {
12030 (self.intrinsics.imported_memory_fill, mem)
12031 };
12032
12033 let (dst, val, len) = self.state.pop3()?;
12034 let mem_index = self.intrinsics.i32_ty.const_int(mem.into(), false);
12035 err!(self.builder.build_call(
12036 memory_fill,
12037 &[
12038 vmctx.as_basic_value_enum().into(),
12039 mem_index.into(),
12040 dst.into(),
12041 val.into(),
12042 len.into(),
12043 ],
12044 "",
12045 ));
12046 }
12047 Operator::RefNull { hty } => {
12052 let ty = err!(wpheaptype_to_type(hty));
12053 let ty = type_to_llvm(self.intrinsics, ty)?;
12054 self.state.push1(ty.const_zero());
12055 }
12056 Operator::RefIsNull => {
12057 let value = self.state.pop1()?.into_pointer_value();
12058 let is_null = err!(self.builder.build_is_null(value, ""));
12059 let is_null = err!(self.builder.build_int_z_extend(
12060 is_null,
12061 self.intrinsics.i32_ty,
12062 ""
12063 ));
12064 self.state.push1(is_null);
12065 }
12066 Operator::RefFunc { function_index } => {
12067 let index = self
12068 .intrinsics
12069 .i32_ty
12070 .const_int(function_index.into(), false);
12071 let value = err!(self.builder.build_call(
12072 self.intrinsics.func_ref,
12073 &[self.ctx.basic().into(), index.into()],
12074 "",
12075 ))
12076 .try_as_basic_value()
12077 .unwrap_basic();
12078 self.state.push1(value);
12079 }
12080 Operator::TableGet { table } => {
12081 let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12082 let elem = self.state.pop1()?;
12083 let table_get = if self
12084 .wasm_module
12085 .local_table_index(TableIndex::from_u32(table))
12086 .is_some()
12087 {
12088 self.intrinsics.table_get
12089 } else {
12090 self.intrinsics.imported_table_get
12091 };
12092 let value = err!(self.builder.build_call(
12093 table_get,
12094 &[self.ctx.basic().into(), table_index.into(), elem.into()],
12095 "",
12096 ))
12097 .try_as_basic_value()
12098 .unwrap_basic();
12099 let value = err!(
12100 self.builder.build_bit_cast(
12101 value,
12102 type_to_llvm(
12103 self.intrinsics,
12104 self.wasm_module
12105 .tables
12106 .get(TableIndex::from_u32(table))
12107 .unwrap()
12108 .ty,
12109 )?,
12110 "",
12111 )
12112 );
12113 self.state.push1(value);
12114 }
12115 Operator::TableSet { table } => {
12116 let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12117 let (elem, value) = self.state.pop2()?;
12118 let value = err!(
12119 self.builder
12120 .build_bit_cast(value, self.intrinsics.ptr_ty, "")
12121 );
12122 let table_set = if self
12123 .wasm_module
12124 .local_table_index(TableIndex::from_u32(table))
12125 .is_some()
12126 {
12127 self.intrinsics.table_set
12128 } else {
12129 self.intrinsics.imported_table_set
12130 };
12131 err!(self.builder.build_call(
12132 table_set,
12133 &[
12134 self.ctx.basic().into(),
12135 table_index.into(),
12136 elem.into(),
12137 value.into(),
12138 ],
12139 "",
12140 ));
12141 }
12142 Operator::TableCopy {
12143 dst_table,
12144 src_table,
12145 } => {
12146 let (dst, src, len) = self.state.pop3()?;
12147 let dst_table = self.intrinsics.i32_ty.const_int(dst_table as u64, false);
12148 let src_table = self.intrinsics.i32_ty.const_int(src_table as u64, false);
12149 err!(self.builder.build_call(
12150 self.intrinsics.table_copy,
12151 &[
12152 self.ctx.basic().into(),
12153 dst_table.into(),
12154 src_table.into(),
12155 dst.into(),
12156 src.into(),
12157 len.into(),
12158 ],
12159 "",
12160 ));
12161 }
12162 Operator::TableInit { elem_index, table } => {
12163 let (dst, src, len) = self.state.pop3()?;
12164 let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12165 let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12166 err!(self.builder.build_call(
12167 self.intrinsics.table_init,
12168 &[
12169 self.ctx.basic().into(),
12170 table.into(),
12171 segment.into(),
12172 dst.into(),
12173 src.into(),
12174 len.into(),
12175 ],
12176 "",
12177 ));
12178 }
12179 Operator::ElemDrop { elem_index } => {
12180 let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12181 err!(self.builder.build_call(
12182 self.intrinsics.elem_drop,
12183 &[self.ctx.basic().into(), segment.into()],
12184 "",
12185 ));
12186 }
12187 Operator::TableFill { table } => {
12188 let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12189 let (start, elem, len) = self.state.pop3()?;
12190 let elem = err!(
12191 self.builder
12192 .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12193 );
12194 err!(self.builder.build_call(
12195 self.intrinsics.table_fill,
12196 &[
12197 self.ctx.basic().into(),
12198 table.into(),
12199 start.into(),
12200 elem.into(),
12201 len.into(),
12202 ],
12203 "",
12204 ));
12205 }
12206 Operator::TableGrow { table } => {
12207 let (elem, delta) = self.state.pop2()?;
12208 let elem = err!(
12209 self.builder
12210 .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12211 );
12212 let (table_grow, table_index) = if let Some(local_table_index) = self
12213 .wasm_module
12214 .local_table_index(TableIndex::from_u32(table))
12215 {
12216 (self.intrinsics.table_grow, local_table_index.as_u32())
12217 } else {
12218 (self.intrinsics.imported_table_grow, table)
12219 };
12220 let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12221 let size = err!(self.builder.build_call(
12222 table_grow,
12223 &[
12224 self.ctx.basic().into(),
12225 elem.into(),
12226 delta.into(),
12227 table_index.into(),
12228 ],
12229 "",
12230 ))
12231 .try_as_basic_value()
12232 .unwrap_basic();
12233 self.state.push1(size);
12234 }
12235 Operator::TableSize { table } => {
12236 let (table_size, table_index) = if let Some(local_table_index) = self
12237 .wasm_module
12238 .local_table_index(TableIndex::from_u32(table))
12239 {
12240 (self.intrinsics.table_size, local_table_index.as_u32())
12241 } else {
12242 (self.intrinsics.imported_table_size, table)
12243 };
12244 let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12245 let size = err!(self.builder.build_call(
12246 table_size,
12247 &[self.ctx.basic().into(), table_index.into()],
12248 "",
12249 ))
12250 .try_as_basic_value()
12251 .unwrap_basic();
12252 self.state.push1(size);
12253 }
12254 Operator::MemoryAtomicWait32 { memarg } => {
12255 let memory_index = MemoryIndex::from_u32(memarg.memory);
12256 let (dst, val, timeout) = self.state.pop3()?;
12257 let wait32_fn_ptr = self.ctx.memory_wait32(memory_index, self.intrinsics)?;
12258 let ret = err!(
12259 self.builder.build_indirect_call(
12260 self.intrinsics.memory_wait32_ty,
12261 wait32_fn_ptr,
12262 &[
12263 vmctx.as_basic_value_enum().into(),
12264 self.intrinsics
12265 .i32_ty
12266 .const_int(memarg.memory as u64, false)
12267 .into(),
12268 dst.into(),
12269 val.into(),
12270 timeout.into(),
12271 ],
12272 "",
12273 )
12274 );
12275 self.state.push1(ret.try_as_basic_value().unwrap_basic());
12276 }
12277 Operator::MemoryAtomicWait64 { memarg } => {
12278 let memory_index = MemoryIndex::from_u32(memarg.memory);
12279 let (dst, val, timeout) = self.state.pop3()?;
12280 let wait64_fn_ptr = self.ctx.memory_wait64(memory_index, self.intrinsics)?;
12281 let ret = err!(
12282 self.builder.build_indirect_call(
12283 self.intrinsics.memory_wait64_ty,
12284 wait64_fn_ptr,
12285 &[
12286 vmctx.as_basic_value_enum().into(),
12287 self.intrinsics
12288 .i32_ty
12289 .const_int(memarg.memory as u64, false)
12290 .into(),
12291 dst.into(),
12292 val.into(),
12293 timeout.into(),
12294 ],
12295 "",
12296 )
12297 );
12298 self.state.push1(ret.try_as_basic_value().unwrap_basic());
12299 }
12300 Operator::MemoryAtomicNotify { memarg } => {
12301 let memory_index = MemoryIndex::from_u32(memarg.memory);
12302 let (dst, count) = self.state.pop2()?;
12303 let notify_fn_ptr = self.ctx.memory_notify(memory_index, self.intrinsics)?;
12304 let cnt = err!(
12305 self.builder.build_indirect_call(
12306 self.intrinsics.memory_notify_ty,
12307 notify_fn_ptr,
12308 &[
12309 vmctx.as_basic_value_enum().into(),
12310 self.intrinsics
12311 .i32_ty
12312 .const_int(memarg.memory as u64, false)
12313 .into(),
12314 dst.into(),
12315 count.into(),
12316 ],
12317 "",
12318 )
12319 );
12320 self.state.push1(cnt.try_as_basic_value().unwrap_basic());
12321 }
12322
12323 Operator::TryTable { try_table } => {
12324 let current_block = self
12325 .builder
12326 .get_insert_block()
12327 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12328
12329 self.builder.position_at_end(current_block);
12330
12331 let end_block = self.context.append_basic_block(self.function, "try_end");
12332
12333 let end_phis = {
12334 self.builder.position_at_end(end_block);
12335
12336 let phis = self
12337 .module_translation
12338 .blocktype_params_results(&try_table.ty)?
12339 .1
12340 .iter()
12341 .map(|&wp_ty| {
12342 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
12343 type_to_llvm(self.intrinsics, wasm_ty)
12344 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
12345 })
12346 })
12347 .collect::<Result<_, _>>()?;
12348
12349 self.builder.position_at_end(current_block);
12350 phis
12351 };
12352
12353 let catches: Vec<_> = try_table
12357 .catches
12358 .into_iter()
12359 .unique_by(|v| match v {
12360 Catch::One { tag, .. } | Catch::OneRef { tag, .. } => *tag as i32,
12361 Catch::All { .. } | Catch::AllRef { .. } => CATCH_ALL_TAG_VALUE,
12362 })
12363 .collect();
12364
12365 let null = self.intrinsics.ptr_ty.const_zero();
12367
12368 let mut catch_tag_values = vec![];
12369 let mut lpad_clauses: Vec<BasicValueEnum<'ctx>> = catches
12370 .iter()
12371 .map(|catch| match catch {
12372 Catch::All { .. } | Catch::AllRef { .. } => {
12373 catch_tag_values.push(CATCH_ALL_TAG_VALUE as u32);
12374 Ok(null.into())
12375 }
12376 Catch::One { tag, .. } | Catch::OneRef { tag, .. } => {
12377 catch_tag_values.push(*tag);
12378 Ok(self.get_or_insert_tag_type_info_global(*tag as i32))
12379 }
12380 })
12381 .collect::<Result<Vec<BasicValueEnum<'ctx>>, CompileError>>()?;
12382
12383 let mut outer_catch_blocks = vec![];
12387 for outer_landingpad in self.state.landingpads.iter().rev() {
12388 for catch_info @ TagCatchInfo { tag, .. } in &outer_landingpad.tags {
12389 if !catch_tag_values.contains(tag) {
12390 catch_tag_values.push(*tag);
12391 lpad_clauses.push(if *tag as i32 == CATCH_ALL_TAG_VALUE {
12392 null.into()
12393 } else {
12394 *self.tags_cache.get(&(*tag as i32)).expect(
12395 "If a previous try_table encountered a tag, \
12396 it should be in the cache",
12397 )
12398 });
12399 outer_catch_blocks.push(*catch_info);
12400 }
12401 }
12402 }
12403
12404 let mut maybe_lpad_block = None;
12408 let mut catch_blocks = vec![];
12409 if !lpad_clauses.is_empty() {
12410 let lpad_block = self.context.append_basic_block(self.function, "catch");
12411 let catch_all_block =
12412 self.context.append_basic_block(self.function, "catch_all");
12413 let catch_specific_block = self
12414 .context
12415 .append_basic_block(self.function, "catch_specific");
12416 let catch_end_block =
12417 self.context.append_basic_block(self.function, "catch_end");
12418 let rethrow_block = self.context.append_basic_block(self.function, "rethrow");
12419
12420 self.builder.position_at_end(lpad_block);
12421
12422 let res = err!(self.builder.build_landing_pad(
12423 self.intrinsics.lpad_exception_ty,
12424 self.intrinsics.personality,
12425 &lpad_clauses,
12426 false,
12427 "exc_struct",
12428 ));
12429
12430 let res = res.into_struct_value();
12431
12432 let uw_exc = err!(self.builder.build_extract_value(res, 0, "exc_ptr"));
12433 let pre_selector =
12434 err!(self.builder.build_extract_value(res, 1, "pre_selector"));
12435
12436 let pre_selector_is_zero = err!(self.builder.build_int_compare(
12439 IntPredicate::EQ,
12440 pre_selector.into_int_value(),
12441 self.intrinsics.i32_zero,
12442 "pre_selector_is_zero"
12443 ));
12444 err!(self.builder.build_conditional_branch(
12445 pre_selector_is_zero,
12446 catch_all_block,
12447 catch_specific_block
12448 ));
12449
12450 self.builder.position_at_end(catch_all_block);
12451 err!(self.builder.build_unconditional_branch(catch_end_block));
12452
12453 self.builder.position_at_end(catch_specific_block);
12454 let selector_value = err!(self.builder.build_call(
12455 self.intrinsics.personality2,
12456 &[self.ctx.basic().into(), uw_exc.into()],
12457 "selector"
12458 ));
12459 err!(self.builder.build_unconditional_branch(catch_end_block));
12460
12461 self.builder.position_at_end(catch_end_block);
12462 let selector = err!(self.builder.build_phi(self.intrinsics.i32_ty, "selector"));
12463 selector.add_incoming(&[
12464 (
12465 &self
12466 .intrinsics
12467 .i32_ty
12468 .const_int(CATCH_ALL_TAG_VALUE as u64, false),
12469 catch_all_block,
12470 ),
12471 (
12472 &selector_value
12473 .try_as_basic_value()
12474 .unwrap_basic()
12475 .into_int_value(),
12476 catch_specific_block,
12477 ),
12478 ]);
12479
12480 let uw_exc = uw_exc.into_pointer_value();
12525 let exnref = err!(self.builder.build_call(
12526 self.intrinsics.exception_into_exnref,
12527 &[uw_exc.into()],
12528 "exnref"
12529 ));
12530
12531 let exnref = exnref.try_as_basic_value().unwrap_basic().into_int_value();
12532 let selector = selector.as_basic_value().into_int_value();
12533
12534 for catch in catches.iter() {
12535 match catch {
12536 Catch::All { label } => {
12537 let b = self
12538 .context
12539 .append_basic_block(self.function, "catch_all_clause");
12540 self.builder.position_at_end(b);
12541 let frame = self.state.frame_at_depth(*label)?;
12542
12543 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12544
12545 self.builder.position_at_end(catch_end_block);
12546 catch_blocks.push((b, None));
12547 }
12548 Catch::One { tag, label } => {
12549 let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12550 let signature = &self.wasm_module.signatures[tag_idx];
12551 let params = signature.params();
12552
12553 let b = self.context.append_basic_block(
12554 self.function,
12555 format!("catch_one_clause_{tag}").as_str(),
12556 );
12557 self.builder.position_at_end(b);
12558
12559 let exnref_phi = err!(
12560 self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12561 );
12562 exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12563
12564 let exn_payload_ptr = err!(self.builder.build_direct_call(
12566 self.intrinsics.read_exnref,
12567 &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12568 "exn_ptr",
12569 ));
12570 let exn_payload_ptr = exn_payload_ptr
12571 .try_as_basic_value()
12572 .unwrap_basic()
12573 .into_pointer_value();
12574
12575 let values = params
12577 .iter()
12578 .enumerate()
12579 .map(|(i, v)| {
12580 let name = format!("value_{i}");
12581 let ptr = err!(unsafe {
12582 self.builder.build_gep(
12583 self.intrinsics.i128_ty,
12584 exn_payload_ptr,
12585 &[self
12586 .intrinsics
12587 .i32_ty
12588 .const_int(i as u64, false)],
12589 format!("{name}_ptr").as_str(),
12590 )
12591 });
12592 err_nt!(self.builder.build_load(
12593 type_to_llvm(self.intrinsics, *v)?,
12594 ptr,
12595 &name,
12596 ))
12597 })
12598 .collect::<Result<Vec<_>, CompileError>>()?;
12599
12600 let frame = self.state.frame_at_depth(*label)?;
12601
12602 for (phi, value) in frame.phis().iter().zip(values.iter()) {
12603 phi.add_incoming(&[(value, b)])
12604 }
12605
12606 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12607
12608 self.builder.position_at_end(catch_end_block);
12609 catch_blocks.push((b, Some(exnref_phi)));
12610 }
12611 Catch::OneRef { label, tag } => {
12612 let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12613 let signature = &self.wasm_module.signatures[tag_idx];
12614 let params = signature.params();
12615
12616 let b = self.context.append_basic_block(
12617 self.function,
12618 format!("catch_one_ref_clause_{tag}").as_str(),
12619 );
12620 self.builder.position_at_end(b);
12621
12622 let exnref_phi = err!(
12623 self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12624 );
12625 exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12626
12627 let exn_payload_ptr = err!(self.builder.build_direct_call(
12629 self.intrinsics.read_exnref,
12630 &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12631 "exn_ptr",
12632 ));
12633 let exn_payload_ptr = exn_payload_ptr
12634 .try_as_basic_value()
12635 .unwrap_basic()
12636 .into_pointer_value();
12637
12638 let mut values = params
12640 .iter()
12641 .enumerate()
12642 .map(|(i, v)| {
12643 let name = format!("value_{i}");
12644 let ptr = err!(unsafe {
12645 self.builder.build_gep(
12646 self.intrinsics.i128_ty,
12647 exn_payload_ptr,
12648 &[self
12649 .intrinsics
12650 .i32_ty
12651 .const_int(i as u64, false)],
12652 format!("{name}_ptr").as_str(),
12653 )
12654 });
12655 err_nt!(self.builder.build_load(
12656 type_to_llvm(self.intrinsics, *v)?,
12657 ptr,
12658 &name,
12659 ))
12660 })
12661 .collect::<Result<Vec<_>, CompileError>>()?;
12662
12663 values.push(exnref_phi.as_basic_value());
12664
12665 let frame = self.state.frame_at_depth(*label)?;
12666
12667 for (phi, value) in frame.phis().iter().zip(values.iter()) {
12668 phi.add_incoming(&[(value, b)])
12669 }
12670
12671 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12672
12673 self.builder.position_at_end(catch_end_block);
12674 catch_blocks.push((b, Some(exnref_phi)));
12675 }
12676 Catch::AllRef { label } => {
12677 let b = self
12678 .context
12679 .append_basic_block(self.function, "catch_all_ref_clause");
12680 self.builder.position_at_end(b);
12681
12682 let exnref_phi = err!(
12683 self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12684 );
12685 exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12686
12687 let frame = self.state.frame_at_depth(*label)?;
12688
12689 let phis = frame.phis();
12690
12691 assert_eq!(phis.len(), 1);
12692 phis[0].add_incoming(&[(&exnref_phi.as_basic_value(), b)]);
12693
12694 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12695
12696 self.builder.position_at_end(catch_end_block);
12697 catch_blocks.push((b, Some(exnref_phi)));
12698 }
12699 }
12700 }
12701
12702 for catch_info in &outer_catch_blocks {
12703 if let Some(phi) = catch_info.exnref_phi {
12704 phi.add_incoming(&[(&exnref, catch_end_block)]);
12705 }
12706 }
12707
12708 err!(
12709 self.builder.build_switch(
12710 selector,
12711 rethrow_block,
12712 catch_blocks
12713 .iter()
12714 .enumerate()
12715 .map(|(i, v)| (
12716 self.intrinsics
12717 .i32_ty
12718 .const_int(catch_tag_values[i] as _, false),
12719 v.0
12720 ))
12721 .chain(outer_catch_blocks.iter().map(|catch_info| (
12722 self.intrinsics.i32_ty.const_int(catch_info.tag as _, false),
12723 catch_info.catch_block
12724 )))
12725 .collect::<Vec<_>>()
12726 .as_slice()
12727 )
12728 );
12729
12730 self.builder.position_at_end(rethrow_block);
12734
12735 err!(self.builder.build_call(
12736 self.intrinsics.throw,
12737 &[self.ctx.basic().into(), exnref.into()],
12738 "rethrow"
12739 ));
12740 err!(self.builder.build_unreachable());
12742
12743 maybe_lpad_block = Some(lpad_block);
12744 }
12745
12746 self.builder.position_at_end(current_block);
12748
12749 let catch_tags_and_blocks = catch_tag_values
12752 .into_iter()
12753 .zip(catch_blocks)
12754 .map(|(tag, (block, exnref_phi))| TagCatchInfo {
12755 tag,
12756 catch_block: block,
12757 exnref_phi,
12758 })
12759 .collect::<Vec<_>>();
12760 self.state.push_landingpad(
12761 maybe_lpad_block,
12762 end_block,
12763 end_phis,
12764 &catch_tags_and_blocks,
12765 self.module_translation
12766 .blocktype_params_results(&try_table.ty)?
12767 .0
12768 .len(),
12769 );
12770 }
12771 Operator::Throw { tag_index } => {
12772 let current_block = self
12773 .builder
12774 .get_insert_block()
12775 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12776
12777 let sig_index = self.wasm_module.tags[TagIndex::from_u32(tag_index)];
12778 let signature = &self.wasm_module.signatures[sig_index];
12779 let params = signature.params();
12780 let values = self.state.popn_save_extra(params.len())?;
12781
12782 values.iter().enumerate().try_for_each(|(i, (v, _))| {
12783 let t = type_to_llvm(self.intrinsics, params[i])?;
12784 if t != v.get_type() {
12785 return Err(CompileError::Codegen(format!(
12786 "Incompatible types: {:?} != {:?}",
12787 t,
12788 v.get_type()
12789 )));
12790 }
12791
12792 Ok(())
12793 })?;
12794
12795 let exnref = err!(
12797 self.builder.build_direct_call(
12798 self.intrinsics.alloc_exception,
12799 &[
12800 self.ctx.basic().into(),
12801 self.intrinsics
12802 .i32_ty
12803 .const_int(tag_index as _, false)
12804 .into()
12805 ],
12806 "exnref",
12807 )
12808 );
12809 let exnref = exnref.try_as_basic_value().unwrap_basic();
12810
12811 let exn_payload_ptr = err!(self.builder.build_direct_call(
12812 self.intrinsics.read_exnref,
12813 &[self.ctx.basic().into(), exnref.into()],
12814 "exn_ptr",
12815 ));
12816 let exn_payload_ptr = exn_payload_ptr
12817 .try_as_basic_value()
12818 .unwrap_basic()
12819 .into_pointer_value();
12820
12821 for (i, value) in values.into_iter().enumerate() {
12822 let ptr = err!(unsafe {
12823 self.builder.build_gep(
12824 self.intrinsics.i128_ty,
12825 exn_payload_ptr,
12826 &[self.intrinsics.i32_ty.const_int(i as u64, false)],
12827 format!("value_{i}_ptr").as_str(),
12828 )
12829 });
12830 err!(self.builder.build_store(ptr, value.0));
12831 }
12832
12833 if let Some(pad) = self.state.get_innermost_landingpad() {
12834 let unreachable_block = self
12835 .context
12836 .append_basic_block(self.function, "_throw_unreachable");
12837
12838 err!(self.builder.build_invoke(
12839 self.intrinsics.throw,
12840 &[self.ctx.basic(), exnref],
12841 unreachable_block,
12842 pad,
12843 "throw",
12844 ));
12845
12846 self.builder.position_at_end(unreachable_block);
12847 err!(self.builder.build_unreachable());
12849
12850 self.builder.position_at_end(current_block);
12851 } else {
12852 err!(self.builder.build_call(
12853 self.intrinsics.throw,
12854 &[self.ctx.basic().into(), exnref.into()],
12855 "throw"
12856 ));
12857 err!(self.builder.build_unreachable());
12859 }
12860
12861 self.state.reachable = false;
12862 }
12863 Operator::ThrowRef => {
12864 let current_block = self
12865 .builder
12866 .get_insert_block()
12867 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12868
12869 let exnref = self.state.pop1()?;
12870
12871 if let Some(pad) = self.state.get_innermost_landingpad() {
12872 let unreachable_block = self
12873 .context
12874 .append_basic_block(self.function, "_rethrow_unreachable");
12875
12876 err!(self.builder.build_invoke(
12877 self.intrinsics.throw,
12878 &[self.ctx.basic(), exnref],
12879 unreachable_block,
12880 pad,
12881 "throw",
12882 ));
12883
12884 self.builder.position_at_end(unreachable_block);
12885 err!(self.builder.build_unreachable());
12887
12888 self.builder.position_at_end(current_block);
12889 } else {
12890 err!(self.builder.build_call(
12891 self.intrinsics.throw,
12892 &[self.ctx.basic().into(), exnref.into()],
12893 "throw"
12894 ));
12895 err!(self.builder.build_unreachable());
12897 }
12898
12899 self.state.reachable = false;
12900 }
12901 _ => {
12902 return Err(CompileError::Codegen(format!(
12903 "Operator {op:?} unimplemented",
12904 )));
12905 }
12906 }
12907
12908 Ok(())
12909 }
12910}
12911
12912fn is_f32_arithmetic(bits: u32) -> bool {
12913 let bits = bits & 0x7FFF_FFFF;
12915 bits < 0x7FC0_0000
12916}
12917
12918fn is_f64_arithmetic(bits: u64) -> bool {
12919 let bits = bits & 0x7FFF_FFFF_FFFF_FFFF;
12921 bits < 0x7FF8_0000_0000_0000
12922}
12923
12924const LEF32_GEQ_I32_MIN: u64 = i32::MIN as u64;
12932const GEF32_LEQ_I32_MAX: u64 = 2147483520; const LEF64_GEQ_I32_MIN: u64 = i32::MIN as u64;
12936const GEF64_LEQ_I32_MAX: u64 = i32::MAX as u64;
12938const LEF32_GEQ_U32_MIN: u64 = u32::MIN as u64;
12940const GEF32_LEQ_U32_MAX: u64 = 4294967040; const LEF64_GEQ_U32_MIN: u64 = u32::MIN as u64;
12944const GEF64_LEQ_U32_MAX: u64 = 4294967295; const LEF32_GEQ_I64_MIN: u64 = i64::MIN as u64;
12948const GEF32_LEQ_I64_MAX: u64 = 9223371487098961920; const LEF64_GEQ_I64_MIN: u64 = i64::MIN as u64;
12952const GEF64_LEQ_I64_MAX: u64 = 9223372036854774784; const LEF32_GEQ_U64_MIN: u64 = u64::MIN;
12956const GEF32_LEQ_U64_MAX: u64 = 18446742974197923840; const LEF64_GEQ_U64_MIN: u64 = u64::MIN;
12960const GEF64_LEQ_U64_MAX: u64 = 18446744073709549568;