1use std::collections::HashMap;
2
3use super::{
4 intrinsics::{
5 CtxType, FunctionCache, GlobalCache, Intrinsics, MemoryCache, tbaa_label, type_to_llvm,
6 },
7 state::{ControlFrame, ExtraInfo, IfElseState, State, TagCatchInfo},
9};
10use inkwell::{
11 AddressSpace, AtomicOrdering, AtomicRMWBinOp, DLLStorageClass, FloatPredicate, IntPredicate,
12 attributes::AttributeLoc,
13 builder::Builder,
14 context::Context,
15 module::{Linkage, Module},
16 passes::PassBuilderOptions,
17 targets::{FileType, TargetMachine},
18 types::{BasicType, BasicTypeEnum, FloatMathType, IntType, PointerType, VectorType},
19 values::{
20 BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue, FloatValue,
21 FunctionValue, InstructionOpcode, InstructionValue, IntValue, PhiValue, PointerValue,
22 VectorValue,
23 },
24};
25use itertools::Itertools;
26use smallvec::SmallVec;
27use target_lexicon::{BinaryFormat, OperatingSystem, Triple};
28
29use crate::{
30 abi::{Abi, G0M0FunctionKind, LocalFunctionG0M0params, get_abi},
31 config::LLVM,
32 error::{err, err_nt},
33 object_file::{CompiledFunction, load_object_file},
34};
35use wasmer_compiler::{
36 FunctionBinaryReader, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddlewareChain,
37 ModuleTranslationState, from_binaryreadererror_wasmerror,
38 misc::CompiledKind,
39 types::{
40 relocation::RelocationTarget,
41 symbols::{Symbol, SymbolRegistry},
42 },
43 wasmparser::{Catch, MemArg, Operator},
44 wpheaptype_to_type, wptype_to_type,
45};
46use wasmer_types::{
47 CompileError, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex,
48 ModuleInfo, SignatureIndex, TableIndex, Type,
49};
50use wasmer_types::{TagIndex, entity::PrimaryMap};
51use wasmer_vm::{MemoryStyle, TableStyle, VMOffsets};
52
53const FUNCTION_SECTION_ELF: &str = "__TEXT,wasmer_function";
54const FUNCTION_SECTION_MACHO: &str = "__TEXT";
55const FUNCTION_SEGMENT_MACHO: &str = "wasmer_function";
56
57const CATCH_ALL_TAG_VALUE: i32 = i32::MAX;
63
64const LLVMIR_LARGE_FUNCTION_THRESHOLD: usize = 100_000;
67
68pub struct FuncTranslator {
69 ctx: Context,
70 target_machine: TargetMachine,
71 target_machine_no_opt: Option<TargetMachine>,
72 abi: Box<dyn Abi>,
73 binary_fmt: BinaryFormat,
74 func_section: String,
75}
76
77impl FuncTranslator {
78 pub fn new(
79 target_machine: TargetMachine,
80 target_machine_no_opt: Option<TargetMachine>,
81 binary_fmt: BinaryFormat,
82 ) -> Result<Self, CompileError> {
83 let abi = get_abi(&target_machine);
84 Ok(Self {
85 ctx: Context::create(),
86 target_machine,
87 target_machine_no_opt,
88 abi,
89 func_section: match binary_fmt {
90 BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
91 BinaryFormat::Macho => FUNCTION_SEGMENT_MACHO.to_string(),
92 _ => {
93 return Err(CompileError::UnsupportedTarget(format!(
94 "Unsupported binary format: {binary_fmt:?}"
95 )));
96 }
97 },
98 binary_fmt,
99 })
100 }
101
102 #[allow(clippy::too_many_arguments)]
103 pub fn translate_to_module(
104 &self,
105 wasm_module: &ModuleInfo,
106 module_translation: &ModuleTranslationState,
107 local_func_index: &LocalFunctionIndex,
108 function_body: &FunctionBodyData,
109 config: &LLVM,
110 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
111 _table_styles: &PrimaryMap<TableIndex, TableStyle>,
112 symbol_registry: &dyn SymbolRegistry,
113 target: &Triple,
114 ) -> Result<Module<'_>, CompileError> {
115 let func_index = wasm_module.func_index(*local_func_index);
117 let function =
118 CompiledKind::Local(*local_func_index, wasm_module.get_function_name(func_index));
119 let function_name =
120 symbol_registry.symbol_to_name(Symbol::LocalFunction(*local_func_index));
121
122 let g0m0_is_enabled = config.enable_g0m0_opt;
123 let func_kind = if g0m0_is_enabled {
124 Some(G0M0FunctionKind::Local)
125 } else {
126 None
127 };
128
129 let module_name = match wasm_module.name.as_ref() {
130 None => format!("<anonymous module> function {function_name}"),
131 Some(module_name) => format!("module {module_name} function {function_name}"),
132 };
133 let module = self.ctx.create_module(module_name.as_str());
134
135 let target_machine = &self.target_machine;
136 let target_triple = target_machine.get_triple();
137 let target_data = target_machine.get_target_data();
138 module.set_triple(&target_triple);
139 module.set_data_layout(&target_data.get_data_layout());
140 let wasm_fn_type = wasm_module
141 .signatures
142 .get(wasm_module.functions[func_index])
143 .unwrap();
144
145 let offsets = VMOffsets::new(8, wasm_module);
147 let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data, &self.binary_fmt);
148 let (func_type, func_attrs) = self.abi.func_type_to_llvm(
149 &self.ctx,
150 &intrinsics,
151 Some(&offsets),
152 wasm_fn_type,
153 func_kind,
154 )?;
155
156 let func = module.add_function(&function_name, func_type, Some(Linkage::External));
157 for (attr, attr_loc) in &func_attrs {
158 func.add_attribute(*attr_loc, *attr);
159 }
160
161 if !matches!(target.operating_system, OperatingSystem::Windows) {
162 func.add_attribute(AttributeLoc::Function, intrinsics.stack_probe);
163 }
164
165 func.add_attribute(AttributeLoc::Function, intrinsics.uwtable);
166 func.add_attribute(AttributeLoc::Function, intrinsics.frame_pointer);
167
168 let section = match self.binary_fmt {
169 BinaryFormat::Elf => FUNCTION_SECTION_ELF.to_string(),
170 BinaryFormat::Macho => {
171 format!("{FUNCTION_SECTION_MACHO},{FUNCTION_SEGMENT_MACHO}")
172 }
173 _ => {
174 return Err(CompileError::UnsupportedTarget(format!(
175 "Unsupported binary format: {:?}",
176 self.binary_fmt
177 )));
178 }
179 };
180
181 func.set_personality_function(intrinsics.personality);
182 func.as_global_value().set_section(Some(§ion));
183
184 func.set_linkage(Linkage::DLLExport);
185 func.as_global_value()
186 .set_dll_storage_class(DLLStorageClass::Export);
187
188 let entry = self.ctx.append_basic_block(func, "entry");
189 let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
190 let return_ = self.ctx.append_basic_block(func, "return");
191 let alloca_builder = self.ctx.create_builder();
192 let cache_builder = self.ctx.create_builder();
193 let builder = self.ctx.create_builder();
194 cache_builder.position_at_end(entry);
195 let br = err!(cache_builder.build_unconditional_branch(start_of_code));
196 alloca_builder.position_before(&br);
197 cache_builder.position_before(&br);
198 builder.position_at_end(start_of_code);
199
200 let mut state = State::new();
201 builder.position_at_end(return_);
202 let phis: SmallVec<[PhiValue; 1]> = wasm_fn_type
203 .results()
204 .iter()
205 .map(|&wasm_ty| {
206 type_to_llvm(&intrinsics, wasm_ty).map(|ty| builder.build_phi(ty, "").unwrap())
207 })
208 .collect::<Result<_, _>>()?;
209 state.push_block(return_, phis, 0);
210 builder.position_at_end(start_of_code);
211
212 let mut reader = MiddlewareBinaryReader::new_with_offset(
213 function_body.data,
214 function_body.module_offset,
215 );
216 reader.set_middleware_chain(
217 config
218 .middlewares
219 .generate_function_middleware_chain(*local_func_index),
220 );
221
222 let mut params = vec![];
223 let first_param =
224 if func_type.get_return_type().is_none() && wasm_fn_type.results().len() > 1 {
225 if g0m0_is_enabled { 4 } else { 2 }
226 } else if g0m0_is_enabled {
227 3
228 } else {
229 1
230 };
231 let mut is_first_alloca = true;
232 let mut insert_alloca = |ty, name: String| -> Result<PointerValue, CompileError> {
233 let alloca = err!(alloca_builder.build_alloca(ty, &name));
234 if is_first_alloca {
235 alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
236 is_first_alloca = false;
237 }
238 Ok(alloca)
239 };
240
241 for idx in 0..wasm_fn_type.params().len() {
259 let ty = wasm_fn_type.params()[idx];
260 let ty = type_to_llvm(&intrinsics, ty)?;
261 let value = func
262 .get_nth_param((idx as u32).checked_add(first_param).unwrap())
263 .unwrap();
264 let alloca = insert_alloca(ty, format!("param_{idx}"))?;
265 err!(cache_builder.build_store(alloca, value));
266 params.push((ty, alloca));
267 }
268
269 let mut locals = vec![];
270 let num_locals = reader.read_local_count()?;
271 for idx in 0..num_locals {
272 let (count, ty) = reader.read_local_decl()?;
273 let ty = err!(wptype_to_type(ty));
274 let ty = type_to_llvm(&intrinsics, ty)?;
275 for _ in 0..count {
276 let alloca = insert_alloca(ty, format!("local_{idx}"))?;
277 err!(cache_builder.build_store(alloca, ty.const_zero()));
278 locals.push((ty, alloca));
279 }
280 }
281
282 let mut params_locals = params.clone();
283 params_locals.extend(locals.iter().cloned());
284
285 let mut g0m0_params = None;
286
287 if g0m0_is_enabled {
288 let value = self.abi.get_g0_ptr_param(&func);
289 let g0 = insert_alloca(intrinsics.i32_ty.as_basic_type_enum(), "g0".to_string())?;
290 err!(cache_builder.build_store(g0, value));
291 g0.set_name("g0");
292 let m0 = self.abi.get_m0_ptr_param(&func);
293 m0.set_name("m0_base_ptr");
294
295 g0m0_params = Some((g0, m0));
296 }
297
298 let mut fcg = LLVMFunctionCodeGenerator {
299 g0m0: g0m0_params,
300 context: &self.ctx,
301 builder,
302 alloca_builder,
303 intrinsics: &intrinsics,
304 state,
305 function: func,
306 locals: params_locals,
307 ctx: CtxType::new(wasm_module, &func, &cache_builder, &*self.abi, config),
308 unreachable_depth: 0,
309 memory_styles,
310 _table_styles,
311 module: &module,
312 module_translation,
313 wasm_module,
314 symbol_registry,
315 abi: &*self.abi,
316 config,
317 tags_cache: HashMap::new(),
318 binary_fmt: self.binary_fmt,
319 };
320
321 fcg.ctx.add_func(
322 func_index,
323 func.as_global_value().as_pointer_value(),
324 func_type,
325 fcg.ctx.basic(),
326 &func_attrs,
327 );
328
329 while fcg.state.has_control_frames() {
330 let pos = reader.current_position() as u32;
331 let op = reader.read_operator()?;
332 fcg.translate_operator(op, pos)?;
333 }
334
335 fcg.finalize(wasm_fn_type)?;
336
337 if let Some(ref callbacks) = config.callbacks {
338 callbacks.preopt_ir(&function, &module);
339 }
340
341 let mut passes = vec![];
342
343 if config.enable_verifier {
344 passes.push("verify");
345 }
346
347 passes.push("sccp");
348 passes.push("early-cse");
349 passes.push("adce");
351 passes.push("sroa");
352 passes.push("aggressive-instcombine");
353 passes.push("jump-threading");
354 passes.push("simplifycfg");
356 passes.push("reassociate");
357 passes.push("loop-rotate");
358 passes.push("indvars");
359 passes.push("sccp");
363 passes.push("reassociate");
364 passes.push("simplifycfg");
365 passes.push("gvn");
366 passes.push("memcpyopt");
367 passes.push("dse");
368 passes.push("dce");
369 passes.push("reassociate");
371 passes.push("simplifycfg");
372 passes.push("mem2reg");
373
374 module
375 .run_passes(
376 passes.join(",").as_str(),
377 target_machine,
378 PassBuilderOptions::create(),
379 )
380 .unwrap();
381
382 if let Some(ref callbacks) = config.callbacks {
383 callbacks.postopt_ir(&function, &module);
384 }
385
386 Ok(module)
387 }
388
389 #[allow(clippy::too_many_arguments)]
390 pub fn translate(
391 &self,
392 wasm_module: &ModuleInfo,
393 module_translation: &ModuleTranslationState,
394 local_func_index: &LocalFunctionIndex,
395 function_body: &FunctionBodyData,
396 config: &LLVM,
397 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
398 table_styles: &PrimaryMap<TableIndex, TableStyle>,
399 symbol_registry: &dyn SymbolRegistry,
400 target: &Triple,
401 ) -> Result<CompiledFunction, CompileError> {
402 let module = self.translate_to_module(
403 wasm_module,
404 module_translation,
405 local_func_index,
406 function_body,
407 config,
408 memory_styles,
409 table_styles,
410 symbol_registry,
411 target,
412 )?;
413 let function = CompiledKind::Local(
414 *local_func_index,
415 wasm_module.get_function_name(wasm_module.func_index(*local_func_index)),
416 );
417
418 let target_machine = if function_body.data.len() > LLVMIR_LARGE_FUNCTION_THRESHOLD {
419 self.target_machine_no_opt
420 .as_ref()
421 .unwrap_or(&self.target_machine)
422 } else {
423 &self.target_machine
424 };
425 let memory_buffer = target_machine
426 .write_to_memory_buffer(&module, FileType::Object)
427 .unwrap();
428
429 if let Some(ref callbacks) = config.callbacks {
430 callbacks.obj_memory_buffer(&function, &memory_buffer);
431 let asm_buffer = target_machine
432 .write_to_memory_buffer(&module, FileType::Assembly)
433 .unwrap();
434 callbacks.asm_memory_buffer(&function, &asm_buffer)
435 }
436
437 let mem_buf_slice = memory_buffer.as_slice();
438
439 load_object_file(
440 mem_buf_slice,
441 &self.func_section,
442 RelocationTarget::LocalFunc(*local_func_index),
443 |name: &str| {
444 Ok({
445 let name = if matches!(self.binary_fmt, BinaryFormat::Macho) {
446 if name.starts_with("_") {
447 name.replacen("_", "", 1)
448 } else {
449 name.to_string()
450 }
451 } else {
452 name.to_string()
453 };
454 if let Some(Symbol::LocalFunction(local_func_index)) =
455 symbol_registry.name_to_symbol(&name)
456 {
457 Some(RelocationTarget::LocalFunc(local_func_index))
458 } else {
459 None
460 }
461 })
462 },
463 self.binary_fmt,
464 )
465 }
466}
467
468impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
469 fn splat_vector(
471 &self,
472 value: BasicValueEnum<'ctx>,
473 vec_ty: VectorType<'ctx>,
474 ) -> Result<VectorValue<'ctx>, CompileError> {
475 err_nt!(
478 self.builder.build_shuffle_vector(
479 err!(self.builder.build_insert_element(
480 vec_ty.get_undef(),
481 value,
482 self.intrinsics.i32_zero,
483 "",
484 )),
485 vec_ty.get_undef(),
486 self.intrinsics
487 .i32_ty
488 .vec_type(vec_ty.get_size())
489 .const_zero(),
490 "",
491 )
492 )
493 }
494
495 #[allow(clippy::too_many_arguments)]
498 fn trunc_sat<T: FloatMathType<'ctx>>(
499 &self,
500 fvec_ty: T,
501 ivec_ty: T::MathConvType,
502 lower_bound: u64, upper_bound: u64, int_min_value: u64,
505 int_max_value: u64,
506 value: IntValue<'ctx>,
507 ) -> Result<VectorValue<'ctx>, CompileError> {
508 let fvec_ty = fvec_ty.as_basic_type_enum().into_vector_type();
522 let ivec_ty = ivec_ty.as_basic_type_enum().into_vector_type();
523 let fvec_element_ty = fvec_ty.get_element_type().into_float_type();
524 let ivec_element_ty = ivec_ty.get_element_type().into_int_type();
525
526 let is_signed = int_min_value != 0;
527 let int_min_value = self.splat_vector(
528 ivec_element_ty
529 .const_int(int_min_value, is_signed)
530 .as_basic_value_enum(),
531 ivec_ty,
532 )?;
533 let int_max_value = self.splat_vector(
534 ivec_element_ty
535 .const_int(int_max_value, is_signed)
536 .as_basic_value_enum(),
537 ivec_ty,
538 )?;
539 let lower_bound = if is_signed {
540 err!(self.builder.build_signed_int_to_float(
541 ivec_element_ty.const_int(lower_bound, is_signed),
542 fvec_element_ty,
543 "",
544 ))
545 } else {
546 err!(self.builder.build_unsigned_int_to_float(
547 ivec_element_ty.const_int(lower_bound, is_signed),
548 fvec_element_ty,
549 "",
550 ))
551 };
552 let upper_bound = if is_signed {
553 err!(self.builder.build_signed_int_to_float(
554 ivec_element_ty.const_int(upper_bound, is_signed),
555 fvec_element_ty,
556 "",
557 ))
558 } else {
559 err!(self.builder.build_unsigned_int_to_float(
560 ivec_element_ty.const_int(upper_bound, is_signed),
561 fvec_element_ty,
562 "",
563 ))
564 };
565
566 let value = err!(self.builder.build_bit_cast(value, fvec_ty, "")).into_vector_value();
567 let zero = fvec_ty.const_zero();
568 let lower_bound = self.splat_vector(lower_bound.as_basic_value_enum(), fvec_ty)?;
569 let upper_bound = self.splat_vector(upper_bound.as_basic_value_enum(), fvec_ty)?;
570 let nan_cmp =
571 err!(
572 self.builder
573 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
574 );
575 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
576 FloatPredicate::OGT,
577 value,
578 upper_bound,
579 "above_upper_bound",
580 ));
581 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
582 FloatPredicate::OLT,
583 value,
584 lower_bound,
585 "below_lower_bound",
586 ));
587 let not_representable = err!(self.builder.build_or(
588 err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
589 below_lower_bound_cmp,
590 "not_representable_as_int",
591 ));
592 let value =
593 err!(
594 self.builder
595 .build_select(not_representable, zero, value, "safe_to_convert")
596 )
597 .into_vector_value();
598 let value = if is_signed {
599 self.builder
600 .build_float_to_signed_int(value, ivec_ty, "as_int")
601 } else {
602 self.builder
603 .build_float_to_unsigned_int(value, ivec_ty, "as_int")
604 };
605
606 let value = err!(value);
607 let value =
608 err!(
609 self.builder
610 .build_select(above_upper_bound_cmp, int_max_value, value, "")
611 )
612 .into_vector_value();
613 err_nt!(
614 self.builder
615 .build_select(below_lower_bound_cmp, int_min_value, value, "")
616 .map(|v| v.into_vector_value())
617 )
618 }
619
620 #[allow(clippy::too_many_arguments)]
623 fn trunc_sat_into_int<T: FloatMathType<'ctx>>(
624 &self,
625 fvec_ty: T,
626 ivec_ty: T::MathConvType,
627 lower_bound: u64, upper_bound: u64, int_min_value: u64,
630 int_max_value: u64,
631 value: IntValue<'ctx>,
632 ) -> Result<IntValue<'ctx>, CompileError> {
633 let res = self.trunc_sat(
634 fvec_ty,
635 ivec_ty,
636 lower_bound,
637 upper_bound,
638 int_min_value,
639 int_max_value,
640 value,
641 )?;
642 err_nt!(
643 self.builder
644 .build_bit_cast(res, self.intrinsics.i128_ty, "")
645 .map(|v| v.into_int_value())
646 )
647 }
648
649 fn trunc_sat_scalar(
652 &self,
653 int_ty: IntType<'ctx>,
654 lower_bound: u64, upper_bound: u64, int_min_value: u64,
657 int_max_value: u64,
658 value: FloatValue<'ctx>,
659 ) -> Result<IntValue<'ctx>, CompileError> {
660 let is_signed = int_min_value != 0;
676 let int_min_value = int_ty.const_int(int_min_value, is_signed);
677 let int_max_value = int_ty.const_int(int_max_value, is_signed);
678
679 let lower_bound = if is_signed {
680 err!(self.builder.build_signed_int_to_float(
681 int_ty.const_int(lower_bound, is_signed),
682 value.get_type(),
683 "",
684 ))
685 } else {
686 err!(self.builder.build_unsigned_int_to_float(
687 int_ty.const_int(lower_bound, is_signed),
688 value.get_type(),
689 "",
690 ))
691 };
692 let upper_bound = if is_signed {
693 err!(self.builder.build_signed_int_to_float(
694 int_ty.const_int(upper_bound, is_signed),
695 value.get_type(),
696 "",
697 ))
698 } else {
699 err!(self.builder.build_unsigned_int_to_float(
700 int_ty.const_int(upper_bound, is_signed),
701 value.get_type(),
702 "",
703 ))
704 };
705
706 let zero = value.get_type().const_zero();
707
708 let nan_cmp =
709 err!(
710 self.builder
711 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
712 );
713 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
714 FloatPredicate::OGT,
715 value,
716 upper_bound,
717 "above_upper_bound",
718 ));
719 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
720 FloatPredicate::OLT,
721 value,
722 lower_bound,
723 "below_lower_bound",
724 ));
725 let not_representable = err!(self.builder.build_or(
726 err!(self.builder.build_or(nan_cmp, above_upper_bound_cmp, "")),
727 below_lower_bound_cmp,
728 "not_representable_as_int",
729 ));
730 let value =
731 err!(
732 self.builder
733 .build_select(not_representable, zero, value, "safe_to_convert")
734 )
735 .into_float_value();
736 let value = if is_signed {
737 err!(
738 self.builder
739 .build_float_to_signed_int(value, int_ty, "as_int")
740 )
741 } else {
742 err!(
743 self.builder
744 .build_float_to_unsigned_int(value, int_ty, "as_int")
745 )
746 };
747 let value =
748 err!(
749 self.builder
750 .build_select(above_upper_bound_cmp, int_max_value, value, "")
751 )
752 .into_int_value();
753 let value =
754 err!(
755 self.builder
756 .build_select(below_lower_bound_cmp, int_min_value, value, "")
757 )
758 .into_int_value();
759
760 err_nt!(
761 self.builder
762 .build_bit_cast(value, int_ty, "")
763 .map(|v| v.into_int_value())
764 )
765 }
766
767 fn trap_if_not_representable_as_int(
768 &self,
769 lower_bound: u64, upper_bound: u64, value: FloatValue,
772 ) -> Result<(), CompileError> {
773 let float_ty = value.get_type();
774 let int_ty = if float_ty == self.intrinsics.f32_ty {
775 self.intrinsics.i32_ty
776 } else {
777 self.intrinsics.i64_ty
778 };
779
780 let lower_bound = err!(self.builder.build_bit_cast(
781 int_ty.const_int(lower_bound, false),
782 float_ty,
783 ""
784 ))
785 .into_float_value();
786 let upper_bound = err!(self.builder.build_bit_cast(
787 int_ty.const_int(upper_bound, false),
788 float_ty,
789 ""
790 ))
791 .into_float_value();
792
793 let above_upper_bound_cmp = err!(self.builder.build_float_compare(
797 FloatPredicate::UGT,
798 value,
799 upper_bound,
800 "above_upper_bound",
801 ));
802 let below_lower_bound_cmp = err!(self.builder.build_float_compare(
803 FloatPredicate::ULT,
804 value,
805 lower_bound,
806 "below_lower_bound",
807 ));
808 let out_of_bounds = err!(self.builder.build_or(
809 above_upper_bound_cmp,
810 below_lower_bound_cmp,
811 "out_of_bounds",
812 ));
813
814 let failure_block = self
815 .context
816 .append_basic_block(self.function, "conversion_failure_block");
817 let continue_block = self
818 .context
819 .append_basic_block(self.function, "conversion_success_block");
820
821 err!(
822 self.builder
823 .build_conditional_branch(out_of_bounds, failure_block, continue_block)
824 );
825 self.builder.position_at_end(failure_block);
826 let is_nan =
827 err!(
828 self.builder
829 .build_float_compare(FloatPredicate::UNO, value, value, "is_nan")
830 );
831 let trap_code = err!(self.builder.build_select(
832 is_nan,
833 self.intrinsics.trap_bad_conversion_to_integer,
834 self.intrinsics.trap_illegal_arithmetic,
835 "",
836 ));
837 err!(
838 self.builder
839 .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
840 );
841 err!(self.builder.build_unreachable());
842 self.builder.position_at_end(continue_block);
843
844 Ok(())
845 }
846
847 fn trap_if_zero_or_overflow(
848 &self,
849 left: IntValue,
850 right: IntValue,
851 ) -> Result<(), CompileError> {
852 let int_type = left.get_type();
853
854 let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
855 let min_value = int_type.const_int(i32::MIN as u64, false);
856 let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
857 (min_value, neg_one_value)
858 } else if int_type == self.intrinsics.i64_ty {
859 let min_value = int_type.const_int(i64::MIN as u64, false);
860 let neg_one_value = int_type.const_int(-1i64 as u64, false);
861 (min_value, neg_one_value)
862 } else {
863 unreachable!()
864 };
865
866 let divisor_is_zero = err!(self.builder.build_int_compare(
867 IntPredicate::EQ,
868 right,
869 int_type.const_zero(),
870 "divisor_is_zero",
871 ));
872 let should_trap = err!(self.builder.build_or(
873 divisor_is_zero,
874 err!(self.builder.build_and(
875 err!(self.builder.build_int_compare(
876 IntPredicate::EQ,
877 left,
878 min_value,
879 "left_is_min"
880 )),
881 err!(self.builder.build_int_compare(
882 IntPredicate::EQ,
883 right,
884 neg_one_value,
885 "right_is_neg_one",
886 )),
887 "div_will_overflow",
888 )),
889 "div_should_trap",
890 ));
891
892 let should_trap = err!(self.builder.build_call(
893 self.intrinsics.expect_i1,
894 &[
895 should_trap.into(),
896 self.intrinsics.i1_ty.const_zero().into(),
897 ],
898 "should_trap_expect",
899 ))
900 .try_as_basic_value()
901 .unwrap_basic()
902 .into_int_value();
903
904 let shouldnt_trap_block = self
905 .context
906 .append_basic_block(self.function, "shouldnt_trap_block");
907 let should_trap_block = self
908 .context
909 .append_basic_block(self.function, "should_trap_block");
910 err!(self.builder.build_conditional_branch(
911 should_trap,
912 should_trap_block,
913 shouldnt_trap_block
914 ));
915 self.builder.position_at_end(should_trap_block);
916 let trap_code = err!(self.builder.build_select(
917 divisor_is_zero,
918 self.intrinsics.trap_integer_division_by_zero,
919 self.intrinsics.trap_illegal_arithmetic,
920 "",
921 ));
922 err!(
923 self.builder
924 .build_call(self.intrinsics.throw_trap, &[trap_code.into()], "throw")
925 );
926 err!(self.builder.build_unreachable());
927 self.builder.position_at_end(shouldnt_trap_block);
928
929 Ok(())
930 }
931
932 fn trap_if_zero(&self, value: IntValue) -> Result<(), CompileError> {
933 let int_type = value.get_type();
934 let should_trap = err!(self.builder.build_int_compare(
935 IntPredicate::EQ,
936 value,
937 int_type.const_zero(),
938 "divisor_is_zero",
939 ));
940
941 let should_trap = err!(self.builder.build_call(
942 self.intrinsics.expect_i1,
943 &[
944 should_trap.into(),
945 self.intrinsics.i1_ty.const_zero().into(),
946 ],
947 "should_trap_expect",
948 ))
949 .try_as_basic_value()
950 .unwrap_basic()
951 .into_int_value();
952
953 let shouldnt_trap_block = self
954 .context
955 .append_basic_block(self.function, "shouldnt_trap_block");
956 let should_trap_block = self
957 .context
958 .append_basic_block(self.function, "should_trap_block");
959 err!(self.builder.build_conditional_branch(
960 should_trap,
961 should_trap_block,
962 shouldnt_trap_block
963 ));
964 self.builder.position_at_end(should_trap_block);
965 err!(self.builder.build_call(
966 self.intrinsics.throw_trap,
967 &[self.intrinsics.trap_integer_division_by_zero.into()],
968 "throw",
969 ));
970 err!(self.builder.build_unreachable());
971 self.builder.position_at_end(shouldnt_trap_block);
972
973 Ok(())
974 }
975
976 fn v128_into_int_vec(
977 &self,
978 value: BasicValueEnum<'ctx>,
979 info: ExtraInfo,
980 int_vec_ty: VectorType<'ctx>,
981 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
982 let (value, info) = if self.config.enable_nan_canonicalization {
983 if info.has_pending_f32_nan() {
984 let value = err!(
985 self.builder
986 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
987 );
988 (self.canonicalize_nans(value)?, info.strip_pending())
989 } else if info.has_pending_f64_nan() {
990 let value = err!(
991 self.builder
992 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
993 );
994 (self.canonicalize_nans(value)?, info.strip_pending())
995 } else {
996 (value, info)
997 }
998 } else {
999 (value, info)
1000 };
1001 Ok((
1002 err!(self.builder.build_bit_cast(value, int_vec_ty, "")).into_vector_value(),
1003 info,
1004 ))
1005 }
1006
1007 fn v128_into_i8x16(
1008 &self,
1009 value: BasicValueEnum<'ctx>,
1010 info: ExtraInfo,
1011 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1012 self.v128_into_int_vec(value, info, self.intrinsics.i8x16_ty)
1013 }
1014
1015 fn v128_into_i16x8(
1016 &self,
1017 value: BasicValueEnum<'ctx>,
1018 info: ExtraInfo,
1019 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1020 self.v128_into_int_vec(value, info, self.intrinsics.i16x8_ty)
1021 }
1022
1023 fn v128_into_i32x4(
1024 &self,
1025 value: BasicValueEnum<'ctx>,
1026 info: ExtraInfo,
1027 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1028 self.v128_into_int_vec(value, info, self.intrinsics.i32x4_ty)
1029 }
1030
1031 fn v128_into_i64x2(
1032 &self,
1033 value: BasicValueEnum<'ctx>,
1034 info: ExtraInfo,
1035 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1036 self.v128_into_int_vec(value, info, self.intrinsics.i64x2_ty)
1037 }
1038
1039 fn v128_into_f32x4(
1042 &self,
1043 value: BasicValueEnum<'ctx>,
1044 info: ExtraInfo,
1045 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1046 let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f64_nan()
1047 {
1048 let value = err!(
1049 self.builder
1050 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1051 );
1052 (self.canonicalize_nans(value)?, info.strip_pending())
1053 } else {
1054 (value, info)
1055 };
1056 Ok((
1057 err!(
1058 self.builder
1059 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1060 )
1061 .into_vector_value(),
1062 info,
1063 ))
1064 }
1065
1066 fn v128_into_f64x2(
1069 &self,
1070 value: BasicValueEnum<'ctx>,
1071 info: ExtraInfo,
1072 ) -> Result<(VectorValue<'ctx>, ExtraInfo), CompileError> {
1073 let (value, info) = if self.config.enable_nan_canonicalization && info.has_pending_f32_nan()
1074 {
1075 let value = err!(
1076 self.builder
1077 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1078 );
1079 (self.canonicalize_nans(value)?, info.strip_pending())
1080 } else {
1081 (value, info)
1082 };
1083 Ok((
1084 err!(
1085 self.builder
1086 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1087 )
1088 .into_vector_value(),
1089 info,
1090 ))
1091 }
1092
1093 fn apply_pending_canonicalization(
1094 &self,
1095 value: BasicValueEnum<'ctx>,
1096 info: ExtraInfo,
1097 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1098 if !self.config.enable_nan_canonicalization {
1099 return Ok(value);
1100 }
1101
1102 if info.has_pending_f32_nan() {
1103 if value.get_type().is_vector_type()
1104 || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1105 {
1106 let ty = value.get_type();
1107 let value = err!(
1108 self.builder
1109 .build_bit_cast(value, self.intrinsics.f32x4_ty, "")
1110 );
1111 let value = self.canonicalize_nans(value)?;
1112 err_nt!(self.builder.build_bit_cast(value, ty, ""))
1113 } else {
1114 self.canonicalize_nans(value)
1115 }
1116 } else if info.has_pending_f64_nan() {
1117 if value.get_type().is_vector_type()
1118 || value.get_type() == self.intrinsics.i128_ty.as_basic_type_enum()
1119 {
1120 let ty = value.get_type();
1121 let value = err!(
1122 self.builder
1123 .build_bit_cast(value, self.intrinsics.f64x2_ty, "")
1124 );
1125 let value = self.canonicalize_nans(value)?;
1126 err_nt!(self.builder.build_bit_cast(value, ty, ""))
1127 } else {
1128 self.canonicalize_nans(value)
1129 }
1130 } else {
1131 Ok(value)
1132 }
1133 }
1134
1135 fn canonicalize_nans(
1137 &self,
1138 value: BasicValueEnum<'ctx>,
1139 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1140 if !self.config.enable_nan_canonicalization {
1141 return Ok(value);
1142 }
1143
1144 let f_ty = value.get_type();
1145 if f_ty.is_vector_type() {
1146 let value = value.into_vector_value();
1147 let f_ty = f_ty.into_vector_type();
1148 let zero = f_ty.const_zero();
1149 let nan_cmp =
1150 err!(
1151 self.builder
1152 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1153 );
1154 let canonical_qnan = f_ty
1155 .get_element_type()
1156 .into_float_type()
1157 .const_float(f64::NAN);
1158 let canonical_qnan = self.splat_vector(canonical_qnan.as_basic_value_enum(), f_ty)?;
1159 err_nt!(
1160 self.builder
1161 .build_select(nan_cmp, canonical_qnan, value, "")
1162 .map(|v| v.as_basic_value_enum())
1163 )
1164 } else {
1165 let value = value.into_float_value();
1166 let f_ty = f_ty.into_float_type();
1167 let zero = f_ty.const_zero();
1168 let nan_cmp =
1169 err!(
1170 self.builder
1171 .build_float_compare(FloatPredicate::UNO, value, zero, "nan")
1172 );
1173 let canonical_qnan = f_ty.const_float(f64::NAN);
1174 err_nt!(
1175 self.builder
1176 .build_select(nan_cmp, canonical_qnan, value, "")
1177 .map(|v| v.as_basic_value_enum())
1178 )
1179 }
1180 }
1181
1182 fn mark_memaccess_nodelete(
1186 &mut self,
1187 memory_index: MemoryIndex,
1188 memaccess: InstructionValue<'ctx>,
1189 ) -> Result<(), CompileError> {
1190 if let MemoryCache::Static { base_ptr: _ } = self.ctx.memory(
1191 memory_index,
1192 self.intrinsics,
1193 self.module,
1194 self.memory_styles,
1195 )? {
1196 memaccess.set_volatile(true).unwrap();
1199 }
1200 Ok(())
1201 }
1202
1203 fn annotate_user_memaccess(
1204 &mut self,
1205 memory_index: MemoryIndex,
1206 _memarg: &MemArg,
1207 alignment: u32,
1208 memaccess: InstructionValue<'ctx>,
1209 ) -> Result<(), CompileError> {
1210 match memaccess.get_opcode() {
1211 InstructionOpcode::Load | InstructionOpcode::Store => {
1212 memaccess.set_alignment(alignment).unwrap();
1213 }
1214 _ => {}
1215 };
1216 self.mark_memaccess_nodelete(memory_index, memaccess)?;
1217 tbaa_label(
1218 self.module,
1219 self.intrinsics,
1220 format!("memory {}", memory_index.as_u32()),
1221 memaccess,
1222 );
1223 Ok(())
1224 }
1225
1226 fn resolve_memory_ptr(
1227 &mut self,
1228 memory_index: MemoryIndex,
1229 memarg: &MemArg,
1230 ptr_ty: PointerType<'ctx>,
1231 var_offset: IntValue<'ctx>,
1232 value_size: usize,
1233 ) -> Result<PointerValue<'ctx>, CompileError> {
1234 let builder = &self.builder;
1235 let intrinsics = &self.intrinsics;
1236 let context = &self.context;
1237 let function = &self.function;
1238
1239 let imm_offset = intrinsics.i64_ty.const_int(memarg.offset, false);
1241 let var_offset = err!(builder.build_int_z_extend(var_offset, intrinsics.i64_ty, ""));
1242 let offset = err!(builder.build_int_add(var_offset, imm_offset, ""));
1243
1244 let base_ptr = if let Some((_, ref m0)) = self.g0m0 {
1246 *m0
1247 } else {
1248 match self
1249 .ctx
1250 .memory(memory_index, intrinsics, self.module, self.memory_styles)?
1251 {
1252 MemoryCache::Dynamic {
1253 ptr_to_base_ptr,
1254 ptr_to_current_length,
1255 } => {
1256 let minimum = self.wasm_module.memories[memory_index].minimum;
1258 let value_size_v = intrinsics.i64_ty.const_int(value_size as u64, false);
1259 let ptr_in_bounds = if offset.is_const() {
1260 let load_offset_end =
1263 offset.const_add(value_size_v).get_zero_extended_constant();
1264 if load_offset_end.is_some_and(|load_offset_end| {
1265 load_offset_end <= minimum.bytes().0 as u64
1266 }) {
1267 Some(intrinsics.i64_ty.const_int(1, false))
1268 } else {
1269 None
1270 }
1271 } else {
1272 None
1273 };
1274
1275 let ptr_in_bounds = match ptr_in_bounds {
1276 Some(ptr) => ptr,
1277 None => {
1278 let load_offset_end = err!(builder.build_int_add(
1279 offset,
1280 value_size_v,
1281 "load_offset_end"
1282 ));
1283
1284 let current_length = err!(builder.build_load(
1285 self.intrinsics.i32_ty,
1286 ptr_to_current_length,
1287 "current_length"
1288 ))
1289 .into_int_value();
1290 tbaa_label(
1291 self.module,
1292 self.intrinsics,
1293 format!("memory {} length", memory_index.as_u32()),
1294 current_length.as_instruction_value().unwrap(),
1295 );
1296 let current_length = err!(builder.build_int_z_extend(
1297 current_length,
1298 intrinsics.i64_ty,
1299 "current_length_zextd"
1300 ));
1301
1302 err!(builder.build_int_compare(
1303 IntPredicate::ULE,
1304 load_offset_end,
1305 current_length,
1306 "ptr_in_bounds",
1307 ))
1308 }
1309 };
1310
1311 if !ptr_in_bounds.is_constant_int()
1312 || ptr_in_bounds.get_zero_extended_constant().unwrap() != 1
1313 {
1314 let ptr_in_bounds = err!(builder.build_call(
1320 intrinsics.expect_i1,
1321 &[
1322 ptr_in_bounds.into(),
1323 intrinsics.i1_ty.const_int(1, true).into(),
1324 ],
1325 "ptr_in_bounds_expect",
1326 ))
1327 .try_as_basic_value()
1328 .unwrap_basic()
1329 .into_int_value();
1330
1331 let in_bounds_continue_block =
1332 context.append_basic_block(*function, "in_bounds_continue_block");
1333 let not_in_bounds_block =
1334 context.append_basic_block(*function, "not_in_bounds_block");
1335 err!(builder.build_conditional_branch(
1336 ptr_in_bounds,
1337 in_bounds_continue_block,
1338 not_in_bounds_block,
1339 ));
1340 builder.position_at_end(not_in_bounds_block);
1341 err!(builder.build_call(
1342 intrinsics.throw_trap,
1343 &[intrinsics.trap_memory_oob.into()],
1344 "throw",
1345 ));
1346 err!(builder.build_unreachable());
1347 builder.position_at_end(in_bounds_continue_block);
1348 }
1349 let ptr_to_base =
1350 err!(builder.build_load(intrinsics.ptr_ty, ptr_to_base_ptr, "ptr_to_base"))
1351 .into_pointer_value();
1352 tbaa_label(
1353 self.module,
1354 self.intrinsics,
1355 format!("memory base_ptr {}", memory_index.as_u32()),
1356 ptr_to_base.as_instruction_value().unwrap(),
1357 );
1358 ptr_to_base
1359 }
1360 MemoryCache::Static { base_ptr } => base_ptr,
1361 }
1362 };
1363 let value_ptr = unsafe {
1364 err!(builder.build_gep(self.intrinsics.i8_ty, base_ptr, &[offset], "mem_value_ptr"))
1365 };
1366 err_nt!(
1367 builder
1368 .build_bit_cast(value_ptr, ptr_ty, "mem_value")
1369 .map(|v| v.into_pointer_value())
1370 )
1371 }
1372
1373 fn trap_if_misaligned(
1374 &self,
1375 _memarg: &MemArg,
1376 ptr: PointerValue<'ctx>,
1377 align: u8,
1378 ) -> Result<(), CompileError> {
1379 if align <= 1 {
1380 return Ok(());
1381 }
1382 let value = err!(self.builder.build_ptr_to_int(
1383 ptr,
1384 self.intrinsics.i64_ty,
1385 "mischeck_value"
1386 ));
1387 let and = err!(self.builder.build_and(
1388 value,
1389 self.intrinsics.i64_ty.const_int((align - 1).into(), false),
1390 "misaligncheck",
1391 ));
1392 let aligned = err!(self.builder.build_int_compare(
1393 IntPredicate::EQ,
1394 and,
1395 self.intrinsics.i64_zero,
1396 "is_aligned"
1397 ));
1398 let aligned = err!(self.builder.build_call(
1399 self.intrinsics.expect_i1,
1400 &[
1401 aligned.into(),
1402 self.intrinsics.i1_ty.const_int(1, false).into(),
1403 ],
1404 "is_aligned_expect",
1405 ))
1406 .try_as_basic_value()
1407 .unwrap_basic()
1408 .into_int_value();
1409
1410 let continue_block = self
1411 .context
1412 .append_basic_block(self.function, "aligned_access_continue_block");
1413 let not_aligned_block = self
1414 .context
1415 .append_basic_block(self.function, "misaligned_trap_block");
1416 err!(
1417 self.builder
1418 .build_conditional_branch(aligned, continue_block, not_aligned_block)
1419 );
1420
1421 self.builder.position_at_end(not_aligned_block);
1422 err!(self.builder.build_call(
1423 self.intrinsics.throw_trap,
1424 &[self.intrinsics.trap_unaligned_atomic.into()],
1425 "throw",
1426 ));
1427 err!(self.builder.build_unreachable());
1428
1429 self.builder.position_at_end(continue_block);
1430 Ok(())
1431 }
1432
1433 fn finalize(&mut self, wasm_fn_type: &FunctionType) -> Result<(), CompileError> {
1434 let func_type = self.function.get_type();
1435
1436 let results = self.state.popn_save_extra(wasm_fn_type.results().len())?;
1437 let results = err!(
1438 results
1439 .into_iter()
1440 .map(|(v, i)| self.apply_pending_canonicalization(v, i))
1441 .collect::<Result<Vec<_>, _>>()
1442 );
1443
1444 if wasm_fn_type.results().is_empty() {
1445 err!(self.builder.build_return(None));
1446 } else if self.abi.is_sret(wasm_fn_type)? {
1447 let sret = self
1448 .function
1449 .get_first_param()
1450 .unwrap()
1451 .into_pointer_value();
1452 let llvm_params: Vec<_> = wasm_fn_type
1453 .results()
1454 .iter()
1455 .map(|x| type_to_llvm(self.intrinsics, *x).unwrap())
1456 .collect();
1457 let mut struct_value = self
1458 .context
1459 .struct_type(llvm_params.as_slice(), false)
1460 .get_undef();
1461 for (idx, value) in results.into_iter().enumerate() {
1462 let value = err!(self.builder.build_bit_cast(
1463 value,
1464 type_to_llvm(self.intrinsics, wasm_fn_type.results()[idx])?,
1465 "",
1466 ));
1467 struct_value =
1468 err!(
1469 self.builder
1470 .build_insert_value(struct_value, value, idx as u32, "")
1471 )
1472 .into_struct_value();
1473 }
1474 err!(self.builder.build_store(sret, struct_value));
1475 err!(self.builder.build_return(None));
1476 } else {
1477 err!(
1478 self.builder
1479 .build_return(Some(&self.abi.pack_values_for_register_return(
1480 self.intrinsics,
1481 &self.builder,
1482 &results,
1483 &func_type,
1484 )?))
1485 );
1486 }
1487 Ok(())
1488 }
1489
1490 fn get_or_insert_tag_type_info_global(&mut self, tag: i32) -> BasicValueEnum<'ctx> {
1493 if let Some(tag) = self.tags_cache.get(&tag) {
1494 return *tag;
1495 }
1496
1497 let tag_ty = self
1498 .context
1499 .struct_type(&[self.intrinsics.i32_ty.into()], false);
1500 let tag_glbl = self.module.add_global(
1501 tag_ty,
1502 Some(AddressSpace::default()),
1503 &format!("__wasmer_eh_type_info_{tag}"),
1504 );
1505 tag_glbl.set_initializer(
1506 &tag_ty
1507 .const_named_struct(&[self.intrinsics.i32_ty.const_int(tag as _, false).into()])
1508 .as_basic_value_enum(),
1509 );
1510
1511 tag_glbl.set_linkage(Linkage::External);
1512 tag_glbl.set_constant(true);
1513 if matches!(self.binary_fmt, target_lexicon::BinaryFormat::Macho) {
1521 tag_glbl.set_section(Some(&format!("{FUNCTION_SECTION_MACHO},_eh_ti_{tag}")));
1522 }
1523
1524 let tag_glbl = tag_glbl.as_basic_value_enum();
1525
1526 self.tags_cache.insert(tag, tag_glbl);
1527 tag_glbl
1528 }
1529
1530 fn build_g0m0_indirect_call(
1531 &mut self,
1532 table_index: u32,
1533 ctx_ptr: PointerValue<'ctx>,
1534 func_type: &FunctionType,
1535 func_ptr: PointerValue<'ctx>,
1536 func_index: IntValue<'ctx>,
1537 ) -> Result<(), CompileError> {
1538 let Some((g0, m0)) = self.g0m0 else {
1539 return Err(CompileError::Codegen(
1540 "Call to build_g0m0_indirect_call without g0m0 parameters!".to_string(),
1541 ));
1542 };
1543
1544 let mut local_func_indices = vec![];
1545 let mut foreign_func_indices = vec![];
1546
1547 for t in &self.wasm_module.table_initializers {
1548 if t.table_index.as_u32() == table_index {
1549 for (func_in_table_idx, func_idx) in t.elements.iter().enumerate() {
1550 if self.wasm_module.local_func_index(*func_idx).is_some() {
1551 local_func_indices.push(func_in_table_idx)
1552 } else {
1553 foreign_func_indices.push(func_in_table_idx)
1554 }
1555 }
1556 break;
1557 }
1558 }
1559
1560 let g0_value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, "g0"));
1563
1564 let needs_switch = self.g0m0.is_some()
1565 && !local_func_indices.is_empty()
1566 && !foreign_func_indices.is_empty();
1567
1568 if needs_switch {
1569 let foreign_idx_block = self
1570 .context
1571 .append_basic_block(self.function, "foreign_call_block");
1572 let local_idx_block = self
1573 .context
1574 .append_basic_block(self.function, "local_call_block");
1575 let unreachable_indirect_call_branch_block = self
1576 .context
1577 .append_basic_block(self.function, "unreachable_indirect_call_branch");
1578
1579 let cont = self.context.append_basic_block(self.function, "cont");
1580
1581 err!(
1582 self.builder.build_switch(
1583 func_index,
1584 unreachable_indirect_call_branch_block,
1585 &local_func_indices
1586 .into_iter()
1587 .map(|v| (
1588 self.intrinsics.i32_ty.const_int(v as _, false),
1589 local_idx_block
1590 ))
1591 .chain(foreign_func_indices.into_iter().map(|v| (
1592 self.intrinsics.i32_ty.const_int(v as _, false),
1593 foreign_idx_block
1594 )))
1595 .collect::<Vec<_>>()
1596 )
1597 );
1598
1599 self.builder
1600 .position_at_end(unreachable_indirect_call_branch_block);
1601 err!(self.builder.build_unreachable());
1602
1603 self.builder.position_at_end(local_idx_block);
1605 let local_call_site = self.build_indirect_call(
1606 ctx_ptr,
1607 func_type,
1608 func_ptr,
1609 Some(G0M0FunctionKind::Local),
1610 Some((g0_value.into_int_value(), m0)),
1611 )?;
1612
1613 let local_rets = self.abi.rets_from_call(
1614 &self.builder,
1615 self.intrinsics,
1616 local_call_site,
1617 func_type,
1618 )?;
1619
1620 err!(self.builder.build_unconditional_branch(cont));
1621
1622 self.builder.position_at_end(foreign_idx_block);
1623 let foreign_call_site = self.build_indirect_call(
1624 ctx_ptr,
1625 func_type,
1626 func_ptr,
1627 Some(G0M0FunctionKind::Imported),
1628 None,
1629 )?;
1630
1631 let foreign_rets = self.abi.rets_from_call(
1632 &self.builder,
1633 self.intrinsics,
1634 foreign_call_site,
1635 func_type,
1636 )?;
1637
1638 err!(self.builder.build_unconditional_branch(cont));
1639
1640 self.builder.position_at_end(cont);
1641
1642 for i in 0..foreign_rets.len() {
1643 let f_i = foreign_rets[i];
1644 let l_i = local_rets[i];
1645 let ty = f_i.get_type();
1646 let v = err!(self.builder.build_phi(ty, ""));
1647 v.add_incoming(&[(&f_i, foreign_idx_block), (&l_i, local_idx_block)]);
1648 self.state.push1(v.as_basic_value());
1649 }
1650 } else if foreign_func_indices.is_empty() {
1651 let call_site = self.build_indirect_call(
1652 ctx_ptr,
1653 func_type,
1654 func_ptr,
1655 Some(G0M0FunctionKind::Local),
1656 Some((g0_value.into_int_value(), m0)),
1657 )?;
1658
1659 self.abi
1660 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1661 .iter()
1662 .for_each(|ret| self.state.push1(*ret));
1663 } else {
1664 let call_site = self.build_indirect_call(
1665 ctx_ptr,
1666 func_type,
1667 func_ptr,
1668 Some(G0M0FunctionKind::Imported),
1669 Some((g0_value.into_int_value(), m0)),
1670 )?;
1671 self.abi
1672 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
1673 .iter()
1674 .for_each(|ret| self.state.push1(*ret));
1675 }
1676
1677 Ok(())
1678 }
1679
1680 fn build_indirect_call(
1681 &mut self,
1682 ctx_ptr: PointerValue<'ctx>,
1683 func_type: &FunctionType,
1684 func_ptr: PointerValue<'ctx>,
1685 func_kind: Option<G0M0FunctionKind>,
1686 g0m0_params: LocalFunctionG0M0params<'ctx>,
1687 ) -> Result<CallSiteValue<'ctx>, CompileError> {
1688 let (llvm_func_type, llvm_func_attrs) = self.abi.func_type_to_llvm(
1689 self.context,
1690 self.intrinsics,
1691 Some(self.ctx.get_offsets()),
1692 func_type,
1693 func_kind,
1694 )?;
1695
1696 let params = self.state.popn_save_extra(func_type.params().len())?;
1697
1698 let params = params
1700 .iter()
1701 .zip(func_type.params().iter())
1702 .map(|((v, info), wasm_ty)| match wasm_ty {
1703 Type::F32 => err_nt!(self.builder.build_bit_cast(
1704 self.apply_pending_canonicalization(*v, *info)?,
1705 self.intrinsics.f32_ty,
1706 "",
1707 )),
1708 Type::F64 => err_nt!(self.builder.build_bit_cast(
1709 self.apply_pending_canonicalization(*v, *info)?,
1710 self.intrinsics.f64_ty,
1711 "",
1712 )),
1713 Type::V128 => self.apply_pending_canonicalization(*v, *info),
1714 _ => Ok(*v),
1715 })
1716 .collect::<Result<Vec<_>, _>>()?;
1717
1718 let params = self.abi.args_to_call(
1719 &self.alloca_builder,
1720 func_type,
1721 &llvm_func_type,
1722 ctx_ptr,
1723 params.as_slice(),
1724 self.intrinsics,
1725 g0m0_params,
1726 )?;
1727
1728 let typed_func_ptr = err!(self.builder.build_pointer_cast(
1729 func_ptr,
1730 self.context.ptr_type(AddressSpace::default()),
1731 "typed_func_ptr",
1732 ));
1733
1734 let call_site_local = if let Some(lpad) = self.state.get_innermost_landingpad() {
1755 let then_block = self.context.append_basic_block(self.function, "then_block");
1756
1757 let ret = err!(self.builder.build_indirect_invoke(
1758 llvm_func_type,
1759 typed_func_ptr,
1760 params.as_slice(),
1761 then_block,
1762 lpad,
1763 "",
1764 ));
1765
1766 self.builder.position_at_end(then_block);
1767 ret
1768 } else {
1769 err!(
1770 self.builder.build_indirect_call(
1771 llvm_func_type,
1772 typed_func_ptr,
1773 params
1774 .iter()
1775 .copied()
1776 .map(Into::into)
1777 .collect::<Vec<BasicMetadataValueEnum>>()
1778 .as_slice(),
1779 "indirect_call",
1780 )
1781 )
1782 };
1783 for (attr, attr_loc) in llvm_func_attrs {
1784 call_site_local.add_attribute(attr_loc, attr);
1785 }
1786
1787 Ok(call_site_local)
1788 }
1789}
1790
1791pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
1877 g0m0: Option<(PointerValue<'ctx>, PointerValue<'ctx>)>,
1878 context: &'ctx Context,
1879 builder: Builder<'ctx>,
1880 alloca_builder: Builder<'ctx>,
1881 intrinsics: &'a Intrinsics<'ctx>,
1882 state: State<'ctx>,
1883 function: FunctionValue<'ctx>,
1884 locals: Vec<(BasicTypeEnum<'ctx>, PointerValue<'ctx>)>, ctx: CtxType<'ctx, 'a>,
1886 unreachable_depth: usize,
1887 memory_styles: &'a PrimaryMap<MemoryIndex, MemoryStyle>,
1888 _table_styles: &'a PrimaryMap<TableIndex, TableStyle>,
1889
1890 module: &'a Module<'ctx>,
1898 module_translation: &'a ModuleTranslationState,
1899 wasm_module: &'a ModuleInfo,
1900 symbol_registry: &'a dyn SymbolRegistry,
1901 abi: &'a dyn Abi,
1902 config: &'a LLVM,
1903 tags_cache: HashMap<i32, BasicValueEnum<'ctx>>,
1904 binary_fmt: target_lexicon::BinaryFormat,
1905}
1906
1907impl<'ctx> LLVMFunctionCodeGenerator<'ctx, '_> {
1908 fn quiet_nan(&self, value: BasicValueEnum<'ctx>) -> Result<BasicValueEnum<'ctx>, CompileError> {
1909 let intrinsic = if value
1910 .get_type()
1911 .eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1912 {
1913 Some(self.intrinsics.add_f32)
1914 } else if value
1915 .get_type()
1916 .eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1917 {
1918 Some(self.intrinsics.add_f64)
1919 } else if value
1920 .get_type()
1921 .eq(&self.intrinsics.f32x4_ty.as_basic_type_enum())
1922 {
1923 Some(self.intrinsics.add_f32x4)
1924 } else if value
1925 .get_type()
1926 .eq(&self.intrinsics.f64x2_ty.as_basic_type_enum())
1927 {
1928 Some(self.intrinsics.add_f64x2)
1929 } else {
1930 None
1931 };
1932
1933 match intrinsic {
1934 Some(intrinsic) => err_nt!(
1935 self.builder
1936 .build_call(
1937 intrinsic,
1938 &[
1939 value.into(),
1940 value.get_type().const_zero().into(),
1941 self.intrinsics.fp_rounding_md,
1942 self.intrinsics.fp_exception_md,
1943 ],
1944 "",
1945 )
1946 .map(|v| v.try_as_basic_value().unwrap_basic())
1947 ),
1948 None => Ok(value),
1949 }
1950 }
1951
1952 fn finalize_minmax_result(
1953 &self,
1954 value: BasicValueEnum<'ctx>,
1955 ) -> Result<BasicValueEnum<'ctx>, CompileError> {
1956 let ty = value.get_type();
1957 if ty.eq(&self.intrinsics.f32_ty.as_basic_type_enum())
1958 || ty.eq(&self.intrinsics.f64_ty.as_basic_type_enum())
1959 {
1960 let value = value.into_float_value();
1961 let is_nan = err!(self.builder.build_float_compare(
1962 FloatPredicate::UNO,
1963 value,
1964 value,
1965 "res_is_nan"
1966 ));
1967 let quiet = self.quiet_nan(value.as_basic_value_enum())?;
1968 let result =
1969 err!(
1970 self.builder
1971 .build_select(is_nan, quiet, value.as_basic_value_enum(), "")
1972 );
1973 Ok(result.as_basic_value_enum())
1974 } else if ty.eq(&self.intrinsics.f32x4_ty.as_basic_type_enum()) {
1975 let value = value.into_vector_value();
1976 let is_nan = err!(self.builder.build_call(
1977 self.intrinsics.cmp_f32x4,
1978 &[
1979 value.into(),
1980 value.into(),
1981 self.intrinsics.fp_uno_md,
1982 self.intrinsics.fp_exception_md,
1983 ],
1984 "",
1985 ))
1986 .try_as_basic_value()
1987 .unwrap_basic()
1988 .into_vector_value();
1989 let quiet = self
1990 .quiet_nan(value.as_basic_value_enum())?
1991 .into_vector_value();
1992 let result = err!(self.builder.build_select(
1993 is_nan,
1994 quiet.as_basic_value_enum(),
1995 value.as_basic_value_enum(),
1996 "",
1997 ));
1998 Ok(result.as_basic_value_enum())
1999 } else if ty.eq(&self.intrinsics.f64x2_ty.as_basic_type_enum()) {
2000 let value = value.into_vector_value();
2001 let is_nan = err!(self.builder.build_call(
2002 self.intrinsics.cmp_f64x2,
2003 &[
2004 value.into(),
2005 value.into(),
2006 self.intrinsics.fp_uno_md,
2007 self.intrinsics.fp_exception_md,
2008 ],
2009 "",
2010 ))
2011 .try_as_basic_value()
2012 .unwrap_basic()
2013 .into_vector_value();
2014 let quiet = self
2015 .quiet_nan(value.as_basic_value_enum())?
2016 .into_vector_value();
2017 let result = err!(self.builder.build_select(
2018 is_nan,
2019 quiet.as_basic_value_enum(),
2020 value.as_basic_value_enum(),
2021 "",
2022 ));
2023 Ok(result.as_basic_value_enum())
2024 } else {
2025 Ok(value)
2026 }
2027 }
2028
2029 fn translate_operator(&mut self, op: Operator, _source_loc: u32) -> Result<(), CompileError> {
2030 let vmctx = &self.ctx.basic().into_pointer_value();
2033
2034 if !self.state.reachable {
2037 match op {
2038 Operator::Block { blockty: _ }
2039 | Operator::Loop { blockty: _ }
2040 | Operator::If { blockty: _ } => {
2041 self.unreachable_depth += 1;
2042 return Ok(());
2043 }
2044 Operator::Else => {
2045 if self.unreachable_depth != 0 {
2046 return Ok(());
2047 }
2048 }
2049 Operator::End => {
2050 if self.unreachable_depth != 0 {
2051 self.unreachable_depth -= 1;
2052 return Ok(());
2053 }
2054 }
2055 _ => {
2056 return Ok(());
2057 }
2058 }
2059 }
2060
2061 match op {
2062 Operator::Block { blockty } => {
2067 let current_block = self
2068 .builder
2069 .get_insert_block()
2070 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2071
2072 let end_block = self.context.append_basic_block(self.function, "end");
2073 self.builder.position_at_end(end_block);
2074
2075 let phis: SmallVec<[PhiValue<'ctx>; 1]> = self
2076 .module_translation
2077 .blocktype_params_results(&blockty)?
2078 .1
2079 .iter()
2080 .map(|&wp_ty| {
2081 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2082 type_to_llvm(self.intrinsics, wasm_ty)
2083 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2084 })
2085 })
2086 .collect::<Result<_, _>>()?;
2087
2088 self.state.push_block(
2089 end_block,
2090 phis,
2091 self.module_translation
2092 .blocktype_params_results(&blockty)?
2093 .0
2094 .len(),
2095 );
2096 self.builder.position_at_end(current_block);
2097 }
2098 Operator::Loop { blockty } => {
2099 let loop_body = self.context.append_basic_block(self.function, "loop_body");
2100 let loop_next = self.context.append_basic_block(self.function, "loop_outer");
2101 let pre_loop_block = self.builder.get_insert_block().unwrap();
2102
2103 err!(self.builder.build_unconditional_branch(loop_body));
2104
2105 self.builder.position_at_end(loop_next);
2106 let blocktypes = self.module_translation.blocktype_params_results(&blockty)?;
2107 let phis = blocktypes
2108 .1
2109 .iter()
2110 .map(|&wp_ty| {
2111 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2112 type_to_llvm(self.intrinsics, wasm_ty)
2113 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2114 })
2115 })
2116 .collect::<Result<_, _>>()?;
2117 self.builder.position_at_end(loop_body);
2118 let loop_phis: SmallVec<[PhiValue<'ctx>; 1]> = blocktypes
2119 .0
2120 .iter()
2121 .map(|&wp_ty| {
2122 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2123 type_to_llvm(self.intrinsics, wasm_ty)
2124 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2125 })
2126 })
2127 .collect::<Result<_, _>>()?;
2128 for phi in loop_phis.iter().rev() {
2129 let (value, info) = self.state.pop1_extra()?;
2130 let value = self.apply_pending_canonicalization(value, info)?;
2131 phi.add_incoming(&[(&value, pre_loop_block)]);
2132 }
2133 for phi in &loop_phis {
2134 self.state.push1(phi.as_basic_value());
2135 }
2136
2137 let num_inputs = loop_phis.len();
2138 self.state
2139 .push_loop(loop_body, loop_next, loop_phis, phis, num_inputs);
2140 }
2141 Operator::Br { relative_depth } => {
2142 let frame = self.state.frame_at_depth(relative_depth)?;
2143
2144 let current_block = self
2145 .builder
2146 .get_insert_block()
2147 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2148
2149 let phis = if frame.is_loop() {
2150 frame.loop_body_phis()
2151 } else {
2152 frame.phis()
2153 };
2154
2155 let len = phis.len();
2156 let values = self.state.peekn_extra(len)?;
2157 let values = values
2158 .iter()
2159 .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2160 .collect::<Result<Vec<_>, _>>()?;
2161
2162 for (phi, value) in phis.iter().zip(values.into_iter()) {
2166 phi.add_incoming(&[(&value, current_block)]);
2167 }
2168
2169 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2170
2171 self.state.popn(len)?;
2172 self.state.reachable = false;
2173 }
2174 Operator::BrIf { relative_depth } => {
2175 let cond = self.state.pop1()?;
2176 let frame = self.state.frame_at_depth(relative_depth)?;
2177
2178 let current_block = self
2179 .builder
2180 .get_insert_block()
2181 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2182
2183 let phis = if frame.is_loop() {
2184 frame.loop_body_phis()
2185 } else {
2186 frame.phis()
2187 };
2188
2189 let param_stack = self.state.peekn_extra(phis.len())?;
2190 let param_stack = param_stack
2191 .iter()
2192 .map(|(v, info)| self.apply_pending_canonicalization(*v, *info))
2193 .collect::<Result<Vec<_>, _>>()?;
2194
2195 for (phi, value) in phis.iter().zip(param_stack) {
2196 phi.add_incoming(&[(&value, current_block)]);
2197 }
2198
2199 let else_block = self.context.append_basic_block(self.function, "else");
2200
2201 let cond_value = err!(self.builder.build_int_compare(
2202 IntPredicate::NE,
2203 cond.into_int_value(),
2204 self.intrinsics.i32_zero,
2205 "",
2206 ));
2207 err!(self.builder.build_conditional_branch(
2208 cond_value,
2209 *frame.br_dest(),
2210 else_block
2211 ));
2212 self.builder.position_at_end(else_block);
2213 }
2214 Operator::BrTable { ref targets } => {
2215 let current_block = self
2216 .builder
2217 .get_insert_block()
2218 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2219
2220 let index = self.state.pop1()?;
2221
2222 let default_frame = self.state.frame_at_depth(targets.default())?;
2223
2224 let phis = if default_frame.is_loop() {
2225 default_frame.loop_body_phis()
2226 } else {
2227 default_frame.phis()
2228 };
2229 let args = self.state.peekn(phis.len())?;
2230
2231 for (phi, value) in phis.iter().zip(args.iter()) {
2232 phi.add_incoming(&[(value, current_block)]);
2233 }
2234
2235 let cases: Vec<_> = targets
2236 .targets()
2237 .enumerate()
2238 .map(|(case_index, depth)| {
2239 let depth = depth.map_err(from_binaryreadererror_wasmerror)?;
2240 let frame_result: Result<&ControlFrame, CompileError> =
2241 self.state.frame_at_depth(depth);
2242 let frame = match frame_result {
2243 Ok(v) => v,
2244 Err(e) => return Err(e),
2245 };
2246 let case_index_literal =
2247 self.context.i32_type().const_int(case_index as u64, false);
2248 let phis = if frame.is_loop() {
2249 frame.loop_body_phis()
2250 } else {
2251 frame.phis()
2252 };
2253 for (phi, value) in phis.iter().zip(args.iter()) {
2254 phi.add_incoming(&[(value, current_block)]);
2255 }
2256
2257 Ok((case_index_literal, *frame.br_dest()))
2258 })
2259 .collect::<Result<_, _>>()?;
2260
2261 err!(self.builder.build_switch(
2262 index.into_int_value(),
2263 *default_frame.br_dest(),
2264 &cases[..],
2265 ));
2266
2267 let args_len = args.len();
2268 self.state.popn(args_len)?;
2269 self.state.reachable = false;
2270 }
2271 Operator::If { blockty } => {
2272 let current_block = self
2273 .builder
2274 .get_insert_block()
2275 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2276 let if_then_block = self.context.append_basic_block(self.function, "if_then");
2277 let if_else_block = self.context.append_basic_block(self.function, "if_else");
2278 let end_block = self.context.append_basic_block(self.function, "if_end");
2279
2280 let end_phis = {
2281 self.builder.position_at_end(end_block);
2282
2283 let phis = self
2284 .module_translation
2285 .blocktype_params_results(&blockty)?
2286 .1
2287 .iter()
2288 .map(|&wp_ty| {
2289 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
2290 type_to_llvm(self.intrinsics, wasm_ty)
2291 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
2292 })
2293 })
2294 .collect::<Result<_, _>>()?;
2295
2296 self.builder.position_at_end(current_block);
2297 phis
2298 };
2299
2300 let cond = self.state.pop1()?;
2301
2302 let cond_value = err!(self.builder.build_int_compare(
2303 IntPredicate::NE,
2304 cond.into_int_value(),
2305 self.intrinsics.i32_zero,
2306 "",
2307 ));
2308
2309 err!(self.builder.build_conditional_branch(
2310 cond_value,
2311 if_then_block,
2312 if_else_block
2313 ));
2314 self.builder.position_at_end(if_else_block);
2315 let block_param_types = self
2316 .module_translation
2317 .blocktype_params_results(&blockty)?
2318 .0
2319 .iter()
2320 .map(|&wp_ty| {
2321 err_nt!(wptype_to_type(wp_ty))
2322 .and_then(|wasm_ty| type_to_llvm(self.intrinsics, wasm_ty))
2323 })
2324 .collect::<Result<Vec<_>, _>>()?;
2325 let else_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2326 .iter()
2327 .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2328 .collect::<Result<SmallVec<_>, _>>()?;
2329 self.builder.position_at_end(if_then_block);
2330 let then_phis: SmallVec<[PhiValue<'ctx>; 1]> = block_param_types
2331 .iter()
2332 .map(|&ty| err_nt!(self.builder.build_phi(ty, "")))
2333 .collect::<Result<SmallVec<_>, _>>()?;
2334 for (else_phi, then_phi) in else_phis.iter().rev().zip(then_phis.iter().rev()) {
2335 let (value, info) = self.state.pop1_extra()?;
2336 let value = self.apply_pending_canonicalization(value, info)?;
2337 else_phi.add_incoming(&[(&value, current_block)]);
2338 then_phi.add_incoming(&[(&value, current_block)]);
2339 }
2340 for phi in then_phis.iter() {
2341 self.state.push1(phi.as_basic_value());
2342 }
2343
2344 self.state.push_if(
2345 if_then_block,
2346 if_else_block,
2347 end_block,
2348 then_phis,
2349 else_phis,
2350 end_phis,
2351 block_param_types.len(),
2352 );
2353 }
2354 Operator::Else => {
2355 if self.state.reachable {
2356 let frame = self.state.frame_at_depth(0)?;
2357 let current_block = self.builder.get_insert_block().ok_or_else(|| {
2358 CompileError::Codegen("not currently in a block".to_string())
2359 })?;
2360
2361 for phi in frame.phis().to_vec().iter().rev() {
2362 let (value, info) = self.state.pop1_extra()?;
2363 let value = self.apply_pending_canonicalization(value, info)?;
2364 phi.add_incoming(&[(&value, current_block)])
2365 }
2366
2367 let frame = self.state.frame_at_depth(0)?;
2368 err!(self.builder.build_unconditional_branch(*frame.code_after()));
2369 }
2370
2371 let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
2372 if_else,
2373 if_else_state,
2374 ..
2375 } = self.state.frame_at_depth_mut(0)?
2376 {
2377 (if_else, if_else_state)
2378 } else {
2379 unreachable!()
2380 };
2381
2382 *if_else_state = IfElseState::Else;
2383
2384 self.builder.position_at_end(*if_else_block);
2385 self.state.reachable = true;
2386
2387 if let ControlFrame::IfElse { else_phis, .. } = self.state.frame_at_depth(0)? {
2388 for phi in else_phis.clone().iter() {
2390 self.state.push1(phi.as_basic_value());
2391 }
2392 };
2393 }
2394
2395 Operator::End => {
2396 let frame = self.state.pop_frame()?;
2397 let current_block = self
2398 .builder
2399 .get_insert_block()
2400 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2401
2402 if self.state.reachable {
2403 for phi in frame.phis().iter().rev() {
2404 let (value, info) = self.state.pop1_extra()?;
2405 let value = self.apply_pending_canonicalization(value, info)?;
2406 phi.add_incoming(&[(&value, current_block)]);
2407 }
2408
2409 err!(self.builder.build_unconditional_branch(*frame.code_after()));
2410 }
2411
2412 if let ControlFrame::IfElse {
2413 if_else,
2414 next,
2415 if_else_state: IfElseState::If,
2416 else_phis,
2417 ..
2418 } = &frame
2419 {
2420 for (phi, else_phi) in frame.phis().iter().zip(else_phis.iter()) {
2421 phi.add_incoming(&[(&else_phi.as_basic_value(), *if_else)]);
2422 }
2423 self.builder.position_at_end(*if_else);
2424 err!(self.builder.build_unconditional_branch(*next));
2425 } else if let ControlFrame::Landingpad { .. } = &frame {
2426 self.state.pop_landingpad();
2427 };
2428
2429 self.builder.position_at_end(*frame.code_after());
2430 self.state.reset_stack(&frame);
2431
2432 self.state.reachable = true;
2433
2434 for phi in frame.phis() {
2436 if phi.count_incoming() != 0 {
2437 self.state.push1(phi.as_basic_value());
2438 } else {
2439 let basic_ty = phi.as_basic_value().get_type();
2446 let placeholder_value = basic_ty.const_zero();
2447 self.state.push1(placeholder_value);
2448 phi.as_instruction().erase_from_basic_block();
2449 }
2450 }
2451 }
2452 Operator::Return => {
2453 let current_block = self
2454 .builder
2455 .get_insert_block()
2456 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
2457
2458 let frame = self.state.outermost_frame()?;
2459 for phi in frame.phis().to_vec().iter().rev() {
2460 let (arg, info) = self.state.pop1_extra()?;
2461 let arg = self.apply_pending_canonicalization(arg, info)?;
2462 phi.add_incoming(&[(&arg, current_block)]);
2463 }
2464 let frame = self.state.outermost_frame()?;
2465 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
2466
2467 self.state.reachable = false;
2468 }
2469
2470 Operator::Unreachable => {
2471 err!(self.builder.build_call(
2472 self.intrinsics.throw_trap,
2473 &[self.intrinsics.trap_unreachable.into()],
2474 "throw",
2475 ));
2476 err!(self.builder.build_unreachable());
2477
2478 self.state.reachable = false;
2479 }
2480
2481 Operator::Nop => {
2486 }
2488 Operator::Drop => {
2489 self.state.pop1()?;
2490 }
2491
2492 Operator::I32Const { value } => {
2494 let i = self.intrinsics.i32_ty.const_int(value as u64, false);
2495 let info = if is_f32_arithmetic(value as u32) {
2496 ExtraInfo::arithmetic_f32()
2497 } else {
2498 Default::default()
2499 };
2500 self.state.push1_extra(i, info);
2501 }
2502 Operator::I64Const { value } => {
2503 let i = self.intrinsics.i64_ty.const_int(value as u64, false);
2504 let info = if is_f64_arithmetic(value as u64) {
2505 ExtraInfo::arithmetic_f64()
2506 } else {
2507 Default::default()
2508 };
2509 self.state.push1_extra(i, info);
2510 }
2511 Operator::F32Const { value } => {
2512 let bits = self.intrinsics.i32_ty.const_int(value.bits() as u64, false);
2513 let info = if is_f32_arithmetic(value.bits()) {
2514 ExtraInfo::arithmetic_f32()
2515 } else {
2516 Default::default()
2517 };
2518 let f = err!(
2519 self.builder
2520 .build_bit_cast(bits, self.intrinsics.f32_ty, "f")
2521 );
2522 self.state.push1_extra(f, info);
2523 }
2524 Operator::F64Const { value } => {
2525 let bits = self.intrinsics.i64_ty.const_int(value.bits(), false);
2526 let info = if is_f64_arithmetic(value.bits()) {
2527 ExtraInfo::arithmetic_f64()
2528 } else {
2529 Default::default()
2530 };
2531 let f = err!(
2532 self.builder
2533 .build_bit_cast(bits, self.intrinsics.f64_ty, "f")
2534 );
2535 self.state.push1_extra(f, info);
2536 }
2537 Operator::V128Const { value } => {
2538 let mut hi: [u8; 8] = Default::default();
2539 let mut lo: [u8; 8] = Default::default();
2540 hi.copy_from_slice(&value.bytes()[0..8]);
2541 lo.copy_from_slice(&value.bytes()[8..16]);
2542 let packed = [u64::from_le_bytes(hi), u64::from_le_bytes(lo)];
2543 let i = self
2544 .intrinsics
2545 .i128_ty
2546 .const_int_arbitrary_precision(&packed);
2547 let mut quad1: [u8; 4] = Default::default();
2548 let mut quad2: [u8; 4] = Default::default();
2549 let mut quad3: [u8; 4] = Default::default();
2550 let mut quad4: [u8; 4] = Default::default();
2551 quad1.copy_from_slice(&value.bytes()[0..4]);
2552 quad2.copy_from_slice(&value.bytes()[4..8]);
2553 quad3.copy_from_slice(&value.bytes()[8..12]);
2554 quad4.copy_from_slice(&value.bytes()[12..16]);
2555 let mut info: ExtraInfo = Default::default();
2556 if is_f32_arithmetic(u32::from_le_bytes(quad1))
2557 && is_f32_arithmetic(u32::from_le_bytes(quad2))
2558 && is_f32_arithmetic(u32::from_le_bytes(quad3))
2559 && is_f32_arithmetic(u32::from_le_bytes(quad4))
2560 {
2561 info |= ExtraInfo::arithmetic_f32();
2562 }
2563 if is_f64_arithmetic(packed[0]) && is_f64_arithmetic(packed[1]) {
2564 info |= ExtraInfo::arithmetic_f64();
2565 }
2566 self.state.push1_extra(i, info);
2567 }
2568
2569 Operator::I8x16Splat => {
2570 let (v, i) = self.state.pop1_extra()?;
2571 let v = v.into_int_value();
2572 let v = err!(
2573 self.builder
2574 .build_int_truncate(v, self.intrinsics.i8_ty, "")
2575 );
2576 let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
2577 let res = err!(
2578 self.builder
2579 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2580 );
2581 self.state.push1_extra(res, i);
2582 }
2583 Operator::I16x8Splat => {
2584 let (v, i) = self.state.pop1_extra()?;
2585 let v = v.into_int_value();
2586 let v = err!(
2587 self.builder
2588 .build_int_truncate(v, self.intrinsics.i16_ty, "")
2589 );
2590 let res = self.splat_vector(v.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
2591 let res = err!(
2592 self.builder
2593 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2594 );
2595 self.state.push1_extra(res, i);
2596 }
2597 Operator::I32x4Splat => {
2598 let (v, i) = self.state.pop1_extra()?;
2599 let res = self.splat_vector(v, self.intrinsics.i32x4_ty)?;
2600 let res = err!(
2601 self.builder
2602 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2603 );
2604 self.state.push1_extra(res, i);
2605 }
2606 Operator::I64x2Splat => {
2607 let (v, i) = self.state.pop1_extra()?;
2608 let res = self.splat_vector(v, self.intrinsics.i64x2_ty)?;
2609 let res = err!(
2610 self.builder
2611 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2612 );
2613 self.state.push1_extra(res, i);
2614 }
2615 Operator::F32x4Splat => {
2616 let (v, i) = self.state.pop1_extra()?;
2617 let res = self.splat_vector(v, self.intrinsics.f32x4_ty)?;
2618 let res = err!(
2619 self.builder
2620 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2621 );
2622 self.state.push1_extra(res, i);
2625 }
2626 Operator::F64x2Splat => {
2627 let (v, i) = self.state.pop1_extra()?;
2628 let res = self.splat_vector(v, self.intrinsics.f64x2_ty)?;
2629 let res = err!(
2630 self.builder
2631 .build_bit_cast(res, self.intrinsics.i128_ty, "")
2632 );
2633 self.state.push1_extra(res, i);
2636 }
2637
2638 Operator::LocalGet { local_index } => {
2640 let (type_value, pointer_value) = self.locals[local_index as usize];
2641 let v = err!(self.builder.build_load(
2642 type_value,
2643 pointer_value,
2644 &format!("local_{local_index}_get")
2645 ));
2646 tbaa_label(
2647 self.module,
2648 self.intrinsics,
2649 format!("local {local_index}"),
2650 v.as_instruction_value().unwrap(),
2651 );
2652 self.state.push1(v);
2653 }
2654 Operator::LocalSet { local_index } => {
2655 let pointer_value = self.locals[local_index as usize].1;
2656 let (v, i) = self.state.pop1_extra()?;
2657 let v = self.apply_pending_canonicalization(v, i)?;
2658 let store = err!(self.builder.build_store(pointer_value, v));
2659 tbaa_label(
2660 self.module,
2661 self.intrinsics,
2662 format!("local {local_index}"),
2663 store,
2664 );
2665 }
2666 Operator::LocalTee { local_index } => {
2667 let pointer_value = self.locals[local_index as usize].1;
2668 let (v, i) = self.state.peek1_extra()?;
2669 let v = self.apply_pending_canonicalization(v, i)?;
2670 let store = err!(self.builder.build_store(pointer_value, v));
2671 tbaa_label(
2672 self.module,
2673 self.intrinsics,
2674 format!("local {local_index}"),
2675 store,
2676 );
2677 }
2678
2679 Operator::GlobalGet { global_index } => {
2680 if self.g0m0.is_some() && global_index == 0 {
2681 let Some((g0, _)) = self.g0m0 else {
2682 unreachable!()
2683 };
2684
2685 let value = err!(self.builder.build_load(self.intrinsics.i32_ty, g0, ""));
2687
2688 self.state.push1(value);
2689 } else {
2690 let global_index = GlobalIndex::from_u32(global_index);
2691 match self
2692 .ctx
2693 .global(global_index, self.intrinsics, self.module)?
2694 {
2695 GlobalCache::Const { value } => {
2696 self.state.push1(*value);
2697 }
2698 GlobalCache::Mut {
2699 ptr_to_value,
2700 value_type,
2701 } => {
2702 let value =
2703 err!(self.builder.build_load(*value_type, *ptr_to_value, ""));
2704 tbaa_label(
2705 self.module,
2706 self.intrinsics,
2707 format!("global {}", global_index.as_u32()),
2708 value.as_instruction_value().unwrap(),
2709 );
2710 self.state.push1(value);
2711 }
2712 }
2713 }
2714 }
2715 Operator::GlobalSet { global_index } => {
2716 if self.g0m0.is_some() && global_index == 0 {
2717 let Some((g0, _)) = self.g0m0 else {
2718 unreachable!()
2719 };
2720 let ptr_to_value = g0;
2721 let (value, info) = self.state.pop1_extra()?;
2722 let value = self.apply_pending_canonicalization(value, info)?;
2723 let store = err!(self.builder.build_store(ptr_to_value, value));
2724 tbaa_label(self.module, self.intrinsics, "global 0".to_string(), store);
2725 } else {
2726 let global_index = GlobalIndex::from_u32(global_index);
2727 match self
2728 .ctx
2729 .global(global_index, self.intrinsics, self.module)?
2730 {
2731 GlobalCache::Const { value: _ } => {
2732 return Err(CompileError::Codegen(format!(
2733 "global.set on immutable global index {}",
2734 global_index.as_u32()
2735 )));
2736 }
2737 GlobalCache::Mut { ptr_to_value, .. } => {
2738 let ptr_to_value = *ptr_to_value;
2739 let (value, info) = self.state.pop1_extra()?;
2740 let value = self.apply_pending_canonicalization(value, info)?;
2741 let store = err!(self.builder.build_store(ptr_to_value, value));
2742 tbaa_label(
2743 self.module,
2744 self.intrinsics,
2745 format!("global {}", global_index.as_u32()),
2746 store,
2747 );
2748 }
2749 }
2750 }
2751 }
2752
2753 Operator::TypedSelect { .. } | Operator::Select => {
2756 let ((v1, i1), (v2, i2), (cond, _)) = self.state.pop3_extra()?;
2757 let (v1, i1, v2, i2) = if i1.has_pending_f32_nan() != i2.has_pending_f32_nan()
2765 || i1.has_pending_f64_nan() != i2.has_pending_f64_nan()
2766 {
2767 (
2768 self.apply_pending_canonicalization(v1, i1)?,
2769 i1.strip_pending(),
2770 self.apply_pending_canonicalization(v2, i2)?,
2771 i2.strip_pending(),
2772 )
2773 } else {
2774 (v1, i1, v2, i2)
2775 };
2776 let cond_value = err!(self.builder.build_int_compare(
2777 IntPredicate::NE,
2778 cond.into_int_value(),
2779 self.intrinsics.i32_zero,
2780 "",
2781 ));
2782 let res = err!(self.builder.build_select(cond_value, v1, v2, ""));
2783 let info = {
2784 let mut info = (i1.strip_pending() & i2.strip_pending())?;
2785 if i1.has_pending_f32_nan() {
2786 debug_assert!(i2.has_pending_f32_nan());
2787 info = (info | ExtraInfo::pending_f32_nan())?;
2788 }
2789 if i1.has_pending_f64_nan() {
2790 debug_assert!(i2.has_pending_f64_nan());
2791 info = (info | ExtraInfo::pending_f64_nan())?;
2792 }
2793 info
2794 };
2795 self.state.push1_extra(res, info);
2796 }
2797 Operator::Call { function_index } => {
2798 let func_index = FunctionIndex::from_u32(function_index);
2799 let sigindex = &self.wasm_module.functions[func_index];
2800 let func_type = &self.wasm_module.signatures[*sigindex];
2801
2802 let mut g0m0_params = None;
2803
2804 let FunctionCache {
2805 func,
2806 llvm_func_type,
2807 vmctx: callee_vmctx,
2808 attrs,
2809 } = if let Some(local_func_index) = self.wasm_module.local_func_index(func_index) {
2810 if let Some((g0, m0)) = &self.g0m0 {
2811 let value = err!(self.builder.build_load(self.intrinsics.i32_ty, *g0, ""));
2813
2814 g0m0_params = Some((value.into_int_value(), *m0));
2815 }
2816
2817 let function_name = self
2818 .symbol_registry
2819 .symbol_to_name(Symbol::LocalFunction(local_func_index));
2820
2821 self.ctx.local_func(
2822 local_func_index,
2823 func_index,
2824 self.intrinsics,
2825 self.module,
2826 self.context,
2827 func_type,
2828 &function_name,
2829 )?
2830 } else {
2831 self.ctx
2832 .func(func_index, self.intrinsics, self.context, func_type)?
2833 };
2834 let llvm_func_type = *llvm_func_type;
2835 let func = *func;
2836 let callee_vmctx = *callee_vmctx;
2837 let attrs = attrs.clone();
2838
2839 let params = self.state.popn_save_extra(func_type.params().len())?;
2845
2846 let params = params
2848 .iter()
2849 .zip(func_type.params().iter())
2850 .map(|((v, info), wasm_ty)| match wasm_ty {
2851 Type::F32 => err_nt!(self.builder.build_bit_cast(
2852 self.apply_pending_canonicalization(*v, *info)?,
2853 self.intrinsics.f32_ty,
2854 "",
2855 )),
2856 Type::F64 => err_nt!(self.builder.build_bit_cast(
2857 self.apply_pending_canonicalization(*v, *info)?,
2858 self.intrinsics.f64_ty,
2859 "",
2860 )),
2861 Type::V128 => self.apply_pending_canonicalization(*v, *info),
2862 _ => Ok(*v),
2863 })
2864 .collect::<Result<Vec<_>, _>>()?;
2865
2866 let params = self.abi.args_to_call(
2867 &self.alloca_builder,
2868 func_type,
2869 &llvm_func_type,
2870 callee_vmctx.into_pointer_value(),
2871 params.as_slice(),
2872 self.intrinsics,
2873 g0m0_params,
2874 )?;
2875
2876 let call_site = if let Some(lpad) = self.state.get_innermost_landingpad() {
2896 let then_block = self.context.append_basic_block(self.function, "then_block");
2897
2898 let ret = err!(self.builder.build_indirect_invoke(
2899 llvm_func_type,
2900 func,
2901 params.as_slice(),
2902 then_block,
2903 lpad,
2904 "",
2905 ));
2906
2907 self.builder.position_at_end(then_block);
2908 ret
2909 } else {
2910 err!(
2911 self.builder.build_indirect_call(
2912 llvm_func_type,
2913 func,
2914 params
2915 .iter()
2916 .copied()
2917 .map(Into::into)
2918 .collect::<Vec<BasicMetadataValueEnum>>()
2919 .as_slice(),
2920 "",
2921 )
2922 )
2923 };
2924 for (attr, attr_loc) in attrs {
2925 call_site.add_attribute(attr_loc, attr);
2926 }
2927 self.abi
2944 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
2945 .iter()
2946 .for_each(|ret| self.state.push1(*ret));
2947 }
2948 Operator::CallIndirect {
2949 type_index,
2950 table_index,
2951 } => {
2952 let sigindex = SignatureIndex::from_u32(type_index);
2953 let func_type = &self.wasm_module.signatures[sigindex];
2954 let expected_dynamic_sigindex =
2955 self.ctx
2956 .dynamic_sigindex(sigindex, self.intrinsics, self.module)?;
2957 let (table_base, table_bound) = self.ctx.table(
2958 TableIndex::from_u32(table_index),
2959 self.intrinsics,
2960 self.module,
2961 &self.builder,
2962 )?;
2963 let func_index = self.state.pop1()?.into_int_value();
2964
2965 let truncated_table_bounds = err!(self.builder.build_int_truncate(
2966 table_bound,
2967 self.intrinsics.i32_ty,
2968 "truncated_table_bounds",
2969 ));
2970
2971 let index_in_bounds = err!(self.builder.build_int_compare(
2973 IntPredicate::ULT,
2974 func_index,
2975 truncated_table_bounds,
2976 "index_in_bounds",
2977 ));
2978
2979 let index_in_bounds = err!(self.builder.build_call(
2980 self.intrinsics.expect_i1,
2981 &[
2982 index_in_bounds.into(),
2983 self.intrinsics.i1_ty.const_int(1, false).into(),
2984 ],
2985 "index_in_bounds_expect",
2986 ))
2987 .try_as_basic_value()
2988 .unwrap_basic()
2989 .into_int_value();
2990
2991 let in_bounds_continue_block = self
2992 .context
2993 .append_basic_block(self.function, "in_bounds_continue_block");
2994 let not_in_bounds_block = self
2995 .context
2996 .append_basic_block(self.function, "not_in_bounds_block");
2997 err!(self.builder.build_conditional_branch(
2998 index_in_bounds,
2999 in_bounds_continue_block,
3000 not_in_bounds_block,
3001 ));
3002 self.builder.position_at_end(not_in_bounds_block);
3003 err!(self.builder.build_call(
3004 self.intrinsics.throw_trap,
3005 &[self.intrinsics.trap_table_access_oob.into()],
3006 "throw",
3007 ));
3008 err!(self.builder.build_unreachable());
3009 self.builder.position_at_end(in_bounds_continue_block);
3010
3011 let casted_table_base = err!(self.builder.build_pointer_cast(
3014 table_base,
3015 self.context.ptr_type(AddressSpace::default()),
3016 "casted_table_base",
3017 ));
3018
3019 let funcref_ptr = unsafe {
3020 err!(self.builder.build_in_bounds_gep(
3021 self.intrinsics.ptr_ty,
3022 casted_table_base,
3023 &[func_index],
3024 "funcref_ptr",
3025 ))
3026 };
3027
3028 let anyfunc_struct_ptr = err!(self.builder.build_load(
3030 self.intrinsics.ptr_ty,
3031 funcref_ptr,
3032 "anyfunc_struct_ptr",
3033 ))
3034 .into_pointer_value();
3035
3036 {
3038 let funcref_not_null = err!(
3039 self.builder
3040 .build_is_not_null(anyfunc_struct_ptr, "null funcref check")
3041 );
3042
3043 let funcref_continue_deref_block = self
3044 .context
3045 .append_basic_block(self.function, "funcref_continue deref_block");
3046
3047 let funcref_is_null_block = self
3048 .context
3049 .append_basic_block(self.function, "funcref_is_null_block");
3050 err!(self.builder.build_conditional_branch(
3051 funcref_not_null,
3052 funcref_continue_deref_block,
3053 funcref_is_null_block,
3054 ));
3055 self.builder.position_at_end(funcref_is_null_block);
3056 err!(self.builder.build_call(
3057 self.intrinsics.throw_trap,
3058 &[self.intrinsics.trap_call_indirect_null.into()],
3059 "throw",
3060 ));
3061 err!(self.builder.build_unreachable());
3062 self.builder.position_at_end(funcref_continue_deref_block);
3063 }
3064
3065 let func_ptr_ptr = self
3067 .builder
3068 .build_struct_gep(
3069 self.intrinsics.anyfunc_ty,
3070 anyfunc_struct_ptr,
3071 0,
3072 "func_ptr_ptr",
3073 )
3074 .unwrap();
3075 let sigindex_ptr = self
3076 .builder
3077 .build_struct_gep(
3078 self.intrinsics.anyfunc_ty,
3079 anyfunc_struct_ptr,
3080 1,
3081 "sigindex_ptr",
3082 )
3083 .unwrap();
3084 let ctx_ptr_ptr = self
3085 .builder
3086 .build_struct_gep(
3087 self.intrinsics.anyfunc_ty,
3088 anyfunc_struct_ptr,
3089 2,
3090 "ctx_ptr_ptr",
3091 )
3092 .unwrap();
3093 let (func_ptr, found_dynamic_sigindex, ctx_ptr) = (
3094 err!(
3095 self.builder
3096 .build_load(self.intrinsics.ptr_ty, func_ptr_ptr, "func_ptr")
3097 )
3098 .into_pointer_value(),
3099 err!(
3100 self.builder
3101 .build_load(self.intrinsics.i32_ty, sigindex_ptr, "sigindex")
3102 )
3103 .into_int_value(),
3104 err!(
3105 self.builder
3106 .build_load(self.intrinsics.ptr_ty, ctx_ptr_ptr, "ctx_ptr")
3107 ),
3108 );
3109
3110 let elem_initialized = err!(self.builder.build_is_not_null(func_ptr, ""));
3114
3115 let sigindices_equal = err!(self.builder.build_int_compare(
3118 IntPredicate::EQ,
3119 expected_dynamic_sigindex,
3120 found_dynamic_sigindex,
3121 "sigindices_equal",
3122 ));
3123
3124 let initialized_and_sigindices_match = err!(self.builder.build_and(
3125 elem_initialized,
3126 sigindices_equal,
3127 ""
3128 ));
3129
3130 let initialized_and_sigindices_match = err!(self.builder.build_call(
3132 self.intrinsics.expect_i1,
3133 &[
3134 initialized_and_sigindices_match.into(),
3135 self.intrinsics.i1_ty.const_int(1, false).into(),
3136 ],
3137 "initialized_and_sigindices_match_expect",
3138 ))
3139 .try_as_basic_value()
3140 .unwrap_basic()
3141 .into_int_value();
3142
3143 let continue_block = self
3144 .context
3145 .append_basic_block(self.function, "continue_block");
3146 let sigindices_notequal_block = self
3147 .context
3148 .append_basic_block(self.function, "sigindices_notequal_block");
3149 err!(self.builder.build_conditional_branch(
3150 initialized_and_sigindices_match,
3151 continue_block,
3152 sigindices_notequal_block,
3153 ));
3154
3155 self.builder.position_at_end(sigindices_notequal_block);
3156 let trap_code = err!(self.builder.build_select(
3157 elem_initialized,
3158 self.intrinsics.trap_call_indirect_sig,
3159 self.intrinsics.trap_call_indirect_null,
3160 "",
3161 ));
3162 err!(self.builder.build_call(
3163 self.intrinsics.throw_trap,
3164 &[trap_code.into()],
3165 "throw"
3166 ));
3167 err!(self.builder.build_unreachable());
3168 self.builder.position_at_end(continue_block);
3169
3170 if self.g0m0.is_some() {
3171 self.build_g0m0_indirect_call(
3172 table_index,
3173 ctx_ptr.into_pointer_value(),
3174 func_type,
3175 func_ptr,
3176 func_index,
3177 )?;
3178 } else {
3179 let call_site = self.build_indirect_call(
3180 ctx_ptr.into_pointer_value(),
3181 func_type,
3182 func_ptr,
3183 None,
3184 None,
3185 )?;
3186
3187 self.abi
3188 .rets_from_call(&self.builder, self.intrinsics, call_site, func_type)?
3189 .iter()
3190 .for_each(|ret| self.state.push1(*ret));
3191 }
3192 }
3193
3194 Operator::I32Add | Operator::I64Add => {
3199 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3200 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3201 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3202 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3203 let res = err!(self.builder.build_int_add(v1, v2, ""));
3204 self.state.push1(res);
3205 }
3206 Operator::I8x16Add => {
3207 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3208 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3209 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3210 let res = err!(self.builder.build_int_add(v1, v2, ""));
3211 let res = err!(
3212 self.builder
3213 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3214 );
3215 self.state.push1(res);
3216 }
3217 Operator::I16x8Add => {
3218 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3219 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3220 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3221 let res = err!(self.builder.build_int_add(v1, v2, ""));
3222 let res = err!(
3223 self.builder
3224 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3225 );
3226 self.state.push1(res);
3227 }
3228 Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U => {
3229 let extend_op = match op {
3230 Operator::I16x8ExtAddPairwiseI8x16S => {
3231 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, "")
3232 }
3233 Operator::I16x8ExtAddPairwiseI8x16U => {
3234 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, "")
3235 }
3236 _ => unreachable!("Unhandled internal variant"),
3237 };
3238 let (v, i) = self.state.pop1_extra()?;
3239 let (v, _) = self.v128_into_i8x16(v, i)?;
3240
3241 let left = err!(self.builder.build_shuffle_vector(
3242 v,
3243 v.get_type().get_undef(),
3244 VectorType::const_vector(&[
3245 self.intrinsics.i32_consts[0],
3246 self.intrinsics.i32_consts[2],
3247 self.intrinsics.i32_consts[4],
3248 self.intrinsics.i32_consts[6],
3249 self.intrinsics.i32_consts[8],
3250 self.intrinsics.i32_consts[10],
3251 self.intrinsics.i32_consts[12],
3252 self.intrinsics.i32_consts[14],
3253 ]),
3254 "",
3255 ));
3256 let left = err!(extend_op(self, left));
3257 let right = err!(self.builder.build_shuffle_vector(
3258 v,
3259 v.get_type().get_undef(),
3260 VectorType::const_vector(&[
3261 self.intrinsics.i32_consts[1],
3262 self.intrinsics.i32_consts[3],
3263 self.intrinsics.i32_consts[5],
3264 self.intrinsics.i32_consts[7],
3265 self.intrinsics.i32_consts[9],
3266 self.intrinsics.i32_consts[11],
3267 self.intrinsics.i32_consts[13],
3268 self.intrinsics.i32_consts[15],
3269 ]),
3270 "",
3271 ));
3272 let right = err!(extend_op(self, right));
3273
3274 let res = err!(self.builder.build_int_add(left, right, ""));
3275 let res = err!(
3276 self.builder
3277 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3278 );
3279 self.state.push1(res);
3280 }
3281 Operator::I32x4Add => {
3282 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3283 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3284 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3285 let res = err!(self.builder.build_int_add(v1, v2, ""));
3286 let res = err!(
3287 self.builder
3288 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3289 );
3290 self.state.push1(res);
3291 }
3292 Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
3293 let extend_op = match op {
3294 Operator::I32x4ExtAddPairwiseI16x8S => {
3295 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3296 }
3297 Operator::I32x4ExtAddPairwiseI16x8U => {
3298 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3299 }
3300 _ => unreachable!("Unhandled internal variant"),
3301 };
3302 let (v, i) = self.state.pop1_extra()?;
3303 let (v, _) = self.v128_into_i16x8(v, i)?;
3304
3305 let left = err!(self.builder.build_shuffle_vector(
3306 v,
3307 v.get_type().get_undef(),
3308 VectorType::const_vector(&[
3309 self.intrinsics.i32_consts[0],
3310 self.intrinsics.i32_consts[2],
3311 self.intrinsics.i32_consts[4],
3312 self.intrinsics.i32_consts[6],
3313 ]),
3314 "",
3315 ));
3316 let left = err!(extend_op(self, left));
3317 let right = err!(self.builder.build_shuffle_vector(
3318 v,
3319 v.get_type().get_undef(),
3320 VectorType::const_vector(&[
3321 self.intrinsics.i32_consts[1],
3322 self.intrinsics.i32_consts[3],
3323 self.intrinsics.i32_consts[5],
3324 self.intrinsics.i32_consts[7],
3325 ]),
3326 "",
3327 ));
3328 let right = err!(extend_op(self, right));
3329
3330 let res = err!(self.builder.build_int_add(left, right, ""));
3331 let res = err!(
3332 self.builder
3333 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3334 );
3335 self.state.push1(res);
3336 }
3337 Operator::I64x2Add => {
3338 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3339 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3340 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3341 let res = err!(self.builder.build_int_add(v1, v2, ""));
3342 let res = err!(
3343 self.builder
3344 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3345 );
3346 self.state.push1(res);
3347 }
3348 Operator::I8x16AddSatS => {
3349 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3350 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3351 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3352 let res = err!(self.builder.build_call(
3353 self.intrinsics.sadd_sat_i8x16,
3354 &[v1.into(), v2.into()],
3355 ""
3356 ))
3357 .try_as_basic_value()
3358 .unwrap_basic();
3359 let res = err!(
3360 self.builder
3361 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3362 );
3363 self.state.push1(res);
3364 }
3365 Operator::I16x8AddSatS => {
3366 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3367 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3368 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3369 let res = err!(self.builder.build_call(
3370 self.intrinsics.sadd_sat_i16x8,
3371 &[v1.into(), v2.into()],
3372 ""
3373 ))
3374 .try_as_basic_value()
3375 .unwrap_basic();
3376 let res = err!(
3377 self.builder
3378 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3379 );
3380 self.state.push1(res);
3381 }
3382 Operator::I8x16AddSatU => {
3383 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3384 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3385 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3386 let res = err!(self.builder.build_call(
3387 self.intrinsics.uadd_sat_i8x16,
3388 &[v1.into(), v2.into()],
3389 ""
3390 ))
3391 .try_as_basic_value()
3392 .unwrap_basic();
3393 let res = err!(
3394 self.builder
3395 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3396 );
3397 self.state.push1(res);
3398 }
3399 Operator::I16x8AddSatU => {
3400 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3401 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3402 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3403 let res = err!(self.builder.build_call(
3404 self.intrinsics.uadd_sat_i16x8,
3405 &[v1.into(), v2.into()],
3406 ""
3407 ))
3408 .try_as_basic_value()
3409 .unwrap_basic();
3410 let res = err!(
3411 self.builder
3412 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3413 );
3414 self.state.push1(res);
3415 }
3416 Operator::I32Sub | Operator::I64Sub => {
3417 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3418 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3419 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3420 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3421 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3422 self.state.push1(res);
3423 }
3424 Operator::I8x16Sub => {
3425 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3426 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3427 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3428 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3429 let res = err!(
3430 self.builder
3431 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3432 );
3433 self.state.push1(res);
3434 }
3435 Operator::I16x8Sub => {
3436 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3437 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3438 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3439 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3440 let res = err!(
3441 self.builder
3442 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3443 );
3444 self.state.push1(res);
3445 }
3446 Operator::I32x4Sub => {
3447 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3448 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3449 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3450 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3451 let res = err!(
3452 self.builder
3453 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3454 );
3455 self.state.push1(res);
3456 }
3457 Operator::I64x2Sub => {
3458 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3459 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3460 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3461 let res = err!(self.builder.build_int_sub(v1, v2, ""));
3462 let res = err!(
3463 self.builder
3464 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3465 );
3466 self.state.push1(res);
3467 }
3468 Operator::I8x16SubSatS => {
3469 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3470 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3471 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3472 let res = err!(self.builder.build_call(
3473 self.intrinsics.ssub_sat_i8x16,
3474 &[v1.into(), v2.into()],
3475 ""
3476 ))
3477 .try_as_basic_value()
3478 .unwrap_basic();
3479 let res = err!(
3480 self.builder
3481 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3482 );
3483 self.state.push1(res);
3484 }
3485 Operator::I16x8SubSatS => {
3486 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3487 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3488 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3489 let res = err!(self.builder.build_call(
3490 self.intrinsics.ssub_sat_i16x8,
3491 &[v1.into(), v2.into()],
3492 ""
3493 ))
3494 .try_as_basic_value()
3495 .unwrap_basic();
3496 let res = err!(
3497 self.builder
3498 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3499 );
3500 self.state.push1(res);
3501 }
3502 Operator::I8x16SubSatU => {
3503 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3504 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3505 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3506 let res = err!(self.builder.build_call(
3507 self.intrinsics.usub_sat_i8x16,
3508 &[v1.into(), v2.into()],
3509 ""
3510 ))
3511 .try_as_basic_value()
3512 .unwrap_basic();
3513 let res = err!(
3514 self.builder
3515 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3516 );
3517 self.state.push1(res);
3518 }
3519 Operator::I16x8SubSatU => {
3520 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3521 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3522 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3523 let res = err!(self.builder.build_call(
3524 self.intrinsics.usub_sat_i16x8,
3525 &[v1.into(), v2.into()],
3526 ""
3527 ))
3528 .try_as_basic_value()
3529 .unwrap_basic();
3530 let res = err!(
3531 self.builder
3532 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3533 );
3534 self.state.push1(res);
3535 }
3536 Operator::I32Mul | Operator::I64Mul => {
3537 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3538 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3539 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3540 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3541 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3542 self.state.push1(res);
3543 }
3544 Operator::I16x8Mul => {
3545 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3546 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3547 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3548 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3549 let res = err!(
3550 self.builder
3551 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3552 );
3553 self.state.push1(res);
3554 }
3555 Operator::I32x4Mul => {
3556 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3557 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3558 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3559 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3560 let res = err!(
3561 self.builder
3562 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3563 );
3564 self.state.push1(res);
3565 }
3566 Operator::I64x2Mul => {
3567 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3568 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
3569 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
3570 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3571 let res = err!(
3572 self.builder
3573 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3574 );
3575 self.state.push1(res);
3576 }
3577 Operator::I16x8Q15MulrSatS => {
3578 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3579 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3580 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3581
3582 let max_value = self.intrinsics.i16_ty.const_int(i16::MAX as u64, false);
3583 let max_values = VectorType::const_vector(&[max_value; 8]);
3584
3585 let v1 = err!(
3586 self.builder
3587 .build_int_s_extend(v1, self.intrinsics.i32x8_ty, "")
3588 );
3589 let v2 = err!(
3590 self.builder
3591 .build_int_s_extend(v2, self.intrinsics.i32x8_ty, "")
3592 );
3593 let res = err!(self.builder.build_int_mul(v1, v2, ""));
3594
3595 let bit = self.intrinsics.i32_ty.const_int(0x4000, false);
3597 let bits = VectorType::const_vector(&[bit; 8]);
3598
3599 let res = err!(self.builder.build_int_add(res, bits, ""));
3600
3601 let fifteen = self.intrinsics.i32_consts[15];
3602 let fifteens = VectorType::const_vector(&[fifteen; 8]);
3603
3604 let res = err!(self.builder.build_right_shift(res, fifteens, true, ""));
3605 let saturate_up = {
3606 let max_values = err!(self.builder.build_int_s_extend(
3607 max_values,
3608 self.intrinsics.i32x8_ty,
3609 ""
3610 ));
3611 err!(
3612 self.builder
3613 .build_int_compare(IntPredicate::SGT, res, max_values, "")
3614 )
3615 };
3616
3617 let res = err!(
3618 self.builder
3619 .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
3620 );
3621
3622 let res = err!(self.builder.build_select(saturate_up, max_values, res, ""))
3623 .into_vector_value();
3624 let res = err!(
3625 self.builder
3626 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3627 );
3628 self.state.push1(res);
3629 }
3630 Operator::I16x8ExtMulLowI8x16S
3631 | Operator::I16x8ExtMulLowI8x16U
3632 | Operator::I16x8ExtMulHighI8x16S
3633 | Operator::I16x8ExtMulHighI8x16U => {
3634 let extend_op = match op {
3635 Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulHighI8x16S => {
3636 |s: &Self, v| -> Result<VectorValue, CompileError> {
3637 err_nt!(s.builder.build_int_s_extend(v, s.intrinsics.i16x8_ty, ""))
3638 }
3639 }
3640 Operator::I16x8ExtMulLowI8x16U | Operator::I16x8ExtMulHighI8x16U => {
3641 |s: &Self, v| -> Result<VectorValue, CompileError> {
3642 err_nt!(s.builder.build_int_z_extend(v, s.intrinsics.i16x8_ty, ""))
3643 }
3644 }
3645 _ => unreachable!("Unhandled internal variant"),
3646 };
3647 let shuffle_array = match op {
3648 Operator::I16x8ExtMulLowI8x16S | Operator::I16x8ExtMulLowI8x16U => [
3649 self.intrinsics.i32_consts[0],
3650 self.intrinsics.i32_consts[2],
3651 self.intrinsics.i32_consts[4],
3652 self.intrinsics.i32_consts[6],
3653 self.intrinsics.i32_consts[8],
3654 self.intrinsics.i32_consts[10],
3655 self.intrinsics.i32_consts[12],
3656 self.intrinsics.i32_consts[14],
3657 ],
3658 Operator::I16x8ExtMulHighI8x16S | Operator::I16x8ExtMulHighI8x16U => [
3659 self.intrinsics.i32_consts[1],
3660 self.intrinsics.i32_consts[3],
3661 self.intrinsics.i32_consts[5],
3662 self.intrinsics.i32_consts[7],
3663 self.intrinsics.i32_consts[9],
3664 self.intrinsics.i32_consts[11],
3665 self.intrinsics.i32_consts[13],
3666 self.intrinsics.i32_consts[15],
3667 ],
3668 _ => unreachable!("Unhandled internal variant"),
3669 };
3670 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3671 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
3672 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
3673 let val1 = err!(self.builder.build_shuffle_vector(
3674 v1,
3675 v1.get_type().get_undef(),
3676 VectorType::const_vector(&shuffle_array),
3677 "",
3678 ));
3679 let val1 = err!(extend_op(self, val1));
3680 let val2 = err!(self.builder.build_shuffle_vector(
3681 v2,
3682 v2.get_type().get_undef(),
3683 VectorType::const_vector(&shuffle_array),
3684 "",
3685 ));
3686 let val2 = err!(extend_op(self, val2));
3687 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3688 let res = err!(
3689 self.builder
3690 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3691 );
3692 self.state.push1(res);
3693 }
3694 Operator::I32x4ExtMulLowI16x8S
3695 | Operator::I32x4ExtMulLowI16x8U
3696 | Operator::I32x4ExtMulHighI16x8S
3697 | Operator::I32x4ExtMulHighI16x8U => {
3698 let extend_op = match op {
3699 Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulHighI16x8S => {
3700 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
3701 }
3702 Operator::I32x4ExtMulLowI16x8U | Operator::I32x4ExtMulHighI16x8U => {
3703 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
3704 }
3705 _ => unreachable!("Unhandled internal variant"),
3706 };
3707 let shuffle_array = match op {
3708 Operator::I32x4ExtMulLowI16x8S | Operator::I32x4ExtMulLowI16x8U => [
3709 self.intrinsics.i32_consts[0],
3710 self.intrinsics.i32_consts[2],
3711 self.intrinsics.i32_consts[4],
3712 self.intrinsics.i32_consts[6],
3713 ],
3714 Operator::I32x4ExtMulHighI16x8S | Operator::I32x4ExtMulHighI16x8U => [
3715 self.intrinsics.i32_consts[1],
3716 self.intrinsics.i32_consts[3],
3717 self.intrinsics.i32_consts[5],
3718 self.intrinsics.i32_consts[7],
3719 ],
3720 _ => unreachable!("Unhandled internal variant"),
3721 };
3722 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3723 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3724 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3725 let val1 = err!(self.builder.build_shuffle_vector(
3726 v1,
3727 v1.get_type().get_undef(),
3728 VectorType::const_vector(&shuffle_array),
3729 "",
3730 ));
3731 let val1 = err!(extend_op(self, val1));
3732 let val2 = err!(self.builder.build_shuffle_vector(
3733 v2,
3734 v2.get_type().get_undef(),
3735 VectorType::const_vector(&shuffle_array),
3736 "",
3737 ));
3738 let val2 = err!(extend_op(self, val2));
3739 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3740 let res = err!(
3741 self.builder
3742 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3743 );
3744 self.state.push1(res);
3745 }
3746 Operator::I64x2ExtMulLowI32x4S
3747 | Operator::I64x2ExtMulLowI32x4U
3748 | Operator::I64x2ExtMulHighI32x4S
3749 | Operator::I64x2ExtMulHighI32x4U => {
3750 let extend_op = match op {
3751 Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulHighI32x4S => {
3752 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
3753 }
3754 Operator::I64x2ExtMulLowI32x4U | Operator::I64x2ExtMulHighI32x4U => {
3755 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
3756 }
3757 _ => unreachable!("Unhandled internal variant"),
3758 };
3759 let shuffle_array = match op {
3760 Operator::I64x2ExtMulLowI32x4S | Operator::I64x2ExtMulLowI32x4U => {
3761 [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[2]]
3762 }
3763 Operator::I64x2ExtMulHighI32x4S | Operator::I64x2ExtMulHighI32x4U => {
3764 [self.intrinsics.i32_consts[1], self.intrinsics.i32_consts[3]]
3765 }
3766 _ => unreachable!("Unhandled internal variant"),
3767 };
3768 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3769 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
3770 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
3771 let val1 = err!(self.builder.build_shuffle_vector(
3772 v1,
3773 v1.get_type().get_undef(),
3774 VectorType::const_vector(&shuffle_array),
3775 "",
3776 ));
3777 let val1 = err!(extend_op(self, val1));
3778 let val2 = err!(self.builder.build_shuffle_vector(
3779 v2,
3780 v2.get_type().get_undef(),
3781 VectorType::const_vector(&shuffle_array),
3782 "",
3783 ));
3784 let val2 = err!(extend_op(self, val2));
3785 let res = err!(self.builder.build_int_mul(val1, val2, ""));
3786 let res = err!(
3787 self.builder
3788 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3789 );
3790 self.state.push1(res);
3791 }
3792 Operator::I32x4DotI16x8S => {
3793 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3794 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
3795 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
3796 let low_i16 = [
3797 self.intrinsics.i32_consts[0],
3798 self.intrinsics.i32_consts[2],
3799 self.intrinsics.i32_consts[4],
3800 self.intrinsics.i32_consts[6],
3801 ];
3802 let high_i16 = [
3803 self.intrinsics.i32_consts[1],
3804 self.intrinsics.i32_consts[3],
3805 self.intrinsics.i32_consts[5],
3806 self.intrinsics.i32_consts[7],
3807 ];
3808 let v1_low = err!(self.builder.build_shuffle_vector(
3809 v1,
3810 v1.get_type().get_undef(),
3811 VectorType::const_vector(&low_i16),
3812 "",
3813 ));
3814 let v1_low = err!(self.builder.build_int_s_extend(
3815 v1_low,
3816 self.intrinsics.i32x4_ty,
3817 ""
3818 ));
3819 let v1_high = err!(self.builder.build_shuffle_vector(
3820 v1,
3821 v1.get_type().get_undef(),
3822 VectorType::const_vector(&high_i16),
3823 "",
3824 ));
3825 let v1_high = err!(self.builder.build_int_s_extend(
3826 v1_high,
3827 self.intrinsics.i32x4_ty,
3828 ""
3829 ));
3830 let v2_low = err!(self.builder.build_shuffle_vector(
3831 v2,
3832 v2.get_type().get_undef(),
3833 VectorType::const_vector(&low_i16),
3834 "",
3835 ));
3836 let v2_low = err!(self.builder.build_int_s_extend(
3837 v2_low,
3838 self.intrinsics.i32x4_ty,
3839 ""
3840 ));
3841 let v2_high = err!(self.builder.build_shuffle_vector(
3842 v2,
3843 v2.get_type().get_undef(),
3844 VectorType::const_vector(&high_i16),
3845 "",
3846 ));
3847 let v2_high = err!(self.builder.build_int_s_extend(
3848 v2_high,
3849 self.intrinsics.i32x4_ty,
3850 ""
3851 ));
3852 let low_product = err!(self.builder.build_int_mul(v1_low, v2_low, ""));
3853 let high_product = err!(self.builder.build_int_mul(v1_high, v2_high, ""));
3854
3855 let res = err!(self.builder.build_int_add(low_product, high_product, ""));
3856 let res = err!(
3857 self.builder
3858 .build_bit_cast(res, self.intrinsics.i128_ty, "")
3859 );
3860 self.state.push1(res);
3861 }
3862 Operator::I32DivS | Operator::I64DivS => {
3863 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3864 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3865 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3866 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3867
3868 self.trap_if_zero_or_overflow(v1, v2)?;
3869
3870 let res = err!(self.builder.build_int_signed_div(v1, v2, ""));
3871 self.state.push1(res);
3872 }
3873 Operator::I32DivU | Operator::I64DivU => {
3874 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3875 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3876 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3877 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3878
3879 self.trap_if_zero(v2)?;
3880
3881 let res = err!(self.builder.build_int_unsigned_div(v1, v2, ""));
3882 self.state.push1(res);
3883 }
3884 Operator::I32RemS | Operator::I64RemS => {
3885 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3886 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3887 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3888 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3889 let int_type = v1.get_type();
3890 let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {
3891 let min_value = int_type.const_int(i32::MIN as u64, false);
3892 let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);
3893 (min_value, neg_one_value)
3894 } else if int_type == self.intrinsics.i64_ty {
3895 let min_value = int_type.const_int(i64::MIN as u64, false);
3896 let neg_one_value = int_type.const_int(-1i64 as u64, false);
3897 (min_value, neg_one_value)
3898 } else {
3899 unreachable!()
3900 };
3901
3902 self.trap_if_zero(v2)?;
3903
3904 let will_overflow = err!(self.builder.build_and(
3916 err!(self.builder.build_int_compare(
3917 IntPredicate::EQ,
3918 v1,
3919 min_value,
3920 "left_is_min"
3921 )),
3922 err!(self.builder.build_int_compare(
3923 IntPredicate::EQ,
3924 v2,
3925 neg_one_value,
3926 "right_is_neg_one",
3927 )),
3928 "srem_will_overflow",
3929 ));
3930 let v1 =
3931 err!(
3932 self.builder
3933 .build_select(will_overflow, int_type.const_zero(), v1, "")
3934 )
3935 .into_int_value();
3936 let res = err!(self.builder.build_int_signed_rem(v1, v2, ""));
3937 self.state.push1(res);
3938 }
3939 Operator::I32RemU | Operator::I64RemU => {
3940 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3941 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3942 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3943 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3944
3945 self.trap_if_zero(v2)?;
3946
3947 let res = err!(self.builder.build_int_unsigned_rem(v1, v2, ""));
3948 self.state.push1(res);
3949 }
3950 Operator::I32And | Operator::I64And | Operator::V128And => {
3951 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3952 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3953 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3954 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3955 let res = err!(self.builder.build_and(v1, v2, ""));
3956 self.state.push1(res);
3957 }
3958 Operator::I32Or | Operator::I64Or | Operator::V128Or => {
3959 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3960 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3961 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3962 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3963 let res = err!(self.builder.build_or(v1, v2, ""));
3964 self.state.push1(res);
3965 }
3966 Operator::I32Xor | Operator::I64Xor | Operator::V128Xor => {
3967 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3968 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3969 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3970 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3971 let res = err!(self.builder.build_xor(v1, v2, ""));
3972 self.state.push1(res);
3973 }
3974 Operator::V128AndNot => {
3975 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
3976 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3977 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3978 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
3979 let v2 = err!(self.builder.build_not(v2, ""));
3980 let res = err!(self.builder.build_and(v1, v2, ""));
3981 self.state.push1(res);
3982 }
3983 Operator::V128Bitselect => {
3984 let ((v1, i1), (v2, i2), (cond, cond_info)) = self.state.pop3_extra()?;
3985 let v1 = self.apply_pending_canonicalization(v1, i1)?;
3986 let v2 = self.apply_pending_canonicalization(v2, i2)?;
3987 let cond = self.apply_pending_canonicalization(cond, cond_info)?;
3988 let v1 = err!(
3989 self.builder
3990 .build_bit_cast(v1, self.intrinsics.i1x128_ty, "")
3991 )
3992 .into_vector_value();
3993 let v2 = err!(
3994 self.builder
3995 .build_bit_cast(v2, self.intrinsics.i1x128_ty, "")
3996 )
3997 .into_vector_value();
3998 let cond = err!(
3999 self.builder
4000 .build_bit_cast(cond, self.intrinsics.i1x128_ty, "")
4001 )
4002 .into_vector_value();
4003 let res = err!(self.builder.build_select(cond, v1, v2, ""));
4004 let res = err!(
4005 self.builder
4006 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4007 );
4008 self.state.push1(res);
4009 }
4010 Operator::I8x16Bitmask => {
4011 let (v, i) = self.state.pop1_extra()?;
4012 let (v, _) = self.v128_into_i8x16(v, i)?;
4013
4014 let zeros = self.intrinsics.i8x16_ty.const_zero();
4015 let res = err!(
4016 self.builder
4017 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4018 );
4019 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i16_ty, ""))
4020 .into_int_value();
4021 let res = err!(
4022 self.builder
4023 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4024 );
4025 self.state.push1(res);
4026 }
4027 Operator::I16x8Bitmask => {
4028 let (v, i) = self.state.pop1_extra()?;
4029 let (v, _) = self.v128_into_i16x8(v, i)?;
4030
4031 let zeros = self.intrinsics.i16x8_ty.const_zero();
4032 let res = err!(
4033 self.builder
4034 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4035 );
4036 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i8_ty, ""))
4037 .into_int_value();
4038 let res = err!(
4039 self.builder
4040 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4041 );
4042 self.state.push1(res);
4043 }
4044 Operator::I32x4Bitmask => {
4045 let (v, i) = self.state.pop1_extra()?;
4046 let (v, _) = self.v128_into_i32x4(v, i)?;
4047
4048 let zeros = self.intrinsics.i32x4_ty.const_zero();
4049 let res = err!(
4050 self.builder
4051 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4052 );
4053 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i4_ty, ""))
4054 .into_int_value();
4055 let res = err!(
4056 self.builder
4057 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4058 );
4059 self.state.push1(res);
4060 }
4061 Operator::I64x2Bitmask => {
4062 let (v, i) = self.state.pop1_extra()?;
4063 let (v, _) = self.v128_into_i64x2(v, i)?;
4064
4065 let zeros = self.intrinsics.i64x2_ty.const_zero();
4066 let res = err!(
4067 self.builder
4068 .build_int_compare(IntPredicate::SLT, v, zeros, "")
4069 );
4070 let res = err!(self.builder.build_bit_cast(res, self.intrinsics.i2_ty, ""))
4071 .into_int_value();
4072 let res = err!(
4073 self.builder
4074 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
4075 );
4076 self.state.push1(res);
4077 }
4078 Operator::I32Shl => {
4079 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4080 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4081 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4082 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4083 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4084 let v2 = err!(self.builder.build_and(v2, mask, ""));
4085 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4086 self.state.push1(res);
4087 }
4088 Operator::I64Shl => {
4089 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4090 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4091 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4092 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4093 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4094 let v2 = err!(self.builder.build_and(v2, mask, ""));
4095 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4096 self.state.push1(res);
4097 }
4098 Operator::I8x16Shl => {
4099 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4100 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4101 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4102 let v2 = v2.into_int_value();
4103 let v2 = err!(
4104 self.builder
4105 .build_and(v2, self.intrinsics.i32_consts[7], "")
4106 );
4107 let v2 = err!(
4108 self.builder
4109 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4110 );
4111 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4112 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4113 let res = err!(
4114 self.builder
4115 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4116 );
4117 self.state.push1(res);
4118 }
4119 Operator::I16x8Shl => {
4120 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4121 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4122 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4123 let v2 = v2.into_int_value();
4124 let v2 = err!(
4125 self.builder
4126 .build_and(v2, self.intrinsics.i32_consts[15], "")
4127 );
4128 let v2 = err!(
4129 self.builder
4130 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4131 );
4132 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4133 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4134 let res = err!(
4135 self.builder
4136 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4137 );
4138 self.state.push1(res);
4139 }
4140 Operator::I32x4Shl => {
4141 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4142 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4143 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4144 let v2 = v2.into_int_value();
4145 let v2 = err!(self.builder.build_and(
4146 v2,
4147 self.intrinsics.i32_ty.const_int(31, false),
4148 ""
4149 ));
4150 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4151 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4152 let res = err!(
4153 self.builder
4154 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4155 );
4156 self.state.push1(res);
4157 }
4158 Operator::I64x2Shl => {
4159 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4160 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4161 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4162 let v2 = v2.into_int_value();
4163 let v2 = err!(self.builder.build_and(
4164 v2,
4165 self.intrinsics.i32_ty.const_int(63, false),
4166 ""
4167 ));
4168 let v2 = err!(
4169 self.builder
4170 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4171 );
4172 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4173 let res = err!(self.builder.build_left_shift(v1, v2, ""));
4174 let res = err!(
4175 self.builder
4176 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4177 );
4178 self.state.push1(res);
4179 }
4180 Operator::I32ShrS => {
4181 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4182 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4183 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4184 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4185 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4186 let v2 = err!(self.builder.build_and(v2, mask, ""));
4187 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4188 self.state.push1(res);
4189 }
4190 Operator::I64ShrS => {
4191 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4192 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4193 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4194 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4195 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4196 let v2 = err!(self.builder.build_and(v2, mask, ""));
4197 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4198 self.state.push1(res);
4199 }
4200 Operator::I8x16ShrS => {
4201 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4202 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4203 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4204 let v2 = v2.into_int_value();
4205 let v2 = err!(
4206 self.builder
4207 .build_and(v2, self.intrinsics.i32_consts[7], "")
4208 );
4209 let v2 = err!(
4210 self.builder
4211 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4212 );
4213 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4214 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4215 let res = err!(
4216 self.builder
4217 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4218 );
4219 self.state.push1(res);
4220 }
4221 Operator::I16x8ShrS => {
4222 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4223 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4224 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4225 let v2 = v2.into_int_value();
4226 let v2 = err!(
4227 self.builder
4228 .build_and(v2, self.intrinsics.i32_consts[15], "")
4229 );
4230 let v2 = err!(
4231 self.builder
4232 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4233 );
4234 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4235 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4236 let res = err!(
4237 self.builder
4238 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4239 );
4240 self.state.push1(res);
4241 }
4242 Operator::I32x4ShrS => {
4243 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4244 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4245 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4246 let v2 = v2.into_int_value();
4247 let v2 = err!(self.builder.build_and(
4248 v2,
4249 self.intrinsics.i32_ty.const_int(31, false),
4250 ""
4251 ));
4252 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4253 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4254 let res = err!(
4255 self.builder
4256 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4257 );
4258 self.state.push1(res);
4259 }
4260 Operator::I64x2ShrS => {
4261 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4262 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4263 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4264 let v2 = v2.into_int_value();
4265 let v2 = err!(self.builder.build_and(
4266 v2,
4267 self.intrinsics.i32_ty.const_int(63, false),
4268 ""
4269 ));
4270 let v2 = err!(
4271 self.builder
4272 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4273 );
4274 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4275 let res = err!(self.builder.build_right_shift(v1, v2, true, ""));
4276 let res = err!(
4277 self.builder
4278 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4279 );
4280 self.state.push1(res);
4281 }
4282 Operator::I32ShrU => {
4283 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4284 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4285 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4286 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4287 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4288 let v2 = err!(self.builder.build_and(v2, mask, ""));
4289 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4290 self.state.push1(res);
4291 }
4292 Operator::I64ShrU => {
4293 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4294 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4295 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4296 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4297 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4298 let v2 = err!(self.builder.build_and(v2, mask, ""));
4299 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4300 self.state.push1(res);
4301 }
4302 Operator::I8x16ShrU => {
4303 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4304 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4305 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4306 let v2 = v2.into_int_value();
4307 let v2 = err!(
4308 self.builder
4309 .build_and(v2, self.intrinsics.i32_consts[7], "")
4310 );
4311 let v2 = err!(
4312 self.builder
4313 .build_int_truncate(v2, self.intrinsics.i8_ty, "")
4314 );
4315 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
4316 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4317 let res = err!(
4318 self.builder
4319 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4320 );
4321 self.state.push1(res);
4322 }
4323 Operator::I16x8ShrU => {
4324 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4325 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4326 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4327 let v2 = v2.into_int_value();
4328 let v2 = err!(
4329 self.builder
4330 .build_and(v2, self.intrinsics.i32_consts[15], "")
4331 );
4332 let v2 = err!(
4333 self.builder
4334 .build_int_truncate(v2, self.intrinsics.i16_ty, "")
4335 );
4336 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i16x8_ty)?;
4337 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4338 let res = err!(
4339 self.builder
4340 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4341 );
4342 self.state.push1(res);
4343 }
4344 Operator::I32x4ShrU => {
4345 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4346 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4347 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4348 let v2 = v2.into_int_value();
4349 let v2 = err!(self.builder.build_and(
4350 v2,
4351 self.intrinsics.i32_ty.const_int(31, false),
4352 ""
4353 ));
4354 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i32x4_ty)?;
4355 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4356 let res = err!(
4357 self.builder
4358 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4359 );
4360 self.state.push1(res);
4361 }
4362 Operator::I64x2ShrU => {
4363 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4364 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
4365 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4366 let v2 = v2.into_int_value();
4367 let v2 = err!(self.builder.build_and(
4368 v2,
4369 self.intrinsics.i32_ty.const_int(63, false),
4370 ""
4371 ));
4372 let v2 = err!(
4373 self.builder
4374 .build_int_z_extend(v2, self.intrinsics.i64_ty, "")
4375 );
4376 let v2 = self.splat_vector(v2.as_basic_value_enum(), self.intrinsics.i64x2_ty)?;
4377 let res = err!(self.builder.build_right_shift(v1, v2, false, ""));
4378 let res = err!(
4379 self.builder
4380 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4381 );
4382 self.state.push1(res);
4383 }
4384 Operator::I32Rotl => {
4385 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4386 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4387 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4388 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4389 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4390 let v2 = err!(self.builder.build_and(v2, mask, ""));
4391 let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4392 let rhs = {
4393 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4394 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4395 err!(self.builder.build_right_shift(v1, rhs, false, ""))
4396 };
4397 let res = err!(self.builder.build_or(lhs, rhs, ""));
4398 self.state.push1(res);
4399 }
4400 Operator::I64Rotl => {
4401 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4402 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4403 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4404 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4405 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4406 let v2 = err!(self.builder.build_and(v2, mask, ""));
4407 let lhs = err!(self.builder.build_left_shift(v1, v2, ""));
4408 let rhs = {
4409 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4410 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4411 err!(self.builder.build_right_shift(v1, rhs, false, ""))
4412 };
4413 let res = err!(self.builder.build_or(lhs, rhs, ""));
4414 self.state.push1(res);
4415 }
4416 Operator::I32Rotr => {
4417 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4418 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4419 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4420 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4421 let mask = self.intrinsics.i32_ty.const_int(31u64, false);
4422 let v2 = err!(self.builder.build_and(v2, mask, ""));
4423 let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4424 let rhs = {
4425 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4426 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4427 err!(self.builder.build_left_shift(v1, rhs, ""))
4428 };
4429 let res = err!(self.builder.build_or(lhs, rhs, ""));
4430 self.state.push1(res);
4431 }
4432 Operator::I64Rotr => {
4433 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4434 let v1 = self.apply_pending_canonicalization(v1, i1)?;
4435 let v2 = self.apply_pending_canonicalization(v2, i2)?;
4436 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
4437 let mask = self.intrinsics.i64_ty.const_int(63u64, false);
4438 let v2 = err!(self.builder.build_and(v2, mask, ""));
4439 let lhs = err!(self.builder.build_right_shift(v1, v2, false, ""));
4440 let rhs = {
4441 let negv2 = err!(self.builder.build_int_neg(v2, ""));
4442 let rhs = err!(self.builder.build_and(negv2, mask, ""));
4443 err!(self.builder.build_left_shift(v1, rhs, ""))
4444 };
4445 let res = err!(self.builder.build_or(lhs, rhs, ""));
4446 self.state.push1(res);
4447 }
4448 Operator::I32Clz => {
4449 let (input, info) = self.state.pop1_extra()?;
4450 let input = self.apply_pending_canonicalization(input, info)?;
4451 let is_zero_undef = self.intrinsics.i1_zero;
4452 let res = err!(self.builder.build_call(
4453 self.intrinsics.ctlz_i32,
4454 &[input.into(), is_zero_undef.into()],
4455 "",
4456 ))
4457 .try_as_basic_value()
4458 .unwrap_basic();
4459 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4460 }
4461 Operator::I64Clz => {
4462 let (input, info) = self.state.pop1_extra()?;
4463 let input = self.apply_pending_canonicalization(input, info)?;
4464 let is_zero_undef = self.intrinsics.i1_zero;
4465 let res = err!(self.builder.build_call(
4466 self.intrinsics.ctlz_i64,
4467 &[input.into(), is_zero_undef.into()],
4468 "",
4469 ))
4470 .try_as_basic_value()
4471 .unwrap_basic();
4472 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4473 }
4474 Operator::I32Ctz => {
4475 let (input, info) = self.state.pop1_extra()?;
4476 let input = self.apply_pending_canonicalization(input, info)?;
4477 let is_zero_undef = self.intrinsics.i1_zero;
4478 let res = err!(self.builder.build_call(
4479 self.intrinsics.cttz_i32,
4480 &[input.into(), is_zero_undef.into()],
4481 "",
4482 ))
4483 .try_as_basic_value()
4484 .unwrap_basic();
4485 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4486 }
4487 Operator::I64Ctz => {
4488 let (input, info) = self.state.pop1_extra()?;
4489 let input = self.apply_pending_canonicalization(input, info)?;
4490 let is_zero_undef = self.intrinsics.i1_zero;
4491 let res = err!(self.builder.build_call(
4492 self.intrinsics.cttz_i64,
4493 &[input.into(), is_zero_undef.into()],
4494 "",
4495 ))
4496 .try_as_basic_value()
4497 .unwrap_basic();
4498 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4499 }
4500 Operator::I8x16Popcnt => {
4501 let (v, i) = self.state.pop1_extra()?;
4502 let (v, _) = self.v128_into_i8x16(v, i)?;
4503 let res = err!(self.builder.build_call(
4504 self.intrinsics.ctpop_i8x16,
4505 &[v.into()],
4506 ""
4507 ))
4508 .try_as_basic_value()
4509 .unwrap_basic();
4510 let res = err!(
4511 self.builder
4512 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4513 );
4514 self.state.push1(res);
4515 }
4516 Operator::I32Popcnt => {
4517 let (input, info) = self.state.pop1_extra()?;
4518 let input = self.apply_pending_canonicalization(input, info)?;
4519 let res = err!(self.builder.build_call(
4520 self.intrinsics.ctpop_i32,
4521 &[input.into()],
4522 ""
4523 ))
4524 .try_as_basic_value()
4525 .unwrap_basic();
4526 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4527 }
4528 Operator::I64Popcnt => {
4529 let (input, info) = self.state.pop1_extra()?;
4530 let input = self.apply_pending_canonicalization(input, info)?;
4531 let res = err!(self.builder.build_call(
4532 self.intrinsics.ctpop_i64,
4533 &[input.into()],
4534 ""
4535 ))
4536 .try_as_basic_value()
4537 .unwrap_basic();
4538 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4539 }
4540 Operator::I32Eqz => {
4541 let input = self.state.pop1()?.into_int_value();
4542 let cond = err!(self.builder.build_int_compare(
4543 IntPredicate::EQ,
4544 input,
4545 self.intrinsics.i32_zero,
4546 "",
4547 ));
4548 let res = err!(
4549 self.builder
4550 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4551 );
4552 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
4553 }
4554 Operator::I64Eqz => {
4555 let input = self.state.pop1()?.into_int_value();
4556 let cond = err!(self.builder.build_int_compare(
4557 IntPredicate::EQ,
4558 input,
4559 self.intrinsics.i64_zero,
4560 "",
4561 ));
4562 let res = err!(
4563 self.builder
4564 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
4565 );
4566 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
4567 }
4568 Operator::I8x16Abs => {
4569 let (v, i) = self.state.pop1_extra()?;
4570 let (v, _) = self.v128_into_i8x16(v, i)?;
4571
4572 let seven = self.intrinsics.i8_ty.const_int(7, false);
4573 let seven = VectorType::const_vector(&[seven; 16]);
4574 let all_sign_bits = err!(self.builder.build_right_shift(v, seven, true, ""));
4575 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4576 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4577 let res = err!(
4578 self.builder
4579 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4580 );
4581 self.state.push1(res);
4582 }
4583 Operator::I16x8Abs => {
4584 let (v, i) = self.state.pop1_extra()?;
4585 let (v, _) = self.v128_into_i16x8(v, i)?;
4586
4587 let fifteen = self.intrinsics.i16_ty.const_int(15, false);
4588 let fifteen = VectorType::const_vector(&[fifteen; 8]);
4589 let all_sign_bits = err!(self.builder.build_right_shift(v, fifteen, true, ""));
4590 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4591 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4592 let res = err!(
4593 self.builder
4594 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4595 );
4596 self.state.push1(res);
4597 }
4598 Operator::I32x4Abs => {
4599 let (v, i) = self.state.pop1_extra()?;
4600 let (v, _) = self.v128_into_i32x4(v, i)?;
4601
4602 let thirtyone = self.intrinsics.i32_ty.const_int(31, false);
4603 let thirtyone = VectorType::const_vector(&[thirtyone; 4]);
4604 let all_sign_bits = err!(self.builder.build_right_shift(v, thirtyone, true, ""));
4605 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4606 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4607 let res = err!(
4608 self.builder
4609 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4610 );
4611 self.state.push1(res);
4612 }
4613 Operator::I64x2Abs => {
4614 let (v, i) = self.state.pop1_extra()?;
4615 let (v, _) = self.v128_into_i64x2(v, i)?;
4616
4617 let sixtythree = self.intrinsics.i64_ty.const_int(63, false);
4618 let sixtythree = VectorType::const_vector(&[sixtythree; 2]);
4619 let all_sign_bits = err!(self.builder.build_right_shift(v, sixtythree, true, ""));
4620 let xor = err!(self.builder.build_xor(v, all_sign_bits, ""));
4621 let res = err!(self.builder.build_int_sub(xor, all_sign_bits, ""));
4622 let res = err!(
4623 self.builder
4624 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4625 );
4626 self.state.push1(res);
4627 }
4628 Operator::I8x16MinS => {
4629 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4630 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4631 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4632 let cmp = err!(
4633 self.builder
4634 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4635 );
4636 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4637 let res = err!(
4638 self.builder
4639 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4640 );
4641 self.state.push1(res);
4642 }
4643 Operator::I8x16MinU => {
4644 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4645 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4646 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4647 let cmp = err!(
4648 self.builder
4649 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4650 );
4651 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4652 let res = err!(
4653 self.builder
4654 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4655 );
4656 self.state.push1(res);
4657 }
4658 Operator::I8x16MaxS => {
4659 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4660 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4661 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4662 let cmp = err!(
4663 self.builder
4664 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4665 );
4666 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4667 let res = err!(
4668 self.builder
4669 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4670 );
4671 self.state.push1(res);
4672 }
4673 Operator::I8x16MaxU => {
4674 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4675 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4676 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4677 let cmp = err!(
4678 self.builder
4679 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4680 );
4681 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4682 let res = err!(
4683 self.builder
4684 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4685 );
4686 self.state.push1(res);
4687 }
4688 Operator::I16x8MinS => {
4689 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4690 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4691 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4692 let cmp = err!(
4693 self.builder
4694 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4695 );
4696 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4697 let res = err!(
4698 self.builder
4699 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4700 );
4701 self.state.push1(res);
4702 }
4703 Operator::I16x8MinU => {
4704 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4705 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4706 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4707 let cmp = err!(
4708 self.builder
4709 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4710 );
4711 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4712 let res = err!(
4713 self.builder
4714 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4715 );
4716 self.state.push1(res);
4717 }
4718 Operator::I16x8MaxS => {
4719 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4720 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4721 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4722 let cmp = err!(
4723 self.builder
4724 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4725 );
4726 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4727 let res = err!(
4728 self.builder
4729 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4730 );
4731 self.state.push1(res);
4732 }
4733 Operator::I16x8MaxU => {
4734 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4735 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4736 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4737 let cmp = err!(
4738 self.builder
4739 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4740 );
4741 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4742 let res = err!(
4743 self.builder
4744 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4745 );
4746 self.state.push1(res);
4747 }
4748 Operator::I32x4MinS => {
4749 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4750 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4751 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4752 let cmp = err!(
4753 self.builder
4754 .build_int_compare(IntPredicate::SLT, v1, v2, "")
4755 );
4756 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4757 let res = err!(
4758 self.builder
4759 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4760 );
4761 self.state.push1(res);
4762 }
4763 Operator::I32x4MinU => {
4764 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4765 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4766 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4767 let cmp = err!(
4768 self.builder
4769 .build_int_compare(IntPredicate::ULT, v1, v2, "")
4770 );
4771 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4772 let res = err!(
4773 self.builder
4774 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4775 );
4776 self.state.push1(res);
4777 }
4778 Operator::I32x4MaxS => {
4779 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4780 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4781 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4782 let cmp = err!(
4783 self.builder
4784 .build_int_compare(IntPredicate::SGT, v1, v2, "")
4785 );
4786 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4787 let res = err!(
4788 self.builder
4789 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4790 );
4791 self.state.push1(res);
4792 }
4793 Operator::I32x4MaxU => {
4794 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4795 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
4796 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
4797 let cmp = err!(
4798 self.builder
4799 .build_int_compare(IntPredicate::UGT, v1, v2, "")
4800 );
4801 let res = err!(self.builder.build_select(cmp, v1, v2, ""));
4802 let res = err!(
4803 self.builder
4804 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4805 );
4806 self.state.push1(res);
4807 }
4808 Operator::I8x16AvgrU => {
4809 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4810 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
4811 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
4812
4813 let ext_ty = self.intrinsics.i16_ty.vec_type(16);
4824 let one = self.intrinsics.i16_ty.const_int(1, false);
4825 let one = VectorType::const_vector(&[one; 16]);
4826
4827 let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4828 let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4829 let res = err!(self.builder.build_int_add(
4830 err!(self.builder.build_int_add(one, v1, "")),
4831 v2,
4832 ""
4833 ));
4834 let res = err!(self.builder.build_right_shift(res, one, false, ""));
4835 let res = err!(
4836 self.builder
4837 .build_int_truncate(res, self.intrinsics.i8x16_ty, "")
4838 );
4839 let res = err!(
4840 self.builder
4841 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4842 );
4843 self.state.push1(res);
4844 }
4845 Operator::I16x8AvgrU => {
4846 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4847 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
4848 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
4849
4850 let ext_ty = self.intrinsics.i32_ty.vec_type(8);
4861 let one = self.intrinsics.i32_consts[1];
4862 let one = VectorType::const_vector(&[one; 8]);
4863
4864 let v1 = err!(self.builder.build_int_z_extend(v1, ext_ty, ""));
4865 let v2 = err!(self.builder.build_int_z_extend(v2, ext_ty, ""));
4866 let res = err!(self.builder.build_int_add(
4867 err!(self.builder.build_int_add(one, v1, "")),
4868 v2,
4869 ""
4870 ));
4871 let res = err!(self.builder.build_right_shift(res, one, false, ""));
4872 let res = err!(
4873 self.builder
4874 .build_int_truncate(res, self.intrinsics.i16x8_ty, "")
4875 );
4876 let res = err!(
4877 self.builder
4878 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4879 );
4880 self.state.push1(res);
4881 }
4882
4883 Operator::F32Add => {
4888 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4889 let res = err!(self.builder.build_call(
4890 self.intrinsics.add_f32,
4891 &[
4892 v1.into(),
4893 v2.into(),
4894 self.intrinsics.fp_rounding_md,
4895 self.intrinsics.fp_exception_md,
4896 ],
4897 "",
4898 ))
4899 .try_as_basic_value()
4900 .unwrap_basic();
4901 self.state.push1_extra(
4902 res,
4903 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4904 );
4905 }
4906 Operator::F64Add => {
4907 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4908 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4909 let res = err!(self.builder.build_call(
4910 self.intrinsics.add_f64,
4911 &[
4912 v1.into(),
4913 v2.into(),
4914 self.intrinsics.fp_rounding_md,
4915 self.intrinsics.fp_exception_md,
4916 ],
4917 "",
4918 ))
4919 .try_as_basic_value()
4920 .unwrap_basic();
4921 self.state.push1_extra(
4922 res,
4923 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4924 );
4925 }
4926 Operator::F32x4Add => {
4927 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4928 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
4929 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
4930 let res = err!(self.builder.build_call(
4931 self.intrinsics.add_f32x4,
4932 &[
4933 v1.into(),
4934 v2.into(),
4935 self.intrinsics.fp_rounding_md,
4936 self.intrinsics.fp_exception_md,
4937 ],
4938 "",
4939 ))
4940 .try_as_basic_value()
4941 .unwrap_basic();
4942 let res = err!(
4943 self.builder
4944 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4945 );
4946 self.state.push1_extra(
4947 res,
4948 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4949 );
4950 }
4951 Operator::F64x2Add => {
4952 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4953 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
4954 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
4955 let res = err!(self.builder.build_call(
4956 self.intrinsics.add_f64x2,
4957 &[
4958 v1.into(),
4959 v2.into(),
4960 self.intrinsics.fp_rounding_md,
4961 self.intrinsics.fp_exception_md,
4962 ],
4963 "",
4964 ))
4965 .try_as_basic_value()
4966 .unwrap_basic();
4967 let res = err!(
4968 self.builder
4969 .build_bit_cast(res, self.intrinsics.i128_ty, "")
4970 );
4971 self.state.push1_extra(
4972 res,
4973 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
4974 );
4975 }
4976 Operator::F32Sub => {
4977 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4978 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4979 let res = err!(self.builder.build_call(
4980 self.intrinsics.sub_f32,
4981 &[
4982 v1.into(),
4983 v2.into(),
4984 self.intrinsics.fp_rounding_md,
4985 self.intrinsics.fp_exception_md,
4986 ],
4987 "",
4988 ))
4989 .try_as_basic_value()
4990 .unwrap_basic();
4991 self.state.push1_extra(
4992 res,
4993 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
4994 );
4995 }
4996 Operator::F64Sub => {
4997 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
4998 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
4999 let res = err!(self.builder.build_call(
5000 self.intrinsics.sub_f64,
5001 &[
5002 v1.into(),
5003 v2.into(),
5004 self.intrinsics.fp_rounding_md,
5005 self.intrinsics.fp_exception_md,
5006 ],
5007 "",
5008 ))
5009 .try_as_basic_value()
5010 .unwrap_basic();
5011 self.state.push1_extra(
5012 res,
5013 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5014 );
5015 }
5016 Operator::F32x4Sub => {
5017 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5018 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5019 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5020 let res = err!(self.builder.build_call(
5021 self.intrinsics.sub_f32x4,
5022 &[
5023 v1.into(),
5024 v2.into(),
5025 self.intrinsics.fp_rounding_md,
5026 self.intrinsics.fp_exception_md,
5027 ],
5028 "",
5029 ))
5030 .try_as_basic_value()
5031 .unwrap_basic();
5032 let res = err!(
5033 self.builder
5034 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5035 );
5036 self.state.push1_extra(
5037 res,
5038 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5039 );
5040 }
5041 Operator::F64x2Sub => {
5042 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5043 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5044 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5045 let res = err!(self.builder.build_call(
5046 self.intrinsics.sub_f64x2,
5047 &[
5048 v1.into(),
5049 v2.into(),
5050 self.intrinsics.fp_rounding_md,
5051 self.intrinsics.fp_exception_md,
5052 ],
5053 "",
5054 ))
5055 .try_as_basic_value()
5056 .unwrap_basic();
5057 let res = err!(
5058 self.builder
5059 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5060 );
5061 self.state.push1_extra(
5062 res,
5063 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5064 );
5065 }
5066 Operator::F32Mul => {
5067 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5068 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5069 let res = err!(self.builder.build_call(
5070 self.intrinsics.mul_f32,
5071 &[
5072 v1.into(),
5073 v2.into(),
5074 self.intrinsics.fp_rounding_md,
5075 self.intrinsics.fp_exception_md,
5076 ],
5077 "",
5078 ))
5079 .try_as_basic_value()
5080 .unwrap_basic();
5081 self.state.push1_extra(
5082 res,
5083 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5084 );
5085 }
5086 Operator::F64Mul => {
5087 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5088 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5089 let res = err!(self.builder.build_call(
5090 self.intrinsics.mul_f64,
5091 &[
5092 v1.into(),
5093 v2.into(),
5094 self.intrinsics.fp_rounding_md,
5095 self.intrinsics.fp_exception_md,
5096 ],
5097 "",
5098 ))
5099 .try_as_basic_value()
5100 .unwrap_basic();
5101 self.state.push1_extra(
5102 res,
5103 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5104 );
5105 }
5106 Operator::F32x4Mul => {
5107 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5108 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5109 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5110 let res = err!(self.builder.build_call(
5111 self.intrinsics.mul_f32x4,
5112 &[
5113 v1.into(),
5114 v2.into(),
5115 self.intrinsics.fp_rounding_md,
5116 self.intrinsics.fp_exception_md,
5117 ],
5118 "",
5119 ))
5120 .try_as_basic_value()
5121 .unwrap_basic();
5122 let res = err!(
5123 self.builder
5124 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5125 );
5126 self.state.push1_extra(
5127 res,
5128 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5129 );
5130 }
5131 Operator::F64x2Mul => {
5132 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5133 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5134 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5135 let res = err!(self.builder.build_call(
5136 self.intrinsics.mul_f64x2,
5137 &[
5138 v1.into(),
5139 v2.into(),
5140 self.intrinsics.fp_rounding_md,
5141 self.intrinsics.fp_exception_md,
5142 ],
5143 "",
5144 ))
5145 .try_as_basic_value()
5146 .unwrap_basic();
5147 let res = err!(
5148 self.builder
5149 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5150 );
5151 self.state.push1_extra(
5152 res,
5153 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5154 );
5155 }
5156 Operator::F32Div => {
5157 let (v1, v2) = self.state.pop2()?;
5158 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5159 let res = err!(self.builder.build_call(
5160 self.intrinsics.div_f32,
5161 &[
5162 v1.into(),
5163 v2.into(),
5164 self.intrinsics.fp_rounding_md,
5165 self.intrinsics.fp_exception_md,
5166 ],
5167 "",
5168 ))
5169 .try_as_basic_value()
5170 .unwrap_basic();
5171 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5172 }
5173 Operator::F64Div => {
5174 let (v1, v2) = self.state.pop2()?;
5175 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
5176 let res = err!(self.builder.build_call(
5177 self.intrinsics.div_f64,
5178 &[
5179 v1.into(),
5180 v2.into(),
5181 self.intrinsics.fp_rounding_md,
5182 self.intrinsics.fp_exception_md,
5183 ],
5184 "",
5185 ))
5186 .try_as_basic_value()
5187 .unwrap_basic();
5188 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5189 }
5190 Operator::F32x4Div => {
5191 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5192 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
5193 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
5194 let res = err!(self.builder.build_call(
5195 self.intrinsics.div_f32x4,
5196 &[
5197 v1.into(),
5198 v2.into(),
5199 self.intrinsics.fp_rounding_md,
5200 self.intrinsics.fp_exception_md,
5201 ],
5202 "",
5203 ))
5204 .try_as_basic_value()
5205 .unwrap_basic();
5206 let res = err!(
5207 self.builder
5208 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5209 );
5210 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5211 }
5212 Operator::F64x2Div => {
5213 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5214 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
5215 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
5216 let res = err!(self.builder.build_call(
5217 self.intrinsics.div_f64x2,
5218 &[
5219 v1.into(),
5220 v2.into(),
5221 self.intrinsics.fp_rounding_md,
5222 self.intrinsics.fp_exception_md,
5223 ],
5224 "",
5225 ))
5226 .try_as_basic_value()
5227 .unwrap_basic();
5228 let res = err!(
5229 self.builder
5230 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5231 );
5232 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5233 }
5234 Operator::F32Sqrt => {
5235 let input = self.state.pop1()?;
5236 let res = err!(self.builder.build_call(
5237 self.intrinsics.sqrt_f32,
5238 &[input.into()],
5239 ""
5240 ))
5241 .try_as_basic_value()
5242 .unwrap_basic();
5243 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5244 }
5245 Operator::F64Sqrt => {
5246 let input = self.state.pop1()?;
5247 let res = err!(self.builder.build_call(
5248 self.intrinsics.sqrt_f64,
5249 &[input.into()],
5250 ""
5251 ))
5252 .try_as_basic_value()
5253 .unwrap_basic();
5254 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5255 }
5256 Operator::F32x4Sqrt => {
5257 let (v, i) = self.state.pop1_extra()?;
5258 let (v, _) = self.v128_into_f32x4(v, i)?;
5259 let res = err!(self.builder.build_call(
5260 self.intrinsics.sqrt_f32x4,
5261 &[v.into()],
5262 ""
5263 ))
5264 .try_as_basic_value()
5265 .unwrap_basic();
5266 let bits = err!(
5267 self.builder
5268 .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5269 );
5270 self.state.push1_extra(bits, ExtraInfo::pending_f32_nan());
5271 }
5272 Operator::F64x2Sqrt => {
5273 let (v, i) = self.state.pop1_extra()?;
5274 let (v, _) = self.v128_into_f64x2(v, i)?;
5275 let res = err!(self.builder.build_call(
5276 self.intrinsics.sqrt_f64x2,
5277 &[v.into()],
5278 ""
5279 ))
5280 .try_as_basic_value()
5281 .unwrap_basic();
5282 let bits = err!(
5283 self.builder
5284 .build_bit_cast(res, self.intrinsics.i128_ty, "bits")
5285 );
5286 self.state.push1(bits);
5287 }
5288 Operator::F32Min => {
5289 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5290 let lhs = self
5291 .apply_pending_canonicalization(lhs, lhs_info)?
5292 .into_float_value();
5293 let rhs = self
5294 .apply_pending_canonicalization(rhs, rhs_info)?
5295 .into_float_value();
5296
5297 let res = err!(self.builder.build_call(
5298 self.intrinsics.minimum_f32,
5299 &[lhs.into(), rhs.into()],
5300 "",
5301 ))
5302 .try_as_basic_value()
5303 .unwrap_basic();
5304
5305 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5306 let res = res.into_float_value();
5307
5308 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5309 }
5310 Operator::F64Min => {
5311 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5312 let lhs = self
5313 .apply_pending_canonicalization(lhs, lhs_info)?
5314 .into_float_value();
5315 let rhs = self
5316 .apply_pending_canonicalization(rhs, rhs_info)?
5317 .into_float_value();
5318
5319 let res = err!(self.builder.build_call(
5320 self.intrinsics.minimum_f64,
5321 &[lhs.into(), rhs.into()],
5322 "",
5323 ))
5324 .try_as_basic_value()
5325 .unwrap_basic();
5326
5327 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5328 let res = res.into_float_value();
5329
5330 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5331 }
5332 Operator::F32x4Min => {
5333 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5334 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5335 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5336 let res = err!(self.builder.build_call(
5337 self.intrinsics.minimum_f32x4,
5338 &[v1.into(), v2.into()],
5339 "",
5340 ))
5341 .try_as_basic_value()
5342 .unwrap_basic();
5343
5344 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5345 let res = res.into_vector_value();
5346
5347 let res = err!(
5348 self.builder
5349 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5350 );
5351 self.state.push1_extra(
5352 res,
5353 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5354 );
5355 }
5356 Operator::F32x4PMin => {
5357 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5359 let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5360 let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5361 let cmp = err!(
5362 self.builder
5363 .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5364 );
5365 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5366 let res = err!(
5367 self.builder
5368 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5369 );
5370 self.state.push1(res);
5371 }
5372 Operator::F64x2Min => {
5373 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5374 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5375 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5376 let res = err!(self.builder.build_call(
5377 self.intrinsics.minimum_f64x2,
5378 &[v1.into(), v2.into()],
5379 "",
5380 ))
5381 .try_as_basic_value()
5382 .unwrap_basic();
5383
5384 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5385 let res = res.into_vector_value();
5386
5387 let res = err!(
5388 self.builder
5389 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5390 );
5391 self.state.push1_extra(
5392 res,
5393 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5394 );
5395 }
5396 Operator::F64x2PMin => {
5397 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5399 let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5400 let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5401 let cmp = err!(
5402 self.builder
5403 .build_float_compare(FloatPredicate::OLT, v2, v1, "")
5404 );
5405 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5406 let res = err!(
5407 self.builder
5408 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5409 );
5410 self.state.push1(res);
5411 }
5412 Operator::F32Max => {
5413 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5414 let lhs = self
5415 .apply_pending_canonicalization(lhs, lhs_info)?
5416 .into_float_value();
5417 let rhs = self
5418 .apply_pending_canonicalization(rhs, rhs_info)?
5419 .into_float_value();
5420
5421 let res = err!(self.builder.build_call(
5422 self.intrinsics.maximum_f32,
5423 &[lhs.into(), rhs.into()],
5424 "",
5425 ))
5426 .try_as_basic_value()
5427 .unwrap_basic();
5428
5429 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5430 let res = res.into_float_value();
5431
5432 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
5433 }
5434 Operator::F64Max => {
5435 let ((lhs, lhs_info), (rhs, rhs_info)) = self.state.pop2_extra()?;
5436 let lhs = self
5437 .apply_pending_canonicalization(lhs, lhs_info)?
5438 .into_float_value();
5439 let rhs = self
5440 .apply_pending_canonicalization(rhs, rhs_info)?
5441 .into_float_value();
5442
5443 let res = err!(self.builder.build_call(
5444 self.intrinsics.maximum_f64,
5445 &[lhs.into(), rhs.into()],
5446 "",
5447 ))
5448 .try_as_basic_value()
5449 .unwrap_basic();
5450
5451 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5452 let res = res.into_float_value();
5453
5454 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
5455 }
5456 Operator::F32x4Max => {
5457 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5458 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
5459 let (v2, i2) = self.v128_into_f32x4(v2, i2)?;
5460 let res = err!(self.builder.build_call(
5461 self.intrinsics.maximum_f32x4,
5462 &[v1.into(), v2.into()],
5463 "",
5464 ))
5465 .try_as_basic_value()
5466 .unwrap_basic();
5467
5468 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5469 let res = res.into_vector_value();
5470
5471 let res = err!(
5472 self.builder
5473 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5474 );
5475 self.state.push1_extra(
5476 res,
5477 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f32_nan())?,
5478 );
5479 }
5480 Operator::F32x4PMax => {
5481 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5483 let (v1, _i1) = self.v128_into_f32x4(v1, i1)?;
5484 let (v2, _i2) = self.v128_into_f32x4(v2, i2)?;
5485 let cmp = err!(
5486 self.builder
5487 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5488 );
5489 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5490
5491 let res = err!(
5492 self.builder
5493 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5494 );
5495 self.state.push1(res);
5496 }
5497 Operator::F64x2Max => {
5498 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5499 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
5500 let (v2, i2) = self.v128_into_f64x2(v2, i2)?;
5501 let res = err!(self.builder.build_call(
5502 self.intrinsics.maximum_f64x2,
5503 &[v1.into(), v2.into()],
5504 "",
5505 ))
5506 .try_as_basic_value()
5507 .unwrap_basic();
5508
5509 let res = self.finalize_minmax_result(res.as_basic_value_enum())?;
5510 let res = res.into_vector_value();
5511
5512 let res = err!(
5513 self.builder
5514 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5515 );
5516 self.state.push1_extra(
5517 res,
5518 ((i1.strip_pending() & i2.strip_pending())? | ExtraInfo::pending_f64_nan())?,
5519 );
5520 }
5521 Operator::F64x2PMax => {
5522 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5524 let (v1, _i1) = self.v128_into_f64x2(v1, i1)?;
5525 let (v2, _i2) = self.v128_into_f64x2(v2, i2)?;
5526 let cmp = err!(
5527 self.builder
5528 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
5529 );
5530 let res = err!(self.builder.build_select(cmp, v2, v1, ""));
5531 let res = err!(
5532 self.builder
5533 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5534 );
5535 self.state.push1(res);
5536 }
5537 Operator::F32Ceil => {
5538 let (input, info) = self.state.pop1_extra()?;
5539 let res = err!(self.builder.build_call(
5540 self.intrinsics.ceil_f32,
5541 &[input.into()],
5542 ""
5543 ))
5544 .try_as_basic_value()
5545 .unwrap_basic();
5546 self.state
5547 .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5548 }
5549 Operator::F32x4Ceil => {
5550 let (v, i) = self.state.pop1_extra()?;
5551 let (v, _) = self.v128_into_f32x4(v, i)?;
5552 let res = err!(self.builder.build_call(
5553 self.intrinsics.ceil_f32x4,
5554 &[v.into()],
5555 ""
5556 ))
5557 .try_as_basic_value()
5558 .unwrap_basic();
5559 let res = err!(
5560 self.builder
5561 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5562 );
5563 self.state
5564 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5565 }
5566 Operator::F64Ceil => {
5567 let (input, info) = self.state.pop1_extra()?;
5568 let res = err!(self.builder.build_call(
5569 self.intrinsics.ceil_f64,
5570 &[input.into()],
5571 ""
5572 ))
5573 .try_as_basic_value()
5574 .unwrap_basic();
5575 self.state
5576 .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5577 }
5578 Operator::F64x2Ceil => {
5579 let (v, i) = self.state.pop1_extra()?;
5580 let (v, _) = self.v128_into_f64x2(v, i)?;
5581 let res = err!(self.builder.build_call(
5582 self.intrinsics.ceil_f64x2,
5583 &[v.into()],
5584 ""
5585 ))
5586 .try_as_basic_value()
5587 .unwrap_basic();
5588 let res = err!(
5589 self.builder
5590 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5591 );
5592 self.state
5593 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5594 }
5595 Operator::F32Floor => {
5596 let (input, info) = self.state.pop1_extra()?;
5597 let res = err!(self.builder.build_call(
5598 self.intrinsics.floor_f32,
5599 &[input.into()],
5600 ""
5601 ))
5602 .try_as_basic_value()
5603 .unwrap_basic();
5604 self.state
5605 .push1_extra(res, (info | ExtraInfo::pending_f32_nan())?);
5606 }
5607 Operator::F32x4Floor => {
5608 let (v, i) = self.state.pop1_extra()?;
5609 let (v, _) = self.v128_into_f32x4(v, i)?;
5610 let res = err!(self.builder.build_call(
5611 self.intrinsics.floor_f32x4,
5612 &[v.into()],
5613 ""
5614 ))
5615 .try_as_basic_value()
5616 .unwrap_basic();
5617 let res = err!(
5618 self.builder
5619 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5620 );
5621 self.state
5622 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5623 }
5624 Operator::F64Floor => {
5625 let (input, info) = self.state.pop1_extra()?;
5626 let res = err!(self.builder.build_call(
5627 self.intrinsics.floor_f64,
5628 &[input.into()],
5629 ""
5630 ))
5631 .try_as_basic_value()
5632 .unwrap_basic();
5633 self.state
5634 .push1_extra(res, (info | ExtraInfo::pending_f64_nan())?);
5635 }
5636 Operator::F64x2Floor => {
5637 let (v, i) = self.state.pop1_extra()?;
5638 let (v, _) = self.v128_into_f64x2(v, i)?;
5639 let res = err!(self.builder.build_call(
5640 self.intrinsics.floor_f64x2,
5641 &[v.into()],
5642 ""
5643 ))
5644 .try_as_basic_value()
5645 .unwrap_basic();
5646 let res = err!(
5647 self.builder
5648 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5649 );
5650 self.state
5651 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5652 }
5653 Operator::F32Trunc => {
5654 let (v, i) = self.state.pop1_extra()?;
5655 let res = err!(
5656 self.builder
5657 .build_call(self.intrinsics.trunc_f32, &[v.into()], "")
5658 )
5659 .try_as_basic_value()
5660 .unwrap_basic();
5661 self.state
5662 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5663 }
5664 Operator::F32x4Trunc => {
5665 let (v, i) = self.state.pop1_extra()?;
5666 let (v, _) = self.v128_into_f32x4(v, i)?;
5667 let res = err!(self.builder.build_call(
5668 self.intrinsics.trunc_f32x4,
5669 &[v.into()],
5670 ""
5671 ))
5672 .try_as_basic_value()
5673 .unwrap_basic();
5674 let res = err!(
5675 self.builder
5676 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5677 );
5678 self.state
5679 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5680 }
5681 Operator::F64Trunc => {
5682 let (v, i) = self.state.pop1_extra()?;
5683 let res = err!(
5684 self.builder
5685 .build_call(self.intrinsics.trunc_f64, &[v.into()], "")
5686 )
5687 .try_as_basic_value()
5688 .unwrap_basic();
5689 self.state
5690 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5691 }
5692 Operator::F64x2Trunc => {
5693 let (v, i) = self.state.pop1_extra()?;
5694 let (v, _) = self.v128_into_f64x2(v, i)?;
5695 let res = err!(self.builder.build_call(
5696 self.intrinsics.trunc_f64x2,
5697 &[v.into()],
5698 ""
5699 ))
5700 .try_as_basic_value()
5701 .unwrap_basic();
5702 let res = err!(
5703 self.builder
5704 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5705 );
5706 self.state
5707 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5708 }
5709 Operator::F32Nearest => {
5710 let (v, i) = self.state.pop1_extra()?;
5711 let res = err!(self.builder.build_call(
5712 self.intrinsics.nearbyint_f32,
5713 &[v.into()],
5714 ""
5715 ))
5716 .try_as_basic_value()
5717 .unwrap_basic();
5718 self.state
5719 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5720 }
5721 Operator::F32x4Nearest => {
5722 let (v, i) = self.state.pop1_extra()?;
5723 let (v, _) = self.v128_into_f32x4(v, i)?;
5724 let res = err!(self.builder.build_call(
5725 self.intrinsics.nearbyint_f32x4,
5726 &[v.into()],
5727 ""
5728 ))
5729 .try_as_basic_value()
5730 .unwrap_basic();
5731 let res = err!(
5732 self.builder
5733 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5734 );
5735 self.state
5736 .push1_extra(res, (i | ExtraInfo::pending_f32_nan())?);
5737 }
5738 Operator::F64Nearest => {
5739 let (v, i) = self.state.pop1_extra()?;
5740 let res = err!(self.builder.build_call(
5741 self.intrinsics.nearbyint_f64,
5742 &[v.into()],
5743 ""
5744 ))
5745 .try_as_basic_value()
5746 .unwrap_basic();
5747 self.state
5748 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5749 }
5750 Operator::F64x2Nearest => {
5751 let (v, i) = self.state.pop1_extra()?;
5752 let (v, _) = self.v128_into_f64x2(v, i)?;
5753 let res = err!(self.builder.build_call(
5754 self.intrinsics.nearbyint_f64x2,
5755 &[v.into()],
5756 ""
5757 ))
5758 .try_as_basic_value()
5759 .unwrap_basic();
5760 let res = err!(
5761 self.builder
5762 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5763 );
5764 self.state
5765 .push1_extra(res, (i | ExtraInfo::pending_f64_nan())?);
5766 }
5767 Operator::F32Abs => {
5768 let (v, i) = self.state.pop1_extra()?;
5769 let v = self.apply_pending_canonicalization(v, i)?;
5770 let res = err!(
5771 self.builder
5772 .build_call(self.intrinsics.fabs_f32, &[v.into()], "")
5773 )
5774 .try_as_basic_value()
5775 .unwrap_basic();
5776 self.state.push1_extra(res, i.strip_pending());
5779 }
5780 Operator::F64Abs => {
5781 let (v, i) = self.state.pop1_extra()?;
5782 let v = self.apply_pending_canonicalization(v, i)?;
5783 let res = err!(
5784 self.builder
5785 .build_call(self.intrinsics.fabs_f64, &[v.into()], "")
5786 )
5787 .try_as_basic_value()
5788 .unwrap_basic();
5789 self.state.push1_extra(res, i.strip_pending());
5792 }
5793 Operator::F32x4Abs => {
5794 let (v, i) = self.state.pop1_extra()?;
5795 let v = err!(self.builder.build_bit_cast(
5796 v.into_int_value(),
5797 self.intrinsics.f32x4_ty,
5798 ""
5799 ));
5800 let v = self.apply_pending_canonicalization(v, i)?;
5801 let res = err!(self.builder.build_call(
5802 self.intrinsics.fabs_f32x4,
5803 &[v.into()],
5804 ""
5805 ))
5806 .try_as_basic_value()
5807 .unwrap_basic();
5808 let res = err!(
5809 self.builder
5810 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5811 );
5812 self.state.push1_extra(res, i.strip_pending());
5815 }
5816 Operator::F64x2Abs => {
5817 let (v, i) = self.state.pop1_extra()?;
5818 let v = err!(self.builder.build_bit_cast(
5819 v.into_int_value(),
5820 self.intrinsics.f64x2_ty,
5821 ""
5822 ));
5823 let v = self.apply_pending_canonicalization(v, i)?;
5824 let res = err!(self.builder.build_call(
5825 self.intrinsics.fabs_f64x2,
5826 &[v.into()],
5827 ""
5828 ))
5829 .try_as_basic_value()
5830 .unwrap_basic();
5831 let res = err!(
5832 self.builder
5833 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5834 );
5835 self.state.push1_extra(res, i.strip_pending());
5838 }
5839 Operator::F32x4Neg => {
5840 let (v, i) = self.state.pop1_extra()?;
5841 let v = err!(self.builder.build_bit_cast(
5842 v.into_int_value(),
5843 self.intrinsics.f32x4_ty,
5844 ""
5845 ));
5846 let v = self
5847 .apply_pending_canonicalization(v, i)?
5848 .into_vector_value();
5849 let res = err!(self.builder.build_float_neg(v, ""));
5850 let res = err!(
5851 self.builder
5852 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5853 );
5854 self.state.push1_extra(res, i.strip_pending());
5857 }
5858 Operator::F64x2Neg => {
5859 let (v, i) = self.state.pop1_extra()?;
5860 let v = err!(self.builder.build_bit_cast(
5861 v.into_int_value(),
5862 self.intrinsics.f64x2_ty,
5863 ""
5864 ));
5865 let v = self
5866 .apply_pending_canonicalization(v, i)?
5867 .into_vector_value();
5868 let res = err!(self.builder.build_float_neg(v, ""));
5869 let res = err!(
5870 self.builder
5871 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5872 );
5873 self.state.push1_extra(res, i.strip_pending());
5876 }
5877 Operator::F32Neg | Operator::F64Neg => {
5878 let (v, i) = self.state.pop1_extra()?;
5879 let v = self
5880 .apply_pending_canonicalization(v, i)?
5881 .into_float_value();
5882 let res = err!(self.builder.build_float_neg(v, ""));
5883 self.state.push1_extra(res, i.strip_pending());
5886 }
5887 Operator::F32Copysign => {
5888 let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5889 let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5890 let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5891 let res = err!(self.builder.build_call(
5892 self.intrinsics.copysign_f32,
5893 &[mag.into(), sgn.into()],
5894 ""
5895 ))
5896 .try_as_basic_value()
5897 .unwrap_basic();
5898 self.state.push1_extra(res, mag_info.strip_pending());
5901 }
5902 Operator::F64Copysign => {
5903 let ((mag, mag_info), (sgn, sgn_info)) = self.state.pop2_extra()?;
5904 let mag = self.apply_pending_canonicalization(mag, mag_info)?;
5905 let sgn = self.apply_pending_canonicalization(sgn, sgn_info)?;
5906 let res = err!(self.builder.build_call(
5907 self.intrinsics.copysign_f64,
5908 &[mag.into(), sgn.into()],
5909 ""
5910 ))
5911 .try_as_basic_value()
5912 .unwrap_basic();
5913 self.state.push1_extra(res, mag_info.strip_pending());
5916 }
5917
5918 Operator::I32Eq | Operator::I64Eq => {
5923 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5924 let v1 = self.apply_pending_canonicalization(v1, i1)?;
5925 let v2 = self.apply_pending_canonicalization(v2, i2)?;
5926 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
5927 let cond = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5928 let res = err!(
5929 self.builder
5930 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
5931 );
5932 self.state.push1_extra(
5933 res,
5934 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
5935 );
5936 }
5937 Operator::I8x16Eq => {
5938 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5939 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
5940 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
5941 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5942 let res = err!(
5943 self.builder
5944 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
5945 );
5946 let res = err!(
5947 self.builder
5948 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5949 );
5950 self.state.push1(res);
5951 }
5952 Operator::I16x8Eq => {
5953 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5954 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
5955 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
5956 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5957 let res = err!(
5958 self.builder
5959 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
5960 );
5961 let res = err!(
5962 self.builder
5963 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5964 );
5965 self.state.push1(res);
5966 }
5967 Operator::I32x4Eq => {
5968 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5969 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
5970 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
5971 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5972 let res = err!(
5973 self.builder
5974 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
5975 );
5976 let res = err!(
5977 self.builder
5978 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5979 );
5980 self.state.push1(res);
5981 }
5982 Operator::I64x2Eq => {
5983 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5984 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
5985 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
5986 let res = err!(self.builder.build_int_compare(IntPredicate::EQ, v1, v2, ""));
5987 let res = err!(
5988 self.builder
5989 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
5990 );
5991 let res = err!(
5992 self.builder
5993 .build_bit_cast(res, self.intrinsics.i128_ty, "")
5994 );
5995 self.state.push1(res);
5996 }
5997 Operator::I32Ne | Operator::I64Ne => {
5998 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
5999 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6000 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6001 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6002 let cond = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6003 let res = err!(
6004 self.builder
6005 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6006 );
6007 self.state.push1_extra(
6008 res,
6009 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6010 );
6011 }
6012 Operator::I8x16Ne => {
6013 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6014 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6015 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6016 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6017 let res = err!(
6018 self.builder
6019 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6020 );
6021 let res = err!(
6022 self.builder
6023 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6024 );
6025 self.state.push1(res);
6026 }
6027 Operator::I16x8Ne => {
6028 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6029 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6030 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6031 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6032 let res = err!(
6033 self.builder
6034 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6035 );
6036 let res = err!(
6037 self.builder
6038 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6039 );
6040 self.state.push1(res);
6041 }
6042 Operator::I32x4Ne => {
6043 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6044 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6045 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6046 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6047 let res = err!(
6048 self.builder
6049 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6050 );
6051 let res = err!(
6052 self.builder
6053 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6054 );
6055 self.state.push1(res);
6056 }
6057 Operator::I64x2Ne => {
6058 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6059 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6060 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6061 let res = err!(self.builder.build_int_compare(IntPredicate::NE, v1, v2, ""));
6062 let res = err!(
6063 self.builder
6064 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6065 );
6066 let res = err!(
6067 self.builder
6068 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6069 );
6070 self.state.push1(res);
6071 }
6072 Operator::I32LtS | Operator::I64LtS => {
6073 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6074 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6075 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6076 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6077 let cond = err!(
6078 self.builder
6079 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6080 );
6081 let res = err!(
6082 self.builder
6083 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6084 );
6085 self.state.push1_extra(
6086 res,
6087 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6088 );
6089 }
6090 Operator::I8x16LtS => {
6091 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6092 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6093 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6094 let res = err!(
6095 self.builder
6096 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6097 );
6098 let res = err!(
6099 self.builder
6100 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6101 );
6102 let res = err!(
6103 self.builder
6104 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6105 );
6106 self.state.push1(res);
6107 }
6108 Operator::I16x8LtS => {
6109 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6110 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6111 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6112 let res = err!(
6113 self.builder
6114 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6115 );
6116 let res = err!(
6117 self.builder
6118 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6119 );
6120 let res = err!(
6121 self.builder
6122 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6123 );
6124 self.state.push1(res);
6125 }
6126 Operator::I32x4LtS => {
6127 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6128 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6129 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6130 let res = err!(
6131 self.builder
6132 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6133 );
6134 let res = err!(
6135 self.builder
6136 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6137 );
6138 let res = err!(
6139 self.builder
6140 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6141 );
6142 self.state.push1(res);
6143 }
6144 Operator::I64x2LtS => {
6145 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6146 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6147 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6148 let res = err!(
6149 self.builder
6150 .build_int_compare(IntPredicate::SLT, v1, v2, "")
6151 );
6152 let res = err!(
6153 self.builder
6154 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6155 );
6156 let res = err!(
6157 self.builder
6158 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6159 );
6160 self.state.push1(res);
6161 }
6162 Operator::I32LtU | Operator::I64LtU => {
6163 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6164 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6165 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6166 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6167 let cond = err!(
6168 self.builder
6169 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6170 );
6171 let res = err!(
6172 self.builder
6173 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6174 );
6175 self.state.push1(res);
6176 }
6177 Operator::I8x16LtU => {
6178 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6179 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6180 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6181 let res = err!(
6182 self.builder
6183 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6184 );
6185 let res = err!(
6186 self.builder
6187 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6188 );
6189 let res = err!(
6190 self.builder
6191 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6192 );
6193 self.state.push1(res);
6194 }
6195 Operator::I16x8LtU => {
6196 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6197 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6198 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6199 let res = err!(
6200 self.builder
6201 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6202 );
6203 let res = err!(
6204 self.builder
6205 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6206 );
6207 let res = err!(
6208 self.builder
6209 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6210 );
6211 self.state.push1(res);
6212 }
6213 Operator::I32x4LtU => {
6214 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6215 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6216 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6217 let res = err!(
6218 self.builder
6219 .build_int_compare(IntPredicate::ULT, v1, v2, "")
6220 );
6221 let res = err!(
6222 self.builder
6223 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6224 );
6225 let res = err!(
6226 self.builder
6227 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6228 );
6229 self.state.push1(res);
6230 }
6231 Operator::I32LeS | Operator::I64LeS => {
6232 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6233 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6234 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6235 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6236 let cond = err!(
6237 self.builder
6238 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6239 );
6240 let res = err!(
6241 self.builder
6242 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6243 );
6244 self.state.push1_extra(
6245 res,
6246 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6247 );
6248 }
6249 Operator::I8x16LeS => {
6250 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6251 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6252 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6253 let res = err!(
6254 self.builder
6255 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6256 );
6257 let res = err!(
6258 self.builder
6259 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6260 );
6261 let res = err!(
6262 self.builder
6263 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6264 );
6265 self.state.push1(res);
6266 }
6267 Operator::I16x8LeS => {
6268 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6269 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6270 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6271 let res = err!(
6272 self.builder
6273 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6274 );
6275 let res = err!(
6276 self.builder
6277 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6278 );
6279 let res = err!(
6280 self.builder
6281 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6282 );
6283 self.state.push1(res);
6284 }
6285 Operator::I32x4LeS => {
6286 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6287 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6288 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6289 let res = err!(
6290 self.builder
6291 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6292 );
6293 let res = err!(
6294 self.builder
6295 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6296 );
6297 let res = err!(
6298 self.builder
6299 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6300 );
6301 self.state.push1(res);
6302 }
6303 Operator::I64x2LeS => {
6304 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6305 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6306 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6307 let res = err!(
6308 self.builder
6309 .build_int_compare(IntPredicate::SLE, v1, v2, "")
6310 );
6311 let res = err!(
6312 self.builder
6313 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6314 );
6315 let res = err!(
6316 self.builder
6317 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6318 );
6319 self.state.push1(res);
6320 }
6321 Operator::I32LeU | Operator::I64LeU => {
6322 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6323 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6324 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6325 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6326 let cond = err!(
6327 self.builder
6328 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6329 );
6330 let res = err!(
6331 self.builder
6332 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6333 );
6334 self.state.push1_extra(
6335 res,
6336 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6337 );
6338 }
6339 Operator::I8x16LeU => {
6340 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6341 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6342 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6343 let res = err!(
6344 self.builder
6345 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6346 );
6347 let res = err!(
6348 self.builder
6349 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6350 );
6351 let res = err!(
6352 self.builder
6353 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6354 );
6355 self.state.push1(res);
6356 }
6357 Operator::I16x8LeU => {
6358 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6359 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6360 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6361 let res = err!(
6362 self.builder
6363 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6364 );
6365 let res = err!(
6366 self.builder
6367 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6368 );
6369 let res = err!(
6370 self.builder
6371 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6372 );
6373 self.state.push1(res);
6374 }
6375 Operator::I32x4LeU => {
6376 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6377 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6378 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6379 let res = err!(
6380 self.builder
6381 .build_int_compare(IntPredicate::ULE, v1, v2, "")
6382 );
6383 let res = err!(
6384 self.builder
6385 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6386 );
6387 let res = err!(
6388 self.builder
6389 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6390 );
6391 self.state.push1(res);
6392 }
6393 Operator::I32GtS | Operator::I64GtS => {
6394 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6395 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6396 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6397 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6398 let cond = err!(
6399 self.builder
6400 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6401 );
6402 let res = err!(
6403 self.builder
6404 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6405 );
6406 self.state.push1_extra(
6407 res,
6408 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6409 );
6410 }
6411 Operator::I8x16GtS => {
6412 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6413 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6414 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6415 let res = err!(
6416 self.builder
6417 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6418 );
6419 let res = err!(
6420 self.builder
6421 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6422 );
6423 let res = err!(
6424 self.builder
6425 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6426 );
6427 self.state.push1(res);
6428 }
6429 Operator::I16x8GtS => {
6430 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6431 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6432 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6433 let res = err!(
6434 self.builder
6435 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6436 );
6437 let res = err!(
6438 self.builder
6439 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6440 );
6441 let res = err!(
6442 self.builder
6443 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6444 );
6445 self.state.push1(res);
6446 }
6447 Operator::I32x4GtS => {
6448 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6449 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6450 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6451 let res = err!(
6452 self.builder
6453 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6454 );
6455 let res = err!(
6456 self.builder
6457 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6458 );
6459 let res = err!(
6460 self.builder
6461 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6462 );
6463 self.state.push1(res);
6464 }
6465 Operator::I64x2GtS => {
6466 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6467 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6468 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6469 let res = err!(
6470 self.builder
6471 .build_int_compare(IntPredicate::SGT, v1, v2, "")
6472 );
6473 let res = err!(
6474 self.builder
6475 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6476 );
6477 let res = err!(
6478 self.builder
6479 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6480 );
6481 self.state.push1(res);
6482 }
6483 Operator::I32GtU | Operator::I64GtU => {
6484 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6485 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6486 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6487 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6488 let cond = err!(
6489 self.builder
6490 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6491 );
6492 let res = err!(
6493 self.builder
6494 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6495 );
6496 self.state.push1_extra(
6497 res,
6498 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6499 );
6500 }
6501 Operator::I8x16GtU => {
6502 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6503 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6504 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6505 let res = err!(
6506 self.builder
6507 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6508 );
6509 let res = err!(
6510 self.builder
6511 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6512 );
6513 let res = err!(
6514 self.builder
6515 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6516 );
6517 self.state.push1(res);
6518 }
6519 Operator::I16x8GtU => {
6520 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6521 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6522 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6523 let res = err!(
6524 self.builder
6525 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6526 );
6527 let res = err!(
6528 self.builder
6529 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6530 );
6531 let res = err!(
6532 self.builder
6533 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6534 );
6535 self.state.push1(res);
6536 }
6537 Operator::I32x4GtU => {
6538 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6539 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6540 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6541 let res = err!(
6542 self.builder
6543 .build_int_compare(IntPredicate::UGT, v1, v2, "")
6544 );
6545 let res = err!(
6546 self.builder
6547 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6548 );
6549 let res = err!(
6550 self.builder
6551 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6552 );
6553 self.state.push1(res);
6554 }
6555 Operator::I32GeS | Operator::I64GeS => {
6556 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6557 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6558 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6559 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6560 let cond = err!(
6561 self.builder
6562 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6563 );
6564 let res = err!(
6565 self.builder
6566 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6567 );
6568 self.state.push1(res);
6569 }
6570 Operator::I8x16GeS => {
6571 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6572 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6573 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6574 let res = err!(
6575 self.builder
6576 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6577 );
6578 let res = err!(
6579 self.builder
6580 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6581 );
6582 let res = err!(
6583 self.builder
6584 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6585 );
6586 self.state.push1(res);
6587 }
6588 Operator::I16x8GeS => {
6589 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6590 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6591 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6592 let res = err!(
6593 self.builder
6594 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6595 );
6596 let res = err!(
6597 self.builder
6598 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6599 );
6600 let res = err!(
6601 self.builder
6602 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6603 );
6604 self.state.push1(res);
6605 }
6606 Operator::I32x4GeS => {
6607 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6608 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6609 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6610 let res = err!(
6611 self.builder
6612 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6613 );
6614 let res = err!(
6615 self.builder
6616 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6617 );
6618 let res = err!(
6619 self.builder
6620 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6621 );
6622 self.state.push1(res);
6623 }
6624 Operator::I64x2GeS => {
6625 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6626 let (v1, _) = self.v128_into_i64x2(v1, i1)?;
6627 let (v2, _) = self.v128_into_i64x2(v2, i2)?;
6628 let res = err!(
6629 self.builder
6630 .build_int_compare(IntPredicate::SGE, v1, v2, "")
6631 );
6632 let res = err!(
6633 self.builder
6634 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6635 );
6636 let res = err!(
6637 self.builder
6638 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6639 );
6640 self.state.push1(res);
6641 }
6642 Operator::I32GeU | Operator::I64GeU => {
6643 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6644 let v1 = self.apply_pending_canonicalization(v1, i1)?;
6645 let v2 = self.apply_pending_canonicalization(v2, i2)?;
6646 let (v1, v2) = (v1.into_int_value(), v2.into_int_value());
6647 let cond = err!(
6648 self.builder
6649 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6650 );
6651 let res = err!(
6652 self.builder
6653 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6654 );
6655 self.state.push1_extra(
6656 res,
6657 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6658 );
6659 }
6660 Operator::I8x16GeU => {
6661 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6662 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
6663 let (v2, _) = self.v128_into_i8x16(v2, i2)?;
6664 let res = err!(
6665 self.builder
6666 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6667 );
6668 let res = err!(
6669 self.builder
6670 .build_int_s_extend(res, self.intrinsics.i8x16_ty, "")
6671 );
6672 let res = err!(
6673 self.builder
6674 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6675 );
6676 self.state.push1(res);
6677 }
6678 Operator::I16x8GeU => {
6679 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6680 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
6681 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
6682 let res = err!(
6683 self.builder
6684 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6685 );
6686 let res = err!(
6687 self.builder
6688 .build_int_s_extend(res, self.intrinsics.i16x8_ty, "")
6689 );
6690 let res = err!(
6691 self.builder
6692 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6693 );
6694 self.state.push1(res);
6695 }
6696 Operator::I32x4GeU => {
6697 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6698 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
6699 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
6700 let res = err!(
6701 self.builder
6702 .build_int_compare(IntPredicate::UGE, v1, v2, "")
6703 );
6704 let res = err!(
6705 self.builder
6706 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6707 );
6708 let res = err!(
6709 self.builder
6710 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6711 );
6712 self.state.push1(res);
6713 }
6714
6715 Operator::F32Eq | Operator::F64Eq => {
6720 let (v1, v2) = self.state.pop2()?;
6721 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6722 let cond = err!(
6723 self.builder
6724 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6725 );
6726 let res = err!(
6727 self.builder
6728 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6729 );
6730 self.state.push1_extra(
6731 res,
6732 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6733 );
6734 }
6735 Operator::F32x4Eq => {
6736 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6737 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6738 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6739 let res = err!(
6740 self.builder
6741 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6742 );
6743 let res = err!(
6744 self.builder
6745 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6746 );
6747 let res = err!(
6748 self.builder
6749 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6750 );
6751 self.state.push1(res);
6752 }
6753 Operator::F64x2Eq => {
6754 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6755 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6756 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6757 let res = err!(
6758 self.builder
6759 .build_float_compare(FloatPredicate::OEQ, v1, v2, "")
6760 );
6761 let res = err!(
6762 self.builder
6763 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6764 );
6765 let res = err!(
6766 self.builder
6767 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6768 );
6769 self.state.push1(res);
6770 }
6771 Operator::F32Ne | Operator::F64Ne => {
6772 let (v1, v2) = self.state.pop2()?;
6773 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6774 let cond = err!(
6775 self.builder
6776 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6777 );
6778 let res = err!(
6779 self.builder
6780 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6781 );
6782 self.state.push1_extra(
6783 res,
6784 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6785 );
6786 }
6787 Operator::F32x4Ne => {
6788 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6789 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6790 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6791 let res = err!(
6792 self.builder
6793 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6794 );
6795 let res = err!(
6796 self.builder
6797 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6798 );
6799 let res = err!(
6800 self.builder
6801 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6802 );
6803 self.state.push1(res);
6804 }
6805 Operator::F64x2Ne => {
6806 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6807 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6808 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6809 let res = err!(
6810 self.builder
6811 .build_float_compare(FloatPredicate::UNE, v1, v2, "")
6812 );
6813 let res = err!(
6814 self.builder
6815 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6816 );
6817 let res = err!(
6818 self.builder
6819 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6820 );
6821 self.state.push1(res);
6822 }
6823 Operator::F32Lt | Operator::F64Lt => {
6824 let (v1, v2) = self.state.pop2()?;
6825 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6826 let cond = err!(
6827 self.builder
6828 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6829 );
6830 let res = err!(
6831 self.builder
6832 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6833 );
6834 self.state.push1_extra(
6835 res,
6836 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6837 );
6838 }
6839 Operator::F32x4Lt => {
6840 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6841 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6842 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6843 let res = err!(
6844 self.builder
6845 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6846 );
6847 let res = err!(
6848 self.builder
6849 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6850 );
6851 let res = err!(
6852 self.builder
6853 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6854 );
6855 self.state.push1(res);
6856 }
6857 Operator::F64x2Lt => {
6858 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6859 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6860 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6861 let res = err!(
6862 self.builder
6863 .build_float_compare(FloatPredicate::OLT, v1, v2, "")
6864 );
6865 let res = err!(
6866 self.builder
6867 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6868 );
6869 let res = err!(
6870 self.builder
6871 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6872 );
6873 self.state.push1(res);
6874 }
6875 Operator::F32Le | Operator::F64Le => {
6876 let (v1, v2) = self.state.pop2()?;
6877 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6878 let cond = err!(
6879 self.builder
6880 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6881 );
6882 let res = err!(
6883 self.builder
6884 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6885 );
6886 self.state.push1_extra(
6887 res,
6888 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6889 );
6890 }
6891 Operator::F32x4Le => {
6892 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6893 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6894 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6895 let res = err!(
6896 self.builder
6897 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6898 );
6899 let res = err!(
6900 self.builder
6901 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6902 );
6903 let res = err!(
6904 self.builder
6905 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6906 );
6907 self.state.push1(res);
6908 }
6909 Operator::F64x2Le => {
6910 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6911 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6912 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6913 let res = err!(
6914 self.builder
6915 .build_float_compare(FloatPredicate::OLE, v1, v2, "")
6916 );
6917 let res = err!(
6918 self.builder
6919 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6920 );
6921 let res = err!(
6922 self.builder
6923 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6924 );
6925 self.state.push1(res);
6926 }
6927 Operator::F32Gt | Operator::F64Gt => {
6928 let (v1, v2) = self.state.pop2()?;
6929 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6930 let cond = err!(
6931 self.builder
6932 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6933 );
6934 let res = err!(
6935 self.builder
6936 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6937 );
6938 self.state.push1_extra(
6939 res,
6940 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6941 );
6942 }
6943 Operator::F32x4Gt => {
6944 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6945 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6946 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6947 let res = err!(
6948 self.builder
6949 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6950 );
6951 let res = err!(
6952 self.builder
6953 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
6954 );
6955 let res = err!(
6956 self.builder
6957 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6958 );
6959 self.state.push1(res);
6960 }
6961 Operator::F64x2Gt => {
6962 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6963 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
6964 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
6965 let res = err!(
6966 self.builder
6967 .build_float_compare(FloatPredicate::OGT, v1, v2, "")
6968 );
6969 let res = err!(
6970 self.builder
6971 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
6972 );
6973 let res = err!(
6974 self.builder
6975 .build_bit_cast(res, self.intrinsics.i128_ty, "")
6976 );
6977 self.state.push1(res);
6978 }
6979 Operator::F32Ge | Operator::F64Ge => {
6980 let (v1, v2) = self.state.pop2()?;
6981 let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
6982 let cond = err!(
6983 self.builder
6984 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
6985 );
6986 let res = err!(
6987 self.builder
6988 .build_int_z_extend(cond, self.intrinsics.i32_ty, "")
6989 );
6990 self.state.push1_extra(
6991 res,
6992 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
6993 );
6994 }
6995 Operator::F32x4Ge => {
6996 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
6997 let (v1, _) = self.v128_into_f32x4(v1, i1)?;
6998 let (v2, _) = self.v128_into_f32x4(v2, i2)?;
6999 let res = err!(
7000 self.builder
7001 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7002 );
7003 let res = err!(
7004 self.builder
7005 .build_int_s_extend(res, self.intrinsics.i32x4_ty, "")
7006 );
7007 let res = err!(
7008 self.builder
7009 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7010 );
7011 self.state.push1(res);
7012 }
7013 Operator::F64x2Ge => {
7014 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7015 let (v1, _) = self.v128_into_f64x2(v1, i1)?;
7016 let (v2, _) = self.v128_into_f64x2(v2, i2)?;
7017 let res = err!(
7018 self.builder
7019 .build_float_compare(FloatPredicate::OGE, v1, v2, "")
7020 );
7021 let res = err!(
7022 self.builder
7023 .build_int_s_extend(res, self.intrinsics.i64x2_ty, "")
7024 );
7025 let res = err!(
7026 self.builder
7027 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7028 );
7029 self.state.push1(res);
7030 }
7031
7032 Operator::I32WrapI64 => {
7037 let (v, i) = self.state.pop1_extra()?;
7038 let v = self.apply_pending_canonicalization(v, i)?;
7039 let v = v.into_int_value();
7040 let res = err!(
7041 self.builder
7042 .build_int_truncate(v, self.intrinsics.i32_ty, "")
7043 );
7044 self.state.push1(res);
7045 }
7046 Operator::I64ExtendI32S => {
7047 let (v, i) = self.state.pop1_extra()?;
7048 let v = self.apply_pending_canonicalization(v, i)?;
7049 let v = v.into_int_value();
7050 let res = err!(
7051 self.builder
7052 .build_int_s_extend(v, self.intrinsics.i64_ty, "")
7053 );
7054 self.state.push1(res);
7055 }
7056 Operator::I64ExtendI32U => {
7057 let (v, i) = self.state.pop1_extra()?;
7058 let v = self.apply_pending_canonicalization(v, i)?;
7059 let v = v.into_int_value();
7060 let res = err!(
7061 self.builder
7062 .build_int_z_extend(v, self.intrinsics.i64_ty, "")
7063 );
7064 self.state.push1_extra(res, ExtraInfo::arithmetic_f64());
7065 }
7066 Operator::I16x8ExtendLowI8x16S => {
7067 let (v, i) = self.state.pop1_extra()?;
7068 let (v, _) = self.v128_into_i8x16(v, i)?;
7069 let low = err!(self.builder.build_shuffle_vector(
7070 v,
7071 v.get_type().get_undef(),
7072 VectorType::const_vector(&[
7073 self.intrinsics.i32_consts[0],
7074 self.intrinsics.i32_consts[1],
7075 self.intrinsics.i32_consts[2],
7076 self.intrinsics.i32_consts[3],
7077 self.intrinsics.i32_consts[4],
7078 self.intrinsics.i32_consts[5],
7079 self.intrinsics.i32_consts[6],
7080 self.intrinsics.i32_consts[7],
7081 ]),
7082 "",
7083 ));
7084 let res = err!(
7085 self.builder
7086 .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7087 );
7088 let res = err!(
7089 self.builder
7090 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7091 );
7092 self.state.push1(res);
7093 }
7094 Operator::I16x8ExtendHighI8x16S => {
7095 let (v, i) = self.state.pop1_extra()?;
7096 let (v, _) = self.v128_into_i8x16(v, i)?;
7097 let low = err!(self.builder.build_shuffle_vector(
7098 v,
7099 v.get_type().get_undef(),
7100 VectorType::const_vector(&[
7101 self.intrinsics.i32_consts[8],
7102 self.intrinsics.i32_consts[9],
7103 self.intrinsics.i32_consts[10],
7104 self.intrinsics.i32_consts[11],
7105 self.intrinsics.i32_consts[12],
7106 self.intrinsics.i32_consts[13],
7107 self.intrinsics.i32_consts[14],
7108 self.intrinsics.i32_consts[15],
7109 ]),
7110 "",
7111 ));
7112 let res = err!(
7113 self.builder
7114 .build_int_s_extend(low, self.intrinsics.i16x8_ty, "")
7115 );
7116 let res = err!(
7117 self.builder
7118 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7119 );
7120 self.state.push1(res);
7121 }
7122 Operator::I16x8ExtendLowI8x16U => {
7123 let (v, i) = self.state.pop1_extra()?;
7124 let (v, _) = self.v128_into_i8x16(v, i)?;
7125 let low = err!(self.builder.build_shuffle_vector(
7126 v,
7127 v.get_type().get_undef(),
7128 VectorType::const_vector(&[
7129 self.intrinsics.i32_consts[0],
7130 self.intrinsics.i32_consts[1],
7131 self.intrinsics.i32_consts[2],
7132 self.intrinsics.i32_consts[3],
7133 self.intrinsics.i32_consts[4],
7134 self.intrinsics.i32_consts[5],
7135 self.intrinsics.i32_consts[6],
7136 self.intrinsics.i32_consts[7],
7137 ]),
7138 "",
7139 ));
7140 let res = err!(
7141 self.builder
7142 .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7143 );
7144 let res = err!(
7145 self.builder
7146 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7147 );
7148 self.state.push1(res);
7149 }
7150 Operator::I16x8ExtendHighI8x16U => {
7151 let (v, i) = self.state.pop1_extra()?;
7152 let (v, _) = self.v128_into_i8x16(v, i)?;
7153 let low = err!(self.builder.build_shuffle_vector(
7154 v,
7155 v.get_type().get_undef(),
7156 VectorType::const_vector(&[
7157 self.intrinsics.i32_consts[8],
7158 self.intrinsics.i32_consts[9],
7159 self.intrinsics.i32_consts[10],
7160 self.intrinsics.i32_consts[11],
7161 self.intrinsics.i32_consts[12],
7162 self.intrinsics.i32_consts[13],
7163 self.intrinsics.i32_consts[14],
7164 self.intrinsics.i32_consts[15],
7165 ]),
7166 "",
7167 ));
7168 let res = err!(
7169 self.builder
7170 .build_int_z_extend(low, self.intrinsics.i16x8_ty, "")
7171 );
7172 let res = err!(
7173 self.builder
7174 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7175 );
7176 self.state.push1(res);
7177 }
7178 Operator::I32x4ExtendLowI16x8S => {
7179 let (v, i) = self.state.pop1_extra()?;
7180 let (v, _) = self.v128_into_i16x8(v, i)?;
7181 let low = err!(self.builder.build_shuffle_vector(
7182 v,
7183 v.get_type().get_undef(),
7184 VectorType::const_vector(&[
7185 self.intrinsics.i32_consts[0],
7186 self.intrinsics.i32_consts[1],
7187 self.intrinsics.i32_consts[2],
7188 self.intrinsics.i32_consts[3],
7189 ]),
7190 "",
7191 ));
7192 let res = err!(
7193 self.builder
7194 .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7195 );
7196 let res = err!(
7197 self.builder
7198 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7199 );
7200 self.state.push1(res);
7201 }
7202 Operator::I32x4ExtendHighI16x8S => {
7203 let (v, i) = self.state.pop1_extra()?;
7204 let (v, _) = self.v128_into_i16x8(v, i)?;
7205 let low = err!(self.builder.build_shuffle_vector(
7206 v,
7207 v.get_type().get_undef(),
7208 VectorType::const_vector(&[
7209 self.intrinsics.i32_consts[4],
7210 self.intrinsics.i32_consts[5],
7211 self.intrinsics.i32_consts[6],
7212 self.intrinsics.i32_consts[7],
7213 ]),
7214 "",
7215 ));
7216 let res = err!(
7217 self.builder
7218 .build_int_s_extend(low, self.intrinsics.i32x4_ty, "")
7219 );
7220 let res = err!(
7221 self.builder
7222 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7223 );
7224 self.state.push1(res);
7225 }
7226 Operator::I32x4ExtendLowI16x8U => {
7227 let (v, i) = self.state.pop1_extra()?;
7228 let (v, _) = self.v128_into_i16x8(v, i)?;
7229 let low = err!(self.builder.build_shuffle_vector(
7230 v,
7231 v.get_type().get_undef(),
7232 VectorType::const_vector(&[
7233 self.intrinsics.i32_consts[0],
7234 self.intrinsics.i32_consts[1],
7235 self.intrinsics.i32_consts[2],
7236 self.intrinsics.i32_consts[3],
7237 ]),
7238 "",
7239 ));
7240 let res = err!(
7241 self.builder
7242 .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7243 );
7244 let res = err!(
7245 self.builder
7246 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7247 );
7248 self.state.push1(res);
7249 }
7250 Operator::I32x4ExtendHighI16x8U => {
7251 let (v, i) = self.state.pop1_extra()?;
7252 let (v, _) = self.v128_into_i16x8(v, i)?;
7253 let low = err!(self.builder.build_shuffle_vector(
7254 v,
7255 v.get_type().get_undef(),
7256 VectorType::const_vector(&[
7257 self.intrinsics.i32_consts[4],
7258 self.intrinsics.i32_consts[5],
7259 self.intrinsics.i32_consts[6],
7260 self.intrinsics.i32_consts[7],
7261 ]),
7262 "",
7263 ));
7264 let res = err!(
7265 self.builder
7266 .build_int_z_extend(low, self.intrinsics.i32x4_ty, "")
7267 );
7268 let res = err!(
7269 self.builder
7270 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7271 );
7272 self.state.push1(res);
7273 }
7274 Operator::I64x2ExtendLowI32x4U
7275 | Operator::I64x2ExtendLowI32x4S
7276 | Operator::I64x2ExtendHighI32x4U
7277 | Operator::I64x2ExtendHighI32x4S => {
7278 let extend = match op {
7279 Operator::I64x2ExtendLowI32x4U | Operator::I64x2ExtendHighI32x4U => {
7280 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
7281 }
7282 Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendHighI32x4S => {
7283 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
7284 }
7285 _ => unreachable!("Unhandled inner case"),
7286 };
7287 let indices = match op {
7288 Operator::I64x2ExtendLowI32x4S | Operator::I64x2ExtendLowI32x4U => {
7289 [self.intrinsics.i32_consts[0], self.intrinsics.i32_consts[1]]
7290 }
7291 Operator::I64x2ExtendHighI32x4S | Operator::I64x2ExtendHighI32x4U => {
7292 [self.intrinsics.i32_consts[2], self.intrinsics.i32_consts[3]]
7293 }
7294 _ => unreachable!("Unhandled inner case"),
7295 };
7296 let (v, i) = self.state.pop1_extra()?;
7297 let (v, _) = self.v128_into_i32x4(v, i)?;
7298 let low = err!(self.builder.build_shuffle_vector(
7299 v,
7300 v.get_type().get_undef(),
7301 VectorType::const_vector(&indices),
7302 "",
7303 ));
7304 let res = err!(extend(self, low));
7305 let res = err!(
7306 self.builder
7307 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7308 );
7309 self.state.push1(res);
7310 }
7311 Operator::I8x16NarrowI16x8S => {
7312 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7313 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7314 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7315 let min = self.intrinsics.i16_ty.const_int(0xff80, false);
7316 let max = self.intrinsics.i16_ty.const_int(0x007f, false);
7317 let min = VectorType::const_vector(&[min; 8]);
7318 let max = VectorType::const_vector(&[max; 8]);
7319 let apply_min_clamp_v1 =
7320 err!(
7321 self.builder
7322 .build_int_compare(IntPredicate::SLT, v1, min, "")
7323 );
7324 let apply_max_clamp_v1 =
7325 err!(
7326 self.builder
7327 .build_int_compare(IntPredicate::SGT, v1, max, "")
7328 );
7329 let apply_min_clamp_v2 =
7330 err!(
7331 self.builder
7332 .build_int_compare(IntPredicate::SLT, v2, min, "")
7333 );
7334 let apply_max_clamp_v2 =
7335 err!(
7336 self.builder
7337 .build_int_compare(IntPredicate::SGT, v2, max, "")
7338 );
7339 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7340 .into_vector_value();
7341 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7342 .into_vector_value();
7343 let v1 = err!(self.builder.build_int_truncate(
7344 v1,
7345 self.intrinsics.i8_ty.vec_type(8),
7346 ""
7347 ));
7348 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7349 .into_vector_value();
7350 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7351 .into_vector_value();
7352 let v2 = err!(self.builder.build_int_truncate(
7353 v2,
7354 self.intrinsics.i8_ty.vec_type(8),
7355 ""
7356 ));
7357 let res = err!(self.builder.build_shuffle_vector(
7358 v1,
7359 v2,
7360 VectorType::const_vector(&[
7361 self.intrinsics.i32_consts[0],
7362 self.intrinsics.i32_consts[1],
7363 self.intrinsics.i32_consts[2],
7364 self.intrinsics.i32_consts[3],
7365 self.intrinsics.i32_consts[4],
7366 self.intrinsics.i32_consts[5],
7367 self.intrinsics.i32_consts[6],
7368 self.intrinsics.i32_consts[7],
7369 self.intrinsics.i32_consts[8],
7370 self.intrinsics.i32_consts[9],
7371 self.intrinsics.i32_consts[10],
7372 self.intrinsics.i32_consts[11],
7373 self.intrinsics.i32_consts[12],
7374 self.intrinsics.i32_consts[13],
7375 self.intrinsics.i32_consts[14],
7376 self.intrinsics.i32_consts[15],
7377 ]),
7378 "",
7379 ));
7380 let res = err!(
7381 self.builder
7382 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7383 );
7384 self.state.push1(res);
7385 }
7386 Operator::I8x16NarrowI16x8U => {
7387 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7388 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
7389 let (v2, _) = self.v128_into_i16x8(v2, i2)?;
7390 let min = self.intrinsics.i16x8_ty.const_zero();
7391 let max = self.intrinsics.i16_ty.const_int(0x00ff, false);
7392 let max = VectorType::const_vector(&[max; 8]);
7393 let apply_min_clamp_v1 =
7394 err!(
7395 self.builder
7396 .build_int_compare(IntPredicate::SLT, v1, min, "")
7397 );
7398 let apply_max_clamp_v1 =
7399 err!(
7400 self.builder
7401 .build_int_compare(IntPredicate::SGT, v1, max, "")
7402 );
7403 let apply_min_clamp_v2 =
7404 err!(
7405 self.builder
7406 .build_int_compare(IntPredicate::SLT, v2, min, "")
7407 );
7408 let apply_max_clamp_v2 =
7409 err!(
7410 self.builder
7411 .build_int_compare(IntPredicate::SGT, v2, max, "")
7412 );
7413 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7414 .into_vector_value();
7415 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7416 .into_vector_value();
7417 let v1 = err!(self.builder.build_int_truncate(
7418 v1,
7419 self.intrinsics.i8_ty.vec_type(8),
7420 ""
7421 ));
7422 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7423 .into_vector_value();
7424 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7425 .into_vector_value();
7426 let v2 = err!(self.builder.build_int_truncate(
7427 v2,
7428 self.intrinsics.i8_ty.vec_type(8),
7429 ""
7430 ));
7431 let res = err!(self.builder.build_shuffle_vector(
7432 v1,
7433 v2,
7434 VectorType::const_vector(&[
7435 self.intrinsics.i32_consts[0],
7436 self.intrinsics.i32_consts[1],
7437 self.intrinsics.i32_consts[2],
7438 self.intrinsics.i32_consts[3],
7439 self.intrinsics.i32_consts[4],
7440 self.intrinsics.i32_consts[5],
7441 self.intrinsics.i32_consts[6],
7442 self.intrinsics.i32_consts[7],
7443 self.intrinsics.i32_consts[8],
7444 self.intrinsics.i32_consts[9],
7445 self.intrinsics.i32_consts[10],
7446 self.intrinsics.i32_consts[11],
7447 self.intrinsics.i32_consts[12],
7448 self.intrinsics.i32_consts[13],
7449 self.intrinsics.i32_consts[14],
7450 self.intrinsics.i32_consts[15],
7451 ]),
7452 "",
7453 ));
7454 let res = err!(
7455 self.builder
7456 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7457 );
7458 self.state.push1(res);
7459 }
7460 Operator::I16x8NarrowI32x4S => {
7461 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7462 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7463 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7464 let min = self.intrinsics.i32_ty.const_int(0xffff8000, false);
7465 let max = self.intrinsics.i32_ty.const_int(0x00007fff, false);
7466 let min = VectorType::const_vector(&[min; 4]);
7467 let max = VectorType::const_vector(&[max; 4]);
7468 let apply_min_clamp_v1 =
7469 err!(
7470 self.builder
7471 .build_int_compare(IntPredicate::SLT, v1, min, "")
7472 );
7473 let apply_max_clamp_v1 =
7474 err!(
7475 self.builder
7476 .build_int_compare(IntPredicate::SGT, v1, max, "")
7477 );
7478 let apply_min_clamp_v2 =
7479 err!(
7480 self.builder
7481 .build_int_compare(IntPredicate::SLT, v2, min, "")
7482 );
7483 let apply_max_clamp_v2 =
7484 err!(
7485 self.builder
7486 .build_int_compare(IntPredicate::SGT, v2, max, "")
7487 );
7488 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7489 .into_vector_value();
7490 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7491 .into_vector_value();
7492 let v1 = err!(self.builder.build_int_truncate(
7493 v1,
7494 self.intrinsics.i16_ty.vec_type(4),
7495 ""
7496 ));
7497 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7498 .into_vector_value();
7499 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7500 .into_vector_value();
7501 let v2 = err!(self.builder.build_int_truncate(
7502 v2,
7503 self.intrinsics.i16_ty.vec_type(4),
7504 ""
7505 ));
7506 let res = err!(self.builder.build_shuffle_vector(
7507 v1,
7508 v2,
7509 VectorType::const_vector(&[
7510 self.intrinsics.i32_consts[0],
7511 self.intrinsics.i32_consts[1],
7512 self.intrinsics.i32_consts[2],
7513 self.intrinsics.i32_consts[3],
7514 self.intrinsics.i32_consts[4],
7515 self.intrinsics.i32_consts[5],
7516 self.intrinsics.i32_consts[6],
7517 self.intrinsics.i32_consts[7],
7518 ]),
7519 "",
7520 ));
7521 let res = err!(
7522 self.builder
7523 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7524 );
7525 self.state.push1(res);
7526 }
7527 Operator::I16x8NarrowI32x4U => {
7528 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
7529 let (v1, _) = self.v128_into_i32x4(v1, i1)?;
7530 let (v2, _) = self.v128_into_i32x4(v2, i2)?;
7531 let min = self.intrinsics.i32x4_ty.const_zero();
7532 let max = self.intrinsics.i32_ty.const_int(0xffff, false);
7533 let max = VectorType::const_vector(&[max; 4]);
7534 let apply_min_clamp_v1 =
7535 err!(
7536 self.builder
7537 .build_int_compare(IntPredicate::SLT, v1, min, "")
7538 );
7539 let apply_max_clamp_v1 =
7540 err!(
7541 self.builder
7542 .build_int_compare(IntPredicate::SGT, v1, max, "")
7543 );
7544 let apply_min_clamp_v2 =
7545 err!(
7546 self.builder
7547 .build_int_compare(IntPredicate::SLT, v2, min, "")
7548 );
7549 let apply_max_clamp_v2 =
7550 err!(
7551 self.builder
7552 .build_int_compare(IntPredicate::SGT, v2, max, "")
7553 );
7554 let v1 = err!(self.builder.build_select(apply_min_clamp_v1, min, v1, ""))
7555 .into_vector_value();
7556 let v1 = err!(self.builder.build_select(apply_max_clamp_v1, max, v1, ""))
7557 .into_vector_value();
7558 let v1 = err!(self.builder.build_int_truncate(
7559 v1,
7560 self.intrinsics.i16_ty.vec_type(4),
7561 ""
7562 ));
7563 let v2 = err!(self.builder.build_select(apply_min_clamp_v2, min, v2, ""))
7564 .into_vector_value();
7565 let v2 = err!(self.builder.build_select(apply_max_clamp_v2, max, v2, ""))
7566 .into_vector_value();
7567 let v2 = err!(self.builder.build_int_truncate(
7568 v2,
7569 self.intrinsics.i16_ty.vec_type(4),
7570 ""
7571 ));
7572 let res = err!(self.builder.build_shuffle_vector(
7573 v1,
7574 v2,
7575 VectorType::const_vector(&[
7576 self.intrinsics.i32_consts[0],
7577 self.intrinsics.i32_consts[1],
7578 self.intrinsics.i32_consts[2],
7579 self.intrinsics.i32_consts[3],
7580 self.intrinsics.i32_consts[4],
7581 self.intrinsics.i32_consts[5],
7582 self.intrinsics.i32_consts[6],
7583 self.intrinsics.i32_consts[7],
7584 ]),
7585 "",
7586 ));
7587 let res = err!(
7588 self.builder
7589 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7590 );
7591 self.state.push1(res);
7592 }
7593 Operator::I32x4TruncSatF32x4S => {
7594 let (v, i) = self.state.pop1_extra()?;
7595 let v = self.apply_pending_canonicalization(v, i)?;
7596 let v = v.into_int_value();
7597 let res = self.trunc_sat_into_int(
7598 self.intrinsics.f32x4_ty,
7599 self.intrinsics.i32x4_ty,
7600 LEF32_GEQ_I32_MIN,
7601 GEF32_LEQ_I32_MAX,
7602 i32::MIN as u64,
7603 i32::MAX as u64,
7604 v,
7605 )?;
7606 self.state.push1(res);
7607 }
7608 Operator::I32x4TruncSatF32x4U => {
7609 let (v, i) = self.state.pop1_extra()?;
7610 let v = self.apply_pending_canonicalization(v, i)?;
7611 let v = v.into_int_value();
7612 let res = self.trunc_sat_into_int(
7613 self.intrinsics.f32x4_ty,
7614 self.intrinsics.i32x4_ty,
7615 LEF32_GEQ_U32_MIN,
7616 GEF32_LEQ_U32_MAX,
7617 u32::MIN as u64,
7618 u32::MAX as u64,
7619 v,
7620 )?;
7621 self.state.push1(res);
7622 }
7623 Operator::I32x4TruncSatF64x2SZero | Operator::I32x4TruncSatF64x2UZero => {
7624 let ((min, max), (cmp_min, cmp_max)) = match op {
7625 Operator::I32x4TruncSatF64x2SZero => (
7626 (i32::MIN as u64, i32::MAX as u64),
7627 (LEF64_GEQ_I32_MIN, GEF64_LEQ_I32_MAX),
7628 ),
7629 Operator::I32x4TruncSatF64x2UZero => (
7630 (u32::MIN as u64, u32::MAX as u64),
7631 (LEF64_GEQ_U32_MIN, GEF64_LEQ_U32_MAX),
7632 ),
7633 _ => unreachable!("Unhandled internal variant"),
7634 };
7635 let (v, i) = self.state.pop1_extra()?;
7636 let v = self.apply_pending_canonicalization(v, i)?;
7637 let v = v.into_int_value();
7638 let res = self.trunc_sat(
7639 self.intrinsics.f64x2_ty,
7640 self.intrinsics.i32_ty.vec_type(2),
7641 cmp_min,
7642 cmp_max,
7643 min,
7644 max,
7645 v,
7646 )?;
7647
7648 let zero = self.intrinsics.i32_consts[0];
7649 let zeros = VectorType::const_vector(&[zero; 2]);
7650 let res = err!(self.builder.build_shuffle_vector(
7651 res,
7652 zeros,
7653 VectorType::const_vector(&[
7654 self.intrinsics.i32_consts[0],
7655 self.intrinsics.i32_consts[1],
7656 self.intrinsics.i32_consts[2],
7657 self.intrinsics.i32_consts[3],
7658 ]),
7659 "",
7660 ));
7661 let res = err!(
7662 self.builder
7663 .build_bit_cast(res, self.intrinsics.i128_ty, "")
7664 );
7665 self.state.push1(res);
7666 }
7667 Operator::I32TruncF32S => {
7698 let v1 = self.state.pop1()?.into_float_value();
7699 self.trap_if_not_representable_as_int(
7700 0xcf000000, 0x4effffff, v1,
7703 )?;
7704 let res = err!(self.builder.build_float_to_signed_int(
7705 v1,
7706 self.intrinsics.i32_ty,
7707 ""
7708 ));
7709 self.state.push1(res);
7710 }
7711 Operator::I32TruncF64S => {
7712 let v1 = self.state.pop1()?.into_float_value();
7713 self.trap_if_not_representable_as_int(
7714 0xc1e00000001fffff, 0x41dfffffffffffff, v1,
7717 )?;
7718 let res = err!(self.builder.build_float_to_signed_int(
7719 v1,
7720 self.intrinsics.i32_ty,
7721 ""
7722 ));
7723 self.state.push1(res);
7724 }
7725 Operator::I32TruncSatF32S => {
7726 let (v, i) = self.state.pop1_extra()?;
7727 let v = self.apply_pending_canonicalization(v, i)?;
7728 let v = v.into_float_value();
7729 let res = self.trunc_sat_scalar(
7730 self.intrinsics.i32_ty,
7731 LEF32_GEQ_I32_MIN,
7732 GEF32_LEQ_I32_MAX,
7733 i32::MIN as u32 as u64,
7734 i32::MAX as u32 as u64,
7735 v,
7736 )?;
7737 self.state.push1(res);
7738 }
7739 Operator::I32TruncSatF64S => {
7740 let (v, i) = self.state.pop1_extra()?;
7741 let v = self.apply_pending_canonicalization(v, i)?;
7742 let v = v.into_float_value();
7743 let res = self.trunc_sat_scalar(
7744 self.intrinsics.i32_ty,
7745 LEF64_GEQ_I32_MIN,
7746 GEF64_LEQ_I32_MAX,
7747 i32::MIN as u64,
7748 i32::MAX as u64,
7749 v,
7750 )?;
7751 self.state.push1(res);
7752 }
7753 Operator::I64TruncF32S => {
7754 let v1 = self.state.pop1()?.into_float_value();
7755 self.trap_if_not_representable_as_int(
7756 0xdf000000, 0x5effffff, v1,
7759 )?;
7760 let res = err!(self.builder.build_float_to_signed_int(
7761 v1,
7762 self.intrinsics.i64_ty,
7763 ""
7764 ));
7765 self.state.push1(res);
7766 }
7767 Operator::I64TruncF64S => {
7768 let v1 = self.state.pop1()?.into_float_value();
7769 self.trap_if_not_representable_as_int(
7770 0xc3e0000000000000, 0x43dfffffffffffff, v1,
7773 )?;
7774 let res = err!(self.builder.build_float_to_signed_int(
7775 v1,
7776 self.intrinsics.i64_ty,
7777 ""
7778 ));
7779 self.state.push1(res);
7780 }
7781 Operator::I64TruncSatF32S => {
7782 let (v, i) = self.state.pop1_extra()?;
7783 let v = self.apply_pending_canonicalization(v, i)?;
7784 let v = v.into_float_value();
7785 let res = self.trunc_sat_scalar(
7786 self.intrinsics.i64_ty,
7787 LEF32_GEQ_I64_MIN,
7788 GEF32_LEQ_I64_MAX,
7789 i64::MIN as u64,
7790 i64::MAX as u64,
7791 v,
7792 )?;
7793 self.state.push1(res);
7794 }
7795 Operator::I64TruncSatF64S => {
7796 let (v, i) = self.state.pop1_extra()?;
7797 let v = self.apply_pending_canonicalization(v, i)?;
7798 let v = v.into_float_value();
7799 let res = self.trunc_sat_scalar(
7800 self.intrinsics.i64_ty,
7801 LEF64_GEQ_I64_MIN,
7802 GEF64_LEQ_I64_MAX,
7803 i64::MIN as u64,
7804 i64::MAX as u64,
7805 v,
7806 )?;
7807 self.state.push1(res);
7808 }
7809 Operator::I32TruncF32U => {
7810 let v1 = self.state.pop1()?.into_float_value();
7811 self.trap_if_not_representable_as_int(
7812 0xbf7fffff, 0x4f7fffff, v1,
7815 )?;
7816 let res = err!(self.builder.build_float_to_unsigned_int(
7817 v1,
7818 self.intrinsics.i32_ty,
7819 ""
7820 ));
7821 self.state.push1(res);
7822 }
7823 Operator::I32TruncF64U => {
7824 let v1 = self.state.pop1()?.into_float_value();
7825 self.trap_if_not_representable_as_int(
7826 0xbfefffffffffffff, 0x41efffffffffffff, v1,
7829 )?;
7830 let res = err!(self.builder.build_float_to_unsigned_int(
7831 v1,
7832 self.intrinsics.i32_ty,
7833 ""
7834 ));
7835 self.state.push1(res);
7836 }
7837 Operator::I32TruncSatF32U => {
7838 let (v, i) = self.state.pop1_extra()?;
7839 let v = self.apply_pending_canonicalization(v, i)?;
7840 let v = v.into_float_value();
7841 let res = self.trunc_sat_scalar(
7842 self.intrinsics.i32_ty,
7843 LEF32_GEQ_U32_MIN,
7844 GEF32_LEQ_U32_MAX,
7845 u32::MIN as u64,
7846 u32::MAX as u64,
7847 v,
7848 )?;
7849 self.state.push1(res);
7850 }
7851 Operator::I32TruncSatF64U => {
7852 let (v, i) = self.state.pop1_extra()?;
7853 let v = self.apply_pending_canonicalization(v, i)?;
7854 let v = v.into_float_value();
7855 let res = self.trunc_sat_scalar(
7856 self.intrinsics.i32_ty,
7857 LEF64_GEQ_U32_MIN,
7858 GEF64_LEQ_U32_MAX,
7859 u32::MIN as u64,
7860 u32::MAX as u64,
7861 v,
7862 )?;
7863 self.state.push1(res);
7864 }
7865 Operator::I64TruncF32U => {
7866 let v1 = self.state.pop1()?.into_float_value();
7867 self.trap_if_not_representable_as_int(
7868 0xbf7fffff, 0x5f7fffff, v1,
7871 )?;
7872 let res = err!(self.builder.build_float_to_unsigned_int(
7873 v1,
7874 self.intrinsics.i64_ty,
7875 ""
7876 ));
7877 self.state.push1(res);
7878 }
7879 Operator::I64TruncF64U => {
7880 let v1 = self.state.pop1()?.into_float_value();
7881 self.trap_if_not_representable_as_int(
7882 0xbfefffffffffffff, 0x43efffffffffffff, v1,
7885 )?;
7886 let res = err!(self.builder.build_float_to_unsigned_int(
7887 v1,
7888 self.intrinsics.i64_ty,
7889 ""
7890 ));
7891 self.state.push1(res);
7892 }
7893 Operator::I64TruncSatF32U => {
7894 let (v, i) = self.state.pop1_extra()?;
7895 let v = self.apply_pending_canonicalization(v, i)?;
7896 let v = v.into_float_value();
7897 let res = self.trunc_sat_scalar(
7898 self.intrinsics.i64_ty,
7899 LEF32_GEQ_U64_MIN,
7900 GEF32_LEQ_U64_MAX,
7901 u64::MIN,
7902 u64::MAX,
7903 v,
7904 )?;
7905 self.state.push1(res);
7906 }
7907 Operator::I64TruncSatF64U => {
7908 let (v, i) = self.state.pop1_extra()?;
7909 let v = self.apply_pending_canonicalization(v, i)?;
7910 let v = v.into_float_value();
7911 let res = self.trunc_sat_scalar(
7912 self.intrinsics.i64_ty,
7913 LEF64_GEQ_U64_MIN,
7914 GEF64_LEQ_U64_MAX,
7915 u64::MIN,
7916 u64::MAX,
7917 v,
7918 )?;
7919 self.state.push1(res);
7920 }
7921 Operator::F32DemoteF64 => {
7922 let v = self.state.pop1()?;
7923 let v = v.into_float_value();
7924 let res = err!(self.builder.build_call(
7925 self.intrinsics.fptrunc_f64,
7926 &[
7927 v.into(),
7928 self.intrinsics.fp_rounding_md,
7929 self.intrinsics.fp_exception_md,
7930 ],
7931 "",
7932 ))
7933 .try_as_basic_value()
7934 .unwrap_basic();
7935 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
7936 }
7937 Operator::F64PromoteF32 => {
7938 let v = self.state.pop1()?;
7939 let v = v.into_float_value();
7940 let res = err!(self.builder.build_call(
7941 self.intrinsics.fpext_f32,
7942 &[v.into(), self.intrinsics.fp_exception_md],
7943 "",
7944 ))
7945 .try_as_basic_value()
7946 .unwrap_basic();
7947 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
7948 }
7949 Operator::F32ConvertI32S | Operator::F32ConvertI64S => {
7950 let (v, i) = self.state.pop1_extra()?;
7951 let v = self.apply_pending_canonicalization(v, i)?;
7952 let v = v.into_int_value();
7953 let res = err!(self.builder.build_signed_int_to_float(
7954 v,
7955 self.intrinsics.f32_ty,
7956 ""
7957 ));
7958 self.state.push1(res);
7959 }
7960 Operator::F64ConvertI32S | Operator::F64ConvertI64S => {
7961 let (v, i) = self.state.pop1_extra()?;
7962 let v = self.apply_pending_canonicalization(v, i)?;
7963 let v = v.into_int_value();
7964 let res = err!(self.builder.build_signed_int_to_float(
7965 v,
7966 self.intrinsics.f64_ty,
7967 ""
7968 ));
7969 self.state.push1(res);
7970 }
7971 Operator::F32ConvertI32U | Operator::F32ConvertI64U => {
7972 let (v, i) = self.state.pop1_extra()?;
7973 let v = self.apply_pending_canonicalization(v, i)?;
7974 let v = v.into_int_value();
7975 let res = err!(self.builder.build_unsigned_int_to_float(
7976 v,
7977 self.intrinsics.f32_ty,
7978 ""
7979 ));
7980 self.state.push1(res);
7981 }
7982 Operator::F64ConvertI32U | Operator::F64ConvertI64U => {
7983 let (v, i) = self.state.pop1_extra()?;
7984 let v = self.apply_pending_canonicalization(v, i)?;
7985 let v = v.into_int_value();
7986 let res = err!(self.builder.build_unsigned_int_to_float(
7987 v,
7988 self.intrinsics.f64_ty,
7989 ""
7990 ));
7991 self.state.push1(res);
7992 }
7993 Operator::F32x4ConvertI32x4S => {
7994 let v = self.state.pop1()?;
7995 let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
7996 .into_vector_value();
7997 let res = err!(self.builder.build_signed_int_to_float(
7998 v,
7999 self.intrinsics.f32x4_ty,
8000 ""
8001 ));
8002 let res = err!(
8003 self.builder
8004 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8005 );
8006 self.state.push1(res);
8007 }
8008 Operator::F32x4ConvertI32x4U => {
8009 let v = self.state.pop1()?;
8010 let v = err!(self.builder.build_bit_cast(v, self.intrinsics.i32x4_ty, ""))
8011 .into_vector_value();
8012 let res = err!(self.builder.build_unsigned_int_to_float(
8013 v,
8014 self.intrinsics.f32x4_ty,
8015 ""
8016 ));
8017 let res = err!(
8018 self.builder
8019 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8020 );
8021 self.state.push1(res);
8022 }
8023 Operator::F64x2ConvertLowI32x4S | Operator::F64x2ConvertLowI32x4U => {
8024 let extend = match op {
8025 Operator::F64x2ConvertLowI32x4U => {
8026 |s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i64x2_ty, "")
8027 }
8028 Operator::F64x2ConvertLowI32x4S => {
8029 |s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i64x2_ty, "")
8030 }
8031 _ => unreachable!("Unhandled inner case"),
8032 };
8033 let (v, i) = self.state.pop1_extra()?;
8034 let (v, _) = self.v128_into_i32x4(v, i)?;
8035 let low = err!(self.builder.build_shuffle_vector(
8036 v,
8037 v.get_type().get_undef(),
8038 VectorType::const_vector(&[
8039 self.intrinsics.i32_consts[0],
8040 self.intrinsics.i32_consts[1],
8041 ]),
8042 "",
8043 ));
8044 let res = err!(extend(self, low));
8045 let res = err!(self.builder.build_signed_int_to_float(
8046 res,
8047 self.intrinsics.f64x2_ty,
8048 ""
8049 ));
8050 let res = err!(
8051 self.builder
8052 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8053 );
8054 self.state.push1(res);
8055 }
8056 Operator::F64x2PromoteLowF32x4 => {
8057 let (v, i) = self.state.pop1_extra()?;
8058 let (v, _) = self.v128_into_f32x4(v, i)?;
8059 let low = err!(self.builder.build_shuffle_vector(
8060 v,
8061 v.get_type().get_undef(),
8062 VectorType::const_vector(&[
8063 self.intrinsics.i32_consts[0],
8064 self.intrinsics.i32_consts[1],
8065 ]),
8066 "",
8067 ));
8068 let res = err!(
8069 self.builder
8070 .build_float_ext(low, self.intrinsics.f64x2_ty, "")
8071 );
8072 let res = err!(
8073 self.builder
8074 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8075 );
8076 self.state.push1_extra(res, ExtraInfo::pending_f64_nan());
8077 }
8078 Operator::F32x4DemoteF64x2Zero => {
8079 let (v, i) = self.state.pop1_extra()?;
8080 let (v, _) = self.v128_into_f64x2(v, i)?;
8081 let f32x2_ty = self.intrinsics.f32_ty.vec_type(2);
8082 let res = err!(self.builder.build_float_trunc(v, f32x2_ty, ""));
8083 let zeros = f32x2_ty.const_zero();
8084 let res = err!(self.builder.build_shuffle_vector(
8085 res,
8086 zeros,
8087 VectorType::const_vector(&[
8088 self.intrinsics.i32_consts[0],
8089 self.intrinsics.i32_consts[1],
8090 self.intrinsics.i32_consts[2],
8091 self.intrinsics.i32_consts[3],
8092 ]),
8093 "",
8094 ));
8095 let res = err!(
8096 self.builder
8097 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8098 );
8099 self.state.push1_extra(res, ExtraInfo::pending_f32_nan());
8100 }
8101 Operator::I32ReinterpretF32 => {
8126 let (v, i) = self.state.pop1_extra()?;
8127 let v = self.apply_pending_canonicalization(v, i)?;
8128 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i32_ty, ""));
8129 self.state.push1_extra(ret, ExtraInfo::arithmetic_f32());
8130 }
8131 Operator::I64ReinterpretF64 => {
8132 let (v, i) = self.state.pop1_extra()?;
8133 let v = self.apply_pending_canonicalization(v, i)?;
8134 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.i64_ty, ""));
8135 self.state.push1_extra(ret, ExtraInfo::arithmetic_f64());
8136 }
8137 Operator::F32ReinterpretI32 => {
8138 let (v, i) = self.state.pop1_extra()?;
8139 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f32_ty, ""));
8140 self.state.push1_extra(ret, i);
8141 }
8142 Operator::F64ReinterpretI64 => {
8143 let (v, i) = self.state.pop1_extra()?;
8144 let ret = err!(self.builder.build_bit_cast(v, self.intrinsics.f64_ty, ""));
8145 self.state.push1_extra(ret, i);
8146 }
8147
8148 Operator::I32Extend8S => {
8153 let value = self.state.pop1()?.into_int_value();
8154 let narrow_value = err!(self.builder.build_int_truncate(
8155 value,
8156 self.intrinsics.i8_ty,
8157 ""
8158 ));
8159 let extended_value = err!(self.builder.build_int_s_extend(
8160 narrow_value,
8161 self.intrinsics.i32_ty,
8162 ""
8163 ));
8164 self.state.push1(extended_value);
8165 }
8166 Operator::I32Extend16S => {
8167 let value = self.state.pop1()?.into_int_value();
8168 let narrow_value = err!(self.builder.build_int_truncate(
8169 value,
8170 self.intrinsics.i16_ty,
8171 ""
8172 ));
8173 let extended_value = err!(self.builder.build_int_s_extend(
8174 narrow_value,
8175 self.intrinsics.i32_ty,
8176 ""
8177 ));
8178 self.state.push1(extended_value);
8179 }
8180 Operator::I64Extend8S => {
8181 let value = self.state.pop1()?.into_int_value();
8182 let narrow_value = err!(self.builder.build_int_truncate(
8183 value,
8184 self.intrinsics.i8_ty,
8185 ""
8186 ));
8187 let extended_value = err!(self.builder.build_int_s_extend(
8188 narrow_value,
8189 self.intrinsics.i64_ty,
8190 ""
8191 ));
8192 self.state.push1(extended_value);
8193 }
8194 Operator::I64Extend16S => {
8195 let value = self.state.pop1()?.into_int_value();
8196 let narrow_value = err!(self.builder.build_int_truncate(
8197 value,
8198 self.intrinsics.i16_ty,
8199 ""
8200 ));
8201 let extended_value = err!(self.builder.build_int_s_extend(
8202 narrow_value,
8203 self.intrinsics.i64_ty,
8204 ""
8205 ));
8206 self.state.push1(extended_value);
8207 }
8208 Operator::I64Extend32S => {
8209 let value = self.state.pop1()?.into_int_value();
8210 let narrow_value = err!(self.builder.build_int_truncate(
8211 value,
8212 self.intrinsics.i32_ty,
8213 ""
8214 ));
8215 let extended_value = err!(self.builder.build_int_s_extend(
8216 narrow_value,
8217 self.intrinsics.i64_ty,
8218 ""
8219 ));
8220 self.state.push1(extended_value);
8221 }
8222
8223 Operator::I32Load { ref memarg } => {
8228 let offset = self.state.pop1()?.into_int_value();
8229 let memory_index = MemoryIndex::from_u32(0);
8230 let effective_address = self.resolve_memory_ptr(
8231 memory_index,
8232 memarg,
8233 self.intrinsics.ptr_ty,
8234 offset,
8235 4,
8236 )?;
8237 let result = err!(self.builder.build_load(
8238 self.intrinsics.i32_ty,
8239 effective_address,
8240 ""
8241 ));
8242 self.annotate_user_memaccess(
8243 memory_index,
8244 memarg,
8245 1,
8246 result.as_instruction_value().unwrap(),
8247 )?;
8248 self.state.push1(result);
8249 }
8250 Operator::I64Load { ref memarg } => {
8251 let offset = self.state.pop1()?.into_int_value();
8252 let memory_index = MemoryIndex::from_u32(0);
8253 let effective_address = self.resolve_memory_ptr(
8254 memory_index,
8255 memarg,
8256 self.intrinsics.ptr_ty,
8257 offset,
8258 8,
8259 )?;
8260 let result = err!(self.builder.build_load(
8261 self.intrinsics.i64_ty,
8262 effective_address,
8263 ""
8264 ));
8265 self.annotate_user_memaccess(
8266 memory_index,
8267 memarg,
8268 1,
8269 result.as_instruction_value().unwrap(),
8270 )?;
8271 self.state.push1(result);
8272 }
8273 Operator::F32Load { ref memarg } => {
8274 let offset = self.state.pop1()?.into_int_value();
8275 let memory_index = MemoryIndex::from_u32(0);
8276 let effective_address = self.resolve_memory_ptr(
8277 memory_index,
8278 memarg,
8279 self.intrinsics.ptr_ty,
8280 offset,
8281 4,
8282 )?;
8283 let result = err!(self.builder.build_load(
8284 self.intrinsics.f32_ty,
8285 effective_address,
8286 ""
8287 ));
8288 self.annotate_user_memaccess(
8289 memory_index,
8290 memarg,
8291 1,
8292 result.as_instruction_value().unwrap(),
8293 )?;
8294 self.state.push1(result);
8295 }
8296 Operator::F64Load { ref memarg } => {
8297 let offset = self.state.pop1()?.into_int_value();
8298 let memory_index = MemoryIndex::from_u32(0);
8299 let effective_address = self.resolve_memory_ptr(
8300 memory_index,
8301 memarg,
8302 self.intrinsics.ptr_ty,
8303 offset,
8304 8,
8305 )?;
8306 let result = err!(self.builder.build_load(
8307 self.intrinsics.f64_ty,
8308 effective_address,
8309 ""
8310 ));
8311 self.annotate_user_memaccess(
8312 memory_index,
8313 memarg,
8314 1,
8315 result.as_instruction_value().unwrap(),
8316 )?;
8317 self.state.push1(result);
8318 }
8319 Operator::V128Load { ref memarg } => {
8320 let offset = self.state.pop1()?.into_int_value();
8321 let memory_index = MemoryIndex::from_u32(0);
8322 let effective_address = self.resolve_memory_ptr(
8323 memory_index,
8324 memarg,
8325 self.intrinsics.ptr_ty,
8326 offset,
8327 16,
8328 )?;
8329 let result = err!(self.builder.build_load(
8330 self.intrinsics.i128_ty,
8331 effective_address,
8332 ""
8333 ));
8334 self.annotate_user_memaccess(
8335 memory_index,
8336 memarg,
8337 1,
8338 result.as_instruction_value().unwrap(),
8339 )?;
8340 self.state.push1(result);
8341 }
8342 Operator::V128Load8Lane { ref memarg, lane } => {
8343 let (v, i) = self.state.pop1_extra()?;
8344 let (v, _i) = self.v128_into_i8x16(v, i)?;
8345 let offset = self.state.pop1()?.into_int_value();
8346 let memory_index = MemoryIndex::from_u32(memarg.memory);
8347 let effective_address = self.resolve_memory_ptr(
8348 memory_index,
8349 memarg,
8350 self.intrinsics.ptr_ty,
8351 offset,
8352 1,
8353 )?;
8354 let element = err!(self.builder.build_load(
8355 self.intrinsics.i8_ty,
8356 effective_address,
8357 ""
8358 ));
8359 self.annotate_user_memaccess(
8360 memory_index,
8361 memarg,
8362 1,
8363 element.as_instruction_value().unwrap(),
8364 )?;
8365 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8366 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8367 let res = err!(
8368 self.builder
8369 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8370 );
8371 self.state.push1(res);
8372 }
8373 Operator::V128Load16Lane { ref memarg, lane } => {
8374 let (v, i) = self.state.pop1_extra()?;
8375 let (v, i) = self.v128_into_i16x8(v, i)?;
8376 let offset = self.state.pop1()?.into_int_value();
8377 let memory_index = MemoryIndex::from_u32(memarg.memory);
8378 let effective_address = self.resolve_memory_ptr(
8379 memory_index,
8380 memarg,
8381 self.intrinsics.ptr_ty,
8382 offset,
8383 2,
8384 )?;
8385 let element = err!(self.builder.build_load(
8386 self.intrinsics.i16_ty,
8387 effective_address,
8388 ""
8389 ));
8390 self.annotate_user_memaccess(
8391 memory_index,
8392 memarg,
8393 1,
8394 element.as_instruction_value().unwrap(),
8395 )?;
8396 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8397 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8398 let res = err!(
8399 self.builder
8400 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8401 );
8402 self.state.push1_extra(res, i);
8403 }
8404 Operator::V128Load32Lane { ref memarg, lane } => {
8405 let (v, i) = self.state.pop1_extra()?;
8406 let (v, i) = self.v128_into_i32x4(v, i)?;
8407 let offset = self.state.pop1()?.into_int_value();
8408 let memory_index = MemoryIndex::from_u32(memarg.memory);
8409 let effective_address = self.resolve_memory_ptr(
8410 memory_index,
8411 memarg,
8412 self.intrinsics.ptr_ty,
8413 offset,
8414 4,
8415 )?;
8416 let element = err!(self.builder.build_load(
8417 self.intrinsics.i32_ty,
8418 effective_address,
8419 ""
8420 ));
8421 self.annotate_user_memaccess(
8422 memory_index,
8423 memarg,
8424 1,
8425 element.as_instruction_value().unwrap(),
8426 )?;
8427 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8428 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8429 let res = err!(
8430 self.builder
8431 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8432 );
8433 self.state.push1_extra(res, i);
8434 }
8435 Operator::V128Load64Lane { ref memarg, lane } => {
8436 let (v, i) = self.state.pop1_extra()?;
8437 let (v, i) = self.v128_into_i64x2(v, i)?;
8438 let offset = self.state.pop1()?.into_int_value();
8439 let memory_index = MemoryIndex::from_u32(memarg.memory);
8440 let effective_address = self.resolve_memory_ptr(
8441 memory_index,
8442 memarg,
8443 self.intrinsics.ptr_ty,
8444 offset,
8445 8,
8446 )?;
8447 let element = err!(self.builder.build_load(
8448 self.intrinsics.i64_ty,
8449 effective_address,
8450 ""
8451 ));
8452 self.annotate_user_memaccess(
8453 memory_index,
8454 memarg,
8455 1,
8456 element.as_instruction_value().unwrap(),
8457 )?;
8458 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8459 let res = err!(self.builder.build_insert_element(v, element, idx, ""));
8460 let res = err!(
8461 self.builder
8462 .build_bit_cast(res, self.intrinsics.i128_ty, "")
8463 );
8464 self.state.push1_extra(res, i);
8465 }
8466
8467 Operator::I32Store { ref memarg } => {
8468 let value = self.state.pop1()?;
8469 let offset = self.state.pop1()?.into_int_value();
8470 let memory_index = MemoryIndex::from_u32(0);
8471 let effective_address = self.resolve_memory_ptr(
8472 memory_index,
8473 memarg,
8474 self.intrinsics.ptr_ty,
8475 offset,
8476 4,
8477 )?;
8478 let dead_load = err!(self.builder.build_load(
8479 self.intrinsics.i32_ty,
8480 effective_address,
8481 ""
8482 ));
8483 self.annotate_user_memaccess(
8484 memory_index,
8485 memarg,
8486 1,
8487 dead_load.as_instruction_value().unwrap(),
8488 )?;
8489 let store = err!(self.builder.build_store(effective_address, value));
8490 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8491 }
8492 Operator::I64Store { ref memarg } => {
8493 let value = self.state.pop1()?;
8494 let offset = self.state.pop1()?.into_int_value();
8495 let memory_index = MemoryIndex::from_u32(0);
8496 let effective_address = self.resolve_memory_ptr(
8497 memory_index,
8498 memarg,
8499 self.intrinsics.ptr_ty,
8500 offset,
8501 8,
8502 )?;
8503 let dead_load = err!(self.builder.build_load(
8504 self.intrinsics.i64_ty,
8505 effective_address,
8506 ""
8507 ));
8508 self.annotate_user_memaccess(
8509 memory_index,
8510 memarg,
8511 1,
8512 dead_load.as_instruction_value().unwrap(),
8513 )?;
8514 let store = err!(self.builder.build_store(effective_address, value));
8515 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8516 }
8517 Operator::F32Store { ref memarg } => {
8518 let (v, i) = self.state.pop1_extra()?;
8519 let v = self.apply_pending_canonicalization(v, i)?;
8520 let offset = self.state.pop1()?.into_int_value();
8521 let memory_index = MemoryIndex::from_u32(0);
8522 let effective_address = self.resolve_memory_ptr(
8523 memory_index,
8524 memarg,
8525 self.intrinsics.ptr_ty,
8526 offset,
8527 4,
8528 )?;
8529 let dead_load = err!(self.builder.build_load(
8530 self.intrinsics.f32_ty,
8531 effective_address,
8532 ""
8533 ));
8534 self.annotate_user_memaccess(
8535 memory_index,
8536 memarg,
8537 1,
8538 dead_load.as_instruction_value().unwrap(),
8539 )?;
8540 let store = err!(self.builder.build_store(effective_address, v));
8541 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8542 }
8543 Operator::F64Store { ref memarg } => {
8544 let (v, i) = self.state.pop1_extra()?;
8545 let v = self.apply_pending_canonicalization(v, i)?;
8546 let offset = self.state.pop1()?.into_int_value();
8547 let memory_index = MemoryIndex::from_u32(0);
8548 let effective_address = self.resolve_memory_ptr(
8549 memory_index,
8550 memarg,
8551 self.intrinsics.ptr_ty,
8552 offset,
8553 8,
8554 )?;
8555 let dead_load = err!(self.builder.build_load(
8556 self.intrinsics.f64_ty,
8557 effective_address,
8558 ""
8559 ));
8560 self.annotate_user_memaccess(
8561 memory_index,
8562 memarg,
8563 1,
8564 dead_load.as_instruction_value().unwrap(),
8565 )?;
8566 let store = err!(self.builder.build_store(effective_address, v));
8567 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8568 }
8569 Operator::V128Store { ref memarg } => {
8570 let (v, i) = self.state.pop1_extra()?;
8571 let v = self.apply_pending_canonicalization(v, i)?;
8572 let offset = self.state.pop1()?.into_int_value();
8573 let memory_index = MemoryIndex::from_u32(0);
8574 let effective_address = self.resolve_memory_ptr(
8575 memory_index,
8576 memarg,
8577 self.intrinsics.ptr_ty,
8578 offset,
8579 16,
8580 )?;
8581 let dead_load = err!(self.builder.build_load(
8582 self.intrinsics.i128_ty,
8583 effective_address,
8584 ""
8585 ));
8586 self.annotate_user_memaccess(
8587 memory_index,
8588 memarg,
8589 1,
8590 dead_load.as_instruction_value().unwrap(),
8591 )?;
8592 let store = err!(self.builder.build_store(effective_address, v));
8593 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8594 }
8595 Operator::V128Store8Lane { ref memarg, lane } => {
8596 let (v, i) = self.state.pop1_extra()?;
8597 let (v, _i) = self.v128_into_i8x16(v, i)?;
8598 let offset = self.state.pop1()?.into_int_value();
8599 let memory_index = MemoryIndex::from_u32(memarg.memory);
8600
8601 let effective_address = self.resolve_memory_ptr(
8602 memory_index,
8603 memarg,
8604 self.intrinsics.ptr_ty,
8605 offset,
8606 1,
8607 )?;
8608 let dead_load = err!(self.builder.build_load(
8609 self.intrinsics.i8_ty,
8610 effective_address,
8611 ""
8612 ));
8613 self.annotate_user_memaccess(
8614 memory_index,
8615 memarg,
8616 1,
8617 dead_load.as_instruction_value().unwrap(),
8618 )?;
8619 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8620 let val = err!(self.builder.build_extract_element(v, idx, ""));
8621 let store = err!(self.builder.build_store(effective_address, val));
8622 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8623 }
8624 Operator::V128Store16Lane { ref memarg, lane } => {
8625 let (v, i) = self.state.pop1_extra()?;
8626 let (v, _i) = self.v128_into_i16x8(v, i)?;
8627 let offset = self.state.pop1()?.into_int_value();
8628 let memory_index = MemoryIndex::from_u32(memarg.memory);
8629
8630 let effective_address = self.resolve_memory_ptr(
8631 memory_index,
8632 memarg,
8633 self.intrinsics.ptr_ty,
8634 offset,
8635 2,
8636 )?;
8637 let dead_load = err!(self.builder.build_load(
8638 self.intrinsics.i16_ty,
8639 effective_address,
8640 ""
8641 ));
8642 self.annotate_user_memaccess(
8643 memory_index,
8644 memarg,
8645 1,
8646 dead_load.as_instruction_value().unwrap(),
8647 )?;
8648 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8649 let val = err!(self.builder.build_extract_element(v, idx, ""));
8650 let store = err!(self.builder.build_store(effective_address, val));
8651 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8652 }
8653 Operator::V128Store32Lane { ref memarg, lane } => {
8654 let (v, i) = self.state.pop1_extra()?;
8655 let (v, _i) = self.v128_into_i32x4(v, i)?;
8656 let offset = self.state.pop1()?.into_int_value();
8657 let memory_index = MemoryIndex::from_u32(memarg.memory);
8658
8659 let effective_address = self.resolve_memory_ptr(
8660 memory_index,
8661 memarg,
8662 self.intrinsics.ptr_ty,
8663 offset,
8664 4,
8665 )?;
8666 let dead_load = err!(self.builder.build_load(
8667 self.intrinsics.i32_ty,
8668 effective_address,
8669 ""
8670 ));
8671 self.annotate_user_memaccess(
8672 memory_index,
8673 memarg,
8674 1,
8675 dead_load.as_instruction_value().unwrap(),
8676 )?;
8677 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8678 let val = err!(self.builder.build_extract_element(v, idx, ""));
8679 let store = err!(self.builder.build_store(effective_address, val));
8680 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8681 }
8682 Operator::V128Store64Lane { ref memarg, lane } => {
8683 let (v, i) = self.state.pop1_extra()?;
8684 let (v, _i) = self.v128_into_i64x2(v, i)?;
8685 let offset = self.state.pop1()?.into_int_value();
8686 let memory_index = MemoryIndex::from_u32(memarg.memory);
8687
8688 let effective_address = self.resolve_memory_ptr(
8689 memory_index,
8690 memarg,
8691 self.intrinsics.ptr_ty,
8692 offset,
8693 8,
8694 )?;
8695 let dead_load = err!(self.builder.build_load(
8696 self.intrinsics.i64_ty,
8697 effective_address,
8698 ""
8699 ));
8700 self.annotate_user_memaccess(
8701 memory_index,
8702 memarg,
8703 1,
8704 dead_load.as_instruction_value().unwrap(),
8705 )?;
8706 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
8707 let val = err!(self.builder.build_extract_element(v, idx, ""));
8708 let store = err!(self.builder.build_store(effective_address, val));
8709 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
8710 }
8711 Operator::I32Load8S { ref memarg } => {
8712 let offset = self.state.pop1()?.into_int_value();
8713 let memory_index = MemoryIndex::from_u32(0);
8714 let effective_address = self.resolve_memory_ptr(
8715 memory_index,
8716 memarg,
8717 self.intrinsics.ptr_ty,
8718 offset,
8719 1,
8720 )?;
8721 let narrow_result = err!(self.builder.build_load(
8722 self.intrinsics.i8_ty,
8723 effective_address,
8724 ""
8725 ));
8726 self.annotate_user_memaccess(
8727 memory_index,
8728 memarg,
8729 1,
8730 narrow_result.as_instruction_value().unwrap(),
8731 )?;
8732 let result = err!(self.builder.build_int_s_extend(
8733 narrow_result.into_int_value(),
8734 self.intrinsics.i32_ty,
8735 "",
8736 ));
8737 self.state.push1(result);
8738 }
8739 Operator::I32Load16S { ref memarg } => {
8740 let offset = self.state.pop1()?.into_int_value();
8741 let memory_index = MemoryIndex::from_u32(0);
8742 let effective_address = self.resolve_memory_ptr(
8743 memory_index,
8744 memarg,
8745 self.intrinsics.ptr_ty,
8746 offset,
8747 2,
8748 )?;
8749 let narrow_result = err!(self.builder.build_load(
8750 self.intrinsics.i16_ty,
8751 effective_address,
8752 ""
8753 ));
8754 self.annotate_user_memaccess(
8755 memory_index,
8756 memarg,
8757 1,
8758 narrow_result.as_instruction_value().unwrap(),
8759 )?;
8760 let result = err!(self.builder.build_int_s_extend(
8761 narrow_result.into_int_value(),
8762 self.intrinsics.i32_ty,
8763 "",
8764 ));
8765 self.state.push1(result);
8766 }
8767 Operator::I64Load8S { ref memarg } => {
8768 let offset = self.state.pop1()?.into_int_value();
8769 let memory_index = MemoryIndex::from_u32(0);
8770 let effective_address = self.resolve_memory_ptr(
8771 memory_index,
8772 memarg,
8773 self.intrinsics.ptr_ty,
8774 offset,
8775 1,
8776 )?;
8777 let narrow_result = err!(self.builder.build_load(
8778 self.intrinsics.i8_ty,
8779 effective_address,
8780 ""
8781 ))
8782 .into_int_value();
8783 self.annotate_user_memaccess(
8784 memory_index,
8785 memarg,
8786 1,
8787 narrow_result.as_instruction_value().unwrap(),
8788 )?;
8789 let result = err!(self.builder.build_int_s_extend(
8790 narrow_result,
8791 self.intrinsics.i64_ty,
8792 ""
8793 ));
8794 self.state.push1(result);
8795 }
8796 Operator::I64Load16S { ref memarg } => {
8797 let offset = self.state.pop1()?.into_int_value();
8798 let memory_index = MemoryIndex::from_u32(0);
8799 let effective_address = self.resolve_memory_ptr(
8800 memory_index,
8801 memarg,
8802 self.intrinsics.ptr_ty,
8803 offset,
8804 2,
8805 )?;
8806 let narrow_result = err!(self.builder.build_load(
8807 self.intrinsics.i16_ty,
8808 effective_address,
8809 ""
8810 ))
8811 .into_int_value();
8812 self.annotate_user_memaccess(
8813 memory_index,
8814 memarg,
8815 1,
8816 narrow_result.as_instruction_value().unwrap(),
8817 )?;
8818 let result = err!(self.builder.build_int_s_extend(
8819 narrow_result,
8820 self.intrinsics.i64_ty,
8821 ""
8822 ));
8823 self.state.push1(result);
8824 }
8825 Operator::I64Load32S { ref memarg } => {
8826 let offset = self.state.pop1()?.into_int_value();
8827 let memory_index = MemoryIndex::from_u32(0);
8828 let effective_address = self.resolve_memory_ptr(
8829 memory_index,
8830 memarg,
8831 self.intrinsics.ptr_ty,
8832 offset,
8833 4,
8834 )?;
8835 let narrow_result = err!(self.builder.build_load(
8836 self.intrinsics.i32_ty,
8837 effective_address,
8838 ""
8839 ));
8840 self.annotate_user_memaccess(
8841 memory_index,
8842 memarg,
8843 1,
8844 narrow_result.as_instruction_value().unwrap(),
8845 )?;
8846 let result = err!(self.builder.build_int_s_extend(
8847 narrow_result.into_int_value(),
8848 self.intrinsics.i64_ty,
8849 "",
8850 ));
8851 self.state.push1(result);
8852 }
8853
8854 Operator::I32Load8U { ref memarg } => {
8855 let offset = self.state.pop1()?.into_int_value();
8856 let memory_index = MemoryIndex::from_u32(0);
8857 let effective_address = self.resolve_memory_ptr(
8858 memory_index,
8859 memarg,
8860 self.intrinsics.ptr_ty,
8861 offset,
8862 1,
8863 )?;
8864 let narrow_result = err!(self.builder.build_load(
8865 self.intrinsics.i8_ty,
8866 effective_address,
8867 ""
8868 ));
8869 self.annotate_user_memaccess(
8870 memory_index,
8871 memarg,
8872 1,
8873 narrow_result.as_instruction_value().unwrap(),
8874 )?;
8875 let result = err!(self.builder.build_int_z_extend(
8876 narrow_result.into_int_value(),
8877 self.intrinsics.i32_ty,
8878 "",
8879 ));
8880 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8881 }
8882 Operator::I32Load16U { ref memarg } => {
8883 let offset = self.state.pop1()?.into_int_value();
8884 let memory_index = MemoryIndex::from_u32(0);
8885 let effective_address = self.resolve_memory_ptr(
8886 memory_index,
8887 memarg,
8888 self.intrinsics.ptr_ty,
8889 offset,
8890 2,
8891 )?;
8892 let narrow_result = err!(self.builder.build_load(
8893 self.intrinsics.i16_ty,
8894 effective_address,
8895 ""
8896 ));
8897 self.annotate_user_memaccess(
8898 memory_index,
8899 memarg,
8900 1,
8901 narrow_result.as_instruction_value().unwrap(),
8902 )?;
8903 let result = err!(self.builder.build_int_z_extend(
8904 narrow_result.into_int_value(),
8905 self.intrinsics.i32_ty,
8906 "",
8907 ));
8908 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
8909 }
8910 Operator::I64Load8U { ref memarg } => {
8911 let offset = self.state.pop1()?.into_int_value();
8912 let memory_index = MemoryIndex::from_u32(0);
8913 let effective_address = self.resolve_memory_ptr(
8914 memory_index,
8915 memarg,
8916 self.intrinsics.ptr_ty,
8917 offset,
8918 1,
8919 )?;
8920 let narrow_result = err!(self.builder.build_load(
8921 self.intrinsics.i8_ty,
8922 effective_address,
8923 ""
8924 ));
8925 self.annotate_user_memaccess(
8926 memory_index,
8927 memarg,
8928 1,
8929 narrow_result.as_instruction_value().unwrap(),
8930 )?;
8931 let result = err!(self.builder.build_int_z_extend(
8932 narrow_result.into_int_value(),
8933 self.intrinsics.i64_ty,
8934 "",
8935 ));
8936 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8937 }
8938 Operator::I64Load16U { ref memarg } => {
8939 let offset = self.state.pop1()?.into_int_value();
8940 let memory_index = MemoryIndex::from_u32(0);
8941 let effective_address = self.resolve_memory_ptr(
8942 memory_index,
8943 memarg,
8944 self.intrinsics.ptr_ty,
8945 offset,
8946 2,
8947 )?;
8948 let narrow_result = err!(self.builder.build_load(
8949 self.intrinsics.i16_ty,
8950 effective_address,
8951 ""
8952 ));
8953 self.annotate_user_memaccess(
8954 memory_index,
8955 memarg,
8956 1,
8957 narrow_result.as_instruction_value().unwrap(),
8958 )?;
8959 let result = err!(self.builder.build_int_z_extend(
8960 narrow_result.into_int_value(),
8961 self.intrinsics.i64_ty,
8962 "",
8963 ));
8964 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8965 }
8966 Operator::I64Load32U { ref memarg } => {
8967 let offset = self.state.pop1()?.into_int_value();
8968 let memory_index = MemoryIndex::from_u32(0);
8969 let effective_address = self.resolve_memory_ptr(
8970 memory_index,
8971 memarg,
8972 self.intrinsics.ptr_ty,
8973 offset,
8974 4,
8975 )?;
8976 let narrow_result = err!(self.builder.build_load(
8977 self.intrinsics.i32_ty,
8978 effective_address,
8979 ""
8980 ));
8981 self.annotate_user_memaccess(
8982 memory_index,
8983 memarg,
8984 1,
8985 narrow_result.as_instruction_value().unwrap(),
8986 )?;
8987 let result = err!(self.builder.build_int_z_extend(
8988 narrow_result.into_int_value(),
8989 self.intrinsics.i64_ty,
8990 "",
8991 ));
8992 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
8993 }
8994
8995 Operator::I32Store8 { ref memarg } | Operator::I64Store8 { ref memarg } => {
8996 let value = self.state.pop1()?.into_int_value();
8997 let offset = self.state.pop1()?.into_int_value();
8998 let memory_index = MemoryIndex::from_u32(0);
8999 let effective_address = self.resolve_memory_ptr(
9000 memory_index,
9001 memarg,
9002 self.intrinsics.ptr_ty,
9003 offset,
9004 1,
9005 )?;
9006 let dead_load = err!(self.builder.build_load(
9007 self.intrinsics.i8_ty,
9008 effective_address,
9009 ""
9010 ));
9011 self.annotate_user_memaccess(
9012 memory_index,
9013 memarg,
9014 1,
9015 dead_load.as_instruction_value().unwrap(),
9016 )?;
9017 let narrow_value = err!(self.builder.build_int_truncate(
9018 value,
9019 self.intrinsics.i8_ty,
9020 ""
9021 ));
9022 let store = err!(self.builder.build_store(effective_address, narrow_value));
9023 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9024 }
9025 Operator::I32Store16 { ref memarg } | Operator::I64Store16 { ref memarg } => {
9026 let value = self.state.pop1()?.into_int_value();
9027 let offset = self.state.pop1()?.into_int_value();
9028 let memory_index = MemoryIndex::from_u32(0);
9029 let effective_address = self.resolve_memory_ptr(
9030 memory_index,
9031 memarg,
9032 self.intrinsics.ptr_ty,
9033 offset,
9034 2,
9035 )?;
9036 let dead_load = err!(self.builder.build_load(
9037 self.intrinsics.i16_ty,
9038 effective_address,
9039 ""
9040 ));
9041 self.annotate_user_memaccess(
9042 memory_index,
9043 memarg,
9044 1,
9045 dead_load.as_instruction_value().unwrap(),
9046 )?;
9047 let narrow_value = err!(self.builder.build_int_truncate(
9048 value,
9049 self.intrinsics.i16_ty,
9050 ""
9051 ));
9052 let store = err!(self.builder.build_store(effective_address, narrow_value));
9053 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9054 }
9055 Operator::I64Store32 { ref memarg } => {
9056 let value = self.state.pop1()?.into_int_value();
9057 let offset = self.state.pop1()?.into_int_value();
9058 let memory_index = MemoryIndex::from_u32(0);
9059 let effective_address = self.resolve_memory_ptr(
9060 memory_index,
9061 memarg,
9062 self.intrinsics.ptr_ty,
9063 offset,
9064 4,
9065 )?;
9066 let dead_load = err!(self.builder.build_load(
9067 self.intrinsics.i32_ty,
9068 effective_address,
9069 ""
9070 ));
9071 self.annotate_user_memaccess(
9072 memory_index,
9073 memarg,
9074 1,
9075 dead_load.as_instruction_value().unwrap(),
9076 )?;
9077 let narrow_value = err!(self.builder.build_int_truncate(
9078 value,
9079 self.intrinsics.i32_ty,
9080 ""
9081 ));
9082 let store = err!(self.builder.build_store(effective_address, narrow_value));
9083 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
9084 }
9085 Operator::I8x16Neg => {
9086 let (v, i) = self.state.pop1_extra()?;
9087 let (v, _) = self.v128_into_i8x16(v, i)?;
9088 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9089 let res = err!(
9090 self.builder
9091 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9092 );
9093 self.state.push1(res);
9094 }
9095 Operator::I16x8Neg => {
9096 let (v, i) = self.state.pop1_extra()?;
9097 let (v, _) = self.v128_into_i16x8(v, i)?;
9098 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9099 let res = err!(
9100 self.builder
9101 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9102 );
9103 self.state.push1(res);
9104 }
9105 Operator::I32x4Neg => {
9106 let (v, i) = self.state.pop1_extra()?;
9107 let (v, _) = self.v128_into_i32x4(v, i)?;
9108 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9109 let res = err!(
9110 self.builder
9111 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9112 );
9113 self.state.push1(res);
9114 }
9115 Operator::I64x2Neg => {
9116 let (v, i) = self.state.pop1_extra()?;
9117 let (v, _) = self.v128_into_i64x2(v, i)?;
9118 let res = err!(self.builder.build_int_sub(v.get_type().const_zero(), v, ""));
9119 let res = err!(
9120 self.builder
9121 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9122 );
9123 self.state.push1(res);
9124 }
9125 Operator::V128Not => {
9126 let (v, i) = self.state.pop1_extra()?;
9127 let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9128 let res = err!(self.builder.build_not(v, ""));
9129 self.state.push1(res);
9130 }
9131 Operator::V128AnyTrue => {
9132 let v = self.state.pop1()?.into_int_value();
9135 let res = err!(self.builder.build_int_compare(
9136 IntPredicate::NE,
9137 v,
9138 v.get_type().const_zero(),
9139 "",
9140 ));
9141 let res = err!(
9142 self.builder
9143 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9144 );
9145 self.state.push1_extra(
9146 res,
9147 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9148 );
9149 }
9150 Operator::I8x16AllTrue
9151 | Operator::I16x8AllTrue
9152 | Operator::I32x4AllTrue
9153 | Operator::I64x2AllTrue => {
9154 let vec_ty = match op {
9155 Operator::I8x16AllTrue => self.intrinsics.i8x16_ty,
9156 Operator::I16x8AllTrue => self.intrinsics.i16x8_ty,
9157 Operator::I32x4AllTrue => self.intrinsics.i32x4_ty,
9158 Operator::I64x2AllTrue => self.intrinsics.i64x2_ty,
9159 _ => unreachable!(),
9160 };
9161 let (v, i) = self.state.pop1_extra()?;
9162 let v = self.apply_pending_canonicalization(v, i)?.into_int_value();
9163 let lane_int_ty = self.context.custom_width_int_type(vec_ty.get_size());
9164 let vec = err!(self.builder.build_bit_cast(v, vec_ty, "vec")).into_vector_value();
9165 let mask = err!(self.builder.build_int_compare(
9166 IntPredicate::NE,
9167 vec,
9168 vec_ty.const_zero(),
9169 "mask",
9170 ));
9171 let cmask =
9172 err!(self.builder.build_bit_cast(mask, lane_int_ty, "cmask")).into_int_value();
9173 let res = err!(self.builder.build_int_compare(
9174 IntPredicate::EQ,
9175 cmask,
9176 lane_int_ty.const_int(u64::MAX, true),
9177 "",
9178 ));
9179 let res = err!(
9180 self.builder
9181 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9182 );
9183 self.state.push1_extra(
9184 res,
9185 (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
9186 );
9187 }
9188 Operator::I8x16ExtractLaneS { lane } => {
9189 let (v, i) = self.state.pop1_extra()?;
9190 let (v, _) = self.v128_into_i8x16(v, i)?;
9191 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9192 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9193 let res = err!(
9194 self.builder
9195 .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9196 );
9197 self.state.push1(res);
9198 }
9199 Operator::I8x16ExtractLaneU { lane } => {
9200 let (v, i) = self.state.pop1_extra()?;
9201 let (v, _) = self.v128_into_i8x16(v, i)?;
9202 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9203 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9204 let res = err!(
9205 self.builder
9206 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9207 );
9208 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9209 }
9210 Operator::I16x8ExtractLaneS { lane } => {
9211 let (v, i) = self.state.pop1_extra()?;
9212 let (v, _) = self.v128_into_i16x8(v, i)?;
9213 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9214 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9215 let res = err!(
9216 self.builder
9217 .build_int_s_extend(res, self.intrinsics.i32_ty, "")
9218 );
9219 self.state.push1(res);
9220 }
9221 Operator::I16x8ExtractLaneU { lane } => {
9222 let (v, i) = self.state.pop1_extra()?;
9223 let (v, _) = self.v128_into_i16x8(v, i)?;
9224 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9225 let res = err!(self.builder.build_extract_element(v, idx, "")).into_int_value();
9226 let res = err!(
9227 self.builder
9228 .build_int_z_extend(res, self.intrinsics.i32_ty, "")
9229 );
9230 self.state.push1_extra(res, ExtraInfo::arithmetic_f32());
9231 }
9232 Operator::I32x4ExtractLane { lane } => {
9233 let (v, i) = self.state.pop1_extra()?;
9234 let (v, i) = self.v128_into_i32x4(v, i)?;
9235 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9236 let res = err!(self.builder.build_extract_element(v, idx, ""));
9237 self.state.push1_extra(res, i);
9238 }
9239 Operator::I64x2ExtractLane { lane } => {
9240 let (v, i) = self.state.pop1_extra()?;
9241 let (v, i) = self.v128_into_i64x2(v, i)?;
9242 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9243 let res = err!(self.builder.build_extract_element(v, idx, ""));
9244 self.state.push1_extra(res, i);
9245 }
9246 Operator::F32x4ExtractLane { lane } => {
9247 let (v, i) = self.state.pop1_extra()?;
9248 let (v, i) = self.v128_into_f32x4(v, i)?;
9249 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9250 let res = err!(self.builder.build_extract_element(v, idx, ""));
9251 self.state.push1_extra(res, i);
9252 }
9253 Operator::F64x2ExtractLane { lane } => {
9254 let (v, i) = self.state.pop1_extra()?;
9255 let (v, i) = self.v128_into_f64x2(v, i)?;
9256 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9257 let res = err!(self.builder.build_extract_element(v, idx, ""));
9258 self.state.push1_extra(res, i);
9259 }
9260 Operator::I8x16ReplaceLane { lane } => {
9261 let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9262 let (v1, _) = self.v128_into_i8x16(v1, i1)?;
9263 let v2 = v2.into_int_value();
9264 let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i8_ty, ""));
9265 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9266 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9267 let res = err!(
9268 self.builder
9269 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9270 );
9271 self.state.push1(res);
9272 }
9273 Operator::I16x8ReplaceLane { lane } => {
9274 let ((v1, i1), (v2, _)) = self.state.pop2_extra()?;
9275 let (v1, _) = self.v128_into_i16x8(v1, i1)?;
9276 let v2 = v2.into_int_value();
9277 let v2 = err!(self.builder.build_int_cast(v2, self.intrinsics.i16_ty, ""));
9278 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9279 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9280 let res = err!(
9281 self.builder
9282 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9283 );
9284 self.state.push1(res);
9285 }
9286 Operator::I32x4ReplaceLane { lane } => {
9287 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9288 let (v1, i1) = self.v128_into_i32x4(v1, i1)?;
9289 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9290 let v2 = v2.into_int_value();
9291 let i2 = i2.strip_pending();
9292 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9293 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9294 let res = err!(
9295 self.builder
9296 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9297 );
9298 self.state
9299 .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f32())?);
9300 }
9301 Operator::I64x2ReplaceLane { lane } => {
9302 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9303 let (v1, i1) = self.v128_into_i64x2(v1, i1)?;
9304 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9305 let v2 = v2.into_int_value();
9306 let i2 = i2.strip_pending();
9307 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9308 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9309 let res = err!(
9310 self.builder
9311 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9312 );
9313 self.state
9314 .push1_extra(res, ((i1 & i2)? & ExtraInfo::arithmetic_f64())?);
9315 }
9316 Operator::F32x4ReplaceLane { lane } => {
9317 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9318 let (v1, i1) = self.v128_into_f32x4(v1, i1)?;
9319 let push_pending_f32_nan_to_result =
9320 i1.has_pending_f32_nan() && i2.has_pending_f32_nan();
9321 let (v1, v2) = if !push_pending_f32_nan_to_result {
9322 (
9323 self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9324 .into_vector_value(),
9325 self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9326 .into_float_value(),
9327 )
9328 } else {
9329 (v1, v2.into_float_value())
9330 };
9331 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9332 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9333 let res = err!(
9334 self.builder
9335 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9336 );
9337 let info = if push_pending_f32_nan_to_result {
9338 ExtraInfo::pending_f32_nan()
9339 } else {
9340 (i1.strip_pending() & i2.strip_pending())?
9341 };
9342 self.state.push1_extra(res, info);
9343 }
9344 Operator::F64x2ReplaceLane { lane } => {
9345 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9346 let (v1, i1) = self.v128_into_f64x2(v1, i1)?;
9347 let push_pending_f64_nan_to_result =
9348 i1.has_pending_f64_nan() && i2.has_pending_f64_nan();
9349 let (v1, v2) = if !push_pending_f64_nan_to_result {
9350 (
9351 self.apply_pending_canonicalization(v1.as_basic_value_enum(), i1)?
9352 .into_vector_value(),
9353 self.apply_pending_canonicalization(v2.as_basic_value_enum(), i2)?
9354 .into_float_value(),
9355 )
9356 } else {
9357 (v1, v2.into_float_value())
9358 };
9359 let idx = self.intrinsics.i32_ty.const_int(lane.into(), false);
9360 let res = err!(self.builder.build_insert_element(v1, v2, idx, ""));
9361 let res = err!(
9362 self.builder
9363 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9364 );
9365 let info = if push_pending_f64_nan_to_result {
9366 ExtraInfo::pending_f64_nan()
9367 } else {
9368 (i1.strip_pending() & i2.strip_pending())?
9369 };
9370 self.state.push1_extra(res, info);
9371 }
9372 Operator::I8x16Swizzle => {
9373 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9374 let v1 = self.apply_pending_canonicalization(v1, i1)?;
9375 let v1 = err!(
9376 self.builder
9377 .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9378 )
9379 .into_vector_value();
9380 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9381 let v2 = err!(
9382 self.builder
9383 .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9384 )
9385 .into_vector_value();
9386 let lanes = self.intrinsics.i8_ty.const_int(16, false);
9387 let lanes =
9388 self.splat_vector(lanes.as_basic_value_enum(), self.intrinsics.i8x16_ty)?;
9389 let mut res = self.intrinsics.i8x16_ty.get_undef();
9390 let idx_out_of_range = err!(self.builder.build_int_compare(
9391 IntPredicate::UGE,
9392 v2,
9393 lanes,
9394 "idx_out_of_range",
9395 ));
9396 let idx_clamped = err!(self.builder.build_select(
9397 idx_out_of_range,
9398 self.intrinsics.i8x16_ty.const_zero(),
9399 v2,
9400 "idx_clamped",
9401 ))
9402 .into_vector_value();
9403 for i in 0..16 {
9404 let idx = err!(self.builder.build_extract_element(
9405 idx_clamped,
9406 self.intrinsics.i32_ty.const_int(i, false),
9407 "idx",
9408 ))
9409 .into_int_value();
9410 let replace_with_zero = err!(self.builder.build_extract_element(
9411 idx_out_of_range,
9412 self.intrinsics.i32_ty.const_int(i, false),
9413 "replace_with_zero",
9414 ))
9415 .into_int_value();
9416 let elem =
9417 err!(self.builder.build_extract_element(v1, idx, "elem")).into_int_value();
9418 let elem_or_zero = err!(self.builder.build_select(
9419 replace_with_zero,
9420 self.intrinsics.i8_zero,
9421 elem,
9422 "elem_or_zero",
9423 ));
9424 res = err!(self.builder.build_insert_element(
9425 res,
9426 elem_or_zero,
9427 self.intrinsics.i32_ty.const_int(i, false),
9428 "",
9429 ));
9430 }
9431 let res = err!(
9432 self.builder
9433 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9434 );
9435 self.state.push1(res);
9436 }
9437 Operator::I8x16Shuffle { lanes } => {
9438 let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
9439 let v1 = self.apply_pending_canonicalization(v1, i1)?;
9440 let v1 = err!(
9441 self.builder
9442 .build_bit_cast(v1, self.intrinsics.i8x16_ty, "")
9443 )
9444 .into_vector_value();
9445 let v2 = self.apply_pending_canonicalization(v2, i2)?;
9446 let v2 = err!(
9447 self.builder
9448 .build_bit_cast(v2, self.intrinsics.i8x16_ty, "")
9449 )
9450 .into_vector_value();
9451 let mask = VectorType::const_vector(
9452 lanes
9453 .iter()
9454 .map(|l| self.intrinsics.i32_ty.const_int((*l).into(), false))
9455 .collect::<Vec<IntValue>>()
9456 .as_slice(),
9457 );
9458 let res = err!(self.builder.build_shuffle_vector(v1, v2, mask, ""));
9459 let res = err!(
9460 self.builder
9461 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9462 );
9463 self.state.push1(res);
9464 }
9465 Operator::V128Load8x8S { ref memarg } => {
9466 let offset = self.state.pop1()?.into_int_value();
9467 let memory_index = MemoryIndex::from_u32(0);
9468 let effective_address = self.resolve_memory_ptr(
9469 memory_index,
9470 memarg,
9471 self.intrinsics.ptr_ty,
9472 offset,
9473 8,
9474 )?;
9475 let v = err!(self.builder.build_load(
9476 self.intrinsics.i64_ty,
9477 effective_address,
9478 ""
9479 ));
9480 let v = err!(
9481 self.builder
9482 .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9483 )
9484 .into_vector_value();
9485 let res = err!(
9486 self.builder
9487 .build_int_s_extend(v, self.intrinsics.i16x8_ty, "")
9488 );
9489 let res = err!(
9490 self.builder
9491 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9492 );
9493 self.state.push1(res);
9494 }
9495 Operator::V128Load8x8U { ref memarg } => {
9496 let offset = self.state.pop1()?.into_int_value();
9497 let memory_index = MemoryIndex::from_u32(0);
9498 let effective_address = self.resolve_memory_ptr(
9499 memory_index,
9500 memarg,
9501 self.intrinsics.ptr_ty,
9502 offset,
9503 8,
9504 )?;
9505 let v = err!(self.builder.build_load(
9506 self.intrinsics.i64_ty,
9507 effective_address,
9508 ""
9509 ));
9510 let v = err!(
9511 self.builder
9512 .build_bit_cast(v, self.intrinsics.i8_ty.vec_type(8), "")
9513 )
9514 .into_vector_value();
9515 let res = err!(
9516 self.builder
9517 .build_int_z_extend(v, self.intrinsics.i16x8_ty, "")
9518 );
9519 let res = err!(
9520 self.builder
9521 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9522 );
9523 self.state.push1(res);
9524 }
9525 Operator::V128Load16x4S { ref memarg } => {
9526 let offset = self.state.pop1()?.into_int_value();
9527 let memory_index = MemoryIndex::from_u32(0);
9528 let effective_address = self.resolve_memory_ptr(
9529 memory_index,
9530 memarg,
9531 self.intrinsics.ptr_ty,
9532 offset,
9533 8,
9534 )?;
9535 let v = err!(self.builder.build_load(
9536 self.intrinsics.i64_ty,
9537 effective_address,
9538 ""
9539 ));
9540 let v = err!(self.builder.build_bit_cast(
9541 v,
9542 self.intrinsics.i16_ty.vec_type(4),
9543 ""
9544 ))
9545 .into_vector_value();
9546 let res = err!(
9547 self.builder
9548 .build_int_s_extend(v, self.intrinsics.i32x4_ty, "")
9549 );
9550 let res = err!(
9551 self.builder
9552 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9553 );
9554 self.state.push1(res);
9555 }
9556 Operator::V128Load16x4U { ref memarg } => {
9557 let offset = self.state.pop1()?.into_int_value();
9558 let memory_index = MemoryIndex::from_u32(0);
9559 let effective_address = self.resolve_memory_ptr(
9560 memory_index,
9561 memarg,
9562 self.intrinsics.ptr_ty,
9563 offset,
9564 8,
9565 )?;
9566 let v = err!(self.builder.build_load(
9567 self.intrinsics.i64_ty,
9568 effective_address,
9569 ""
9570 ));
9571 let v = err!(self.builder.build_bit_cast(
9572 v,
9573 self.intrinsics.i16_ty.vec_type(4),
9574 ""
9575 ))
9576 .into_vector_value();
9577 let res = err!(
9578 self.builder
9579 .build_int_z_extend(v, self.intrinsics.i32x4_ty, "")
9580 );
9581 let res = err!(
9582 self.builder
9583 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9584 );
9585 self.state.push1(res);
9586 }
9587 Operator::V128Load32x2S { ref memarg } => {
9588 let offset = self.state.pop1()?.into_int_value();
9589 let memory_index = MemoryIndex::from_u32(0);
9590 let effective_address = self.resolve_memory_ptr(
9591 memory_index,
9592 memarg,
9593 self.intrinsics.ptr_ty,
9594 offset,
9595 8,
9596 )?;
9597 let v = err!(self.builder.build_load(
9598 self.intrinsics.i64_ty,
9599 effective_address,
9600 ""
9601 ));
9602 let v = err!(self.builder.build_bit_cast(
9603 v,
9604 self.intrinsics.i32_ty.vec_type(2),
9605 ""
9606 ))
9607 .into_vector_value();
9608 let res = err!(
9609 self.builder
9610 .build_int_s_extend(v, self.intrinsics.i64x2_ty, "")
9611 );
9612 let res = err!(
9613 self.builder
9614 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9615 );
9616 self.state.push1(res);
9617 }
9618 Operator::V128Load32x2U { ref memarg } => {
9619 let offset = self.state.pop1()?.into_int_value();
9620 let memory_index = MemoryIndex::from_u32(0);
9621 let effective_address = self.resolve_memory_ptr(
9622 memory_index,
9623 memarg,
9624 self.intrinsics.ptr_ty,
9625 offset,
9626 8,
9627 )?;
9628 let v = err!(self.builder.build_load(
9629 self.intrinsics.i64_ty,
9630 effective_address,
9631 ""
9632 ));
9633 let v = err!(self.builder.build_bit_cast(
9634 v,
9635 self.intrinsics.i32_ty.vec_type(2),
9636 ""
9637 ))
9638 .into_vector_value();
9639 let res = err!(
9640 self.builder
9641 .build_int_z_extend(v, self.intrinsics.i64x2_ty, "")
9642 );
9643 let res = err!(
9644 self.builder
9645 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9646 );
9647 self.state.push1(res);
9648 }
9649 Operator::V128Load32Zero { ref memarg } => {
9650 let offset = self.state.pop1()?.into_int_value();
9651 let memory_index = MemoryIndex::from_u32(0);
9652 let effective_address = self.resolve_memory_ptr(
9653 memory_index,
9654 memarg,
9655 self.intrinsics.ptr_ty,
9656 offset,
9657 4,
9658 )?;
9659 let elem = err!(self.builder.build_load(
9660 self.intrinsics.i32_ty,
9661 effective_address,
9662 ""
9663 ));
9664 self.annotate_user_memaccess(
9665 memory_index,
9666 memarg,
9667 1,
9668 elem.as_instruction_value().unwrap(),
9669 )?;
9670 let res = err!(self.builder.build_int_z_extend(
9671 elem.into_int_value(),
9672 self.intrinsics.i128_ty,
9673 "",
9674 ));
9675 self.state.push1(res);
9676 }
9677 Operator::V128Load64Zero { ref memarg } => {
9678 let offset = self.state.pop1()?.into_int_value();
9679 let memory_index = MemoryIndex::from_u32(0);
9680 let effective_address = self.resolve_memory_ptr(
9681 memory_index,
9682 memarg,
9683 self.intrinsics.ptr_ty,
9684 offset,
9685 8,
9686 )?;
9687 let elem = err!(self.builder.build_load(
9688 self.intrinsics.i64_ty,
9689 effective_address,
9690 ""
9691 ));
9692 self.annotate_user_memaccess(
9693 memory_index,
9694 memarg,
9695 1,
9696 elem.as_instruction_value().unwrap(),
9697 )?;
9698 let res = err!(self.builder.build_int_z_extend(
9699 elem.into_int_value(),
9700 self.intrinsics.i128_ty,
9701 "",
9702 ));
9703 self.state.push1(res);
9704 }
9705 Operator::V128Load8Splat { ref memarg } => {
9706 let offset = self.state.pop1()?.into_int_value();
9707 let memory_index = MemoryIndex::from_u32(0);
9708 let effective_address = self.resolve_memory_ptr(
9709 memory_index,
9710 memarg,
9711 self.intrinsics.ptr_ty,
9712 offset,
9713 1,
9714 )?;
9715 let elem = err!(self.builder.build_load(
9716 self.intrinsics.i8_ty,
9717 effective_address,
9718 ""
9719 ));
9720 self.annotate_user_memaccess(
9721 memory_index,
9722 memarg,
9723 1,
9724 elem.as_instruction_value().unwrap(),
9725 )?;
9726 let res = self.splat_vector(elem, self.intrinsics.i8x16_ty)?;
9727 let res = err!(
9728 self.builder
9729 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9730 );
9731 self.state.push1(res);
9732 }
9733 Operator::V128Load16Splat { ref memarg } => {
9734 let offset = self.state.pop1()?.into_int_value();
9735 let memory_index = MemoryIndex::from_u32(0);
9736 let effective_address = self.resolve_memory_ptr(
9737 memory_index,
9738 memarg,
9739 self.intrinsics.ptr_ty,
9740 offset,
9741 2,
9742 )?;
9743 let elem = err!(self.builder.build_load(
9744 self.intrinsics.i16_ty,
9745 effective_address,
9746 ""
9747 ));
9748 self.annotate_user_memaccess(
9749 memory_index,
9750 memarg,
9751 1,
9752 elem.as_instruction_value().unwrap(),
9753 )?;
9754 let res = self.splat_vector(elem, self.intrinsics.i16x8_ty)?;
9755 let res = err!(
9756 self.builder
9757 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9758 );
9759 self.state.push1(res);
9760 }
9761 Operator::V128Load32Splat { ref memarg } => {
9762 let offset = self.state.pop1()?.into_int_value();
9763 let memory_index = MemoryIndex::from_u32(0);
9764 let effective_address = self.resolve_memory_ptr(
9765 memory_index,
9766 memarg,
9767 self.intrinsics.ptr_ty,
9768 offset,
9769 4,
9770 )?;
9771 let elem = err!(self.builder.build_load(
9772 self.intrinsics.i32_ty,
9773 effective_address,
9774 ""
9775 ));
9776 self.annotate_user_memaccess(
9777 memory_index,
9778 memarg,
9779 1,
9780 elem.as_instruction_value().unwrap(),
9781 )?;
9782 let res = self.splat_vector(elem, self.intrinsics.i32x4_ty)?;
9783 let res = err!(
9784 self.builder
9785 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9786 );
9787 self.state.push1(res);
9788 }
9789 Operator::V128Load64Splat { ref memarg } => {
9790 let offset = self.state.pop1()?.into_int_value();
9791 let memory_index = MemoryIndex::from_u32(0);
9792 let effective_address = self.resolve_memory_ptr(
9793 memory_index,
9794 memarg,
9795 self.intrinsics.ptr_ty,
9796 offset,
9797 8,
9798 )?;
9799 let elem = err!(self.builder.build_load(
9800 self.intrinsics.i64_ty,
9801 effective_address,
9802 ""
9803 ));
9804 self.annotate_user_memaccess(
9805 memory_index,
9806 memarg,
9807 1,
9808 elem.as_instruction_value().unwrap(),
9809 )?;
9810 let res = self.splat_vector(elem, self.intrinsics.i64x2_ty)?;
9811 let res = err!(
9812 self.builder
9813 .build_bit_cast(res, self.intrinsics.i128_ty, "")
9814 );
9815 self.state.push1(res);
9816 }
9817 Operator::AtomicFence => {
9818 }
9826 Operator::I32AtomicLoad { ref memarg } => {
9827 let offset = self.state.pop1()?.into_int_value();
9828 let memory_index = MemoryIndex::from_u32(0);
9829 let effective_address = self.resolve_memory_ptr(
9830 memory_index,
9831 memarg,
9832 self.intrinsics.ptr_ty,
9833 offset,
9834 4,
9835 )?;
9836 self.trap_if_misaligned(memarg, effective_address, 4)?;
9837 let result = err!(self.builder.build_load(
9838 self.intrinsics.i32_ty,
9839 effective_address,
9840 "atomic_load"
9841 ));
9842 let load = result.as_instruction_value().unwrap();
9843 self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
9844 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9845 .unwrap();
9846 self.state.push1(result);
9847 }
9848 Operator::I64AtomicLoad { ref memarg } => {
9849 let offset = self.state.pop1()?.into_int_value();
9850 let memory_index = MemoryIndex::from_u32(0);
9851 let effective_address = self.resolve_memory_ptr(
9852 memory_index,
9853 memarg,
9854 self.intrinsics.ptr_ty,
9855 offset,
9856 8,
9857 )?;
9858 self.trap_if_misaligned(memarg, effective_address, 8)?;
9859 let result = err!(self.builder.build_load(
9860 self.intrinsics.i64_ty,
9861 effective_address,
9862 ""
9863 ));
9864 let load = result.as_instruction_value().unwrap();
9865 self.annotate_user_memaccess(memory_index, memarg, 8, load)?;
9866 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9867 .unwrap();
9868 self.state.push1(result);
9869 }
9870 Operator::I32AtomicLoad8U { ref memarg } => {
9871 let offset = self.state.pop1()?.into_int_value();
9872 let memory_index = MemoryIndex::from_u32(0);
9873 let effective_address = self.resolve_memory_ptr(
9874 memory_index,
9875 memarg,
9876 self.intrinsics.ptr_ty,
9877 offset,
9878 1,
9879 )?;
9880 self.trap_if_misaligned(memarg, effective_address, 1)?;
9881 let narrow_result = err!(self.builder.build_load(
9882 self.intrinsics.i8_ty,
9883 effective_address,
9884 ""
9885 ))
9886 .into_int_value();
9887 let load = narrow_result.as_instruction_value().unwrap();
9888 self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9889 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9890 .unwrap();
9891 let result = err!(self.builder.build_int_z_extend(
9892 narrow_result,
9893 self.intrinsics.i32_ty,
9894 ""
9895 ));
9896 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9897 }
9898 Operator::I32AtomicLoad16U { ref memarg } => {
9899 let offset = self.state.pop1()?.into_int_value();
9900 let memory_index = MemoryIndex::from_u32(0);
9901 let effective_address = self.resolve_memory_ptr(
9902 memory_index,
9903 memarg,
9904 self.intrinsics.ptr_ty,
9905 offset,
9906 2,
9907 )?;
9908 self.trap_if_misaligned(memarg, effective_address, 2)?;
9909 let narrow_result = err!(self.builder.build_load(
9910 self.intrinsics.i16_ty,
9911 effective_address,
9912 ""
9913 ))
9914 .into_int_value();
9915 let load = narrow_result.as_instruction_value().unwrap();
9916 self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9917 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9918 .unwrap();
9919 let result = err!(self.builder.build_int_z_extend(
9920 narrow_result,
9921 self.intrinsics.i32_ty,
9922 ""
9923 ));
9924 self.state.push1_extra(result, ExtraInfo::arithmetic_f32());
9925 }
9926 Operator::I64AtomicLoad8U { ref memarg } => {
9927 let offset = self.state.pop1()?.into_int_value();
9928 let memory_index = MemoryIndex::from_u32(0);
9929 let effective_address = self.resolve_memory_ptr(
9930 memory_index,
9931 memarg,
9932 self.intrinsics.ptr_ty,
9933 offset,
9934 1,
9935 )?;
9936 self.trap_if_misaligned(memarg, effective_address, 1)?;
9937 let narrow_result = err!(self.builder.build_load(
9938 self.intrinsics.i8_ty,
9939 effective_address,
9940 ""
9941 ))
9942 .into_int_value();
9943 let load = narrow_result.as_instruction_value().unwrap();
9944 self.annotate_user_memaccess(memory_index, memarg, 1, load)?;
9945 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9946 .unwrap();
9947 let result = err!(self.builder.build_int_z_extend(
9948 narrow_result,
9949 self.intrinsics.i64_ty,
9950 ""
9951 ));
9952 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9953 }
9954 Operator::I64AtomicLoad16U { ref memarg } => {
9955 let offset = self.state.pop1()?.into_int_value();
9956 let memory_index = MemoryIndex::from_u32(0);
9957 let effective_address = self.resolve_memory_ptr(
9958 memory_index,
9959 memarg,
9960 self.intrinsics.ptr_ty,
9961 offset,
9962 2,
9963 )?;
9964 self.trap_if_misaligned(memarg, effective_address, 2)?;
9965 let narrow_result = err!(self.builder.build_load(
9966 self.intrinsics.i16_ty,
9967 effective_address,
9968 ""
9969 ))
9970 .into_int_value();
9971 let load = narrow_result.as_instruction_value().unwrap();
9972 self.annotate_user_memaccess(memory_index, memarg, 2, load)?;
9973 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
9974 .unwrap();
9975 let result = err!(self.builder.build_int_z_extend(
9976 narrow_result,
9977 self.intrinsics.i64_ty,
9978 ""
9979 ));
9980 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
9981 }
9982 Operator::I64AtomicLoad32U { ref memarg } => {
9983 let offset = self.state.pop1()?.into_int_value();
9984 let memory_index = MemoryIndex::from_u32(0);
9985 let effective_address = self.resolve_memory_ptr(
9986 memory_index,
9987 memarg,
9988 self.intrinsics.ptr_ty,
9989 offset,
9990 4,
9991 )?;
9992 self.trap_if_misaligned(memarg, effective_address, 4)?;
9993 let narrow_result = err!(self.builder.build_load(
9994 self.intrinsics.i32_ty,
9995 effective_address,
9996 ""
9997 ))
9998 .into_int_value();
9999 let load = narrow_result.as_instruction_value().unwrap();
10000 self.annotate_user_memaccess(memory_index, memarg, 4, load)?;
10001 load.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10002 .unwrap();
10003 let result = err!(self.builder.build_int_z_extend(
10004 narrow_result,
10005 self.intrinsics.i64_ty,
10006 ""
10007 ));
10008 self.state.push1_extra(result, ExtraInfo::arithmetic_f64());
10009 }
10010 Operator::I32AtomicStore { ref memarg } => {
10011 let value = self.state.pop1()?;
10012 let offset = self.state.pop1()?.into_int_value();
10013 let memory_index = MemoryIndex::from_u32(0);
10014 let effective_address = self.resolve_memory_ptr(
10015 memory_index,
10016 memarg,
10017 self.intrinsics.ptr_ty,
10018 offset,
10019 4,
10020 )?;
10021 self.trap_if_misaligned(memarg, effective_address, 4)?;
10022 let store = err!(self.builder.build_store(effective_address, value));
10023 self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10024 store
10025 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10026 .unwrap();
10027 }
10028 Operator::I64AtomicStore { ref memarg } => {
10029 let value = self.state.pop1()?;
10030 let offset = self.state.pop1()?.into_int_value();
10031 let memory_index = MemoryIndex::from_u32(0);
10032 let effective_address = self.resolve_memory_ptr(
10033 memory_index,
10034 memarg,
10035 self.intrinsics.ptr_ty,
10036 offset,
10037 8,
10038 )?;
10039 self.trap_if_misaligned(memarg, effective_address, 8)?;
10040 let store = err!(self.builder.build_store(effective_address, value));
10041 self.annotate_user_memaccess(memory_index, memarg, 8, store)?;
10042 store
10043 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10044 .unwrap();
10045 }
10046 Operator::I32AtomicStore8 { ref memarg } | Operator::I64AtomicStore8 { ref memarg } => {
10047 let value = self.state.pop1()?.into_int_value();
10048 let offset = self.state.pop1()?.into_int_value();
10049 let memory_index = MemoryIndex::from_u32(0);
10050 let effective_address = self.resolve_memory_ptr(
10051 memory_index,
10052 memarg,
10053 self.intrinsics.ptr_ty,
10054 offset,
10055 1,
10056 )?;
10057 self.trap_if_misaligned(memarg, effective_address, 1)?;
10058 let narrow_value = err!(self.builder.build_int_truncate(
10059 value,
10060 self.intrinsics.i8_ty,
10061 ""
10062 ));
10063 let store = err!(self.builder.build_store(effective_address, narrow_value));
10064 self.annotate_user_memaccess(memory_index, memarg, 1, store)?;
10065 store
10066 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10067 .unwrap();
10068 }
10069 Operator::I32AtomicStore16 { ref memarg }
10070 | Operator::I64AtomicStore16 { ref memarg } => {
10071 let value = self.state.pop1()?.into_int_value();
10072 let offset = self.state.pop1()?.into_int_value();
10073 let memory_index = MemoryIndex::from_u32(0);
10074 let effective_address = self.resolve_memory_ptr(
10075 memory_index,
10076 memarg,
10077 self.intrinsics.ptr_ty,
10078 offset,
10079 2,
10080 )?;
10081 self.trap_if_misaligned(memarg, effective_address, 2)?;
10082 let narrow_value = err!(self.builder.build_int_truncate(
10083 value,
10084 self.intrinsics.i16_ty,
10085 ""
10086 ));
10087 let store = err!(self.builder.build_store(effective_address, narrow_value));
10088 self.annotate_user_memaccess(memory_index, memarg, 2, store)?;
10089 store
10090 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10091 .unwrap();
10092 }
10093 Operator::I64AtomicStore32 { ref memarg } => {
10094 let value = self.state.pop1()?.into_int_value();
10095 let offset = self.state.pop1()?.into_int_value();
10096 let memory_index = MemoryIndex::from_u32(0);
10097 let effective_address = self.resolve_memory_ptr(
10098 memory_index,
10099 memarg,
10100 self.intrinsics.ptr_ty,
10101 offset,
10102 4,
10103 )?;
10104 self.trap_if_misaligned(memarg, effective_address, 4)?;
10105 let narrow_value = err!(self.builder.build_int_truncate(
10106 value,
10107 self.intrinsics.i32_ty,
10108 ""
10109 ));
10110 let store = err!(self.builder.build_store(effective_address, narrow_value));
10111 self.annotate_user_memaccess(memory_index, memarg, 4, store)?;
10112 store
10113 .set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
10114 .unwrap();
10115 }
10116 Operator::I32AtomicRmw8AddU { ref memarg } => {
10117 let value = self.state.pop1()?.into_int_value();
10118 let offset = self.state.pop1()?.into_int_value();
10119 let memory_index = MemoryIndex::from_u32(0);
10120 let effective_address = self.resolve_memory_ptr(
10121 memory_index,
10122 memarg,
10123 self.intrinsics.ptr_ty,
10124 offset,
10125 1,
10126 )?;
10127 self.trap_if_misaligned(memarg, effective_address, 1)?;
10128 let narrow_value = err!(self.builder.build_int_truncate(
10129 value,
10130 self.intrinsics.i8_ty,
10131 ""
10132 ));
10133 let old = self
10134 .builder
10135 .build_atomicrmw(
10136 AtomicRMWBinOp::Add,
10137 effective_address,
10138 narrow_value,
10139 AtomicOrdering::SequentiallyConsistent,
10140 )
10141 .unwrap();
10142 tbaa_label(
10143 self.module,
10144 self.intrinsics,
10145 format!("memory {}", memory_index.as_u32()),
10146 old.as_instruction_value().unwrap(),
10147 );
10148 let old = err!(
10149 self.builder
10150 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10151 );
10152 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10153 }
10154 Operator::I32AtomicRmw16AddU { ref memarg } => {
10155 let value = self.state.pop1()?.into_int_value();
10156 let offset = self.state.pop1()?.into_int_value();
10157 let memory_index = MemoryIndex::from_u32(0);
10158 let effective_address = self.resolve_memory_ptr(
10159 memory_index,
10160 memarg,
10161 self.intrinsics.ptr_ty,
10162 offset,
10163 2,
10164 )?;
10165 self.trap_if_misaligned(memarg, effective_address, 2)?;
10166 let narrow_value = err!(self.builder.build_int_truncate(
10167 value,
10168 self.intrinsics.i16_ty,
10169 ""
10170 ));
10171 let old = self
10172 .builder
10173 .build_atomicrmw(
10174 AtomicRMWBinOp::Add,
10175 effective_address,
10176 narrow_value,
10177 AtomicOrdering::SequentiallyConsistent,
10178 )
10179 .unwrap();
10180 tbaa_label(
10181 self.module,
10182 self.intrinsics,
10183 format!("memory {}", memory_index.as_u32()),
10184 old.as_instruction_value().unwrap(),
10185 );
10186 let old = err!(
10187 self.builder
10188 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10189 );
10190 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10191 }
10192 Operator::I32AtomicRmwAdd { ref memarg } => {
10193 let value = self.state.pop1()?.into_int_value();
10194 let offset = self.state.pop1()?.into_int_value();
10195 let memory_index = MemoryIndex::from_u32(0);
10196 let effective_address = self.resolve_memory_ptr(
10197 memory_index,
10198 memarg,
10199 self.intrinsics.ptr_ty,
10200 offset,
10201 4,
10202 )?;
10203 self.trap_if_misaligned(memarg, effective_address, 4)?;
10204 let old = self
10205 .builder
10206 .build_atomicrmw(
10207 AtomicRMWBinOp::Add,
10208 effective_address,
10209 value,
10210 AtomicOrdering::SequentiallyConsistent,
10211 )
10212 .unwrap();
10213 tbaa_label(
10214 self.module,
10215 self.intrinsics,
10216 format!("memory {}", memory_index.as_u32()),
10217 old.as_instruction_value().unwrap(),
10218 );
10219 self.state.push1(old);
10220 }
10221 Operator::I64AtomicRmw8AddU { ref memarg } => {
10222 let value = self.state.pop1()?.into_int_value();
10223 let offset = self.state.pop1()?.into_int_value();
10224 let memory_index = MemoryIndex::from_u32(0);
10225 let effective_address = self.resolve_memory_ptr(
10226 memory_index,
10227 memarg,
10228 self.intrinsics.ptr_ty,
10229 offset,
10230 1,
10231 )?;
10232 self.trap_if_misaligned(memarg, effective_address, 1)?;
10233 let narrow_value = err!(self.builder.build_int_truncate(
10234 value,
10235 self.intrinsics.i8_ty,
10236 ""
10237 ));
10238 let old = self
10239 .builder
10240 .build_atomicrmw(
10241 AtomicRMWBinOp::Add,
10242 effective_address,
10243 narrow_value,
10244 AtomicOrdering::SequentiallyConsistent,
10245 )
10246 .unwrap();
10247 self.annotate_user_memaccess(
10248 memory_index,
10249 memarg,
10250 0,
10251 old.as_instruction_value().unwrap(),
10252 )?;
10253 let old = err!(
10254 self.builder
10255 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10256 );
10257 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10258 }
10259 Operator::I64AtomicRmw16AddU { ref memarg } => {
10260 let value = self.state.pop1()?.into_int_value();
10261 let offset = self.state.pop1()?.into_int_value();
10262 let memory_index = MemoryIndex::from_u32(0);
10263 let effective_address = self.resolve_memory_ptr(
10264 memory_index,
10265 memarg,
10266 self.intrinsics.ptr_ty,
10267 offset,
10268 2,
10269 )?;
10270 self.trap_if_misaligned(memarg, effective_address, 2)?;
10271 let narrow_value = err!(self.builder.build_int_truncate(
10272 value,
10273 self.intrinsics.i16_ty,
10274 ""
10275 ));
10276 let old = self
10277 .builder
10278 .build_atomicrmw(
10279 AtomicRMWBinOp::Add,
10280 effective_address,
10281 narrow_value,
10282 AtomicOrdering::SequentiallyConsistent,
10283 )
10284 .unwrap();
10285 self.annotate_user_memaccess(
10286 memory_index,
10287 memarg,
10288 0,
10289 old.as_instruction_value().unwrap(),
10290 )?;
10291 let old = err!(
10292 self.builder
10293 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10294 );
10295 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10296 }
10297 Operator::I64AtomicRmw32AddU { ref memarg } => {
10298 let value = self.state.pop1()?.into_int_value();
10299 let offset = self.state.pop1()?.into_int_value();
10300 let memory_index = MemoryIndex::from_u32(0);
10301 let effective_address = self.resolve_memory_ptr(
10302 memory_index,
10303 memarg,
10304 self.intrinsics.ptr_ty,
10305 offset,
10306 4,
10307 )?;
10308 self.trap_if_misaligned(memarg, effective_address, 4)?;
10309 let narrow_value = err!(self.builder.build_int_truncate(
10310 value,
10311 self.intrinsics.i32_ty,
10312 ""
10313 ));
10314 let old = self
10315 .builder
10316 .build_atomicrmw(
10317 AtomicRMWBinOp::Add,
10318 effective_address,
10319 narrow_value,
10320 AtomicOrdering::SequentiallyConsistent,
10321 )
10322 .unwrap();
10323 self.annotate_user_memaccess(
10324 memory_index,
10325 memarg,
10326 0,
10327 old.as_instruction_value().unwrap(),
10328 )?;
10329 let old = err!(
10330 self.builder
10331 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10332 );
10333 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10334 }
10335 Operator::I64AtomicRmwAdd { ref memarg } => {
10336 let value = self.state.pop1()?.into_int_value();
10337 let offset = self.state.pop1()?.into_int_value();
10338 let memory_index = MemoryIndex::from_u32(0);
10339 let effective_address = self.resolve_memory_ptr(
10340 memory_index,
10341 memarg,
10342 self.intrinsics.ptr_ty,
10343 offset,
10344 8,
10345 )?;
10346 self.trap_if_misaligned(memarg, effective_address, 8)?;
10347 let old = self
10348 .builder
10349 .build_atomicrmw(
10350 AtomicRMWBinOp::Add,
10351 effective_address,
10352 value,
10353 AtomicOrdering::SequentiallyConsistent,
10354 )
10355 .unwrap();
10356 self.annotate_user_memaccess(
10357 memory_index,
10358 memarg,
10359 0,
10360 old.as_instruction_value().unwrap(),
10361 )?;
10362 self.state.push1(old);
10363 }
10364 Operator::I32AtomicRmw8SubU { ref memarg } => {
10365 let value = self.state.pop1()?.into_int_value();
10366 let offset = self.state.pop1()?.into_int_value();
10367 let memory_index = MemoryIndex::from_u32(0);
10368 let effective_address = self.resolve_memory_ptr(
10369 memory_index,
10370 memarg,
10371 self.intrinsics.ptr_ty,
10372 offset,
10373 1,
10374 )?;
10375 self.trap_if_misaligned(memarg, effective_address, 1)?;
10376 let narrow_value = err!(self.builder.build_int_truncate(
10377 value,
10378 self.intrinsics.i8_ty,
10379 ""
10380 ));
10381 let old = self
10382 .builder
10383 .build_atomicrmw(
10384 AtomicRMWBinOp::Sub,
10385 effective_address,
10386 narrow_value,
10387 AtomicOrdering::SequentiallyConsistent,
10388 )
10389 .unwrap();
10390 self.annotate_user_memaccess(
10391 memory_index,
10392 memarg,
10393 0,
10394 old.as_instruction_value().unwrap(),
10395 )?;
10396 let old = err!(
10397 self.builder
10398 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10399 );
10400 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10401 }
10402 Operator::I32AtomicRmw16SubU { ref memarg } => {
10403 let value = self.state.pop1()?.into_int_value();
10404 let offset = self.state.pop1()?.into_int_value();
10405 let memory_index = MemoryIndex::from_u32(0);
10406 let effective_address = self.resolve_memory_ptr(
10407 memory_index,
10408 memarg,
10409 self.intrinsics.ptr_ty,
10410 offset,
10411 2,
10412 )?;
10413 self.trap_if_misaligned(memarg, effective_address, 2)?;
10414 let narrow_value = err!(self.builder.build_int_truncate(
10415 value,
10416 self.intrinsics.i16_ty,
10417 ""
10418 ));
10419 let old = self
10420 .builder
10421 .build_atomicrmw(
10422 AtomicRMWBinOp::Sub,
10423 effective_address,
10424 narrow_value,
10425 AtomicOrdering::SequentiallyConsistent,
10426 )
10427 .unwrap();
10428 self.annotate_user_memaccess(
10429 memory_index,
10430 memarg,
10431 0,
10432 old.as_instruction_value().unwrap(),
10433 )?;
10434 let old = err!(
10435 self.builder
10436 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10437 );
10438 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10439 }
10440 Operator::I32AtomicRmwSub { ref memarg } => {
10441 let value = self.state.pop1()?.into_int_value();
10442 let offset = self.state.pop1()?.into_int_value();
10443 let memory_index = MemoryIndex::from_u32(0);
10444 let effective_address = self.resolve_memory_ptr(
10445 memory_index,
10446 memarg,
10447 self.intrinsics.ptr_ty,
10448 offset,
10449 4,
10450 )?;
10451 self.trap_if_misaligned(memarg, effective_address, 4)?;
10452 let old = self
10453 .builder
10454 .build_atomicrmw(
10455 AtomicRMWBinOp::Sub,
10456 effective_address,
10457 value,
10458 AtomicOrdering::SequentiallyConsistent,
10459 )
10460 .unwrap();
10461 self.annotate_user_memaccess(
10462 memory_index,
10463 memarg,
10464 0,
10465 old.as_instruction_value().unwrap(),
10466 )?;
10467 self.state.push1(old);
10468 }
10469 Operator::I64AtomicRmw8SubU { ref memarg } => {
10470 let value = self.state.pop1()?.into_int_value();
10471 let offset = self.state.pop1()?.into_int_value();
10472 let memory_index = MemoryIndex::from_u32(0);
10473 let effective_address = self.resolve_memory_ptr(
10474 memory_index,
10475 memarg,
10476 self.intrinsics.ptr_ty,
10477 offset,
10478 1,
10479 )?;
10480 self.trap_if_misaligned(memarg, effective_address, 1)?;
10481 let narrow_value = err!(self.builder.build_int_truncate(
10482 value,
10483 self.intrinsics.i8_ty,
10484 ""
10485 ));
10486 let old = self
10487 .builder
10488 .build_atomicrmw(
10489 AtomicRMWBinOp::Sub,
10490 effective_address,
10491 narrow_value,
10492 AtomicOrdering::SequentiallyConsistent,
10493 )
10494 .unwrap();
10495 self.annotate_user_memaccess(
10496 memory_index,
10497 memarg,
10498 0,
10499 old.as_instruction_value().unwrap(),
10500 )?;
10501 let old = err!(
10502 self.builder
10503 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10504 );
10505 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10506 }
10507 Operator::I64AtomicRmw16SubU { ref memarg } => {
10508 let value = self.state.pop1()?.into_int_value();
10509 let offset = self.state.pop1()?.into_int_value();
10510 let memory_index = MemoryIndex::from_u32(0);
10511 let effective_address = self.resolve_memory_ptr(
10512 memory_index,
10513 memarg,
10514 self.intrinsics.ptr_ty,
10515 offset,
10516 2,
10517 )?;
10518 self.trap_if_misaligned(memarg, effective_address, 2)?;
10519 let narrow_value = err!(self.builder.build_int_truncate(
10520 value,
10521 self.intrinsics.i16_ty,
10522 ""
10523 ));
10524 let old = self
10525 .builder
10526 .build_atomicrmw(
10527 AtomicRMWBinOp::Sub,
10528 effective_address,
10529 narrow_value,
10530 AtomicOrdering::SequentiallyConsistent,
10531 )
10532 .unwrap();
10533 self.annotate_user_memaccess(
10534 memory_index,
10535 memarg,
10536 0,
10537 old.as_instruction_value().unwrap(),
10538 )?;
10539 let old = err!(
10540 self.builder
10541 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10542 );
10543 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10544 }
10545 Operator::I64AtomicRmw32SubU { ref memarg } => {
10546 let value = self.state.pop1()?.into_int_value();
10547 let offset = self.state.pop1()?.into_int_value();
10548 let memory_index = MemoryIndex::from_u32(0);
10549 let effective_address = self.resolve_memory_ptr(
10550 memory_index,
10551 memarg,
10552 self.intrinsics.ptr_ty,
10553 offset,
10554 4,
10555 )?;
10556 self.trap_if_misaligned(memarg, effective_address, 4)?;
10557 let narrow_value = err!(self.builder.build_int_truncate(
10558 value,
10559 self.intrinsics.i32_ty,
10560 ""
10561 ));
10562 let old = self
10563 .builder
10564 .build_atomicrmw(
10565 AtomicRMWBinOp::Sub,
10566 effective_address,
10567 narrow_value,
10568 AtomicOrdering::SequentiallyConsistent,
10569 )
10570 .unwrap();
10571 self.annotate_user_memaccess(
10572 memory_index,
10573 memarg,
10574 0,
10575 old.as_instruction_value().unwrap(),
10576 )?;
10577 let old = err!(
10578 self.builder
10579 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10580 );
10581 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10582 }
10583 Operator::I64AtomicRmwSub { ref memarg } => {
10584 let value = self.state.pop1()?.into_int_value();
10585 let offset = self.state.pop1()?.into_int_value();
10586 let memory_index = MemoryIndex::from_u32(0);
10587 let effective_address = self.resolve_memory_ptr(
10588 memory_index,
10589 memarg,
10590 self.intrinsics.ptr_ty,
10591 offset,
10592 8,
10593 )?;
10594 self.trap_if_misaligned(memarg, effective_address, 8)?;
10595 let old = self
10596 .builder
10597 .build_atomicrmw(
10598 AtomicRMWBinOp::Sub,
10599 effective_address,
10600 value,
10601 AtomicOrdering::SequentiallyConsistent,
10602 )
10603 .unwrap();
10604 self.annotate_user_memaccess(
10605 memory_index,
10606 memarg,
10607 0,
10608 old.as_instruction_value().unwrap(),
10609 )?;
10610 self.state.push1(old);
10611 }
10612 Operator::I32AtomicRmw8AndU { ref memarg } => {
10613 let value = self.state.pop1()?.into_int_value();
10614 let offset = self.state.pop1()?.into_int_value();
10615 let memory_index = MemoryIndex::from_u32(0);
10616 let effective_address = self.resolve_memory_ptr(
10617 memory_index,
10618 memarg,
10619 self.intrinsics.ptr_ty,
10620 offset,
10621 1,
10622 )?;
10623 self.trap_if_misaligned(memarg, effective_address, 1)?;
10624 let narrow_value = err!(self.builder.build_int_truncate(
10625 value,
10626 self.intrinsics.i8_ty,
10627 ""
10628 ));
10629 let old = self
10630 .builder
10631 .build_atomicrmw(
10632 AtomicRMWBinOp::And,
10633 effective_address,
10634 narrow_value,
10635 AtomicOrdering::SequentiallyConsistent,
10636 )
10637 .unwrap();
10638 self.annotate_user_memaccess(
10639 memory_index,
10640 memarg,
10641 0,
10642 old.as_instruction_value().unwrap(),
10643 )?;
10644 let old = err!(
10645 self.builder
10646 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10647 );
10648 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10649 }
10650 Operator::I32AtomicRmw16AndU { ref memarg } => {
10651 let value = self.state.pop1()?.into_int_value();
10652 let offset = self.state.pop1()?.into_int_value();
10653 let memory_index = MemoryIndex::from_u32(0);
10654 let effective_address = self.resolve_memory_ptr(
10655 memory_index,
10656 memarg,
10657 self.intrinsics.ptr_ty,
10658 offset,
10659 2,
10660 )?;
10661 self.trap_if_misaligned(memarg, effective_address, 2)?;
10662 let narrow_value = err!(self.builder.build_int_truncate(
10663 value,
10664 self.intrinsics.i16_ty,
10665 ""
10666 ));
10667 let old = self
10668 .builder
10669 .build_atomicrmw(
10670 AtomicRMWBinOp::And,
10671 effective_address,
10672 narrow_value,
10673 AtomicOrdering::SequentiallyConsistent,
10674 )
10675 .unwrap();
10676 self.annotate_user_memaccess(
10677 memory_index,
10678 memarg,
10679 0,
10680 old.as_instruction_value().unwrap(),
10681 )?;
10682 let old = err!(
10683 self.builder
10684 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10685 );
10686 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10687 }
10688 Operator::I32AtomicRmwAnd { ref memarg } => {
10689 let value = self.state.pop1()?.into_int_value();
10690 let offset = self.state.pop1()?.into_int_value();
10691 let memory_index = MemoryIndex::from_u32(0);
10692 let effective_address = self.resolve_memory_ptr(
10693 memory_index,
10694 memarg,
10695 self.intrinsics.ptr_ty,
10696 offset,
10697 4,
10698 )?;
10699 self.trap_if_misaligned(memarg, effective_address, 4)?;
10700 let old = self
10701 .builder
10702 .build_atomicrmw(
10703 AtomicRMWBinOp::And,
10704 effective_address,
10705 value,
10706 AtomicOrdering::SequentiallyConsistent,
10707 )
10708 .unwrap();
10709 self.annotate_user_memaccess(
10710 memory_index,
10711 memarg,
10712 0,
10713 old.as_instruction_value().unwrap(),
10714 )?;
10715 self.state.push1(old);
10716 }
10717 Operator::I64AtomicRmw8AndU { ref memarg } => {
10718 let value = self.state.pop1()?.into_int_value();
10719 let offset = self.state.pop1()?.into_int_value();
10720 let memory_index = MemoryIndex::from_u32(0);
10721 let effective_address = self.resolve_memory_ptr(
10722 memory_index,
10723 memarg,
10724 self.intrinsics.ptr_ty,
10725 offset,
10726 1,
10727 )?;
10728 self.trap_if_misaligned(memarg, effective_address, 1)?;
10729 let narrow_value = err!(self.builder.build_int_truncate(
10730 value,
10731 self.intrinsics.i8_ty,
10732 ""
10733 ));
10734 let old = self
10735 .builder
10736 .build_atomicrmw(
10737 AtomicRMWBinOp::And,
10738 effective_address,
10739 narrow_value,
10740 AtomicOrdering::SequentiallyConsistent,
10741 )
10742 .unwrap();
10743 self.annotate_user_memaccess(
10744 memory_index,
10745 memarg,
10746 0,
10747 old.as_instruction_value().unwrap(),
10748 )?;
10749 let old = err!(
10750 self.builder
10751 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10752 );
10753 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10754 }
10755 Operator::I64AtomicRmw16AndU { ref memarg } => {
10756 let value = self.state.pop1()?.into_int_value();
10757 let offset = self.state.pop1()?.into_int_value();
10758 let memory_index = MemoryIndex::from_u32(0);
10759 let effective_address = self.resolve_memory_ptr(
10760 memory_index,
10761 memarg,
10762 self.intrinsics.ptr_ty,
10763 offset,
10764 2,
10765 )?;
10766 self.trap_if_misaligned(memarg, effective_address, 2)?;
10767 let narrow_value = err!(self.builder.build_int_truncate(
10768 value,
10769 self.intrinsics.i16_ty,
10770 ""
10771 ));
10772 let old = self
10773 .builder
10774 .build_atomicrmw(
10775 AtomicRMWBinOp::And,
10776 effective_address,
10777 narrow_value,
10778 AtomicOrdering::SequentiallyConsistent,
10779 )
10780 .unwrap();
10781 self.annotate_user_memaccess(
10782 memory_index,
10783 memarg,
10784 0,
10785 old.as_instruction_value().unwrap(),
10786 )?;
10787 let old = err!(
10788 self.builder
10789 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10790 );
10791 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10792 }
10793 Operator::I64AtomicRmw32AndU { ref memarg } => {
10794 let value = self.state.pop1()?.into_int_value();
10795 let offset = self.state.pop1()?.into_int_value();
10796 let memory_index = MemoryIndex::from_u32(0);
10797 let effective_address = self.resolve_memory_ptr(
10798 memory_index,
10799 memarg,
10800 self.intrinsics.ptr_ty,
10801 offset,
10802 4,
10803 )?;
10804 self.trap_if_misaligned(memarg, effective_address, 4)?;
10805 let narrow_value = err!(self.builder.build_int_truncate(
10806 value,
10807 self.intrinsics.i32_ty,
10808 ""
10809 ));
10810 let old = self
10811 .builder
10812 .build_atomicrmw(
10813 AtomicRMWBinOp::And,
10814 effective_address,
10815 narrow_value,
10816 AtomicOrdering::SequentiallyConsistent,
10817 )
10818 .unwrap();
10819 self.annotate_user_memaccess(
10820 memory_index,
10821 memarg,
10822 0,
10823 old.as_instruction_value().unwrap(),
10824 )?;
10825 let old = err!(
10826 self.builder
10827 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
10828 );
10829 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
10830 }
10831 Operator::I64AtomicRmwAnd { ref memarg } => {
10832 let value = self.state.pop1()?.into_int_value();
10833 let offset = self.state.pop1()?.into_int_value();
10834 let memory_index = MemoryIndex::from_u32(0);
10835 let effective_address = self.resolve_memory_ptr(
10836 memory_index,
10837 memarg,
10838 self.intrinsics.ptr_ty,
10839 offset,
10840 8,
10841 )?;
10842 self.trap_if_misaligned(memarg, effective_address, 8)?;
10843 let old = self
10844 .builder
10845 .build_atomicrmw(
10846 AtomicRMWBinOp::And,
10847 effective_address,
10848 value,
10849 AtomicOrdering::SequentiallyConsistent,
10850 )
10851 .unwrap();
10852 self.annotate_user_memaccess(
10853 memory_index,
10854 memarg,
10855 0,
10856 old.as_instruction_value().unwrap(),
10857 )?;
10858 self.state.push1(old);
10859 }
10860 Operator::I32AtomicRmw8OrU { ref memarg } => {
10861 let value = self.state.pop1()?.into_int_value();
10862 let offset = self.state.pop1()?.into_int_value();
10863 let memory_index = MemoryIndex::from_u32(0);
10864 let effective_address = self.resolve_memory_ptr(
10865 memory_index,
10866 memarg,
10867 self.intrinsics.ptr_ty,
10868 offset,
10869 1,
10870 )?;
10871 self.trap_if_misaligned(memarg, effective_address, 1)?;
10872 let narrow_value = err!(self.builder.build_int_truncate(
10873 value,
10874 self.intrinsics.i8_ty,
10875 ""
10876 ));
10877 let old = self
10878 .builder
10879 .build_atomicrmw(
10880 AtomicRMWBinOp::Or,
10881 effective_address,
10882 narrow_value,
10883 AtomicOrdering::SequentiallyConsistent,
10884 )
10885 .unwrap();
10886 self.annotate_user_memaccess(
10887 memory_index,
10888 memarg,
10889 0,
10890 old.as_instruction_value().unwrap(),
10891 )?;
10892 let old = err!(
10893 self.builder
10894 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10895 );
10896 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10897 }
10898 Operator::I32AtomicRmw16OrU { ref memarg } => {
10899 let value = self.state.pop1()?.into_int_value();
10900 let offset = self.state.pop1()?.into_int_value();
10901 let memory_index = MemoryIndex::from_u32(0);
10902 let effective_address = self.resolve_memory_ptr(
10903 memory_index,
10904 memarg,
10905 self.intrinsics.ptr_ty,
10906 offset,
10907 2,
10908 )?;
10909 self.trap_if_misaligned(memarg, effective_address, 2)?;
10910 let narrow_value = err!(self.builder.build_int_truncate(
10911 value,
10912 self.intrinsics.i16_ty,
10913 ""
10914 ));
10915 let old = self
10916 .builder
10917 .build_atomicrmw(
10918 AtomicRMWBinOp::Or,
10919 effective_address,
10920 narrow_value,
10921 AtomicOrdering::SequentiallyConsistent,
10922 )
10923 .unwrap();
10924 self.annotate_user_memaccess(
10925 memory_index,
10926 memarg,
10927 0,
10928 old.as_instruction_value().unwrap(),
10929 )?;
10930 let old = err!(
10931 self.builder
10932 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10933 );
10934 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10935 }
10936 Operator::I32AtomicRmwOr { ref memarg } => {
10937 let value = self.state.pop1()?.into_int_value();
10938 let offset = self.state.pop1()?.into_int_value();
10939 let memory_index = MemoryIndex::from_u32(0);
10940 let effective_address = self.resolve_memory_ptr(
10941 memory_index,
10942 memarg,
10943 self.intrinsics.ptr_ty,
10944 offset,
10945 4,
10946 )?;
10947 self.trap_if_misaligned(memarg, effective_address, 4)?;
10948 let old = self
10949 .builder
10950 .build_atomicrmw(
10951 AtomicRMWBinOp::Or,
10952 effective_address,
10953 value,
10954 AtomicOrdering::SequentiallyConsistent,
10955 )
10956 .unwrap();
10957 self.annotate_user_memaccess(
10958 memory_index,
10959 memarg,
10960 0,
10961 old.as_instruction_value().unwrap(),
10962 )?;
10963 let old = err!(
10964 self.builder
10965 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
10966 );
10967 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
10968 }
10969 Operator::I64AtomicRmw8OrU { ref memarg } => {
10970 let value = self.state.pop1()?.into_int_value();
10971 let offset = self.state.pop1()?.into_int_value();
10972 let memory_index = MemoryIndex::from_u32(0);
10973 let effective_address = self.resolve_memory_ptr(
10974 memory_index,
10975 memarg,
10976 self.intrinsics.ptr_ty,
10977 offset,
10978 1,
10979 )?;
10980 self.trap_if_misaligned(memarg, effective_address, 1)?;
10981 let narrow_value = err!(self.builder.build_int_truncate(
10982 value,
10983 self.intrinsics.i8_ty,
10984 ""
10985 ));
10986 let old = self
10987 .builder
10988 .build_atomicrmw(
10989 AtomicRMWBinOp::Or,
10990 effective_address,
10991 narrow_value,
10992 AtomicOrdering::SequentiallyConsistent,
10993 )
10994 .unwrap();
10995 self.annotate_user_memaccess(
10996 memory_index,
10997 memarg,
10998 0,
10999 old.as_instruction_value().unwrap(),
11000 )?;
11001 let old = err!(
11002 self.builder
11003 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11004 );
11005 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11006 }
11007 Operator::I64AtomicRmw16OrU { ref memarg } => {
11008 let value = self.state.pop1()?.into_int_value();
11009 let offset = self.state.pop1()?.into_int_value();
11010 let memory_index = MemoryIndex::from_u32(0);
11011 let effective_address = self.resolve_memory_ptr(
11012 memory_index,
11013 memarg,
11014 self.intrinsics.ptr_ty,
11015 offset,
11016 2,
11017 )?;
11018 self.trap_if_misaligned(memarg, effective_address, 2)?;
11019 let narrow_value = err!(self.builder.build_int_truncate(
11020 value,
11021 self.intrinsics.i16_ty,
11022 ""
11023 ));
11024 let old = self
11025 .builder
11026 .build_atomicrmw(
11027 AtomicRMWBinOp::Or,
11028 effective_address,
11029 narrow_value,
11030 AtomicOrdering::SequentiallyConsistent,
11031 )
11032 .unwrap();
11033 self.annotate_user_memaccess(
11034 memory_index,
11035 memarg,
11036 0,
11037 old.as_instruction_value().unwrap(),
11038 )?;
11039 let old = err!(
11040 self.builder
11041 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11042 );
11043 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11044 }
11045 Operator::I64AtomicRmw32OrU { ref memarg } => {
11046 let value = self.state.pop1()?.into_int_value();
11047 let offset = self.state.pop1()?.into_int_value();
11048 let memory_index = MemoryIndex::from_u32(0);
11049 let effective_address = self.resolve_memory_ptr(
11050 memory_index,
11051 memarg,
11052 self.intrinsics.ptr_ty,
11053 offset,
11054 4,
11055 )?;
11056 self.trap_if_misaligned(memarg, effective_address, 4)?;
11057 let narrow_value = err!(self.builder.build_int_truncate(
11058 value,
11059 self.intrinsics.i32_ty,
11060 ""
11061 ));
11062 let old = self
11063 .builder
11064 .build_atomicrmw(
11065 AtomicRMWBinOp::Or,
11066 effective_address,
11067 narrow_value,
11068 AtomicOrdering::SequentiallyConsistent,
11069 )
11070 .unwrap();
11071 self.annotate_user_memaccess(
11072 memory_index,
11073 memarg,
11074 0,
11075 old.as_instruction_value().unwrap(),
11076 )?;
11077 let old = err!(
11078 self.builder
11079 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11080 );
11081 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11082 }
11083 Operator::I64AtomicRmwOr { ref memarg } => {
11084 let value = self.state.pop1()?.into_int_value();
11085 let offset = self.state.pop1()?.into_int_value();
11086 let memory_index = MemoryIndex::from_u32(0);
11087 let effective_address = self.resolve_memory_ptr(
11088 memory_index,
11089 memarg,
11090 self.intrinsics.ptr_ty,
11091 offset,
11092 8,
11093 )?;
11094 self.trap_if_misaligned(memarg, effective_address, 8)?;
11095 let old = self
11096 .builder
11097 .build_atomicrmw(
11098 AtomicRMWBinOp::Or,
11099 effective_address,
11100 value,
11101 AtomicOrdering::SequentiallyConsistent,
11102 )
11103 .unwrap();
11104 self.annotate_user_memaccess(
11105 memory_index,
11106 memarg,
11107 0,
11108 old.as_instruction_value().unwrap(),
11109 )?;
11110 self.state.push1(old);
11111 }
11112 Operator::I32AtomicRmw8XorU { ref memarg } => {
11113 let value = self.state.pop1()?.into_int_value();
11114 let offset = self.state.pop1()?.into_int_value();
11115 let memory_index = MemoryIndex::from_u32(0);
11116 let effective_address = self.resolve_memory_ptr(
11117 memory_index,
11118 memarg,
11119 self.intrinsics.ptr_ty,
11120 offset,
11121 1,
11122 )?;
11123 self.trap_if_misaligned(memarg, effective_address, 2)?;
11124 let narrow_value = err!(self.builder.build_int_truncate(
11125 value,
11126 self.intrinsics.i8_ty,
11127 ""
11128 ));
11129 let old = self
11130 .builder
11131 .build_atomicrmw(
11132 AtomicRMWBinOp::Xor,
11133 effective_address,
11134 narrow_value,
11135 AtomicOrdering::SequentiallyConsistent,
11136 )
11137 .unwrap();
11138 self.annotate_user_memaccess(
11139 memory_index,
11140 memarg,
11141 0,
11142 old.as_instruction_value().unwrap(),
11143 )?;
11144 let old = err!(
11145 self.builder
11146 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11147 );
11148 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11149 }
11150 Operator::I32AtomicRmw16XorU { ref memarg } => {
11151 let value = self.state.pop1()?.into_int_value();
11152 let offset = self.state.pop1()?.into_int_value();
11153 let memory_index = MemoryIndex::from_u32(0);
11154 let effective_address = self.resolve_memory_ptr(
11155 memory_index,
11156 memarg,
11157 self.intrinsics.ptr_ty,
11158 offset,
11159 2,
11160 )?;
11161 self.trap_if_misaligned(memarg, effective_address, 2)?;
11162 let narrow_value = err!(self.builder.build_int_truncate(
11163 value,
11164 self.intrinsics.i16_ty,
11165 ""
11166 ));
11167 let old = self
11168 .builder
11169 .build_atomicrmw(
11170 AtomicRMWBinOp::Xor,
11171 effective_address,
11172 narrow_value,
11173 AtomicOrdering::SequentiallyConsistent,
11174 )
11175 .unwrap();
11176 self.annotate_user_memaccess(
11177 memory_index,
11178 memarg,
11179 0,
11180 old.as_instruction_value().unwrap(),
11181 )?;
11182 let old = err!(
11183 self.builder
11184 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11185 );
11186 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11187 }
11188 Operator::I32AtomicRmwXor { ref memarg } => {
11189 let value = self.state.pop1()?.into_int_value();
11190 let offset = self.state.pop1()?.into_int_value();
11191 let memory_index = MemoryIndex::from_u32(0);
11192 let effective_address = self.resolve_memory_ptr(
11193 memory_index,
11194 memarg,
11195 self.intrinsics.ptr_ty,
11196 offset,
11197 4,
11198 )?;
11199 self.trap_if_misaligned(memarg, effective_address, 4)?;
11200 let old = self
11201 .builder
11202 .build_atomicrmw(
11203 AtomicRMWBinOp::Xor,
11204 effective_address,
11205 value,
11206 AtomicOrdering::SequentiallyConsistent,
11207 )
11208 .unwrap();
11209 self.annotate_user_memaccess(
11210 memory_index,
11211 memarg,
11212 0,
11213 old.as_instruction_value().unwrap(),
11214 )?;
11215 self.state.push1(old);
11216 }
11217 Operator::I64AtomicRmw8XorU { ref memarg } => {
11218 let value = self.state.pop1()?.into_int_value();
11219 let offset = self.state.pop1()?.into_int_value();
11220 let memory_index = MemoryIndex::from_u32(0);
11221 let effective_address = self.resolve_memory_ptr(
11222 memory_index,
11223 memarg,
11224 self.intrinsics.ptr_ty,
11225 offset,
11226 1,
11227 )?;
11228 self.trap_if_misaligned(memarg, effective_address, 1)?;
11229 let narrow_value = err!(self.builder.build_int_truncate(
11230 value,
11231 self.intrinsics.i8_ty,
11232 ""
11233 ));
11234 let old = self
11235 .builder
11236 .build_atomicrmw(
11237 AtomicRMWBinOp::Xor,
11238 effective_address,
11239 narrow_value,
11240 AtomicOrdering::SequentiallyConsistent,
11241 )
11242 .unwrap();
11243 self.annotate_user_memaccess(
11244 memory_index,
11245 memarg,
11246 0,
11247 old.as_instruction_value().unwrap(),
11248 )?;
11249 let old = err!(
11250 self.builder
11251 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11252 );
11253 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11254 }
11255 Operator::I64AtomicRmw16XorU { ref memarg } => {
11256 let value = self.state.pop1()?.into_int_value();
11257 let offset = self.state.pop1()?.into_int_value();
11258 let memory_index = MemoryIndex::from_u32(0);
11259 let effective_address = self.resolve_memory_ptr(
11260 memory_index,
11261 memarg,
11262 self.intrinsics.ptr_ty,
11263 offset,
11264 2,
11265 )?;
11266 self.trap_if_misaligned(memarg, effective_address, 2)?;
11267 let narrow_value = err!(self.builder.build_int_truncate(
11268 value,
11269 self.intrinsics.i16_ty,
11270 ""
11271 ));
11272 let old = self
11273 .builder
11274 .build_atomicrmw(
11275 AtomicRMWBinOp::Xor,
11276 effective_address,
11277 narrow_value,
11278 AtomicOrdering::SequentiallyConsistent,
11279 )
11280 .unwrap();
11281 self.annotate_user_memaccess(
11282 memory_index,
11283 memarg,
11284 0,
11285 old.as_instruction_value().unwrap(),
11286 )?;
11287 let old = err!(
11288 self.builder
11289 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11290 );
11291 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11292 }
11293 Operator::I64AtomicRmw32XorU { ref memarg } => {
11294 let value = self.state.pop1()?.into_int_value();
11295 let offset = self.state.pop1()?.into_int_value();
11296 let memory_index = MemoryIndex::from_u32(0);
11297 let effective_address = self.resolve_memory_ptr(
11298 memory_index,
11299 memarg,
11300 self.intrinsics.ptr_ty,
11301 offset,
11302 4,
11303 )?;
11304 self.trap_if_misaligned(memarg, effective_address, 4)?;
11305 let narrow_value = err!(self.builder.build_int_truncate(
11306 value,
11307 self.intrinsics.i32_ty,
11308 ""
11309 ));
11310 let old = self
11311 .builder
11312 .build_atomicrmw(
11313 AtomicRMWBinOp::Xor,
11314 effective_address,
11315 narrow_value,
11316 AtomicOrdering::SequentiallyConsistent,
11317 )
11318 .unwrap();
11319 self.annotate_user_memaccess(
11320 memory_index,
11321 memarg,
11322 0,
11323 old.as_instruction_value().unwrap(),
11324 )?;
11325 let old = err!(
11326 self.builder
11327 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11328 );
11329 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11330 }
11331 Operator::I64AtomicRmwXor { ref memarg } => {
11332 let value = self.state.pop1()?.into_int_value();
11333 let offset = self.state.pop1()?.into_int_value();
11334 let memory_index = MemoryIndex::from_u32(0);
11335 let effective_address = self.resolve_memory_ptr(
11336 memory_index,
11337 memarg,
11338 self.intrinsics.ptr_ty,
11339 offset,
11340 8,
11341 )?;
11342 self.trap_if_misaligned(memarg, effective_address, 8)?;
11343 let old = self
11344 .builder
11345 .build_atomicrmw(
11346 AtomicRMWBinOp::Xor,
11347 effective_address,
11348 value,
11349 AtomicOrdering::SequentiallyConsistent,
11350 )
11351 .unwrap();
11352 self.annotate_user_memaccess(
11353 memory_index,
11354 memarg,
11355 0,
11356 old.as_instruction_value().unwrap(),
11357 )?;
11358 self.state.push1(old);
11359 }
11360 Operator::I32AtomicRmw8XchgU { ref memarg } => {
11361 let value = self.state.pop1()?.into_int_value();
11362 let offset = self.state.pop1()?.into_int_value();
11363 let memory_index = MemoryIndex::from_u32(0);
11364 let effective_address = self.resolve_memory_ptr(
11365 memory_index,
11366 memarg,
11367 self.intrinsics.ptr_ty,
11368 offset,
11369 1,
11370 )?;
11371 self.trap_if_misaligned(memarg, effective_address, 1)?;
11372 let narrow_value = err!(self.builder.build_int_truncate(
11373 value,
11374 self.intrinsics.i8_ty,
11375 ""
11376 ));
11377 let old = self
11378 .builder
11379 .build_atomicrmw(
11380 AtomicRMWBinOp::Xchg,
11381 effective_address,
11382 narrow_value,
11383 AtomicOrdering::SequentiallyConsistent,
11384 )
11385 .unwrap();
11386 self.annotate_user_memaccess(
11387 memory_index,
11388 memarg,
11389 0,
11390 old.as_instruction_value().unwrap(),
11391 )?;
11392 let old = err!(
11393 self.builder
11394 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11395 );
11396 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11397 }
11398 Operator::I32AtomicRmw16XchgU { ref memarg } => {
11399 let value = self.state.pop1()?.into_int_value();
11400 let offset = self.state.pop1()?.into_int_value();
11401 let memory_index = MemoryIndex::from_u32(0);
11402 let effective_address = self.resolve_memory_ptr(
11403 memory_index,
11404 memarg,
11405 self.intrinsics.ptr_ty,
11406 offset,
11407 2,
11408 )?;
11409 self.trap_if_misaligned(memarg, effective_address, 2)?;
11410 let narrow_value = err!(self.builder.build_int_truncate(
11411 value,
11412 self.intrinsics.i16_ty,
11413 ""
11414 ));
11415 let old = self
11416 .builder
11417 .build_atomicrmw(
11418 AtomicRMWBinOp::Xchg,
11419 effective_address,
11420 narrow_value,
11421 AtomicOrdering::SequentiallyConsistent,
11422 )
11423 .unwrap();
11424 self.annotate_user_memaccess(
11425 memory_index,
11426 memarg,
11427 0,
11428 old.as_instruction_value().unwrap(),
11429 )?;
11430 let old = err!(
11431 self.builder
11432 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11433 );
11434 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11435 }
11436 Operator::I32AtomicRmwXchg { ref memarg } => {
11437 let value = self.state.pop1()?.into_int_value();
11438 let offset = self.state.pop1()?.into_int_value();
11439 let memory_index = MemoryIndex::from_u32(0);
11440 let effective_address = self.resolve_memory_ptr(
11441 memory_index,
11442 memarg,
11443 self.intrinsics.ptr_ty,
11444 offset,
11445 4,
11446 )?;
11447 self.trap_if_misaligned(memarg, effective_address, 4)?;
11448 let old = self
11449 .builder
11450 .build_atomicrmw(
11451 AtomicRMWBinOp::Xchg,
11452 effective_address,
11453 value,
11454 AtomicOrdering::SequentiallyConsistent,
11455 )
11456 .unwrap();
11457 self.annotate_user_memaccess(
11458 memory_index,
11459 memarg,
11460 0,
11461 old.as_instruction_value().unwrap(),
11462 )?;
11463 self.state.push1(old);
11464 }
11465 Operator::I64AtomicRmw8XchgU { ref memarg } => {
11466 let value = self.state.pop1()?.into_int_value();
11467 let offset = self.state.pop1()?.into_int_value();
11468 let memory_index = MemoryIndex::from_u32(0);
11469 let effective_address = self.resolve_memory_ptr(
11470 memory_index,
11471 memarg,
11472 self.intrinsics.ptr_ty,
11473 offset,
11474 1,
11475 )?;
11476 self.trap_if_misaligned(memarg, effective_address, 1)?;
11477 let narrow_value = err!(self.builder.build_int_truncate(
11478 value,
11479 self.intrinsics.i8_ty,
11480 ""
11481 ));
11482 let old = self
11483 .builder
11484 .build_atomicrmw(
11485 AtomicRMWBinOp::Xchg,
11486 effective_address,
11487 narrow_value,
11488 AtomicOrdering::SequentiallyConsistent,
11489 )
11490 .unwrap();
11491 self.annotate_user_memaccess(
11492 memory_index,
11493 memarg,
11494 0,
11495 old.as_instruction_value().unwrap(),
11496 )?;
11497 let old = err!(
11498 self.builder
11499 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11500 );
11501 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11502 }
11503 Operator::I64AtomicRmw16XchgU { ref memarg } => {
11504 let value = self.state.pop1()?.into_int_value();
11505 let offset = self.state.pop1()?.into_int_value();
11506 let memory_index = MemoryIndex::from_u32(0);
11507 let effective_address = self.resolve_memory_ptr(
11508 memory_index,
11509 memarg,
11510 self.intrinsics.ptr_ty,
11511 offset,
11512 2,
11513 )?;
11514 self.trap_if_misaligned(memarg, effective_address, 2)?;
11515 let narrow_value = err!(self.builder.build_int_truncate(
11516 value,
11517 self.intrinsics.i16_ty,
11518 ""
11519 ));
11520 let old = self
11521 .builder
11522 .build_atomicrmw(
11523 AtomicRMWBinOp::Xchg,
11524 effective_address,
11525 narrow_value,
11526 AtomicOrdering::SequentiallyConsistent,
11527 )
11528 .unwrap();
11529 self.annotate_user_memaccess(
11530 memory_index,
11531 memarg,
11532 0,
11533 old.as_instruction_value().unwrap(),
11534 )?;
11535 let old = err!(
11536 self.builder
11537 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11538 );
11539 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11540 }
11541 Operator::I64AtomicRmw32XchgU { ref memarg } => {
11542 let value = self.state.pop1()?.into_int_value();
11543 let offset = self.state.pop1()?.into_int_value();
11544 let memory_index = MemoryIndex::from_u32(0);
11545 let effective_address = self.resolve_memory_ptr(
11546 memory_index,
11547 memarg,
11548 self.intrinsics.ptr_ty,
11549 offset,
11550 4,
11551 )?;
11552 self.trap_if_misaligned(memarg, effective_address, 4)?;
11553 let narrow_value = err!(self.builder.build_int_truncate(
11554 value,
11555 self.intrinsics.i32_ty,
11556 ""
11557 ));
11558 let old = self
11559 .builder
11560 .build_atomicrmw(
11561 AtomicRMWBinOp::Xchg,
11562 effective_address,
11563 narrow_value,
11564 AtomicOrdering::SequentiallyConsistent,
11565 )
11566 .unwrap();
11567 self.annotate_user_memaccess(
11568 memory_index,
11569 memarg,
11570 0,
11571 old.as_instruction_value().unwrap(),
11572 )?;
11573 let old = err!(
11574 self.builder
11575 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11576 );
11577 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11578 }
11579 Operator::I64AtomicRmwXchg { ref memarg } => {
11580 let value = self.state.pop1()?.into_int_value();
11581 let offset = self.state.pop1()?.into_int_value();
11582 let memory_index = MemoryIndex::from_u32(0);
11583 let effective_address = self.resolve_memory_ptr(
11584 memory_index,
11585 memarg,
11586 self.intrinsics.ptr_ty,
11587 offset,
11588 8,
11589 )?;
11590 self.trap_if_misaligned(memarg, effective_address, 8)?;
11591 let old = self
11592 .builder
11593 .build_atomicrmw(
11594 AtomicRMWBinOp::Xchg,
11595 effective_address,
11596 value,
11597 AtomicOrdering::SequentiallyConsistent,
11598 )
11599 .unwrap();
11600 self.annotate_user_memaccess(
11601 memory_index,
11602 memarg,
11603 0,
11604 old.as_instruction_value().unwrap(),
11605 )?;
11606 self.state.push1(old);
11607 }
11608 Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
11609 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11610 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11611 let new = self.apply_pending_canonicalization(new, new_info)?;
11612 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11613 let offset = self.state.pop1()?.into_int_value();
11614 let memory_index = MemoryIndex::from_u32(0);
11615 let effective_address = self.resolve_memory_ptr(
11616 memory_index,
11617 memarg,
11618 self.intrinsics.ptr_ty,
11619 offset,
11620 1,
11621 )?;
11622 self.trap_if_misaligned(memarg, effective_address, 1)?;
11623 let narrow_cmp = err!(self.builder.build_int_truncate(
11624 cmp,
11625 self.intrinsics.i8_ty,
11626 ""
11627 ));
11628 let narrow_new = err!(self.builder.build_int_truncate(
11629 new,
11630 self.intrinsics.i8_ty,
11631 ""
11632 ));
11633 let old = self
11634 .builder
11635 .build_cmpxchg(
11636 effective_address,
11637 narrow_cmp,
11638 narrow_new,
11639 AtomicOrdering::SequentiallyConsistent,
11640 AtomicOrdering::SequentiallyConsistent,
11641 )
11642 .unwrap();
11643 self.annotate_user_memaccess(
11644 memory_index,
11645 memarg,
11646 0,
11647 old.as_instruction_value().unwrap(),
11648 )?;
11649 let old = self
11650 .builder
11651 .build_extract_value(old, 0, "")
11652 .unwrap()
11653 .into_int_value();
11654 let old = err!(
11655 self.builder
11656 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11657 );
11658 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11659 }
11660 Operator::I32AtomicRmw16CmpxchgU { ref memarg } => {
11661 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11662 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11663 let new = self.apply_pending_canonicalization(new, new_info)?;
11664 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11665 let offset = self.state.pop1()?.into_int_value();
11666 let memory_index = MemoryIndex::from_u32(0);
11667 let effective_address = self.resolve_memory_ptr(
11668 memory_index,
11669 memarg,
11670 self.intrinsics.ptr_ty,
11671 offset,
11672 2,
11673 )?;
11674 self.trap_if_misaligned(memarg, effective_address, 2)?;
11675 let narrow_cmp = err!(self.builder.build_int_truncate(
11676 cmp,
11677 self.intrinsics.i16_ty,
11678 ""
11679 ));
11680 let narrow_new = err!(self.builder.build_int_truncate(
11681 new,
11682 self.intrinsics.i16_ty,
11683 ""
11684 ));
11685 let old = self
11686 .builder
11687 .build_cmpxchg(
11688 effective_address,
11689 narrow_cmp,
11690 narrow_new,
11691 AtomicOrdering::SequentiallyConsistent,
11692 AtomicOrdering::SequentiallyConsistent,
11693 )
11694 .unwrap();
11695 self.annotate_user_memaccess(
11696 memory_index,
11697 memarg,
11698 0,
11699 old.as_instruction_value().unwrap(),
11700 )?;
11701 let old = self
11702 .builder
11703 .build_extract_value(old, 0, "")
11704 .unwrap()
11705 .into_int_value();
11706 let old = err!(
11707 self.builder
11708 .build_int_z_extend(old, self.intrinsics.i32_ty, "")
11709 );
11710 self.state.push1_extra(old, ExtraInfo::arithmetic_f32());
11711 }
11712 Operator::I32AtomicRmwCmpxchg { ref memarg } => {
11713 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11714 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11715 let new = self.apply_pending_canonicalization(new, new_info)?;
11716 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11717 let offset = self.state.pop1()?.into_int_value();
11718 let memory_index = MemoryIndex::from_u32(0);
11719 let effective_address = self.resolve_memory_ptr(
11720 memory_index,
11721 memarg,
11722 self.intrinsics.ptr_ty,
11723 offset,
11724 4,
11725 )?;
11726 self.trap_if_misaligned(memarg, effective_address, 4)?;
11727 let old = self
11728 .builder
11729 .build_cmpxchg(
11730 effective_address,
11731 cmp,
11732 new,
11733 AtomicOrdering::SequentiallyConsistent,
11734 AtomicOrdering::SequentiallyConsistent,
11735 )
11736 .unwrap();
11737 self.annotate_user_memaccess(
11738 memory_index,
11739 memarg,
11740 0,
11741 old.as_instruction_value().unwrap(),
11742 )?;
11743 let old = err!(self.builder.build_extract_value(old, 0, ""));
11744 self.state.push1(old);
11745 }
11746 Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
11747 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11748 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11749 let new = self.apply_pending_canonicalization(new, new_info)?;
11750 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11751 let offset = self.state.pop1()?.into_int_value();
11752 let memory_index = MemoryIndex::from_u32(0);
11753 let effective_address = self.resolve_memory_ptr(
11754 memory_index,
11755 memarg,
11756 self.intrinsics.ptr_ty,
11757 offset,
11758 1,
11759 )?;
11760 self.trap_if_misaligned(memarg, effective_address, 1)?;
11761 let narrow_cmp = err!(self.builder.build_int_truncate(
11762 cmp,
11763 self.intrinsics.i8_ty,
11764 ""
11765 ));
11766 let narrow_new = err!(self.builder.build_int_truncate(
11767 new,
11768 self.intrinsics.i8_ty,
11769 ""
11770 ));
11771 let old = self
11772 .builder
11773 .build_cmpxchg(
11774 effective_address,
11775 narrow_cmp,
11776 narrow_new,
11777 AtomicOrdering::SequentiallyConsistent,
11778 AtomicOrdering::SequentiallyConsistent,
11779 )
11780 .unwrap();
11781 self.annotate_user_memaccess(
11782 memory_index,
11783 memarg,
11784 0,
11785 old.as_instruction_value().unwrap(),
11786 )?;
11787 let old = self
11788 .builder
11789 .build_extract_value(old, 0, "")
11790 .unwrap()
11791 .into_int_value();
11792 let old = err!(
11793 self.builder
11794 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11795 );
11796 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11797 }
11798 Operator::I64AtomicRmw16CmpxchgU { ref memarg } => {
11799 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11800 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11801 let new = self.apply_pending_canonicalization(new, new_info)?;
11802 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11803 let offset = self.state.pop1()?.into_int_value();
11804 let memory_index = MemoryIndex::from_u32(0);
11805 let effective_address = self.resolve_memory_ptr(
11806 memory_index,
11807 memarg,
11808 self.intrinsics.ptr_ty,
11809 offset,
11810 2,
11811 )?;
11812 self.trap_if_misaligned(memarg, effective_address, 2)?;
11813 let narrow_cmp = err!(self.builder.build_int_truncate(
11814 cmp,
11815 self.intrinsics.i16_ty,
11816 ""
11817 ));
11818 let narrow_new = err!(self.builder.build_int_truncate(
11819 new,
11820 self.intrinsics.i16_ty,
11821 ""
11822 ));
11823 let old = self
11824 .builder
11825 .build_cmpxchg(
11826 effective_address,
11827 narrow_cmp,
11828 narrow_new,
11829 AtomicOrdering::SequentiallyConsistent,
11830 AtomicOrdering::SequentiallyConsistent,
11831 )
11832 .unwrap();
11833 self.annotate_user_memaccess(
11834 memory_index,
11835 memarg,
11836 0,
11837 old.as_instruction_value().unwrap(),
11838 )?;
11839 let old = self
11840 .builder
11841 .build_extract_value(old, 0, "")
11842 .unwrap()
11843 .into_int_value();
11844 let old = err!(
11845 self.builder
11846 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11847 );
11848 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11849 }
11850 Operator::I64AtomicRmw32CmpxchgU { ref memarg } => {
11851 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11852 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11853 let new = self.apply_pending_canonicalization(new, new_info)?;
11854 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11855 let offset = self.state.pop1()?.into_int_value();
11856 let memory_index = MemoryIndex::from_u32(0);
11857 let effective_address = self.resolve_memory_ptr(
11858 memory_index,
11859 memarg,
11860 self.intrinsics.ptr_ty,
11861 offset,
11862 4,
11863 )?;
11864 self.trap_if_misaligned(memarg, effective_address, 4)?;
11865 let narrow_cmp = err!(self.builder.build_int_truncate(
11866 cmp,
11867 self.intrinsics.i32_ty,
11868 ""
11869 ));
11870 let narrow_new = err!(self.builder.build_int_truncate(
11871 new,
11872 self.intrinsics.i32_ty,
11873 ""
11874 ));
11875 let old = self
11876 .builder
11877 .build_cmpxchg(
11878 effective_address,
11879 narrow_cmp,
11880 narrow_new,
11881 AtomicOrdering::SequentiallyConsistent,
11882 AtomicOrdering::SequentiallyConsistent,
11883 )
11884 .unwrap();
11885 self.annotate_user_memaccess(
11886 memory_index,
11887 memarg,
11888 0,
11889 old.as_instruction_value().unwrap(),
11890 )?;
11891 let old = self
11892 .builder
11893 .build_extract_value(old, 0, "")
11894 .unwrap()
11895 .into_int_value();
11896 let old = err!(
11897 self.builder
11898 .build_int_z_extend(old, self.intrinsics.i64_ty, "")
11899 );
11900 self.state.push1_extra(old, ExtraInfo::arithmetic_f64());
11901 }
11902 Operator::I64AtomicRmwCmpxchg { ref memarg } => {
11903 let ((cmp, cmp_info), (new, new_info)) = self.state.pop2_extra()?;
11904 let cmp = self.apply_pending_canonicalization(cmp, cmp_info)?;
11905 let new = self.apply_pending_canonicalization(new, new_info)?;
11906 let (cmp, new) = (cmp.into_int_value(), new.into_int_value());
11907 let offset = self.state.pop1()?.into_int_value();
11908 let memory_index = MemoryIndex::from_u32(0);
11909 let effective_address = self.resolve_memory_ptr(
11910 memory_index,
11911 memarg,
11912 self.intrinsics.ptr_ty,
11913 offset,
11914 8,
11915 )?;
11916 self.trap_if_misaligned(memarg, effective_address, 8)?;
11917 let old = self
11918 .builder
11919 .build_cmpxchg(
11920 effective_address,
11921 cmp,
11922 new,
11923 AtomicOrdering::SequentiallyConsistent,
11924 AtomicOrdering::SequentiallyConsistent,
11925 )
11926 .unwrap();
11927 self.annotate_user_memaccess(
11928 memory_index,
11929 memarg,
11930 0,
11931 old.as_instruction_value().unwrap(),
11932 )?;
11933 let old = err!(self.builder.build_extract_value(old, 0, ""));
11934 self.state.push1(old);
11935 }
11936
11937 Operator::MemoryGrow { mem } => {
11938 let memory_index = MemoryIndex::from_u32(mem);
11939 let delta = self.state.pop1()?;
11940 let grow_fn_ptr = self.ctx.memory_grow(memory_index, self.intrinsics)?;
11941 let grow = err!(self.builder.build_indirect_call(
11942 self.intrinsics.memory_grow_ty,
11943 grow_fn_ptr,
11944 &[
11945 vmctx.as_basic_value_enum().into(),
11946 delta.into(),
11947 self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11948 ],
11949 "",
11950 ));
11951 self.state.push1(grow.try_as_basic_value().unwrap_basic());
11952 }
11953 Operator::MemorySize { mem } => {
11954 let memory_index = MemoryIndex::from_u32(mem);
11955 let size_fn_ptr = self.ctx.memory_size(memory_index, self.intrinsics)?;
11956 let size = err!(self.builder.build_indirect_call(
11957 self.intrinsics.memory_size_ty,
11958 size_fn_ptr,
11959 &[
11960 vmctx.as_basic_value_enum().into(),
11961 self.intrinsics.i32_ty.const_int(mem.into(), false).into(),
11962 ],
11963 "",
11964 ));
11965 self.state.push1(size.try_as_basic_value().unwrap_basic());
11967 }
11968 Operator::MemoryInit { data_index, mem } => {
11969 let (dest, src, len) = self.state.pop3()?;
11970 let mem = self.intrinsics.i32_ty.const_int(mem.into(), false);
11971 let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11972 err!(self.builder.build_call(
11973 self.intrinsics.memory_init,
11974 &[
11975 vmctx.as_basic_value_enum().into(),
11976 mem.into(),
11977 segment.into(),
11978 dest.into(),
11979 src.into(),
11980 len.into(),
11981 ],
11982 "",
11983 ));
11984 }
11985 Operator::DataDrop { data_index } => {
11986 let segment = self.intrinsics.i32_ty.const_int(data_index.into(), false);
11987 err!(self.builder.build_call(
11988 self.intrinsics.data_drop,
11989 &[vmctx.as_basic_value_enum().into(), segment.into()],
11990 "",
11991 ));
11992 }
11993 Operator::MemoryCopy { dst_mem, src_mem } => {
11994 let _dst = dst_mem;
11996 let (memory_copy, src) = if let Some(local_memory_index) = self
11997 .wasm_module
11998 .local_memory_index(MemoryIndex::from_u32(src_mem))
11999 {
12000 (self.intrinsics.memory_copy, local_memory_index.as_u32())
12001 } else {
12002 (self.intrinsics.imported_memory_copy, src_mem)
12003 };
12004
12005 let (dest_pos, src_pos, len) = self.state.pop3()?;
12006 let src_index = self.intrinsics.i32_ty.const_int(src.into(), false);
12007 err!(self.builder.build_call(
12008 memory_copy,
12009 &[
12010 vmctx.as_basic_value_enum().into(),
12011 src_index.into(),
12012 dest_pos.into(),
12013 src_pos.into(),
12014 len.into(),
12015 ],
12016 "",
12017 ));
12018 }
12019 Operator::MemoryFill { mem } => {
12020 let (memory_fill, mem) = if let Some(local_memory_index) = self
12021 .wasm_module
12022 .local_memory_index(MemoryIndex::from_u32(mem))
12023 {
12024 (self.intrinsics.memory_fill, local_memory_index.as_u32())
12025 } else {
12026 (self.intrinsics.imported_memory_fill, mem)
12027 };
12028
12029 let (dst, val, len) = self.state.pop3()?;
12030 let mem_index = self.intrinsics.i32_ty.const_int(mem.into(), false);
12031 err!(self.builder.build_call(
12032 memory_fill,
12033 &[
12034 vmctx.as_basic_value_enum().into(),
12035 mem_index.into(),
12036 dst.into(),
12037 val.into(),
12038 len.into(),
12039 ],
12040 "",
12041 ));
12042 }
12043 Operator::RefNull { hty } => {
12048 let ty = err!(wpheaptype_to_type(hty));
12049 let ty = type_to_llvm(self.intrinsics, ty)?;
12050 self.state.push1(ty.const_zero());
12051 }
12052 Operator::RefIsNull => {
12053 let value = self.state.pop1()?.into_pointer_value();
12054 let is_null = err!(self.builder.build_is_null(value, ""));
12055 let is_null = err!(self.builder.build_int_z_extend(
12056 is_null,
12057 self.intrinsics.i32_ty,
12058 ""
12059 ));
12060 self.state.push1(is_null);
12061 }
12062 Operator::RefFunc { function_index } => {
12063 let index = self
12064 .intrinsics
12065 .i32_ty
12066 .const_int(function_index.into(), false);
12067 let value = err!(self.builder.build_call(
12068 self.intrinsics.func_ref,
12069 &[self.ctx.basic().into(), index.into()],
12070 "",
12071 ))
12072 .try_as_basic_value()
12073 .unwrap_basic();
12074 self.state.push1(value);
12075 }
12076 Operator::TableGet { table } => {
12077 let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12078 let elem = self.state.pop1()?;
12079 let table_get = if self
12080 .wasm_module
12081 .local_table_index(TableIndex::from_u32(table))
12082 .is_some()
12083 {
12084 self.intrinsics.table_get
12085 } else {
12086 self.intrinsics.imported_table_get
12087 };
12088 let value = err!(self.builder.build_call(
12089 table_get,
12090 &[self.ctx.basic().into(), table_index.into(), elem.into()],
12091 "",
12092 ))
12093 .try_as_basic_value()
12094 .unwrap_basic();
12095 let value = err!(
12096 self.builder.build_bit_cast(
12097 value,
12098 type_to_llvm(
12099 self.intrinsics,
12100 self.wasm_module
12101 .tables
12102 .get(TableIndex::from_u32(table))
12103 .unwrap()
12104 .ty,
12105 )?,
12106 "",
12107 )
12108 );
12109 self.state.push1(value);
12110 }
12111 Operator::TableSet { table } => {
12112 let table_index = self.intrinsics.i32_ty.const_int(table.into(), false);
12113 let (elem, value) = self.state.pop2()?;
12114 let value = err!(
12115 self.builder
12116 .build_bit_cast(value, self.intrinsics.ptr_ty, "")
12117 );
12118 let table_set = if self
12119 .wasm_module
12120 .local_table_index(TableIndex::from_u32(table))
12121 .is_some()
12122 {
12123 self.intrinsics.table_set
12124 } else {
12125 self.intrinsics.imported_table_set
12126 };
12127 err!(self.builder.build_call(
12128 table_set,
12129 &[
12130 self.ctx.basic().into(),
12131 table_index.into(),
12132 elem.into(),
12133 value.into(),
12134 ],
12135 "",
12136 ));
12137 }
12138 Operator::TableCopy {
12139 dst_table,
12140 src_table,
12141 } => {
12142 let (dst, src, len) = self.state.pop3()?;
12143 let dst_table = self.intrinsics.i32_ty.const_int(dst_table as u64, false);
12144 let src_table = self.intrinsics.i32_ty.const_int(src_table as u64, false);
12145 err!(self.builder.build_call(
12146 self.intrinsics.table_copy,
12147 &[
12148 self.ctx.basic().into(),
12149 dst_table.into(),
12150 src_table.into(),
12151 dst.into(),
12152 src.into(),
12153 len.into(),
12154 ],
12155 "",
12156 ));
12157 }
12158 Operator::TableInit { elem_index, table } => {
12159 let (dst, src, len) = self.state.pop3()?;
12160 let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12161 let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12162 err!(self.builder.build_call(
12163 self.intrinsics.table_init,
12164 &[
12165 self.ctx.basic().into(),
12166 table.into(),
12167 segment.into(),
12168 dst.into(),
12169 src.into(),
12170 len.into(),
12171 ],
12172 "",
12173 ));
12174 }
12175 Operator::ElemDrop { elem_index } => {
12176 let segment = self.intrinsics.i32_ty.const_int(elem_index as u64, false);
12177 err!(self.builder.build_call(
12178 self.intrinsics.elem_drop,
12179 &[self.ctx.basic().into(), segment.into()],
12180 "",
12181 ));
12182 }
12183 Operator::TableFill { table } => {
12184 let table = self.intrinsics.i32_ty.const_int(table as u64, false);
12185 let (start, elem, len) = self.state.pop3()?;
12186 let elem = err!(
12187 self.builder
12188 .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12189 );
12190 err!(self.builder.build_call(
12191 self.intrinsics.table_fill,
12192 &[
12193 self.ctx.basic().into(),
12194 table.into(),
12195 start.into(),
12196 elem.into(),
12197 len.into(),
12198 ],
12199 "",
12200 ));
12201 }
12202 Operator::TableGrow { table } => {
12203 let (elem, delta) = self.state.pop2()?;
12204 let elem = err!(
12205 self.builder
12206 .build_bit_cast(elem, self.intrinsics.ptr_ty, "")
12207 );
12208 let (table_grow, table_index) = if let Some(local_table_index) = self
12209 .wasm_module
12210 .local_table_index(TableIndex::from_u32(table))
12211 {
12212 (self.intrinsics.table_grow, local_table_index.as_u32())
12213 } else {
12214 (self.intrinsics.imported_table_grow, table)
12215 };
12216 let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12217 let size = err!(self.builder.build_call(
12218 table_grow,
12219 &[
12220 self.ctx.basic().into(),
12221 elem.into(),
12222 delta.into(),
12223 table_index.into(),
12224 ],
12225 "",
12226 ))
12227 .try_as_basic_value()
12228 .unwrap_basic();
12229 self.state.push1(size);
12230 }
12231 Operator::TableSize { table } => {
12232 let (table_size, table_index) = if let Some(local_table_index) = self
12233 .wasm_module
12234 .local_table_index(TableIndex::from_u32(table))
12235 {
12236 (self.intrinsics.table_size, local_table_index.as_u32())
12237 } else {
12238 (self.intrinsics.imported_table_size, table)
12239 };
12240 let table_index = self.intrinsics.i32_ty.const_int(table_index as u64, false);
12241 let size = err!(self.builder.build_call(
12242 table_size,
12243 &[self.ctx.basic().into(), table_index.into()],
12244 "",
12245 ))
12246 .try_as_basic_value()
12247 .unwrap_basic();
12248 self.state.push1(size);
12249 }
12250 Operator::MemoryAtomicWait32 { memarg } => {
12251 let memory_index = MemoryIndex::from_u32(memarg.memory);
12252 let (dst, val, timeout) = self.state.pop3()?;
12253 let wait32_fn_ptr = self.ctx.memory_wait32(memory_index, self.intrinsics)?;
12254 let ret = err!(
12255 self.builder.build_indirect_call(
12256 self.intrinsics.memory_wait32_ty,
12257 wait32_fn_ptr,
12258 &[
12259 vmctx.as_basic_value_enum().into(),
12260 self.intrinsics
12261 .i32_ty
12262 .const_int(memarg.memory as u64, false)
12263 .into(),
12264 dst.into(),
12265 val.into(),
12266 timeout.into(),
12267 ],
12268 "",
12269 )
12270 );
12271 self.state.push1(ret.try_as_basic_value().unwrap_basic());
12272 }
12273 Operator::MemoryAtomicWait64 { memarg } => {
12274 let memory_index = MemoryIndex::from_u32(memarg.memory);
12275 let (dst, val, timeout) = self.state.pop3()?;
12276 let wait64_fn_ptr = self.ctx.memory_wait64(memory_index, self.intrinsics)?;
12277 let ret = err!(
12278 self.builder.build_indirect_call(
12279 self.intrinsics.memory_wait64_ty,
12280 wait64_fn_ptr,
12281 &[
12282 vmctx.as_basic_value_enum().into(),
12283 self.intrinsics
12284 .i32_ty
12285 .const_int(memarg.memory as u64, false)
12286 .into(),
12287 dst.into(),
12288 val.into(),
12289 timeout.into(),
12290 ],
12291 "",
12292 )
12293 );
12294 self.state.push1(ret.try_as_basic_value().unwrap_basic());
12295 }
12296 Operator::MemoryAtomicNotify { memarg } => {
12297 let memory_index = MemoryIndex::from_u32(memarg.memory);
12298 let (dst, count) = self.state.pop2()?;
12299 let notify_fn_ptr = self.ctx.memory_notify(memory_index, self.intrinsics)?;
12300 let cnt = err!(
12301 self.builder.build_indirect_call(
12302 self.intrinsics.memory_notify_ty,
12303 notify_fn_ptr,
12304 &[
12305 vmctx.as_basic_value_enum().into(),
12306 self.intrinsics
12307 .i32_ty
12308 .const_int(memarg.memory as u64, false)
12309 .into(),
12310 dst.into(),
12311 count.into(),
12312 ],
12313 "",
12314 )
12315 );
12316 self.state.push1(cnt.try_as_basic_value().unwrap_basic());
12317 }
12318
12319 Operator::TryTable { try_table } => {
12320 let current_block = self
12321 .builder
12322 .get_insert_block()
12323 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12324
12325 self.builder.position_at_end(current_block);
12326
12327 let end_block = self.context.append_basic_block(self.function, "try_end");
12328
12329 let end_phis = {
12330 self.builder.position_at_end(end_block);
12331
12332 let phis = self
12333 .module_translation
12334 .blocktype_params_results(&try_table.ty)?
12335 .1
12336 .iter()
12337 .map(|&wp_ty| {
12338 err_nt!(wptype_to_type(wp_ty)).and_then(|wasm_ty| {
12339 type_to_llvm(self.intrinsics, wasm_ty)
12340 .and_then(|ty| err_nt!(self.builder.build_phi(ty, "")))
12341 })
12342 })
12343 .collect::<Result<_, _>>()?;
12344
12345 self.builder.position_at_end(current_block);
12346 phis
12347 };
12348
12349 let catches: Vec<_> = try_table
12353 .catches
12354 .into_iter()
12355 .unique_by(|v| match v {
12356 Catch::One { tag, .. } | Catch::OneRef { tag, .. } => *tag as i32,
12357 Catch::All { .. } | Catch::AllRef { .. } => CATCH_ALL_TAG_VALUE,
12358 })
12359 .collect();
12360
12361 let null = self.intrinsics.ptr_ty.const_zero();
12363
12364 let mut catch_tag_values = vec![];
12365 let mut lpad_clauses: Vec<BasicValueEnum<'ctx>> = catches
12366 .iter()
12367 .map(|catch| match catch {
12368 Catch::All { .. } | Catch::AllRef { .. } => {
12369 catch_tag_values.push(CATCH_ALL_TAG_VALUE as u32);
12370 Ok(null.into())
12371 }
12372 Catch::One { tag, .. } | Catch::OneRef { tag, .. } => {
12373 catch_tag_values.push(*tag);
12374 Ok(self.get_or_insert_tag_type_info_global(*tag as i32))
12375 }
12376 })
12377 .collect::<Result<Vec<BasicValueEnum<'ctx>>, CompileError>>()?;
12378
12379 let mut outer_catch_blocks = vec![];
12383 for outer_landingpad in self.state.landingpads.iter().rev() {
12384 for catch_info @ TagCatchInfo { tag, .. } in &outer_landingpad.tags {
12385 if !catch_tag_values.contains(tag) {
12386 catch_tag_values.push(*tag);
12387 lpad_clauses.push(if *tag as i32 == CATCH_ALL_TAG_VALUE {
12388 null.into()
12389 } else {
12390 *self.tags_cache.get(&(*tag as i32)).expect(
12391 "If a previous try_table encountered a tag, \
12392 it should be in the cache",
12393 )
12394 });
12395 outer_catch_blocks.push(*catch_info);
12396 }
12397 }
12398 }
12399
12400 let mut maybe_lpad_block = None;
12404 let mut catch_blocks = vec![];
12405 if !lpad_clauses.is_empty() {
12406 let lpad_block = self.context.append_basic_block(self.function, "catch");
12407 let catch_all_block =
12408 self.context.append_basic_block(self.function, "catch_all");
12409 let catch_specific_block = self
12410 .context
12411 .append_basic_block(self.function, "catch_specific");
12412 let catch_end_block =
12413 self.context.append_basic_block(self.function, "catch_end");
12414 let rethrow_block = self.context.append_basic_block(self.function, "rethrow");
12415
12416 self.builder.position_at_end(lpad_block);
12417
12418 let res = err!(self.builder.build_landing_pad(
12419 self.intrinsics.lpad_exception_ty,
12420 self.intrinsics.personality,
12421 &lpad_clauses,
12422 false,
12423 "exc_struct",
12424 ));
12425
12426 let res = res.into_struct_value();
12427
12428 let uw_exc = err!(self.builder.build_extract_value(res, 0, "exc_ptr"));
12429 let pre_selector =
12430 err!(self.builder.build_extract_value(res, 1, "pre_selector"));
12431
12432 let pre_selector_is_zero = err!(self.builder.build_int_compare(
12435 IntPredicate::EQ,
12436 pre_selector.into_int_value(),
12437 self.intrinsics.i32_zero,
12438 "pre_selector_is_zero"
12439 ));
12440 err!(self.builder.build_conditional_branch(
12441 pre_selector_is_zero,
12442 catch_all_block,
12443 catch_specific_block
12444 ));
12445
12446 self.builder.position_at_end(catch_all_block);
12447 err!(self.builder.build_unconditional_branch(catch_end_block));
12448
12449 self.builder.position_at_end(catch_specific_block);
12450 let selector_value = err!(self.builder.build_call(
12451 self.intrinsics.personality2,
12452 &[self.ctx.basic().into(), uw_exc.into()],
12453 "selector"
12454 ));
12455 err!(self.builder.build_unconditional_branch(catch_end_block));
12456
12457 self.builder.position_at_end(catch_end_block);
12458 let selector = err!(self.builder.build_phi(self.intrinsics.i32_ty, "selector"));
12459 selector.add_incoming(&[
12460 (
12461 &self
12462 .intrinsics
12463 .i32_ty
12464 .const_int(CATCH_ALL_TAG_VALUE as u64, false),
12465 catch_all_block,
12466 ),
12467 (
12468 &selector_value
12469 .try_as_basic_value()
12470 .unwrap_basic()
12471 .into_int_value(),
12472 catch_specific_block,
12473 ),
12474 ]);
12475
12476 let uw_exc = uw_exc.into_pointer_value();
12521 let exnref = err!(self.builder.build_call(
12522 self.intrinsics.exception_into_exnref,
12523 &[uw_exc.into()],
12524 "exnref"
12525 ));
12526
12527 let exnref = exnref.try_as_basic_value().unwrap_basic().into_int_value();
12528 let selector = selector.as_basic_value().into_int_value();
12529
12530 for catch in catches.iter() {
12531 match catch {
12532 Catch::All { label } => {
12533 let b = self
12534 .context
12535 .append_basic_block(self.function, "catch_all_clause");
12536 self.builder.position_at_end(b);
12537 let frame = self.state.frame_at_depth(*label)?;
12538
12539 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12540
12541 self.builder.position_at_end(catch_end_block);
12542 catch_blocks.push((b, None));
12543 }
12544 Catch::One { tag, label } => {
12545 let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12546 let signature = &self.wasm_module.signatures[tag_idx];
12547 let params = signature.params();
12548
12549 let b = self.context.append_basic_block(
12550 self.function,
12551 format!("catch_one_clause_{tag}").as_str(),
12552 );
12553 self.builder.position_at_end(b);
12554
12555 let exnref_phi = err!(
12556 self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12557 );
12558 exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12559
12560 let exn_payload_ptr = err!(self.builder.build_direct_call(
12562 self.intrinsics.read_exnref,
12563 &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12564 "exn_ptr",
12565 ));
12566 let exn_payload_ptr = exn_payload_ptr
12567 .try_as_basic_value()
12568 .unwrap_basic()
12569 .into_pointer_value();
12570
12571 let values = params
12573 .iter()
12574 .enumerate()
12575 .map(|(i, v)| {
12576 let name = format!("value_{i}");
12577 let ptr = err!(unsafe {
12578 self.builder.build_gep(
12579 self.intrinsics.i128_ty,
12580 exn_payload_ptr,
12581 &[self
12582 .intrinsics
12583 .i32_ty
12584 .const_int(i as u64, false)],
12585 format!("{name}_ptr").as_str(),
12586 )
12587 });
12588 err_nt!(self.builder.build_load(
12589 type_to_llvm(self.intrinsics, *v)?,
12590 ptr,
12591 &name,
12592 ))
12593 })
12594 .collect::<Result<Vec<_>, CompileError>>()?;
12595
12596 let frame = self.state.frame_at_depth(*label)?;
12597
12598 for (phi, value) in frame.phis().iter().zip(values.iter()) {
12599 phi.add_incoming(&[(value, b)])
12600 }
12601
12602 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12603
12604 self.builder.position_at_end(catch_end_block);
12605 catch_blocks.push((b, Some(exnref_phi)));
12606 }
12607 Catch::OneRef { label, tag } => {
12608 let tag_idx = self.wasm_module.tags[TagIndex::from_u32(*tag)];
12609 let signature = &self.wasm_module.signatures[tag_idx];
12610 let params = signature.params();
12611
12612 let b = self.context.append_basic_block(
12613 self.function,
12614 format!("catch_one_ref_clause_{tag}").as_str(),
12615 );
12616 self.builder.position_at_end(b);
12617
12618 let exnref_phi = err!(
12619 self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12620 );
12621 exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12622
12623 let exn_payload_ptr = err!(self.builder.build_direct_call(
12625 self.intrinsics.read_exnref,
12626 &[self.ctx.basic().into(), exnref_phi.as_basic_value().into()],
12627 "exn_ptr",
12628 ));
12629 let exn_payload_ptr = exn_payload_ptr
12630 .try_as_basic_value()
12631 .unwrap_basic()
12632 .into_pointer_value();
12633
12634 let mut values = params
12636 .iter()
12637 .enumerate()
12638 .map(|(i, v)| {
12639 let name = format!("value_{i}");
12640 let ptr = err!(unsafe {
12641 self.builder.build_gep(
12642 self.intrinsics.i128_ty,
12643 exn_payload_ptr,
12644 &[self
12645 .intrinsics
12646 .i32_ty
12647 .const_int(i as u64, false)],
12648 format!("{name}_ptr").as_str(),
12649 )
12650 });
12651 err_nt!(self.builder.build_load(
12652 type_to_llvm(self.intrinsics, *v)?,
12653 ptr,
12654 &name,
12655 ))
12656 })
12657 .collect::<Result<Vec<_>, CompileError>>()?;
12658
12659 values.push(exnref_phi.as_basic_value());
12660
12661 let frame = self.state.frame_at_depth(*label)?;
12662
12663 for (phi, value) in frame.phis().iter().zip(values.iter()) {
12664 phi.add_incoming(&[(value, b)])
12665 }
12666
12667 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12668
12669 self.builder.position_at_end(catch_end_block);
12670 catch_blocks.push((b, Some(exnref_phi)));
12671 }
12672 Catch::AllRef { label } => {
12673 let b = self
12674 .context
12675 .append_basic_block(self.function, "catch_all_ref_clause");
12676 self.builder.position_at_end(b);
12677
12678 let exnref_phi = err!(
12679 self.builder.build_phi(self.intrinsics.i32_ty, "exnref_phi")
12680 );
12681 exnref_phi.add_incoming(&[(&exnref, catch_end_block)]);
12682
12683 let frame = self.state.frame_at_depth(*label)?;
12684
12685 let phis = frame.phis();
12686
12687 assert_eq!(phis.len(), 1);
12688 phis[0].add_incoming(&[(&exnref_phi.as_basic_value(), b)]);
12689
12690 err!(self.builder.build_unconditional_branch(*frame.br_dest()));
12691
12692 self.builder.position_at_end(catch_end_block);
12693 catch_blocks.push((b, Some(exnref_phi)));
12694 }
12695 }
12696 }
12697
12698 for catch_info in &outer_catch_blocks {
12699 if let Some(phi) = catch_info.exnref_phi {
12700 phi.add_incoming(&[(&exnref, catch_end_block)]);
12701 }
12702 }
12703
12704 err!(
12705 self.builder.build_switch(
12706 selector,
12707 rethrow_block,
12708 catch_blocks
12709 .iter()
12710 .enumerate()
12711 .map(|(i, v)| (
12712 self.intrinsics
12713 .i32_ty
12714 .const_int(catch_tag_values[i] as _, false),
12715 v.0
12716 ))
12717 .chain(outer_catch_blocks.iter().map(|catch_info| (
12718 self.intrinsics.i32_ty.const_int(catch_info.tag as _, false),
12719 catch_info.catch_block
12720 )))
12721 .collect::<Vec<_>>()
12722 .as_slice()
12723 )
12724 );
12725
12726 self.builder.position_at_end(rethrow_block);
12730
12731 err!(self.builder.build_call(
12732 self.intrinsics.throw,
12733 &[self.ctx.basic().into(), exnref.into()],
12734 "rethrow"
12735 ));
12736 err!(self.builder.build_unreachable());
12738
12739 maybe_lpad_block = Some(lpad_block);
12740 }
12741
12742 self.builder.position_at_end(current_block);
12744
12745 let catch_tags_and_blocks = catch_tag_values
12748 .into_iter()
12749 .zip(catch_blocks)
12750 .map(|(tag, (block, exnref_phi))| TagCatchInfo {
12751 tag,
12752 catch_block: block,
12753 exnref_phi,
12754 })
12755 .collect::<Vec<_>>();
12756 self.state.push_landingpad(
12757 maybe_lpad_block,
12758 end_block,
12759 end_phis,
12760 &catch_tags_and_blocks,
12761 self.module_translation
12762 .blocktype_params_results(&try_table.ty)?
12763 .0
12764 .len(),
12765 );
12766 }
12767 Operator::Throw { tag_index } => {
12768 let current_block = self
12769 .builder
12770 .get_insert_block()
12771 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12772
12773 let sig_index = self.wasm_module.tags[TagIndex::from_u32(tag_index)];
12774 let signature = &self.wasm_module.signatures[sig_index];
12775 let params = signature.params();
12776 let values = self.state.popn_save_extra(params.len())?;
12777
12778 values.iter().enumerate().try_for_each(|(i, (v, _))| {
12779 let t = type_to_llvm(self.intrinsics, params[i])?;
12780 if t != v.get_type() {
12781 return Err(CompileError::Codegen(format!(
12782 "Incompatible types: {:?} != {:?}",
12783 t,
12784 v.get_type()
12785 )));
12786 }
12787
12788 Ok(())
12789 })?;
12790
12791 let exnref = err!(
12793 self.builder.build_direct_call(
12794 self.intrinsics.alloc_exception,
12795 &[
12796 self.ctx.basic().into(),
12797 self.intrinsics
12798 .i32_ty
12799 .const_int(tag_index as _, false)
12800 .into()
12801 ],
12802 "exnref",
12803 )
12804 );
12805 let exnref = exnref.try_as_basic_value().unwrap_basic();
12806
12807 let exn_payload_ptr = err!(self.builder.build_direct_call(
12808 self.intrinsics.read_exnref,
12809 &[self.ctx.basic().into(), exnref.into()],
12810 "exn_ptr",
12811 ));
12812 let exn_payload_ptr = exn_payload_ptr
12813 .try_as_basic_value()
12814 .unwrap_basic()
12815 .into_pointer_value();
12816
12817 for (i, value) in values.into_iter().enumerate() {
12818 let ptr = err!(unsafe {
12819 self.builder.build_gep(
12820 self.intrinsics.i128_ty,
12821 exn_payload_ptr,
12822 &[self.intrinsics.i32_ty.const_int(i as u64, false)],
12823 format!("value_{i}_ptr").as_str(),
12824 )
12825 });
12826 err!(self.builder.build_store(ptr, value.0));
12827 }
12828
12829 if let Some(pad) = self.state.get_innermost_landingpad() {
12830 let unreachable_block = self
12831 .context
12832 .append_basic_block(self.function, "_throw_unreachable");
12833
12834 err!(self.builder.build_invoke(
12835 self.intrinsics.throw,
12836 &[self.ctx.basic(), exnref],
12837 unreachable_block,
12838 pad,
12839 "throw",
12840 ));
12841
12842 self.builder.position_at_end(unreachable_block);
12843 err!(self.builder.build_unreachable());
12845
12846 self.builder.position_at_end(current_block);
12847 } else {
12848 err!(self.builder.build_call(
12849 self.intrinsics.throw,
12850 &[self.ctx.basic().into(), exnref.into()],
12851 "throw"
12852 ));
12853 err!(self.builder.build_unreachable());
12855 }
12856
12857 self.state.reachable = false;
12858 }
12859 Operator::ThrowRef => {
12860 let current_block = self
12861 .builder
12862 .get_insert_block()
12863 .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
12864
12865 let exnref = self.state.pop1()?;
12866
12867 if let Some(pad) = self.state.get_innermost_landingpad() {
12868 let unreachable_block = self
12869 .context
12870 .append_basic_block(self.function, "_rethrow_unreachable");
12871
12872 err!(self.builder.build_invoke(
12873 self.intrinsics.throw,
12874 &[self.ctx.basic(), exnref],
12875 unreachable_block,
12876 pad,
12877 "throw",
12878 ));
12879
12880 self.builder.position_at_end(unreachable_block);
12881 err!(self.builder.build_unreachable());
12883
12884 self.builder.position_at_end(current_block);
12885 } else {
12886 err!(self.builder.build_call(
12887 self.intrinsics.throw,
12888 &[self.ctx.basic().into(), exnref.into()],
12889 "throw"
12890 ));
12891 err!(self.builder.build_unreachable());
12893 }
12894
12895 self.state.reachable = false;
12896 }
12897 _ => {
12898 return Err(CompileError::Codegen(format!(
12899 "Operator {op:?} unimplemented",
12900 )));
12901 }
12902 }
12903
12904 Ok(())
12905 }
12906}
12907
12908fn is_f32_arithmetic(bits: u32) -> bool {
12909 let bits = bits & 0x7FFF_FFFF;
12911 bits < 0x7FC0_0000
12912}
12913
12914fn is_f64_arithmetic(bits: u64) -> bool {
12915 let bits = bits & 0x7FFF_FFFF_FFFF_FFFF;
12917 bits < 0x7FF8_0000_0000_0000
12918}
12919
12920const LEF32_GEQ_I32_MIN: u64 = i32::MIN as u64;
12928const GEF32_LEQ_I32_MAX: u64 = 2147483520; const LEF64_GEQ_I32_MIN: u64 = i32::MIN as u64;
12932const GEF64_LEQ_I32_MAX: u64 = i32::MAX as u64;
12934const LEF32_GEQ_U32_MIN: u64 = u32::MIN as u64;
12936const GEF32_LEQ_U32_MAX: u64 = 4294967040; const LEF64_GEQ_U32_MIN: u64 = u32::MIN as u64;
12940const GEF64_LEQ_U32_MAX: u64 = 4294967295; const LEF32_GEQ_I64_MIN: u64 = i64::MIN as u64;
12944const GEF32_LEQ_I64_MAX: u64 = 9223371487098961920; const LEF64_GEQ_I64_MIN: u64 = i64::MIN as u64;
12948const GEF64_LEQ_I64_MAX: u64 = 9223372036854774784; const LEF32_GEQ_U64_MIN: u64 = u64::MIN;
12952const GEF32_LEQ_U64_MAX: u64 = 18446742974197923840; const LEF64_GEQ_U64_MIN: u64 = u64::MIN;
12956const GEF64_LEQ_U64_MAX: u64 = 18446744073709549568;