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 AnyValue, BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue, FloatValue,
21 FunctionValue, InstructionOpcode, InstructionValue, IntValue, PhiValue, PointerValue,
22 VectorValue,
23 },
24};
25use itertools::Itertools;
26use smallvec::SmallVec;
27use target_lexicon::BinaryFormat;
28
29use crate::{
30 abi::{Abi, G0M0FunctionKind, LocalFunctionG0M0params, get_abi},
31 config::{CompiledKind, LLVM},
32 error::{err, err_nt},
33 object_file::{CompiledFunction, load_object_file},
34};
35use wasmer_compiler::{
36 FunctionBinaryReader, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddlewareChain,
37 ModuleTranslationState, from_binaryreadererror_wasmerror,
38 types::{
39 relocation::RelocationTarget,
40 symbols::{Symbol, SymbolRegistry},
41 },
42 wasmparser::{Catch, MemArg, Operator},
43 wpheaptype_to_type, wptype_to_type,
44};
45use wasmer_types::{
46 CompileError, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex,
47 ModuleInfo, SignatureIndex, TableIndex, Type,
48};
49use wasmer_types::{TagIndex, entity::PrimaryMap};
50use wasmer_vm::{MemoryStyle, TableStyle, VMOffsets};
51
52const FUNCTION_SECTION_ELF: &str = "__TEXT,wasmer_function";
53const FUNCTION_SECTION_MACHO: &str = "__TEXT";
54const FUNCTION_SEGMENT_MACHO: &str = "wasmer_function";
55
56const CATCH_ALL_TAG_VALUE: i32 = i32::MAX;
62
63pub struct FuncTranslator {
64 ctx: Context,
65 target_machine: TargetMachine,
66 abi: Box<dyn Abi>,
67 binary_fmt: BinaryFormat,
68 func_section: String,
69}
70
71impl FuncTranslator {
72 pub fn new(
73 target_machine: TargetMachine,
74 binary_fmt: BinaryFormat,
75 ) -> Result<Self, CompileError> {
76 let abi = get_abi(&target_machine);
77 Ok(Self {
78 ctx: Context::create(),
79 target_machine,
80 abi,
81 func_section: match binary_fmt {
82 BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
83 BinaryFormat::Macho => FUNCTION_SEGMENT_MACHO.to_string(),
84 _ => {
85 return Err(CompileError::UnsupportedTarget(format!(
86 "Unsupported binary format: {binary_fmt:?}"
87 )));
88 }
89 },
90 binary_fmt,
91 })
92 }
93
94 #[allow(clippy::too_many_arguments)]
95 pub fn translate_to_module(
96 &self,
97 wasm_module: &ModuleInfo,
98 module_translation: &ModuleTranslationState,
99 local_func_index: &LocalFunctionIndex,
100 function_body: &FunctionBodyData,
101 config: &LLVM,
102 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
103 _table_styles: &PrimaryMap<TableIndex, TableStyle>,
104 symbol_registry: &dyn SymbolRegistry,
105 ) -> Result<Module, CompileError> {
106 let function = CompiledKind::Local(*local_func_index);
108 let func_index = wasm_module.func_index(*local_func_index);
109 let function_name =
110 symbol_registry.symbol_to_name(Symbol::LocalFunction(*local_func_index));
111
112 let g0m0_is_enabled = config.enable_g0m0_opt;
113 let func_kind = if g0m0_is_enabled {
114 Some(G0M0FunctionKind::Local)
115 } else {
116 None
117 };
118
119 let module_name = match wasm_module.name.as_ref() {
120 None => format!("<anonymous module> function {function_name}"),
121 Some(module_name) => format!("module {module_name} function {function_name}"),
122 };
123 let module = self.ctx.create_module(module_name.as_str());
124
125 let target_machine = &self.target_machine;
126 let target_triple = target_machine.get_triple();
127 let target_data = target_machine.get_target_data();
128 module.set_triple(&target_triple);
129 module.set_data_layout(&target_data.get_data_layout());
130 let wasm_fn_type = wasm_module
131 .signatures
132 .get(wasm_module.functions[func_index])
133 .unwrap();
134
135 let offsets = VMOffsets::new(8, wasm_module);
137 let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data, &self.binary_fmt);
138 let (func_type, func_attrs) = self.abi.func_type_to_llvm(
139 &self.ctx,
140 &intrinsics,
141 Some(&offsets),
142 wasm_fn_type,
143 func_kind,
144 )?;
145
146 let func = module.add_function(&function_name, func_type, Some(Linkage::External));
147 for (attr, attr_loc) in &func_attrs {
148 func.add_attribute(*attr_loc, *attr);
149 }
150
151 func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe);
152 func.add_attribute(AttributeLoc::Function, intrinsics.uwtable);
153 func.add_attribute(AttributeLoc::Function, intrinsics.frame_pointer);
154
155 let section = match self.binary_fmt {
156 BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
157 BinaryFormat::Macho => {
158 format!("{FUNCTION_SECTION_MACHO},{FUNCTION_SEGMENT_MACHO}")
159 }
160 _ => {
161 return Err(CompileError::UnsupportedTarget(format!(
162 "Unsupported binary format: {:?}",
163 self.binary_fmt
164 )));
165 }
166 };
167
168 func.set_personality_function(intrinsics.personality);
169 func.as_global_value().set_section(Some(§ion));
170
171 func.set_linkage(Linkage::DLLExport);
172 func.as_global_value()
173 .set_dll_storage_class(DLLStorageClass::Export);
174
175 let entry = self.ctx.append_basic_block(func, "entry");
176 let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
177 let return_ = self.ctx.append_basic_block(func, "return");
178 let alloca_builder = self.ctx.create_builder();
179 let cache_builder = self.ctx.create_builder();
180 let builder = self.ctx.create_builder();
181 cache_builder.position_at_end(entry);
182 let br = err!(cache_builder.build_unconditional_branch(start_of_code));
183 alloca_builder.position_before(&br);
184 cache_builder.position_before(&br);
185 builder.position_at_end(start_of_code);
186
187 let mut state = State::new();
188 builder.position_at_end(return_);
189 let phis: SmallVec<[PhiValue; 1]> = wasm_fn_type
190 .results()
191 .iter()
192 .map(|&wasm_ty| {
193 type_to_llvm(&intrinsics, wasm_ty).map(|ty| builder.build_phi(ty, "").unwrap())
194 })
195 .collect::<Result<_, _>>()?;
196 state.push_block(return_, phis, 0);
197 builder.position_at_end(start_of_code);
198
199 let mut reader = MiddlewareBinaryReader::new_with_offset(
200 function_body.data,
201 function_body.module_offset,
202 );
203 reader.set_middleware_chain(
204 config
205 .middlewares
206 .generate_function_middleware_chain(*local_func_index),
207 );
208
209 let mut params = vec![];
210 let first_param =
211 if func_type.get_return_type().is_none() && wasm_fn_type.results().len() > 1 {
212 if g0m0_is_enabled { 4 } else { 2 }
213 } else if g0m0_is_enabled {
214 3
215 } else {
216 1
217 };
218 let mut is_first_alloca = true;
219 let mut insert_alloca = |ty, name: String| -> Result<PointerValue, CompileError> {
220 let alloca = err!(alloca_builder.build_alloca(ty, &name));
221 if is_first_alloca {
222 alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
223 is_first_alloca = false;
224 }
225 Ok(alloca)
226 };
227
228 for idx in 0..wasm_fn_type.params().len() {
246 let ty = wasm_fn_type.params()[idx];
247 let ty = type_to_llvm(&intrinsics, ty)?;
248 let value = func
249 .get_nth_param((idx as u32).checked_add(first_param).unwrap())
250 .unwrap();
251 let alloca = insert_alloca(ty, format!("param_{idx}"))?;
252 err!(cache_builder.build_store(alloca, value));
253 params.push((ty, alloca));
254 }
255
256 let mut locals = vec![];
257 let num_locals = reader.read_local_count()?;
258 for idx in 0..num_locals {
259 let (count, ty) = reader.read_local_decl()?;
260 let ty = err!(wptype_to_type(ty));
261 let ty = type_to_llvm(&intrinsics, ty)?;
262 for _ in 0..count {
263 let alloca = insert_alloca(ty, format!("local_{idx}"))?;
264 err!(cache_builder.build_store(alloca, ty.const_zero()));
265 locals.push((ty, alloca));
266 }
267 }
268
269 let mut params_locals = params.clone();
270 params_locals.extend(locals.iter().cloned());
271
272 let mut g0m0_params = None;
273
274 if g0m0_is_enabled {
275 let value = self.abi.get_g0_ptr_param(&func);
276 let g0 = insert_alloca(intrinsics.i32_ty.as_basic_type_enum(), "g0".to_string())?;
277 err!(cache_builder.build_store(g0, value));
278 g0.set_name("g0");
279 let m0 = self.abi.get_m0_ptr_param(&func);
280 m0.set_name("m0_base_ptr");
281
282 g0m0_params = Some((g0, m0));
283 }
284
285 let mut fcg = LLVMFunctionCodeGenerator {
286 g0m0: g0m0_params,
287 context: &self.ctx,
288 builder,
289 alloca_builder,
290 intrinsics: &intrinsics,
291 state,
292 function: func,
293 locals: params_locals,
294 ctx: CtxType::new(wasm_module, &func, &cache_builder, &*self.abi, config),
295 unreachable_depth: 0,
296 memory_styles,
297 _table_styles,
298 module: &module,
299 module_translation,
300 wasm_module,
301 symbol_registry,
302 abi: &*self.abi,
303 config,
304 exception_types_cache: HashMap::new(),
305 vmctx_alloca: None,
306 tags_cache: HashMap::new(),
307 binary_fmt: self.binary_fmt,
308 };
309
310 fcg.ctx.add_func(
311 func_index,
312 func.as_global_value().as_pointer_value(),
313 func_type,
314 fcg.ctx.basic(),
315 &func_attrs,
316 );
317
318 while fcg.state.has_control_frames() {
319 let pos = reader.current_position() as u32;
320 let op = reader.read_operator()?;
321 fcg.translate_operator(op, pos)?;
322 }
323
324 fcg.finalize(wasm_fn_type)?;
325
326 if let Some(ref callbacks) = config.callbacks {
327 callbacks.preopt_ir(&function, &module);
328 }
329
330 let mut passes = vec![];
331
332 if config.enable_verifier {
333 passes.push("verify");
334 }
335
336 passes.push("sccp");
337 passes.push("early-cse");
338 passes.push("adce");
340 passes.push("sroa");
341 passes.push("aggressive-instcombine");
342 passes.push("jump-threading");
343 passes.push("simplifycfg");
345 passes.push("reassociate");
346 passes.push("loop-rotate");
347 passes.push("indvars");
348 passes.push("sccp");
352 passes.push("reassociate");
353 passes.push("simplifycfg");
354 passes.push("gvn");
355 passes.push("memcpyopt");
356 passes.push("dse");
357 passes.push("dce");
358 passes.push("reassociate");
360 passes.push("simplifycfg");
361 passes.push("mem2reg");
362
363 module
374 .run_passes(
375 passes.join(",").as_str(),
376 target_machine,
377 PassBuilderOptions::create(),
378 )
379 .unwrap();
380
381 if let Some(ref callbacks) = config.callbacks {
390 callbacks.postopt_ir(&function, &module);
391 }
392
393 Ok(module)
394 }
395
396 #[allow(clippy::too_many_arguments)]
397 pub fn translate(
398 &self,
399 wasm_module: &ModuleInfo,
400 module_translation: &ModuleTranslationState,
401 local_func_index: &LocalFunctionIndex,
402 function_body: &FunctionBodyData,
403 config: &LLVM,
404 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
405 table_styles: &PrimaryMap<TableIndex, TableStyle>,
406 symbol_registry: &dyn SymbolRegistry,
407 ) -> Result<CompiledFunction, CompileError> {
408 let module = self.translate_to_module(
409 wasm_module,
410 module_translation,
411 local_func_index,
412 function_body,
413 config,
414 memory_styles,
415 table_styles,
416 symbol_registry,
417 )?;
418 let function = CompiledKind::Local(*local_func_index);
419 let target_machine = &self.target_machine;
420 let memory_buffer = target_machine
421 .write_to_memory_buffer(&module, FileType::Object)
422 .unwrap();
423
424 if let Some(ref callbacks) = config.callbacks {
425 callbacks.obj_memory_buffer(&function, &memory_buffer);
426 let asm_buffer = target_machine
427 .write_to_memory_buffer(&module, FileType::Assembly)
428 .unwrap();
429 callbacks.asm_memory_buffer(&function, &asm_buffer)
430 }
431
432 let mem_buf_slice = memory_buffer.as_slice();
433
434 load_object_file(
435 mem_buf_slice,
436 &self.func_section,
437 RelocationTarget::LocalFunc(*local_func_index),
438 |name: &str| {
439 Ok({
440 let name = if matches!(self.binary_fmt, BinaryFormat::Macho) {
441 if name.starts_with("_") {
442 name.replacen("_", "", 1)
443 } else {
444 name.to_string()
445 }
446 } else {
447 name.to_string()
448 };
449 if let Some(Symbol::LocalFunction(local_func_index)) =
450 symbol_registry.name_to_symbol(&name)
451 {
452 Some(RelocationTarget::LocalFunc(local_func_index))
453 } else {
454 None
455 }
456 })
457 },
458 self.binary_fmt,
459 )
460 }
461}
462
463impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
464 fn splat_vector(
466 &self,
467 value: BasicValueEnum<'ctx>,
468 vec_ty: VectorType<'ctx>,
469 ) -> Result<VectorValue<'ctx>, CompileError> {
470 err_nt!(
473 self.builder.build_shuffle_vector(
474 err!(self.builder.build_insert_element(
475 vec_ty.get_undef(),
476 value,
477 self.intrinsics.i32_zero,
478 "",
479 )),
480 vec_ty.get_undef(),
481 self.intrinsics
482 .i32_ty
483 .vec_type(vec_ty.get_size())
484 .const_zero(),
485 "",
486 )
487 )
488 }
489
490 #[allow(clippy::too_many_arguments)]
493 fn trunc_sat<T: FloatMathType<'ctx>>(
494 &self,
495 fvec_ty: T,
496 ivec_ty: T::MathConvType,
497 lower_bound: u64, upper_bound: u64, int_min_value: u64,
500 int_max_value: u64,
501 value: IntValue<'ctx>,
502 ) -> Result<VectorValue<'ctx>, CompileError> {
503 let fvec_ty = fvec_ty.as_basic_type_enum().into_vector_type();
517 let ivec_ty = ivec_ty.as_basic_type_enum().into_vector_type();
518 let fvec_element_ty = fvec_ty.get_element_type().into_float_type();
519 let ivec_element_ty = ivec_ty.get_element_type().into_int_type();
520
521 let is_signed = int_min_value != 0;
522 let int_min_value = self.splat_vector(
523 ivec_element_ty
524 .const_int(int_min_value, is_signed)
525 .as_basic_value_enum(),
526 ivec_ty,
527 )?;
528 let int_max_value = self.splat_vector(
529 ivec_element_ty
530 .const_int(int_max_value, is_signed)
531 .as_basic_value_enum(),
532 ivec_ty,
533 )?;
534 let lower_bound = if is_signed {
535 err!(self.builder.build_signed_int_to_float(
536 ivec_element_ty.const_int(lower_bound, is_signed),
537 fvec_element_ty,
538 "",
539 ))
540 } else {
541 err!(self.builder.build_unsigned_int_to_float(
542 ivec_element_ty.const_int(lower_bound, is_signed),
543 fvec_element_ty,
544 "",
545 ))
546 };
547 let upper_bound = if is_signed {
548 err!(self.builder.build_signed_int_to_float(
549 ivec_element_ty.const_int(upper_bound, is_signed),
550 fvec_element_ty,
551 "",
552 ))
553 } else {
554 err!(self.builder.build_unsigned_int_to_float(
555 ivec_element_ty.const_int(upper_bound, is_signed),
556 fvec_element_ty,
557 "",
558 ))
559 };
560
561 let value = err!(self.builder.build_bit_cast(value, fvec_ty, "")).into_vector_value();
562 let zero = fvec_ty.const_zero();
563 let lower_bound = self.splat_vector(lower_bound.as_basic_value_enum(), fvec_ty)?;
564 let upper_bound = self.splat_vector(upper_bound.as_basic_value_enum(), fvec_ty)?;
565 let nan_cmp =
566 err!(
567 self.builder
568 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
569 );
570 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
571 FloatPredicate::OGT,
572 value,
573 upper_bound,
574 "above_upper_bound",
575 ));
576 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
577 FloatPredicate::OLT,
578 value,
579 lower_bound,
580 "below_lower_bound",
581 ));
582 let not_representable = err!(self.builder.build_or(
583 err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
584 below_lower_bound_cmp,
585 "not_representable_as_int",
586 ));
587 let value =
588 err!(
589 self.builder
590 .build_select(not_representable, zero, value, "safe_to_convert")
591 )
592 .into_vector_value();
593 let value = if is_signed {
594 self.builder
595 .build_float_to_signed_int(value, ivec_ty, "as_int")
596 } else {
597 self.builder
598 .build_float_to_unsigned_int(value, ivec_ty, "as_int")
599 };
600
601 let value = err!(value);
602 let value =
603 err!(
604 self.builder
605 .build_select(above_upper_bound_cmp, int_max_value, value, "")
606 )
607 .into_vector_value();
608 err_nt!(
609 self.builder
610 .build_select(below_lower_bound_cmp, int_min_value, value, "")
611 .map(|v| v.into_vector_value())
612 )
613 }
614
615 #[allow(clippy::too_many_arguments)]
618 fn trunc_sat_into_int<T: FloatMathType<'ctx>>(
619 &self,
620 fvec_ty: T,
621 ivec_ty: T::MathConvType,
622 lower_bound: u64, upper_bound: u64, int_min_value: u64,
625 int_max_value: u64,
626 value: IntValue<'ctx>,
627 ) -> Result<IntValue<'ctx>, CompileError> {
628 let res = self.trunc_sat(
629 fvec_ty,
630 ivec_ty,
631 lower_bound,
632 upper_bound,
633 int_min_value,
634 int_max_value,
635 value,
636 )?;
637 err_nt!(
638 self.builder
639 .build_bit_cast(res, self.intrinsics.i128_ty, "")
640 .map(|v| v.into_int_value())
641 )
642 }
643
644 fn trunc_sat_scalar(
647 &self,
648 int_ty: IntType<'ctx>,
649 lower_bound: u64, upper_bound: u64, int_min_value: u64,
652 int_max_value: u64,
653 value: FloatValue<'ctx>,
654 ) -> Result<IntValue<'ctx>, CompileError> {
655 let is_signed = int_min_value != 0;
671 let int_min_value = int_ty.const_int(int_min_value, is_signed);
672 let int_max_value = int_ty.const_int(int_max_value, is_signed);
673
674 let lower_bound = if is_signed {
675 err!(self.builder.build_signed_int_to_float(
676 int_ty.const_int(lower_bound, is_signed),
677 value.get_type(),
678 "",
679 ))
680 } else {
681 err!(self.builder.build_unsigned_int_to_float(
682 int_ty.const_int(lower_bound, is_signed),
683 value.get_type(),
684 "",
685 ))
686 };
687 let upper_bound = if is_signed {
688 err!(self.builder.build_signed_int_to_float(
689 int_ty.const_int(upper_bound, is_signed),
690 value.get_type(),
691 "",
692 ))
693 } else {
694 err!(self.builder.build_unsigned_int_to_float(
695 int_ty.const_int(upper_bound, is_signed),
696 value.get_type(),
697 "",
698 ))
699 };
700
701 let zero = value.get_type().const_zero();
702
703 let nan_cmp =
704 err!(
705 self.builder
706 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
707 );
708 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
709 FloatPredicate::OGT,
710 value,
711 upper_bound,
712 "above_upper_bound",
713 ));
714 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
715 FloatPredicate::OLT,
716 value,
717 lower_bound,
718 "below_lower_bound",
719 ));
720 let not_representable = err!(self.builder.build_or(
721 err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
722 below_lower_bound_cmp,
723 "not_representable_as_int",
724 ));
725 let value =
726 err!(
727 self.builder
728 .build_select(not_representable, zero, value, "safe_to_convert")
729 )
730 .into_float_value();
731 let value = if is_signed {
732 err!(
733 self.builder
734 .build_float_to_signed_int(value, int_ty, "as_int")
735 )
736 } else {
737 err!(
738 self.builder
739 .build_float_to_unsigned_int(value, int_ty, "as_int")
740 )
741 };
742 let value =
743 err!(
744 self.builder
745 .build_select(above_upper_bound_cmp, int_max_value, value, "")
746 )
747 .into_int_value();
748 let value =
749 err!(
750 self.builder
751 .build_select(below_lower_bound_cmp, int_min_value, value, "")
752 )
753 .into_int_value();
754
755 err_nt!(
756 self.builder
757 .build_bit_cast(value, int_ty, "")
758 .map(|v| v.into_int_value())
759 )
760 }
761
762 fn trap_if_not_representable_as_int(
763 &self,
764 lower_bound: u64, upper_bound: u64, value: FloatValue,
767 ) -> Result<(), CompileError> {
768 let float_ty = value.get_type();
769 let int_ty = if float_ty == self.intrinsics.f32_ty {
770 self.intrinsics.i32_ty
771 } else {
772 self.intrinsics.i64_ty
773 };
774
775 let lower_bound = err!(self.builder.build_bit_cast(
776 int_ty.const_int(lower_bound, false),
777 float_ty,
778 ""
779 ))
780 .into_float_value();
781 let upper_bound = err!(self.builder.build_bit_cast(
782 int_ty.const_int(upper_bound, false),
783 float_ty,
784 ""
785 ))
786 .into_float_value();
787
788 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
792 FloatPredicate::UGT,
793 value,
794 upper_bound,
795 "above_upper_bound",
796 ));
797 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
798 FloatPredicate::ULT,
799 value,
800 lower_bound,
801 "below_lower_bound",
802 ));
803 let out_of_bounds = err!(self.builder.build_or(
804 above_upper_bound_cmp,
805 below_lower_bound_cmp,
806 "out_of_bounds",
807 ));
808
809 let failure_block = self
810 .context
811 .append_basic_block(self.function, "conversion_failure_block");
812 let continue_block = self
813 .context
814 .append_basic_block(self.function, "conversion_success_block");
815
816 err!(
817 self.builder
818 .build_conditional_branch(out_of_bounds, failure_block, continue_block)
819 );
820 self.builder.position_at_end(failure_block);
821 let is_nan =
822 err!(
823 self.builder
824 .build_float_compare(FloatPredicate::UNO, value, value, "is_nan")
825 );
826 let trap_code = err!(self.builder.build_select(
827 is_nan,
828 self.intrinsics.trap_bad_conversion_to_integer,
829 self.intrinsics.trap_illegal_arithmetic,
830 "",
831 ));
832 err!(
833 self.builder
834 .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
835 );
836 err!(self.builder.build_unreachable());
837 self.builder.position_at_end(continue_block);
838
839 Ok(())
840 }
841
842 fn trap_if_zero_or_overflow(
843 &self,
844 left: IntValue,
845 right: IntValue,
846 ) -> Result<(), CompileError> {
847 let int_type = left.get_type();
848
849 let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
850 let min_value = int_type.const_int(i32::MIN as u64, false);
851 let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
852 (min_value, neg_one_value)
853 } else if int_type == self.intrinsics.i64_ty {
854 let min_value = int_type.const_int(i64::MIN as u64, false);
855 let neg_one_value = int_type.const_int(-1i64 as u64, false);
856 (min_value, neg_one_value)
857 } else {
858 unreachable!()
859 };
860
861 let divisor_is_zero = err!(self.builder.build_int_compare(
862 IntPredicate::EQ,
863 right,
864 int_type.const_zero(),
865 "divisor_is_zero",
866 ));
867 let should_trap = err!(self.builder.build_or(
868 divisor_is_zero,
869 err!(self.builder.build_and(
870 err!(self.builder.build_int_compare(
871 IntPredicate::EQ,
872 left,
873 min_value,
874 "left_is_min"
875 )),
876 err!(self.builder.build_int_compare(
877 IntPredicate::EQ,
878 right,
879 neg_one_value,
880 "right_is_neg_one",
881 )),
882 "div_will_overflow",
883 )),
884 "div_should_trap",
885 ));
886
887 let should_trap = err!(self.builder.build_call(
888 self.intrinsics.expect_i1,
889 &[
890 should_trap.into(),
891 self.intrinsics.i1_ty.const_zero().into(),
892 ],
893 "should_trap_expect",
894 ))
895 .try_as_basic_value()
896 .left()
897 .unwrap()
898 .into_int_value();
899
900 let shouldnt_trap_block = self
901 .context
902 .append_basic_block(self.function, "shouldnt_trap_block");
903 let should_trap_block = self
904 .context
905 .append_basic_block(self.function, "should_trap_block");
906 err!(self.builder.build_conditional_branch(
907 should_trap,
908 should_trap_block,
909 shouldnt_trap_block
910 ));
911 self.builder.position_at_end(should_trap_block);
912 let trap_code = err!(self.builder.build_select(
913 divisor_is_zero,
914 self.intrinsics.trap_integer_division_by_zero,
915 self.intrinsics.trap_illegal_arithmetic,
916 "",
917 ));
918 err!(
919 self.builder
920 .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
921 );
922 err!(self.builder.build_unreachable());
923 self.builder.position_at_end(shouldnt_trap_block);
924
925 Ok(())
926 }
927
928 fn trap_if_zero(&self, value: IntValue) -> Result<(), CompileError> {
929 let int_type = value.get_type();
930 let should_trap = err!(self.builder.build_int_compare(
931 IntPredicate::EQ,
932 value,
933 int_type.const_zero(),
934 "divisor_is_zero",
935 ));
936
937 let should_trap = err!(self.builder.build_call(
938 self.intrinsics.expect_i1,
939 &[
940 should_trap.into(),
941 self.intrinsics.i1_ty.const_zero().into(),
942 ],
943 "should_trap_expect",
944 ))
945 .try_as_basic_value()
946 .left()
947 .unwrap()
948 .into_int_value();
949
950 let shouldnt_trap_block = self
951 .context
952 .append_basic_block(self.function, "shouldnt_trap_block");
953 let should_trap_block = self
954 .context
955 .append_basic_block(self.function, "should_trap_block");
956 err!(self.builder.build_conditional_branch(
957 should_trap,
958 should_trap_block,
959 shouldnt_trap_block
960 ));
961 self.builder.position_at_end(should_trap_block);
962 err!(self.builder.build_call(
963 self.intrinsics.throw_trap,
964 &[self.intrinsics.trap_integer_division_by_zero.into()],
965 "throw",
966 ));
967 err!(self.builder.build_unreachable());
968 self.builder.position_at_end(shouldnt_trap_block);
969
970 Ok(())
971 }
972
973 fn v128_into_int_vec(
974 &self,
975 value: BasicValueEnum<'ctx>,
976 info: ExtraInfo,
977 int_vec_ty: VectorType<'ctx>,
978 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
979 let (value, info) = if info.has_pending_f32_nan() {
980 let value = err!(
981 self.builder
982 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
983 );
984 (self.canonicalize_nans(value)?, info.strip_pending())
985 } else if info.has_pending_f64_nan() {
986 let value = err!(
987 self.builder
988 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
989 );
990 (self.canonicalize_nans(value)?, info.strip_pending())
991 } else {
992 (value, info)
993 };
994 Ok((
995 err!(self.builder.build_bit_cast(value, int_vec_ty, "")).into_vector_value(),
996 info,
997 ))
998 }
999
1000 fn v128_into_i8x16(
1001 &self,
1002 value: BasicValueEnum<'ctx>,
1003 info: ExtraInfo,
1004 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1005 self.v128_into_int_vec(value, info, self.intrinsics.i8x16_ty)
1006 }
1007
1008 fn v128_into_i16x8(
1009 &self,
1010 value: BasicValueEnum<'ctx>,
1011 info: ExtraInfo,
1012 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1013 self.v128_into_int_vec(value, info, self.intrinsics.i16x8_ty)
1014 }
1015
1016 fn v128_into_i32x4(
1017 &self,
1018 value: BasicValueEnum<'ctx>,
1019 info: ExtraInfo,
1020 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1021 self.v128_into_int_vec(value, info, self.intrinsics.i32x4_ty)
1022 }
1023
1024 fn v128_into_i64x2(
1025 &self,
1026 value: BasicValueEnum<'ctx>,
1027 info: ExtraInfo,
1028 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1029 self.v128_into_int_vec(value, info, self.intrinsics.i64x2_ty)
1030 }
1031
1032 fn v128_into_f32x4(
1035 &self,
1036 value: BasicValueEnum<'ctx>,
1037 info: ExtraInfo,
1038 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1039 let (value, info) = if info.has_pending_f64_nan() {
1040 let value = err!(
1041 self.builder
1042 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1043 );
1044 (self.canonicalize_nans(value)?, info.strip_pending())
1045 } else {
1046 (value, info)
1047 };
1048 Ok((
1049 err!(
1050 self.builder
1051 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1052 )
1053 .into_vector_value(),
1054 info,
1055 ))
1056 }
1057
1058 fn v128_into_f64x2(
1061 &self,
1062 value: BasicValueEnum<'ctx>,
1063 info: ExtraInfo,
1064 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1065 let (value, info) = if info.has_pending_f32_nan() {
1066 let value = err!(
1067 self.builder
1068 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1069 );
1070 (self.canonicalize_nans(value)?, info.strip_pending())
1071 } else {
1072 (value, info)
1073 };
1074 Ok((
1075 err!(
1076 self.builder
1077 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1078 )
1079 .into_vector_value(),
1080 info,
1081 ))
1082 }
1083
1084 fn apply_pending_canonicalization(
1085 &self,
1086 value: BasicValueEnum<'ctx>,
1087 info: ExtraInfo,
1088 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1089 if !self.config.enable_nan_canonicalization {
1090 return Ok(value);
1091 }
1092
1093 if info.has_pending_f32_nan() {
1094 if value.get_type().is_vector_type()
1095 || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1096 {
1097 let ty = value.get_type();
1098 let value = err!(
1099 self.builder
1100 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1101 );
1102 let value = self.canonicalize_nans(value)?;
1103 err_nt!(self.builder.build_bit_cast(value, ty, ""))
1104 } else {
1105 self.canonicalize_nans(value)
1106 }
1107 } else if info.has_pending_f64_nan() {
1108 if value.get_type().is_vector_type()
1109 || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1110 {
1111 let ty = value.get_type();
1112 let value = err!(
1113 self.builder
1114 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1115 );
1116 let value = self.canonicalize_nans(value)?;
1117 err_nt!(self.builder.build_bit_cast(value, ty, ""))
1118 } else {
1119 self.canonicalize_nans(value)
1120 }
1121 } else {
1122 Ok(value)
1123 }
1124 }
1125
1126 fn canonicalize_nans(
1128 &self,
1129 value: BasicValueEnum<'ctx>,
1130 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1131 if !self.config.enable_nan_canonicalization {
1132 return Ok(value);
1133 }
1134
1135 let f_ty = value.get_type();
1136 if f_ty.is_vector_type() {
1137 let value = value.into_vector_value();
1138 let f_ty = f_ty.into_vector_type();
1139 let zero = f_ty.const_zero();
1140 let nan_cmp =
1141 err!(
1142 self.builder
1143 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1144 );
1145 let canonical_qnan = f_ty
1146 .get_element_type()
1147 .into_float_type()
1148 .const_float(f64::NAN);
1149 let canonical_qnan = self.splat_vector(canonical_qnan.as_basic_value_enum(), f_ty)?;
1150 err_nt!(
1151 self.builder
1152 .build_select(nan_cmp, canonical_qnan, value, "")
1153 .map(|v| v.as_basic_value_enum())
1154 )
1155 } else {
1156 let value = value.into_float_value();
1157 let f_ty = f_ty.into_float_type();
1158 let zero = f_ty.const_zero();
1159 let nan_cmp =
1160 err!(
1161 self.builder
1162 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1163 );
1164 let canonical_qnan = f_ty.const_float(f64::NAN);
1165 err_nt!(
1166 self.builder
1167 .build_select(nan_cmp, canonical_qnan, value, "")
1168 .map(|v| v.as_basic_value_enum())
1169 )
1170 }
1171 }
1172
1173 fn quiet_nan(&self, value: BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, CompileError> {
1174 let intrinsic = if value
1175 .get_type()
1176 .eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1177 {
1178 Some(self.intrinsics.add_f32)
1179 } else if value
1180 .get_type()
1181 .eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1182 {
1183 Some(self.intrinsics.add_f64)
1184 } else if value
1185 .get_type()
1186 .eq(&self.intrinsics.f32x4_ty.as_basic_type_enum())
1187 {
1188 Some(self.intrinsics.add_f32x4)
1189 } else if value
1190 .get_type()
1191 .eq(&self.intrinsics.f64x2_ty.as_basic_type_enum())
1192 {
1193 Some(self.intrinsics.add_f64x2)
1194 } else {
1195 None
1196 };
1197
1198 match intrinsic {
1199 Some(intrinsic) => err_nt!(
1200 self.builder
1201 .build_call(
1202 intrinsic,
1203 &[
1204 value.into(),
1205 value.get_type().const_zero().into(),
1206 self.intrinsics.fp_rounding_md,
1207 self.intrinsics.fp_exception_md,
1208 ],
1209 "",
1210 )
1211 .map(|v| v.try_as_basic_value().left().unwrap())
1212 ),
1213 None => Ok(value),
1214 }
1215 }
1216
1217 fn mark_memaccess_nodelete(
1221 &mut self,
1222 memory_index: MemoryIndex,
1223 memaccess: InstructionValue<'ctx>,
1224 ) -> Result<(), CompileError> {
1225 if let MemoryCache::Static { base_ptr: _ } = self.ctx.memory(
1226 memory_index,
1227 self.intrinsics,
1228 self.module,
1229 self.memory_styles,
1230 )? {
1231 memaccess.set_volatile(true).unwrap();
1234 }
1235 Ok(())
1236 }
1237
1238 fn annotate_user_memaccess(
1239 &mut self,
1240 memory_index: MemoryIndex,
1241 _memarg: &MemArg,
1242 alignment: u32,
1243 memaccess: InstructionValue<'ctx>,
1244 ) -> Result<(), CompileError> {
1245 match memaccess.get_opcode() {
1246 InstructionOpcode::Load | InstructionOpcode::Store => {
1247 memaccess.set_alignment(alignment).unwrap();
1248 }
1249 _ => {}
1250 };
1251 self.mark_memaccess_nodelete(memory_index, memaccess)?;
1252 tbaa_label(
1253 self.module,
1254 self.intrinsics,
1255 format!("memory {}", memory_index.as_u32()),
1256 memaccess,
1257 );
1258 Ok(())
1259 }
1260
1261 fn resolve_memory_ptr(
1262 &mut self,
1263 memory_index: MemoryIndex,
1264 memarg: &MemArg,
1265 ptr_ty: PointerType<'ctx>,
1266 var_offset: IntValue<'ctx>,
1267 value_size: usize,
1268 ) -> Result<PointerValue<'ctx>, CompileError> {
1269 let builder = &self.builder;
1270 let intrinsics = &self.intrinsics;
1271 let context = &self.context;
1272 let function = &self.function;
1273
1274 let imm_offset = intrinsics.i64_ty.const_int(memarg.offset, false);
1276 let var_offset = err!(builder.build_int_z_extend(var_offset, intrinsics.i64_ty, ""));
1277 let offset = err!(builder.build_int_add(var_offset, imm_offset, ""));
1278
1279 let base_ptr = if let Some((_, ref m0)) = self.g0m0 {
1281 *m0
1282 } else {
1283 match self
1284 .ctx
1285 .memory(memory_index, intrinsics, self.module, self.memory_styles)?
1286 {
1287 MemoryCache::Dynamic {
1288 ptr_to_base_ptr,
1289 ptr_to_current_length,
1290 } => {
1291 let minimum = self.wasm_module.memories[memory_index].minimum;
1293 let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
1294 let ptr_in_bounds = if offset.is_const() {
1295 let load_offset_end = offset.const_add(value_size_v);
1298 let ptr_in_bounds = load_offset_end.const_int_compare(
1299 IntPredicate::ULE,
1300 intrinsics.i64_ty.const_int(minimum.bytes().0 as u64, false),
1301 );
1302 if ptr_in_bounds.get_zero_extended_constant() == Some(1) {
1303 Some(ptr_in_bounds)
1304 } else {
1305 None
1306 }
1307 } else {
1308 None
1309 };
1310
1311 let ptr_in_bounds = match ptr_in_bounds {
1312 Some(ptr) => ptr,
1313 None => {
1314 let load_offset_end = err!(builder.build_int_add(
1315 offset,
1316 value_size_v,
1317 "load_offset_end"
1318 ));
1319
1320 let current_length = err!(builder.build_load(
1321 self.intrinsics.i32_ty,
1322 ptr_to_current_length,
1323 "current_length"
1324 ))
1325 .into_int_value();
1326 tbaa_label(
1327 self.module,
1328 self.intrinsics,
1329 format!("memory {} length", memory_index.as_u32()),
1330 current_length.as_instruction_value().unwrap(),
1331 );
1332 let current_length = err!(builder.build_int_z_extend(
1333 current_length,
1334 intrinsics.i64_ty,
1335 "current_length_zextd"
1336 ));
1337
1338 err!(builder.build_int_compare(
1339 IntPredicate::ULE,
1340 load_offset_end,
1341 current_length,
1342 "ptr_in_bounds",
1343 ))
1344 }
1345 };
1346
1347 if !ptr_in_bounds.is_constant_int()
1348 || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
1349 {
1350 let ptr_in_bounds = err!(builder.build_call(
1356 intrinsics.expect_i1,
1357 &[
1358 ptr_in_bounds.into(),
1359 intrinsics.i1_ty.const_int(1, true).into(),
1360 ],
1361 "ptr_in_bounds_expect",
1362 ))
1363 .try_as_basic_value()
1364 .left()
1365 .unwrap()
1366 .into_int_value();
1367
1368 let in_bounds_continue_block =
1369 context.append_basic_block(*function, "in_bounds_continue_block");
1370 let not_in_bounds_block =
1371 context.append_basic_block(*function, "not_in_bounds_block");
1372 err!(builder.build_conditional_branch(
1373 ptr_in_bounds,
1374 in_bounds_continue_block,
1375 not_in_bounds_block,
1376 ));
1377 builder.position_at_end(not_in_bounds_block);
1378 err!(builder.build_call(
1379 intrinsics.throw_trap,
1380 &[intrinsics.trap_memory_oob.into()],
1381 "throw",
1382 ));
1383 err!(builder.build_unreachable());
1384 builder.position_at_end(in_bounds_continue_block);
1385 }
1386 let ptr_to_base =
1387 err!(builder.build_load(intrinsics.ptr_ty, ptr_to_base_ptr, "ptr_to_base"))
1388 .into_pointer_value();
1389 tbaa_label(
1390 self.module,
1391 self.intrinsics,
1392 format!("memory base_ptr {}", memory_index.as_u32()),
1393 ptr_to_base.as_instruction_value().unwrap(),
1394 );
1395 ptr_to_base
1396 }
1397 MemoryCache::Static { base_ptr } => base_ptr,
1398 }
1399 };
1400 let value_ptr = unsafe {
1401 err!(builder.build_gep(self.intrinsics.i8_ty, base_ptr, &[offset], "mem_value_ptr"))
1402 };
1403 err_nt!(
1404 builder
1405 .build_bit_cast(value_ptr, ptr_ty, "mem_value")
1406 .map(|v| v.into_pointer_value())
1407 )
1408 }
1409
1410 fn trap_if_misaligned(
1411 &self,
1412 _memarg: &MemArg,
1413 ptr: PointerValue<'ctx>,
1414 align: u8,
1415 ) -> Result<(), CompileError> {
1416 if align <= 1 {
1417 return Ok(());
1418 }
1419 let value = err!(self.builder.build_ptr_to_int(
1420 ptr,
1421 self.intrinsics.i64_ty,
1422 "mischeck_value"
1423 ));
1424 let and = err!(self.builder.build_and(
1425 value,
1426 self.intrinsics.i64_ty.const_int((align - 1).into(), false),
1427 "misaligncheck",
1428 ));
1429 let aligned = err!(self.builder.build_int_compare(
1430 IntPredicate::EQ,
1431 and,
1432 self.intrinsics.i64_zero,
1433 "is_aligned"
1434 ));
1435 let aligned = err!(self.builder.build_call(
1436 self.intrinsics.expect_i1,
1437 &[
1438 aligned.into(),
1439 self.intrinsics.i1_ty.const_int(1, false).into(),
1440 ],
1441 "is_aligned_expect",
1442 ))
1443 .try_as_basic_value()
1444 .left()
1445 .unwrap()
1446 .into_int_value();
1447
1448 let continue_block = self
1449 .context
1450 .append_basic_block(self.function, "aligned_access_continue_block");
1451 let not_aligned_block = self
1452 .context
1453 .append_basic_block(self.function, "misaligned_trap_block");
1454 err!(
1455 self.builder
1456 .build_conditional_branch(aligned, continue_block, not_aligned_block)
1457 );
1458
1459 self.builder.position_at_end(not_aligned_block);
1460 err!(self.builder.build_call(
1461 self.intrinsics.throw_trap,
1462 &[self.intrinsics.trap_unaligned_atomic.into()],
1463 "throw",
1464 ));
1465 err!(self.builder.build_unreachable());
1466
1467 self.builder.position_at_end(continue_block);
1468 Ok(())
1469 }
1470
1471 fn finalize(&mut self, wasm_fn_type: &FunctionType) -> Result<(), CompileError> {
1472 let func_type = self.function.get_type();
1473
1474 let results = self.state.popn_save_extra(wasm_fn_type.results().len())?;
1475 let results = err!(
1476 results
1477 .into_iter()
1478 .map(|(v, i)| self.apply_pending_canonicalization(v, i))
1479 .collect::<Result<Vec<_>, _>>()
1480 );
1481
1482 if wasm_fn_type.results().is_empty() {
1483 err!(self.builder.build_return(None));
1484 } else if self.abi.is_sret(wasm_fn_type)? {
1485 let sret = self
1486 .function
1487 .get_first_param()
1488 .unwrap()
1489 .into_pointer_value();
1490 let llvm_params: Vec<_> = wasm_fn_type
1491 .results()
1492 .iter()
1493 .map(|x| type_to_llvm(self.intrinsics, *x).unwrap())
1494 .collect();
1495 let mut struct_value = self
1496 .context
1497 .struct_type(llvm_params.as_slice(), false)
1498 .get_undef();
1499 for (idx, value) in results.into_iter().enumerate() {
1500 let value = err!(self.builder.build_bit_cast(
1501 value,
1502 type_to_llvm(self.intrinsics, wasm_fn_type.results()[idx])?,
1503 "",
1504 ));
1505 struct_value =
1506 err!(
1507 self.builder
1508 .build_insert_value(struct_value, value, idx as u32, "")
1509 )
1510 .into_struct_value();
1511 }
1512 err!(self.builder.build_store(sret, struct_value));
1513 err!(self.builder.build_return(None));
1514 } else {
1515 err!(
1516 self.builder
1517 .build_return(Some(&self.abi.pack_values_for_register_return(
1518 self.intrinsics,
1519 &self.builder,
1520 &results,
1521 &func_type,
1522 )?))
1523 );
1524 }
1525 Ok(())
1526 }
1527
1528 fn get_or_insert_tag_type_info_global(&mut self, tag: i32) -> BasicValueEnum<'ctx> {
1531 if let Some(tag) = self.tags_cache.get(&tag) {
1532 return *tag;
1533 }
1534
1535 let tag_ty = self
1536 .context
1537 .struct_type(&[self.intrinsics.i32_ty.into()], false);
1538 let tag_glbl = self.module.add_global(
1539 tag_ty,
1540 Some(AddressSpace::default()),
1541 &format!("__wasmer_eh_type_info_{tag}"),
1542 );
1543 tag_glbl.set_initializer(
1544 &tag_ty
1545 .const_named_struct(&[self.intrinsics.i32_ty.const_int(tag as _, false).into()])
1546 .as_basic_value_enum(),
1547 );
1548
1549 tag_glbl.set_linkage(Linkage::External);
1550 tag_glbl.set_constant(true);
1551 if matches!(self.binary_fmt, target_lexicon::BinaryFormat::Macho) {
1559 tag_glbl.set_section(Some(&format!("{FUNCTION_SECTION_MACHO},_eh_ti_{tag}")));
1560 }
1561
1562 let tag_glbl = tag_glbl.as_basic_value_enum();
1563
1564 self.tags_cache.insert(tag, tag_glbl);
1565 tag_glbl
1566 }
1567
1568 fn get_or_insert_exception_type(
1569 &mut self,
1570 tag: u32,
1571 signature: &FunctionType,
1572 ) -> Result<inkwell::types::StructType<'ctx>, CompileError> {
1573 if let Some(ty) = self.exception_types_cache.get(&tag) {
1574 return Ok(*ty);
1575 }
1576 let types = signature
1577 .params()
1578 .iter()
1579 .map(|v| type_to_llvm(self.intrinsics, *v))
1580 .collect::<Result<Vec<_>, CompileError>>()?;
1581
1582 let ty = self.context.struct_type(&types, false);
1583 self.exception_types_cache.insert(tag, ty);
1584 Ok(ty)
1585 }
1586
1587 fn build_g0m0_indirect_call(
1588 &mut self,
1589 table_index: u32,
1590 ctx_ptr: PointerValue<'ctx>,
1591 func_type: &FunctionType,
1592 func_ptr: PointerValue<'ctx>,
1593 func_index: IntValue<'ctx>,
1594 ) -> Result<(), CompileError> {
1595 let Some((g0, m0)) = self.g0m0 else {
1596 return Err(CompileError::Codegen(
1597 "Call to build_g0m0_indirect_call without g0m0 parameters!".to_string(),
1598 ));
1599 };
1600
1601 let mut local_func_indices = vec![];
1602 let mut foreign_func_indices = vec![];
1603
1604 for t in &self.wasm_module.table_initializers {
1605 if t.table_index.as_u32() == table_index {
1606 for (func_in_table_idx, func_idx) in t.elements.iter().enumerate() {
1607 if self.wasm_module.local_func_index(*func_idx).is_some() {
1608 local_func_indices.push(func_in_table_idx)
1609 } else {
1610 foreign_func_indices.push(func_in_table_idx)
1611 }
1612 }
1613 break;
1614 }
1615 }
1616
1617 let g0_value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, "g0"));
1620
1621 let needs_switch = self.g0m0.is_some()
1622 && !local_func_indices.is_empty()
1623 && !foreign_func_indices.is_empty();
1624
1625 if needs_switch {
1626 let foreign_idx_block = self
1627 .context
1628 .append_basic_block(self.function, "foreign_call_block");
1629 let local_idx_block = self
1630 .context
1631 .append_basic_block(self.function, "local_call_block");
1632 let unreachable_indirect_call_branch_block = self
1633 .context
1634 .append_basic_block(self.function, "unreachable_indirect_call_branch");
1635
1636 let cont = self.context.append_basic_block(self.function, "cont");
1637
1638 err!(
1639 self.builder.build_switch(
1640 func_index,
1641 unreachable_indirect_call_branch_block,
1642 &local_func_indices
1643 .into_iter()
1644 .map(|v| (
1645 self.intrinsics.i32_ty.const_int(v as _, false),
1646 local_idx_block
1647 ))
1648 .chain(foreign_func_indices.into_iter().map(|v| (
1649 self.intrinsics.i32_ty.const_int(v as _, false),
1650 foreign_idx_block
1651 )))
1652 .collect::<Vec<_>>()
1653 )
1654 );
1655
1656 self.builder
1657 .position_at_end(unreachable_indirect_call_branch_block);
1658 err!(self.builder.build_unreachable());
1659
1660 self.builder.position_at_end(local_idx_block);
1662 let local_call_site = self.build_indirect_call(
1663 ctx_ptr,
1664 func_type,
1665 func_ptr,
1666 Some(G0M0FunctionKind::Local),
1667 Some((g0_value.into_int_value(), m0)),
1668 )?;
1669
1670 let local_rets = self.abi.rets_from_call(
1671 &self.builder,
1672 self.intrinsics,
1673 local_call_site,
1674 func_type,
1675 )?;
1676
1677 err!(self.builder.build_unconditional_branch(cont));
1678
1679 self.builder.position_at_end(foreign_idx_block);
1680 let foreign_call_site = self.build_indirect_call(
1681 ctx_ptr,
1682 func_type,
1683 func_ptr,
1684 Some(G0M0FunctionKind::Imported),
1685 None,
1686 )?;
1687
1688 let foreign_rets = self.abi.rets_from_call(
1689 &self.builder,
1690 self.intrinsics,
1691 foreign_call_site,
1692 func_type,
1693 )?;
1694
1695 err!(self.builder.build_unconditional_branch(cont));
1696
1697 self.builder.position_at_end(cont);
1698
1699 for i in 0..foreign_rets.len() {
1700 let f_i = foreign_rets[i];
1701 let l_i = local_rets[i];
1702 let ty = f_i.get_type();
1703 let v = err!(self.builder.build_phi(ty, ""));
1704 v.add_incoming(&[(&f_i, foreign_idx_block), (&l_i, local_idx_block)]);
1705 self.state.push1(v.as_basic_value());
1706 }
1707 } else if foreign_func_indices.is_empty() {
1708 let call_site = self.build_indirect_call(
1709 ctx_ptr,
1710 func_type,
1711 func_ptr,
1712 Some(G0M0FunctionKind::Local),
1713 Some((g0_value.into_int_value(), m0)),
1714 )?;
1715
1716 self.abi
1717 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1718 .iter()
1719 .for_each(|ret| self.state.push1(*ret));
1720 } else {
1721 let call_site = self.build_indirect_call(
1722 ctx_ptr,
1723 func_type,
1724 func_ptr,
1725 Some(G0M0FunctionKind::Imported),
1726 Some((g0_value.into_int_value(), m0)),
1727 )?;
1728 self.abi
1729 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1730 .iter()
1731 .for_each(|ret| self.state.push1(*ret));
1732 }
1733
1734 Ok(())
1735 }
1736
1737 fn build_indirect_call(
1738 &mut self,
1739 ctx_ptr: PointerValue<'ctx>,
1740 func_type: &FunctionType,
1741 func_ptr: PointerValue<'ctx>,
1742 func_kind: Option<G0M0FunctionKind>,
1743 g0m0_params: LocalFunctionG0M0params<'ctx>,
1744 ) -> Result<CallSiteValue<'ctx>, CompileError> {
1745 let (llvm_func_type, llvm_func_attrs) = self.abi.func_type_to_llvm(
1746 self.context,
1747 self.intrinsics,
1748 Some(self.ctx.get_offsets()),
1749 func_type,
1750 func_kind,
1751 )?;
1752
1753 let params = self.state.popn_save_extra(func_type.params().len())?;
1754
1755 let params = params
1757 .iter()
1758 .zip(func_type.params().iter())
1759 .map(|((v, info), wasm_ty)| match wasm_ty {
1760 Type::F32 => err_nt!(self.builder.build_bit_cast(
1761 self.apply_pending_canonicalization(*v, *info)?,
1762 self.intrinsics.f32_ty,
1763 "",
1764 )),
1765 Type::F64 => err_nt!(self.builder.build_bit_cast(
1766 self.apply_pending_canonicalization(*v, *info)?,
1767 self.intrinsics.f64_ty,
1768 "",
1769 )),
1770 Type::V128 => self.apply_pending_canonicalization(*v, *info),
1771 _ => Ok(*v),
1772 })
1773 .collect::<Result<Vec<_>, _>>()?;
1774
1775 let params = self.abi.args_to_call(
1776 &self.alloca_builder,
1777 func_type,
1778 &llvm_func_type,
1779 ctx_ptr,
1780 params.as_slice(),
1781 self.intrinsics,
1782 g0m0_params,
1783 )?;
1784
1785 let typed_func_ptr = err!(self.builder.build_pointer_cast(
1786 func_ptr,
1787 self.context.ptr_type(AddressSpace::default()),
1788 "typed_func_ptr",
1789 ));
1790
1791 let call_site_local = if let Some(lpad) = self.state.get_innermost_landingpad() {
1812 let then_block = self.context.append_basic_block(self.function, "then_block");
1813
1814 let ret = err!(self.builder.build_indirect_invoke(
1815 llvm_func_type,
1816 typed_func_ptr,
1817 params.as_slice(),
1818 then_block,
1819 lpad,
1820 "",
1821 ));
1822
1823 self.builder.position_at_end(then_block);
1824 ret
1825 } else {
1826 err!(
1827 self.builder.build_indirect_call(
1828 llvm_func_type,
1829 typed_func_ptr,
1830 params
1831 .iter()
1832 .copied()
1833 .map(Into::into)
1834 .collect::<Vec<BasicMetadataValueEnum>>()
1835 .as_slice(),
1836 "indirect_call",
1837 )
1838 )
1839 };
1840 for (attr, attr_loc) in llvm_func_attrs {
1841 call_site_local.add_attribute(attr_loc, attr);
1842 }
1843
1844 Ok(call_site_local)
1845 }
1846
1847 fn build_or_get_vmctx_alloca(&mut self) -> Result<PointerValue<'ctx>, CompileError> {
1848 if let Some(vmctx_alloca) = self.vmctx_alloca {
1849 return Ok(vmctx_alloca);
1850 }
1851
1852 let vmctx_alloca = err!(
1853 self.alloca_builder
1854 .build_alloca(self.intrinsics.ptr_ty, "vmctx")
1855 );
1856 err!(
1857 self.alloca_builder
1858 .build_store(vmctx_alloca, self.ctx.basic())
1859 );
1860 self.vmctx_alloca = Some(vmctx_alloca);
1861 Ok(vmctx_alloca)
1862 }
1863}
1864
1865pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
1951 g0m0: Option<(PointerValue<'ctx>, PointerValue<'ctx>)>,
1952 context: &'ctx Context,
1953 builder: Builder<'ctx>,
1954 alloca_builder: Builder<'ctx>,
1955 intrinsics: &'a Intrinsics<'ctx>,
1956 state: State<'ctx>,
1957 function: FunctionValue<'ctx>,
1958 locals: Vec<(BasicTypeEnum<'ctx>, PointerValue<'ctx>)>, ctx: CtxType<'ctx, 'a>,
1960 unreachable_depth: usize,
1961 memory_styles: &'a PrimaryMap<MemoryIndex, MemoryStyle>,
1962 _table_styles: &'a PrimaryMap<TableIndex, TableStyle>,
1963
1964 module: &'a Module<'ctx>,
1972 module_translation: &'a ModuleTranslationState,
1973 wasm_module: &'a ModuleInfo,
1974 symbol_registry: &'a dyn SymbolRegistry,
1975 abi: &'a dyn Abi,
1976 config: &'a LLVM,
1977 tags_cache: HashMap<i32, BasicValueEnum<'ctx>>,
1978 exception_types_cache: HashMap<u32, inkwell::types::StructType<'ctx>>,
1979 vmctx_alloca: Option<PointerValue<'ctx>>,
1980 binary_fmt: target_lexicon::BinaryFormat,
1981}
1982
1983impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
1984 fn translate_operator(&mut self, op: Operator, _source_loc: u32) -> Result<(), CompileError> {
1985 let vmctx = &self.ctx.basic().into_pointer_value();
1988
1989 if !self.state.reachable {
1992 match op {
1993 Operator::Block { blockty: _ }
1994 | Operator::Loop { blockty: _ }
1995 | Operator::If { blockty: _ } => {
1996 self.unreachable_depth += 1;
1997 return Ok(());
1998 }
1999 Operator::Else => {
2000 if self.unreachable_depth != 0 {
2001 return Ok(());
2002 }
2003 }
2004 Operator::End => {
2005 if self.unreachable_depth != 0 {
2006 self.unreachable_depth -= 1;
2007 return Ok(());
2008 }
2009 }
2010 _ => {
2011 return Ok(());
2012 }
2013 }
2014 }
2015
2016 match op {
2017 Operator::Block { blockty } => {
2022 let current_block = self
2023 .builder
2024 .get_insert_block()
2025 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2026
2027 let end_block = self.context.append_basic_block(self.function, "end");
2028 self.builder.position_at_end(end_block);
2029
2030 let phis: SmallVec<[PhiValue<'ctx>; 1]> = self
2031 .module_translation
2032 .blocktype_params_results(&blockty)?
2033 .1
2034 .iter()
2035 .map(|&wp_ty| {
2036 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2037 type_to_llvm(self.intrinsics, wasm_ty)
2038 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2039 })
2040 })
2041 .collect::<Result<_, _>>()?;
2042
2043 self.state.push_block(
2044 end_block,
2045 phis,
2046 self.module_translation
2047 .blocktype_params_results(&blockty)?
2048 .0
2049 .len(),
2050 );
2051 self.builder.position_at_end(current_block);
2052 }
2053 Operator::Loop { blockty } => {
2054 let loop_body = self.context.append_basic_block(self.function, "loop_body");
2055 let loop_next = self.context.append_basic_block(self.function, "loop_outer");
2056 let pre_loop_block = self.builder.get_insert_block().unwrap();
2057
2058 err!(self.builder.build_unconditional_branch(loop_body));
2059
2060 self.builder.position_at_end(loop_next);
2061 let blocktypes = self.module_translation.blocktype_params_results(&blockty)?;
2062 let phis = blocktypes
2063 .1
2064 .iter()
2065 .map(|&wp_ty| {
2066 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2067 type_to_llvm(self.intrinsics, wasm_ty)
2068 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2069 })
2070 })
2071 .collect::<Result<_, _>>()?;
2072 self.builder.position_at_end(loop_body);
2073 let loop_phis: SmallVec<[PhiValue<'ctx>; 1]> = blocktypes
2074 .0
2075 .iter()
2076 .map(|&wp_ty| {
2077 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2078 type_to_llvm(self.intrinsics, wasm_ty)
2079 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2080 })
2081 })
2082 .collect::<Result<_, _>>()?;
2083 for phi in loop_phis.iter().rev() {
2084 let (value, info) = self.state.pop1_extra()?;
2085 let value = self.apply_pending_canonicalization(value, info)?;
2086 phi.add_incoming(&[(&value, pre_loop_block)]);
2087 }
2088 for phi in &loop_phis {
2089 self.state.push1(phi.as_basic_value());
2090 }
2091
2092 let num_inputs = loop_phis.len();
2093 self.state
2094 .push_loop(loop_body, loop_next, loop_phis, phis, num_inputs);
2095 }
2096 Operator::Br { relative_depth } => {
2097 let frame = self.state.frame_at_depth(relative_depth)?;
2098
2099 let current_block = self
2100 .builder
2101 .get_insert_block()
2102 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2103
2104 let phis = if frame.is_loop() {
2105 frame.loop_body_phis()
2106 } else {
2107 frame.phis()
2108 };
2109
2110 let len = phis.len();
2111 let values = self.state.peekn_extra(len)?;
2112 let values = values
2113 .iter()
2114 .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2115 .collect::<Result<Vec<_>, _>>()?;
2116
2117 for (phi, value) in phis.iter().zip(values.into_iter()) {
2121 phi.add_incoming(&[(&value, current_block)]);
2122 }
2123
2124 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2125
2126 self.state.popn(len)?;
2127 self.state.reachable = false;
2128 }
2129 Operator::BrIf { relative_depth } => {
2130 let cond = self.state.pop1()?;
2131 let frame = self.state.frame_at_depth(relative_depth)?;
2132
2133 let current_block = self
2134 .builder
2135 .get_insert_block()
2136 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2137
2138 let phis = if frame.is_loop() {
2139 frame.loop_body_phis()
2140 } else {
2141 frame.phis()
2142 };
2143
2144 let param_stack = self.state.peekn_extra(phis.len())?;
2145 let param_stack = param_stack
2146 .iter()
2147 .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2148 .collect::<Result<Vec<_>, _>>()?;
2149
2150 for (phi, value) in phis.iter().zip(param_stack) {
2151 phi.add_incoming(&[(&value, current_block)]);
2152 }
2153
2154 let else_block = self.context.append_basic_block(self.function, "else");
2155
2156 let cond_value = err!(self.builder.build_int_compare(
2157 IntPredicate::NE,
2158 cond.into_int_value(),
2159 self.intrinsics.i32_zero,
2160 "",
2161 ));
2162 err!(self.builder.build_conditional_branch(
2163 cond_value,
2164 *frame.br_dest(),
2165 else_block
2166 ));
2167 self.builder.position_at_end(else_block);
2168 }
2169 Operator::BrTable { ref targets } => {
2170 let current_block = self
2171 .builder
2172 .get_insert_block()
2173 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2174
2175 let index = self.state.pop1()?;
2176
2177 let default_frame = self.state.frame_at_depth(targets.default())?;
2178
2179 let phis = if default_frame.is_loop() {
2180 default_frame.loop_body_phis()
2181 } else {
2182 default_frame.phis()
2183 };
2184 let args = self.state.peekn(phis.len())?;
2185
2186 for (phi, value) in phis.iter().zip(args.iter()) {
2187 phi.add_incoming(&[(value, current_block)]);
2188 }
2189
2190 let cases: Vec<_> = targets
2191 .targets()
2192 .enumerate()
2193 .map(|(case_index, depth)| {
2194 let depth = depth.map_err(from_binaryreadererror_wasmerror)?;
2195 let frame_result: Result<&ControlFrame, CompileError> =
2196 self.state.frame_at_depth(depth);
2197 let frame = match frame_result {
2198 Ok(v) => v,
2199 Err(e) => return Err(e),
2200 };
2201 let case_index_literal =
2202 self.context.i32_type().const_int(case_index as u64, false);
2203 let phis = if frame.is_loop() {
2204 frame.loop_body_phis()
2205 } else {
2206 frame.phis()
2207 };
2208 for (phi, value) in phis.iter().zip(args.iter()) {
2209 phi.add_incoming(&[(value, current_block)]);
2210 }
2211
2212 Ok((case_index_literal, *frame.br_dest()))
2213 })
2214 .collect::<Result<_, _>>()?;
2215
2216 err!(self.builder.build_switch(
2217 index.into_int_value(),
2218 *default_frame.br_dest(),
2219 &cases[..],
2220 ));
2221
2222 let args_len = args.len();
2223 self.state.popn(args_len)?;
2224 self.state.reachable = false;
2225 }
2226 Operator::If { blockty } => {
2227 let current_block = self
2228 .builder
2229 .get_insert_block()
2230 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2231 let if_then_block = self.context.append_basic_block(self.function, "if_then");
2232 let if_else_block = self.context.append_basic_block(self.function, "if_else");
2233 let end_block = self.context.append_basic_block(self.function, "if_end");
2234
2235 let end_phis = {
2236 self.builder.position_at_end(end_block);
2237
2238 let phis = self
2239 .module_translation
2240 .blocktype_params_results(&blockty)?
2241 .1
2242 .iter()
2243 .map(|&wp_ty| {
2244 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2245 type_to_llvm(self.intrinsics, wasm_ty)
2246 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2247 })
2248 })
2249 .collect::<Result<_, _>>()?;
2250
2251 self.builder.position_at_end(current_block);
2252 phis
2253 };
2254
2255 let cond = self.state.pop1()?;
2256
2257 let cond_value = err!(self.builder.build_int_compare(
2258 IntPredicate::NE,
2259 cond.into_int_value(),
2260 self.intrinsics.i32_zero,
2261 "",
2262 ));
2263
2264 err!(self.builder.build_conditional_branch(
2265 cond_value,
2266 if_then_block,
2267 if_else_block
2268 ));
2269 self.builder.position_at_end(if_else_block);
2270 let block_param_types = self
2271 .module_translation
2272 .blocktype_params_results(&blockty)?
2273 .0
2274 .iter()
2275 .map(|&wp_ty| {
2276 err_nt!(wptype_to_type(wp_ty))
2277 .and_then(|wasm_ty| type_to_llvm(self.intrinsics, wasm_ty))
2278 })
2279 .collect::<Result<Vec<_>, _>>()?;
2280 let else_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2281 .iter()
2282 .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2283 .collect::<Result<SmallVec<_>, _>>()?;
2284 self.builder.position_at_end(if_then_block);
2285 let then_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2286 .iter()
2287 .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2288 .collect::<Result<SmallVec<_>, _>>()?;
2289 for (else_phi, then_phi) in else_phis.iter().rev().zip(then_phis.iter().rev()) {
2290 let (value, info) = self.state.pop1_extra()?;
2291 let value = self.apply_pending_canonicalization(value, info)?;
2292 else_phi.add_incoming(&[(&value, current_block)]);
2293 then_phi.add_incoming(&[(&value, current_block)]);
2294 }
2295 for phi in then_phis.iter() {
2296 self.state.push1(phi.as_basic_value());
2297 }
2298
2299 self.state.push_if(
2300 if_then_block,
2301 if_else_block,
2302 end_block,
2303 then_phis,
2304 else_phis,
2305 end_phis,
2306 block_param_types.len(),
2307 );
2308 }
2309 Operator::Else => {
2310 if self.state.reachable {
2311 let frame = self.state.frame_at_depth(0)?;
2312 let current_block = self.builder.get_insert_block().ok_or_else(|| {
2313 CompileError::Codegen("not currently in a block".to_string())
2314 })?;
2315
2316 for phi in frame.phis().to_vec().iter().rev() {
2317 let (value, info) = self.state.pop1_extra()?;
2318 let value = self.apply_pending_canonicalization(value, info)?;
2319 phi.add_incoming(&[(&value, current_block)])
2320 }
2321
2322 let frame = self.state.frame_at_depth(0)?;
2323 err!(self.builder.build_unconditional_branch(*frame.code_after()));
2324 }
2325
2326 let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
2327 if_else,
2328 if_else_state,
2329 ..
2330 } = self.state.frame_at_depth_mut(0)?
2331 {
2332 (if_else, if_else_state)
2333 } else {
2334 unreachable!()
2335 };
2336
2337 *if_else_state = IfElseState::Else;
2338
2339 self.builder.position_at_end(*if_else_block);
2340 self.state.reachable = true;
2341
2342 if let ControlFrame::IfElse { else_phis, .. } = self.state.frame_at_depth(0)? {
2343 for phi in else_phis.clone().iter() {
2345 self.state.push1(phi.as_basic_value());
2346 }
2347 };
2348 }
2349
2350 Operator::End => {
2351 let frame = self.state.pop_frame()?;
2352 let current_block = self
2353 .builder
2354 .get_insert_block()
2355 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2356
2357 if self.state.reachable {
2358 for phi in frame.phis().iter().rev() {
2359 let (value, info) = self.state.pop1_extra()?;
2360 let value = self.apply_pending_canonicalization(value, info)?;
2361 phi.add_incoming(&[(&value, current_block)]);
2362 }
2363
2364 err!(self.builder.build_unconditional_branch(*frame.code_after()));
2365 }
2366
2367 if let ControlFrame::IfElse {
2368 if_else,
2369 next,
2370 if_else_state: IfElseState::If,
2371 else_phis,
2372 ..
2373 } = &frame
2374 {
2375 for (phi, else_phi) in frame.phis().iter().zip(else_phis.iter()) {
2376 phi.add_incoming(&[(&else_phi.as_basic_value(), *if_else)]);
2377 }
2378 self.builder.position_at_end(*if_else);
2379 err!(self.builder.build_unconditional_branch(*next));
2380 } else if let ControlFrame::Landingpad { .. } = &frame {
2381 self.state.pop_landingpad();
2382 };
2383
2384 self.builder.position_at_end(*frame.code_after());
2385 self.state.reset_stack(&frame);
2386
2387 self.state.reachable = true;
2388
2389 for phi in frame.phis() {
2391 if phi.count_incoming() != 0 {
2392 self.state.push1(phi.as_basic_value());
2393 } else {
2394 let basic_ty = phi.as_basic_value().get_type();
2401 let placeholder_value = basic_ty.const_zero();
2402 self.state.push1(placeholder_value);
2403 phi.as_instruction().erase_from_basic_block();
2404 }
2405 }
2406 }
2407 Operator::Return => {
2408 let current_block = self
2409 .builder
2410 .get_insert_block()
2411 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2412
2413 let frame = self.state.outermost_frame()?;
2414 for phi in frame.phis().to_vec().iter().rev() {
2415 let (arg, info) = self.state.pop1_extra()?;
2416 let arg = self.apply_pending_canonicalization(arg, info)?;
2417 phi.add_incoming(&[(&arg, current_block)]);
2418 }
2419 let frame = self.state.outermost_frame()?;
2420 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2421
2422 self.state.reachable = false;
2423 }
2424
2425 Operator::Unreachable => {
2426 err!(self.builder.build_call(
2427 self.intrinsics.throw_trap,
2428 &[self.intrinsics.trap_unreachable.into()],
2429 "throw",
2430 ));
2431 err!(self.builder.build_unreachable());
2432
2433 self.state.reachable = false;
2434 }
2435
2436 Operator::Nop => {
2441 }
2443 Operator::Drop => {
2444 self.state.pop1()?;
2445 }
2446
2447 Operator::I32Const { value } => {
2449 let i = self.intrinsics.i32_ty.const_int(value as u64, false);
2450 let info = if is_f32_arithmetic(value as u32) {
2451 ExtraInfo::arithmetic_f32()
2452 } else {
2453 Default::default()
2454 };
2455 self.state.push1_extra(i, info);
2456 }
2457 Operator::I64Const { value } => {
2458 let i = self.intrinsics.i64_ty.const_int(value as u64, false);
2459 let info = if is_f64_arithmetic(value as u64) {
2460 ExtraInfo::arithmetic_f64()
2461 } else {
2462 Default::default()
2463 };
2464 self.state.push1_extra(i, info);
2465 }
2466 Operator::F32Const { value } => {
2467 let bits = self.intrinsics.i32_ty.const_int(value.bits() as u64, false);
2468 let info = if is_f32_arithmetic(value.bits()) {
2469 ExtraInfo::arithmetic_f32()
2470 } else {
2471 Default::default()
2472 };
2473 let f = err!(
2474 self.builder
2475 .build_bit_cast(bits, self.intrinsics.f32_ty, "f")
2476 );
2477 self.state.push1_extra(f, info);
2478 }
2479 Operator::F64Const { value } => {
2480 let bits = self.intrinsics.i64_ty.const_int(value.bits(), false);
2481 let info = if is_f64_arithmetic(value.bits()) {
2482 ExtraInfo::arithmetic_f64()
2483 } else {
2484 Default::default()
2485 };
2486 let f = err!(
2487 self.builder
2488 .build_bit_cast(bits, self.intrinsics.f64_ty, "f")
2489 );
2490 self.state.push1_extra(f, info);
2491 }
2492 Operator::V128Const { value } => {
2493 let mut hi: [u8; 8] = Default::default();
2494 let mut lo: [u8; 8] = Default::default();
2495 hi.copy_from_slice(&value.bytes()[0..8]);
2496 lo.copy_from_slice(&value.bytes()[8..16]);
2497 let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
2498 let i = self
2499 .intrinsics
2500 .i128_ty
2501 .const_int_arbitrary_precision(&packed);
2502 let mut quad1: [u8; 4] = Default::default();
2503 let mut quad2: [u8; 4] = Default::default();
2504 let mut quad3: [u8; 4] = Default::default();
2505 let mut quad4: [u8; 4] = Default::default();
2506 quad1.copy_from_slice(&value.bytes()[0..4]);
2507 quad2.copy_from_slice(&value.bytes()[4..8]);
2508 quad3.copy_from_slice(&value.bytes()[8..12]);
2509 quad4.copy_from_slice(&value.bytes()[12..16]);
2510 let mut info: ExtraInfo = Default::default();
2511 if is_f32_arithmetic(u32::from_le_bytes(quad1))
2512 && is_f32_arithmetic(u32::from_le_bytes(quad2))
2513 && is_f32_arithmetic(u32::from_le_bytes(quad3))
2514 && is_f32_arithmetic(u32::from_le_bytes(quad4))
2515 {
2516 info |= ExtraInfo::arithmetic_f32();
2517 }
2518 if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
2519 info |= ExtraInfo::arithmetic_f64();
2520 }
2521 self.state.push1_extra(i, info);
2522 }
2523
2524 Operator::I8x16Splat => {
2525 let (v, i) = self.state.pop1_extra()?;
2526 let v = v.into_int_value();
2527 let v = err!(
2528 self.builder
2529 .build_int_truncate(v, self.intrinsics.i8_ty, "")
2530 );
2531 let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
2532 let res = err!(
2533 self.builder
2534 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2535 );
2536 self.state.push1_extra(res, i);
2537 }
2538 Operator::I16x8Splat => {
2539 let (v, i) = self.state.pop1_extra()?;
2540 let v = v.into_int_value();
2541 let v = err!(
2542 self.builder
2543 .build_int_truncate(v, self.intrinsics.i16_ty, "")
2544 );
2545 let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
2546 let res = err!(
2547 self.builder
2548 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2549 );
2550 self.state.push1_extra(res, i);
2551 }
2552 Operator::I32x4Splat => {
2553 let (v, i) = self.state.pop1_extra()?;
2554 let res = self.splat_vector(v, self.intrinsics.i32x4_ty)?;
2555 let res = err!(
2556 self.builder
2557 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2558 );
2559 self.state.push1_extra(res, i);
2560 }
2561 Operator::I64x2Splat => {
2562 let (v, i) = self.state.pop1_extra()?;
2563 let res = self.splat_vector(v, self.intrinsics.i64x2_ty)?;
2564 let res = err!(
2565 self.builder
2566 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2567 );
2568 self.state.push1_extra(res, i);
2569 }
2570 Operator::F32x4Splat => {
2571 let (v, i) = self.state.pop1_extra()?;
2572 let res = self.splat_vector(v, self.intrinsics.f32x4_ty)?;
2573 let res = err!(
2574 self.builder
2575 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2576 );
2577 self.state.push1_extra(res, i);
2580 }
2581 Operator::F64x2Splat => {
2582 let (v, i) = self.state.pop1_extra()?;
2583 let res = self.splat_vector(v, self.intrinsics.f64x2_ty)?;
2584 let res = err!(
2585 self.builder
2586 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2587 );
2588 self.state.push1_extra(res, i);
2591 }
2592
2593 Operator::LocalGet { local_index } => {
2595 let (type_value, pointer_value) = self.locals[local_index as usize];
2596 let v = err!(self.builder.build_load(
2597 type_value,
2598 pointer_value,
2599 &format!("local_{local_index}_get")
2600 ));
2601 tbaa_label(
2602 self.module,
2603 self.intrinsics,
2604 format!("local {local_index}"),
2605 v.as_instruction_value().unwrap(),
2606 );
2607 self.state.push1(v);
2608 }
2609 Operator::LocalSet { local_index } => {
2610 let pointer_value = self.locals[local_index as usize].1;
2611 let (v, i) = self.state.pop1_extra()?;
2612 let v = self.apply_pending_canonicalization(v, i)?;
2613 let store = err!(self.builder.build_store(pointer_value, v));
2614 tbaa_label(
2615 self.module,
2616 self.intrinsics,
2617 format!("local {local_index}"),
2618 store,
2619 );
2620 }
2621 Operator::LocalTee { local_index } => {
2622 let pointer_value = self.locals[local_index as usize].1;
2623 let (v, i) = self.state.peek1_extra()?;
2624 let v = self.apply_pending_canonicalization(v, i)?;
2625 let store = err!(self.builder.build_store(pointer_value, v));
2626 tbaa_label(
2627 self.module,
2628 self.intrinsics,
2629 format!("local {local_index}"),
2630 store,
2631 );
2632 }
2633
2634 Operator::GlobalGet { global_index } => {
2635 if self.g0m0.is_some() && global_index == 0 {
2636 let Some((g0, _)) = self.g0m0 else {
2637 unreachable!()
2638 };
2639
2640 let value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, ""));
2642
2643 self.state.push1(value);
2644 } else {
2645 let global_index = GlobalIndex::from_u32(global_index);
2646 match self
2647 .ctx
2648 .global(global_index, self.intrinsics, self.module)?
2649 {
2650 GlobalCache::Const { value } => {
2651 self.state.push1(*value);
2652 }
2653 GlobalCache::Mut {
2654 ptr_to_value,
2655 value_type,
2656 } => {
2657 let value =
2658 err!(self.builder.build_load(*value_type, *ptr_to_value, ""));
2659 tbaa_label(
2660 self.module,
2661 self.intrinsics,
2662 format!("global {}", global_index.as_u32()),
2663 value.as_instruction_value().unwrap(),
2664 );
2665 self.state.push1(value);
2666 }
2667 }
2668 }
2669 }
2670 Operator::GlobalSet { global_index } => {
2671 if self.g0m0.is_some() && global_index == 0 {
2672 let Some((g0, _)) = self.g0m0 else {
2673 unreachable!()
2674 };
2675 let ptr_to_value = g0;
2676 let (value, info) = self.state.pop1_extra()?;
2677 let value = self.apply_pending_canonicalization(value, info)?;
2678 let store = err!(self.builder.build_store(ptr_to_value, value));
2679 tbaa_label(self.module, self.intrinsics, "global 0".to_string(), store);
2680 } else {
2681 let global_index = GlobalIndex::from_u32(global_index);
2682 match self
2683 .ctx
2684 .global(global_index, self.intrinsics, self.module)?
2685 {
2686 GlobalCache::Const { value: _ } => {
2687 return Err(CompileError::Codegen(format!(
2688 "global.set on immutable global index {}",
2689 global_index.as_u32()
2690 )));
2691 }
2692 GlobalCache::Mut { ptr_to_value, .. } => {
2693 let ptr_to_value = *ptr_to_value;
2694 let (value, info) = self.state.pop1_extra()?;
2695 let value = self.apply_pending_canonicalization(value, info)?;
2696 let store = err!(self.builder.build_store(ptr_to_value, value));
2697 tbaa_label(
2698 self.module,
2699 self.intrinsics,
2700 format!("global {}", global_index.as_u32()),
2701 store,
2702 );
2703 }
2704 }
2705 }
2706 }
2707
2708 Operator::TypedSelect { .. } | Operator::Select => {
2711 let ((v1, i1), (v2, i2), (cond, _)) = self.state.pop3_extra()?;
2712 let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
2720 || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
2721 {
2722 (
2723 self.apply_pending_canonicalization(v1, i1)?,
2724 i1.strip_pending(),
2725 self.apply_pending_canonicalization(v2, i2)?,
2726 i2.strip_pending(),
2727 )
2728 } else {
2729 (v1, i1, v2, i2)
2730 };
2731 let cond_value = err!(self.builder.build_int_compare(
2732 IntPredicate::NE,
2733 cond.into_int_value(),
2734 self.intrinsics.i32_zero,
2735 "",
2736 ));
2737 let res = err!(self.builder.build_select(cond_value, v1, v2, ""));
2738 let info = {
2739 let mut info = (i1.strip_pending() & i2.strip_pending())?;
2740 if i1.has_pending_f32_nan() {
2741 debug_assert!(i2.has_pending_f32_nan());
2742 info = (info | ExtraInfo::pending_f32_nan())?;
2743 }
2744 if i1.has_pending_f64_nan() {
2745 debug_assert!(i2.has_pending_f64_nan());
2746 info = (info | ExtraInfo::pending_f64_nan())?;
2747 }
2748 info
2749 };
2750 self.state.push1_extra(res, info);
2751 }
2752 Operator::Call { function_index } => {
2753 let func_index = FunctionIndex::from_u32(function_index);
2754 let sigindex = &self.wasm_module.functions[func_index];
2755 let func_type = &self.wasm_module.signatures[*sigindex];
2756
2757 let mut g0m0_params = None;
2758
2759 let FunctionCache {
2760 func,
2761 llvm_func_type,
2762 vmctx: callee_vmctx,
2763 attrs,
2764 } = if let Some(local_func_index) = self.wasm_module.local_func_index(func_index) {
2765 if let Some((g0, m0)) = &self.g0m0 {
2766 let value = err!(self.builder.build_load(self.intrinsics.i32_ty, *g0, ""));
2768
2769 g0m0_params = Some((value.into_int_value(), *m0));
2770 }
2771
2772 let function_name = self
2773 .symbol_registry
2774 .symbol_to_name(Symbol::LocalFunction(local_func_index));
2775
2776 self.ctx.local_func(
2777 local_func_index,
2778 func_index,
2779 self.intrinsics,
2780 self.module,
2781 self.context,
2782 func_type,
2783 &function_name,
2784 )?
2785 } else {
2786 self.ctx
2787 .func(func_index, self.intrinsics, self.context, func_type)?
2788 };
2789 let llvm_func_type = *llvm_func_type;
2790 let func = *func;
2791 let callee_vmctx = *callee_vmctx;
2792 let attrs = attrs.clone();
2793
2794 let params = self.state.popn_save_extra(func_type.params().len())?;
2800
2801 let params = params
2803 .iter()
2804 .zip(func_type.params().iter())
2805 .map(|((v, info), wasm_ty)| match wasm_ty {
2806 Type::F32 => err_nt!(self.builder.build_bit_cast(
2807 self.apply_pending_canonicalization(*v, *info)?,
2808 self.intrinsics.f32_ty,
2809 "",
2810 )),
2811 Type::F64 => err_nt!(self.builder.build_bit_cast(
2812 self.apply_pending_canonicalization(*v, *info)?,
2813 self.intrinsics.f64_ty,
2814 "",
2815 )),
2816 Type::V128 => self.apply_pending_canonicalization(*v, *info),
2817 _ => Ok(*v),
2818 })
2819 .collect::<Result<Vec<_>, _>>()?;
2820
2821 let params = self.abi.args_to_call(
2822 &self.alloca_builder,
2823 func_type,
2824 &llvm_func_type,
2825 callee_vmctx.into_pointer_value(),
2826 params.as_slice(),
2827 self.intrinsics,
2828 g0m0_params,
2829 )?;
2830
2831 let call_site = if let Some(lpad) = self.state.get_innermost_landingpad() {
2851 let then_block = self.context.append_basic_block(self.function, "then_block");
2852
2853 let ret = err!(self.builder.build_indirect_invoke(
2854 llvm_func_type,
2855 func,
2856 params.as_slice(),
2857 then_block,
2858 lpad,
2859 "",
2860 ));
2861
2862 self.builder.position_at_end(then_block);
2863 ret
2864 } else {
2865 err!(
2866 self.builder.build_indirect_call(
2867 llvm_func_type,
2868 func,
2869 params
2870 .iter()
2871 .copied()
2872 .map(Into::into)
2873 .collect::<Vec<BasicMetadataValueEnum>>()
2874 .as_slice(),
2875 "",
2876 )
2877 )
2878 };
2879 for (attr, attr_loc) in attrs {
2880 call_site.add_attribute(attr_loc, attr);
2881 }
2882 self.abi
2899 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
2900 .iter()
2901 .for_each(|ret| self.state.push1(*ret));
2902 }
2903 Operator::CallIndirect {
2904 type_index,
2905 table_index,
2906 } => {
2907 let sigindex = SignatureIndex::from_u32(type_index);
2908 let func_type = &self.wasm_module.signatures[sigindex];
2909 let expected_dynamic_sigindex =
2910 self.ctx
2911 .dynamic_sigindex(sigindex, self.intrinsics, self.module)?;
2912 let (table_base, table_bound) = self.ctx.table(
2913 TableIndex::from_u32(table_index),
2914 self.intrinsics,
2915 self.module,
2916 &self.builder,
2917 )?;
2918 let func_index = self.state.pop1()?.into_int_value();
2919
2920 let truncated_table_bounds = err!(self.builder.build_int_truncate(
2921 table_bound,
2922 self.intrinsics.i32_ty,
2923 "truncated_table_bounds",
2924 ));
2925
2926 let index_in_bounds = err!(self.builder.build_int_compare(
2928 IntPredicate::ULT,
2929 func_index,
2930 truncated_table_bounds,
2931 "index_in_bounds",
2932 ));
2933
2934 let index_in_bounds = err!(self.builder.build_call(
2935 self.intrinsics.expect_i1,
2936 &[
2937 index_in_bounds.into(),
2938 self.intrinsics.i1_ty.const_int(1, false).into(),
2939 ],
2940 "index_in_bounds_expect",
2941 ))
2942 .try_as_basic_value()
2943 .left()
2944 .unwrap()
2945 .into_int_value();
2946
2947 let in_bounds_continue_block = self
2948 .context
2949 .append_basic_block(self.function, "in_bounds_continue_block");
2950 let not_in_bounds_block = self
2951 .context
2952 .append_basic_block(self.function, "not_in_bounds_block");
2953 err!(self.builder.build_conditional_branch(
2954 index_in_bounds,
2955 in_bounds_continue_block,
2956 not_in_bounds_block,
2957 ));
2958 self.builder.position_at_end(not_in_bounds_block);
2959 err!(self.builder.build_call(
2960 self.intrinsics.throw_trap,
2961 &[self.intrinsics.trap_table_access_oob.into()],
2962 "throw",
2963 ));
2964 err!(self.builder.build_unreachable());
2965 self.builder.position_at_end(in_bounds_continue_block);
2966
2967 let casted_table_base = err!(self.builder.build_pointer_cast(
2970 table_base,
2971 self.context.ptr_type(AddressSpace::default()),
2972 "casted_table_base",
2973 ));
2974
2975 let funcref_ptr = unsafe {
2976 err!(self.builder.build_in_bounds_gep(
2977 self.intrinsics.ptr_ty,
2978 casted_table_base,
2979 &[func_index],
2980 "funcref_ptr",
2981 ))
2982 };
2983
2984 let anyfunc_struct_ptr = err!(self.builder.build_load(
2986 self.intrinsics.ptr_ty,
2987 funcref_ptr,
2988 "anyfunc_struct_ptr",
2989 ))
2990 .into_pointer_value();
2991
2992 {
2994 let funcref_not_null = err!(
2995 self.builder
2996 .build_is_not_null(anyfunc_struct_ptr, "null funcref check")
2997 );
2998
2999 let funcref_continue_deref_block = self
3000 .context
3001 .append_basic_block(self.function, "funcref_continue deref_block");
3002
3003 let funcref_is_null_block = self
3004 .context
3005 .append_basic_block(self.function, "funcref_is_null_block");
3006 err!(self.builder.build_conditional_branch(
3007 funcref_not_null,
3008 funcref_continue_deref_block,
3009 funcref_is_null_block,
3010 ));
3011 self.builder.position_at_end(funcref_is_null_block);
3012 err!(self.builder.build_call(
3013 self.intrinsics.throw_trap,
3014 &[self.intrinsics.trap_call_indirect_null.into()],
3015 "throw",
3016 ));
3017 err!(self.builder.build_unreachable());
3018 self.builder.position_at_end(funcref_continue_deref_block);
3019 }
3020
3021 let func_ptr_ptr = self
3023 .builder
3024 .build_struct_gep(
3025 self.intrinsics.anyfunc_ty,
3026 anyfunc_struct_ptr,
3027 0,
3028 "func_ptr_ptr",
3029 )
3030 .unwrap();
3031 let sigindex_ptr = self
3032 .builder
3033 .build_struct_gep(
3034 self.intrinsics.anyfunc_ty,
3035 anyfunc_struct_ptr,
3036 1,
3037 "sigindex_ptr",
3038 )
3039 .unwrap();
3040 let ctx_ptr_ptr = self
3041 .builder
3042 .build_struct_gep(
3043 self.intrinsics.anyfunc_ty,
3044 anyfunc_struct_ptr,
3045 2,
3046 "ctx_ptr_ptr",
3047 )
3048 .unwrap();
3049 let (func_ptr, found_dynamic_sigindex, ctx_ptr) = (
3050 err!(
3051 self.builder
3052 .build_load(self.intrinsics.ptr_ty, func_ptr_ptr, "func_ptr")
3053 )
3054 .into_pointer_value(),
3055 err!(
3056 self.builder
3057 .build_load(self.intrinsics.i32_ty, sigindex_ptr, "sigindex")
3058 )
3059 .into_int_value(),
3060 err!(
3061 self.builder
3062 .build_load(self.intrinsics.ptr_ty, ctx_ptr_ptr, "ctx_ptr")
3063 ),
3064 );
3065
3066 let elem_initialized = err!(self.builder.build_is_not_null(func_ptr, ""));
3070
3071 let sigindices_equal = err!(self.builder.build_int_compare(
3074 IntPredicate::EQ,
3075 expected_dynamic_sigindex,
3076 found_dynamic_sigindex,
3077 "sigindices_equal",
3078 ));
3079
3080 let initialized_and_sigindices_match = err!(self.builder.build_and(
3081 elem_initialized,
3082 sigindices_equal,
3083 ""
3084 ));
3085
3086 let initialized_and_sigindices_match = err!(self.builder.build_call(
3088 self.intrinsics.expect_i1,
3089 &[
3090 initialized_and_sigindices_match.into(),
3091 self.intrinsics.i1_ty.const_int(1, false).into(),
3092 ],
3093 "initialized_and_sigindices_match_expect",
3094 ))
3095 .try_as_basic_value()
3096 .left()
3097 .unwrap()
3098 .into_int_value();
3099
3100 let continue_block = self
3101 .context
3102 .append_basic_block(self.function, "continue_block");
3103 let sigindices_notequal_block = self
3104 .context
3105 .append_basic_block(self.function, "sigindices_notequal_block");
3106 err!(self.builder.build_conditional_branch(
3107 initialized_and_sigindices_match,
3108 continue_block,
3109 sigindices_notequal_block,
3110 ));
3111
3112 self.builder.position_at_end(sigindices_notequal_block);
3113 let trap_code = err!(self.builder.build_select(
3114 elem_initialized,
3115 self.intrinsics.trap_call_indirect_sig,
3116 self.intrinsics.trap_call_indirect_null,
3117 "",
3118 ));
3119 err!(self.builder.build_call(
3120 self.intrinsics.throw_trap,
3121 &[trap_code.into()],
3122 "throw"
3123 ));
3124 err!(self.builder.build_unreachable());
3125 self.builder.position_at_end(continue_block);
3126
3127 if self.g0m0.is_some() {
3128 self.build_g0m0_indirect_call(
3129 table_index,
3130 ctx_ptr.into_pointer_value(),
3131 func_type,
3132 func_ptr,
3133 func_index,
3134 )?;
3135 } else {
3136 let call_site = self.build_indirect_call(
3137 ctx_ptr.into_pointer_value(),
3138 func_type,
3139 func_ptr,
3140 None,
3141 None,
3142 )?;
3143
3144 self.abi
3145 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
3146 .iter()
3147 .for_each(|ret| self.state.push1(*ret));
3148 }
3149 }
3150
3151 Operator::I32Add | Operator::I64Add => {
3156 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3157 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3158 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3159 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3160 let res = err!(self.builder.build_int_add(v1, v2, ""));
3161 self.state.push1(res);
3162 }
3163 Operator::I8x16Add => {
3164 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3165 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3166 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3167 let res = err!(self.builder.build_int_add(v1, v2, ""));
3168 let res = err!(
3169 self.builder
3170 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3171 );
3172 self.state.push1(res);
3173 }
3174 Operator::I16x8Add => {
3175 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3176 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3177 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3178 let res = err!(self.builder.build_int_add(v1, v2, ""));
3179 let res = err!(
3180 self.builder
3181 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3182 );
3183 self.state.push1(res);
3184 }
3185 Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U => {
3186 let extend_op = match op {
3187 Operator::I16x8ExtAddPairwiseI8x16S => {
3188 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, "")
3189 }
3190 Operator::I16x8ExtAddPairwiseI8x16U => {
3191 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, "")
3192 }
3193 _ => unreachable!("Unhandled internal variant"),
3194 };
3195 let (v, i) = self.state.pop1_extra()?;
3196 let (v, _) = self.v128_into_i8x16(v, i)?;
3197
3198 let left = err!(self.builder.build_shuffle_vector(
3199 v,
3200 v.get_type().get_undef(),
3201 VectorType::const_vector(&[
3202 self.intrinsics.i32_consts[0],
3203 self.intrinsics.i32_consts[2],
3204 self.intrinsics.i32_consts[4],
3205 self.intrinsics.i32_consts[6],
3206 self.intrinsics.i32_consts[8],
3207 self.intrinsics.i32_consts[10],
3208 self.intrinsics.i32_consts[12],
3209 self.intrinsics.i32_consts[14],
3210 ]),
3211 "",
3212 ));
3213 let left = err!(extend_op(self, left));
3214 let right = err!(self.builder.build_shuffle_vector(
3215 v,
3216 v.get_type().get_undef(),
3217 VectorType::const_vector(&[
3218 self.intrinsics.i32_consts[1],
3219 self.intrinsics.i32_consts[3],
3220 self.intrinsics.i32_consts[5],
3221 self.intrinsics.i32_consts[7],
3222 self.intrinsics.i32_consts[9],
3223 self.intrinsics.i32_consts[11],
3224 self.intrinsics.i32_consts[13],
3225 self.intrinsics.i32_consts[15],
3226 ]),
3227 "",
3228 ));
3229 let right = err!(extend_op(self, right));
3230
3231 let res = err!(self.builder.build_int_add(left, right, ""));
3232 let res = err!(
3233 self.builder
3234 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3235 );
3236 self.state.push1(res);
3237 }
3238 Operator::I32x4Add => {
3239 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3240 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3241 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3242 let res = err!(self.builder.build_int_add(v1, v2, ""));
3243 let res = err!(
3244 self.builder
3245 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3246 );
3247 self.state.push1(res);
3248 }
3249 Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
3250 let extend_op = match op {
3251 Operator::I32x4ExtAddPairwiseI16x8S => {
3252 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3253 }
3254 Operator::I32x4ExtAddPairwiseI16x8U => {
3255 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3256 }
3257 _ => unreachable!("Unhandled internal variant"),
3258 };
3259 let (v, i) = self.state.pop1_extra()?;
3260 let (v, _) = self.v128_into_i16x8(v, i)?;
3261
3262 let left = err!(self.builder.build_shuffle_vector(
3263 v,
3264 v.get_type().get_undef(),
3265 VectorType::const_vector(&[
3266 self.intrinsics.i32_consts[0],
3267 self.intrinsics.i32_consts[2],
3268 self.intrinsics.i32_consts[4],
3269 self.intrinsics.i32_consts[6],
3270 ]),
3271 "",
3272 ));
3273 let left = err!(extend_op(self, left));
3274 let right = err!(self.builder.build_shuffle_vector(
3275 v,
3276 v.get_type().get_undef(),
3277 VectorType::const_vector(&[
3278 self.intrinsics.i32_consts[1],
3279 self.intrinsics.i32_consts[3],
3280 self.intrinsics.i32_consts[5],
3281 self.intrinsics.i32_consts[7],
3282 ]),
3283 "",
3284 ));
3285 let right = err!(extend_op(self, right));
3286
3287 let res = err!(self.builder.build_int_add(left, right, ""));
3288 let res = err!(
3289 self.builder
3290 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3291 );
3292 self.state.push1(res);
3293 }
3294 Operator::I64x2Add => {
3295 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3296 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3297 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3298 let res = err!(self.builder.build_int_add(v1, v2, ""));
3299 let res = err!(
3300 self.builder
3301 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3302 );
3303 self.state.push1(res);
3304 }
3305 Operator::I8x16AddSatS => {
3306 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3307 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3308 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3309 let res = err!(self.builder.build_call(
3310 self.intrinsics.sadd_sat_i8x16,
3311 &[v1.into(), v2.into()],
3312 ""
3313 ))
3314 .try_as_basic_value()
3315 .left()
3316 .unwrap();
3317 let res = err!(
3318 self.builder
3319 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3320 );
3321 self.state.push1(res);
3322 }
3323 Operator::I16x8AddSatS => {
3324 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3325 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3326 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3327 let res = err!(self.builder.build_call(
3328 self.intrinsics.sadd_sat_i16x8,
3329 &[v1.into(), v2.into()],
3330 ""
3331 ))
3332 .try_as_basic_value()
3333 .left()
3334 .unwrap();
3335 let res = err!(
3336 self.builder
3337 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3338 );
3339 self.state.push1(res);
3340 }
3341 Operator::I8x16AddSatU => {
3342 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3343 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3344 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3345 let res = err!(self.builder.build_call(
3346 self.intrinsics.uadd_sat_i8x16,
3347 &[v1.into(), v2.into()],
3348 ""
3349 ))
3350 .try_as_basic_value()
3351 .left()
3352 .unwrap();
3353 let res = err!(
3354 self.builder
3355 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3356 );
3357 self.state.push1(res);
3358 }
3359 Operator::I16x8AddSatU => {
3360 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3361 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3362 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3363 let res = err!(self.builder.build_call(
3364 self.intrinsics.uadd_sat_i16x8,
3365 &[v1.into(), v2.into()],
3366 ""
3367 ))
3368 .try_as_basic_value()
3369 .left()
3370 .unwrap();
3371 let res = err!(
3372 self.builder
3373 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3374 );
3375 self.state.push1(res);
3376 }
3377 Operator::I32Sub | Operator::I64Sub => {
3378 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3379 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3380 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3381 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3382 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3383 self.state.push1(res);
3384 }
3385 Operator::I8x16Sub => {
3386 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3387 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3388 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3389 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3390 let res = err!(
3391 self.builder
3392 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3393 );
3394 self.state.push1(res);
3395 }
3396 Operator::I16x8Sub => {
3397 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3398 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3399 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3400 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3401 let res = err!(
3402 self.builder
3403 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3404 );
3405 self.state.push1(res);
3406 }
3407 Operator::I32x4Sub => {
3408 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3409 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3410 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3411 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3412 let res = err!(
3413 self.builder
3414 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3415 );
3416 self.state.push1(res);
3417 }
3418 Operator::I64x2Sub => {
3419 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3420 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3421 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3422 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3423 let res = err!(
3424 self.builder
3425 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3426 );
3427 self.state.push1(res);
3428 }
3429 Operator::I8x16SubSatS => {
3430 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3431 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3432 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3433 let res = err!(self.builder.build_call(
3434 self.intrinsics.ssub_sat_i8x16,
3435 &[v1.into(), v2.into()],
3436 ""
3437 ))
3438 .try_as_basic_value()
3439 .left()
3440 .unwrap();
3441 let res = err!(
3442 self.builder
3443 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3444 );
3445 self.state.push1(res);
3446 }
3447 Operator::I16x8SubSatS => {
3448 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3449 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3450 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3451 let res = err!(self.builder.build_call(
3452 self.intrinsics.ssub_sat_i16x8,
3453 &[v1.into(), v2.into()],
3454 ""
3455 ))
3456 .try_as_basic_value()
3457 .left()
3458 .unwrap();
3459 let res = err!(
3460 self.builder
3461 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3462 );
3463 self.state.push1(res);
3464 }
3465 Operator::I8x16SubSatU => {
3466 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3467 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3468 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3469 let res = err!(self.builder.build_call(
3470 self.intrinsics.usub_sat_i8x16,
3471 &[v1.into(), v2.into()],
3472 ""
3473 ))
3474 .try_as_basic_value()
3475 .left()
3476 .unwrap();
3477 let res = err!(
3478 self.builder
3479 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3480 );
3481 self.state.push1(res);
3482 }
3483 Operator::I16x8SubSatU => {
3484 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3485 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3486 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3487 let res = err!(self.builder.build_call(
3488 self.intrinsics.usub_sat_i16x8,
3489 &[v1.into(), v2.into()],
3490 ""
3491 ))
3492 .try_as_basic_value()
3493 .left()
3494 .unwrap();
3495 let res = err!(
3496 self.builder
3497 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3498 );
3499 self.state.push1(res);
3500 }
3501 Operator::I32Mul | Operator::I64Mul => {
3502 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3503 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3504 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3505 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3506 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3507 self.state.push1(res);
3508 }
3509 Operator::I16x8Mul => {
3510 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3511 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3512 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3513 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3514 let res = err!(
3515 self.builder
3516 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3517 );
3518 self.state.push1(res);
3519 }
3520 Operator::I32x4Mul => {
3521 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3522 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3523 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3524 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3525 let res = err!(
3526 self.builder
3527 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3528 );
3529 self.state.push1(res);
3530 }
3531 Operator::I64x2Mul => {
3532 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3533 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3534 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3535 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3536 let res = err!(
3537 self.builder
3538 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3539 );
3540 self.state.push1(res);
3541 }
3542 Operator::I16x8Q15MulrSatS => {
3543 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3544 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3545 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3546
3547 let max_value = self.intrinsics.i16_ty.const_int(i16::MAX as u64, false);
3548 let max_values = VectorType::const_vector(&[max_value; 8]);
3549
3550 let v1 = err!(
3551 self.builder
3552 .build_int_s_extend(v1, self.intrinsics.i32x8_ty, "")
3553 );
3554 let v2 = err!(
3555 self.builder
3556 .build_int_s_extend(v2, self.intrinsics.i32x8_ty, "")
3557 );
3558 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3559
3560 let bit = self.intrinsics.i32_ty.const_int(0x4000, false);
3562 let bits = VectorType::const_vector(&[bit; 8]);
3563
3564 let res = err!(self.builder.build_int_add(res, bits, ""));
3565
3566 let fifteen = self.intrinsics.i32_consts[15];
3567 let fifteens = VectorType::const_vector(&[fifteen; 8]);
3568
3569 let res = err!(self.builder.build_right_shift(res, fifteens, true, ""));
3570 let saturate_up = {
3571 let max_values = err!(self.builder.build_int_s_extend(
3572 max_values,
3573 self.intrinsics.i32x8_ty,
3574 ""
3575 ));
3576 err!(
3577 self.builder
3578 .build_int_compare(IntPredicate::SGT, res, max_values, "")
3579 )
3580 };
3581
3582 let res = err!(
3583 self.builder
3584 .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
3585 );
3586
3587 let res = err!(self.builder.build_select(saturate_up, max_values, res, ""))
3588 .into_vector_value();
3589 let res = err!(
3590 self.builder
3591 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3592 );
3593 self.state.push1(res);
3594 }
3595 Operator::I16x8ExtMulLowI8x16S
3596 | Operator::I16x8ExtMulLowI8x16U
3597 | Operator::I16x8ExtMulHighI8x16S
3598 | Operator::I16x8ExtMulHighI8x16U => {
3599 let extend_op = match op {
3600 Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulHighI8x16S => {
3601 |s: &Self, v| -> Result<VectorValue, CompileError> {
3602 err_nt!(s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, ""))
3603 }
3604 }
3605 Operator::I16x8ExtMulLowI8x16U | Operator::I16x8ExtMulHighI8x16U => {
3606 |s: &Self, v| -> Result<VectorValue, CompileError> {
3607 err_nt!(s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, ""))
3608 }
3609 }
3610 _ => unreachable!("Unhandled internal variant"),
3611 };
3612 let shuffle_array = match op {
3613 Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulLowI8x16U => [
3614 self.intrinsics.i32_consts[0],
3615 self.intrinsics.i32_consts[2],
3616 self.intrinsics.i32_consts[4],
3617 self.intrinsics.i32_consts[6],
3618 self.intrinsics.i32_consts[8],
3619 self.intrinsics.i32_consts[10],
3620 self.intrinsics.i32_consts[12],
3621 self.intrinsics.i32_consts[14],
3622 ],
3623 Operator::I16x8ExtMulHighI8x16S | Operator::I16x8ExtMulHighI8x16U => [
3624 self.intrinsics.i32_consts[1],
3625 self.intrinsics.i32_consts[3],
3626 self.intrinsics.i32_consts[5],
3627 self.intrinsics.i32_consts[7],
3628 self.intrinsics.i32_consts[9],
3629 self.intrinsics.i32_consts[11],
3630 self.intrinsics.i32_consts[13],
3631 self.intrinsics.i32_consts[15],
3632 ],
3633 _ => unreachable!("Unhandled internal variant"),
3634 };
3635 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3636 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3637 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3638 let val1 = err!(self.builder.build_shuffle_vector(
3639 v1,
3640 v1.get_type().get_undef(),
3641 VectorType::const_vector(&shuffle_array),
3642 "",
3643 ));
3644 let val1 = err!(extend_op(self, val1));
3645 let val2 = err!(self.builder.build_shuffle_vector(
3646 v2,
3647 v2.get_type().get_undef(),
3648 VectorType::const_vector(&shuffle_array),
3649 "",
3650 ));
3651 let val2 = err!(extend_op(self, val2));
3652 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3653 let res = err!(
3654 self.builder
3655 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3656 );
3657 self.state.push1(res);
3658 }
3659 Operator::I32x4ExtMulLowI16x8S
3660 | Operator::I32x4ExtMulLowI16x8U
3661 | Operator::I32x4ExtMulHighI16x8S
3662 | Operator::I32x4ExtMulHighI16x8U => {
3663 let extend_op = match op {
3664 Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulHighI16x8S => {
3665 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3666 }
3667 Operator::I32x4ExtMulLowI16x8U | Operator::I32x4ExtMulHighI16x8U => {
3668 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3669 }
3670 _ => unreachable!("Unhandled internal variant"),
3671 };
3672 let shuffle_array = match op {
3673 Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulLowI16x8U => [
3674 self.intrinsics.i32_consts[0],
3675 self.intrinsics.i32_consts[2],
3676 self.intrinsics.i32_consts[4],
3677 self.intrinsics.i32_consts[6],
3678 ],
3679 Operator::I32x4ExtMulHighI16x8S | Operator::I32x4ExtMulHighI16x8U => [
3680 self.intrinsics.i32_consts[1],
3681 self.intrinsics.i32_consts[3],
3682 self.intrinsics.i32_consts[5],
3683 self.intrinsics.i32_consts[7],
3684 ],
3685 _ => unreachable!("Unhandled internal variant"),
3686 };
3687 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3688 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3689 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3690 let val1 = err!(self.builder.build_shuffle_vector(
3691 v1,
3692 v1.get_type().get_undef(),
3693 VectorType::const_vector(&shuffle_array),
3694 "",
3695 ));
3696 let val1 = err!(extend_op(self, val1));
3697 let val2 = err!(self.builder.build_shuffle_vector(
3698 v2,
3699 v2.get_type().get_undef(),
3700 VectorType::const_vector(&shuffle_array),
3701 "",
3702 ));
3703 let val2 = err!(extend_op(self, val2));
3704 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3705 let res = err!(
3706 self.builder
3707 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3708 );
3709 self.state.push1(res);
3710 }
3711 Operator::I64x2ExtMulLowI32x4S
3712 | Operator::I64x2ExtMulLowI32x4U
3713 | Operator::I64x2ExtMulHighI32x4S
3714 | Operator::I64x2ExtMulHighI32x4U => {
3715 let extend_op = match op {
3716 Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulHighI32x4S => {
3717 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
3718 }
3719 Operator::I64x2ExtMulLowI32x4U | Operator::I64x2ExtMulHighI32x4U => {
3720 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
3721 }
3722 _ => unreachable!("Unhandled internal variant"),
3723 };
3724 let shuffle_array = match op {
3725 Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulLowI32x4U => {
3726 [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[2]]
3727 }
3728 Operator::I64x2ExtMulHighI32x4S | Operator::I64x2ExtMulHighI32x4U => {
3729 [self.intrinsics.i32_consts[1], self.intrinsics.i32_consts[3]]
3730 }
3731 _ => unreachable!("Unhandled internal variant"),
3732 };
3733 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3734 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3735 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3736 let val1 = err!(self.builder.build_shuffle_vector(
3737 v1,
3738 v1.get_type().get_undef(),
3739 VectorType::const_vector(&shuffle_array),
3740 "",
3741 ));
3742 let val1 = err!(extend_op(self, val1));
3743 let val2 = err!(self.builder.build_shuffle_vector(
3744 v2,
3745 v2.get_type().get_undef(),
3746 VectorType::const_vector(&shuffle_array),
3747 "",
3748 ));
3749 let val2 = err!(extend_op(self, val2));
3750 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3751 let res = err!(
3752 self.builder
3753 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3754 );
3755 self.state.push1(res);
3756 }
3757 Operator::I32x4DotI16x8S => {
3758 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3759 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3760 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3761 let low_i16 = [
3762 self.intrinsics.i32_consts[0],
3763 self.intrinsics.i32_consts[2],
3764 self.intrinsics.i32_consts[4],
3765 self.intrinsics.i32_consts[6],
3766 ];
3767 let high_i16 = [
3768 self.intrinsics.i32_consts[1],
3769 self.intrinsics.i32_consts[3],
3770 self.intrinsics.i32_consts[5],
3771 self.intrinsics.i32_consts[7],
3772 ];
3773 let v1_low = err!(self.builder.build_shuffle_vector(
3774 v1,
3775 v1.get_type().get_undef(),
3776 VectorType::const_vector(&low_i16),
3777 "",
3778 ));
3779 let v1_low = err!(self.builder.build_int_s_extend(
3780 v1_low,
3781 self.intrinsics.i32x4_ty,
3782 ""
3783 ));
3784 let v1_high = err!(self.builder.build_shuffle_vector(
3785 v1,
3786 v1.get_type().get_undef(),
3787 VectorType::const_vector(&high_i16),
3788 "",
3789 ));
3790 let v1_high = err!(self.builder.build_int_s_extend(
3791 v1_high,
3792 self.intrinsics.i32x4_ty,
3793 ""
3794 ));
3795 let v2_low = err!(self.builder.build_shuffle_vector(
3796 v2,
3797 v2.get_type().get_undef(),
3798 VectorType::const_vector(&low_i16),
3799 "",
3800 ));
3801 let v2_low = err!(self.builder.build_int_s_extend(
3802 v2_low,
3803 self.intrinsics.i32x4_ty,
3804 ""
3805 ));
3806 let v2_high = err!(self.builder.build_shuffle_vector(
3807 v2,
3808 v2.get_type().get_undef(),
3809 VectorType::const_vector(&high_i16),
3810 "",
3811 ));
3812 let v2_high = err!(self.builder.build_int_s_extend(
3813 v2_high,
3814 self.intrinsics.i32x4_ty,
3815 ""
3816 ));
3817 let low_product = err!(self.builder.build_int_mul(v1_low, v2_low, ""));
3818 let high_product = err!(self.builder.build_int_mul(v1_high, v2_high, ""));
3819
3820 let res = err!(self.builder.build_int_add(low_product, high_product, ""));
3821 let res = err!(
3822 self.builder
3823 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3824 );
3825 self.state.push1(res);
3826 }
3827 Operator::I32DivS | Operator::I64DivS => {
3828 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3829 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3830 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3831 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3832
3833 self.trap_if_zero_or_overflow(v1, v2)?;
3834
3835 let res = err!(self.builder.build_int_signed_div(v1, v2, ""));
3836 self.state.push1(res);
3837 }
3838 Operator::I32DivU | Operator::I64DivU => {
3839 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3840 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3841 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3842 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3843
3844 self.trap_if_zero(v2)?;
3845
3846 let res = err!(self.builder.build_int_unsigned_div(v1, v2, ""));
3847 self.state.push1(res);
3848 }
3849 Operator::I32RemS | Operator::I64RemS => {
3850 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3851 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3852 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3853 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3854 let int_type = v1.get_type();
3855 let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
3856 let min_value = int_type.const_int(i32::MIN as u64, false);
3857 let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
3858 (min_value, neg_one_value)
3859 } else if int_type == self.intrinsics.i64_ty {
3860 let min_value = int_type.const_int(i64::MIN as u64, false);
3861 let neg_one_value = int_type.const_int(-1i64 as u64, false);
3862 (min_value, neg_one_value)
3863 } else {
3864 unreachable!()
3865 };
3866
3867 self.trap_if_zero(v2)?;
3868
3869 let will_overflow = err!(self.builder.build_and(
3881 err!(self.builder.build_int_compare(
3882 IntPredicate::EQ,
3883 v1,
3884 min_value,
3885 "left_is_min"
3886 )),
3887 err!(self.builder.build_int_compare(
3888 IntPredicate::EQ,
3889 v2,
3890 neg_one_value,
3891 "right_is_neg_one",
3892 )),
3893 "srem_will_overflow",
3894 ));
3895 let v1 =
3896 err!(
3897 self.builder
3898 .build_select(will_overflow, int_type.const_zero(), v1, "")
3899 )
3900 .into_int_value();
3901 let res = err!(self.builder.build_int_signed_rem(v1, v2, ""));
3902 self.state.push1(res);
3903 }
3904 Operator::I32RemU | Operator::I64RemU => {
3905 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3906 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3907 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3908 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3909
3910 self.trap_if_zero(v2)?;
3911
3912 let res = err!(self.builder.build_int_unsigned_rem(v1, v2, ""));
3913 self.state.push1(res);
3914 }
3915 Operator::I32And | Operator::I64And | Operator::V128And => {
3916 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3917 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3918 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3919 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3920 let res = err!(self.builder.build_and(v1, v2, ""));
3921 self.state.push1(res);
3922 }
3923 Operator::I32Or | Operator::I64Or | Operator::V128Or => {
3924 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3925 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3926 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3927 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3928 let res = err!(self.builder.build_or(v1, v2, ""));
3929 self.state.push1(res);
3930 }
3931 Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
3932 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3933 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3934 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3935 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3936 let res = err!(self.builder.build_xor(v1, v2, ""));
3937 self.state.push1(res);
3938 }
3939 Operator::V128AndNot => {
3940 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3941 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3942 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3943 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3944 let v2 = err!(self.builder.build_not(v2, ""));
3945 let res = err!(self.builder.build_and(v1, v2, ""));
3946 self.state.push1(res);
3947 }
3948 Operator::V128Bitselect => {
3949 let ((v1, i1), (v2, i2), (cond, cond_info)) = self.state.pop3_extra()?;
3950 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3951 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3952 let cond = self.apply_pending_canonicalization(cond, cond_info)?;
3953 let v1 = err!(
3954 self.builder
3955 .build_bit_cast(v1, self.intrinsics.i1x128_ty, "")
3956 )
3957 .into_vector_value();
3958 let v2 = err!(
3959 self.builder
3960 .build_bit_cast(v2, self.intrinsics.i1x128_ty, "")
3961 )
3962 .into_vector_value();
3963 let cond = err!(
3964 self.builder
3965 .build_bit_cast(cond, self.intrinsics.i1x128_ty, "")
3966 )
3967 .into_vector_value();
3968 let res = err!(self.builder.build_select(cond, v1, v2, ""));
3969 let res = err!(
3970 self.builder
3971 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3972 );
3973 self.state.push1(res);
3974 }
3975 Operator::I8x16Bitmask => {
3976 let (v, i) = self.state.pop1_extra()?;
3977 let (v, _) = self.v128_into_i8x16(v, i)?;
3978
3979 let zeros = self.intrinsics.i8x16_ty.const_zero();
3980 let res = err!(
3981 self.builder
3982 .build_int_compare(IntPredicate::SLT, v, zeros, "")
3983 );
3984 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i16_ty, ""))
3985 .into_int_value();
3986 let res = err!(
3987 self.builder
3988 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
3989 );
3990 self.state.push1(res);
3991 }
3992 Operator::I16x8Bitmask => {
3993 let (v, i) = self.state.pop1_extra()?;
3994 let (v, _) = self.v128_into_i16x8(v, i)?;
3995
3996 let zeros = self.intrinsics.i16x8_ty.const_zero();
3997 let res = err!(
3998 self.builder
3999 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4000 );
4001 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i8_ty, ""))
4002 .into_int_value();
4003 let res = err!(
4004 self.builder
4005 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4006 );
4007 self.state.push1(res);
4008 }
4009 Operator::I32x4Bitmask => {
4010 let (v, i) = self.state.pop1_extra()?;
4011 let (v, _) = self.v128_into_i32x4(v, i)?;
4012
4013 let zeros = self.intrinsics.i32x4_ty.const_zero();
4014 let res = err!(
4015 self.builder
4016 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4017 );
4018 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i4_ty, ""))
4019 .into_int_value();
4020 let res = err!(
4021 self.builder
4022 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4023 );
4024 self.state.push1(res);
4025 }
4026 Operator::I64x2Bitmask => {
4027 let (v, i) = self.state.pop1_extra()?;
4028 let (v, _) = self.v128_into_i64x2(v, i)?;
4029
4030 let zeros = self.intrinsics.i64x2_ty.const_zero();
4031 let res = err!(
4032 self.builder
4033 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4034 );
4035 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i2_ty, ""))
4036 .into_int_value();
4037 let res = err!(
4038 self.builder
4039 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4040 );
4041 self.state.push1(res);
4042 }
4043 Operator::I32Shl => {
4044 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4045 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4046 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4047 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4048 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4049 let v2 = err!(self.builder.build_and(v2, mask, ""));
4050 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4051 self.state.push1(res);
4052 }
4053 Operator::I64Shl => {
4054 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4055 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4056 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4057 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4058 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4059 let v2 = err!(self.builder.build_and(v2, mask, ""));
4060 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4061 self.state.push1(res);
4062 }
4063 Operator::I8x16Shl => {
4064 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4065 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4066 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4067 let v2 = v2.into_int_value();
4068 let v2 = err!(
4069 self.builder
4070 .build_and(v2, self.intrinsics.i32_consts[7], "")
4071 );
4072 let v2 = err!(
4073 self.builder
4074 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4075 );
4076 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4077 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4078 let res = err!(
4079 self.builder
4080 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4081 );
4082 self.state.push1(res);
4083 }
4084 Operator::I16x8Shl => {
4085 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4086 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4087 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4088 let v2 = v2.into_int_value();
4089 let v2 = err!(
4090 self.builder
4091 .build_and(v2, self.intrinsics.i32_consts[15], "")
4092 );
4093 let v2 = err!(
4094 self.builder
4095 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4096 );
4097 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4098 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4099 let res = err!(
4100 self.builder
4101 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4102 );
4103 self.state.push1(res);
4104 }
4105 Operator::I32x4Shl => {
4106 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4107 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4108 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4109 let v2 = v2.into_int_value();
4110 let v2 = err!(self.builder.build_and(
4111 v2,
4112 self.intrinsics.i32_ty.const_int(31, false),
4113 ""
4114 ));
4115 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4116 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4117 let res = err!(
4118 self.builder
4119 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4120 );
4121 self.state.push1(res);
4122 }
4123 Operator::I64x2Shl => {
4124 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4125 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4126 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4127 let v2 = v2.into_int_value();
4128 let v2 = err!(self.builder.build_and(
4129 v2,
4130 self.intrinsics.i32_ty.const_int(63, false),
4131 ""
4132 ));
4133 let v2 = err!(
4134 self.builder
4135 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4136 );
4137 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4138 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4139 let res = err!(
4140 self.builder
4141 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4142 );
4143 self.state.push1(res);
4144 }
4145 Operator::I32ShrS => {
4146 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4147 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4148 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4149 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4150 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4151 let v2 = err!(self.builder.build_and(v2, mask, ""));
4152 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4153 self.state.push1(res);
4154 }
4155 Operator::I64ShrS => {
4156 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4157 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4158 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4159 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4160 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4161 let v2 = err!(self.builder.build_and(v2, mask, ""));
4162 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4163 self.state.push1(res);
4164 }
4165 Operator::I8x16ShrS => {
4166 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4167 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4168 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4169 let v2 = v2.into_int_value();
4170 let v2 = err!(
4171 self.builder
4172 .build_and(v2, self.intrinsics.i32_consts[7], "")
4173 );
4174 let v2 = err!(
4175 self.builder
4176 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4177 );
4178 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4179 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4180 let res = err!(
4181 self.builder
4182 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4183 );
4184 self.state.push1(res);
4185 }
4186 Operator::I16x8ShrS => {
4187 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4188 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4189 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4190 let v2 = v2.into_int_value();
4191 let v2 = err!(
4192 self.builder
4193 .build_and(v2, self.intrinsics.i32_consts[15], "")
4194 );
4195 let v2 = err!(
4196 self.builder
4197 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4198 );
4199 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4200 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4201 let res = err!(
4202 self.builder
4203 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4204 );
4205 self.state.push1(res);
4206 }
4207 Operator::I32x4ShrS => {
4208 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4209 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4210 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4211 let v2 = v2.into_int_value();
4212 let v2 = err!(self.builder.build_and(
4213 v2,
4214 self.intrinsics.i32_ty.const_int(31, false),
4215 ""
4216 ));
4217 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4218 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4219 let res = err!(
4220 self.builder
4221 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4222 );
4223 self.state.push1(res);
4224 }
4225 Operator::I64x2ShrS => {
4226 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4227 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4228 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4229 let v2 = v2.into_int_value();
4230 let v2 = err!(self.builder.build_and(
4231 v2,
4232 self.intrinsics.i32_ty.const_int(63, false),
4233 ""
4234 ));
4235 let v2 = err!(
4236 self.builder
4237 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4238 );
4239 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4240 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4241 let res = err!(
4242 self.builder
4243 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4244 );
4245 self.state.push1(res);
4246 }
4247 Operator::I32ShrU => {
4248 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4249 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4250 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4251 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4252 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4253 let v2 = err!(self.builder.build_and(v2, mask, ""));
4254 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4255 self.state.push1(res);
4256 }
4257 Operator::I64ShrU => {
4258 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4259 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4260 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4261 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4262 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4263 let v2 = err!(self.builder.build_and(v2, mask, ""));
4264 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4265 self.state.push1(res);
4266 }
4267 Operator::I8x16ShrU => {
4268 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4269 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4270 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4271 let v2 = v2.into_int_value();
4272 let v2 = err!(
4273 self.builder
4274 .build_and(v2, self.intrinsics.i32_consts[7], "")
4275 );
4276 let v2 = err!(
4277 self.builder
4278 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4279 );
4280 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4281 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4282 let res = err!(
4283 self.builder
4284 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4285 );
4286 self.state.push1(res);
4287 }
4288 Operator::I16x8ShrU => {
4289 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4290 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4291 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4292 let v2 = v2.into_int_value();
4293 let v2 = err!(
4294 self.builder
4295 .build_and(v2, self.intrinsics.i32_consts[15], "")
4296 );
4297 let v2 = err!(
4298 self.builder
4299 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4300 );
4301 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4302 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4303 let res = err!(
4304 self.builder
4305 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4306 );
4307 self.state.push1(res);
4308 }
4309 Operator::I32x4ShrU => {
4310 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4311 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4312 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4313 let v2 = v2.into_int_value();
4314 let v2 = err!(self.builder.build_and(
4315 v2,
4316 self.intrinsics.i32_ty.const_int(31, false),
4317 ""
4318 ));
4319 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4320 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4321 let res = err!(
4322 self.builder
4323 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4324 );
4325 self.state.push1(res);
4326 }
4327 Operator::I64x2ShrU => {
4328 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4329 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4330 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4331 let v2 = v2.into_int_value();
4332 let v2 = err!(self.builder.build_and(
4333 v2,
4334 self.intrinsics.i32_ty.const_int(63, false),
4335 ""
4336 ));
4337 let v2 = err!(
4338 self.builder
4339 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4340 );
4341 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4342 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4343 let res = err!(
4344 self.builder
4345 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4346 );
4347 self.state.push1(res);
4348 }
4349 Operator::I32Rotl => {
4350 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4351 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4352 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4353 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4354 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4355 let v2 = err!(self.builder.build_and(v2, mask, ""));
4356 let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4357 let rhs = {
4358 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4359 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4360 err!(self.builder.build_right_shift(v1, rhs, false, ""))
4361 };
4362 let res = err!(self.builder.build_or(lhs, rhs, ""));
4363 self.state.push1(res);
4364 }
4365 Operator::I64Rotl => {
4366 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4367 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4368 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4369 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4370 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4371 let v2 = err!(self.builder.build_and(v2, mask, ""));
4372 let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4373 let rhs = {
4374 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4375 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4376 err!(self.builder.build_right_shift(v1, rhs, false, ""))
4377 };
4378 let res = err!(self.builder.build_or(lhs, rhs, ""));
4379 self.state.push1(res);
4380 }
4381 Operator::I32Rotr => {
4382 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4383 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4384 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4385 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4386 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4387 let v2 = err!(self.builder.build_and(v2, mask, ""));
4388 let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4389 let rhs = {
4390 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4391 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4392 err!(self.builder.build_left_shift(v1, rhs, ""))
4393 };
4394 let res = err!(self.builder.build_or(lhs, rhs, ""));
4395 self.state.push1(res);
4396 }
4397 Operator::I64Rotr => {
4398 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4399 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4400 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4401 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4402 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4403 let v2 = err!(self.builder.build_and(v2, mask, ""));
4404 let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4405 let rhs = {
4406 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4407 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4408 err!(self.builder.build_left_shift(v1, rhs, ""))
4409 };
4410 let res = err!(self.builder.build_or(lhs, rhs, ""));
4411 self.state.push1(res);
4412 }
4413 Operator::I32Clz => {
4414 let (input, info) = self.state.pop1_extra()?;
4415 let input = self.apply_pending_canonicalization(input, info)?;
4416 let is_zero_undef = self.intrinsics.i1_zero;
4417 let res = err!(self.builder.build_call(
4418 self.intrinsics.ctlz_i32,
4419 &[input.into(), is_zero_undef.into()],
4420 "",
4421 ))
4422 .try_as_basic_value()
4423 .left()
4424 .unwrap();
4425 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4426 }
4427 Operator::I64Clz => {
4428 let (input, info) = self.state.pop1_extra()?;
4429 let input = self.apply_pending_canonicalization(input, info)?;
4430 let is_zero_undef = self.intrinsics.i1_zero;
4431 let res = err!(self.builder.build_call(
4432 self.intrinsics.ctlz_i64,
4433 &[input.into(), is_zero_undef.into()],
4434 "",
4435 ))
4436 .try_as_basic_value()
4437 .left()
4438 .unwrap();
4439 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4440 }
4441 Operator::I32Ctz => {
4442 let (input, info) = self.state.pop1_extra()?;
4443 let input = self.apply_pending_canonicalization(input, info)?;
4444 let is_zero_undef = self.intrinsics.i1_zero;
4445 let res = err!(self.builder.build_call(
4446 self.intrinsics.cttz_i32,
4447 &[input.into(), is_zero_undef.into()],
4448 "",
4449 ))
4450 .try_as_basic_value()
4451 .left()
4452 .unwrap();
4453 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4454 }
4455 Operator::I64Ctz => {
4456 let (input, info) = self.state.pop1_extra()?;
4457 let input = self.apply_pending_canonicalization(input, info)?;
4458 let is_zero_undef = self.intrinsics.i1_zero;
4459 let res = err!(self.builder.build_call(
4460 self.intrinsics.cttz_i64,
4461 &[input.into(), is_zero_undef.into()],
4462 "",
4463 ))
4464 .try_as_basic_value()
4465 .left()
4466 .unwrap();
4467 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4468 }
4469 Operator::I8x16Popcnt => {
4470 let (v, i) = self.state.pop1_extra()?;
4471 let (v, _) = self.v128_into_i8x16(v, i)?;
4472 let res = err!(self.builder.build_call(
4473 self.intrinsics.ctpop_i8x16,
4474 &[v.into()],
4475 ""
4476 ))
4477 .try_as_basic_value()
4478 .left()
4479 .unwrap();
4480 let res = err!(
4481 self.builder
4482 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4483 );
4484 self.state.push1(res);
4485 }
4486 Operator::I32Popcnt => {
4487 let (input, info) = self.state.pop1_extra()?;
4488 let input = self.apply_pending_canonicalization(input, info)?;
4489 let res = err!(self.builder.build_call(
4490 self.intrinsics.ctpop_i32,
4491 &[input.into()],
4492 ""
4493 ))
4494 .try_as_basic_value()
4495 .left()
4496 .unwrap();
4497 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4498 }
4499 Operator::I64Popcnt => {
4500 let (input, info) = self.state.pop1_extra()?;
4501 let input = self.apply_pending_canonicalization(input, info)?;
4502 let res = err!(self.builder.build_call(
4503 self.intrinsics.ctpop_i64,
4504 &[input.into()],
4505 ""
4506 ))
4507 .try_as_basic_value()
4508 .left()
4509 .unwrap();
4510 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4511 }
4512 Operator::I32Eqz => {
4513 let input = self.state.pop1()?.into_int_value();
4514 let cond = err!(self.builder.build_int_compare(
4515 IntPredicate::EQ,
4516 input,
4517 self.intrinsics.i32_zero,
4518 "",
4519 ));
4520 let res = err!(
4521 self.builder
4522 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4523 );
4524 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4525 }
4526 Operator::I64Eqz => {
4527 let input = self.state.pop1()?.into_int_value();
4528 let cond = err!(self.builder.build_int_compare(
4529 IntPredicate::EQ,
4530 input,
4531 self.intrinsics.i64_zero,
4532 "",
4533 ));
4534 let res = err!(
4535 self.builder
4536 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4537 );
4538 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4539 }
4540 Operator::I8x16Abs => {
4541 let (v, i) = self.state.pop1_extra()?;
4542 let (v, _) = self.v128_into_i8x16(v, i)?;
4543
4544 let seven = self.intrinsics.i8_ty.const_int(7, false);
4545 let seven = VectorType::const_vector(&[seven; 16]);
4546 let all_sign_bits = err!(self.builder.build_right_shift(v, seven, true, ""));
4547 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4548 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4549 let res = err!(
4550 self.builder
4551 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4552 );
4553 self.state.push1(res);
4554 }
4555 Operator::I16x8Abs => {
4556 let (v, i) = self.state.pop1_extra()?;
4557 let (v, _) = self.v128_into_i16x8(v, i)?;
4558
4559 let fifteen = self.intrinsics.i16_ty.const_int(15, false);
4560 let fifteen = VectorType::const_vector(&[fifteen; 8]);
4561 let all_sign_bits = err!(self.builder.build_right_shift(v, fifteen, true, ""));
4562 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4563 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4564 let res = err!(
4565 self.builder
4566 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4567 );
4568 self.state.push1(res);
4569 }
4570 Operator::I32x4Abs => {
4571 let (v, i) = self.state.pop1_extra()?;
4572 let (v, _) = self.v128_into_i32x4(v, i)?;
4573
4574 let thirtyone = self.intrinsics.i32_ty.const_int(31, false);
4575 let thirtyone = VectorType::const_vector(&[thirtyone; 4]);
4576 let all_sign_bits = err!(self.builder.build_right_shift(v, thirtyone, true, ""));
4577 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4578 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4579 let res = err!(
4580 self.builder
4581 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4582 );
4583 self.state.push1(res);
4584 }
4585 Operator::I64x2Abs => {
4586 let (v, i) = self.state.pop1_extra()?;
4587 let (v, _) = self.v128_into_i64x2(v, i)?;
4588
4589 let sixtythree = self.intrinsics.i64_ty.const_int(63, false);
4590 let sixtythree = VectorType::const_vector(&[sixtythree; 2]);
4591 let all_sign_bits = err!(self.builder.build_right_shift(v, sixtythree, true, ""));
4592 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4593 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4594 let res = err!(
4595 self.builder
4596 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4597 );
4598 self.state.push1(res);
4599 }
4600 Operator::I8x16MinS => {
4601 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4602 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4603 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4604 let cmp = err!(
4605 self.builder
4606 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4607 );
4608 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4609 let res = err!(
4610 self.builder
4611 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4612 );
4613 self.state.push1(res);
4614 }
4615 Operator::I8x16MinU => {
4616 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4617 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4618 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4619 let cmp = err!(
4620 self.builder
4621 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4622 );
4623 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4624 let res = err!(
4625 self.builder
4626 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4627 );
4628 self.state.push1(res);
4629 }
4630 Operator::I8x16MaxS => {
4631 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4632 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4633 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4634 let cmp = err!(
4635 self.builder
4636 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4637 );
4638 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4639 let res = err!(
4640 self.builder
4641 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4642 );
4643 self.state.push1(res);
4644 }
4645 Operator::I8x16MaxU => {
4646 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4647 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4648 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4649 let cmp = err!(
4650 self.builder
4651 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4652 );
4653 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4654 let res = err!(
4655 self.builder
4656 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4657 );
4658 self.state.push1(res);
4659 }
4660 Operator::I16x8MinS => {
4661 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4662 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4663 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4664 let cmp = err!(
4665 self.builder
4666 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4667 );
4668 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4669 let res = err!(
4670 self.builder
4671 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4672 );
4673 self.state.push1(res);
4674 }
4675 Operator::I16x8MinU => {
4676 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4677 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4678 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4679 let cmp = err!(
4680 self.builder
4681 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4682 );
4683 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4684 let res = err!(
4685 self.builder
4686 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4687 );
4688 self.state.push1(res);
4689 }
4690 Operator::I16x8MaxS => {
4691 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4692 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4693 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4694 let cmp = err!(
4695 self.builder
4696 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4697 );
4698 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4699 let res = err!(
4700 self.builder
4701 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4702 );
4703 self.state.push1(res);
4704 }
4705 Operator::I16x8MaxU => {
4706 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4707 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4708 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4709 let cmp = err!(
4710 self.builder
4711 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4712 );
4713 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4714 let res = err!(
4715 self.builder
4716 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4717 );
4718 self.state.push1(res);
4719 }
4720 Operator::I32x4MinS => {
4721 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4722 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4723 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4724 let cmp = err!(
4725 self.builder
4726 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4727 );
4728 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4729 let res = err!(
4730 self.builder
4731 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4732 );
4733 self.state.push1(res);
4734 }
4735 Operator::I32x4MinU => {
4736 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4737 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4738 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4739 let cmp = err!(
4740 self.builder
4741 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4742 );
4743 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4744 let res = err!(
4745 self.builder
4746 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4747 );
4748 self.state.push1(res);
4749 }
4750 Operator::I32x4MaxS => {
4751 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4752 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4753 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4754 let cmp = err!(
4755 self.builder
4756 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4757 );
4758 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4759 let res = err!(
4760 self.builder
4761 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4762 );
4763 self.state.push1(res);
4764 }
4765 Operator::I32x4MaxU => {
4766 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4767 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4768 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4769 let cmp = err!(
4770 self.builder
4771 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4772 );
4773 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4774 let res = err!(
4775 self.builder
4776 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4777 );
4778 self.state.push1(res);
4779 }
4780 Operator::I8x16AvgrU => {
4781 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4782 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4783 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4784
4785 let ext_ty = self.intrinsics.i16_ty.vec_type(16);
4796 let one = self.intrinsics.i16_ty.const_int(1, false);
4797 let one = VectorType::const_vector(&[one; 16]);
4798
4799 let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4800 let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4801 let res = err!(self.builder.build_int_add(
4802 err!(self.builder.build_int_add(one, v1, "")),
4803 v2,
4804 ""
4805 ));
4806 let res = err!(self.builder.build_right_shift(res, one, false, ""));
4807 let res = err!(
4808 self.builder
4809 .build_int_truncate(res, self.intrinsics.i8x16_ty, "")
4810 );
4811 let res = err!(
4812 self.builder
4813 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4814 );
4815 self.state.push1(res);
4816 }
4817 Operator::I16x8AvgrU => {
4818 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4819 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4820 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4821
4822 let ext_ty = self.intrinsics.i32_ty.vec_type(8);
4833 let one = self.intrinsics.i32_consts[1];
4834 let one = VectorType::const_vector(&[one; 8]);
4835
4836 let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4837 let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4838 let res = err!(self.builder.build_int_add(
4839 err!(self.builder.build_int_add(one, v1, "")),
4840 v2,
4841 ""
4842 ));
4843 let res = err!(self.builder.build_right_shift(res, one, false, ""));
4844 let res = err!(
4845 self.builder
4846 .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
4847 );
4848 let res = err!(
4849 self.builder
4850 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4851 );
4852 self.state.push1(res);
4853 }
4854
4855 Operator::F32Add => {
4860 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4861 let res = err!(self.builder.build_call(
4862 self.intrinsics.add_f32,
4863 &[
4864 v1.into(),
4865 v2.into(),
4866 self.intrinsics.fp_rounding_md,
4867 self.intrinsics.fp_exception_md,
4868 ],
4869 "",
4870 ))
4871 .try_as_basic_value()
4872 .left()
4873 .unwrap();
4874 self.state.push1_extra(
4875 res,
4876 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4877 );
4878 }
4879 Operator::F64Add => {
4880 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4881 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4882 let res = err!(self.builder.build_call(
4883 self.intrinsics.add_f64,
4884 &[
4885 v1.into(),
4886 v2.into(),
4887 self.intrinsics.fp_rounding_md,
4888 self.intrinsics.fp_exception_md,
4889 ],
4890 "",
4891 ))
4892 .try_as_basic_value()
4893 .left()
4894 .unwrap();
4895 self.state.push1_extra(
4896 res,
4897 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4898 );
4899 }
4900 Operator::F32x4Add => {
4901 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4902 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4903 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4904 let res = err!(self.builder.build_call(
4905 self.intrinsics.add_f32x4,
4906 &[
4907 v1.into(),
4908 v2.into(),
4909 self.intrinsics.fp_rounding_md,
4910 self.intrinsics.fp_exception_md,
4911 ],
4912 "",
4913 ))
4914 .try_as_basic_value()
4915 .left()
4916 .unwrap();
4917 let res = err!(
4918 self.builder
4919 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4920 );
4921 self.state.push1_extra(
4922 res,
4923 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4924 );
4925 }
4926 Operator::F64x2Add => {
4927 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4928 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
4929 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
4930 let res = err!(self.builder.build_call(
4931 self.intrinsics.add_f64x2,
4932 &[
4933 v1.into(),
4934 v2.into(),
4935 self.intrinsics.fp_rounding_md,
4936 self.intrinsics.fp_exception_md,
4937 ],
4938 "",
4939 ))
4940 .try_as_basic_value()
4941 .left()
4942 .unwrap();
4943 let res = err!(
4944 self.builder
4945 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4946 );
4947 self.state.push1_extra(
4948 res,
4949 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4950 );
4951 }
4952 Operator::F32Sub => {
4953 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4954 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4955 let res = err!(self.builder.build_call(
4956 self.intrinsics.sub_f32,
4957 &[
4958 v1.into(),
4959 v2.into(),
4960 self.intrinsics.fp_rounding_md,
4961 self.intrinsics.fp_exception_md,
4962 ],
4963 "",
4964 ))
4965 .try_as_basic_value()
4966 .left()
4967 .unwrap();
4968 self.state.push1_extra(
4969 res,
4970 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4971 );
4972 }
4973 Operator::F64Sub => {
4974 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4975 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4976 let res = err!(self.builder.build_call(
4977 self.intrinsics.sub_f64,
4978 &[
4979 v1.into(),
4980 v2.into(),
4981 self.intrinsics.fp_rounding_md,
4982 self.intrinsics.fp_exception_md,
4983 ],
4984 "",
4985 ))
4986 .try_as_basic_value()
4987 .left()
4988 .unwrap();
4989 self.state.push1_extra(
4990 res,
4991 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4992 );
4993 }
4994 Operator::F32x4Sub => {
4995 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4996 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4997 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4998 let res = err!(self.builder.build_call(
4999 self.intrinsics.sub_f32x4,
5000 &[
5001 v1.into(),
5002 v2.into(),
5003 self.intrinsics.fp_rounding_md,
5004 self.intrinsics.fp_exception_md,
5005 ],
5006 "",
5007 ))
5008 .try_as_basic_value()
5009 .left()
5010 .unwrap();
5011 let res = err!(
5012 self.builder
5013 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5014 );
5015 self.state.push1_extra(
5016 res,
5017 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5018 );
5019 }
5020 Operator::F64x2Sub => {
5021 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5022 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5023 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5024 let res = err!(self.builder.build_call(
5025 self.intrinsics.sub_f64x2,
5026 &[
5027 v1.into(),
5028 v2.into(),
5029 self.intrinsics.fp_rounding_md,
5030 self.intrinsics.fp_exception_md,
5031 ],
5032 "",
5033 ))
5034 .try_as_basic_value()
5035 .left()
5036 .unwrap();
5037 let res = err!(
5038 self.builder
5039 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5040 );
5041 self.state.push1_extra(
5042 res,
5043 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5044 );
5045 }
5046 Operator::F32Mul => {
5047 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5048 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5049 let res = err!(self.builder.build_call(
5050 self.intrinsics.mul_f32,
5051 &[
5052 v1.into(),
5053 v2.into(),
5054 self.intrinsics.fp_rounding_md,
5055 self.intrinsics.fp_exception_md,
5056 ],
5057 "",
5058 ))
5059 .try_as_basic_value()
5060 .left()
5061 .unwrap();
5062 self.state.push1_extra(
5063 res,
5064 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5065 );
5066 }
5067 Operator::F64Mul => {
5068 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5069 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5070 let res = err!(self.builder.build_call(
5071 self.intrinsics.mul_f64,
5072 &[
5073 v1.into(),
5074 v2.into(),
5075 self.intrinsics.fp_rounding_md,
5076 self.intrinsics.fp_exception_md,
5077 ],
5078 "",
5079 ))
5080 .try_as_basic_value()
5081 .left()
5082 .unwrap();
5083 self.state.push1_extra(
5084 res,
5085 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5086 );
5087 }
5088 Operator::F32x4Mul => {
5089 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5090 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5091 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5092 let res = err!(self.builder.build_call(
5093 self.intrinsics.mul_f32x4,
5094 &[
5095 v1.into(),
5096 v2.into(),
5097 self.intrinsics.fp_rounding_md,
5098 self.intrinsics.fp_exception_md,
5099 ],
5100 "",
5101 ))
5102 .try_as_basic_value()
5103 .left()
5104 .unwrap();
5105 let res = err!(
5106 self.builder
5107 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5108 );
5109 self.state.push1_extra(
5110 res,
5111 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5112 );
5113 }
5114 Operator::F64x2Mul => {
5115 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5116 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5117 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5118 let res = err!(self.builder.build_call(
5119 self.intrinsics.mul_f64x2,
5120 &[
5121 v1.into(),
5122 v2.into(),
5123 self.intrinsics.fp_rounding_md,
5124 self.intrinsics.fp_exception_md,
5125 ],
5126 "",
5127 ))
5128 .try_as_basic_value()
5129 .left()
5130 .unwrap();
5131 let res = err!(
5132 self.builder
5133 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5134 );
5135 self.state.push1_extra(
5136 res,
5137 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5138 );
5139 }
5140 Operator::F32Div => {
5141 let (v1, v2) = self.state.pop2()?;
5142 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5143 let res = err!(self.builder.build_call(
5144 self.intrinsics.div_f32,
5145 &[
5146 v1.into(),
5147 v2.into(),
5148 self.intrinsics.fp_rounding_md,
5149 self.intrinsics.fp_exception_md,
5150 ],
5151 "",
5152 ))
5153 .try_as_basic_value()
5154 .left()
5155 .unwrap();
5156 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5157 }
5158 Operator::F64Div => {
5159 let (v1, v2) = self.state.pop2()?;
5160 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5161 let res = err!(self.builder.build_call(
5162 self.intrinsics.div_f64,
5163 &[
5164 v1.into(),
5165 v2.into(),
5166 self.intrinsics.fp_rounding_md,
5167 self.intrinsics.fp_exception_md,
5168 ],
5169 "",
5170 ))
5171 .try_as_basic_value()
5172 .left()
5173 .unwrap();
5174 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5175 }
5176 Operator::F32x4Div => {
5177 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5178 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5179 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5180 let res = err!(self.builder.build_call(
5181 self.intrinsics.div_f32x4,
5182 &[
5183 v1.into(),
5184 v2.into(),
5185 self.intrinsics.fp_rounding_md,
5186 self.intrinsics.fp_exception_md,
5187 ],
5188 "",
5189 ))
5190 .try_as_basic_value()
5191 .left()
5192 .unwrap();
5193 let res = err!(
5194 self.builder
5195 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5196 );
5197 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5198 }
5199 Operator::F64x2Div => {
5200 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5201 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5202 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5203 let res = err!(self.builder.build_call(
5204 self.intrinsics.div_f64x2,
5205 &[
5206 v1.into(),
5207 v2.into(),
5208 self.intrinsics.fp_rounding_md,
5209 self.intrinsics.fp_exception_md,
5210 ],
5211 "",
5212 ))
5213 .try_as_basic_value()
5214 .left()
5215 .unwrap();
5216 let res = err!(
5217 self.builder
5218 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5219 );
5220 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5221 }
5222 Operator::F32Sqrt => {
5223 let input = self.state.pop1()?;
5224 let res = err!(self.builder.build_call(
5225 self.intrinsics.sqrt_f32,
5226 &[input.into()],
5227 ""
5228 ))
5229 .try_as_basic_value()
5230 .left()
5231 .unwrap();
5232 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5233 }
5234 Operator::F64Sqrt => {
5235 let input = self.state.pop1()?;
5236 let res = err!(self.builder.build_call(
5237 self.intrinsics.sqrt_f64,
5238 &[input.into()],
5239 ""
5240 ))
5241 .try_as_basic_value()
5242 .left()
5243 .unwrap();
5244 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5245 }
5246 Operator::F32x4Sqrt => {
5247 let (v, i) = self.state.pop1_extra()?;
5248 let (v, _) = self.v128_into_f32x4(v, i)?;
5249 let res = err!(self.builder.build_call(
5250 self.intrinsics.sqrt_f32x4,
5251 &[v.into()],
5252 ""
5253 ))
5254 .try_as_basic_value()
5255 .left()
5256 .unwrap();
5257 let bits = err!(
5258 self.builder
5259 .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5260 );
5261 self.state.push1_extra(bits, ExtraInfo::pending_f32_nan());
5262 }
5263 Operator::F64x2Sqrt => {
5264 let (v, i) = self.state.pop1_extra()?;
5265 let (v, _) = self.v128_into_f64x2(v, i)?;
5266 let res = err!(self.builder.build_call(
5267 self.intrinsics.sqrt_f64x2,
5268 &[v.into()],
5269 ""
5270 ))
5271 .try_as_basic_value()
5272 .left()
5273 .unwrap();
5274 let bits = err!(
5275 self.builder
5276 .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5277 );
5278 self.state.push1(bits);
5279 }
5280 Operator::F32Min => {
5281 let (v1, v2) = self.state.pop2()?;
5285 let v1 = self.canonicalize_nans(v1)?;
5286 let v2 = self.canonicalize_nans(v2)?;
5287
5288 let v1_is_nan = err!(self.builder.build_call(
5289 self.intrinsics.cmp_f32,
5290 &[
5291 v1.into(),
5292 self.intrinsics.f32_zero.into(),
5293 self.intrinsics.fp_uno_md,
5294 self.intrinsics.fp_exception_md,
5295 ],
5296 "",
5297 ))
5298 .try_as_basic_value()
5299 .left()
5300 .unwrap()
5301 .into_int_value();
5302 let v2_is_nan = err!(self.builder.build_call(
5303 self.intrinsics.cmp_f32,
5304 &[
5305 v2.into(),
5306 self.intrinsics.f32_zero.into(),
5307 self.intrinsics.fp_uno_md,
5308 self.intrinsics.fp_exception_md,
5309 ],
5310 "",
5311 ))
5312 .try_as_basic_value()
5313 .left()
5314 .unwrap()
5315 .into_int_value();
5316 let v1_lt_v2 = err!(self.builder.build_call(
5317 self.intrinsics.cmp_f32,
5318 &[
5319 v1.into(),
5320 v2.into(),
5321 self.intrinsics.fp_olt_md,
5322 self.intrinsics.fp_exception_md,
5323 ],
5324 "",
5325 ))
5326 .try_as_basic_value()
5327 .left()
5328 .unwrap()
5329 .into_int_value();
5330 let v1_gt_v2 = err!(self.builder.build_call(
5331 self.intrinsics.cmp_f32,
5332 &[
5333 v1.into(),
5334 v2.into(),
5335 self.intrinsics.fp_ogt_md,
5336 self.intrinsics.fp_exception_md,
5337 ],
5338 "",
5339 ))
5340 .try_as_basic_value()
5341 .left()
5342 .unwrap()
5343 .into_int_value();
5344
5345 let res = err!(self.builder.build_select(
5346 v1_is_nan,
5347 self.quiet_nan(v1)?,
5348 err!(self.builder.build_select(
5349 v2_is_nan,
5350 self.quiet_nan(v2)?,
5351 err!(self.builder.build_select(
5352 v1_lt_v2,
5353 v1,
5354 err!(self.builder.build_select(
5355 v1_gt_v2,
5356 v2,
5357 err!(self.builder.build_bit_cast(
5358 err!(self.builder.build_or(
5359 err!(self.builder.build_bit_cast(
5360 v1,
5361 self.intrinsics.i32_ty,
5362 ""
5363 ))
5364 .into_int_value(),
5365 err!(self.builder.build_bit_cast(
5366 v2,
5367 self.intrinsics.i32_ty,
5368 ""
5369 ))
5370 .into_int_value(),
5371 "",
5372 )),
5373 self.intrinsics.f32_ty,
5374 "",
5375 )),
5376 "",
5377 )),
5378 "",
5379 )),
5380 "",
5381 )),
5382 "",
5383 ));
5384
5385 self.state.push1(res);
5386 }
5387 Operator::F64Min => {
5388 let (v1, v2) = self.state.pop2()?;
5392 let v1 = self.canonicalize_nans(v1)?;
5393 let v2 = self.canonicalize_nans(v2)?;
5394
5395 let v1_is_nan = err!(self.builder.build_call(
5396 self.intrinsics.cmp_f64,
5397 &[
5398 v1.into(),
5399 self.intrinsics.f64_zero.into(),
5400 self.intrinsics.fp_uno_md,
5401 self.intrinsics.fp_exception_md,
5402 ],
5403 "",
5404 ))
5405 .try_as_basic_value()
5406 .left()
5407 .unwrap()
5408 .into_int_value();
5409 let v2_is_nan = err!(self.builder.build_call(
5410 self.intrinsics.cmp_f64,
5411 &[
5412 v2.into(),
5413 self.intrinsics.f64_zero.into(),
5414 self.intrinsics.fp_uno_md,
5415 self.intrinsics.fp_exception_md,
5416 ],
5417 "",
5418 ))
5419 .try_as_basic_value()
5420 .left()
5421 .unwrap()
5422 .into_int_value();
5423 let v1_lt_v2 = err!(self.builder.build_call(
5424 self.intrinsics.cmp_f64,
5425 &[
5426 v1.into(),
5427 v2.into(),
5428 self.intrinsics.fp_olt_md,
5429 self.intrinsics.fp_exception_md,
5430 ],
5431 "",
5432 ))
5433 .try_as_basic_value()
5434 .left()
5435 .unwrap()
5436 .into_int_value();
5437 let v1_gt_v2 = err!(self.builder.build_call(
5438 self.intrinsics.cmp_f64,
5439 &[
5440 v1.into(),
5441 v2.into(),
5442 self.intrinsics.fp_ogt_md,
5443 self.intrinsics.fp_exception_md,
5444 ],
5445 "",
5446 ))
5447 .try_as_basic_value()
5448 .left()
5449 .unwrap()
5450 .into_int_value();
5451
5452 let res = err!(self.builder.build_select(
5453 v1_is_nan,
5454 self.quiet_nan(v1)?,
5455 err!(self.builder.build_select(
5456 v2_is_nan,
5457 self.quiet_nan(v2)?,
5458 err!(self.builder.build_select(
5459 v1_lt_v2,
5460 v1,
5461 err!(self.builder.build_select(
5462 v1_gt_v2,
5463 v2,
5464 err!(self.builder.build_bit_cast(
5465 err!(self.builder.build_or(
5466 err!(self.builder.build_bit_cast(
5467 v1,
5468 self.intrinsics.i64_ty,
5469 ""
5470 ))
5471 .into_int_value(),
5472 err!(self.builder.build_bit_cast(
5473 v2,
5474 self.intrinsics.i64_ty,
5475 ""
5476 ))
5477 .into_int_value(),
5478 "",
5479 )),
5480 self.intrinsics.f64_ty,
5481 "",
5482 )),
5483 "",
5484 )),
5485 "",
5486 )),
5487 "",
5488 )),
5489 "",
5490 ));
5491
5492 self.state.push1(res);
5493 }
5494 Operator::F32x4Min => {
5495 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5499 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5500 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5501
5502 let v1_is_nan = err!(self.builder.build_call(
5503 self.intrinsics.cmp_f32x4,
5504 &[
5505 v1.into(),
5506 self.intrinsics.f32x4_zero.into(),
5507 self.intrinsics.fp_uno_md,
5508 self.intrinsics.fp_exception_md,
5509 ],
5510 "",
5511 ))
5512 .try_as_basic_value()
5513 .left()
5514 .unwrap()
5515 .into_vector_value();
5516 let v2_is_nan = err!(self.builder.build_call(
5517 self.intrinsics.cmp_f32x4,
5518 &[
5519 v2.into(),
5520 self.intrinsics.f32x4_zero.into(),
5521 self.intrinsics.fp_uno_md,
5522 self.intrinsics.fp_exception_md,
5523 ],
5524 "",
5525 ))
5526 .try_as_basic_value()
5527 .left()
5528 .unwrap()
5529 .into_vector_value();
5530 let v1_lt_v2 = err!(self.builder.build_call(
5531 self.intrinsics.cmp_f32x4,
5532 &[
5533 v1.into(),
5534 v2.into(),
5535 self.intrinsics.fp_olt_md,
5536 self.intrinsics.fp_exception_md,
5537 ],
5538 "",
5539 ))
5540 .try_as_basic_value()
5541 .left()
5542 .unwrap()
5543 .into_vector_value();
5544 let v1_gt_v2 = err!(self.builder.build_call(
5545 self.intrinsics.cmp_f32x4,
5546 &[
5547 v1.into(),
5548 v2.into(),
5549 self.intrinsics.fp_ogt_md,
5550 self.intrinsics.fp_exception_md,
5551 ],
5552 "",
5553 ))
5554 .try_as_basic_value()
5555 .left()
5556 .unwrap()
5557 .into_vector_value();
5558
5559 let res = err!(
5560 self.builder.build_select(
5561 v1_is_nan,
5562 self.quiet_nan(v1.into())?.into_vector_value(),
5563 err!(
5564 self.builder.build_select(
5565 v2_is_nan,
5566 self.quiet_nan(v2.into())?.into_vector_value(),
5567 err!(self.builder.build_select(
5568 v1_lt_v2,
5569 v1.into(),
5570 err!(self.builder.build_select(
5571 v1_gt_v2,
5572 v2.into(),
5573 err!(self.builder.build_bit_cast(
5574 err!(self.builder.build_or(
5575 err!(self.builder.build_bit_cast(
5576 v1,
5577 self.intrinsics.i32x4_ty,
5578 "",
5579 ))
5580 .into_vector_value(),
5581 err!(self.builder.build_bit_cast(
5582 v2,
5583 self.intrinsics.i32x4_ty,
5584 "",
5585 ))
5586 .into_vector_value(),
5587 "",
5588 )),
5589 self.intrinsics.f32x4_ty,
5590 "",
5591 )),
5592 "",
5593 )),
5594 "",
5595 ))
5596 .into_vector_value(),
5597 "",
5598 )
5599 )
5600 .into_vector_value(),
5601 "",
5602 )
5603 );
5604
5605 let res = err!(
5606 self.builder
5607 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5608 );
5609 self.state.push1(res);
5610 }
5611 Operator::F32x4PMin => {
5612 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5614 let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5615 let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5616 let cmp = err!(
5617 self.builder
5618 .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5619 );
5620 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5621 let res = err!(
5622 self.builder
5623 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5624 );
5625 self.state.push1(res);
5626 }
5627 Operator::F64x2Min => {
5628 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5632 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5633 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5634
5635 let v1_is_nan = err!(self.builder.build_call(
5636 self.intrinsics.cmp_f64x2,
5637 &[
5638 v1.into(),
5639 self.intrinsics.f64x2_zero.into(),
5640 self.intrinsics.fp_uno_md,
5641 self.intrinsics.fp_exception_md,
5642 ],
5643 "",
5644 ))
5645 .try_as_basic_value()
5646 .left()
5647 .unwrap()
5648 .into_vector_value();
5649 let v2_is_nan = err!(self.builder.build_call(
5650 self.intrinsics.cmp_f64x2,
5651 &[
5652 v2.into(),
5653 self.intrinsics.f64x2_zero.into(),
5654 self.intrinsics.fp_uno_md,
5655 self.intrinsics.fp_exception_md,
5656 ],
5657 "",
5658 ))
5659 .try_as_basic_value()
5660 .left()
5661 .unwrap()
5662 .into_vector_value();
5663 let v1_lt_v2 = err!(self.builder.build_call(
5664 self.intrinsics.cmp_f64x2,
5665 &[
5666 v1.into(),
5667 v2.into(),
5668 self.intrinsics.fp_olt_md,
5669 self.intrinsics.fp_exception_md,
5670 ],
5671 "",
5672 ))
5673 .try_as_basic_value()
5674 .left()
5675 .unwrap()
5676 .into_vector_value();
5677 let v1_gt_v2 = err!(self.builder.build_call(
5678 self.intrinsics.cmp_f64x2,
5679 &[
5680 v1.into(),
5681 v2.into(),
5682 self.intrinsics.fp_ogt_md,
5683 self.intrinsics.fp_exception_md,
5684 ],
5685 "",
5686 ))
5687 .try_as_basic_value()
5688 .left()
5689 .unwrap()
5690 .into_vector_value();
5691
5692 let res = err!(
5693 self.builder.build_select(
5694 v1_is_nan,
5695 self.quiet_nan(v1.into())?.into_vector_value(),
5696 err!(
5697 self.builder.build_select(
5698 v2_is_nan,
5699 self.quiet_nan(v2.into())?.into_vector_value(),
5700 err!(self.builder.build_select(
5701 v1_lt_v2,
5702 v1.into(),
5703 err!(self.builder.build_select(
5704 v1_gt_v2,
5705 v2.into(),
5706 err!(self.builder.build_bit_cast(
5707 err!(self.builder.build_or(
5708 err!(self.builder.build_bit_cast(
5709 v1,
5710 self.intrinsics.i64x2_ty,
5711 "",
5712 ))
5713 .into_vector_value(),
5714 err!(self.builder.build_bit_cast(
5715 v2,
5716 self.intrinsics.i64x2_ty,
5717 "",
5718 ))
5719 .into_vector_value(),
5720 "",
5721 )),
5722 self.intrinsics.f64x2_ty,
5723 "",
5724 )),
5725 "",
5726 )),
5727 "",
5728 ))
5729 .into_vector_value(),
5730 "",
5731 )
5732 )
5733 .into_vector_value(),
5734 "",
5735 )
5736 );
5737
5738 let res = err!(
5739 self.builder
5740 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5741 );
5742 self.state.push1(res);
5743 }
5744 Operator::F64x2PMin => {
5745 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5747 let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5748 let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5749 let cmp = err!(
5750 self.builder
5751 .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5752 );
5753 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5754 let res = err!(
5755 self.builder
5756 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5757 );
5758 self.state.push1(res);
5759 }
5760 Operator::F32Max => {
5761 let (v1, v2) = self.state.pop2()?;
5765 let v1 = self.canonicalize_nans(v1)?;
5766 let v2 = self.canonicalize_nans(v2)?;
5767
5768 let v1_is_nan = err!(self.builder.build_call(
5769 self.intrinsics.cmp_f32,
5770 &[
5771 v1.into(),
5772 self.intrinsics.f32_zero.into(),
5773 self.intrinsics.fp_uno_md,
5774 self.intrinsics.fp_exception_md,
5775 ],
5776 "",
5777 ))
5778 .try_as_basic_value()
5779 .left()
5780 .unwrap()
5781 .into_int_value();
5782 let v2_is_nan = err!(self.builder.build_call(
5783 self.intrinsics.cmp_f32,
5784 &[
5785 v2.into(),
5786 self.intrinsics.f32_zero.into(),
5787 self.intrinsics.fp_uno_md,
5788 self.intrinsics.fp_exception_md,
5789 ],
5790 "",
5791 ))
5792 .try_as_basic_value()
5793 .left()
5794 .unwrap()
5795 .into_int_value();
5796 let v1_lt_v2 = err!(self.builder.build_call(
5797 self.intrinsics.cmp_f32,
5798 &[
5799 v1.into(),
5800 v2.into(),
5801 self.intrinsics.fp_olt_md,
5802 self.intrinsics.fp_exception_md,
5803 ],
5804 "",
5805 ))
5806 .try_as_basic_value()
5807 .left()
5808 .unwrap()
5809 .into_int_value();
5810 let v1_gt_v2 = err!(self.builder.build_call(
5811 self.intrinsics.cmp_f32,
5812 &[
5813 v1.into(),
5814 v2.into(),
5815 self.intrinsics.fp_ogt_md,
5816 self.intrinsics.fp_exception_md,
5817 ],
5818 "",
5819 ))
5820 .try_as_basic_value()
5821 .left()
5822 .unwrap()
5823 .into_int_value();
5824
5825 let res = err!(self.builder.build_select(
5826 v1_is_nan,
5827 self.quiet_nan(v1)?,
5828 err!(self.builder.build_select(
5829 v2_is_nan,
5830 self.quiet_nan(v2)?,
5831 err!(self.builder.build_select(
5832 v1_lt_v2,
5833 v2,
5834 err!(self.builder.build_select(
5835 v1_gt_v2,
5836 v1,
5837 err!(self.builder.build_bit_cast(
5838 err!(self.builder.build_and(
5839 err!(self.builder.build_bit_cast(
5840 v1,
5841 self.intrinsics.i32_ty,
5842 ""
5843 ))
5844 .into_int_value(),
5845 err!(self.builder.build_bit_cast(
5846 v2,
5847 self.intrinsics.i32_ty,
5848 ""
5849 ))
5850 .into_int_value(),
5851 "",
5852 )),
5853 self.intrinsics.f32_ty,
5854 "",
5855 )),
5856 "",
5857 )),
5858 "",
5859 )),
5860 "",
5861 )),
5862 "",
5863 ));
5864
5865 self.state.push1(res);
5866 }
5867 Operator::F64Max => {
5868 let (v1, v2) = self.state.pop2()?;
5872 let v1 = self.canonicalize_nans(v1)?;
5873 let v2 = self.canonicalize_nans(v2)?;
5874
5875 let v1_is_nan = err!(self.builder.build_call(
5876 self.intrinsics.cmp_f64,
5877 &[
5878 v1.into(),
5879 self.intrinsics.f64_zero.into(),
5880 self.intrinsics.fp_uno_md,
5881 self.intrinsics.fp_exception_md,
5882 ],
5883 "",
5884 ))
5885 .try_as_basic_value()
5886 .left()
5887 .unwrap()
5888 .into_int_value();
5889 let v2_is_nan = err!(self.builder.build_call(
5890 self.intrinsics.cmp_f64,
5891 &[
5892 v2.into(),
5893 self.intrinsics.f64_zero.into(),
5894 self.intrinsics.fp_uno_md,
5895 self.intrinsics.fp_exception_md,
5896 ],
5897 "",
5898 ))
5899 .try_as_basic_value()
5900 .left()
5901 .unwrap()
5902 .into_int_value();
5903 let v1_lt_v2 = err!(self.builder.build_call(
5904 self.intrinsics.cmp_f64,
5905 &[
5906 v1.into(),
5907 v2.into(),
5908 self.intrinsics.fp_olt_md,
5909 self.intrinsics.fp_exception_md,
5910 ],
5911 "",
5912 ))
5913 .try_as_basic_value()
5914 .left()
5915 .unwrap()
5916 .into_int_value();
5917 let v1_gt_v2 = err!(self.builder.build_call(
5918 self.intrinsics.cmp_f64,
5919 &[
5920 v1.into(),
5921 v2.into(),
5922 self.intrinsics.fp_ogt_md,
5923 self.intrinsics.fp_exception_md,
5924 ],
5925 "",
5926 ))
5927 .try_as_basic_value()
5928 .left()
5929 .unwrap()
5930 .into_int_value();
5931
5932 let res = err!(self.builder.build_select(
5933 v1_is_nan,
5934 self.quiet_nan(v1)?,
5935 err!(self.builder.build_select(
5936 v2_is_nan,
5937 self.quiet_nan(v2)?,
5938 err!(self.builder.build_select(
5939 v1_lt_v2,
5940 v2,
5941 err!(self.builder.build_select(
5942 v1_gt_v2,
5943 v1,
5944 err!(self.builder.build_bit_cast(
5945 err!(self.builder.build_and(
5946 err!(self.builder.build_bit_cast(
5947 v1,
5948 self.intrinsics.i64_ty,
5949 ""
5950 ))
5951 .into_int_value(),
5952 err!(self.builder.build_bit_cast(
5953 v2,
5954 self.intrinsics.i64_ty,
5955 ""
5956 ))
5957 .into_int_value(),
5958 "",
5959 )),
5960 self.intrinsics.f64_ty,
5961 "",
5962 )),
5963 "",
5964 )),
5965 "",
5966 )),
5967 "",
5968 )),
5969 "",
5970 ));
5971
5972 self.state.push1(res);
5973 }
5974 Operator::F32x4Max => {
5975 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5979 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5980 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5981
5982 let v1_is_nan = err!(self.builder.build_call(
5983 self.intrinsics.cmp_f32x4,
5984 &[
5985 v1.into(),
5986 self.intrinsics.f32x4_zero.into(),
5987 self.intrinsics.fp_uno_md,
5988 self.intrinsics.fp_exception_md,
5989 ],
5990 "",
5991 ))
5992 .try_as_basic_value()
5993 .left()
5994 .unwrap()
5995 .into_vector_value();
5996 let v2_is_nan = err!(self.builder.build_call(
5997 self.intrinsics.cmp_f32x4,
5998 &[
5999 v2.into(),
6000 self.intrinsics.f32x4_zero.into(),
6001 self.intrinsics.fp_uno_md,
6002 self.intrinsics.fp_exception_md,
6003 ],
6004 "",
6005 ))
6006 .try_as_basic_value()
6007 .left()
6008 .unwrap()
6009 .into_vector_value();
6010 let v1_lt_v2 = err!(self.builder.build_call(
6011 self.intrinsics.cmp_f32x4,
6012 &[
6013 v1.into(),
6014 v2.into(),
6015 self.intrinsics.fp_olt_md,
6016 self.intrinsics.fp_exception_md,
6017 ],
6018 "",
6019 ))
6020 .try_as_basic_value()
6021 .left()
6022 .unwrap()
6023 .into_vector_value();
6024 let v1_gt_v2 = err!(self.builder.build_call(
6025 self.intrinsics.cmp_f32x4,
6026 &[
6027 v1.into(),
6028 v2.into(),
6029 self.intrinsics.fp_ogt_md,
6030 self.intrinsics.fp_exception_md,
6031 ],
6032 "",
6033 ))
6034 .try_as_basic_value()
6035 .left()
6036 .unwrap()
6037 .into_vector_value();
6038
6039 let res = err!(
6040 self.builder.build_select(
6041 v1_is_nan,
6042 self.quiet_nan(v1.into())?.into_vector_value(),
6043 err!(
6044 self.builder.build_select(
6045 v2_is_nan,
6046 self.quiet_nan(v2.into())?.into_vector_value(),
6047 err!(self.builder.build_select(
6048 v1_lt_v2,
6049 v2.into(),
6050 err!(self.builder.build_select(
6051 v1_gt_v2,
6052 v1.into(),
6053 err!(self.builder.build_bit_cast(
6054 err!(self.builder.build_and(
6055 err!(self.builder.build_bit_cast(
6056 v1,
6057 self.intrinsics.i32x4_ty,
6058 "",
6059 ))
6060 .into_vector_value(),
6061 err!(self.builder.build_bit_cast(
6062 v2,
6063 self.intrinsics.i32x4_ty,
6064 "",
6065 ))
6066 .into_vector_value(),
6067 "",
6068 )),
6069 self.intrinsics.f32x4_ty,
6070 "",
6071 )),
6072 "",
6073 )),
6074 "",
6075 ))
6076 .into_vector_value(),
6077 "",
6078 )
6079 )
6080 .into_vector_value(),
6081 "",
6082 )
6083 );
6084
6085 let res = err!(
6086 self.builder
6087 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6088 );
6089 self.state.push1(res);
6090 }
6091 Operator::F32x4PMax => {
6092 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6094 let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
6095 let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
6096 let cmp = err!(
6097 self.builder
6098 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6099 );
6100 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
6101
6102 let res = err!(
6103 self.builder
6104 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6105 );
6106 self.state.push1(res);
6107 }
6108 Operator::F64x2Max => {
6109 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6113 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6114 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6115
6116 let v1_is_nan = err!(self.builder.build_call(
6117 self.intrinsics.cmp_f64x2,
6118 &[
6119 v1.into(),
6120 self.intrinsics.f64x2_zero.into(),
6121 self.intrinsics.fp_uno_md,
6122 self.intrinsics.fp_exception_md,
6123 ],
6124 "",
6125 ))
6126 .try_as_basic_value()
6127 .left()
6128 .unwrap()
6129 .into_vector_value();
6130 let v2_is_nan = err!(self.builder.build_call(
6131 self.intrinsics.cmp_f64x2,
6132 &[
6133 v2.into(),
6134 self.intrinsics.f64x2_zero.into(),
6135 self.intrinsics.fp_uno_md,
6136 self.intrinsics.fp_exception_md,
6137 ],
6138 "",
6139 ))
6140 .try_as_basic_value()
6141 .left()
6142 .unwrap()
6143 .into_vector_value();
6144 let v1_lt_v2 = err!(self.builder.build_call(
6145 self.intrinsics.cmp_f64x2,
6146 &[
6147 v1.into(),
6148 v2.into(),
6149 self.intrinsics.fp_olt_md,
6150 self.intrinsics.fp_exception_md,
6151 ],
6152 "",
6153 ))
6154 .try_as_basic_value()
6155 .left()
6156 .unwrap()
6157 .into_vector_value();
6158 let v1_gt_v2 = err!(self.builder.build_call(
6159 self.intrinsics.cmp_f64x2,
6160 &[
6161 v1.into(),
6162 v2.into(),
6163 self.intrinsics.fp_ogt_md,
6164 self.intrinsics.fp_exception_md,
6165 ],
6166 "",
6167 ))
6168 .try_as_basic_value()
6169 .left()
6170 .unwrap()
6171 .into_vector_value();
6172
6173 let res = err!(
6174 self.builder.build_select(
6175 v1_is_nan,
6176 self.quiet_nan(v1.into())?.into_vector_value(),
6177 err!(
6178 self.builder.build_select(
6179 v2_is_nan,
6180 self.quiet_nan(v2.into())?.into_vector_value(),
6181 err!(self.builder.build_select(
6182 v1_lt_v2,
6183 v2.into(),
6184 err!(self.builder.build_select(
6185 v1_gt_v2,
6186 v1.into(),
6187 err!(self.builder.build_bit_cast(
6188 err!(self.builder.build_and(
6189 err!(self.builder.build_bit_cast(
6190 v1,
6191 self.intrinsics.i64x2_ty,
6192 "",
6193 ))
6194 .into_vector_value(),
6195 err!(self.builder.build_bit_cast(
6196 v2,
6197 self.intrinsics.i64x2_ty,
6198 "",
6199 ))
6200 .into_vector_value(),
6201 "",
6202 )),
6203 self.intrinsics.f64x2_ty,
6204 "",
6205 )),
6206 "",
6207 )),
6208 "",
6209 ))
6210 .into_vector_value(),
6211 "",
6212 )
6213 )
6214 .into_vector_value(),
6215 "",
6216 )
6217 );
6218
6219 let res = err!(
6220 self.builder
6221 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6222 );
6223 self.state.push1(res);
6224 }
6225 Operator::F64x2PMax => {
6226 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6228 let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
6229 let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
6230 let cmp = err!(
6231 self.builder
6232 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6233 );
6234 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
6235 let res = err!(
6236 self.builder
6237 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6238 );
6239 self.state.push1(res);
6240 }
6241 Operator::F32Ceil => {
6242 let (input, info) = self.state.pop1_extra()?;
6243 let res = err!(self.builder.build_call(
6244 self.intrinsics.ceil_f32,
6245 &[input.into()],
6246 ""
6247 ))
6248 .try_as_basic_value()
6249 .left()
6250 .unwrap();
6251 self.state
6252 .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
6253 }
6254 Operator::F32x4Ceil => {
6255 let (v, i) = self.state.pop1_extra()?;
6256 let (v, _) = self.v128_into_f32x4(v, i)?;
6257 let res = err!(self.builder.build_call(
6258 self.intrinsics.ceil_f32x4,
6259 &[v.into()],
6260 ""
6261 ))
6262 .try_as_basic_value()
6263 .left()
6264 .unwrap();
6265 let res = err!(
6266 self.builder
6267 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6268 );
6269 self.state
6270 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6271 }
6272 Operator::F64Ceil => {
6273 let (input, info) = self.state.pop1_extra()?;
6274 let res = err!(self.builder.build_call(
6275 self.intrinsics.ceil_f64,
6276 &[input.into()],
6277 ""
6278 ))
6279 .try_as_basic_value()
6280 .left()
6281 .unwrap();
6282 self.state
6283 .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
6284 }
6285 Operator::F64x2Ceil => {
6286 let (v, i) = self.state.pop1_extra()?;
6287 let (v, _) = self.v128_into_f64x2(v, i)?;
6288 let res = err!(self.builder.build_call(
6289 self.intrinsics.ceil_f64x2,
6290 &[v.into()],
6291 ""
6292 ))
6293 .try_as_basic_value()
6294 .left()
6295 .unwrap();
6296 let res = err!(
6297 self.builder
6298 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6299 );
6300 self.state
6301 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6302 }
6303 Operator::F32Floor => {
6304 let (input, info) = self.state.pop1_extra()?;
6305 let res = err!(self.builder.build_call(
6306 self.intrinsics.floor_f32,
6307 &[input.into()],
6308 ""
6309 ))
6310 .try_as_basic_value()
6311 .left()
6312 .unwrap();
6313 self.state
6314 .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
6315 }
6316 Operator::F32x4Floor => {
6317 let (v, i) = self.state.pop1_extra()?;
6318 let (v, _) = self.v128_into_f32x4(v, i)?;
6319 let res = err!(self.builder.build_call(
6320 self.intrinsics.floor_f32x4,
6321 &[v.into()],
6322 ""
6323 ))
6324 .try_as_basic_value()
6325 .left()
6326 .unwrap();
6327 let res = err!(
6328 self.builder
6329 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6330 );
6331 self.state
6332 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6333 }
6334 Operator::F64Floor => {
6335 let (input, info) = self.state.pop1_extra()?;
6336 let res = err!(self.builder.build_call(
6337 self.intrinsics.floor_f64,
6338 &[input.into()],
6339 ""
6340 ))
6341 .try_as_basic_value()
6342 .left()
6343 .unwrap();
6344 self.state
6345 .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
6346 }
6347 Operator::F64x2Floor => {
6348 let (v, i) = self.state.pop1_extra()?;
6349 let (v, _) = self.v128_into_f64x2(v, i)?;
6350 let res = err!(self.builder.build_call(
6351 self.intrinsics.floor_f64x2,
6352 &[v.into()],
6353 ""
6354 ))
6355 .try_as_basic_value()
6356 .left()
6357 .unwrap();
6358 let res = err!(
6359 self.builder
6360 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6361 );
6362 self.state
6363 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6364 }
6365 Operator::F32Trunc => {
6366 let (v, i) = self.state.pop1_extra()?;
6367 let res = err!(
6368 self.builder
6369 .build_call(self.intrinsics.trunc_f32, &[v.into()], "")
6370 )
6371 .try_as_basic_value()
6372 .left()
6373 .unwrap();
6374 self.state
6375 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6376 }
6377 Operator::F32x4Trunc => {
6378 let (v, i) = self.state.pop1_extra()?;
6379 let (v, _) = self.v128_into_f32x4(v, i)?;
6380 let res = err!(self.builder.build_call(
6381 self.intrinsics.trunc_f32x4,
6382 &[v.into()],
6383 ""
6384 ))
6385 .try_as_basic_value()
6386 .left()
6387 .unwrap();
6388 let res = err!(
6389 self.builder
6390 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6391 );
6392 self.state
6393 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6394 }
6395 Operator::F64Trunc => {
6396 let (v, i) = self.state.pop1_extra()?;
6397 let res = err!(
6398 self.builder
6399 .build_call(self.intrinsics.trunc_f64, &[v.into()], "")
6400 )
6401 .try_as_basic_value()
6402 .left()
6403 .unwrap();
6404 self.state
6405 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6406 }
6407 Operator::F64x2Trunc => {
6408 let (v, i) = self.state.pop1_extra()?;
6409 let (v, _) = self.v128_into_f64x2(v, i)?;
6410 let res = err!(self.builder.build_call(
6411 self.intrinsics.trunc_f64x2,
6412 &[v.into()],
6413 ""
6414 ))
6415 .try_as_basic_value()
6416 .left()
6417 .unwrap();
6418 let res = err!(
6419 self.builder
6420 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6421 );
6422 self.state
6423 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6424 }
6425 Operator::F32Nearest => {
6426 let (v, i) = self.state.pop1_extra()?;
6427 let res = err!(self.builder.build_call(
6428 self.intrinsics.nearbyint_f32,
6429 &[v.into()],
6430 ""
6431 ))
6432 .try_as_basic_value()
6433 .left()
6434 .unwrap();
6435 self.state
6436 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6437 }
6438 Operator::F32x4Nearest => {
6439 let (v, i) = self.state.pop1_extra()?;
6440 let (v, _) = self.v128_into_f32x4(v, i)?;
6441 let res = err!(self.builder.build_call(
6442 self.intrinsics.nearbyint_f32x4,
6443 &[v.into()],
6444 ""
6445 ))
6446 .try_as_basic_value()
6447 .left()
6448 .unwrap();
6449 let res = err!(
6450 self.builder
6451 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6452 );
6453 self.state
6454 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
6455 }
6456 Operator::F64Nearest => {
6457 let (v, i) = self.state.pop1_extra()?;
6458 let res = err!(self.builder.build_call(
6459 self.intrinsics.nearbyint_f64,
6460 &[v.into()],
6461 ""
6462 ))
6463 .try_as_basic_value()
6464 .left()
6465 .unwrap();
6466 self.state
6467 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6468 }
6469 Operator::F64x2Nearest => {
6470 let (v, i) = self.state.pop1_extra()?;
6471 let (v, _) = self.v128_into_f64x2(v, i)?;
6472 let res = err!(self.builder.build_call(
6473 self.intrinsics.nearbyint_f64x2,
6474 &[v.into()],
6475 ""
6476 ))
6477 .try_as_basic_value()
6478 .left()
6479 .unwrap();
6480 let res = err!(
6481 self.builder
6482 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6483 );
6484 self.state
6485 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
6486 }
6487 Operator::F32Abs => {
6488 let (v, i) = self.state.pop1_extra()?;
6489 let v = self.apply_pending_canonicalization(v, i)?;
6490 let res = err!(
6491 self.builder
6492 .build_call(self.intrinsics.fabs_f32, &[v.into()], "")
6493 )
6494 .try_as_basic_value()
6495 .left()
6496 .unwrap();
6497 self.state.push1_extra(res, i.strip_pending());
6500 }
6501 Operator::F64Abs => {
6502 let (v, i) = self.state.pop1_extra()?;
6503 let v = self.apply_pending_canonicalization(v, i)?;
6504 let res = err!(
6505 self.builder
6506 .build_call(self.intrinsics.fabs_f64, &[v.into()], "")
6507 )
6508 .try_as_basic_value()
6509 .left()
6510 .unwrap();
6511 self.state.push1_extra(res, i.strip_pending());
6514 }
6515 Operator::F32x4Abs => {
6516 let (v, i) = self.state.pop1_extra()?;
6517 let v = err!(self.builder.build_bit_cast(
6518 v.into_int_value(),
6519 self.intrinsics.f32x4_ty,
6520 ""
6521 ));
6522 let v = self.apply_pending_canonicalization(v, i)?;
6523 let res = err!(self.builder.build_call(
6524 self.intrinsics.fabs_f32x4,
6525 &[v.into()],
6526 ""
6527 ))
6528 .try_as_basic_value()
6529 .left()
6530 .unwrap();
6531 let res = err!(
6532 self.builder
6533 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6534 );
6535 self.state.push1_extra(res, i.strip_pending());
6538 }
6539 Operator::F64x2Abs => {
6540 let (v, i) = self.state.pop1_extra()?;
6541 let v = err!(self.builder.build_bit_cast(
6542 v.into_int_value(),
6543 self.intrinsics.f64x2_ty,
6544 ""
6545 ));
6546 let v = self.apply_pending_canonicalization(v, i)?;
6547 let res = err!(self.builder.build_call(
6548 self.intrinsics.fabs_f64x2,
6549 &[v.into()],
6550 ""
6551 ))
6552 .try_as_basic_value()
6553 .left()
6554 .unwrap();
6555 let res = err!(
6556 self.builder
6557 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6558 );
6559 self.state.push1_extra(res, i.strip_pending());
6562 }
6563 Operator::F32x4Neg => {
6564 let (v, i) = self.state.pop1_extra()?;
6565 let v = err!(self.builder.build_bit_cast(
6566 v.into_int_value(),
6567 self.intrinsics.f32x4_ty,
6568 ""
6569 ));
6570 let v = self
6571 .apply_pending_canonicalization(v, i)?
6572 .into_vector_value();
6573 let res = err!(self.builder.build_float_neg(v, ""));
6574 let res = err!(
6575 self.builder
6576 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6577 );
6578 self.state.push1_extra(res, i.strip_pending());
6581 }
6582 Operator::F64x2Neg => {
6583 let (v, i) = self.state.pop1_extra()?;
6584 let v = err!(self.builder.build_bit_cast(
6585 v.into_int_value(),
6586 self.intrinsics.f64x2_ty,
6587 ""
6588 ));
6589 let v = self
6590 .apply_pending_canonicalization(v, i)?
6591 .into_vector_value();
6592 let res = err!(self.builder.build_float_neg(v, ""));
6593 let res = err!(
6594 self.builder
6595 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6596 );
6597 self.state.push1_extra(res, i.strip_pending());
6600 }
6601 Operator::F32Neg | Operator::F64Neg => {
6602 let (v, i) = self.state.pop1_extra()?;
6603 let v = self
6604 .apply_pending_canonicalization(v, i)?
6605 .into_float_value();
6606 let res = err!(self.builder.build_float_neg(v, ""));
6607 self.state.push1_extra(res, i.strip_pending());
6610 }
6611 Operator::F32Copysign => {
6612 let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
6613 let mag = self.apply_pending_canonicalization(mag, mag_info)?;
6614 let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
6615 let res = err!(self.builder.build_call(
6616 self.intrinsics.copysign_f32,
6617 &[mag.into(), sgn.into()],
6618 ""
6619 ))
6620 .try_as_basic_value()
6621 .left()
6622 .unwrap();
6623 self.state.push1_extra(res, mag_info.strip_pending());
6626 }
6627 Operator::F64Copysign => {
6628 let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
6629 let mag = self.apply_pending_canonicalization(mag, mag_info)?;
6630 let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
6631 let res = err!(self.builder.build_call(
6632 self.intrinsics.copysign_f64,
6633 &[mag.into(), sgn.into()],
6634 ""
6635 ))
6636 .try_as_basic_value()
6637 .left()
6638 .unwrap();
6639 self.state.push1_extra(res, mag_info.strip_pending());
6642 }
6643
6644 Operator::I32Eq | Operator::I64Eq => {
6649 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6650 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6651 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6652 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6653 let cond = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6654 let res = err!(
6655 self.builder
6656 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6657 );
6658 self.state.push1_extra(
6659 res,
6660 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6661 );
6662 }
6663 Operator::I8x16Eq => {
6664 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6665 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6666 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6667 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6668 let res = err!(
6669 self.builder
6670 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6671 );
6672 let res = err!(
6673 self.builder
6674 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6675 );
6676 self.state.push1(res);
6677 }
6678 Operator::I16x8Eq => {
6679 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6680 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6681 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6682 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6683 let res = err!(
6684 self.builder
6685 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6686 );
6687 let res = err!(
6688 self.builder
6689 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6690 );
6691 self.state.push1(res);
6692 }
6693 Operator::I32x4Eq => {
6694 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6695 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6696 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6697 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6698 let res = err!(
6699 self.builder
6700 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6701 );
6702 let res = err!(
6703 self.builder
6704 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6705 );
6706 self.state.push1(res);
6707 }
6708 Operator::I64x2Eq => {
6709 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6710 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6711 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6712 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
6713 let res = err!(
6714 self.builder
6715 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6716 );
6717 let res = err!(
6718 self.builder
6719 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6720 );
6721 self.state.push1(res);
6722 }
6723 Operator::I32Ne | Operator::I64Ne => {
6724 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6725 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6726 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6727 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6728 let cond = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6729 let res = err!(
6730 self.builder
6731 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6732 );
6733 self.state.push1_extra(
6734 res,
6735 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6736 );
6737 }
6738 Operator::I8x16Ne => {
6739 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6740 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6741 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6742 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6743 let res = err!(
6744 self.builder
6745 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6746 );
6747 let res = err!(
6748 self.builder
6749 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6750 );
6751 self.state.push1(res);
6752 }
6753 Operator::I16x8Ne => {
6754 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6755 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6756 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6757 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6758 let res = err!(
6759 self.builder
6760 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6761 );
6762 let res = err!(
6763 self.builder
6764 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6765 );
6766 self.state.push1(res);
6767 }
6768 Operator::I32x4Ne => {
6769 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6770 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6771 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6772 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6773 let res = err!(
6774 self.builder
6775 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6776 );
6777 let res = err!(
6778 self.builder
6779 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6780 );
6781 self.state.push1(res);
6782 }
6783 Operator::I64x2Ne => {
6784 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6785 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6786 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6787 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6788 let res = err!(
6789 self.builder
6790 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6791 );
6792 let res = err!(
6793 self.builder
6794 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6795 );
6796 self.state.push1(res);
6797 }
6798 Operator::I32LtS | Operator::I64LtS => {
6799 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6800 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6801 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6802 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6803 let cond = err!(
6804 self.builder
6805 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6806 );
6807 let res = err!(
6808 self.builder
6809 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6810 );
6811 self.state.push1_extra(
6812 res,
6813 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6814 );
6815 }
6816 Operator::I8x16LtS => {
6817 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6818 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6819 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6820 let res = err!(
6821 self.builder
6822 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6823 );
6824 let res = err!(
6825 self.builder
6826 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6827 );
6828 let res = err!(
6829 self.builder
6830 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6831 );
6832 self.state.push1(res);
6833 }
6834 Operator::I16x8LtS => {
6835 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6836 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6837 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6838 let res = err!(
6839 self.builder
6840 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6841 );
6842 let res = err!(
6843 self.builder
6844 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6845 );
6846 let res = err!(
6847 self.builder
6848 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6849 );
6850 self.state.push1(res);
6851 }
6852 Operator::I32x4LtS => {
6853 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6854 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6855 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6856 let res = err!(
6857 self.builder
6858 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6859 );
6860 let res = err!(
6861 self.builder
6862 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6863 );
6864 let res = err!(
6865 self.builder
6866 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6867 );
6868 self.state.push1(res);
6869 }
6870 Operator::I64x2LtS => {
6871 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6872 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6873 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6874 let res = err!(
6875 self.builder
6876 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6877 );
6878 let res = err!(
6879 self.builder
6880 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6881 );
6882 let res = err!(
6883 self.builder
6884 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6885 );
6886 self.state.push1(res);
6887 }
6888 Operator::I32LtU | Operator::I64LtU => {
6889 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6890 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6891 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6892 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6893 let cond = err!(
6894 self.builder
6895 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6896 );
6897 let res = err!(
6898 self.builder
6899 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6900 );
6901 self.state.push1(res);
6902 }
6903 Operator::I8x16LtU => {
6904 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6905 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6906 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6907 let res = err!(
6908 self.builder
6909 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6910 );
6911 let res = err!(
6912 self.builder
6913 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6914 );
6915 let res = err!(
6916 self.builder
6917 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6918 );
6919 self.state.push1(res);
6920 }
6921 Operator::I16x8LtU => {
6922 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6923 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6924 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6925 let res = err!(
6926 self.builder
6927 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6928 );
6929 let res = err!(
6930 self.builder
6931 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6932 );
6933 let res = err!(
6934 self.builder
6935 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6936 );
6937 self.state.push1(res);
6938 }
6939 Operator::I32x4LtU => {
6940 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6941 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6942 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6943 let res = err!(
6944 self.builder
6945 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6946 );
6947 let res = err!(
6948 self.builder
6949 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6950 );
6951 let res = err!(
6952 self.builder
6953 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6954 );
6955 self.state.push1(res);
6956 }
6957 Operator::I32LeS | Operator::I64LeS => {
6958 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6959 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6960 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6961 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6962 let cond = err!(
6963 self.builder
6964 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6965 );
6966 let res = err!(
6967 self.builder
6968 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6969 );
6970 self.state.push1_extra(
6971 res,
6972 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6973 );
6974 }
6975 Operator::I8x16LeS => {
6976 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6977 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6978 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6979 let res = err!(
6980 self.builder
6981 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6982 );
6983 let res = err!(
6984 self.builder
6985 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6986 );
6987 let res = err!(
6988 self.builder
6989 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6990 );
6991 self.state.push1(res);
6992 }
6993 Operator::I16x8LeS => {
6994 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6995 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6996 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6997 let res = err!(
6998 self.builder
6999 .build_int_compare(IntPredicate::SLE, v1, v2, "")
7000 );
7001 let res = err!(
7002 self.builder
7003 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7004 );
7005 let res = err!(
7006 self.builder
7007 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7008 );
7009 self.state.push1(res);
7010 }
7011 Operator::I32x4LeS => {
7012 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7013 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7014 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7015 let res = err!(
7016 self.builder
7017 .build_int_compare(IntPredicate::SLE, v1, v2, "")
7018 );
7019 let res = err!(
7020 self.builder
7021 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7022 );
7023 let res = err!(
7024 self.builder
7025 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7026 );
7027 self.state.push1(res);
7028 }
7029 Operator::I64x2LeS => {
7030 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7031 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
7032 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
7033 let res = err!(
7034 self.builder
7035 .build_int_compare(IntPredicate::SLE, v1, v2, "")
7036 );
7037 let res = err!(
7038 self.builder
7039 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7040 );
7041 let res = err!(
7042 self.builder
7043 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7044 );
7045 self.state.push1(res);
7046 }
7047 Operator::I32LeU | Operator::I64LeU => {
7048 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7049 let v1 = self.apply_pending_canonicalization(v1, i1)?;
7050 let v2 = self.apply_pending_canonicalization(v2, i2)?;
7051 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7052 let cond = err!(
7053 self.builder
7054 .build_int_compare(IntPredicate::ULE, v1, v2, "")
7055 );
7056 let res = err!(
7057 self.builder
7058 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7059 );
7060 self.state.push1_extra(
7061 res,
7062 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7063 );
7064 }
7065 Operator::I8x16LeU => {
7066 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7067 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7068 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7069 let res = err!(
7070 self.builder
7071 .build_int_compare(IntPredicate::ULE, v1, v2, "")
7072 );
7073 let res = err!(
7074 self.builder
7075 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7076 );
7077 let res = err!(
7078 self.builder
7079 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7080 );
7081 self.state.push1(res);
7082 }
7083 Operator::I16x8LeU => {
7084 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7085 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7086 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7087 let res = err!(
7088 self.builder
7089 .build_int_compare(IntPredicate::ULE, v1, v2, "")
7090 );
7091 let res = err!(
7092 self.builder
7093 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7094 );
7095 let res = err!(
7096 self.builder
7097 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7098 );
7099 self.state.push1(res);
7100 }
7101 Operator::I32x4LeU => {
7102 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7103 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7104 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7105 let res = err!(
7106 self.builder
7107 .build_int_compare(IntPredicate::ULE, v1, v2, "")
7108 );
7109 let res = err!(
7110 self.builder
7111 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7112 );
7113 let res = err!(
7114 self.builder
7115 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7116 );
7117 self.state.push1(res);
7118 }
7119 Operator::I32GtS | Operator::I64GtS => {
7120 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7121 let v1 = self.apply_pending_canonicalization(v1, i1)?;
7122 let v2 = self.apply_pending_canonicalization(v2, i2)?;
7123 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7124 let cond = err!(
7125 self.builder
7126 .build_int_compare(IntPredicate::SGT, v1, v2, "")
7127 );
7128 let res = err!(
7129 self.builder
7130 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7131 );
7132 self.state.push1_extra(
7133 res,
7134 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7135 );
7136 }
7137 Operator::I8x16GtS => {
7138 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7139 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7140 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7141 let res = err!(
7142 self.builder
7143 .build_int_compare(IntPredicate::SGT, v1, v2, "")
7144 );
7145 let res = err!(
7146 self.builder
7147 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7148 );
7149 let res = err!(
7150 self.builder
7151 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7152 );
7153 self.state.push1(res);
7154 }
7155 Operator::I16x8GtS => {
7156 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7157 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7158 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7159 let res = err!(
7160 self.builder
7161 .build_int_compare(IntPredicate::SGT, v1, v2, "")
7162 );
7163 let res = err!(
7164 self.builder
7165 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7166 );
7167 let res = err!(
7168 self.builder
7169 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7170 );
7171 self.state.push1(res);
7172 }
7173 Operator::I32x4GtS => {
7174 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7175 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7176 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7177 let res = err!(
7178 self.builder
7179 .build_int_compare(IntPredicate::SGT, v1, v2, "")
7180 );
7181 let res = err!(
7182 self.builder
7183 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7184 );
7185 let res = err!(
7186 self.builder
7187 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7188 );
7189 self.state.push1(res);
7190 }
7191 Operator::I64x2GtS => {
7192 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7193 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
7194 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
7195 let res = err!(
7196 self.builder
7197 .build_int_compare(IntPredicate::SGT, v1, v2, "")
7198 );
7199 let res = err!(
7200 self.builder
7201 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7202 );
7203 let res = err!(
7204 self.builder
7205 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7206 );
7207 self.state.push1(res);
7208 }
7209 Operator::I32GtU | Operator::I64GtU => {
7210 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7211 let v1 = self.apply_pending_canonicalization(v1, i1)?;
7212 let v2 = self.apply_pending_canonicalization(v2, i2)?;
7213 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7214 let cond = err!(
7215 self.builder
7216 .build_int_compare(IntPredicate::UGT, v1, v2, "")
7217 );
7218 let res = err!(
7219 self.builder
7220 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7221 );
7222 self.state.push1_extra(
7223 res,
7224 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7225 );
7226 }
7227 Operator::I8x16GtU => {
7228 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7229 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7230 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7231 let res = err!(
7232 self.builder
7233 .build_int_compare(IntPredicate::UGT, v1, v2, "")
7234 );
7235 let res = err!(
7236 self.builder
7237 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7238 );
7239 let res = err!(
7240 self.builder
7241 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7242 );
7243 self.state.push1(res);
7244 }
7245 Operator::I16x8GtU => {
7246 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7247 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7248 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7249 let res = err!(
7250 self.builder
7251 .build_int_compare(IntPredicate::UGT, v1, v2, "")
7252 );
7253 let res = err!(
7254 self.builder
7255 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7256 );
7257 let res = err!(
7258 self.builder
7259 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7260 );
7261 self.state.push1(res);
7262 }
7263 Operator::I32x4GtU => {
7264 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7265 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7266 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7267 let res = err!(
7268 self.builder
7269 .build_int_compare(IntPredicate::UGT, v1, v2, "")
7270 );
7271 let res = err!(
7272 self.builder
7273 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7274 );
7275 let res = err!(
7276 self.builder
7277 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7278 );
7279 self.state.push1(res);
7280 }
7281 Operator::I32GeS | Operator::I64GeS => {
7282 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7283 let v1 = self.apply_pending_canonicalization(v1, i1)?;
7284 let v2 = self.apply_pending_canonicalization(v2, i2)?;
7285 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7286 let cond = err!(
7287 self.builder
7288 .build_int_compare(IntPredicate::SGE, v1, v2, "")
7289 );
7290 let res = err!(
7291 self.builder
7292 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7293 );
7294 self.state.push1(res);
7295 }
7296 Operator::I8x16GeS => {
7297 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7298 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7299 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7300 let res = err!(
7301 self.builder
7302 .build_int_compare(IntPredicate::SGE, v1, v2, "")
7303 );
7304 let res = err!(
7305 self.builder
7306 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7307 );
7308 let res = err!(
7309 self.builder
7310 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7311 );
7312 self.state.push1(res);
7313 }
7314 Operator::I16x8GeS => {
7315 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7316 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7317 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7318 let res = err!(
7319 self.builder
7320 .build_int_compare(IntPredicate::SGE, v1, v2, "")
7321 );
7322 let res = err!(
7323 self.builder
7324 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7325 );
7326 let res = err!(
7327 self.builder
7328 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7329 );
7330 self.state.push1(res);
7331 }
7332 Operator::I32x4GeS => {
7333 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7334 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7335 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7336 let res = err!(
7337 self.builder
7338 .build_int_compare(IntPredicate::SGE, v1, v2, "")
7339 );
7340 let res = err!(
7341 self.builder
7342 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7343 );
7344 let res = err!(
7345 self.builder
7346 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7347 );
7348 self.state.push1(res);
7349 }
7350 Operator::I64x2GeS => {
7351 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7352 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
7353 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
7354 let res = err!(
7355 self.builder
7356 .build_int_compare(IntPredicate::SGE, v1, v2, "")
7357 );
7358 let res = err!(
7359 self.builder
7360 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7361 );
7362 let res = err!(
7363 self.builder
7364 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7365 );
7366 self.state.push1(res);
7367 }
7368 Operator::I32GeU | Operator::I64GeU => {
7369 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7370 let v1 = self.apply_pending_canonicalization(v1, i1)?;
7371 let v2 = self.apply_pending_canonicalization(v2, i2)?;
7372 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
7373 let cond = err!(
7374 self.builder
7375 .build_int_compare(IntPredicate::UGE, v1, v2, "")
7376 );
7377 let res = err!(
7378 self.builder
7379 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7380 );
7381 self.state.push1_extra(
7382 res,
7383 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7384 );
7385 }
7386 Operator::I8x16GeU => {
7387 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7388 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
7389 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
7390 let res = err!(
7391 self.builder
7392 .build_int_compare(IntPredicate::UGE, v1, v2, "")
7393 );
7394 let res = err!(
7395 self.builder
7396 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
7397 );
7398 let res = err!(
7399 self.builder
7400 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7401 );
7402 self.state.push1(res);
7403 }
7404 Operator::I16x8GeU => {
7405 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7406 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7407 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7408 let res = err!(
7409 self.builder
7410 .build_int_compare(IntPredicate::UGE, v1, v2, "")
7411 );
7412 let res = err!(
7413 self.builder
7414 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
7415 );
7416 let res = err!(
7417 self.builder
7418 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7419 );
7420 self.state.push1(res);
7421 }
7422 Operator::I32x4GeU => {
7423 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7424 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7425 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7426 let res = err!(
7427 self.builder
7428 .build_int_compare(IntPredicate::UGE, v1, v2, "")
7429 );
7430 let res = err!(
7431 self.builder
7432 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7433 );
7434 let res = err!(
7435 self.builder
7436 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7437 );
7438 self.state.push1(res);
7439 }
7440
7441 Operator::F32Eq | Operator::F64Eq => {
7446 let (v1, v2) = self.state.pop2()?;
7447 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7448 let cond = err!(
7449 self.builder
7450 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
7451 );
7452 let res = err!(
7453 self.builder
7454 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7455 );
7456 self.state.push1_extra(
7457 res,
7458 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7459 );
7460 }
7461 Operator::F32x4Eq => {
7462 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7463 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7464 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7465 let res = err!(
7466 self.builder
7467 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
7468 );
7469 let res = err!(
7470 self.builder
7471 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7472 );
7473 let res = err!(
7474 self.builder
7475 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7476 );
7477 self.state.push1(res);
7478 }
7479 Operator::F64x2Eq => {
7480 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7481 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7482 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7483 let res = err!(
7484 self.builder
7485 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
7486 );
7487 let res = err!(
7488 self.builder
7489 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7490 );
7491 let res = err!(
7492 self.builder
7493 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7494 );
7495 self.state.push1(res);
7496 }
7497 Operator::F32Ne | Operator::F64Ne => {
7498 let (v1, v2) = self.state.pop2()?;
7499 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7500 let cond = err!(
7501 self.builder
7502 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
7503 );
7504 let res = err!(
7505 self.builder
7506 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7507 );
7508 self.state.push1_extra(
7509 res,
7510 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7511 );
7512 }
7513 Operator::F32x4Ne => {
7514 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7515 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7516 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7517 let res = err!(
7518 self.builder
7519 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
7520 );
7521 let res = err!(
7522 self.builder
7523 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7524 );
7525 let res = err!(
7526 self.builder
7527 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7528 );
7529 self.state.push1(res);
7530 }
7531 Operator::F64x2Ne => {
7532 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7533 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7534 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7535 let res = err!(
7536 self.builder
7537 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
7538 );
7539 let res = err!(
7540 self.builder
7541 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7542 );
7543 let res = err!(
7544 self.builder
7545 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7546 );
7547 self.state.push1(res);
7548 }
7549 Operator::F32Lt | Operator::F64Lt => {
7550 let (v1, v2) = self.state.pop2()?;
7551 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7552 let cond = err!(
7553 self.builder
7554 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
7555 );
7556 let res = err!(
7557 self.builder
7558 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7559 );
7560 self.state.push1_extra(
7561 res,
7562 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7563 );
7564 }
7565 Operator::F32x4Lt => {
7566 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7567 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7568 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7569 let res = err!(
7570 self.builder
7571 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
7572 );
7573 let res = err!(
7574 self.builder
7575 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7576 );
7577 let res = err!(
7578 self.builder
7579 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7580 );
7581 self.state.push1(res);
7582 }
7583 Operator::F64x2Lt => {
7584 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7585 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7586 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7587 let res = err!(
7588 self.builder
7589 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
7590 );
7591 let res = err!(
7592 self.builder
7593 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7594 );
7595 let res = err!(
7596 self.builder
7597 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7598 );
7599 self.state.push1(res);
7600 }
7601 Operator::F32Le | Operator::F64Le => {
7602 let (v1, v2) = self.state.pop2()?;
7603 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7604 let cond = err!(
7605 self.builder
7606 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
7607 );
7608 let res = err!(
7609 self.builder
7610 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7611 );
7612 self.state.push1_extra(
7613 res,
7614 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7615 );
7616 }
7617 Operator::F32x4Le => {
7618 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7619 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7620 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7621 let res = err!(
7622 self.builder
7623 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
7624 );
7625 let res = err!(
7626 self.builder
7627 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7628 );
7629 let res = err!(
7630 self.builder
7631 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7632 );
7633 self.state.push1(res);
7634 }
7635 Operator::F64x2Le => {
7636 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7637 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7638 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7639 let res = err!(
7640 self.builder
7641 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
7642 );
7643 let res = err!(
7644 self.builder
7645 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7646 );
7647 let res = err!(
7648 self.builder
7649 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7650 );
7651 self.state.push1(res);
7652 }
7653 Operator::F32Gt | Operator::F64Gt => {
7654 let (v1, v2) = self.state.pop2()?;
7655 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7656 let cond = err!(
7657 self.builder
7658 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
7659 );
7660 let res = err!(
7661 self.builder
7662 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7663 );
7664 self.state.push1_extra(
7665 res,
7666 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7667 );
7668 }
7669 Operator::F32x4Gt => {
7670 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7671 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7672 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7673 let res = err!(
7674 self.builder
7675 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
7676 );
7677 let res = err!(
7678 self.builder
7679 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7680 );
7681 let res = err!(
7682 self.builder
7683 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7684 );
7685 self.state.push1(res);
7686 }
7687 Operator::F64x2Gt => {
7688 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7689 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7690 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7691 let res = err!(
7692 self.builder
7693 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
7694 );
7695 let res = err!(
7696 self.builder
7697 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7698 );
7699 let res = err!(
7700 self.builder
7701 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7702 );
7703 self.state.push1(res);
7704 }
7705 Operator::F32Ge | Operator::F64Ge => {
7706 let (v1, v2) = self.state.pop2()?;
7707 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
7708 let cond = err!(
7709 self.builder
7710 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7711 );
7712 let res = err!(
7713 self.builder
7714 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
7715 );
7716 self.state.push1_extra(
7717 res,
7718 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
7719 );
7720 }
7721 Operator::F32x4Ge => {
7722 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7723 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
7724 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
7725 let res = err!(
7726 self.builder
7727 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7728 );
7729 let res = err!(
7730 self.builder
7731 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7732 );
7733 let res = err!(
7734 self.builder
7735 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7736 );
7737 self.state.push1(res);
7738 }
7739 Operator::F64x2Ge => {
7740 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7741 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7742 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7743 let res = err!(
7744 self.builder
7745 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7746 );
7747 let res = err!(
7748 self.builder
7749 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7750 );
7751 let res = err!(
7752 self.builder
7753 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7754 );
7755 self.state.push1(res);
7756 }
7757
7758 Operator::I32WrapI64 => {
7763 let (v, i) = self.state.pop1_extra()?;
7764 let v = self.apply_pending_canonicalization(v, i)?;
7765 let v = v.into_int_value();
7766 let res = err!(
7767 self.builder
7768 .build_int_truncate(v, self.intrinsics.i32_ty, "")
7769 );
7770 self.state.push1(res);
7771 }
7772 Operator::I64ExtendI32S => {
7773 let (v, i) = self.state.pop1_extra()?;
7774 let v = self.apply_pending_canonicalization(v, i)?;
7775 let v = v.into_int_value();
7776 let res = err!(
7777 self.builder
7778 .build_int_s_extend(v, self.intrinsics.i64_ty, "")
7779 );
7780 self.state.push1(res);
7781 }
7782 Operator::I64ExtendI32U => {
7783 let (v, i) = self.state.pop1_extra()?;
7784 let v = self.apply_pending_canonicalization(v, i)?;
7785 let v = v.into_int_value();
7786 let res = err!(
7787 self.builder
7788 .build_int_z_extend(v, self.intrinsics.i64_ty, "")
7789 );
7790 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
7791 }
7792 Operator::I16x8ExtendLowI8x16S => {
7793 let (v, i) = self.state.pop1_extra()?;
7794 let (v, _) = self.v128_into_i8x16(v, i)?;
7795 let low = err!(self.builder.build_shuffle_vector(
7796 v,
7797 v.get_type().get_undef(),
7798 VectorType::const_vector(&[
7799 self.intrinsics.i32_consts[0],
7800 self.intrinsics.i32_consts[1],
7801 self.intrinsics.i32_consts[2],
7802 self.intrinsics.i32_consts[3],
7803 self.intrinsics.i32_consts[4],
7804 self.intrinsics.i32_consts[5],
7805 self.intrinsics.i32_consts[6],
7806 self.intrinsics.i32_consts[7],
7807 ]),
7808 "",
7809 ));
7810 let res = err!(
7811 self.builder
7812 .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7813 );
7814 let res = err!(
7815 self.builder
7816 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7817 );
7818 self.state.push1(res);
7819 }
7820 Operator::I16x8ExtendHighI8x16S => {
7821 let (v, i) = self.state.pop1_extra()?;
7822 let (v, _) = self.v128_into_i8x16(v, i)?;
7823 let low = err!(self.builder.build_shuffle_vector(
7824 v,
7825 v.get_type().get_undef(),
7826 VectorType::const_vector(&[
7827 self.intrinsics.i32_consts[8],
7828 self.intrinsics.i32_consts[9],
7829 self.intrinsics.i32_consts[10],
7830 self.intrinsics.i32_consts[11],
7831 self.intrinsics.i32_consts[12],
7832 self.intrinsics.i32_consts[13],
7833 self.intrinsics.i32_consts[14],
7834 self.intrinsics.i32_consts[15],
7835 ]),
7836 "",
7837 ));
7838 let res = err!(
7839 self.builder
7840 .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7841 );
7842 let res = err!(
7843 self.builder
7844 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7845 );
7846 self.state.push1(res);
7847 }
7848 Operator::I16x8ExtendLowI8x16U => {
7849 let (v, i) = self.state.pop1_extra()?;
7850 let (v, _) = self.v128_into_i8x16(v, i)?;
7851 let low = err!(self.builder.build_shuffle_vector(
7852 v,
7853 v.get_type().get_undef(),
7854 VectorType::const_vector(&[
7855 self.intrinsics.i32_consts[0],
7856 self.intrinsics.i32_consts[1],
7857 self.intrinsics.i32_consts[2],
7858 self.intrinsics.i32_consts[3],
7859 self.intrinsics.i32_consts[4],
7860 self.intrinsics.i32_consts[5],
7861 self.intrinsics.i32_consts[6],
7862 self.intrinsics.i32_consts[7],
7863 ]),
7864 "",
7865 ));
7866 let res = err!(
7867 self.builder
7868 .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7869 );
7870 let res = err!(
7871 self.builder
7872 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7873 );
7874 self.state.push1(res);
7875 }
7876 Operator::I16x8ExtendHighI8x16U => {
7877 let (v, i) = self.state.pop1_extra()?;
7878 let (v, _) = self.v128_into_i8x16(v, i)?;
7879 let low = err!(self.builder.build_shuffle_vector(
7880 v,
7881 v.get_type().get_undef(),
7882 VectorType::const_vector(&[
7883 self.intrinsics.i32_consts[8],
7884 self.intrinsics.i32_consts[9],
7885 self.intrinsics.i32_consts[10],
7886 self.intrinsics.i32_consts[11],
7887 self.intrinsics.i32_consts[12],
7888 self.intrinsics.i32_consts[13],
7889 self.intrinsics.i32_consts[14],
7890 self.intrinsics.i32_consts[15],
7891 ]),
7892 "",
7893 ));
7894 let res = err!(
7895 self.builder
7896 .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7897 );
7898 let res = err!(
7899 self.builder
7900 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7901 );
7902 self.state.push1(res);
7903 }
7904 Operator::I32x4ExtendLowI16x8S => {
7905 let (v, i) = self.state.pop1_extra()?;
7906 let (v, _) = self.v128_into_i16x8(v, i)?;
7907 let low = err!(self.builder.build_shuffle_vector(
7908 v,
7909 v.get_type().get_undef(),
7910 VectorType::const_vector(&[
7911 self.intrinsics.i32_consts[0],
7912 self.intrinsics.i32_consts[1],
7913 self.intrinsics.i32_consts[2],
7914 self.intrinsics.i32_consts[3],
7915 ]),
7916 "",
7917 ));
7918 let res = err!(
7919 self.builder
7920 .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7921 );
7922 let res = err!(
7923 self.builder
7924 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7925 );
7926 self.state.push1(res);
7927 }
7928 Operator::I32x4ExtendHighI16x8S => {
7929 let (v, i) = self.state.pop1_extra()?;
7930 let (v, _) = self.v128_into_i16x8(v, i)?;
7931 let low = err!(self.builder.build_shuffle_vector(
7932 v,
7933 v.get_type().get_undef(),
7934 VectorType::const_vector(&[
7935 self.intrinsics.i32_consts[4],
7936 self.intrinsics.i32_consts[5],
7937 self.intrinsics.i32_consts[6],
7938 self.intrinsics.i32_consts[7],
7939 ]),
7940 "",
7941 ));
7942 let res = err!(
7943 self.builder
7944 .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7945 );
7946 let res = err!(
7947 self.builder
7948 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7949 );
7950 self.state.push1(res);
7951 }
7952 Operator::I32x4ExtendLowI16x8U => {
7953 let (v, i) = self.state.pop1_extra()?;
7954 let (v, _) = self.v128_into_i16x8(v, i)?;
7955 let low = err!(self.builder.build_shuffle_vector(
7956 v,
7957 v.get_type().get_undef(),
7958 VectorType::const_vector(&[
7959 self.intrinsics.i32_consts[0],
7960 self.intrinsics.i32_consts[1],
7961 self.intrinsics.i32_consts[2],
7962 self.intrinsics.i32_consts[3],
7963 ]),
7964 "",
7965 ));
7966 let res = err!(
7967 self.builder
7968 .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7969 );
7970 let res = err!(
7971 self.builder
7972 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7973 );
7974 self.state.push1(res);
7975 }
7976 Operator::I32x4ExtendHighI16x8U => {
7977 let (v, i) = self.state.pop1_extra()?;
7978 let (v, _) = self.v128_into_i16x8(v, i)?;
7979 let low = err!(self.builder.build_shuffle_vector(
7980 v,
7981 v.get_type().get_undef(),
7982 VectorType::const_vector(&[
7983 self.intrinsics.i32_consts[4],
7984 self.intrinsics.i32_consts[5],
7985 self.intrinsics.i32_consts[6],
7986 self.intrinsics.i32_consts[7],
7987 ]),
7988 "",
7989 ));
7990 let res = err!(
7991 self.builder
7992 .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7993 );
7994 let res = err!(
7995 self.builder
7996 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7997 );
7998 self.state.push1(res);
7999 }
8000 Operator::I64x2ExtendLowI32x4U
8001 | Operator::I64x2ExtendLowI32x4S
8002 | Operator::I64x2ExtendHighI32x4U
8003 | Operator::I64x2ExtendHighI32x4S => {
8004 let extend = match op {
8005 Operator::I64x2ExtendLowI32x4U | Operator::I64x2ExtendHighI32x4U => {
8006 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8007 }
8008 Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendHighI32x4S => {
8009 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8010 }
8011 _ => unreachable!("Unhandled inner case"),
8012 };
8013 let indices = match op {
8014 Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendLowI32x4U => {
8015 [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[1]]
8016 }
8017 Operator::I64x2ExtendHighI32x4S | Operator::I64x2ExtendHighI32x4U => {
8018 [self.intrinsics.i32_consts[2], self.intrinsics.i32_consts[3]]
8019 }
8020 _ => unreachable!("Unhandled inner case"),
8021 };
8022 let (v, i) = self.state.pop1_extra()?;
8023 let (v, _) = self.v128_into_i32x4(v, i)?;
8024 let low = err!(self.builder.build_shuffle_vector(
8025 v,
8026 v.get_type().get_undef(),
8027 VectorType::const_vector(&indices),
8028 "",
8029 ));
8030 let res = err!(extend(self, low));
8031 let res = err!(
8032 self.builder
8033 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8034 );
8035 self.state.push1(res);
8036 }
8037 Operator::I8x16NarrowI16x8S => {
8038 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8039 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
8040 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
8041 let min = self.intrinsics.i16_ty.const_int(0xff80, false);
8042 let max = self.intrinsics.i16_ty.const_int(0x007f, false);
8043 let min = VectorType::const_vector(&[min; 8]);
8044 let max = VectorType::const_vector(&[max; 8]);
8045 let apply_min_clamp_v1 =
8046 err!(
8047 self.builder
8048 .build_int_compare(IntPredicate::SLT, v1, min, "")
8049 );
8050 let apply_max_clamp_v1 =
8051 err!(
8052 self.builder
8053 .build_int_compare(IntPredicate::SGT, v1, max, "")
8054 );
8055 let apply_min_clamp_v2 =
8056 err!(
8057 self.builder
8058 .build_int_compare(IntPredicate::SLT, v2, min, "")
8059 );
8060 let apply_max_clamp_v2 =
8061 err!(
8062 self.builder
8063 .build_int_compare(IntPredicate::SGT, v2, max, "")
8064 );
8065 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8066 .into_vector_value();
8067 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8068 .into_vector_value();
8069 let v1 = err!(self.builder.build_int_truncate(
8070 v1,
8071 self.intrinsics.i8_ty.vec_type(8),
8072 ""
8073 ));
8074 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8075 .into_vector_value();
8076 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8077 .into_vector_value();
8078 let v2 = err!(self.builder.build_int_truncate(
8079 v2,
8080 self.intrinsics.i8_ty.vec_type(8),
8081 ""
8082 ));
8083 let res = err!(self.builder.build_shuffle_vector(
8084 v1,
8085 v2,
8086 VectorType::const_vector(&[
8087 self.intrinsics.i32_consts[0],
8088 self.intrinsics.i32_consts[1],
8089 self.intrinsics.i32_consts[2],
8090 self.intrinsics.i32_consts[3],
8091 self.intrinsics.i32_consts[4],
8092 self.intrinsics.i32_consts[5],
8093 self.intrinsics.i32_consts[6],
8094 self.intrinsics.i32_consts[7],
8095 self.intrinsics.i32_consts[8],
8096 self.intrinsics.i32_consts[9],
8097 self.intrinsics.i32_consts[10],
8098 self.intrinsics.i32_consts[11],
8099 self.intrinsics.i32_consts[12],
8100 self.intrinsics.i32_consts[13],
8101 self.intrinsics.i32_consts[14],
8102 self.intrinsics.i32_consts[15],
8103 ]),
8104 "",
8105 ));
8106 let res = err!(
8107 self.builder
8108 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8109 );
8110 self.state.push1(res);
8111 }
8112 Operator::I8x16NarrowI16x8U => {
8113 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8114 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
8115 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
8116 let min = self.intrinsics.i16x8_ty.const_zero();
8117 let max = self.intrinsics.i16_ty.const_int(0x00ff, false);
8118 let max = VectorType::const_vector(&[max; 8]);
8119 let apply_min_clamp_v1 =
8120 err!(
8121 self.builder
8122 .build_int_compare(IntPredicate::SLT, v1, min, "")
8123 );
8124 let apply_max_clamp_v1 =
8125 err!(
8126 self.builder
8127 .build_int_compare(IntPredicate::SGT, v1, max, "")
8128 );
8129 let apply_min_clamp_v2 =
8130 err!(
8131 self.builder
8132 .build_int_compare(IntPredicate::SLT, v2, min, "")
8133 );
8134 let apply_max_clamp_v2 =
8135 err!(
8136 self.builder
8137 .build_int_compare(IntPredicate::SGT, v2, max, "")
8138 );
8139 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8140 .into_vector_value();
8141 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8142 .into_vector_value();
8143 let v1 = err!(self.builder.build_int_truncate(
8144 v1,
8145 self.intrinsics.i8_ty.vec_type(8),
8146 ""
8147 ));
8148 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8149 .into_vector_value();
8150 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8151 .into_vector_value();
8152 let v2 = err!(self.builder.build_int_truncate(
8153 v2,
8154 self.intrinsics.i8_ty.vec_type(8),
8155 ""
8156 ));
8157 let res = err!(self.builder.build_shuffle_vector(
8158 v1,
8159 v2,
8160 VectorType::const_vector(&[
8161 self.intrinsics.i32_consts[0],
8162 self.intrinsics.i32_consts[1],
8163 self.intrinsics.i32_consts[2],
8164 self.intrinsics.i32_consts[3],
8165 self.intrinsics.i32_consts[4],
8166 self.intrinsics.i32_consts[5],
8167 self.intrinsics.i32_consts[6],
8168 self.intrinsics.i32_consts[7],
8169 self.intrinsics.i32_consts[8],
8170 self.intrinsics.i32_consts[9],
8171 self.intrinsics.i32_consts[10],
8172 self.intrinsics.i32_consts[11],
8173 self.intrinsics.i32_consts[12],
8174 self.intrinsics.i32_consts[13],
8175 self.intrinsics.i32_consts[14],
8176 self.intrinsics.i32_consts[15],
8177 ]),
8178 "",
8179 ));
8180 let res = err!(
8181 self.builder
8182 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8183 );
8184 self.state.push1(res);
8185 }
8186 Operator::I16x8NarrowI32x4S => {
8187 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8188 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
8189 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
8190 let min = self.intrinsics.i32_ty.const_int(0xffff8000, false);
8191 let max = self.intrinsics.i32_ty.const_int(0x00007fff, false);
8192 let min = VectorType::const_vector(&[min; 4]);
8193 let max = VectorType::const_vector(&[max; 4]);
8194 let apply_min_clamp_v1 =
8195 err!(
8196 self.builder
8197 .build_int_compare(IntPredicate::SLT, v1, min, "")
8198 );
8199 let apply_max_clamp_v1 =
8200 err!(
8201 self.builder
8202 .build_int_compare(IntPredicate::SGT, v1, max, "")
8203 );
8204 let apply_min_clamp_v2 =
8205 err!(
8206 self.builder
8207 .build_int_compare(IntPredicate::SLT, v2, min, "")
8208 );
8209 let apply_max_clamp_v2 =
8210 err!(
8211 self.builder
8212 .build_int_compare(IntPredicate::SGT, v2, max, "")
8213 );
8214 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8215 .into_vector_value();
8216 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8217 .into_vector_value();
8218 let v1 = err!(self.builder.build_int_truncate(
8219 v1,
8220 self.intrinsics.i16_ty.vec_type(4),
8221 ""
8222 ));
8223 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8224 .into_vector_value();
8225 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8226 .into_vector_value();
8227 let v2 = err!(self.builder.build_int_truncate(
8228 v2,
8229 self.intrinsics.i16_ty.vec_type(4),
8230 ""
8231 ));
8232 let res = err!(self.builder.build_shuffle_vector(
8233 v1,
8234 v2,
8235 VectorType::const_vector(&[
8236 self.intrinsics.i32_consts[0],
8237 self.intrinsics.i32_consts[1],
8238 self.intrinsics.i32_consts[2],
8239 self.intrinsics.i32_consts[3],
8240 self.intrinsics.i32_consts[4],
8241 self.intrinsics.i32_consts[5],
8242 self.intrinsics.i32_consts[6],
8243 self.intrinsics.i32_consts[7],
8244 ]),
8245 "",
8246 ));
8247 let res = err!(
8248 self.builder
8249 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8250 );
8251 self.state.push1(res);
8252 }
8253 Operator::I16x8NarrowI32x4U => {
8254 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
8255 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
8256 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
8257 let min = self.intrinsics.i32x4_ty.const_zero();
8258 let max = self.intrinsics.i32_ty.const_int(0xffff, false);
8259 let max = VectorType::const_vector(&[max; 4]);
8260 let apply_min_clamp_v1 =
8261 err!(
8262 self.builder
8263 .build_int_compare(IntPredicate::SLT, v1, min, "")
8264 );
8265 let apply_max_clamp_v1 =
8266 err!(
8267 self.builder
8268 .build_int_compare(IntPredicate::SGT, v1, max, "")
8269 );
8270 let apply_min_clamp_v2 =
8271 err!(
8272 self.builder
8273 .build_int_compare(IntPredicate::SLT, v2, min, "")
8274 );
8275 let apply_max_clamp_v2 =
8276 err!(
8277 self.builder
8278 .build_int_compare(IntPredicate::SGT, v2, max, "")
8279 );
8280 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
8281 .into_vector_value();
8282 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
8283 .into_vector_value();
8284 let v1 = err!(self.builder.build_int_truncate(
8285 v1,
8286 self.intrinsics.i16_ty.vec_type(4),
8287 ""
8288 ));
8289 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
8290 .into_vector_value();
8291 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
8292 .into_vector_value();
8293 let v2 = err!(self.builder.build_int_truncate(
8294 v2,
8295 self.intrinsics.i16_ty.vec_type(4),
8296 ""
8297 ));
8298 let res = err!(self.builder.build_shuffle_vector(
8299 v1,
8300 v2,
8301 VectorType::const_vector(&[
8302 self.intrinsics.i32_consts[0],
8303 self.intrinsics.i32_consts[1],
8304 self.intrinsics.i32_consts[2],
8305 self.intrinsics.i32_consts[3],
8306 self.intrinsics.i32_consts[4],
8307 self.intrinsics.i32_consts[5],
8308 self.intrinsics.i32_consts[6],
8309 self.intrinsics.i32_consts[7],
8310 ]),
8311 "",
8312 ));
8313 let res = err!(
8314 self.builder
8315 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8316 );
8317 self.state.push1(res);
8318 }
8319 Operator::I32x4TruncSatF32x4S => {
8320 let (v, i) = self.state.pop1_extra()?;
8321 let v = self.apply_pending_canonicalization(v, i)?;
8322 let v = v.into_int_value();
8323 let res = self.trunc_sat_into_int(
8324 self.intrinsics.f32x4_ty,
8325 self.intrinsics.i32x4_ty,
8326 LEF32_GEQ_I32_MIN,
8327 GEF32_LEQ_I32_MAX,
8328 i32::MIN as u64,
8329 i32::MAX as u64,
8330 v,
8331 )?;
8332 self.state.push1(res);
8333 }
8334 Operator::I32x4TruncSatF32x4U => {
8335 let (v, i) = self.state.pop1_extra()?;
8336 let v = self.apply_pending_canonicalization(v, i)?;
8337 let v = v.into_int_value();
8338 let res = self.trunc_sat_into_int(
8339 self.intrinsics.f32x4_ty,
8340 self.intrinsics.i32x4_ty,
8341 LEF32_GEQ_U32_MIN,
8342 GEF32_LEQ_U32_MAX,
8343 u32::MIN as u64,
8344 u32::MAX as u64,
8345 v,
8346 )?;
8347 self.state.push1(res);
8348 }
8349 Operator::I32x4TruncSatF64x2SZero | Operator::I32x4TruncSatF64x2UZero => {
8350 let ((min, max), (cmp_min, cmp_max)) = match op {
8351 Operator::I32x4TruncSatF64x2SZero => (
8352 (i32::MIN as u64, i32::MAX as u64),
8353 (LEF64_GEQ_I32_MIN, GEF64_LEQ_I32_MAX),
8354 ),
8355 Operator::I32x4TruncSatF64x2UZero => (
8356 (u32::MIN as u64, u32::MAX as u64),
8357 (LEF64_GEQ_U32_MIN, GEF64_LEQ_U32_MAX),
8358 ),
8359 _ => unreachable!("Unhandled internal variant"),
8360 };
8361 let (v, i) = self.state.pop1_extra()?;
8362 let v = self.apply_pending_canonicalization(v, i)?;
8363 let v = v.into_int_value();
8364 let res = self.trunc_sat(
8365 self.intrinsics.f64x2_ty,
8366 self.intrinsics.i32_ty.vec_type(2),
8367 cmp_min,
8368 cmp_max,
8369 min,
8370 max,
8371 v,
8372 )?;
8373
8374 let zero = self.intrinsics.i32_consts[0];
8375 let zeros = VectorType::const_vector(&[zero; 2]);
8376 let res = err!(self.builder.build_shuffle_vector(
8377 res,
8378 zeros,
8379 VectorType::const_vector(&[
8380 self.intrinsics.i32_consts[0],
8381 self.intrinsics.i32_consts[1],
8382 self.intrinsics.i32_consts[2],
8383 self.intrinsics.i32_consts[3],
8384 ]),
8385 "",
8386 ));
8387 let res = err!(
8388 self.builder
8389 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8390 );
8391 self.state.push1(res);
8392 }
8393 Operator::I32TruncF32S => {
8424 let v1 = self.state.pop1()?.into_float_value();
8425 self.trap_if_not_representable_as_int(
8426 0xcf000000, 0x4effffff, v1,
8429 )?;
8430 let res = err!(self.builder.build_float_to_signed_int(
8431 v1,
8432 self.intrinsics.i32_ty,
8433 ""
8434 ));
8435 self.state.push1(res);
8436 }
8437 Operator::I32TruncF64S => {
8438 let v1 = self.state.pop1()?.into_float_value();
8439 self.trap_if_not_representable_as_int(
8440 0xc1e00000001fffff, 0x41dfffffffffffff, v1,
8443 )?;
8444 let res = err!(self.builder.build_float_to_signed_int(
8445 v1,
8446 self.intrinsics.i32_ty,
8447 ""
8448 ));
8449 self.state.push1(res);
8450 }
8451 Operator::I32TruncSatF32S => {
8452 let (v, i) = self.state.pop1_extra()?;
8453 let v = self.apply_pending_canonicalization(v, i)?;
8454 let v = v.into_float_value();
8455 let res = self.trunc_sat_scalar(
8456 self.intrinsics.i32_ty,
8457 LEF32_GEQ_I32_MIN,
8458 GEF32_LEQ_I32_MAX,
8459 i32::MIN as u32 as u64,
8460 i32::MAX as u32 as u64,
8461 v,
8462 )?;
8463 self.state.push1(res);
8464 }
8465 Operator::I32TruncSatF64S => {
8466 let (v, i) = self.state.pop1_extra()?;
8467 let v = self.apply_pending_canonicalization(v, i)?;
8468 let v = v.into_float_value();
8469 let res = self.trunc_sat_scalar(
8470 self.intrinsics.i32_ty,
8471 LEF64_GEQ_I32_MIN,
8472 GEF64_LEQ_I32_MAX,
8473 i32::MIN as u64,
8474 i32::MAX as u64,
8475 v,
8476 )?;
8477 self.state.push1(res);
8478 }
8479 Operator::I64TruncF32S => {
8480 let v1 = self.state.pop1()?.into_float_value();
8481 self.trap_if_not_representable_as_int(
8482 0xdf000000, 0x5effffff, v1,
8485 )?;
8486 let res = err!(self.builder.build_float_to_signed_int(
8487 v1,
8488 self.intrinsics.i64_ty,
8489 ""
8490 ));
8491 self.state.push1(res);
8492 }
8493 Operator::I64TruncF64S => {
8494 let v1 = self.state.pop1()?.into_float_value();
8495 self.trap_if_not_representable_as_int(
8496 0xc3e0000000000000, 0x43dfffffffffffff, v1,
8499 )?;
8500 let res = err!(self.builder.build_float_to_signed_int(
8501 v1,
8502 self.intrinsics.i64_ty,
8503 ""
8504 ));
8505 self.state.push1(res);
8506 }
8507 Operator::I64TruncSatF32S => {
8508 let (v, i) = self.state.pop1_extra()?;
8509 let v = self.apply_pending_canonicalization(v, i)?;
8510 let v = v.into_float_value();
8511 let res = self.trunc_sat_scalar(
8512 self.intrinsics.i64_ty,
8513 LEF32_GEQ_I64_MIN,
8514 GEF32_LEQ_I64_MAX,
8515 i64::MIN as u64,
8516 i64::MAX as u64,
8517 v,
8518 )?;
8519 self.state.push1(res);
8520 }
8521 Operator::I64TruncSatF64S => {
8522 let (v, i) = self.state.pop1_extra()?;
8523 let v = self.apply_pending_canonicalization(v, i)?;
8524 let v = v.into_float_value();
8525 let res = self.trunc_sat_scalar(
8526 self.intrinsics.i64_ty,
8527 LEF64_GEQ_I64_MIN,
8528 GEF64_LEQ_I64_MAX,
8529 i64::MIN as u64,
8530 i64::MAX as u64,
8531 v,
8532 )?;
8533 self.state.push1(res);
8534 }
8535 Operator::I32TruncF32U => {
8536 let v1 = self.state.pop1()?.into_float_value();
8537 self.trap_if_not_representable_as_int(
8538 0xbf7fffff, 0x4f7fffff, v1,
8541 )?;
8542 let res = err!(self.builder.build_float_to_unsigned_int(
8543 v1,
8544 self.intrinsics.i32_ty,
8545 ""
8546 ));
8547 self.state.push1(res);
8548 }
8549 Operator::I32TruncF64U => {
8550 let v1 = self.state.pop1()?.into_float_value();
8551 self.trap_if_not_representable_as_int(
8552 0xbfefffffffffffff, 0x41efffffffffffff, v1,
8555 )?;
8556 let res = err!(self.builder.build_float_to_unsigned_int(
8557 v1,
8558 self.intrinsics.i32_ty,
8559 ""
8560 ));
8561 self.state.push1(res);
8562 }
8563 Operator::I32TruncSatF32U => {
8564 let (v, i) = self.state.pop1_extra()?;
8565 let v = self.apply_pending_canonicalization(v, i)?;
8566 let v = v.into_float_value();
8567 let res = self.trunc_sat_scalar(
8568 self.intrinsics.i32_ty,
8569 LEF32_GEQ_U32_MIN,
8570 GEF32_LEQ_U32_MAX,
8571 u32::MIN as u64,
8572 u32::MAX as u64,
8573 v,
8574 )?;
8575 self.state.push1(res);
8576 }
8577 Operator::I32TruncSatF64U => {
8578 let (v, i) = self.state.pop1_extra()?;
8579 let v = self.apply_pending_canonicalization(v, i)?;
8580 let v = v.into_float_value();
8581 let res = self.trunc_sat_scalar(
8582 self.intrinsics.i32_ty,
8583 LEF64_GEQ_U32_MIN,
8584 GEF64_LEQ_U32_MAX,
8585 u32::MIN as u64,
8586 u32::MAX as u64,
8587 v,
8588 )?;
8589 self.state.push1(res);
8590 }
8591 Operator::I64TruncF32U => {
8592 let v1 = self.state.pop1()?.into_float_value();
8593 self.trap_if_not_representable_as_int(
8594 0xbf7fffff, 0x5f7fffff, v1,
8597 )?;
8598 let res = err!(self.builder.build_float_to_unsigned_int(
8599 v1,
8600 self.intrinsics.i64_ty,
8601 ""
8602 ));
8603 self.state.push1(res);
8604 }
8605 Operator::I64TruncF64U => {
8606 let v1 = self.state.pop1()?.into_float_value();
8607 self.trap_if_not_representable_as_int(
8608 0xbfefffffffffffff, 0x43efffffffffffff, v1,
8611 )?;
8612 let res = err!(self.builder.build_float_to_unsigned_int(
8613 v1,
8614 self.intrinsics.i64_ty,
8615 ""
8616 ));
8617 self.state.push1(res);
8618 }
8619 Operator::I64TruncSatF32U => {
8620 let (v, i) = self.state.pop1_extra()?;
8621 let v = self.apply_pending_canonicalization(v, i)?;
8622 let v = v.into_float_value();
8623 let res = self.trunc_sat_scalar(
8624 self.intrinsics.i64_ty,
8625 LEF32_GEQ_U64_MIN,
8626 GEF32_LEQ_U64_MAX,
8627 u64::MIN,
8628 u64::MAX,
8629 v,
8630 )?;
8631 self.state.push1(res);
8632 }
8633 Operator::I64TruncSatF64U => {
8634 let (v, i) = self.state.pop1_extra()?;
8635 let v = self.apply_pending_canonicalization(v, i)?;
8636 let v = v.into_float_value();
8637 let res = self.trunc_sat_scalar(
8638 self.intrinsics.i64_ty,
8639 LEF64_GEQ_U64_MIN,
8640 GEF64_LEQ_U64_MAX,
8641 u64::MIN,
8642 u64::MAX,
8643 v,
8644 )?;
8645 self.state.push1(res);
8646 }
8647 Operator::F32DemoteF64 => {
8648 let v = self.state.pop1()?;
8649 let v = v.into_float_value();
8650 let res = err!(self.builder.build_call(
8651 self.intrinsics.fptrunc_f64,
8652 &[
8653 v.into(),
8654 self.intrinsics.fp_rounding_md,
8655 self.intrinsics.fp_exception_md,
8656 ],
8657 "",
8658 ))
8659 .try_as_basic_value()
8660 .left()
8661 .unwrap();
8662 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8663 }
8664 Operator::F64PromoteF32 => {
8665 let v = self.state.pop1()?;
8666 let v = v.into_float_value();
8667 let res = err!(self.builder.build_call(
8668 self.intrinsics.fpext_f32,
8669 &[v.into(), self.intrinsics.fp_exception_md],
8670 "",
8671 ))
8672 .try_as_basic_value()
8673 .left()
8674 .unwrap();
8675 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8676 }
8677 Operator::F32ConvertI32S | Operator::F32ConvertI64S => {
8678 let (v, i) = self.state.pop1_extra()?;
8679 let v = self.apply_pending_canonicalization(v, i)?;
8680 let v = v.into_int_value();
8681 let res = err!(self.builder.build_signed_int_to_float(
8682 v,
8683 self.intrinsics.f32_ty,
8684 ""
8685 ));
8686 self.state.push1(res);
8687 }
8688 Operator::F64ConvertI32S | Operator::F64ConvertI64S => {
8689 let (v, i) = self.state.pop1_extra()?;
8690 let v = self.apply_pending_canonicalization(v, i)?;
8691 let v = v.into_int_value();
8692 let res = err!(self.builder.build_signed_int_to_float(
8693 v,
8694 self.intrinsics.f64_ty,
8695 ""
8696 ));
8697 self.state.push1(res);
8698 }
8699 Operator::F32ConvertI32U | Operator::F32ConvertI64U => {
8700 let (v, i) = self.state.pop1_extra()?;
8701 let v = self.apply_pending_canonicalization(v, i)?;
8702 let v = v.into_int_value();
8703 let res = err!(self.builder.build_unsigned_int_to_float(
8704 v,
8705 self.intrinsics.f32_ty,
8706 ""
8707 ));
8708 self.state.push1(res);
8709 }
8710 Operator::F64ConvertI32U | Operator::F64ConvertI64U => {
8711 let (v, i) = self.state.pop1_extra()?;
8712 let v = self.apply_pending_canonicalization(v, i)?;
8713 let v = v.into_int_value();
8714 let res = err!(self.builder.build_unsigned_int_to_float(
8715 v,
8716 self.intrinsics.f64_ty,
8717 ""
8718 ));
8719 self.state.push1(res);
8720 }
8721 Operator::F32x4ConvertI32x4S => {
8722 let v = self.state.pop1()?;
8723 let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8724 .into_vector_value();
8725 let res = err!(self.builder.build_signed_int_to_float(
8726 v,
8727 self.intrinsics.f32x4_ty,
8728 ""
8729 ));
8730 let res = err!(
8731 self.builder
8732 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8733 );
8734 self.state.push1(res);
8735 }
8736 Operator::F32x4ConvertI32x4U => {
8737 let v = self.state.pop1()?;
8738 let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8739 .into_vector_value();
8740 let res = err!(self.builder.build_unsigned_int_to_float(
8741 v,
8742 self.intrinsics.f32x4_ty,
8743 ""
8744 ));
8745 let res = err!(
8746 self.builder
8747 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8748 );
8749 self.state.push1(res);
8750 }
8751 Operator::F64x2ConvertLowI32x4S | Operator::F64x2ConvertLowI32x4U => {
8752 let extend = match op {
8753 Operator::F64x2ConvertLowI32x4U => {
8754 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8755 }
8756 Operator::F64x2ConvertLowI32x4S => {
8757 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8758 }
8759 _ => unreachable!("Unhandled inner case"),
8760 };
8761 let (v, i) = self.state.pop1_extra()?;
8762 let (v, _) = self.v128_into_i32x4(v, i)?;
8763 let low = err!(self.builder.build_shuffle_vector(
8764 v,
8765 v.get_type().get_undef(),
8766 VectorType::const_vector(&[
8767 self.intrinsics.i32_consts[0],
8768 self.intrinsics.i32_consts[1],
8769 ]),
8770 "",
8771 ));
8772 let res = err!(extend(self, low));
8773 let res = err!(self.builder.build_signed_int_to_float(
8774 res,
8775 self.intrinsics.f64x2_ty,
8776 ""
8777 ));
8778 let res = err!(
8779 self.builder
8780 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8781 );
8782 self.state.push1(res);
8783 }
8784 Operator::F64x2PromoteLowF32x4 => {
8785 let (v, i) = self.state.pop1_extra()?;
8786 let (v, _) = self.v128_into_f32x4(v, i)?;
8787 let low = err!(self.builder.build_shuffle_vector(
8788 v,
8789 v.get_type().get_undef(),
8790 VectorType::const_vector(&[
8791 self.intrinsics.i32_consts[0],
8792 self.intrinsics.i32_consts[1],
8793 ]),
8794 "",
8795 ));
8796 let res = err!(
8797 self.builder
8798 .build_float_ext(low, self.intrinsics.f64x2_ty, "")
8799 );
8800 let res = err!(
8801 self.builder
8802 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8803 );
8804 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8805 }
8806 Operator::F32x4DemoteF64x2Zero => {
8807 let (v, i) = self.state.pop1_extra()?;
8808 let (v, _) = self.v128_into_f64x2(v, i)?;
8809 let f32x2_ty = self.intrinsics.f32_ty.vec_type(2);
8810 let res = err!(self.builder.build_float_trunc(v, f32x2_ty, ""));
8811 let zeros = f32x2_ty.const_zero();
8812 let res = err!(self.builder.build_shuffle_vector(
8813 res,
8814 zeros,
8815 VectorType::const_vector(&[
8816 self.intrinsics.i32_consts[0],
8817 self.intrinsics.i32_consts[1],
8818 self.intrinsics.i32_consts[2],
8819 self.intrinsics.i32_consts[3],
8820 ]),
8821 "",
8822 ));
8823 let res = err!(
8824 self.builder
8825 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8826 );
8827 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8828 }
8829 Operator::I32ReinterpretF32 => {
8854 let (v, i) = self.state.pop1_extra()?;
8855 let v = self.apply_pending_canonicalization(v, i)?;
8856 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i32_ty, ""));
8857 self.state.push1_extra(ret, ExtraInfo::arithmetic_f32());
8858 }
8859 Operator::I64ReinterpretF64 => {
8860 let (v, i) = self.state.pop1_extra()?;
8861 let v = self.apply_pending_canonicalization(v, i)?;
8862 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i64_ty, ""));
8863 self.state.push1_extra(ret, ExtraInfo::arithmetic_f64());
8864 }
8865 Operator::F32ReinterpretI32 => {
8866 let (v, i) = self.state.pop1_extra()?;
8867 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f32_ty, ""));
8868 self.state.push1_extra(ret, i);
8869 }
8870 Operator::F64ReinterpretI64 => {
8871 let (v, i) = self.state.pop1_extra()?;
8872 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f64_ty, ""));
8873 self.state.push1_extra(ret, i);
8874 }
8875
8876 Operator::I32Extend8S => {
8881 let value = self.state.pop1()?.into_int_value();
8882 let narrow_value = err!(self.builder.build_int_truncate(
8883 value,
8884 self.intrinsics.i8_ty,
8885 ""
8886 ));
8887 let extended_value = err!(self.builder.build_int_s_extend(
8888 narrow_value,
8889 self.intrinsics.i32_ty,
8890 ""
8891 ));
8892 self.state.push1(extended_value);
8893 }
8894 Operator::I32Extend16S => {
8895 let value = self.state.pop1()?.into_int_value();
8896 let narrow_value = err!(self.builder.build_int_truncate(
8897 value,
8898 self.intrinsics.i16_ty,
8899 ""
8900 ));
8901 let extended_value = err!(self.builder.build_int_s_extend(
8902 narrow_value,
8903 self.intrinsics.i32_ty,
8904 ""
8905 ));
8906 self.state.push1(extended_value);
8907 }
8908 Operator::I64Extend8S => {
8909 let value = self.state.pop1()?.into_int_value();
8910 let narrow_value = err!(self.builder.build_int_truncate(
8911 value,
8912 self.intrinsics.i8_ty,
8913 ""
8914 ));
8915 let extended_value = err!(self.builder.build_int_s_extend(
8916 narrow_value,
8917 self.intrinsics.i64_ty,
8918 ""
8919 ));
8920 self.state.push1(extended_value);
8921 }
8922 Operator::I64Extend16S => {
8923 let value = self.state.pop1()?.into_int_value();
8924 let narrow_value = err!(self.builder.build_int_truncate(
8925 value,
8926 self.intrinsics.i16_ty,
8927 ""
8928 ));
8929 let extended_value = err!(self.builder.build_int_s_extend(
8930 narrow_value,
8931 self.intrinsics.i64_ty,
8932 ""
8933 ));
8934 self.state.push1(extended_value);
8935 }
8936 Operator::I64Extend32S => {
8937 let value = self.state.pop1()?.into_int_value();
8938 let narrow_value = err!(self.builder.build_int_truncate(
8939 value,
8940 self.intrinsics.i32_ty,
8941 ""
8942 ));
8943 let extended_value = err!(self.builder.build_int_s_extend(
8944 narrow_value,
8945 self.intrinsics.i64_ty,
8946 ""
8947 ));
8948 self.state.push1(extended_value);
8949 }
8950
8951 Operator::I32Load { ref memarg } => {
8956 let offset = self.state.pop1()?.into_int_value();
8957 let memory_index = MemoryIndex::from_u32(0);
8958 let effective_address = self.resolve_memory_ptr(
8959 memory_index,
8960 memarg,
8961 self.intrinsics.ptr_ty,
8962 offset,
8963 4,
8964 )?;
8965 let result = err!(self.builder.build_load(
8966 self.intrinsics.i32_ty,
8967 effective_address,
8968 ""
8969 ));
8970 self.annotate_user_memaccess(
8971 memory_index,
8972 memarg,
8973 1,
8974 result.as_instruction_value().unwrap(),
8975 )?;
8976 self.state.push1(result);
8977 }
8978 Operator::I64Load { ref memarg } => {
8979 let offset = self.state.pop1()?.into_int_value();
8980 let memory_index = MemoryIndex::from_u32(0);
8981 let effective_address = self.resolve_memory_ptr(
8982 memory_index,
8983 memarg,
8984 self.intrinsics.ptr_ty,
8985 offset,
8986 8,
8987 )?;
8988 let result = err!(self.builder.build_load(
8989 self.intrinsics.i64_ty,
8990 effective_address,
8991 ""
8992 ));
8993 self.annotate_user_memaccess(
8994 memory_index,
8995 memarg,
8996 1,
8997 result.as_instruction_value().unwrap(),
8998 )?;
8999 self.state.push1(result);
9000 }
9001 Operator::F32Load { ref memarg } => {
9002 let offset = self.state.pop1()?.into_int_value();
9003 let memory_index = MemoryIndex::from_u32(0);
9004 let effective_address = self.resolve_memory_ptr(
9005 memory_index,
9006 memarg,
9007 self.intrinsics.ptr_ty,
9008 offset,
9009 4,
9010 )?;
9011 let result = err!(self.builder.build_load(
9012 self.intrinsics.f32_ty,
9013 effective_address,
9014 ""
9015 ));
9016 self.annotate_user_memaccess(
9017 memory_index,
9018 memarg,
9019 1,
9020 result.as_instruction_value().unwrap(),
9021 )?;
9022 self.state.push1(result);
9023 }
9024 Operator::F64Load { ref memarg } => {
9025 let offset = self.state.pop1()?.into_int_value();
9026 let memory_index = MemoryIndex::from_u32(0);
9027 let effective_address = self.resolve_memory_ptr(
9028 memory_index,
9029 memarg,
9030 self.intrinsics.ptr_ty,
9031 offset,
9032 8,
9033 )?;
9034 let result = err!(self.builder.build_load(
9035 self.intrinsics.f64_ty,
9036 effective_address,
9037 ""
9038 ));
9039 self.annotate_user_memaccess(
9040 memory_index,
9041 memarg,
9042 1,
9043 result.as_instruction_value().unwrap(),
9044 )?;
9045 self.state.push1(result);
9046 }
9047 Operator::V128Load { ref memarg } => {
9048 let offset = self.state.pop1()?.into_int_value();
9049 let memory_index = MemoryIndex::from_u32(0);
9050 let effective_address = self.resolve_memory_ptr(
9051 memory_index,
9052 memarg,
9053 self.intrinsics.ptr_ty,
9054 offset,
9055 16,
9056 )?;
9057 let result = err!(self.builder.build_load(
9058 self.intrinsics.i128_ty,
9059 effective_address,
9060 ""
9061 ));
9062 self.annotate_user_memaccess(
9063 memory_index,
9064 memarg,
9065 1,
9066 result.as_instruction_value().unwrap(),
9067 )?;
9068 self.state.push1(result);
9069 }
9070 Operator::V128Load8Lane { ref memarg, lane } => {
9071 let (v, i) = self.state.pop1_extra()?;
9072 let (v, _i) = self.v128_into_i8x16(v, i)?;
9073 let offset = self.state.pop1()?.into_int_value();
9074 let memory_index = MemoryIndex::from_u32(memarg.memory);
9075 let effective_address = self.resolve_memory_ptr(
9076 memory_index,
9077 memarg,
9078 self.intrinsics.ptr_ty,
9079 offset,
9080 1,
9081 )?;
9082 let element = err!(self.builder.build_load(
9083 self.intrinsics.i8_ty,
9084 effective_address,
9085 ""
9086 ));
9087 self.annotate_user_memaccess(
9088 memory_index,
9089 memarg,
9090 1,
9091 element.as_instruction_value().unwrap(),
9092 )?;
9093 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9094 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9095 let res = err!(
9096 self.builder
9097 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9098 );
9099 self.state.push1(res);
9100 }
9101 Operator::V128Load16Lane { ref memarg, lane } => {
9102 let (v, i) = self.state.pop1_extra()?;
9103 let (v, i) = self.v128_into_i16x8(v, i)?;
9104 let offset = self.state.pop1()?.into_int_value();
9105 let memory_index = MemoryIndex::from_u32(memarg.memory);
9106 let effective_address = self.resolve_memory_ptr(
9107 memory_index,
9108 memarg,
9109 self.intrinsics.ptr_ty,
9110 offset,
9111 2,
9112 )?;
9113 let element = err!(self.builder.build_load(
9114 self.intrinsics.i16_ty,
9115 effective_address,
9116 ""
9117 ));
9118 self.annotate_user_memaccess(
9119 memory_index,
9120 memarg,
9121 1,
9122 element.as_instruction_value().unwrap(),
9123 )?;
9124 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9125 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9126 let res = err!(
9127 self.builder
9128 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9129 );
9130 self.state.push1_extra(res, i);
9131 }
9132 Operator::V128Load32Lane { ref memarg, lane } => {
9133 let (v, i) = self.state.pop1_extra()?;
9134 let (v, i) = self.v128_into_i32x4(v, i)?;
9135 let offset = self.state.pop1()?.into_int_value();
9136 let memory_index = MemoryIndex::from_u32(memarg.memory);
9137 let effective_address = self.resolve_memory_ptr(
9138 memory_index,
9139 memarg,
9140 self.intrinsics.ptr_ty,
9141 offset,
9142 4,
9143 )?;
9144 let element = err!(self.builder.build_load(
9145 self.intrinsics.i32_ty,
9146 effective_address,
9147 ""
9148 ));
9149 self.annotate_user_memaccess(
9150 memory_index,
9151 memarg,
9152 1,
9153 element.as_instruction_value().unwrap(),
9154 )?;
9155 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9156 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9157 let res = err!(
9158 self.builder
9159 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9160 );
9161 self.state.push1_extra(res, i);
9162 }
9163 Operator::V128Load64Lane { ref memarg, lane } => {
9164 let (v, i) = self.state.pop1_extra()?;
9165 let (v, i) = self.v128_into_i64x2(v, i)?;
9166 let offset = self.state.pop1()?.into_int_value();
9167 let memory_index = MemoryIndex::from_u32(memarg.memory);
9168 let effective_address = self.resolve_memory_ptr(
9169 memory_index,
9170 memarg,
9171 self.intrinsics.ptr_ty,
9172 offset,
9173 8,
9174 )?;
9175 let element = err!(self.builder.build_load(
9176 self.intrinsics.i64_ty,
9177 effective_address,
9178 ""
9179 ));
9180 self.annotate_user_memaccess(
9181 memory_index,
9182 memarg,
9183 1,
9184 element.as_instruction_value().unwrap(),
9185 )?;
9186 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9187 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
9188 let res = err!(
9189 self.builder
9190 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9191 );
9192 self.state.push1_extra(res, i);
9193 }
9194
9195 Operator::I32Store { ref memarg } => {
9196 let value = self.state.pop1()?;
9197 let offset = self.state.pop1()?.into_int_value();
9198 let memory_index = MemoryIndex::from_u32(0);
9199 let effective_address = self.resolve_memory_ptr(
9200 memory_index,
9201 memarg,
9202 self.intrinsics.ptr_ty,
9203 offset,
9204 4,
9205 )?;
9206 let dead_load = err!(self.builder.build_load(
9207 self.intrinsics.i32_ty,
9208 effective_address,
9209 ""
9210 ));
9211 self.annotate_user_memaccess(
9212 memory_index,
9213 memarg,
9214 1,
9215 dead_load.as_instruction_value().unwrap(),
9216 )?;
9217 let store = err!(self.builder.build_store(effective_address, value));
9218 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9219 }
9220 Operator::I64Store { ref memarg } => {
9221 let value = self.state.pop1()?;
9222 let offset = self.state.pop1()?.into_int_value();
9223 let memory_index = MemoryIndex::from_u32(0);
9224 let effective_address = self.resolve_memory_ptr(
9225 memory_index,
9226 memarg,
9227 self.intrinsics.ptr_ty,
9228 offset,
9229 8,
9230 )?;
9231 let dead_load = err!(self.builder.build_load(
9232 self.intrinsics.i64_ty,
9233 effective_address,
9234 ""
9235 ));
9236 self.annotate_user_memaccess(
9237 memory_index,
9238 memarg,
9239 1,
9240 dead_load.as_instruction_value().unwrap(),
9241 )?;
9242 let store = err!(self.builder.build_store(effective_address, value));
9243 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9244 }
9245 Operator::F32Store { ref memarg } => {
9246 let (v, i) = self.state.pop1_extra()?;
9247 let v = self.apply_pending_canonicalization(v, i)?;
9248 let offset = self.state.pop1()?.into_int_value();
9249 let memory_index = MemoryIndex::from_u32(0);
9250 let effective_address = self.resolve_memory_ptr(
9251 memory_index,
9252 memarg,
9253 self.intrinsics.ptr_ty,
9254 offset,
9255 4,
9256 )?;
9257 let dead_load = err!(self.builder.build_load(
9258 self.intrinsics.f32_ty,
9259 effective_address,
9260 ""
9261 ));
9262 self.annotate_user_memaccess(
9263 memory_index,
9264 memarg,
9265 1,
9266 dead_load.as_instruction_value().unwrap(),
9267 )?;
9268 let store = err!(self.builder.build_store(effective_address, v));
9269 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9270 }
9271 Operator::F64Store { ref memarg } => {
9272 let (v, i) = self.state.pop1_extra()?;
9273 let v = self.apply_pending_canonicalization(v, i)?;
9274 let offset = self.state.pop1()?.into_int_value();
9275 let memory_index = MemoryIndex::from_u32(0);
9276 let effective_address = self.resolve_memory_ptr(
9277 memory_index,
9278 memarg,
9279 self.intrinsics.ptr_ty,
9280 offset,
9281 8,
9282 )?;
9283 let dead_load = err!(self.builder.build_load(
9284 self.intrinsics.f64_ty,
9285 effective_address,
9286 ""
9287 ));
9288 self.annotate_user_memaccess(
9289 memory_index,
9290 memarg,
9291 1,
9292 dead_load.as_instruction_value().unwrap(),
9293 )?;
9294 let store = err!(self.builder.build_store(effective_address, v));
9295 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9296 }
9297 Operator::V128Store { ref memarg } => {
9298 let (v, i) = self.state.pop1_extra()?;
9299 let v = self.apply_pending_canonicalization(v, i)?;
9300 let offset = self.state.pop1()?.into_int_value();
9301 let memory_index = MemoryIndex::from_u32(0);
9302 let effective_address = self.resolve_memory_ptr(
9303 memory_index,
9304 memarg,
9305 self.intrinsics.ptr_ty,
9306 offset,
9307 16,
9308 )?;
9309 let dead_load = err!(self.builder.build_load(
9310 self.intrinsics.i128_ty,
9311 effective_address,
9312 ""
9313 ));
9314 self.annotate_user_memaccess(
9315 memory_index,
9316 memarg,
9317 1,
9318 dead_load.as_instruction_value().unwrap(),
9319 )?;
9320 let store = err!(self.builder.build_store(effective_address, v));
9321 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9322 }
9323 Operator::V128Store8Lane { ref memarg, lane } => {
9324 let (v, i) = self.state.pop1_extra()?;
9325 let (v, _i) = self.v128_into_i8x16(v, i)?;
9326 let offset = self.state.pop1()?.into_int_value();
9327 let memory_index = MemoryIndex::from_u32(memarg.memory);
9328
9329 let effective_address = self.resolve_memory_ptr(
9330 memory_index,
9331 memarg,
9332 self.intrinsics.ptr_ty,
9333 offset,
9334 1,
9335 )?;
9336 let dead_load = err!(self.builder.build_load(
9337 self.intrinsics.i8_ty,
9338 effective_address,
9339 ""
9340 ));
9341 self.annotate_user_memaccess(
9342 memory_index,
9343 memarg,
9344 1,
9345 dead_load.as_instruction_value().unwrap(),
9346 )?;
9347 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9348 let val = err!(self.builder.build_extract_element(v, idx, ""));
9349 let store = err!(self.builder.build_store(effective_address, val));
9350 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9351 }
9352 Operator::V128Store16Lane { ref memarg, lane } => {
9353 let (v, i) = self.state.pop1_extra()?;
9354 let (v, _i) = self.v128_into_i16x8(v, i)?;
9355 let offset = self.state.pop1()?.into_int_value();
9356 let memory_index = MemoryIndex::from_u32(memarg.memory);
9357
9358 let effective_address = self.resolve_memory_ptr(
9359 memory_index,
9360 memarg,
9361 self.intrinsics.ptr_ty,
9362 offset,
9363 2,
9364 )?;
9365 let dead_load = err!(self.builder.build_load(
9366 self.intrinsics.i16_ty,
9367 effective_address,
9368 ""
9369 ));
9370 self.annotate_user_memaccess(
9371 memory_index,
9372 memarg,
9373 1,
9374 dead_load.as_instruction_value().unwrap(),
9375 )?;
9376 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9377 let val = err!(self.builder.build_extract_element(v, idx, ""));
9378 let store = err!(self.builder.build_store(effective_address, val));
9379 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9380 }
9381 Operator::V128Store32Lane { ref memarg, lane } => {
9382 let (v, i) = self.state.pop1_extra()?;
9383 let (v, _i) = self.v128_into_i32x4(v, i)?;
9384 let offset = self.state.pop1()?.into_int_value();
9385 let memory_index = MemoryIndex::from_u32(memarg.memory);
9386
9387 let effective_address = self.resolve_memory_ptr(
9388 memory_index,
9389 memarg,
9390 self.intrinsics.ptr_ty,
9391 offset,
9392 4,
9393 )?;
9394 let dead_load = err!(self.builder.build_load(
9395 self.intrinsics.i32_ty,
9396 effective_address,
9397 ""
9398 ));
9399 self.annotate_user_memaccess(
9400 memory_index,
9401 memarg,
9402 1,
9403 dead_load.as_instruction_value().unwrap(),
9404 )?;
9405 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9406 let val = err!(self.builder.build_extract_element(v, idx, ""));
9407 let store = err!(self.builder.build_store(effective_address, val));
9408 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9409 }
9410 Operator::V128Store64Lane { ref memarg, lane } => {
9411 let (v, i) = self.state.pop1_extra()?;
9412 let (v, _i) = self.v128_into_i64x2(v, i)?;
9413 let offset = self.state.pop1()?.into_int_value();
9414 let memory_index = MemoryIndex::from_u32(memarg.memory);
9415
9416 let effective_address = self.resolve_memory_ptr(
9417 memory_index,
9418 memarg,
9419 self.intrinsics.ptr_ty,
9420 offset,
9421 8,
9422 )?;
9423 let dead_load = err!(self.builder.build_load(
9424 self.intrinsics.i64_ty,
9425 effective_address,
9426 ""
9427 ));
9428 self.annotate_user_memaccess(
9429 memory_index,
9430 memarg,
9431 1,
9432 dead_load.as_instruction_value().unwrap(),
9433 )?;
9434 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9435 let val = err!(self.builder.build_extract_element(v, idx, ""));
9436 let store = err!(self.builder.build_store(effective_address, val));
9437 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9438 }
9439 Operator::I32Load8S { ref memarg } => {
9440 let offset = self.state.pop1()?.into_int_value();
9441 let memory_index = MemoryIndex::from_u32(0);
9442 let effective_address = self.resolve_memory_ptr(
9443 memory_index,
9444 memarg,
9445 self.intrinsics.ptr_ty,
9446 offset,
9447 1,
9448 )?;
9449 let narrow_result = err!(self.builder.build_load(
9450 self.intrinsics.i8_ty,
9451 effective_address,
9452 ""
9453 ));
9454 self.annotate_user_memaccess(
9455 memory_index,
9456 memarg,
9457 1,
9458 narrow_result.as_instruction_value().unwrap(),
9459 )?;
9460 let result = err!(self.builder.build_int_s_extend(
9461 narrow_result.into_int_value(),
9462 self.intrinsics.i32_ty,
9463 "",
9464 ));
9465 self.state.push1(result);
9466 }
9467 Operator::I32Load16S { ref memarg } => {
9468 let offset = self.state.pop1()?.into_int_value();
9469 let memory_index = MemoryIndex::from_u32(0);
9470 let effective_address = self.resolve_memory_ptr(
9471 memory_index,
9472 memarg,
9473 self.intrinsics.ptr_ty,
9474 offset,
9475 2,
9476 )?;
9477 let narrow_result = err!(self.builder.build_load(
9478 self.intrinsics.i16_ty,
9479 effective_address,
9480 ""
9481 ));
9482 self.annotate_user_memaccess(
9483 memory_index,
9484 memarg,
9485 1,
9486 narrow_result.as_instruction_value().unwrap(),
9487 )?;
9488 let result = err!(self.builder.build_int_s_extend(
9489 narrow_result.into_int_value(),
9490 self.intrinsics.i32_ty,
9491 "",
9492 ));
9493 self.state.push1(result);
9494 }
9495 Operator::I64Load8S { ref memarg } => {
9496 let offset = self.state.pop1()?.into_int_value();
9497 let memory_index = MemoryIndex::from_u32(0);
9498 let effective_address = self.resolve_memory_ptr(
9499 memory_index,
9500 memarg,
9501 self.intrinsics.ptr_ty,
9502 offset,
9503 1,
9504 )?;
9505 let narrow_result = err!(self.builder.build_load(
9506 self.intrinsics.i8_ty,
9507 effective_address,
9508 ""
9509 ))
9510 .into_int_value();
9511 self.annotate_user_memaccess(
9512 memory_index,
9513 memarg,
9514 1,
9515 narrow_result.as_instruction_value().unwrap(),
9516 )?;
9517 let result = err!(self.builder.build_int_s_extend(
9518 narrow_result,
9519 self.intrinsics.i64_ty,
9520 ""
9521 ));
9522 self.state.push1(result);
9523 }
9524 Operator::I64Load16S { ref memarg } => {
9525 let offset = self.state.pop1()?.into_int_value();
9526 let memory_index = MemoryIndex::from_u32(0);
9527 let effective_address = self.resolve_memory_ptr(
9528 memory_index,
9529 memarg,
9530 self.intrinsics.ptr_ty,
9531 offset,
9532 2,
9533 )?;
9534 let narrow_result = err!(self.builder.build_load(
9535 self.intrinsics.i16_ty,
9536 effective_address,
9537 ""
9538 ))
9539 .into_int_value();
9540 self.annotate_user_memaccess(
9541 memory_index,
9542 memarg,
9543 1,
9544 narrow_result.as_instruction_value().unwrap(),
9545 )?;
9546 let result = err!(self.builder.build_int_s_extend(
9547 narrow_result,
9548 self.intrinsics.i64_ty,
9549 ""
9550 ));
9551 self.state.push1(result);
9552 }
9553 Operator::I64Load32S { ref memarg } => {
9554 let offset = self.state.pop1()?.into_int_value();
9555 let memory_index = MemoryIndex::from_u32(0);
9556 let effective_address = self.resolve_memory_ptr(
9557 memory_index,
9558 memarg,
9559 self.intrinsics.ptr_ty,
9560 offset,
9561 4,
9562 )?;
9563 let narrow_result = err!(self.builder.build_load(
9564 self.intrinsics.i32_ty,
9565 effective_address,
9566 ""
9567 ));
9568 self.annotate_user_memaccess(
9569 memory_index,
9570 memarg,
9571 1,
9572 narrow_result.as_instruction_value().unwrap(),
9573 )?;
9574 let result = err!(self.builder.build_int_s_extend(
9575 narrow_result.into_int_value(),
9576 self.intrinsics.i64_ty,
9577 "",
9578 ));
9579 self.state.push1(result);
9580 }
9581
9582 Operator::I32Load8U { ref memarg } => {
9583 let offset = self.state.pop1()?.into_int_value();
9584 let memory_index = MemoryIndex::from_u32(0);
9585 let effective_address = self.resolve_memory_ptr(
9586 memory_index,
9587 memarg,
9588 self.intrinsics.ptr_ty,
9589 offset,
9590 1,
9591 )?;
9592 let narrow_result = err!(self.builder.build_load(
9593 self.intrinsics.i8_ty,
9594 effective_address,
9595 ""
9596 ));
9597 self.annotate_user_memaccess(
9598 memory_index,
9599 memarg,
9600 1,
9601 narrow_result.as_instruction_value().unwrap(),
9602 )?;
9603 let result = err!(self.builder.build_int_z_extend(
9604 narrow_result.into_int_value(),
9605 self.intrinsics.i32_ty,
9606 "",
9607 ));
9608 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9609 }
9610 Operator::I32Load16U { ref memarg } => {
9611 let offset = self.state.pop1()?.into_int_value();
9612 let memory_index = MemoryIndex::from_u32(0);
9613 let effective_address = self.resolve_memory_ptr(
9614 memory_index,
9615 memarg,
9616 self.intrinsics.ptr_ty,
9617 offset,
9618 2,
9619 )?;
9620 let narrow_result = err!(self.builder.build_load(
9621 self.intrinsics.i16_ty,
9622 effective_address,
9623 ""
9624 ));
9625 self.annotate_user_memaccess(
9626 memory_index,
9627 memarg,
9628 1,
9629 narrow_result.as_instruction_value().unwrap(),
9630 )?;
9631 let result = err!(self.builder.build_int_z_extend(
9632 narrow_result.into_int_value(),
9633 self.intrinsics.i32_ty,
9634 "",
9635 ));
9636 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9637 }
9638 Operator::I64Load8U { ref memarg } => {
9639 let offset = self.state.pop1()?.into_int_value();
9640 let memory_index = MemoryIndex::from_u32(0);
9641 let effective_address = self.resolve_memory_ptr(
9642 memory_index,
9643 memarg,
9644 self.intrinsics.ptr_ty,
9645 offset,
9646 1,
9647 )?;
9648 let narrow_result = err!(self.builder.build_load(
9649 self.intrinsics.i8_ty,
9650 effective_address,
9651 ""
9652 ));
9653 self.annotate_user_memaccess(
9654 memory_index,
9655 memarg,
9656 1,
9657 narrow_result.as_instruction_value().unwrap(),
9658 )?;
9659 let result = err!(self.builder.build_int_z_extend(
9660 narrow_result.into_int_value(),
9661 self.intrinsics.i64_ty,
9662 "",
9663 ));
9664 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9665 }
9666 Operator::I64Load16U { ref memarg } => {
9667 let offset = self.state.pop1()?.into_int_value();
9668 let memory_index = MemoryIndex::from_u32(0);
9669 let effective_address = self.resolve_memory_ptr(
9670 memory_index,
9671 memarg,
9672 self.intrinsics.ptr_ty,
9673 offset,
9674 2,
9675 )?;
9676 let narrow_result = err!(self.builder.build_load(
9677 self.intrinsics.i16_ty,
9678 effective_address,
9679 ""
9680 ));
9681 self.annotate_user_memaccess(
9682 memory_index,
9683 memarg,
9684 1,
9685 narrow_result.as_instruction_value().unwrap(),
9686 )?;
9687 let result = err!(self.builder.build_int_z_extend(
9688 narrow_result.into_int_value(),
9689 self.intrinsics.i64_ty,
9690 "",
9691 ));
9692 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9693 }
9694 Operator::I64Load32U { ref memarg } => {
9695 let offset = self.state.pop1()?.into_int_value();
9696 let memory_index = MemoryIndex::from_u32(0);
9697 let effective_address = self.resolve_memory_ptr(
9698 memory_index,
9699 memarg,
9700 self.intrinsics.ptr_ty,
9701 offset,
9702 4,
9703 )?;
9704 let narrow_result = err!(self.builder.build_load(
9705 self.intrinsics.i32_ty,
9706 effective_address,
9707 ""
9708 ));
9709 self.annotate_user_memaccess(
9710 memory_index,
9711 memarg,
9712 1,
9713 narrow_result.as_instruction_value().unwrap(),
9714 )?;
9715 let result = err!(self.builder.build_int_z_extend(
9716 narrow_result.into_int_value(),
9717 self.intrinsics.i64_ty,
9718 "",
9719 ));
9720 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9721 }
9722
9723 Operator::I32Store8 { ref memarg } | Operator::I64Store8 { ref memarg } => {
9724 let value = self.state.pop1()?.into_int_value();
9725 let offset = self.state.pop1()?.into_int_value();
9726 let memory_index = MemoryIndex::from_u32(0);
9727 let effective_address = self.resolve_memory_ptr(
9728 memory_index,
9729 memarg,
9730 self.intrinsics.ptr_ty,
9731 offset,
9732 1,
9733 )?;
9734 let dead_load = err!(self.builder.build_load(
9735 self.intrinsics.i8_ty,
9736 effective_address,
9737 ""
9738 ));
9739 self.annotate_user_memaccess(
9740 memory_index,
9741 memarg,
9742 1,
9743 dead_load.as_instruction_value().unwrap(),
9744 )?;
9745 let narrow_value = err!(self.builder.build_int_truncate(
9746 value,
9747 self.intrinsics.i8_ty,
9748 ""
9749 ));
9750 let store = err!(self.builder.build_store(effective_address, narrow_value));
9751 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9752 }
9753 Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
9754 let value = self.state.pop1()?.into_int_value();
9755 let offset = self.state.pop1()?.into_int_value();
9756 let memory_index = MemoryIndex::from_u32(0);
9757 let effective_address = self.resolve_memory_ptr(
9758 memory_index,
9759 memarg,
9760 self.intrinsics.ptr_ty,
9761 offset,
9762 2,
9763 )?;
9764 let dead_load = err!(self.builder.build_load(
9765 self.intrinsics.i16_ty,
9766 effective_address,
9767 ""
9768 ));
9769 self.annotate_user_memaccess(
9770 memory_index,
9771 memarg,
9772 1,
9773 dead_load.as_instruction_value().unwrap(),
9774 )?;
9775 let narrow_value = err!(self.builder.build_int_truncate(
9776 value,
9777 self.intrinsics.i16_ty,
9778 ""
9779 ));
9780 let store = err!(self.builder.build_store(effective_address, narrow_value));
9781 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9782 }
9783 Operator::I64Store32 { ref memarg } => {
9784 let value = self.state.pop1()?.into_int_value();
9785 let offset = self.state.pop1()?.into_int_value();
9786 let memory_index = MemoryIndex::from_u32(0);
9787 let effective_address = self.resolve_memory_ptr(
9788 memory_index,
9789 memarg,
9790 self.intrinsics.ptr_ty,
9791 offset,
9792 4,
9793 )?;
9794 let dead_load = err!(self.builder.build_load(
9795 self.intrinsics.i32_ty,
9796 effective_address,
9797 ""
9798 ));
9799 self.annotate_user_memaccess(
9800 memory_index,
9801 memarg,
9802 1,
9803 dead_load.as_instruction_value().unwrap(),
9804 )?;
9805 let narrow_value = err!(self.builder.build_int_truncate(
9806 value,
9807 self.intrinsics.i32_ty,
9808 ""
9809 ));
9810 let store = err!(self.builder.build_store(effective_address, narrow_value));
9811 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9812 }
9813 Operator::I8x16Neg => {
9814 let (v, i) = self.state.pop1_extra()?;
9815 let (v, _) = self.v128_into_i8x16(v, i)?;
9816 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9817 let res = err!(
9818 self.builder
9819 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9820 );
9821 self.state.push1(res);
9822 }
9823 Operator::I16x8Neg => {
9824 let (v, i) = self.state.pop1_extra()?;
9825 let (v, _) = self.v128_into_i16x8(v, i)?;
9826 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9827 let res = err!(
9828 self.builder
9829 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9830 );
9831 self.state.push1(res);
9832 }
9833 Operator::I32x4Neg => {
9834 let (v, i) = self.state.pop1_extra()?;
9835 let (v, _) = self.v128_into_i32x4(v, i)?;
9836 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9837 let res = err!(
9838 self.builder
9839 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9840 );
9841 self.state.push1(res);
9842 }
9843 Operator::I64x2Neg => {
9844 let (v, i) = self.state.pop1_extra()?;
9845 let (v, _) = self.v128_into_i64x2(v, i)?;
9846 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9847 let res = err!(
9848 self.builder
9849 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9850 );
9851 self.state.push1(res);
9852 }
9853 Operator::V128Not => {
9854 let (v, i) = self.state.pop1_extra()?;
9855 let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9856 let res = err!(self.builder.build_not(v, ""));
9857 self.state.push1(res);
9858 }
9859 Operator::V128AnyTrue => {
9860 let v = self.state.pop1()?.into_int_value();
9863 let res = err!(self.builder.build_int_compare(
9864 IntPredicate::NE,
9865 v,
9866 v.get_type().const_zero(),
9867 "",
9868 ));
9869 let res = err!(
9870 self.builder
9871 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9872 );
9873 self.state.push1_extra(
9874 res,
9875 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9876 );
9877 }
9878 Operator::I8x16AllTrue
9879 | Operator::I16x8AllTrue
9880 | Operator::I32x4AllTrue
9881 | Operator::I64x2AllTrue => {
9882 let vec_ty = match op {
9883 Operator::I8x16AllTrue => self.intrinsics.i8x16_ty,
9884 Operator::I16x8AllTrue => self.intrinsics.i16x8_ty,
9885 Operator::I32x4AllTrue => self.intrinsics.i32x4_ty,
9886 Operator::I64x2AllTrue => self.intrinsics.i64x2_ty,
9887 _ => unreachable!(),
9888 };
9889 let (v, i) = self.state.pop1_extra()?;
9890 let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9891 let lane_int_ty = self.context.custom_width_int_type(vec_ty.get_size());
9892 let vec = err!(self.builder.build_bit_cast(v, vec_ty, "vec")).into_vector_value();
9893 let mask = err!(self.builder.build_int_compare(
9894 IntPredicate::NE,
9895 vec,
9896 vec_ty.const_zero(),
9897 "mask",
9898 ));
9899 let cmask =
9900 err!(self.builder.build_bit_cast(mask, lane_int_ty, "cmask")).into_int_value();
9901 let res = err!(self.builder.build_int_compare(
9902 IntPredicate::EQ,
9903 cmask,
9904 lane_int_ty.const_int(u64::MAX, true),
9905 "",
9906 ));
9907 let res = err!(
9908 self.builder
9909 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9910 );
9911 self.state.push1_extra(
9912 res,
9913 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9914 );
9915 }
9916 Operator::I8x16ExtractLaneS { lane } => {
9917 let (v, i) = self.state.pop1_extra()?;
9918 let (v, _) = self.v128_into_i8x16(v, i)?;
9919 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9920 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9921 let res = err!(
9922 self.builder
9923 .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9924 );
9925 self.state.push1(res);
9926 }
9927 Operator::I8x16ExtractLaneU { lane } => {
9928 let (v, i) = self.state.pop1_extra()?;
9929 let (v, _) = self.v128_into_i8x16(v, i)?;
9930 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9931 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9932 let res = err!(
9933 self.builder
9934 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9935 );
9936 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9937 }
9938 Operator::I16x8ExtractLaneS { lane } => {
9939 let (v, i) = self.state.pop1_extra()?;
9940 let (v, _) = self.v128_into_i16x8(v, i)?;
9941 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9942 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9943 let res = err!(
9944 self.builder
9945 .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9946 );
9947 self.state.push1(res);
9948 }
9949 Operator::I16x8ExtractLaneU { lane } => {
9950 let (v, i) = self.state.pop1_extra()?;
9951 let (v, _) = self.v128_into_i16x8(v, i)?;
9952 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9953 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9954 let res = err!(
9955 self.builder
9956 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9957 );
9958 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9959 }
9960 Operator::I32x4ExtractLane { lane } => {
9961 let (v, i) = self.state.pop1_extra()?;
9962 let (v, i) = self.v128_into_i32x4(v, i)?;
9963 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9964 let res = err!(self.builder.build_extract_element(v, idx, ""));
9965 self.state.push1_extra(res, i);
9966 }
9967 Operator::I64x2ExtractLane { lane } => {
9968 let (v, i) = self.state.pop1_extra()?;
9969 let (v, i) = self.v128_into_i64x2(v, i)?;
9970 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9971 let res = err!(self.builder.build_extract_element(v, idx, ""));
9972 self.state.push1_extra(res, i);
9973 }
9974 Operator::F32x4ExtractLane { lane } => {
9975 let (v, i) = self.state.pop1_extra()?;
9976 let (v, i) = self.v128_into_f32x4(v, i)?;
9977 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9978 let res = err!(self.builder.build_extract_element(v, idx, ""));
9979 self.state.push1_extra(res, i);
9980 }
9981 Operator::F64x2ExtractLane { lane } => {
9982 let (v, i) = self.state.pop1_extra()?;
9983 let (v, i) = self.v128_into_f64x2(v, i)?;
9984 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9985 let res = err!(self.builder.build_extract_element(v, idx, ""));
9986 self.state.push1_extra(res, i);
9987 }
9988 Operator::I8x16ReplaceLane { lane } => {
9989 let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9990 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
9991 let v2 = v2.into_int_value();
9992 let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i8_ty, ""));
9993 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9994 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9995 let res = err!(
9996 self.builder
9997 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9998 );
9999 self.state.push1(res);
10000 }
10001 Operator::I16x8ReplaceLane { lane } => {
10002 let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
10003 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
10004 let v2 = v2.into_int_value();
10005 let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i16_ty, ""));
10006 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10007 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10008 let res = err!(
10009 self.builder
10010 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10011 );
10012 self.state.push1(res);
10013 }
10014 Operator::I32x4ReplaceLane { lane } => {
10015 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10016 let (v1, i1) = self.v128_into_i32x4(v1, i1)?;
10017 let v2 = self.apply_pending_canonicalization(v2, i2)?;
10018 let v2 = v2.into_int_value();
10019 let i2 = i2.strip_pending();
10020 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10021 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10022 let res = err!(
10023 self.builder
10024 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10025 );
10026 self.state
10027 .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f32())?);
10028 }
10029 Operator::I64x2ReplaceLane { lane } => {
10030 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10031 let (v1, i1) = self.v128_into_i64x2(v1, i1)?;
10032 let v2 = self.apply_pending_canonicalization(v2, i2)?;
10033 let v2 = v2.into_int_value();
10034 let i2 = i2.strip_pending();
10035 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10036 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10037 let res = err!(
10038 self.builder
10039 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10040 );
10041 self.state
10042 .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f64())?);
10043 }
10044 Operator::F32x4ReplaceLane { lane } => {
10045 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10046 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
10047 let push_pending_f32_nan_to_result =
10048 i1.has_pending_f32_nan() && i2.has_pending_f32_nan();
10049 let (v1, v2) = if !push_pending_f32_nan_to_result {
10050 (
10051 self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
10052 .into_vector_value(),
10053 self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
10054 .into_float_value(),
10055 )
10056 } else {
10057 (v1, v2.into_float_value())
10058 };
10059 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10060 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10061 let res = err!(
10062 self.builder
10063 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10064 );
10065 let info = if push_pending_f32_nan_to_result {
10066 ExtraInfo::pending_f32_nan()
10067 } else {
10068 (i1.strip_pending() & i2.strip_pending())?
10069 };
10070 self.state.push1_extra(res, info);
10071 }
10072 Operator::F64x2ReplaceLane { lane } => {
10073 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10074 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
10075 let push_pending_f64_nan_to_result =
10076 i1.has_pending_f64_nan() && i2.has_pending_f64_nan();
10077 let (v1, v2) = if !push_pending_f64_nan_to_result {
10078 (
10079 self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
10080 .into_vector_value(),
10081 self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
10082 .into_float_value(),
10083 )
10084 } else {
10085 (v1, v2.into_float_value())
10086 };
10087 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
10088 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
10089 let res = err!(
10090 self.builder
10091 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10092 );
10093 let info = if push_pending_f64_nan_to_result {
10094 ExtraInfo::pending_f64_nan()
10095 } else {
10096 (i1.strip_pending() & i2.strip_pending())?
10097 };
10098 self.state.push1_extra(res, info);
10099 }
10100 Operator::I8x16Swizzle => {
10101 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10102 let v1 = self.apply_pending_canonicalization(v1, i1)?;
10103 let v1 = err!(
10104 self.builder
10105 .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
10106 )
10107 .into_vector_value();
10108 let v2 = self.apply_pending_canonicalization(v2, i2)?;
10109 let v2 = err!(
10110 self.builder
10111 .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
10112 )
10113 .into_vector_value();
10114 let lanes = self.intrinsics.i8_ty.const_int(16, false);
10115 let lanes =
10116 self.splat_vector(lanes.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
10117 let mut res = self.intrinsics.i8x16_ty.get_undef();
10118 let idx_out_of_range = err!(self.builder.build_int_compare(
10119 IntPredicate::UGE,
10120 v2,
10121 lanes,
10122 "idx_out_of_range",
10123 ));
10124 let idx_clamped = err!(self.builder.build_select(
10125 idx_out_of_range,
10126 self.intrinsics.i8x16_ty.const_zero(),
10127 v2,
10128 "idx_clamped",
10129 ))
10130 .into_vector_value();
10131 for i in 0..16 {
10132 let idx = err!(self.builder.build_extract_element(
10133 idx_clamped,
10134 self.intrinsics.i32_ty.const_int(i, false),
10135 "idx",
10136 ))
10137 .into_int_value();
10138 let replace_with_zero = err!(self.builder.build_extract_element(
10139 idx_out_of_range,
10140 self.intrinsics.i32_ty.const_int(i, false),
10141 "replace_with_zero",
10142 ))
10143 .into_int_value();
10144 let elem =
10145 err!(self.builder.build_extract_element(v1, idx, "elem")).into_int_value();
10146 let elem_or_zero = err!(self.builder.build_select(
10147 replace_with_zero,
10148 self.intrinsics.i8_zero,
10149 elem,
10150 "elem_or_zero",
10151 ));
10152 res = err!(self.builder.build_insert_element(
10153 res,
10154 elem_or_zero,
10155 self.intrinsics.i32_ty.const_int(i, false),
10156 "",
10157 ));
10158 }
10159 let res = err!(
10160 self.builder
10161 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10162 );
10163 self.state.push1(res);
10164 }
10165 Operator::I8x16Shuffle { lanes } => {
10166 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
10167 let v1 = self.apply_pending_canonicalization(v1, i1)?;
10168 let v1 = err!(
10169 self.builder
10170 .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
10171 )
10172 .into_vector_value();
10173 let v2 = self.apply_pending_canonicalization(v2, i2)?;
10174 let v2 = err!(
10175 self.builder
10176 .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
10177 )
10178 .into_vector_value();
10179 let mask = VectorType::const_vector(
10180 lanes
10181 .iter()
10182 .map(|l| self.intrinsics.i32_ty.const_int((*l).into(), false))
10183 .collect::<Vec<IntValue>>()
10184 .as_slice(),
10185 );
10186 let res = err!(self.builder.build_shuffle_vector(v1, v2, mask, ""));
10187 let res = err!(
10188 self.builder
10189 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10190 );
10191 self.state.push1(res);
10192 }
10193 Operator::V128Load8x8S { ref memarg } => {
10194 let offset = self.state.pop1()?.into_int_value();
10195 let memory_index = MemoryIndex::from_u32(0);
10196 let effective_address = self.resolve_memory_ptr(
10197 memory_index,
10198 memarg,
10199 self.intrinsics.ptr_ty,
10200 offset,
10201 8,
10202 )?;
10203 let v = err!(self.builder.build_load(
10204 self.intrinsics.i64_ty,
10205 effective_address,
10206 ""
10207 ));
10208 let v = err!(
10209 self.builder
10210 .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
10211 )
10212 .into_vector_value();
10213 let res = err!(
10214 self.builder
10215 .build_int_s_extend(v, self.intrinsics.i16x8_ty, "")
10216 );
10217 let res = err!(
10218 self.builder
10219 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10220 );
10221 self.state.push1(res);
10222 }
10223 Operator::V128Load8x8U { ref memarg } => {
10224 let offset = self.state.pop1()?.into_int_value();
10225 let memory_index = MemoryIndex::from_u32(0);
10226 let effective_address = self.resolve_memory_ptr(
10227 memory_index,
10228 memarg,
10229 self.intrinsics.ptr_ty,
10230 offset,
10231 8,
10232 )?;
10233 let v = err!(self.builder.build_load(
10234 self.intrinsics.i64_ty,
10235 effective_address,
10236 ""
10237 ));
10238 let v = err!(
10239 self.builder
10240 .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
10241 )
10242 .into_vector_value();
10243 let res = err!(
10244 self.builder
10245 .build_int_z_extend(v, self.intrinsics.i16x8_ty, "")
10246 );
10247 let res = err!(
10248 self.builder
10249 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10250 );
10251 self.state.push1(res);
10252 }
10253 Operator::V128Load16x4S { ref memarg } => {
10254 let offset = self.state.pop1()?.into_int_value();
10255 let memory_index = MemoryIndex::from_u32(0);
10256 let effective_address = self.resolve_memory_ptr(
10257 memory_index,
10258 memarg,
10259 self.intrinsics.ptr_ty,
10260 offset,
10261 8,
10262 )?;
10263 let v = err!(self.builder.build_load(
10264 self.intrinsics.i64_ty,
10265 effective_address,
10266 ""
10267 ));
10268 let v = err!(self.builder.build_bit_cast(
10269 v,
10270 self.intrinsics.i16_ty.vec_type(4),
10271 ""
10272 ))
10273 .into_vector_value();
10274 let res = err!(
10275 self.builder
10276 .build_int_s_extend(v, self.intrinsics.i32x4_ty, "")
10277 );
10278 let res = err!(
10279 self.builder
10280 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10281 );
10282 self.state.push1(res);
10283 }
10284 Operator::V128Load16x4U { ref memarg } => {
10285 let offset = self.state.pop1()?.into_int_value();
10286 let memory_index = MemoryIndex::from_u32(0);
10287 let effective_address = self.resolve_memory_ptr(
10288 memory_index,
10289 memarg,
10290 self.intrinsics.ptr_ty,
10291 offset,
10292 8,
10293 )?;
10294 let v = err!(self.builder.build_load(
10295 self.intrinsics.i64_ty,
10296 effective_address,
10297 ""
10298 ));
10299 let v = err!(self.builder.build_bit_cast(
10300 v,
10301 self.intrinsics.i16_ty.vec_type(4),
10302 ""
10303 ))
10304 .into_vector_value();
10305 let res = err!(
10306 self.builder
10307 .build_int_z_extend(v, self.intrinsics.i32x4_ty, "")
10308 );
10309 let res = err!(
10310 self.builder
10311 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10312 );
10313 self.state.push1(res);
10314 }
10315 Operator::V128Load32x2S { ref memarg } => {
10316 let offset = self.state.pop1()?.into_int_value();
10317 let memory_index = MemoryIndex::from_u32(0);
10318 let effective_address = self.resolve_memory_ptr(
10319 memory_index,
10320 memarg,
10321 self.intrinsics.ptr_ty,
10322 offset,
10323 8,
10324 )?;
10325 let v = err!(self.builder.build_load(
10326 self.intrinsics.i64_ty,
10327 effective_address,
10328 ""
10329 ));
10330 let v = err!(self.builder.build_bit_cast(
10331 v,
10332 self.intrinsics.i32_ty.vec_type(2),
10333 ""
10334 ))
10335 .into_vector_value();
10336 let res = err!(
10337 self.builder
10338 .build_int_s_extend(v, self.intrinsics.i64x2_ty, "")
10339 );
10340 let res = err!(
10341 self.builder
10342 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10343 );
10344 self.state.push1(res);
10345 }
10346 Operator::V128Load32x2U { ref memarg } => {
10347 let offset = self.state.pop1()?.into_int_value();
10348 let memory_index = MemoryIndex::from_u32(0);
10349 let effective_address = self.resolve_memory_ptr(
10350 memory_index,
10351 memarg,
10352 self.intrinsics.ptr_ty,
10353 offset,
10354 8,
10355 )?;
10356 let v = err!(self.builder.build_load(
10357 self.intrinsics.i64_ty,
10358 effective_address,
10359 ""
10360 ));
10361 let v = err!(self.builder.build_bit_cast(
10362 v,
10363 self.intrinsics.i32_ty.vec_type(2),
10364 ""
10365 ))
10366 .into_vector_value();
10367 let res = err!(
10368 self.builder
10369 .build_int_z_extend(v, self.intrinsics.i64x2_ty, "")
10370 );
10371 let res = err!(
10372 self.builder
10373 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10374 );
10375 self.state.push1(res);
10376 }
10377 Operator::V128Load32Zero { ref memarg } => {
10378 let offset = self.state.pop1()?.into_int_value();
10379 let memory_index = MemoryIndex::from_u32(0);
10380 let effective_address = self.resolve_memory_ptr(
10381 memory_index,
10382 memarg,
10383 self.intrinsics.ptr_ty,
10384 offset,
10385 4,
10386 )?;
10387 let elem = err!(self.builder.build_load(
10388 self.intrinsics.i32_ty,
10389 effective_address,
10390 ""
10391 ));
10392 self.annotate_user_memaccess(
10393 memory_index,
10394 memarg,
10395 1,
10396 elem.as_instruction_value().unwrap(),
10397 )?;
10398 let res = err!(self.builder.build_int_z_extend(
10399 elem.into_int_value(),
10400 self.intrinsics.i128_ty,
10401 "",
10402 ));
10403 self.state.push1(res);
10404 }
10405 Operator::V128Load64Zero { ref memarg } => {
10406 let offset = self.state.pop1()?.into_int_value();
10407 let memory_index = MemoryIndex::from_u32(0);
10408 let effective_address = self.resolve_memory_ptr(
10409 memory_index,
10410 memarg,
10411 self.intrinsics.ptr_ty,
10412 offset,
10413 8,
10414 )?;
10415 let elem = err!(self.builder.build_load(
10416 self.intrinsics.i64_ty,
10417 effective_address,
10418 ""
10419 ));
10420 self.annotate_user_memaccess(
10421 memory_index,
10422 memarg,
10423 1,
10424 elem.as_instruction_value().unwrap(),
10425 )?;
10426 let res = err!(self.builder.build_int_z_extend(
10427 elem.into_int_value(),
10428 self.intrinsics.i128_ty,
10429 "",
10430 ));
10431 self.state.push1(res);
10432 }
10433 Operator::V128Load8Splat { ref memarg } => {
10434 let offset = self.state.pop1()?.into_int_value();
10435 let memory_index = MemoryIndex::from_u32(0);
10436 let effective_address = self.resolve_memory_ptr(
10437 memory_index,
10438 memarg,
10439 self.intrinsics.ptr_ty,
10440 offset,
10441 1,
10442 )?;
10443 let elem = err!(self.builder.build_load(
10444 self.intrinsics.i8_ty,
10445 effective_address,
10446 ""
10447 ));
10448 self.annotate_user_memaccess(
10449 memory_index,
10450 memarg,
10451 1,
10452 elem.as_instruction_value().unwrap(),
10453 )?;
10454 let res = self.splat_vector(elem, self.intrinsics.i8x16_ty)?;
10455 let res = err!(
10456 self.builder
10457 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10458 );
10459 self.state.push1(res);
10460 }
10461 Operator::V128Load16Splat { ref memarg } => {
10462 let offset = self.state.pop1()?.into_int_value();
10463 let memory_index = MemoryIndex::from_u32(0);
10464 let effective_address = self.resolve_memory_ptr(
10465 memory_index,
10466 memarg,
10467 self.intrinsics.ptr_ty,
10468 offset,
10469 2,
10470 )?;
10471 let elem = err!(self.builder.build_load(
10472 self.intrinsics.i16_ty,
10473 effective_address,
10474 ""
10475 ));
10476 self.annotate_user_memaccess(
10477 memory_index,
10478 memarg,
10479 1,
10480 elem.as_instruction_value().unwrap(),
10481 )?;
10482 let res = self.splat_vector(elem, self.intrinsics.i16x8_ty)?;
10483 let res = err!(
10484 self.builder
10485 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10486 );
10487 self.state.push1(res);
10488 }
10489 Operator::V128Load32Splat { ref memarg } => {
10490 let offset = self.state.pop1()?.into_int_value();
10491 let memory_index = MemoryIndex::from_u32(0);
10492 let effective_address = self.resolve_memory_ptr(
10493 memory_index,
10494 memarg,
10495 self.intrinsics.ptr_ty,
10496 offset,
10497 4,
10498 )?;
10499 let elem = err!(self.builder.build_load(
10500 self.intrinsics.i32_ty,
10501 effective_address,
10502 ""
10503 ));
10504 self.annotate_user_memaccess(
10505 memory_index,
10506 memarg,
10507 1,
10508 elem.as_instruction_value().unwrap(),
10509 )?;
10510 let res = self.splat_vector(elem, self.intrinsics.i32x4_ty)?;
10511 let res = err!(
10512 self.builder
10513 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10514 );
10515 self.state.push1(res);
10516 }
10517 Operator::V128Load64Splat { ref memarg } => {
10518 let offset = self.state.pop1()?.into_int_value();
10519 let memory_index = MemoryIndex::from_u32(0);
10520 let effective_address = self.resolve_memory_ptr(
10521 memory_index,
10522 memarg,
10523 self.intrinsics.ptr_ty,
10524 offset,
10525 8,
10526 )?;
10527 let elem = err!(self.builder.build_load(
10528 self.intrinsics.i64_ty,
10529 effective_address,
10530 ""
10531 ));
10532 self.annotate_user_memaccess(
10533 memory_index,
10534 memarg,
10535 1,
10536 elem.as_instruction_value().unwrap(),
10537 )?;
10538 let res = self.splat_vector(elem, self.intrinsics.i64x2_ty)?;
10539 let res = err!(
10540 self.builder
10541 .build_bit_cast(res, self.intrinsics.i128_ty, "")
10542 );
10543 self.state.push1(res);
10544 }
10545 Operator::AtomicFence => {
10546 }
10554 Operator::I32AtomicLoad { ref memarg } => {
10555 let offset = self.state.pop1()?.into_int_value();
10556 let memory_index = MemoryIndex::from_u32(0);
10557 let effective_address = self.resolve_memory_ptr(
10558 memory_index,
10559 memarg,
10560 self.intrinsics.ptr_ty,
10561 offset,
10562 4,
10563 )?;
10564 self.trap_if_misaligned(memarg, effective_address, 4)?;
10565 let result = err!(self.builder.build_load(
10566 self.intrinsics.i32_ty,
10567 effective_address,
10568 "atomic_load"
10569 ));
10570 let load = result.as_instruction_value().unwrap();
10571 self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10572 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10573 .unwrap();
10574 self.state.push1(result);
10575 }
10576 Operator::I64AtomicLoad { ref memarg } => {
10577 let offset = self.state.pop1()?.into_int_value();
10578 let memory_index = MemoryIndex::from_u32(0);
10579 let effective_address = self.resolve_memory_ptr(
10580 memory_index,
10581 memarg,
10582 self.intrinsics.ptr_ty,
10583 offset,
10584 8,
10585 )?;
10586 self.trap_if_misaligned(memarg, effective_address, 8)?;
10587 let result = err!(self.builder.build_load(
10588 self.intrinsics.i64_ty,
10589 effective_address,
10590 ""
10591 ));
10592 let load = result.as_instruction_value().unwrap();
10593 self.annotate_user_memaccess(memory_index, memarg, 8, load)?;
10594 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10595 .unwrap();
10596 self.state.push1(result);
10597 }
10598 Operator::I32AtomicLoad8U { ref memarg } => {
10599 let offset = self.state.pop1()?.into_int_value();
10600 let memory_index = MemoryIndex::from_u32(0);
10601 let effective_address = self.resolve_memory_ptr(
10602 memory_index,
10603 memarg,
10604 self.intrinsics.ptr_ty,
10605 offset,
10606 1,
10607 )?;
10608 self.trap_if_misaligned(memarg, effective_address, 1)?;
10609 let narrow_result = err!(self.builder.build_load(
10610 self.intrinsics.i8_ty,
10611 effective_address,
10612 ""
10613 ))
10614 .into_int_value();
10615 let load = narrow_result.as_instruction_value().unwrap();
10616 self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
10617 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10618 .unwrap();
10619 let result = err!(self.builder.build_int_z_extend(
10620 narrow_result,
10621 self.intrinsics.i32_ty,
10622 ""
10623 ));
10624 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
10625 }
10626 Operator::I32AtomicLoad16U { ref memarg } => {
10627 let offset = self.state.pop1()?.into_int_value();
10628 let memory_index = MemoryIndex::from_u32(0);
10629 let effective_address = self.resolve_memory_ptr(
10630 memory_index,
10631 memarg,
10632 self.intrinsics.ptr_ty,
10633 offset,
10634 2,
10635 )?;
10636 self.trap_if_misaligned(memarg, effective_address, 2)?;
10637 let narrow_result = err!(self.builder.build_load(
10638 self.intrinsics.i16_ty,
10639 effective_address,
10640 ""
10641 ))
10642 .into_int_value();
10643 let load = narrow_result.as_instruction_value().unwrap();
10644 self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
10645 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10646 .unwrap();
10647 let result = err!(self.builder.build_int_z_extend(
10648 narrow_result,
10649 self.intrinsics.i32_ty,
10650 ""
10651 ));
10652 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
10653 }
10654 Operator::I64AtomicLoad8U { ref memarg } => {
10655 let offset = self.state.pop1()?.into_int_value();
10656 let memory_index = MemoryIndex::from_u32(0);
10657 let effective_address = self.resolve_memory_ptr(
10658 memory_index,
10659 memarg,
10660 self.intrinsics.ptr_ty,
10661 offset,
10662 1,
10663 )?;
10664 self.trap_if_misaligned(memarg, effective_address, 1)?;
10665 let narrow_result = err!(self.builder.build_load(
10666 self.intrinsics.i8_ty,
10667 effective_address,
10668 ""
10669 ))
10670 .into_int_value();
10671 let load = narrow_result.as_instruction_value().unwrap();
10672 self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
10673 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10674 .unwrap();
10675 let result = err!(self.builder.build_int_z_extend(
10676 narrow_result,
10677 self.intrinsics.i64_ty,
10678 ""
10679 ));
10680 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10681 }
10682 Operator::I64AtomicLoad16U { ref memarg } => {
10683 let offset = self.state.pop1()?.into_int_value();
10684 let memory_index = MemoryIndex::from_u32(0);
10685 let effective_address = self.resolve_memory_ptr(
10686 memory_index,
10687 memarg,
10688 self.intrinsics.ptr_ty,
10689 offset,
10690 2,
10691 )?;
10692 self.trap_if_misaligned(memarg, effective_address, 2)?;
10693 let narrow_result = err!(self.builder.build_load(
10694 self.intrinsics.i16_ty,
10695 effective_address,
10696 ""
10697 ))
10698 .into_int_value();
10699 let load = narrow_result.as_instruction_value().unwrap();
10700 self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
10701 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10702 .unwrap();
10703 let result = err!(self.builder.build_int_z_extend(
10704 narrow_result,
10705 self.intrinsics.i64_ty,
10706 ""
10707 ));
10708 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10709 }
10710 Operator::I64AtomicLoad32U { ref memarg } => {
10711 let offset = self.state.pop1()?.into_int_value();
10712 let memory_index = MemoryIndex::from_u32(0);
10713 let effective_address = self.resolve_memory_ptr(
10714 memory_index,
10715 memarg,
10716 self.intrinsics.ptr_ty,
10717 offset,
10718 4,
10719 )?;
10720 self.trap_if_misaligned(memarg, effective_address, 4)?;
10721 let narrow_result = err!(self.builder.build_load(
10722 self.intrinsics.i32_ty,
10723 effective_address,
10724 ""
10725 ))
10726 .into_int_value();
10727 let load = narrow_result.as_instruction_value().unwrap();
10728 self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10729 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10730 .unwrap();
10731 let result = err!(self.builder.build_int_z_extend(
10732 narrow_result,
10733 self.intrinsics.i64_ty,
10734 ""
10735 ));
10736 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10737 }
10738 Operator::I32AtomicStore { ref memarg } => {
10739 let value = self.state.pop1()?;
10740 let offset = self.state.pop1()?.into_int_value();
10741 let memory_index = MemoryIndex::from_u32(0);
10742 let effective_address = self.resolve_memory_ptr(
10743 memory_index,
10744 memarg,
10745 self.intrinsics.ptr_ty,
10746 offset,
10747 4,
10748 )?;
10749 self.trap_if_misaligned(memarg, effective_address, 4)?;
10750 let store = err!(self.builder.build_store(effective_address, value));
10751 self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10752 store
10753 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10754 .unwrap();
10755 }
10756 Operator::I64AtomicStore { ref memarg } => {
10757 let value = self.state.pop1()?;
10758 let offset = self.state.pop1()?.into_int_value();
10759 let memory_index = MemoryIndex::from_u32(0);
10760 let effective_address = self.resolve_memory_ptr(
10761 memory_index,
10762 memarg,
10763 self.intrinsics.ptr_ty,
10764 offset,
10765 8,
10766 )?;
10767 self.trap_if_misaligned(memarg, effective_address, 8)?;
10768 let store = err!(self.builder.build_store(effective_address, value));
10769 self.annotate_user_memaccess(memory_index, memarg, 8, store)?;
10770 store
10771 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10772 .unwrap();
10773 }
10774 Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => {
10775 let value = self.state.pop1()?.into_int_value();
10776 let offset = self.state.pop1()?.into_int_value();
10777 let memory_index = MemoryIndex::from_u32(0);
10778 let effective_address = self.resolve_memory_ptr(
10779 memory_index,
10780 memarg,
10781 self.intrinsics.ptr_ty,
10782 offset,
10783 1,
10784 )?;
10785 self.trap_if_misaligned(memarg, effective_address, 1)?;
10786 let narrow_value = err!(self.builder.build_int_truncate(
10787 value,
10788 self.intrinsics.i8_ty,
10789 ""
10790 ));
10791 let store = err!(self.builder.build_store(effective_address, narrow_value));
10792 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
10793 store
10794 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10795 .unwrap();
10796 }
10797 Operator::I32AtomicStore16 { ref memarg }
10798 | Operator::I64AtomicStore16 { ref memarg } => {
10799 let value = self.state.pop1()?.into_int_value();
10800 let offset = self.state.pop1()?.into_int_value();
10801 let memory_index = MemoryIndex::from_u32(0);
10802 let effective_address = self.resolve_memory_ptr(
10803 memory_index,
10804 memarg,
10805 self.intrinsics.ptr_ty,
10806 offset,
10807 2,
10808 )?;
10809 self.trap_if_misaligned(memarg, effective_address, 2)?;
10810 let narrow_value = err!(self.builder.build_int_truncate(
10811 value,
10812 self.intrinsics.i16_ty,
10813 ""
10814 ));
10815 let store = err!(self.builder.build_store(effective_address, narrow_value));
10816 self.annotate_user_memaccess(memory_index, memarg, 2, store)?;
10817 store
10818 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10819 .unwrap();
10820 }
10821 Operator::I64AtomicStore32 { ref memarg } => {
10822 let value = self.state.pop1()?.into_int_value();
10823 let offset = self.state.pop1()?.into_int_value();
10824 let memory_index = MemoryIndex::from_u32(0);
10825 let effective_address = self.resolve_memory_ptr(
10826 memory_index,
10827 memarg,
10828 self.intrinsics.ptr_ty,
10829 offset,
10830 4,
10831 )?;
10832 self.trap_if_misaligned(memarg, effective_address, 4)?;
10833 let narrow_value = err!(self.builder.build_int_truncate(
10834 value,
10835 self.intrinsics.i32_ty,
10836 ""
10837 ));
10838 let store = err!(self.builder.build_store(effective_address, narrow_value));
10839 self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10840 store
10841 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10842 .unwrap();
10843 }
10844 Operator::I32AtomicRmw8AddU { ref memarg } => {
10845 let value = self.state.pop1()?.into_int_value();
10846 let offset = self.state.pop1()?.into_int_value();
10847 let memory_index = MemoryIndex::from_u32(0);
10848 let effective_address = self.resolve_memory_ptr(
10849 memory_index,
10850 memarg,
10851 self.intrinsics.ptr_ty,
10852 offset,
10853 1,
10854 )?;
10855 self.trap_if_misaligned(memarg, effective_address, 1)?;
10856 let narrow_value = err!(self.builder.build_int_truncate(
10857 value,
10858 self.intrinsics.i8_ty,
10859 ""
10860 ));
10861 let old = self
10862 .builder
10863 .build_atomicrmw(
10864 AtomicRMWBinOp::Add,
10865 effective_address,
10866 narrow_value,
10867 AtomicOrdering::SequentiallyConsistent,
10868 )
10869 .unwrap();
10870 tbaa_label(
10871 self.module,
10872 self.intrinsics,
10873 format!("memory {}", memory_index.as_u32()),
10874 old.as_instruction_value().unwrap(),
10875 );
10876 let old = err!(
10877 self.builder
10878 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10879 );
10880 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10881 }
10882 Operator::I32AtomicRmw16AddU { ref memarg } => {
10883 let value = self.state.pop1()?.into_int_value();
10884 let offset = self.state.pop1()?.into_int_value();
10885 let memory_index = MemoryIndex::from_u32(0);
10886 let effective_address = self.resolve_memory_ptr(
10887 memory_index,
10888 memarg,
10889 self.intrinsics.ptr_ty,
10890 offset,
10891 2,
10892 )?;
10893 self.trap_if_misaligned(memarg, effective_address, 2)?;
10894 let narrow_value = err!(self.builder.build_int_truncate(
10895 value,
10896 self.intrinsics.i16_ty,
10897 ""
10898 ));
10899 let old = self
10900 .builder
10901 .build_atomicrmw(
10902 AtomicRMWBinOp::Add,
10903 effective_address,
10904 narrow_value,
10905 AtomicOrdering::SequentiallyConsistent,
10906 )
10907 .unwrap();
10908 tbaa_label(
10909 self.module,
10910 self.intrinsics,
10911 format!("memory {}", memory_index.as_u32()),
10912 old.as_instruction_value().unwrap(),
10913 );
10914 let old = err!(
10915 self.builder
10916 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10917 );
10918 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10919 }
10920 Operator::I32AtomicRmwAdd { ref memarg } => {
10921 let value = self.state.pop1()?.into_int_value();
10922 let offset = self.state.pop1()?.into_int_value();
10923 let memory_index = MemoryIndex::from_u32(0);
10924 let effective_address = self.resolve_memory_ptr(
10925 memory_index,
10926 memarg,
10927 self.intrinsics.ptr_ty,
10928 offset,
10929 4,
10930 )?;
10931 self.trap_if_misaligned(memarg, effective_address, 4)?;
10932 let old = self
10933 .builder
10934 .build_atomicrmw(
10935 AtomicRMWBinOp::Add,
10936 effective_address,
10937 value,
10938 AtomicOrdering::SequentiallyConsistent,
10939 )
10940 .unwrap();
10941 tbaa_label(
10942 self.module,
10943 self.intrinsics,
10944 format!("memory {}", memory_index.as_u32()),
10945 old.as_instruction_value().unwrap(),
10946 );
10947 self.state.push1(old);
10948 }
10949 Operator::I64AtomicRmw8AddU { ref memarg } => {
10950 let value = self.state.pop1()?.into_int_value();
10951 let offset = self.state.pop1()?.into_int_value();
10952 let memory_index = MemoryIndex::from_u32(0);
10953 let effective_address = self.resolve_memory_ptr(
10954 memory_index,
10955 memarg,
10956 self.intrinsics.ptr_ty,
10957 offset,
10958 1,
10959 )?;
10960 self.trap_if_misaligned(memarg, effective_address, 1)?;
10961 let narrow_value = err!(self.builder.build_int_truncate(
10962 value,
10963 self.intrinsics.i8_ty,
10964 ""
10965 ));
10966 let old = self
10967 .builder
10968 .build_atomicrmw(
10969 AtomicRMWBinOp::Add,
10970 effective_address,
10971 narrow_value,
10972 AtomicOrdering::SequentiallyConsistent,
10973 )
10974 .unwrap();
10975 self.annotate_user_memaccess(
10976 memory_index,
10977 memarg,
10978 0,
10979 old.as_instruction_value().unwrap(),
10980 )?;
10981 let old = err!(
10982 self.builder
10983 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10984 );
10985 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10986 }
10987 Operator::I64AtomicRmw16AddU { ref memarg } => {
10988 let value = self.state.pop1()?.into_int_value();
10989 let offset = self.state.pop1()?.into_int_value();
10990 let memory_index = MemoryIndex::from_u32(0);
10991 let effective_address = self.resolve_memory_ptr(
10992 memory_index,
10993 memarg,
10994 self.intrinsics.ptr_ty,
10995 offset,
10996 2,
10997 )?;
10998 self.trap_if_misaligned(memarg, effective_address, 2)?;
10999 let narrow_value = err!(self.builder.build_int_truncate(
11000 value,
11001 self.intrinsics.i16_ty,
11002 ""
11003 ));
11004 let old = self
11005 .builder
11006 .build_atomicrmw(
11007 AtomicRMWBinOp::Add,
11008 effective_address,
11009 narrow_value,
11010 AtomicOrdering::SequentiallyConsistent,
11011 )
11012 .unwrap();
11013 self.annotate_user_memaccess(
11014 memory_index,
11015 memarg,
11016 0,
11017 old.as_instruction_value().unwrap(),
11018 )?;
11019 let old = err!(
11020 self.builder
11021 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11022 );
11023 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11024 }
11025 Operator::I64AtomicRmw32AddU { ref memarg } => {
11026 let value = self.state.pop1()?.into_int_value();
11027 let offset = self.state.pop1()?.into_int_value();
11028 let memory_index = MemoryIndex::from_u32(0);
11029 let effective_address = self.resolve_memory_ptr(
11030 memory_index,
11031 memarg,
11032 self.intrinsics.ptr_ty,
11033 offset,
11034 4,
11035 )?;
11036 self.trap_if_misaligned(memarg, effective_address, 4)?;
11037 let narrow_value = err!(self.builder.build_int_truncate(
11038 value,
11039 self.intrinsics.i32_ty,
11040 ""
11041 ));
11042 let old = self
11043 .builder
11044 .build_atomicrmw(
11045 AtomicRMWBinOp::Add,
11046 effective_address,
11047 narrow_value,
11048 AtomicOrdering::SequentiallyConsistent,
11049 )
11050 .unwrap();
11051 self.annotate_user_memaccess(
11052 memory_index,
11053 memarg,
11054 0,
11055 old.as_instruction_value().unwrap(),
11056 )?;
11057 let old = err!(
11058 self.builder
11059 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11060 );
11061 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11062 }
11063 Operator::I64AtomicRmwAdd { ref memarg } => {
11064 let value = self.state.pop1()?.into_int_value();
11065 let offset = self.state.pop1()?.into_int_value();
11066 let memory_index = MemoryIndex::from_u32(0);
11067 let effective_address = self.resolve_memory_ptr(
11068 memory_index,
11069 memarg,
11070 self.intrinsics.ptr_ty,
11071 offset,
11072 8,
11073 )?;
11074 self.trap_if_misaligned(memarg, effective_address, 8)?;
11075 let old = self
11076 .builder
11077 .build_atomicrmw(
11078 AtomicRMWBinOp::Add,
11079 effective_address,
11080 value,
11081 AtomicOrdering::SequentiallyConsistent,
11082 )
11083 .unwrap();
11084 self.annotate_user_memaccess(
11085 memory_index,
11086 memarg,
11087 0,
11088 old.as_instruction_value().unwrap(),
11089 )?;
11090 self.state.push1(old);
11091 }
11092 Operator::I32AtomicRmw8SubU { ref memarg } => {
11093 let value = self.state.pop1()?.into_int_value();
11094 let offset = self.state.pop1()?.into_int_value();
11095 let memory_index = MemoryIndex::from_u32(0);
11096 let effective_address = self.resolve_memory_ptr(
11097 memory_index,
11098 memarg,
11099 self.intrinsics.ptr_ty,
11100 offset,
11101 1,
11102 )?;
11103 self.trap_if_misaligned(memarg, effective_address, 1)?;
11104 let narrow_value = err!(self.builder.build_int_truncate(
11105 value,
11106 self.intrinsics.i8_ty,
11107 ""
11108 ));
11109 let old = self
11110 .builder
11111 .build_atomicrmw(
11112 AtomicRMWBinOp::Sub,
11113 effective_address,
11114 narrow_value,
11115 AtomicOrdering::SequentiallyConsistent,
11116 )
11117 .unwrap();
11118 self.annotate_user_memaccess(
11119 memory_index,
11120 memarg,
11121 0,
11122 old.as_instruction_value().unwrap(),
11123 )?;
11124 let old = err!(
11125 self.builder
11126 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11127 );
11128 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11129 }
11130 Operator::I32AtomicRmw16SubU { ref memarg } => {
11131 let value = self.state.pop1()?.into_int_value();
11132 let offset = self.state.pop1()?.into_int_value();
11133 let memory_index = MemoryIndex::from_u32(0);
11134 let effective_address = self.resolve_memory_ptr(
11135 memory_index,
11136 memarg,
11137 self.intrinsics.ptr_ty,
11138 offset,
11139 2,
11140 )?;
11141 self.trap_if_misaligned(memarg, effective_address, 2)?;
11142 let narrow_value = err!(self.builder.build_int_truncate(
11143 value,
11144 self.intrinsics.i16_ty,
11145 ""
11146 ));
11147 let old = self
11148 .builder
11149 .build_atomicrmw(
11150 AtomicRMWBinOp::Sub,
11151 effective_address,
11152 narrow_value,
11153 AtomicOrdering::SequentiallyConsistent,
11154 )
11155 .unwrap();
11156 self.annotate_user_memaccess(
11157 memory_index,
11158 memarg,
11159 0,
11160 old.as_instruction_value().unwrap(),
11161 )?;
11162 let old = err!(
11163 self.builder
11164 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11165 );
11166 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11167 }
11168 Operator::I32AtomicRmwSub { ref memarg } => {
11169 let value = self.state.pop1()?.into_int_value();
11170 let offset = self.state.pop1()?.into_int_value();
11171 let memory_index = MemoryIndex::from_u32(0);
11172 let effective_address = self.resolve_memory_ptr(
11173 memory_index,
11174 memarg,
11175 self.intrinsics.ptr_ty,
11176 offset,
11177 4,
11178 )?;
11179 self.trap_if_misaligned(memarg, effective_address, 4)?;
11180 let old = self
11181 .builder
11182 .build_atomicrmw(
11183 AtomicRMWBinOp::Sub,
11184 effective_address,
11185 value,
11186 AtomicOrdering::SequentiallyConsistent,
11187 )
11188 .unwrap();
11189 self.annotate_user_memaccess(
11190 memory_index,
11191 memarg,
11192 0,
11193 old.as_instruction_value().unwrap(),
11194 )?;
11195 self.state.push1(old);
11196 }
11197 Operator::I64AtomicRmw8SubU { ref memarg } => {
11198 let value = self.state.pop1()?.into_int_value();
11199 let offset = self.state.pop1()?.into_int_value();
11200 let memory_index = MemoryIndex::from_u32(0);
11201 let effective_address = self.resolve_memory_ptr(
11202 memory_index,
11203 memarg,
11204 self.intrinsics.ptr_ty,
11205 offset,
11206 1,
11207 )?;
11208 self.trap_if_misaligned(memarg, effective_address, 1)?;
11209 let narrow_value = err!(self.builder.build_int_truncate(
11210 value,
11211 self.intrinsics.i8_ty,
11212 ""
11213 ));
11214 let old = self
11215 .builder
11216 .build_atomicrmw(
11217 AtomicRMWBinOp::Sub,
11218 effective_address,
11219 narrow_value,
11220 AtomicOrdering::SequentiallyConsistent,
11221 )
11222 .unwrap();
11223 self.annotate_user_memaccess(
11224 memory_index,
11225 memarg,
11226 0,
11227 old.as_instruction_value().unwrap(),
11228 )?;
11229 let old = err!(
11230 self.builder
11231 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11232 );
11233 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11234 }
11235 Operator::I64AtomicRmw16SubU { ref memarg } => {
11236 let value = self.state.pop1()?.into_int_value();
11237 let offset = self.state.pop1()?.into_int_value();
11238 let memory_index = MemoryIndex::from_u32(0);
11239 let effective_address = self.resolve_memory_ptr(
11240 memory_index,
11241 memarg,
11242 self.intrinsics.ptr_ty,
11243 offset,
11244 2,
11245 )?;
11246 self.trap_if_misaligned(memarg, effective_address, 2)?;
11247 let narrow_value = err!(self.builder.build_int_truncate(
11248 value,
11249 self.intrinsics.i16_ty,
11250 ""
11251 ));
11252 let old = self
11253 .builder
11254 .build_atomicrmw(
11255 AtomicRMWBinOp::Sub,
11256 effective_address,
11257 narrow_value,
11258 AtomicOrdering::SequentiallyConsistent,
11259 )
11260 .unwrap();
11261 self.annotate_user_memaccess(
11262 memory_index,
11263 memarg,
11264 0,
11265 old.as_instruction_value().unwrap(),
11266 )?;
11267 let old = err!(
11268 self.builder
11269 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11270 );
11271 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11272 }
11273 Operator::I64AtomicRmw32SubU { ref memarg } => {
11274 let value = self.state.pop1()?.into_int_value();
11275 let offset = self.state.pop1()?.into_int_value();
11276 let memory_index = MemoryIndex::from_u32(0);
11277 let effective_address = self.resolve_memory_ptr(
11278 memory_index,
11279 memarg,
11280 self.intrinsics.ptr_ty,
11281 offset,
11282 4,
11283 )?;
11284 self.trap_if_misaligned(memarg, effective_address, 4)?;
11285 let narrow_value = err!(self.builder.build_int_truncate(
11286 value,
11287 self.intrinsics.i32_ty,
11288 ""
11289 ));
11290 let old = self
11291 .builder
11292 .build_atomicrmw(
11293 AtomicRMWBinOp::Sub,
11294 effective_address,
11295 narrow_value,
11296 AtomicOrdering::SequentiallyConsistent,
11297 )
11298 .unwrap();
11299 self.annotate_user_memaccess(
11300 memory_index,
11301 memarg,
11302 0,
11303 old.as_instruction_value().unwrap(),
11304 )?;
11305 let old = err!(
11306 self.builder
11307 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11308 );
11309 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11310 }
11311 Operator::I64AtomicRmwSub { ref memarg } => {
11312 let value = self.state.pop1()?.into_int_value();
11313 let offset = self.state.pop1()?.into_int_value();
11314 let memory_index = MemoryIndex::from_u32(0);
11315 let effective_address = self.resolve_memory_ptr(
11316 memory_index,
11317 memarg,
11318 self.intrinsics.ptr_ty,
11319 offset,
11320 8,
11321 )?;
11322 self.trap_if_misaligned(memarg, effective_address, 8)?;
11323 let old = self
11324 .builder
11325 .build_atomicrmw(
11326 AtomicRMWBinOp::Sub,
11327 effective_address,
11328 value,
11329 AtomicOrdering::SequentiallyConsistent,
11330 )
11331 .unwrap();
11332 self.annotate_user_memaccess(
11333 memory_index,
11334 memarg,
11335 0,
11336 old.as_instruction_value().unwrap(),
11337 )?;
11338 self.state.push1(old);
11339 }
11340 Operator::I32AtomicRmw8AndU { ref memarg } => {
11341 let value = self.state.pop1()?.into_int_value();
11342 let offset = self.state.pop1()?.into_int_value();
11343 let memory_index = MemoryIndex::from_u32(0);
11344 let effective_address = self.resolve_memory_ptr(
11345 memory_index,
11346 memarg,
11347 self.intrinsics.ptr_ty,
11348 offset,
11349 1,
11350 )?;
11351 self.trap_if_misaligned(memarg, effective_address, 1)?;
11352 let narrow_value = err!(self.builder.build_int_truncate(
11353 value,
11354 self.intrinsics.i8_ty,
11355 ""
11356 ));
11357 let old = self
11358 .builder
11359 .build_atomicrmw(
11360 AtomicRMWBinOp::And,
11361 effective_address,
11362 narrow_value,
11363 AtomicOrdering::SequentiallyConsistent,
11364 )
11365 .unwrap();
11366 self.annotate_user_memaccess(
11367 memory_index,
11368 memarg,
11369 0,
11370 old.as_instruction_value().unwrap(),
11371 )?;
11372 let old = err!(
11373 self.builder
11374 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11375 );
11376 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11377 }
11378 Operator::I32AtomicRmw16AndU { ref memarg } => {
11379 let value = self.state.pop1()?.into_int_value();
11380 let offset = self.state.pop1()?.into_int_value();
11381 let memory_index = MemoryIndex::from_u32(0);
11382 let effective_address = self.resolve_memory_ptr(
11383 memory_index,
11384 memarg,
11385 self.intrinsics.ptr_ty,
11386 offset,
11387 2,
11388 )?;
11389 self.trap_if_misaligned(memarg, effective_address, 2)?;
11390 let narrow_value = err!(self.builder.build_int_truncate(
11391 value,
11392 self.intrinsics.i16_ty,
11393 ""
11394 ));
11395 let old = self
11396 .builder
11397 .build_atomicrmw(
11398 AtomicRMWBinOp::And,
11399 effective_address,
11400 narrow_value,
11401 AtomicOrdering::SequentiallyConsistent,
11402 )
11403 .unwrap();
11404 self.annotate_user_memaccess(
11405 memory_index,
11406 memarg,
11407 0,
11408 old.as_instruction_value().unwrap(),
11409 )?;
11410 let old = err!(
11411 self.builder
11412 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11413 );
11414 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11415 }
11416 Operator::I32AtomicRmwAnd { ref memarg } => {
11417 let value = self.state.pop1()?.into_int_value();
11418 let offset = self.state.pop1()?.into_int_value();
11419 let memory_index = MemoryIndex::from_u32(0);
11420 let effective_address = self.resolve_memory_ptr(
11421 memory_index,
11422 memarg,
11423 self.intrinsics.ptr_ty,
11424 offset,
11425 4,
11426 )?;
11427 self.trap_if_misaligned(memarg, effective_address, 4)?;
11428 let old = self
11429 .builder
11430 .build_atomicrmw(
11431 AtomicRMWBinOp::And,
11432 effective_address,
11433 value,
11434 AtomicOrdering::SequentiallyConsistent,
11435 )
11436 .unwrap();
11437 self.annotate_user_memaccess(
11438 memory_index,
11439 memarg,
11440 0,
11441 old.as_instruction_value().unwrap(),
11442 )?;
11443 self.state.push1(old);
11444 }
11445 Operator::I64AtomicRmw8AndU { ref memarg } => {
11446 let value = self.state.pop1()?.into_int_value();
11447 let offset = self.state.pop1()?.into_int_value();
11448 let memory_index = MemoryIndex::from_u32(0);
11449 let effective_address = self.resolve_memory_ptr(
11450 memory_index,
11451 memarg,
11452 self.intrinsics.ptr_ty,
11453 offset,
11454 1,
11455 )?;
11456 self.trap_if_misaligned(memarg, effective_address, 1)?;
11457 let narrow_value = err!(self.builder.build_int_truncate(
11458 value,
11459 self.intrinsics.i8_ty,
11460 ""
11461 ));
11462 let old = self
11463 .builder
11464 .build_atomicrmw(
11465 AtomicRMWBinOp::And,
11466 effective_address,
11467 narrow_value,
11468 AtomicOrdering::SequentiallyConsistent,
11469 )
11470 .unwrap();
11471 self.annotate_user_memaccess(
11472 memory_index,
11473 memarg,
11474 0,
11475 old.as_instruction_value().unwrap(),
11476 )?;
11477 let old = err!(
11478 self.builder
11479 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11480 );
11481 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11482 }
11483 Operator::I64AtomicRmw16AndU { ref memarg } => {
11484 let value = self.state.pop1()?.into_int_value();
11485 let offset = self.state.pop1()?.into_int_value();
11486 let memory_index = MemoryIndex::from_u32(0);
11487 let effective_address = self.resolve_memory_ptr(
11488 memory_index,
11489 memarg,
11490 self.intrinsics.ptr_ty,
11491 offset,
11492 2,
11493 )?;
11494 self.trap_if_misaligned(memarg, effective_address, 2)?;
11495 let narrow_value = err!(self.builder.build_int_truncate(
11496 value,
11497 self.intrinsics.i16_ty,
11498 ""
11499 ));
11500 let old = self
11501 .builder
11502 .build_atomicrmw(
11503 AtomicRMWBinOp::And,
11504 effective_address,
11505 narrow_value,
11506 AtomicOrdering::SequentiallyConsistent,
11507 )
11508 .unwrap();
11509 self.annotate_user_memaccess(
11510 memory_index,
11511 memarg,
11512 0,
11513 old.as_instruction_value().unwrap(),
11514 )?;
11515 let old = err!(
11516 self.builder
11517 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11518 );
11519 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11520 }
11521 Operator::I64AtomicRmw32AndU { ref memarg } => {
11522 let value = self.state.pop1()?.into_int_value();
11523 let offset = self.state.pop1()?.into_int_value();
11524 let memory_index = MemoryIndex::from_u32(0);
11525 let effective_address = self.resolve_memory_ptr(
11526 memory_index,
11527 memarg,
11528 self.intrinsics.ptr_ty,
11529 offset,
11530 4,
11531 )?;
11532 self.trap_if_misaligned(memarg, effective_address, 4)?;
11533 let narrow_value = err!(self.builder.build_int_truncate(
11534 value,
11535 self.intrinsics.i32_ty,
11536 ""
11537 ));
11538 let old = self
11539 .builder
11540 .build_atomicrmw(
11541 AtomicRMWBinOp::And,
11542 effective_address,
11543 narrow_value,
11544 AtomicOrdering::SequentiallyConsistent,
11545 )
11546 .unwrap();
11547 self.annotate_user_memaccess(
11548 memory_index,
11549 memarg,
11550 0,
11551 old.as_instruction_value().unwrap(),
11552 )?;
11553 let old = err!(
11554 self.builder
11555 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11556 );
11557 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11558 }
11559 Operator::I64AtomicRmwAnd { ref memarg } => {
11560 let value = self.state.pop1()?.into_int_value();
11561 let offset = self.state.pop1()?.into_int_value();
11562 let memory_index = MemoryIndex::from_u32(0);
11563 let effective_address = self.resolve_memory_ptr(
11564 memory_index,
11565 memarg,
11566 self.intrinsics.ptr_ty,
11567 offset,
11568 8,
11569 )?;
11570 self.trap_if_misaligned(memarg, effective_address, 8)?;
11571 let old = self
11572 .builder
11573 .build_atomicrmw(
11574 AtomicRMWBinOp::And,
11575 effective_address,
11576 value,
11577 AtomicOrdering::SequentiallyConsistent,
11578 )
11579 .unwrap();
11580 self.annotate_user_memaccess(
11581 memory_index,
11582 memarg,
11583 0,
11584 old.as_instruction_value().unwrap(),
11585 )?;
11586 self.state.push1(old);
11587 }
11588 Operator::I32AtomicRmw8OrU { ref memarg } => {
11589 let value = self.state.pop1()?.into_int_value();
11590 let offset = self.state.pop1()?.into_int_value();
11591 let memory_index = MemoryIndex::from_u32(0);
11592 let effective_address = self.resolve_memory_ptr(
11593 memory_index,
11594 memarg,
11595 self.intrinsics.ptr_ty,
11596 offset,
11597 1,
11598 )?;
11599 self.trap_if_misaligned(memarg, effective_address, 1)?;
11600 let narrow_value = err!(self.builder.build_int_truncate(
11601 value,
11602 self.intrinsics.i8_ty,
11603 ""
11604 ));
11605 let old = self
11606 .builder
11607 .build_atomicrmw(
11608 AtomicRMWBinOp::Or,
11609 effective_address,
11610 narrow_value,
11611 AtomicOrdering::SequentiallyConsistent,
11612 )
11613 .unwrap();
11614 self.annotate_user_memaccess(
11615 memory_index,
11616 memarg,
11617 0,
11618 old.as_instruction_value().unwrap(),
11619 )?;
11620 let old = err!(
11621 self.builder
11622 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11623 );
11624 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11625 }
11626 Operator::I32AtomicRmw16OrU { ref memarg } => {
11627 let value = self.state.pop1()?.into_int_value();
11628 let offset = self.state.pop1()?.into_int_value();
11629 let memory_index = MemoryIndex::from_u32(0);
11630 let effective_address = self.resolve_memory_ptr(
11631 memory_index,
11632 memarg,
11633 self.intrinsics.ptr_ty,
11634 offset,
11635 2,
11636 )?;
11637 self.trap_if_misaligned(memarg, effective_address, 2)?;
11638 let narrow_value = err!(self.builder.build_int_truncate(
11639 value,
11640 self.intrinsics.i16_ty,
11641 ""
11642 ));
11643 let old = self
11644 .builder
11645 .build_atomicrmw(
11646 AtomicRMWBinOp::Or,
11647 effective_address,
11648 narrow_value,
11649 AtomicOrdering::SequentiallyConsistent,
11650 )
11651 .unwrap();
11652 self.annotate_user_memaccess(
11653 memory_index,
11654 memarg,
11655 0,
11656 old.as_instruction_value().unwrap(),
11657 )?;
11658 let old = err!(
11659 self.builder
11660 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11661 );
11662 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11663 }
11664 Operator::I32AtomicRmwOr { ref memarg } => {
11665 let value = self.state.pop1()?.into_int_value();
11666 let offset = self.state.pop1()?.into_int_value();
11667 let memory_index = MemoryIndex::from_u32(0);
11668 let effective_address = self.resolve_memory_ptr(
11669 memory_index,
11670 memarg,
11671 self.intrinsics.ptr_ty,
11672 offset,
11673 4,
11674 )?;
11675 self.trap_if_misaligned(memarg, effective_address, 4)?;
11676 let old = self
11677 .builder
11678 .build_atomicrmw(
11679 AtomicRMWBinOp::Or,
11680 effective_address,
11681 value,
11682 AtomicOrdering::SequentiallyConsistent,
11683 )
11684 .unwrap();
11685 self.annotate_user_memaccess(
11686 memory_index,
11687 memarg,
11688 0,
11689 old.as_instruction_value().unwrap(),
11690 )?;
11691 let old = err!(
11692 self.builder
11693 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11694 );
11695 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11696 }
11697 Operator::I64AtomicRmw8OrU { ref memarg } => {
11698 let value = self.state.pop1()?.into_int_value();
11699 let offset = self.state.pop1()?.into_int_value();
11700 let memory_index = MemoryIndex::from_u32(0);
11701 let effective_address = self.resolve_memory_ptr(
11702 memory_index,
11703 memarg,
11704 self.intrinsics.ptr_ty,
11705 offset,
11706 1,
11707 )?;
11708 self.trap_if_misaligned(memarg, effective_address, 1)?;
11709 let narrow_value = err!(self.builder.build_int_truncate(
11710 value,
11711 self.intrinsics.i8_ty,
11712 ""
11713 ));
11714 let old = self
11715 .builder
11716 .build_atomicrmw(
11717 AtomicRMWBinOp::Or,
11718 effective_address,
11719 narrow_value,
11720 AtomicOrdering::SequentiallyConsistent,
11721 )
11722 .unwrap();
11723 self.annotate_user_memaccess(
11724 memory_index,
11725 memarg,
11726 0,
11727 old.as_instruction_value().unwrap(),
11728 )?;
11729 let old = err!(
11730 self.builder
11731 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11732 );
11733 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11734 }
11735 Operator::I64AtomicRmw16OrU { ref memarg } => {
11736 let value = self.state.pop1()?.into_int_value();
11737 let offset = self.state.pop1()?.into_int_value();
11738 let memory_index = MemoryIndex::from_u32(0);
11739 let effective_address = self.resolve_memory_ptr(
11740 memory_index,
11741 memarg,
11742 self.intrinsics.ptr_ty,
11743 offset,
11744 2,
11745 )?;
11746 self.trap_if_misaligned(memarg, effective_address, 2)?;
11747 let narrow_value = err!(self.builder.build_int_truncate(
11748 value,
11749 self.intrinsics.i16_ty,
11750 ""
11751 ));
11752 let old = self
11753 .builder
11754 .build_atomicrmw(
11755 AtomicRMWBinOp::Or,
11756 effective_address,
11757 narrow_value,
11758 AtomicOrdering::SequentiallyConsistent,
11759 )
11760 .unwrap();
11761 self.annotate_user_memaccess(
11762 memory_index,
11763 memarg,
11764 0,
11765 old.as_instruction_value().unwrap(),
11766 )?;
11767 let old = err!(
11768 self.builder
11769 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11770 );
11771 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11772 }
11773 Operator::I64AtomicRmw32OrU { ref memarg } => {
11774 let value = self.state.pop1()?.into_int_value();
11775 let offset = self.state.pop1()?.into_int_value();
11776 let memory_index = MemoryIndex::from_u32(0);
11777 let effective_address = self.resolve_memory_ptr(
11778 memory_index,
11779 memarg,
11780 self.intrinsics.ptr_ty,
11781 offset,
11782 4,
11783 )?;
11784 self.trap_if_misaligned(memarg, effective_address, 4)?;
11785 let narrow_value = err!(self.builder.build_int_truncate(
11786 value,
11787 self.intrinsics.i32_ty,
11788 ""
11789 ));
11790 let old = self
11791 .builder
11792 .build_atomicrmw(
11793 AtomicRMWBinOp::Or,
11794 effective_address,
11795 narrow_value,
11796 AtomicOrdering::SequentiallyConsistent,
11797 )
11798 .unwrap();
11799 self.annotate_user_memaccess(
11800 memory_index,
11801 memarg,
11802 0,
11803 old.as_instruction_value().unwrap(),
11804 )?;
11805 let old = err!(
11806 self.builder
11807 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11808 );
11809 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11810 }
11811 Operator::I64AtomicRmwOr { ref memarg } => {
11812 let value = self.state.pop1()?.into_int_value();
11813 let offset = self.state.pop1()?.into_int_value();
11814 let memory_index = MemoryIndex::from_u32(0);
11815 let effective_address = self.resolve_memory_ptr(
11816 memory_index,
11817 memarg,
11818 self.intrinsics.ptr_ty,
11819 offset,
11820 8,
11821 )?;
11822 self.trap_if_misaligned(memarg, effective_address, 8)?;
11823 let old = self
11824 .builder
11825 .build_atomicrmw(
11826 AtomicRMWBinOp::Or,
11827 effective_address,
11828 value,
11829 AtomicOrdering::SequentiallyConsistent,
11830 )
11831 .unwrap();
11832 self.annotate_user_memaccess(
11833 memory_index,
11834 memarg,
11835 0,
11836 old.as_instruction_value().unwrap(),
11837 )?;
11838 self.state.push1(old);
11839 }
11840 Operator::I32AtomicRmw8XorU { ref memarg } => {
11841 let value = self.state.pop1()?.into_int_value();
11842 let offset = self.state.pop1()?.into_int_value();
11843 let memory_index = MemoryIndex::from_u32(0);
11844 let effective_address = self.resolve_memory_ptr(
11845 memory_index,
11846 memarg,
11847 self.intrinsics.ptr_ty,
11848 offset,
11849 1,
11850 )?;
11851 self.trap_if_misaligned(memarg, effective_address, 2)?;
11852 let narrow_value = err!(self.builder.build_int_truncate(
11853 value,
11854 self.intrinsics.i8_ty,
11855 ""
11856 ));
11857 let old = self
11858 .builder
11859 .build_atomicrmw(
11860 AtomicRMWBinOp::Xor,
11861 effective_address,
11862 narrow_value,
11863 AtomicOrdering::SequentiallyConsistent,
11864 )
11865 .unwrap();
11866 self.annotate_user_memaccess(
11867 memory_index,
11868 memarg,
11869 0,
11870 old.as_instruction_value().unwrap(),
11871 )?;
11872 let old = err!(
11873 self.builder
11874 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11875 );
11876 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11877 }
11878 Operator::I32AtomicRmw16XorU { ref memarg } => {
11879 let value = self.state.pop1()?.into_int_value();
11880 let offset = self.state.pop1()?.into_int_value();
11881 let memory_index = MemoryIndex::from_u32(0);
11882 let effective_address = self.resolve_memory_ptr(
11883 memory_index,
11884 memarg,
11885 self.intrinsics.ptr_ty,
11886 offset,
11887 2,
11888 )?;
11889 self.trap_if_misaligned(memarg, effective_address, 2)?;
11890 let narrow_value = err!(self.builder.build_int_truncate(
11891 value,
11892 self.intrinsics.i16_ty,
11893 ""
11894 ));
11895 let old = self
11896 .builder
11897 .build_atomicrmw(
11898 AtomicRMWBinOp::Xor,
11899 effective_address,
11900 narrow_value,
11901 AtomicOrdering::SequentiallyConsistent,
11902 )
11903 .unwrap();
11904 self.annotate_user_memaccess(
11905 memory_index,
11906 memarg,
11907 0,
11908 old.as_instruction_value().unwrap(),
11909 )?;
11910 let old = err!(
11911 self.builder
11912 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11913 );
11914 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11915 }
11916 Operator::I32AtomicRmwXor { ref memarg } => {
11917 let value = self.state.pop1()?.into_int_value();
11918 let offset = self.state.pop1()?.into_int_value();
11919 let memory_index = MemoryIndex::from_u32(0);
11920 let effective_address = self.resolve_memory_ptr(
11921 memory_index,
11922 memarg,
11923 self.intrinsics.ptr_ty,
11924 offset,
11925 4,
11926 )?;
11927 self.trap_if_misaligned(memarg, effective_address, 4)?;
11928 let old = self
11929 .builder
11930 .build_atomicrmw(
11931 AtomicRMWBinOp::Xor,
11932 effective_address,
11933 value,
11934 AtomicOrdering::SequentiallyConsistent,
11935 )
11936 .unwrap();
11937 self.annotate_user_memaccess(
11938 memory_index,
11939 memarg,
11940 0,
11941 old.as_instruction_value().unwrap(),
11942 )?;
11943 self.state.push1(old);
11944 }
11945 Operator::I64AtomicRmw8XorU { ref memarg } => {
11946 let value = self.state.pop1()?.into_int_value();
11947 let offset = self.state.pop1()?.into_int_value();
11948 let memory_index = MemoryIndex::from_u32(0);
11949 let effective_address = self.resolve_memory_ptr(
11950 memory_index,
11951 memarg,
11952 self.intrinsics.ptr_ty,
11953 offset,
11954 1,
11955 )?;
11956 self.trap_if_misaligned(memarg, effective_address, 1)?;
11957 let narrow_value = err!(self.builder.build_int_truncate(
11958 value,
11959 self.intrinsics.i8_ty,
11960 ""
11961 ));
11962 let old = self
11963 .builder
11964 .build_atomicrmw(
11965 AtomicRMWBinOp::Xor,
11966 effective_address,
11967 narrow_value,
11968 AtomicOrdering::SequentiallyConsistent,
11969 )
11970 .unwrap();
11971 self.annotate_user_memaccess(
11972 memory_index,
11973 memarg,
11974 0,
11975 old.as_instruction_value().unwrap(),
11976 )?;
11977 let old = err!(
11978 self.builder
11979 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11980 );
11981 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11982 }
11983 Operator::I64AtomicRmw16XorU { ref memarg } => {
11984 let value = self.state.pop1()?.into_int_value();
11985 let offset = self.state.pop1()?.into_int_value();
11986 let memory_index = MemoryIndex::from_u32(0);
11987 let effective_address = self.resolve_memory_ptr(
11988 memory_index,
11989 memarg,
11990 self.intrinsics.ptr_ty,
11991 offset,
11992 2,
11993 )?;
11994 self.trap_if_misaligned(memarg, effective_address, 2)?;
11995 let narrow_value = err!(self.builder.build_int_truncate(
11996 value,
11997 self.intrinsics.i16_ty,
11998 ""
11999 ));
12000 let old = self
12001 .builder
12002 .build_atomicrmw(
12003 AtomicRMWBinOp::Xor,
12004 effective_address,
12005 narrow_value,
12006 AtomicOrdering::SequentiallyConsistent,
12007 )
12008 .unwrap();
12009 self.annotate_user_memaccess(
12010 memory_index,
12011 memarg,
12012 0,
12013 old.as_instruction_value().unwrap(),
12014 )?;
12015 let old = err!(
12016 self.builder
12017 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12018 );
12019 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12020 }
12021 Operator::I64AtomicRmw32XorU { ref memarg } => {
12022 let value = self.state.pop1()?.into_int_value();
12023 let offset = self.state.pop1()?.into_int_value();
12024 let memory_index = MemoryIndex::from_u32(0);
12025 let effective_address = self.resolve_memory_ptr(
12026 memory_index,
12027 memarg,
12028 self.intrinsics.ptr_ty,
12029 offset,
12030 4,
12031 )?;
12032 self.trap_if_misaligned(memarg, effective_address, 4)?;
12033 let narrow_value = err!(self.builder.build_int_truncate(
12034 value,
12035 self.intrinsics.i32_ty,
12036 ""
12037 ));
12038 let old = self
12039 .builder
12040 .build_atomicrmw(
12041 AtomicRMWBinOp::Xor,
12042 effective_address,
12043 narrow_value,
12044 AtomicOrdering::SequentiallyConsistent,
12045 )
12046 .unwrap();
12047 self.annotate_user_memaccess(
12048 memory_index,
12049 memarg,
12050 0,
12051 old.as_instruction_value().unwrap(),
12052 )?;
12053 let old = err!(
12054 self.builder
12055 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12056 );
12057 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12058 }
12059 Operator::I64AtomicRmwXor { ref memarg } => {
12060 let value = self.state.pop1()?.into_int_value();
12061 let offset = self.state.pop1()?.into_int_value();
12062 let memory_index = MemoryIndex::from_u32(0);
12063 let effective_address = self.resolve_memory_ptr(
12064 memory_index,
12065 memarg,
12066 self.intrinsics.ptr_ty,
12067 offset,
12068 8,
12069 )?;
12070 self.trap_if_misaligned(memarg, effective_address, 8)?;
12071 let old = self
12072 .builder
12073 .build_atomicrmw(
12074 AtomicRMWBinOp::Xor,
12075 effective_address,
12076 value,
12077 AtomicOrdering::SequentiallyConsistent,
12078 )
12079 .unwrap();
12080 self.annotate_user_memaccess(
12081 memory_index,
12082 memarg,
12083 0,
12084 old.as_instruction_value().unwrap(),
12085 )?;
12086 self.state.push1(old);
12087 }
12088 Operator::I32AtomicRmw8XchgU { ref memarg } => {
12089 let value = self.state.pop1()?.into_int_value();
12090 let offset = self.state.pop1()?.into_int_value();
12091 let memory_index = MemoryIndex::from_u32(0);
12092 let effective_address = self.resolve_memory_ptr(
12093 memory_index,
12094 memarg,
12095 self.intrinsics.ptr_ty,
12096 offset,
12097 1,
12098 )?;
12099 self.trap_if_misaligned(memarg, effective_address, 1)?;
12100 let narrow_value = err!(self.builder.build_int_truncate(
12101 value,
12102 self.intrinsics.i8_ty,
12103 ""
12104 ));
12105 let old = self
12106 .builder
12107 .build_atomicrmw(
12108 AtomicRMWBinOp::Xchg,
12109 effective_address,
12110 narrow_value,
12111 AtomicOrdering::SequentiallyConsistent,
12112 )
12113 .unwrap();
12114 self.annotate_user_memaccess(
12115 memory_index,
12116 memarg,
12117 0,
12118 old.as_instruction_value().unwrap(),
12119 )?;
12120 let old = err!(
12121 self.builder
12122 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12123 );
12124 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12125 }
12126 Operator::I32AtomicRmw16XchgU { ref memarg } => {
12127 let value = self.state.pop1()?.into_int_value();
12128 let offset = self.state.pop1()?.into_int_value();
12129 let memory_index = MemoryIndex::from_u32(0);
12130 let effective_address = self.resolve_memory_ptr(
12131 memory_index,
12132 memarg,
12133 self.intrinsics.ptr_ty,
12134 offset,
12135 2,
12136 )?;
12137 self.trap_if_misaligned(memarg, effective_address, 2)?;
12138 let narrow_value = err!(self.builder.build_int_truncate(
12139 value,
12140 self.intrinsics.i16_ty,
12141 ""
12142 ));
12143 let old = self
12144 .builder
12145 .build_atomicrmw(
12146 AtomicRMWBinOp::Xchg,
12147 effective_address,
12148 narrow_value,
12149 AtomicOrdering::SequentiallyConsistent,
12150 )
12151 .unwrap();
12152 self.annotate_user_memaccess(
12153 memory_index,
12154 memarg,
12155 0,
12156 old.as_instruction_value().unwrap(),
12157 )?;
12158 let old = err!(
12159 self.builder
12160 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12161 );
12162 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12163 }
12164 Operator::I32AtomicRmwXchg { ref memarg } => {
12165 let value = self.state.pop1()?.into_int_value();
12166 let offset = self.state.pop1()?.into_int_value();
12167 let memory_index = MemoryIndex::from_u32(0);
12168 let effective_address = self.resolve_memory_ptr(
12169 memory_index,
12170 memarg,
12171 self.intrinsics.ptr_ty,
12172 offset,
12173 4,
12174 )?;
12175 self.trap_if_misaligned(memarg, effective_address, 4)?;
12176 let old = self
12177 .builder
12178 .build_atomicrmw(
12179 AtomicRMWBinOp::Xchg,
12180 effective_address,
12181 value,
12182 AtomicOrdering::SequentiallyConsistent,
12183 )
12184 .unwrap();
12185 self.annotate_user_memaccess(
12186 memory_index,
12187 memarg,
12188 0,
12189 old.as_instruction_value().unwrap(),
12190 )?;
12191 self.state.push1(old);
12192 }
12193 Operator::I64AtomicRmw8XchgU { ref memarg } => {
12194 let value = self.state.pop1()?.into_int_value();
12195 let offset = self.state.pop1()?.into_int_value();
12196 let memory_index = MemoryIndex::from_u32(0);
12197 let effective_address = self.resolve_memory_ptr(
12198 memory_index,
12199 memarg,
12200 self.intrinsics.ptr_ty,
12201 offset,
12202 1,
12203 )?;
12204 self.trap_if_misaligned(memarg, effective_address, 1)?;
12205 let narrow_value = err!(self.builder.build_int_truncate(
12206 value,
12207 self.intrinsics.i8_ty,
12208 ""
12209 ));
12210 let old = self
12211 .builder
12212 .build_atomicrmw(
12213 AtomicRMWBinOp::Xchg,
12214 effective_address,
12215 narrow_value,
12216 AtomicOrdering::SequentiallyConsistent,
12217 )
12218 .unwrap();
12219 self.annotate_user_memaccess(
12220 memory_index,
12221 memarg,
12222 0,
12223 old.as_instruction_value().unwrap(),
12224 )?;
12225 let old = err!(
12226 self.builder
12227 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12228 );
12229 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12230 }
12231 Operator::I64AtomicRmw16XchgU { ref memarg } => {
12232 let value = self.state.pop1()?.into_int_value();
12233 let offset = self.state.pop1()?.into_int_value();
12234 let memory_index = MemoryIndex::from_u32(0);
12235 let effective_address = self.resolve_memory_ptr(
12236 memory_index,
12237 memarg,
12238 self.intrinsics.ptr_ty,
12239 offset,
12240 2,
12241 )?;
12242 self.trap_if_misaligned(memarg, effective_address, 2)?;
12243 let narrow_value = err!(self.builder.build_int_truncate(
12244 value,
12245 self.intrinsics.i16_ty,
12246 ""
12247 ));
12248 let old = self
12249 .builder
12250 .build_atomicrmw(
12251 AtomicRMWBinOp::Xchg,
12252 effective_address,
12253 narrow_value,
12254 AtomicOrdering::SequentiallyConsistent,
12255 )
12256 .unwrap();
12257 self.annotate_user_memaccess(
12258 memory_index,
12259 memarg,
12260 0,
12261 old.as_instruction_value().unwrap(),
12262 )?;
12263 let old = err!(
12264 self.builder
12265 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12266 );
12267 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12268 }
12269 Operator::I64AtomicRmw32XchgU { ref memarg } => {
12270 let value = self.state.pop1()?.into_int_value();
12271 let offset = self.state.pop1()?.into_int_value();
12272 let memory_index = MemoryIndex::from_u32(0);
12273 let effective_address = self.resolve_memory_ptr(
12274 memory_index,
12275 memarg,
12276 self.intrinsics.ptr_ty,
12277 offset,
12278 4,
12279 )?;
12280 self.trap_if_misaligned(memarg, effective_address, 4)?;
12281 let narrow_value = err!(self.builder.build_int_truncate(
12282 value,
12283 self.intrinsics.i32_ty,
12284 ""
12285 ));
12286 let old = self
12287 .builder
12288 .build_atomicrmw(
12289 AtomicRMWBinOp::Xchg,
12290 effective_address,
12291 narrow_value,
12292 AtomicOrdering::SequentiallyConsistent,
12293 )
12294 .unwrap();
12295 self.annotate_user_memaccess(
12296 memory_index,
12297 memarg,
12298 0,
12299 old.as_instruction_value().unwrap(),
12300 )?;
12301 let old = err!(
12302 self.builder
12303 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12304 );
12305 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12306 }
12307 Operator::I64AtomicRmwXchg { ref memarg } => {
12308 let value = self.state.pop1()?.into_int_value();
12309 let offset = self.state.pop1()?.into_int_value();
12310 let memory_index = MemoryIndex::from_u32(0);
12311 let effective_address = self.resolve_memory_ptr(
12312 memory_index,
12313 memarg,
12314 self.intrinsics.ptr_ty,
12315 offset,
12316 8,
12317 )?;
12318 self.trap_if_misaligned(memarg, effective_address, 8)?;
12319 let old = self
12320 .builder
12321 .build_atomicrmw(
12322 AtomicRMWBinOp::Xchg,
12323 effective_address,
12324 value,
12325 AtomicOrdering::SequentiallyConsistent,
12326 )
12327 .unwrap();
12328 self.annotate_user_memaccess(
12329 memory_index,
12330 memarg,
12331 0,
12332 old.as_instruction_value().unwrap(),
12333 )?;
12334 self.state.push1(old);
12335 }
12336 Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
12337 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12338 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12339 let new = self.apply_pending_canonicalization(new, new_info)?;
12340 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12341 let offset = self.state.pop1()?.into_int_value();
12342 let memory_index = MemoryIndex::from_u32(0);
12343 let effective_address = self.resolve_memory_ptr(
12344 memory_index,
12345 memarg,
12346 self.intrinsics.ptr_ty,
12347 offset,
12348 1,
12349 )?;
12350 self.trap_if_misaligned(memarg, effective_address, 1)?;
12351 let narrow_cmp = err!(self.builder.build_int_truncate(
12352 cmp,
12353 self.intrinsics.i8_ty,
12354 ""
12355 ));
12356 let narrow_new = err!(self.builder.build_int_truncate(
12357 new,
12358 self.intrinsics.i8_ty,
12359 ""
12360 ));
12361 let old = self
12362 .builder
12363 .build_cmpxchg(
12364 effective_address,
12365 narrow_cmp,
12366 narrow_new,
12367 AtomicOrdering::SequentiallyConsistent,
12368 AtomicOrdering::SequentiallyConsistent,
12369 )
12370 .unwrap();
12371 self.annotate_user_memaccess(
12372 memory_index,
12373 memarg,
12374 0,
12375 old.as_instruction_value().unwrap(),
12376 )?;
12377 let old = self
12378 .builder
12379 .build_extract_value(old, 0, "")
12380 .unwrap()
12381 .into_int_value();
12382 let old = err!(
12383 self.builder
12384 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12385 );
12386 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12387 }
12388 Operator::I32AtomicRmw16CmpxchgU { ref memarg } => {
12389 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12390 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12391 let new = self.apply_pending_canonicalization(new, new_info)?;
12392 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12393 let offset = self.state.pop1()?.into_int_value();
12394 let memory_index = MemoryIndex::from_u32(0);
12395 let effective_address = self.resolve_memory_ptr(
12396 memory_index,
12397 memarg,
12398 self.intrinsics.ptr_ty,
12399 offset,
12400 2,
12401 )?;
12402 self.trap_if_misaligned(memarg, effective_address, 2)?;
12403 let narrow_cmp = err!(self.builder.build_int_truncate(
12404 cmp,
12405 self.intrinsics.i16_ty,
12406 ""
12407 ));
12408 let narrow_new = err!(self.builder.build_int_truncate(
12409 new,
12410 self.intrinsics.i16_ty,
12411 ""
12412 ));
12413 let old = self
12414 .builder
12415 .build_cmpxchg(
12416 effective_address,
12417 narrow_cmp,
12418 narrow_new,
12419 AtomicOrdering::SequentiallyConsistent,
12420 AtomicOrdering::SequentiallyConsistent,
12421 )
12422 .unwrap();
12423 self.annotate_user_memaccess(
12424 memory_index,
12425 memarg,
12426 0,
12427 old.as_instruction_value().unwrap(),
12428 )?;
12429 let old = self
12430 .builder
12431 .build_extract_value(old, 0, "")
12432 .unwrap()
12433 .into_int_value();
12434 let old = err!(
12435 self.builder
12436 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
12437 );
12438 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
12439 }
12440 Operator::I32AtomicRmwCmpxchg { ref memarg } => {
12441 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12442 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12443 let new = self.apply_pending_canonicalization(new, new_info)?;
12444 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12445 let offset = self.state.pop1()?.into_int_value();
12446 let memory_index = MemoryIndex::from_u32(0);
12447 let effective_address = self.resolve_memory_ptr(
12448 memory_index,
12449 memarg,
12450 self.intrinsics.ptr_ty,
12451 offset,
12452 4,
12453 )?;
12454 self.trap_if_misaligned(memarg, effective_address, 4)?;
12455 let old = self
12456 .builder
12457 .build_cmpxchg(
12458 effective_address,
12459 cmp,
12460 new,
12461 AtomicOrdering::SequentiallyConsistent,
12462 AtomicOrdering::SequentiallyConsistent,
12463 )
12464 .unwrap();
12465 self.annotate_user_memaccess(
12466 memory_index,
12467 memarg,
12468 0,
12469 old.as_instruction_value().unwrap(),
12470 )?;
12471 let old = err!(self.builder.build_extract_value(old, 0, ""));
12472 self.state.push1(old);
12473 }
12474 Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
12475 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12476 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12477 let new = self.apply_pending_canonicalization(new, new_info)?;
12478 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12479 let offset = self.state.pop1()?.into_int_value();
12480 let memory_index = MemoryIndex::from_u32(0);
12481 let effective_address = self.resolve_memory_ptr(
12482 memory_index,
12483 memarg,
12484 self.intrinsics.ptr_ty,
12485 offset,
12486 1,
12487 )?;
12488 self.trap_if_misaligned(memarg, effective_address, 1)?;
12489 let narrow_cmp = err!(self.builder.build_int_truncate(
12490 cmp,
12491 self.intrinsics.i8_ty,
12492 ""
12493 ));
12494 let narrow_new = err!(self.builder.build_int_truncate(
12495 new,
12496 self.intrinsics.i8_ty,
12497 ""
12498 ));
12499 let old = self
12500 .builder
12501 .build_cmpxchg(
12502 effective_address,
12503 narrow_cmp,
12504 narrow_new,
12505 AtomicOrdering::SequentiallyConsistent,
12506 AtomicOrdering::SequentiallyConsistent,
12507 )
12508 .unwrap();
12509 self.annotate_user_memaccess(
12510 memory_index,
12511 memarg,
12512 0,
12513 old.as_instruction_value().unwrap(),
12514 )?;
12515 let old = self
12516 .builder
12517 .build_extract_value(old, 0, "")
12518 .unwrap()
12519 .into_int_value();
12520 let old = err!(
12521 self.builder
12522 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12523 );
12524 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12525 }
12526 Operator::I64AtomicRmw16CmpxchgU { ref memarg } => {
12527 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12528 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12529 let new = self.apply_pending_canonicalization(new, new_info)?;
12530 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12531 let offset = self.state.pop1()?.into_int_value();
12532 let memory_index = MemoryIndex::from_u32(0);
12533 let effective_address = self.resolve_memory_ptr(
12534 memory_index,
12535 memarg,
12536 self.intrinsics.ptr_ty,
12537 offset,
12538 2,
12539 )?;
12540 self.trap_if_misaligned(memarg, effective_address, 2)?;
12541 let narrow_cmp = err!(self.builder.build_int_truncate(
12542 cmp,
12543 self.intrinsics.i16_ty,
12544 ""
12545 ));
12546 let narrow_new = err!(self.builder.build_int_truncate(
12547 new,
12548 self.intrinsics.i16_ty,
12549 ""
12550 ));
12551 let old = self
12552 .builder
12553 .build_cmpxchg(
12554 effective_address,
12555 narrow_cmp,
12556 narrow_new,
12557 AtomicOrdering::SequentiallyConsistent,
12558 AtomicOrdering::SequentiallyConsistent,
12559 )
12560 .unwrap();
12561 self.annotate_user_memaccess(
12562 memory_index,
12563 memarg,
12564 0,
12565 old.as_instruction_value().unwrap(),
12566 )?;
12567 let old = self
12568 .builder
12569 .build_extract_value(old, 0, "")
12570 .unwrap()
12571 .into_int_value();
12572 let old = err!(
12573 self.builder
12574 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12575 );
12576 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12577 }
12578 Operator::I64AtomicRmw32CmpxchgU { ref memarg } => {
12579 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12580 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12581 let new = self.apply_pending_canonicalization(new, new_info)?;
12582 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12583 let offset = self.state.pop1()?.into_int_value();
12584 let memory_index = MemoryIndex::from_u32(0);
12585 let effective_address = self.resolve_memory_ptr(
12586 memory_index,
12587 memarg,
12588 self.intrinsics.ptr_ty,
12589 offset,
12590 4,
12591 )?;
12592 self.trap_if_misaligned(memarg, effective_address, 4)?;
12593 let narrow_cmp = err!(self.builder.build_int_truncate(
12594 cmp,
12595 self.intrinsics.i32_ty,
12596 ""
12597 ));
12598 let narrow_new = err!(self.builder.build_int_truncate(
12599 new,
12600 self.intrinsics.i32_ty,
12601 ""
12602 ));
12603 let old = self
12604 .builder
12605 .build_cmpxchg(
12606 effective_address,
12607 narrow_cmp,
12608 narrow_new,
12609 AtomicOrdering::SequentiallyConsistent,
12610 AtomicOrdering::SequentiallyConsistent,
12611 )
12612 .unwrap();
12613 self.annotate_user_memaccess(
12614 memory_index,
12615 memarg,
12616 0,
12617 old.as_instruction_value().unwrap(),
12618 )?;
12619 let old = self
12620 .builder
12621 .build_extract_value(old, 0, "")
12622 .unwrap()
12623 .into_int_value();
12624 let old = err!(
12625 self.builder
12626 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
12627 );
12628 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
12629 }
12630 Operator::I64AtomicRmwCmpxchg { ref memarg } => {
12631 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
12632 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
12633 let new = self.apply_pending_canonicalization(new, new_info)?;
12634 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
12635 let offset = self.state.pop1()?.into_int_value();
12636 let memory_index = MemoryIndex::from_u32(0);
12637 let effective_address = self.resolve_memory_ptr(
12638 memory_index,
12639 memarg,
12640 self.intrinsics.ptr_ty,
12641 offset,
12642 8,
12643 )?;
12644 self.trap_if_misaligned(memarg, effective_address, 8)?;
12645 let old = self
12646 .builder
12647 .build_cmpxchg(
12648 effective_address,
12649 cmp,
12650 new,
12651 AtomicOrdering::SequentiallyConsistent,
12652 AtomicOrdering::SequentiallyConsistent,
12653 )
12654 .unwrap();
12655 self.annotate_user_memaccess(
12656 memory_index,
12657 memarg,
12658 0,
12659 old.as_instruction_value().unwrap(),
12660 )?;
12661 let old = err!(self.builder.build_extract_value(old, 0, ""));
12662 self.state.push1(old);
12663 }
12664
12665 Operator::MemoryGrow { mem } => {
12666 let memory_index = MemoryIndex::from_u32(mem);
12667 let delta = self.state.pop1()?;
12668 let grow_fn_ptr = self.ctx.memory_grow(memory_index, self.intrinsics)?;
12669 let grow = err!(self.builder.build_indirect_call(
12670 self.intrinsics.memory_grow_ty,
12671 grow_fn_ptr,
12672 &[
12673 vmctx.as_basic_value_enum().into(),
12674 delta.into(),
12675 self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
12676 ],
12677 "",
12678 ));
12679 self.state.push1(grow.try_as_basic_value().left().unwrap());
12680 }
12681 Operator::MemorySize { mem } => {
12682 let memory_index = MemoryIndex::from_u32(mem);
12683 let size_fn_ptr = self.ctx.memory_size(memory_index, self.intrinsics)?;
12684 let size = err!(self.builder.build_indirect_call(
12685 self.intrinsics.memory_size_ty,
12686 size_fn_ptr,
12687 &[
12688 vmctx.as_basic_value_enum().into(),
12689 self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
12690 ],
12691 "",
12692 ));
12693 self.state.push1(size.try_as_basic_value().left().unwrap());
12695 }
12696 Operator::MemoryInit { data_index, mem } => {
12697 let (dest, src, len) = self.state.pop3()?;
12698 let mem = self.intrinsics.i32_ty.const_int(mem.into(), false);
12699 let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
12700 err!(self.builder.build_call(
12701 self.intrinsics.memory_init,
12702 &[
12703 vmctx.as_basic_value_enum().into(),
12704 mem.into(),
12705 segment.into(),
12706 dest.into(),
12707 src.into(),
12708 len.into(),
12709 ],
12710 "",
12711 ));
12712 }
12713 Operator::DataDrop { data_index } => {
12714 let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
12715 err!(self.builder.build_call(
12716 self.intrinsics.data_drop,
12717 &[vmctx.as_basic_value_enum().into(), segment.into()],
12718 "",
12719 ));
12720 }
12721 Operator::MemoryCopy { dst_mem, src_mem } => {
12722 let _dst = dst_mem;
12724 let (memory_copy, src) = if let Some(local_memory_index) = self
12725 .wasm_module
12726 .local_memory_index(MemoryIndex::from_u32(src_mem))
12727 {
12728 (self.intrinsics.memory_copy, local_memory_index.as_u32())
12729 } else {
12730 (self.intrinsics.imported_memory_copy, src_mem)
12731 };
12732
12733 let (dest_pos, src_pos, len) = self.state.pop3()?;
12734 let src_index = self.intrinsics.i32_ty.const_int(src.into(), false);
12735 err!(self.builder.build_call(
12736 memory_copy,
12737 &[
12738 vmctx.as_basic_value_enum().into(),
12739 src_index.into(),
12740 dest_pos.into(),
12741 src_pos.into(),
12742 len.into(),
12743 ],
12744 "",
12745 ));
12746 }
12747 Operator::MemoryFill { mem } => {
12748 let (memory_fill, mem) = if let Some(local_memory_index) = self
12749 .wasm_module
12750 .local_memory_index(MemoryIndex::from_u32(mem))
12751 {
12752 (self.intrinsics.memory_fill, local_memory_index.as_u32())
12753 } else {
12754 (self.intrinsics.imported_memory_fill, mem)
12755 };
12756
12757 let (dst, val, len) = self.state.pop3()?;
12758 let mem_index = self.intrinsics.i32_ty.const_int(mem.into(), false);
12759 err!(self.builder.build_call(
12760 memory_fill,
12761 &[
12762 vmctx.as_basic_value_enum().into(),
12763 mem_index.into(),
12764 dst.into(),
12765 val.into(),
12766 len.into(),
12767 ],
12768 "",
12769 ));
12770 }
12771 Operator::RefNull { hty } => {
12776 let ty = err!(wpheaptype_to_type(hty));
12777 let ty = type_to_llvm(self.intrinsics, ty)?;
12778 self.state.push1(ty.const_zero());
12779 }
12780 Operator::RefIsNull => {
12781 let value = self.state.pop1()?.into_pointer_value();
12782 let is_null = err!(self.builder.build_is_null(value, ""));
12783 let is_null = err!(self.builder.build_int_z_extend(
12784 is_null,
12785 self.intrinsics.i32_ty,
12786 ""
12787 ));
12788 self.state.push1(is_null);
12789 }
12790 Operator::RefFunc { function_index } => {
12791 let index = self
12792 .intrinsics
12793 .i32_ty
12794 .const_int(function_index.into(), false);
12795 let value = err!(self.builder.build_call(
12796 self.intrinsics.func_ref,
12797 &[self.ctx.basic().into(), index.into()],
12798 "",
12799 ))
12800 .try_as_basic_value()
12801 .left()
12802 .unwrap();
12803 self.state.push1(value);
12804 }
12805 Operator::TableGet { table } => {
12806 let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12807 let elem = self.state.pop1()?;
12808 let table_get = if self
12809 .wasm_module
12810 .local_table_index(TableIndex::from_u32(table))
12811 .is_some()
12812 {
12813 self.intrinsics.table_get
12814 } else {
12815 self.intrinsics.imported_table_get
12816 };
12817 let value = err!(self.builder.build_call(
12818 table_get,
12819 &[self.ctx.basic().into(), table_index.into(), elem.into()],
12820 "",
12821 ))
12822 .try_as_basic_value()
12823 .left()
12824 .unwrap();
12825 let value = err!(
12826 self.builder.build_bit_cast(
12827 value,
12828 type_to_llvm(
12829 self.intrinsics,
12830 self.wasm_module
12831 .tables
12832 .get(TableIndex::from_u32(table))
12833 .unwrap()
12834 .ty,
12835 )?,
12836 "",
12837 )
12838 );
12839 self.state.push1(value);
12840 }
12841 Operator::TableSet { table } => {
12842 let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12843 let (elem, value) = self.state.pop2()?;
12844 let value = err!(
12845 self.builder
12846 .build_bit_cast(value, self.intrinsics.ptr_ty, "")
12847 );
12848 let table_set = if self
12849 .wasm_module
12850 .local_table_index(TableIndex::from_u32(table))
12851 .is_some()
12852 {
12853 self.intrinsics.table_set
12854 } else {
12855 self.intrinsics.imported_table_set
12856 };
12857 err!(self.builder.build_call(
12858 table_set,
12859 &[
12860 self.ctx.basic().into(),
12861 table_index.into(),
12862 elem.into(),
12863 value.into(),
12864 ],
12865 "",
12866 ));
12867 }
12868 Operator::TableCopy {
12869 dst_table,
12870 src_table,
12871 } => {
12872 let (dst, src, len) = self.state.pop3()?;
12873 let dst_table = self.intrinsics.i32_ty.const_int(dst_table as u64, false);
12874 let src_table = self.intrinsics.i32_ty.const_int(src_table as u64, false);
12875 err!(self.builder.build_call(
12876 self.intrinsics.table_copy,
12877 &[
12878 self.ctx.basic().into(),
12879 dst_table.into(),
12880 src_table.into(),
12881 dst.into(),
12882 src.into(),
12883 len.into(),
12884 ],
12885 "",
12886 ));
12887 }
12888 Operator::TableInit { elem_index, table } => {
12889 let (dst, src, len) = self.state.pop3()?;
12890 let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12891 let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12892 err!(self.builder.build_call(
12893 self.intrinsics.table_init,
12894 &[
12895 self.ctx.basic().into(),
12896 table.into(),
12897 segment.into(),
12898 dst.into(),
12899 src.into(),
12900 len.into(),
12901 ],
12902 "",
12903 ));
12904 }
12905 Operator::ElemDrop { elem_index } => {
12906 let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12907 err!(self.builder.build_call(
12908 self.intrinsics.elem_drop,
12909 &[self.ctx.basic().into(), segment.into()],
12910 "",
12911 ));
12912 }
12913 Operator::TableFill { table } => {
12914 let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12915 let (start, elem, len) = self.state.pop3()?;
12916 let elem = err!(
12917 self.builder
12918 .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12919 );
12920 err!(self.builder.build_call(
12921 self.intrinsics.table_fill,
12922 &[
12923 self.ctx.basic().into(),
12924 table.into(),
12925 start.into(),
12926 elem.into(),
12927 len.into(),
12928 ],
12929 "",
12930 ));
12931 }
12932 Operator::TableGrow { table } => {
12933 let (elem, delta) = self.state.pop2()?;
12934 let elem = err!(
12935 self.builder
12936 .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12937 );
12938 let (table_grow, table_index) = if let Some(local_table_index) = self
12939 .wasm_module
12940 .local_table_index(TableIndex::from_u32(table))
12941 {
12942 (self.intrinsics.table_grow, local_table_index.as_u32())
12943 } else {
12944 (self.intrinsics.imported_table_grow, table)
12945 };
12946 let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12947 let size = err!(self.builder.build_call(
12948 table_grow,
12949 &[
12950 self.ctx.basic().into(),
12951 elem.into(),
12952 delta.into(),
12953 table_index.into(),
12954 ],
12955 "",
12956 ))
12957 .try_as_basic_value()
12958 .left()
12959 .unwrap();
12960 self.state.push1(size);
12961 }
12962 Operator::TableSize { table } => {
12963 let (table_size, table_index) = if let Some(local_table_index) = self
12964 .wasm_module
12965 .local_table_index(TableIndex::from_u32(table))
12966 {
12967 (self.intrinsics.table_size, local_table_index.as_u32())
12968 } else {
12969 (self.intrinsics.imported_table_size, table)
12970 };
12971 let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12972 let size = err!(self.builder.build_call(
12973 table_size,
12974 &[self.ctx.basic().into(), table_index.into()],
12975 "",
12976 ))
12977 .try_as_basic_value()
12978 .left()
12979 .unwrap();
12980 self.state.push1(size);
12981 }
12982 Operator::MemoryAtomicWait32 { memarg } => {
12983 let memory_index = MemoryIndex::from_u32(memarg.memory);
12984 let (dst, val, timeout) = self.state.pop3()?;
12985 let wait32_fn_ptr = self.ctx.memory_wait32(memory_index, self.intrinsics)?;
12986 let ret = err!(
12987 self.builder.build_indirect_call(
12988 self.intrinsics.memory_wait32_ty,
12989 wait32_fn_ptr,
12990 &[
12991 vmctx.as_basic_value_enum().into(),
12992 self.intrinsics
12993 .i32_ty
12994 .const_int(memarg.memory as u64, false)
12995 .into(),
12996 dst.into(),
12997 val.into(),
12998 timeout.into(),
12999 ],
13000 "",
13001 )
13002 );
13003 self.state.push1(ret.try_as_basic_value().left().unwrap());
13004 }
13005 Operator::MemoryAtomicWait64 { memarg } => {
13006 let memory_index = MemoryIndex::from_u32(memarg.memory);
13007 let (dst, val, timeout) = self.state.pop3()?;
13008 let wait64_fn_ptr = self.ctx.memory_wait64(memory_index, self.intrinsics)?;
13009 let ret = err!(
13010 self.builder.build_indirect_call(
13011 self.intrinsics.memory_wait64_ty,
13012 wait64_fn_ptr,
13013 &[
13014 vmctx.as_basic_value_enum().into(),
13015 self.intrinsics
13016 .i32_ty
13017 .const_int(memarg.memory as u64, false)
13018 .into(),
13019 dst.into(),
13020 val.into(),
13021 timeout.into(),
13022 ],
13023 "",
13024 )
13025 );
13026 self.state.push1(ret.try_as_basic_value().left().unwrap());
13027 }
13028 Operator::MemoryAtomicNotify { memarg } => {
13029 let memory_index = MemoryIndex::from_u32(memarg.memory);
13030 let (dst, count) = self.state.pop2()?;
13031 let notify_fn_ptr = self.ctx.memory_notify(memory_index, self.intrinsics)?;
13032 let cnt = err!(
13033 self.builder.build_indirect_call(
13034 self.intrinsics.memory_notify_ty,
13035 notify_fn_ptr,
13036 &[
13037 vmctx.as_basic_value_enum().into(),
13038 self.intrinsics
13039 .i32_ty
13040 .const_int(memarg.memory as u64, false)
13041 .into(),
13042 dst.into(),
13043 count.into(),
13044 ],
13045 "",
13046 )
13047 );
13048 self.state.push1(cnt.try_as_basic_value().left().unwrap());
13049 }
13050
13051 Operator::TryTable { try_table } => {
13052 let current_block = self
13053 .builder
13054 .get_insert_block()
13055 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
13056
13057 self.builder.position_at_end(current_block);
13058
13059 let end_block = self.context.append_basic_block(self.function, "try_end");
13060
13061 let end_phis = {
13062 self.builder.position_at_end(end_block);
13063
13064 let phis = self
13065 .module_translation
13066 .blocktype_params_results(&try_table.ty)?
13067 .1
13068 .iter()
13069 .map(|&wp_ty| {
13070 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
13071 type_to_llvm(self.intrinsics, wasm_ty)
13072 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
13073 })
13074 })
13075 .collect::<Result<_, _>>()?;
13076
13077 self.builder.position_at_end(current_block);
13078 phis
13079 };
13080
13081 let catches: Vec<_> = try_table
13085 .catches
13086 .into_iter()
13087 .unique_by(|v| match v {
13088 Catch::One { tag, .. } | Catch::OneRef { tag, .. } => *tag as i32,
13089 Catch::All { .. } | Catch::AllRef { .. } => CATCH_ALL_TAG_VALUE,
13090 })
13091 .collect();
13092
13093 let null = self.intrinsics.ptr_ty.const_zero();
13095 let exception_type = self.context.struct_type(
13096 &[self.intrinsics.ptr_ty.into(), self.intrinsics.i32_ty.into()],
13097 false,
13098 );
13099
13100 let mut catch_tag_values = vec![];
13101 let mut lpad_clauses: Vec<BasicValueEnum<'ctx>> = catches
13102 .iter()
13103 .map(|catch| match catch {
13104 Catch::All { .. } | Catch::AllRef { .. } => {
13105 catch_tag_values.push(CATCH_ALL_TAG_VALUE as u32);
13106 Ok(null.into())
13107 }
13108 Catch::One { tag, .. } | Catch::OneRef { tag, .. } => {
13109 catch_tag_values.push(*tag);
13110 Ok(self.get_or_insert_tag_type_info_global(*tag as i32))
13111 }
13112 })
13113 .collect::<Result<Vec<BasicValueEnum<'ctx>>, CompileError>>()?;
13114
13115 let mut outer_catch_blocks = vec![];
13119 for outer_landingpad in self.state.landingpads.iter().rev() {
13120 for catch_info @ TagCatchInfo { tag, .. } in &outer_landingpad.tags {
13121 if !catch_tag_values.contains(tag) {
13122 catch_tag_values.push(*tag);
13123 lpad_clauses.push(if *tag as i32 == CATCH_ALL_TAG_VALUE {
13124 null.into()
13125 } else {
13126 *self.tags_cache.get(&(*tag as i32)).expect(
13127 "If a previous try_table encountered a tag, \
13128 it should be in the cache",
13129 )
13130 });
13131 outer_catch_blocks.push(*catch_info);
13132 }
13133 }
13134 }
13135
13136 let mut maybe_lpad_block = None;
13140 let mut catch_blocks = vec![];
13141 if !lpad_clauses.is_empty() {
13142 let lpad_block = self.context.append_basic_block(self.function, "catch");
13143 let catch_all_block =
13144 self.context.append_basic_block(self.function, "catch_all");
13145 let catch_specific_block = self
13146 .context
13147 .append_basic_block(self.function, "catch_specific");
13148 let catch_end_block =
13149 self.context.append_basic_block(self.function, "catch_end");
13150 let rethrow_block = self.context.append_basic_block(self.function, "rethrow");
13151
13152 self.builder.position_at_end(lpad_block);
13153
13154 let res = err!(self.builder.build_landing_pad(
13155 exception_type,
13156 self.intrinsics.personality,
13157 &lpad_clauses,
13158 false,
13159 "exc_struct",
13160 ));
13161
13162 let res = res.into_struct_value();
13163
13164 let uw_exc = err!(self.builder.build_extract_value(res, 0, "exc_ptr"));
13165 let pre_selector =
13166 err!(self.builder.build_extract_value(res, 1, "pre_selector"));
13167
13168 let pre_selector_is_zero = err!(self.builder.build_int_compare(
13171 IntPredicate::EQ,
13172 pre_selector.into_int_value(),
13173 self.intrinsics.i32_zero,
13174 "pre_selector_is_zero"
13175 ));
13176 err!(self.builder.build_conditional_branch(
13177 pre_selector_is_zero,
13178 catch_all_block,
13179 catch_specific_block
13180 ));
13181
13182 self.builder.position_at_end(catch_all_block);
13183 err!(self.builder.build_unconditional_branch(catch_end_block));
13184
13185 self.builder.position_at_end(catch_specific_block);
13186 let vmctx_alloca = err!(self.build_or_get_vmctx_alloca());
13187 let vmctx_ptr = err!(self.builder.build_load(
13188 self.intrinsics.ptr_ty,
13189 vmctx_alloca,
13190 "vmctx"
13191 ));
13192 let selector_value = err!(self.builder.build_call(
13193 self.intrinsics.personality2,
13194 &[vmctx_ptr.into(), uw_exc.into()],
13195 "selector"
13196 ));
13197 err!(self.builder.build_unconditional_branch(catch_end_block));
13198
13199 self.builder.position_at_end(catch_end_block);
13200 let selector = err!(self.builder.build_phi(self.intrinsics.i32_ty, "selector"));
13201 selector.add_incoming(&[
13202 (
13203 &self
13204 .intrinsics
13205 .i32_ty
13206 .const_int(CATCH_ALL_TAG_VALUE as u64, false),
13207 catch_all_block,
13208 ),
13209 (
13210 &selector_value
13211 .try_as_basic_value()
13212 .left()
13213 .unwrap()
13214 .into_int_value(),
13215 catch_specific_block,
13216 ),
13217 ]);
13218
13219 let uw_exc = uw_exc.into_pointer_value();
13226 let wasmer_exc = err!(self.builder.build_call(
13227 self.intrinsics.read_exception,
13228 &[uw_exc.into()],
13229 "wasmer_exc_ptr"
13230 ));
13231
13232 let wasmer_exc = wasmer_exc.as_any_value_enum().into_pointer_value();
13233 let selector = selector.as_basic_value().into_int_value();
13234
13235 for catch in catches.iter() {
13236 match catch {
13237 Catch::All { label } => {
13238 let b = self
13239 .context
13240 .append_basic_block(self.function, "catch_all_clause");
13241 self.builder.position_at_end(b);
13242 let frame = self.state.frame_at_depth(*label)?;
13243
13244 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13245
13246 self.builder.position_at_end(catch_end_block);
13247 catch_blocks.push((b, None, None));
13248 }
13249 Catch::One { tag, label } => {
13250 let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
13251 let signature = &self.wasm_module.signatures[tag_idx];
13252 let params = signature.params();
13253
13254 let b = self
13255 .context
13256 .append_basic_block(self.function, "catch_one_clause");
13257 self.builder.position_at_end(b);
13258
13259 let wasmer_exc_phi = err!(
13260 self.builder
13261 .build_phi(self.intrinsics.ptr_ty, "wasmer_exc_phi")
13262 );
13263 wasmer_exc_phi.add_incoming(&[(&wasmer_exc, catch_end_block)]);
13264
13265 let inner_exc_ty =
13267 self.get_or_insert_exception_type(*tag, signature)?;
13268
13269 let wasmer_exc_data_ptr_ptr = err!(self.builder.build_struct_gep(
13281 self.intrinsics.exc_ty,
13282 wasmer_exc_phi.as_basic_value().into_pointer_value(),
13283 1,
13284 "wasmer_exc_data_ptr_ptr"
13285 ));
13286
13287 let wasmer_exc_data_ptr = err!(self.builder.build_load(
13288 self.intrinsics.ptr_ty,
13289 wasmer_exc_data_ptr_ptr,
13290 "wasmer_exc_data_ptr"
13291 ));
13292
13293 let wasmer_exc_data_ptr = wasmer_exc_data_ptr.into_pointer_value();
13294
13295 let values = params
13297 .iter()
13298 .enumerate()
13299 .map(|(i, v)| {
13300 let name = format!("value{i}");
13301 let ptr = err!(self.builder.build_struct_gep(
13302 inner_exc_ty,
13303 wasmer_exc_data_ptr,
13304 i as u32,
13305 &(name.clone() + "ptr")
13306 ));
13307 err_nt!(self.builder.build_load(
13308 type_to_llvm(self.intrinsics, *v)?,
13309 ptr,
13310 &name,
13311 ))
13312 })
13313 .collect::<Result<Vec<_>, CompileError>>()?;
13314
13315 let frame = self.state.frame_at_depth(*label)?;
13316
13317 for (phi, value) in frame.phis().iter().zip(values.iter()) {
13320 phi.add_incoming(&[(value, b)])
13321 }
13322
13323 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13324
13325 self.builder.position_at_end(catch_end_block);
13326 catch_blocks.push((b, Some(wasmer_exc_phi), None));
13327 }
13328 Catch::OneRef { label, tag } => {
13329 let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
13330 let signature = &self.wasm_module.signatures[tag_idx];
13331 let params = signature.params();
13332
13333 let b = self
13334 .context
13335 .append_basic_block(self.function, "catch_one_ref_clause");
13336 self.builder.position_at_end(b);
13337
13338 let wasmer_exc_phi = err!(
13339 self.builder
13340 .build_phi(self.intrinsics.ptr_ty, "wasmer_exc_phi")
13341 );
13342 wasmer_exc_phi.add_incoming(&[(&wasmer_exc, catch_end_block)]);
13343
13344 let uw_exc_ptr_phi = err!(
13345 self.builder
13346 .build_phi(self.intrinsics.ptr_ty, "uw_exc_ptr_phi")
13347 );
13348 uw_exc_ptr_phi.add_incoming(&[(&uw_exc, catch_end_block)]);
13349
13350 let inner_exc_ty =
13352 self.get_or_insert_exception_type(*tag, signature)?;
13353
13354 let wasmer_exc_data_ptr_ptr = err!(self.builder.build_struct_gep(
13366 self.intrinsics.exc_ty,
13367 wasmer_exc_phi.as_basic_value().into_pointer_value(),
13368 1,
13369 "wasmer_exc_data_ptr"
13370 ));
13371
13372 let wasmer_exc_data_ptr = err!(self.builder.build_load(
13373 self.intrinsics.ptr_ty,
13374 wasmer_exc_data_ptr_ptr,
13375 "wasmer_exc_data_ptr"
13376 ));
13377
13378 let wasmer_exc_data_ptr = wasmer_exc_data_ptr.into_pointer_value();
13379
13380 let mut values = params
13382 .iter()
13383 .enumerate()
13384 .map(|(i, v)| {
13385 let name = format!("value{i}");
13386 let ptr = err!(self.builder.build_struct_gep(
13387 inner_exc_ty,
13388 wasmer_exc_data_ptr,
13389 i as u32,
13390 &(name.clone() + "ptr")
13391 ));
13392 err_nt!(self.builder.build_load(
13393 type_to_llvm(self.intrinsics, *v)?,
13394 ptr,
13395 &name,
13396 ))
13397 })
13398 .collect::<Result<Vec<_>, CompileError>>()?;
13399
13400 values.push(uw_exc_ptr_phi.as_basic_value());
13401
13402 let frame = self.state.frame_at_depth(*label)?;
13403
13404 for (phi, value) in frame.phis().iter().zip(values.iter()) {
13407 phi.add_incoming(&[(value, b)])
13408 }
13409
13410 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13411
13412 self.builder.position_at_end(catch_end_block);
13413 catch_blocks.push((b, Some(wasmer_exc_phi), Some(uw_exc_ptr_phi)));
13414 }
13415 Catch::AllRef { label } => {
13416 let b = self
13417 .context
13418 .append_basic_block(self.function, "catch_all_ref_clause");
13419 self.builder.position_at_end(b);
13420
13421 let uw_exc_ptr_phi = err!(
13422 self.builder
13423 .build_phi(self.intrinsics.ptr_ty, "uw_exc_ptr_phi")
13424 );
13425 uw_exc_ptr_phi.add_incoming(&[(&uw_exc, catch_end_block)]);
13426
13427 let frame = self.state.frame_at_depth(*label)?;
13428
13429 let phis = frame.phis();
13430
13431 for phi in phis.iter() {
13434 phi.add_incoming(&[(&uw_exc_ptr_phi.as_basic_value(), b)])
13435 }
13436
13437 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
13438
13439 self.builder.position_at_end(catch_end_block);
13440 catch_blocks.push((b, None, Some(uw_exc_ptr_phi)));
13441 }
13442 }
13443 }
13444
13445 for catch_info in &outer_catch_blocks {
13446 if let Some(phi) = catch_info.wasmer_exc_phi {
13447 phi.add_incoming(&[(
13448 &wasmer_exc.as_basic_value_enum(),
13449 catch_end_block,
13450 )]);
13451 }
13452 if let Some(phi) = catch_info.uw_exc_ptr_phi {
13453 phi.add_incoming(&[(&uw_exc.as_basic_value_enum(), catch_end_block)]);
13454 }
13455 }
13456
13457 err!(
13458 self.builder.build_switch(
13459 selector,
13460 rethrow_block,
13461 catch_blocks
13462 .iter()
13463 .enumerate()
13464 .map(|(i, v)| (
13465 self.intrinsics
13466 .i32_ty
13467 .const_int(catch_tag_values[i] as _, false),
13468 v.0
13469 ))
13470 .chain(outer_catch_blocks.iter().map(|catch_info| (
13471 self.intrinsics.i32_ty.const_int(catch_info.tag as _, false),
13472 catch_info.catch_block
13473 )))
13474 .collect::<Vec<_>>()
13475 .as_slice()
13476 )
13477 );
13478
13479 self.builder.position_at_end(rethrow_block);
13483
13484 err!(self.builder.build_call(
13485 self.intrinsics.rethrow,
13486 &[uw_exc.into()],
13487 "rethrow"
13488 ));
13489 err!(self.builder.build_unreachable());
13491
13492 maybe_lpad_block = Some(lpad_block);
13493 }
13494
13495 self.builder.position_at_end(current_block);
13497
13498 let catch_tags_and_blocks = catch_tag_values
13501 .into_iter()
13502 .zip(catch_blocks)
13503 .map(
13504 |(tag, (block, wasmer_exc_phi, uw_exc_ptr_phi))| TagCatchInfo {
13505 tag,
13506 catch_block: block,
13507 wasmer_exc_phi,
13508 uw_exc_ptr_phi,
13509 },
13510 )
13511 .collect::<Vec<_>>();
13512 self.state.push_landingpad(
13513 maybe_lpad_block,
13514 end_block,
13515 end_phis,
13516 &catch_tags_and_blocks,
13517 self.module_translation
13518 .blocktype_params_results(&try_table.ty)?
13519 .0
13520 .len(),
13521 );
13522 }
13523 Operator::Throw { tag_index } => {
13524 let current_block = self
13525 .builder
13526 .get_insert_block()
13527 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
13528
13529 let tag = self.wasm_module.tags[TagIndex::from_u32(tag_index)];
13530 let signature = &self.wasm_module.signatures[tag];
13531 let params = signature.params();
13532 let values = self.state.popn_save_extra(params.len())?;
13533
13534 let vmctx_alloca = err!(self.build_or_get_vmctx_alloca());
13535 let vmctx_ptr = err!(self.builder.build_load(
13536 self.intrinsics.ptr_ty,
13537 vmctx_alloca,
13538 "vmctx"
13539 ));
13540
13541 values.iter().enumerate().try_for_each(|(i, (v, _))| {
13542 let t = type_to_llvm(self.intrinsics, params[i])?;
13543 if t != v.get_type() {
13544 return Err(CompileError::Codegen(format!(
13545 "Incompatible types: {:?} != {:?}",
13546 t,
13547 v.get_type()
13548 )));
13549 }
13550
13551 Ok(())
13552 })?;
13553
13554 let exception_type: inkwell::types::StructType =
13555 self.get_or_insert_exception_type(tag_index, signature)?;
13556
13557 let size = exception_type.size_of().unwrap();
13558
13559 let exc = err!(self.builder.build_direct_call(
13561 self.intrinsics.alloc_exception,
13562 &[size.into()],
13563 "exception_ptr",
13564 ));
13565 let exc = exc.try_as_basic_value().left().unwrap();
13566 let exc = exc.into_pointer_value();
13567
13568 for (i, value) in values.into_iter().enumerate() {
13569 let ptr = err!(self.builder.build_struct_gep(
13570 exception_type,
13571 exc,
13572 i as u32,
13573 i.to_string().as_str(),
13574 ));
13575 err!(self.builder.build_store(ptr, value.0));
13576 }
13577
13578 if let Some(pad) = self.state.get_innermost_landingpad() {
13579 let unreachable_block = self
13580 .context
13581 .append_basic_block(self.function, "_throw_unreachable");
13582
13583 err!(
13584 self.builder.build_invoke(
13585 self.intrinsics.throw,
13586 &[
13587 self.intrinsics
13588 .i32_ty
13589 .const_int(tag_index as _, false)
13590 .into(),
13591 vmctx_ptr,
13592 exc.into(),
13593 size.into()
13594 ],
13595 unreachable_block,
13596 pad,
13597 "throw",
13598 )
13599 );
13600
13601 self.builder.position_at_end(unreachable_block);
13602 err!(self.builder.build_unreachable());
13604
13605 self.builder.position_at_end(current_block);
13606 } else {
13607 err!(
13608 self.builder.build_call(
13609 self.intrinsics.throw,
13610 &[
13611 self.intrinsics
13614 .i32_ty
13615 .const_int(tag_index as _, false)
13616 .into(),
13617 vmctx_ptr.into(),
13618 exc.into(),
13619 size.into()
13620 ],
13621 "throw"
13622 )
13623 );
13624 err!(self.builder.build_unreachable());
13626 }
13627
13628 self.state.reachable = false;
13629 }
13630 Operator::ThrowRef => {
13631 let current_block = self
13632 .builder
13633 .get_insert_block()
13634 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
13635
13636 let exc = self.state.pop1()?;
13637
13638 if let Some(pad) = self.state.get_innermost_landingpad() {
13639 let unreachable_block = self
13640 .context
13641 .append_basic_block(self.function, "_rethrow_unreachable");
13642
13643 err!(self.builder.build_invoke(
13644 self.intrinsics.rethrow,
13645 &[exc],
13646 unreachable_block,
13647 pad,
13648 "throw",
13649 ));
13650
13651 self.builder.position_at_end(unreachable_block);
13652 err!(self.builder.build_unreachable());
13654
13655 self.builder.position_at_end(current_block);
13656 } else {
13657 err!(self.builder.build_call(
13658 self.intrinsics.rethrow,
13659 &[exc.into(),],
13660 "rethrow"
13661 ));
13662 err!(self.builder.build_unreachable());
13664 }
13665
13666 self.state.reachable = false;
13667 }
13668 _ => {
13669 return Err(CompileError::Codegen(format!(
13670 "Operator {op:?} unimplemented",
13671 )));
13672 }
13673 }
13674
13675 Ok(())
13676 }
13677}
13678
13679fn is_f32_arithmetic(bits: u32) -> bool {
13680 let bits = bits & 0x7FFF_FFFF;
13682 bits < 0x7FC0_0000
13683}
13684
13685fn is_f64_arithmetic(bits: u64) -> bool {
13686 let bits = bits & 0x7FFF_FFFF_FFFF_FFFF;
13688 bits < 0x7FF8_0000_0000_0000
13689}
13690
13691const LEF32_GEQ_I32_MIN: u64 = i32::MIN as u64;
13699const GEF32_LEQ_I32_MAX: u64 = 2147483520; const LEF64_GEQ_I32_MIN: u64 = i32::MIN as u64;
13703const GEF64_LEQ_I32_MAX: u64 = i32::MAX as u64;
13705const LEF32_GEQ_U32_MIN: u64 = u32::MIN as u64;
13707const GEF32_LEQ_U32_MAX: u64 = 4294967040; const LEF64_GEQ_U32_MIN: u64 = u32::MIN as u64;
13711const GEF64_LEQ_U32_MAX: u64 = 4294967295; const LEF32_GEQ_I64_MIN: u64 = i64::MIN as u64;
13715const GEF32_LEQ_I64_MAX: u64 = 9223371487098961920; const LEF64_GEQ_I64_MIN: u64 = i64::MIN as u64;
13719const GEF64_LEQ_I64_MAX: u64 = 9223372036854774784; const LEF32_GEQ_U64_MIN: u64 = u64::MIN;
13723const GEF32_LEQ_U64_MAX: u64 = 18446742974197923840; const LEF64_GEQ_U64_MIN: u64 = u64::MIN;
13727const GEF64_LEQ_U64_MAX: u64 = 18446744073709549568;