1use crate::decode::*;
4use crate::encode::Encode;
5use crate::imms::*;
6use crate::profile::{ExecutingPc, ExecutingPcRef};
7use crate::regs::*;
8use alloc::string::ToString;
9use alloc::vec::Vec;
10use core::fmt;
11use core::mem;
12use core::ops::ControlFlow;
13use core::ops::{Index, IndexMut};
14use core::ptr::NonNull;
15use wasmtime_math::WasmFloat;
16mod debug;
17#[cfg(all(not(pulley_tail_calls), not(pulley_assume_llvm_makes_tail_calls)))]
18mod match_loop;
19#[cfg(any(pulley_tail_calls, pulley_assume_llvm_makes_tail_calls))]
20mod tail_loop;
21
22const DEFAULT_STACK_SIZE: usize = 1 << 20; pub struct Vm {
26 state: MachineState,
27 executing_pc: ExecutingPc,
28}
29
30impl Default for Vm {
31 fn default() -> Self {
32 Vm::new()
33 }
34}
35
36impl Vm {
37 pub fn new() -> Self {
39 Self::with_stack(DEFAULT_STACK_SIZE)
40 }
41
42 pub fn with_stack(stack_size: usize) -> Self {
44 Self {
45 state: MachineState::with_stack(stack_size),
46 executing_pc: ExecutingPc::default(),
47 }
48 }
49
50 pub fn state(&self) -> &MachineState {
52 &self.state
53 }
54
55 pub fn state_mut(&mut self) -> &mut MachineState {
57 &mut self.state
58 }
59
60 pub unsafe fn call<'a, T>(
73 &'a mut self,
74 func: NonNull<u8>,
75 args: &[Val],
76 rets: T,
77 ) -> DoneReason<impl Iterator<Item = Val> + use<'a, T>>
78 where
79 T: IntoIterator<Item = RegType> + 'a,
80 {
81 let lr = self.call_start(args);
82
83 match self.call_run(func) {
84 DoneReason::ReturnToHost(()) => DoneReason::ReturnToHost(self.call_end(lr, rets)),
85 DoneReason::Trap { pc, kind } => DoneReason::Trap { pc, kind },
86 DoneReason::CallIndirectHost { id, resume } => {
87 DoneReason::CallIndirectHost { id, resume }
88 }
89 }
90 }
91
92 pub unsafe fn call_start<'a>(&'a mut self, args: &[Val]) -> *mut u8 {
107 let mut x_args = (0..16).map(|x| XReg::new_unchecked(x));
111 let mut f_args = (0..16).map(|f| FReg::new_unchecked(f));
112 let mut v_args = (0..16).map(|v| VReg::new_unchecked(v));
113
114 for arg in args {
115 match arg {
116 Val::XReg(val) => match x_args.next() {
117 Some(reg) => self.state[reg] = *val,
118 None => todo!("stack slots"),
119 },
120 Val::FReg(val) => match f_args.next() {
121 Some(reg) => self.state[reg] = *val,
122 None => todo!("stack slots"),
123 },
124 Val::VReg(val) => match v_args.next() {
125 Some(reg) => self.state[reg] = *val,
126 None => todo!("stack slots"),
127 },
128 }
129 }
130
131 mem::replace(&mut self.state.lr, HOST_RETURN_ADDR)
132 }
133
134 pub unsafe fn call_run(&mut self, pc: NonNull<u8>) -> DoneReason<()> {
143 self.state.debug_assert_done_reason_none();
144 let interpreter = Interpreter {
145 state: &mut self.state,
146 pc: UnsafeBytecodeStream::new(pc),
147 executing_pc: self.executing_pc.as_ref(),
148 };
149 let done = interpreter.run();
150 self.state.done_decode(done)
151 }
152
153 pub unsafe fn call_end<'a>(
164 &'a mut self,
165 old_ret: *mut u8,
166 rets: impl IntoIterator<Item = RegType> + 'a,
167 ) -> impl Iterator<Item = Val> + 'a {
168 self.state.lr = old_ret;
169 let mut x_rets = (0..15).map(|x| XReg::new_unchecked(x));
173 let mut f_rets = (0..16).map(|f| FReg::new_unchecked(f));
174 let mut v_rets = (0..16).map(|v| VReg::new_unchecked(v));
175
176 rets.into_iter().map(move |ty| match ty {
177 RegType::XReg => match x_rets.next() {
178 Some(reg) => Val::XReg(self.state[reg]),
179 None => todo!("stack slots"),
180 },
181 RegType::FReg => match f_rets.next() {
182 Some(reg) => Val::FReg(self.state[reg]),
183 None => todo!("stack slots"),
184 },
185 RegType::VReg => match v_rets.next() {
186 Some(reg) => Val::VReg(self.state[reg]),
187 None => todo!("stack slots"),
188 },
189 })
190 }
191
192 pub fn fp(&self) -> *mut u8 {
194 self.state.fp
195 }
196
197 pub fn lr(&self) -> *mut u8 {
199 self.state.lr
200 }
201
202 pub unsafe fn set_fp(&mut self, fp: *mut u8) {
204 self.state.fp = fp;
205 }
206
207 pub unsafe fn set_lr(&mut self, lr: *mut u8) {
209 self.state.lr = lr;
210 }
211
212 #[cfg(feature = "profile")]
219 pub fn executing_pc(&self) -> &ExecutingPc {
220 &self.executing_pc
221 }
222}
223
224impl Drop for Vm {
225 fn drop(&mut self) {
226 self.executing_pc.set_done();
227 }
228}
229
230#[derive(Clone, Copy, Debug)]
232pub enum RegType {
233 XReg,
235
236 FReg,
238
239 VReg,
241}
242
243#[derive(Clone, Copy, Debug)]
245pub enum Val {
246 XReg(XRegVal),
248
249 FReg(FRegVal),
251
252 VReg(VRegVal),
254}
255
256impl fmt::LowerHex for Val {
257 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258 match self {
259 Val::XReg(v) => fmt::LowerHex::fmt(v, f),
260 Val::FReg(v) => fmt::LowerHex::fmt(v, f),
261 Val::VReg(v) => fmt::LowerHex::fmt(v, f),
262 }
263 }
264}
265
266impl From<XRegVal> for Val {
267 fn from(value: XRegVal) -> Self {
268 Val::XReg(value)
269 }
270}
271
272impl From<u64> for Val {
273 fn from(value: u64) -> Self {
274 XRegVal::new_u64(value).into()
275 }
276}
277
278impl From<u32> for Val {
279 fn from(value: u32) -> Self {
280 XRegVal::new_u32(value).into()
281 }
282}
283
284impl From<i64> for Val {
285 fn from(value: i64) -> Self {
286 XRegVal::new_i64(value).into()
287 }
288}
289
290impl From<i32> for Val {
291 fn from(value: i32) -> Self {
292 XRegVal::new_i32(value).into()
293 }
294}
295
296impl<T> From<*mut T> for Val {
297 fn from(value: *mut T) -> Self {
298 XRegVal::new_ptr(value).into()
299 }
300}
301
302impl From<FRegVal> for Val {
303 fn from(value: FRegVal) -> Self {
304 Val::FReg(value)
305 }
306}
307
308impl From<f64> for Val {
309 fn from(value: f64) -> Self {
310 FRegVal::new_f64(value).into()
311 }
312}
313
314impl From<f32> for Val {
315 fn from(value: f32) -> Self {
316 FRegVal::new_f32(value).into()
317 }
318}
319
320impl From<VRegVal> for Val {
321 fn from(value: VRegVal) -> Self {
322 Val::VReg(value)
323 }
324}
325
326#[derive(Copy, Clone)]
328pub struct XRegVal(XRegUnion);
329
330impl PartialEq for XRegVal {
331 fn eq(&self, other: &Self) -> bool {
332 self.get_u64() == other.get_u64()
333 }
334}
335
336impl Eq for XRegVal {}
337
338impl fmt::Debug for XRegVal {
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 f.debug_struct("XRegVal")
341 .field("as_u64", &self.get_u64())
342 .finish()
343 }
344}
345
346impl fmt::LowerHex for XRegVal {
347 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
348 fmt::LowerHex::fmt(&self.get_u64(), f)
349 }
350}
351
352#[derive(Copy, Clone)]
396union XRegUnion {
397 i32: i32,
398 u32: u32,
399 i64: i64,
400 u64: u64,
401
402 ptr: usize,
413}
414
415impl Default for XRegVal {
416 fn default() -> Self {
417 Self(unsafe { mem::zeroed() })
418 }
419}
420
421#[allow(missing_docs, reason = "self-describing methods")]
422impl XRegVal {
423 pub fn new_i32(x: i32) -> Self {
424 let mut val = XRegVal::default();
425 val.set_i32(x);
426 val
427 }
428
429 pub fn new_u32(x: u32) -> Self {
430 let mut val = XRegVal::default();
431 val.set_u32(x);
432 val
433 }
434
435 pub fn new_i64(x: i64) -> Self {
436 let mut val = XRegVal::default();
437 val.set_i64(x);
438 val
439 }
440
441 pub fn new_u64(x: u64) -> Self {
442 let mut val = XRegVal::default();
443 val.set_u64(x);
444 val
445 }
446
447 pub fn new_ptr<T>(ptr: *mut T) -> Self {
448 let mut val = XRegVal::default();
449 val.set_ptr(ptr);
450 val
451 }
452
453 pub fn get_i32(&self) -> i32 {
454 let x = unsafe { self.0.i32 };
455 i32::from_le(x)
456 }
457
458 pub fn get_u32(&self) -> u32 {
459 let x = unsafe { self.0.u32 };
460 u32::from_le(x)
461 }
462
463 pub fn get_i64(&self) -> i64 {
464 let x = unsafe { self.0.i64 };
465 i64::from_le(x)
466 }
467
468 pub fn get_u64(&self) -> u64 {
469 let x = unsafe { self.0.u64 };
470 u64::from_le(x)
471 }
472
473 pub fn get_ptr<T>(&self) -> *mut T {
474 let ptr = unsafe { self.0.ptr };
475 let ptr = usize::from_le(ptr);
476 #[cfg(has_provenance_apis)]
477 return core::ptr::with_exposed_provenance_mut(ptr);
478 #[cfg(not(has_provenance_apis))]
479 return ptr as *mut T;
480 }
481
482 pub fn set_i32(&mut self, x: i32) {
483 self.0.i32 = x.to_le();
484 }
485
486 pub fn set_u32(&mut self, x: u32) {
487 self.0.u32 = x.to_le();
488 }
489
490 pub fn set_i64(&mut self, x: i64) {
491 self.0.i64 = x.to_le();
492 }
493
494 pub fn set_u64(&mut self, x: u64) {
495 self.0.u64 = x.to_le();
496 }
497
498 pub fn set_ptr<T>(&mut self, ptr: *mut T) {
499 #[cfg(has_provenance_apis)]
500 let ptr = ptr.expose_provenance();
501 #[cfg(not(has_provenance_apis))]
502 let ptr = ptr as usize;
503 self.0.ptr = ptr.to_le();
504 }
505}
506
507#[derive(Copy, Clone)]
509pub struct FRegVal(FRegUnion);
510
511impl fmt::Debug for FRegVal {
512 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
513 f.debug_struct("FRegVal")
514 .field("as_f32", &self.get_f32())
515 .field("as_f64", &self.get_f64())
516 .finish()
517 }
518}
519
520impl fmt::LowerHex for FRegVal {
521 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522 fmt::LowerHex::fmt(&self.get_f64().to_bits(), f)
523 }
524}
525
526#[derive(Copy, Clone)]
529union FRegUnion {
530 f32: u32,
531 f64: u64,
532}
533
534impl Default for FRegVal {
535 fn default() -> Self {
536 Self(unsafe { mem::zeroed() })
537 }
538}
539
540#[allow(missing_docs, reason = "self-describing methods")]
541impl FRegVal {
542 pub fn new_f32(f: f32) -> Self {
543 let mut val = Self::default();
544 val.set_f32(f);
545 val
546 }
547
548 pub fn new_f64(f: f64) -> Self {
549 let mut val = Self::default();
550 val.set_f64(f);
551 val
552 }
553
554 pub fn get_f32(&self) -> f32 {
555 let val = unsafe { self.0.f32 };
556 f32::from_le_bytes(val.to_ne_bytes())
557 }
558
559 pub fn get_f64(&self) -> f64 {
560 let val = unsafe { self.0.f64 };
561 f64::from_le_bytes(val.to_ne_bytes())
562 }
563
564 pub fn set_f32(&mut self, val: f32) {
565 self.0.f32 = u32::from_ne_bytes(val.to_le_bytes());
566 }
567
568 pub fn set_f64(&mut self, val: f64) {
569 self.0.f64 = u64::from_ne_bytes(val.to_le_bytes());
570 }
571}
572
573#[derive(Copy, Clone)]
575pub struct VRegVal(VRegUnion);
576
577impl fmt::Debug for VRegVal {
578 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
579 f.debug_struct("VRegVal")
580 .field("as_u128", &unsafe { self.0.u128 })
581 .finish()
582 }
583}
584
585impl fmt::LowerHex for VRegVal {
586 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587 fmt::LowerHex::fmt(unsafe { &self.0.u128 }, f)
588 }
589}
590
591#[derive(Copy, Clone)]
599#[repr(align(16))]
600union VRegUnion {
601 u128: u128,
602 i8x16: [i8; 16],
603 i16x8: [i16; 8],
604 i32x4: [i32; 4],
605 i64x2: [i64; 2],
606 u8x16: [u8; 16],
607 u16x8: [u16; 8],
608 u32x4: [u32; 4],
609 u64x2: [u64; 2],
610 f32x4: [u32; 4],
614 f64x2: [u64; 2],
615}
616
617impl Default for VRegVal {
618 fn default() -> Self {
619 Self(unsafe { mem::zeroed() })
620 }
621}
622
623#[allow(missing_docs, reason = "self-describing methods")]
624impl VRegVal {
625 pub fn new_u128(i: u128) -> Self {
626 let mut val = Self::default();
627 val.set_u128(i);
628 val
629 }
630
631 pub fn get_u128(&self) -> u128 {
632 let val = unsafe { self.0.u128 };
633 u128::from_le(val)
634 }
635
636 pub fn set_u128(&mut self, val: u128) {
637 self.0.u128 = val.to_le();
638 }
639
640 fn get_i8x16(&self) -> [i8; 16] {
641 let val = unsafe { self.0.i8x16 };
642 val.map(|e| i8::from_le(e))
643 }
644
645 fn set_i8x16(&mut self, val: [i8; 16]) {
646 self.0.i8x16 = val.map(|e| e.to_le());
647 }
648
649 fn get_u8x16(&self) -> [u8; 16] {
650 let val = unsafe { self.0.u8x16 };
651 val.map(|e| u8::from_le(e))
652 }
653
654 fn set_u8x16(&mut self, val: [u8; 16]) {
655 self.0.u8x16 = val.map(|e| e.to_le());
656 }
657
658 fn get_i16x8(&self) -> [i16; 8] {
659 let val = unsafe { self.0.i16x8 };
660 val.map(|e| i16::from_le(e))
661 }
662
663 fn set_i16x8(&mut self, val: [i16; 8]) {
664 self.0.i16x8 = val.map(|e| e.to_le());
665 }
666
667 fn get_u16x8(&self) -> [u16; 8] {
668 let val = unsafe { self.0.u16x8 };
669 val.map(|e| u16::from_le(e))
670 }
671
672 fn set_u16x8(&mut self, val: [u16; 8]) {
673 self.0.u16x8 = val.map(|e| e.to_le());
674 }
675
676 fn get_i32x4(&self) -> [i32; 4] {
677 let val = unsafe { self.0.i32x4 };
678 val.map(|e| i32::from_le(e))
679 }
680
681 fn set_i32x4(&mut self, val: [i32; 4]) {
682 self.0.i32x4 = val.map(|e| e.to_le());
683 }
684
685 fn get_u32x4(&self) -> [u32; 4] {
686 let val = unsafe { self.0.u32x4 };
687 val.map(|e| u32::from_le(e))
688 }
689
690 fn set_u32x4(&mut self, val: [u32; 4]) {
691 self.0.u32x4 = val.map(|e| e.to_le());
692 }
693
694 fn get_i64x2(&self) -> [i64; 2] {
695 let val = unsafe { self.0.i64x2 };
696 val.map(|e| i64::from_le(e))
697 }
698
699 fn set_i64x2(&mut self, val: [i64; 2]) {
700 self.0.i64x2 = val.map(|e| e.to_le());
701 }
702
703 fn get_u64x2(&self) -> [u64; 2] {
704 let val = unsafe { self.0.u64x2 };
705 val.map(|e| u64::from_le(e))
706 }
707
708 fn set_u64x2(&mut self, val: [u64; 2]) {
709 self.0.u64x2 = val.map(|e| e.to_le());
710 }
711
712 fn get_f64x2(&self) -> [f64; 2] {
713 let val = unsafe { self.0.f64x2 };
714 val.map(|e| f64::from_bits(u64::from_le(e)))
715 }
716
717 fn set_f64x2(&mut self, val: [f64; 2]) {
718 self.0.f64x2 = val.map(|e| e.to_bits().to_le());
719 }
720
721 fn get_f32x4(&self) -> [f32; 4] {
722 let val = unsafe { self.0.f32x4 };
723 val.map(|e| f32::from_bits(u32::from_le(e)))
724 }
725
726 fn set_f32x4(&mut self, val: [f32; 4]) {
727 self.0.f32x4 = val.map(|e| e.to_bits().to_le());
728 }
729}
730
731pub struct MachineState {
734 x_regs: [XRegVal; XReg::RANGE.end as usize],
735 f_regs: [FRegVal; FReg::RANGE.end as usize],
736 v_regs: [VRegVal; VReg::RANGE.end as usize],
737 fp: *mut u8,
738 lr: *mut u8,
739 stack: Stack,
740 done_reason: Option<DoneReason<()>>,
741}
742
743unsafe impl Send for MachineState {}
744unsafe impl Sync for MachineState {}
745
746struct Stack {
753 storage: Vec<Align16>,
754}
755
756#[derive(Copy, Clone)]
758#[repr(align(16))]
759struct Align16 {
760 _unused: u128,
763}
764
765impl Stack {
766 fn new(size: usize) -> Stack {
770 Stack {
771 storage: Vec::with_capacity((size + 15) / 16),
776 }
777 }
778
779 fn top(&mut self) -> *mut u8 {
784 let len = self.len();
785 unsafe { self.base().add(len) }
786 }
787
788 fn base(&mut self) -> *mut u8 {
793 self.storage.as_mut_ptr().cast::<u8>()
794 }
795
796 fn len(&self) -> usize {
798 self.storage.capacity() * mem::size_of::<Align16>()
799 }
800}
801
802impl fmt::Debug for MachineState {
803 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
804 let MachineState {
805 x_regs,
806 f_regs,
807 v_regs,
808 stack: _,
809 done_reason: _,
810 fp: _,
811 lr: _,
812 } = self;
813
814 struct RegMap<'a, R>(&'a [R], fn(u8) -> alloc::string::String);
815
816 impl<R: fmt::Debug> fmt::Debug for RegMap<'_, R> {
817 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
818 let mut f = f.debug_map();
819 for (i, r) in self.0.iter().enumerate() {
820 f.entry(&(self.1)(i as u8), r);
821 }
822 f.finish()
823 }
824 }
825
826 f.debug_struct("MachineState")
827 .field(
828 "x_regs",
829 &RegMap(x_regs, |i| XReg::new(i).unwrap().to_string()),
830 )
831 .field(
832 "f_regs",
833 &RegMap(f_regs, |i| FReg::new(i).unwrap().to_string()),
834 )
835 .field(
836 "v_regs",
837 &RegMap(v_regs, |i| VReg::new(i).unwrap().to_string()),
838 )
839 .finish_non_exhaustive()
840 }
841}
842
843macro_rules! index_reg {
844 ($reg_ty:ty,$value_ty:ty,$field:ident) => {
845 impl Index<$reg_ty> for Vm {
846 type Output = $value_ty;
847
848 fn index(&self, reg: $reg_ty) -> &Self::Output {
849 &self.state[reg]
850 }
851 }
852
853 impl IndexMut<$reg_ty> for Vm {
854 fn index_mut(&mut self, reg: $reg_ty) -> &mut Self::Output {
855 &mut self.state[reg]
856 }
857 }
858
859 impl Index<$reg_ty> for MachineState {
860 type Output = $value_ty;
861
862 fn index(&self, reg: $reg_ty) -> &Self::Output {
863 &self.$field[reg.index()]
864 }
865 }
866
867 impl IndexMut<$reg_ty> for MachineState {
868 fn index_mut(&mut self, reg: $reg_ty) -> &mut Self::Output {
869 &mut self.$field[reg.index()]
870 }
871 }
872 };
873}
874
875index_reg!(XReg, XRegVal, x_regs);
876index_reg!(FReg, FRegVal, f_regs);
877index_reg!(VReg, VRegVal, v_regs);
878
879const HOST_RETURN_ADDR: *mut u8 = usize::MAX as *mut u8;
881
882impl MachineState {
883 fn with_stack(stack_size: usize) -> Self {
884 let mut state = Self {
885 x_regs: [Default::default(); XReg::RANGE.end as usize],
886 f_regs: Default::default(),
887 v_regs: Default::default(),
888 stack: Stack::new(stack_size),
889 done_reason: None,
890 fp: HOST_RETURN_ADDR,
891 lr: HOST_RETURN_ADDR,
892 };
893
894 let sp = state.stack.top();
895 state[XReg::sp] = XRegVal::new_ptr(sp);
896
897 state
898 }
899}
900
901mod done {
904 use super::{Encode, Interpreter, MachineState};
905 use core::ops::ControlFlow;
906 use core::ptr::NonNull;
907
908 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
912 pub struct Done {
913 _priv: (),
914 }
915
916 pub enum DoneReason<T> {
918 Trap {
920 pc: NonNull<u8>,
922 kind: Option<TrapKind>,
924 },
925 CallIndirectHost {
927 id: u8,
929 resume: NonNull<u8>,
931 },
932 ReturnToHost(T),
934 }
935
936 #[allow(missing_docs, reason = "self-describing variants")]
938 pub enum TrapKind {
939 DivideByZero,
940 IntegerOverflow,
941 BadConversionToInteger,
942 }
943
944 impl MachineState {
945 pub(super) fn debug_assert_done_reason_none(&mut self) {
946 debug_assert!(self.done_reason.is_none());
947 }
948
949 pub(super) fn done_decode(&mut self, Done { _priv }: Done) -> DoneReason<()> {
950 self.done_reason.take().unwrap()
951 }
952 }
953
954 impl Interpreter<'_> {
955 pub fn done_trap<I: Encode>(&mut self) -> ControlFlow<Done> {
963 self.done_trap_kind::<I>(None)
964 }
965
966 pub fn done_trap_kind<I: Encode>(&mut self, kind: Option<TrapKind>) -> ControlFlow<Done> {
968 let pc = self.current_pc::<I>();
969 self.state.done_reason = Some(DoneReason::Trap { pc, kind });
970 ControlFlow::Break(Done { _priv: () })
971 }
972
973 pub fn done_call_indirect_host(&mut self, id: u8) -> ControlFlow<Done> {
975 self.state.done_reason = Some(DoneReason::CallIndirectHost {
976 id,
977 resume: self.pc.as_ptr(),
978 });
979 ControlFlow::Break(Done { _priv: () })
980 }
981
982 pub fn done_return_to_host(&mut self) -> ControlFlow<Done> {
984 self.state.done_reason = Some(DoneReason::ReturnToHost(()));
985 ControlFlow::Break(Done { _priv: () })
986 }
987 }
988}
989
990use done::Done;
991pub use done::{DoneReason, TrapKind};
992
993struct Interpreter<'a> {
994 state: &'a mut MachineState,
995 pc: UnsafeBytecodeStream,
996 executing_pc: ExecutingPcRef<'a>,
997}
998
999impl Interpreter<'_> {
1000 #[inline]
1007 fn pc_rel_jump<I: Encode>(&mut self, offset: PcRelOffset) -> ControlFlow<Done> {
1008 let offset = isize::try_from(i32::from(offset)).unwrap();
1009 let my_pc = self.current_pc::<I>();
1010 self.pc = unsafe { UnsafeBytecodeStream::new(my_pc.offset(offset)) };
1011 ControlFlow::Continue(())
1012 }
1013
1014 fn current_pc<I: Encode>(&self) -> NonNull<u8> {
1017 unsafe { self.pc.offset(-isize::from(I::WIDTH)).as_ptr() }
1018 }
1019
1020 #[must_use]
1025 fn push<I: Encode, T>(&mut self, val: T) -> ControlFlow<Done> {
1026 let new_sp = self.state[XReg::sp].get_ptr::<T>().wrapping_sub(1);
1027 self.set_sp::<I>(new_sp.cast())?;
1028 unsafe {
1029 new_sp.write_unaligned(val);
1030 }
1031 ControlFlow::Continue(())
1032 }
1033
1034 fn pop<T>(&mut self) -> T {
1036 let sp = self.state[XReg::sp].get_ptr::<T>();
1037 let val = unsafe { sp.read_unaligned() };
1038 self.set_sp_unchecked(sp.wrapping_add(1));
1039 val
1040 }
1041
1042 #[must_use]
1051 fn set_sp<I: Encode>(&mut self, sp: *mut u8) -> ControlFlow<Done> {
1052 let sp_raw = sp as usize;
1053 let base_raw = self.state.stack.base() as usize;
1054 if sp_raw < base_raw {
1055 return self.done_trap::<I>();
1056 }
1057 self.set_sp_unchecked(sp);
1058 ControlFlow::Continue(())
1059 }
1060
1061 fn set_sp_unchecked<T>(&mut self, sp: *mut T) {
1064 if cfg!(debug_assertions) {
1065 let sp_raw = sp as usize;
1066 let base = self.state.stack.base() as usize;
1067 let end = base + self.state.stack.len();
1068 assert!(base <= sp_raw && sp_raw <= end);
1069 }
1070 self.state[XReg::sp].set_ptr(sp);
1071 }
1072
1073 fn g32_addr<T>(&self, base: XReg, addr: XReg, offset: u8) -> *mut T {
1075 let addr = (self.state[base].get_ptr::<T>() as usize)
1076 .wrapping_add(self.state[addr].get_u32() as usize)
1077 .wrapping_add(usize::from(offset));
1078 addr as *mut T
1079 }
1080
1081 unsafe fn load<T>(&self, ptr: XReg, offset: i32) -> T {
1082 unsafe {
1083 self.state[ptr]
1084 .get_ptr::<T>()
1085 .byte_offset(offset as isize)
1086 .read_unaligned()
1087 }
1088 }
1089
1090 unsafe fn load_g32<T>(&self, base: XReg, addr: XReg, offset: u8) -> T {
1094 unsafe { self.g32_addr::<T>(base, addr, offset).read_unaligned() }
1095 }
1096
1097 unsafe fn store<T>(&self, ptr: XReg, offset: i32, val: T) {
1098 self.state[ptr]
1099 .get_ptr::<T>()
1100 .byte_offset(offset as isize)
1101 .write_unaligned(val)
1102 }
1103
1104 unsafe fn store_g32<T>(&self, base: XReg, addr: XReg, offset: u8, val: T) {
1106 unsafe {
1107 self.g32_addr::<T>(base, addr, offset).write_unaligned(val);
1108 }
1109 }
1110
1111 fn check_xnn_from_fnn<I: Encode>(&mut self, val: f64, lo: f64, hi: f64) -> ControlFlow<Done> {
1112 if val != val {
1113 return self.done_trap_kind::<I>(Some(TrapKind::BadConversionToInteger));
1114 }
1115 let val = val.wasm_trunc();
1116 if val <= lo || val >= hi {
1117 return self.done_trap_kind::<I>(Some(TrapKind::IntegerOverflow));
1118 }
1119 ControlFlow::Continue(())
1120 }
1121
1122 fn get_i128(&self, lo: XReg, hi: XReg) -> i128 {
1123 let lo = self.state[lo].get_u64();
1124 let hi = self.state[hi].get_i64();
1125 i128::from(lo) | (i128::from(hi) << 64)
1126 }
1127
1128 fn set_i128(&mut self, lo: XReg, hi: XReg, val: i128) {
1129 self.state[lo].set_u64(val as u64);
1130 self.state[hi].set_u64((val >> 64) as u64);
1131 }
1132
1133 fn record_executing_pc_for_profiling(&mut self) {
1134 self.executing_pc.record(self.pc.as_ptr().as_ptr() as usize);
1136 }
1137}
1138
1139#[test]
1140fn simple_push_pop() {
1141 let mut state = MachineState::with_stack(16);
1142 let pc = ExecutingPc::default();
1143 unsafe {
1144 let mut bytecode = [0; 10];
1145 let mut i = Interpreter {
1146 state: &mut state,
1147 pc: UnsafeBytecodeStream::new(NonNull::new(bytecode.as_mut_ptr().offset(4)).unwrap()),
1149 executing_pc: pc.as_ref(),
1150 };
1151 assert!(i.push::<crate::Ret, _>(0_i32).is_continue());
1152 assert_eq!(i.pop::<i32>(), 0_i32);
1153 assert!(i.push::<crate::Ret, _>(1_i32).is_continue());
1154 assert!(i.push::<crate::Ret, _>(2_i32).is_continue());
1155 assert!(i.push::<crate::Ret, _>(3_i32).is_continue());
1156 assert!(i.push::<crate::Ret, _>(4_i32).is_continue());
1157 assert!(i.push::<crate::Ret, _>(5_i32).is_break());
1158 assert!(i.push::<crate::Ret, _>(6_i32).is_break());
1159 assert_eq!(i.pop::<i32>(), 4_i32);
1160 assert_eq!(i.pop::<i32>(), 3_i32);
1161 assert_eq!(i.pop::<i32>(), 2_i32);
1162 assert_eq!(i.pop::<i32>(), 1_i32);
1163 }
1164}
1165
1166macro_rules! br_if_imm {
1167 ($(
1168 fn $snake:ident(&mut self, a: XReg, b: $imm:ident, offset: PcRelOffset)
1169 = $camel:ident / $op:tt / $get:ident;
1170 )*) => {$(
1171 fn $snake(&mut self, a: XReg, b: $imm, offset: PcRelOffset) -> ControlFlow<Done> {
1172 let a = self.state[a].$get();
1173 if a $op b.into() {
1174 self.pc_rel_jump::<crate::$camel>(offset)
1175 } else {
1176 ControlFlow::Continue(())
1177 }
1178 }
1179 )*};
1180}
1181
1182impl OpVisitor for Interpreter<'_> {
1183 type BytecodeStream = UnsafeBytecodeStream;
1184 type Return = ControlFlow<Done>;
1185
1186 fn bytecode(&mut self) -> &mut UnsafeBytecodeStream {
1187 &mut self.pc
1188 }
1189
1190 fn ret(&mut self) -> ControlFlow<Done> {
1191 let lr = self.state.lr;
1192 if lr == HOST_RETURN_ADDR {
1193 self.done_return_to_host()
1194 } else {
1195 self.pc = unsafe { UnsafeBytecodeStream::new(NonNull::new_unchecked(lr)) };
1196 ControlFlow::Continue(())
1197 }
1198 }
1199
1200 fn call(&mut self, offset: PcRelOffset) -> ControlFlow<Done> {
1201 let return_addr = self.pc.as_ptr();
1202 self.state.lr = return_addr.as_ptr();
1203 self.pc_rel_jump::<crate::Call>(offset);
1204 ControlFlow::Continue(())
1205 }
1206
1207 fn call1(&mut self, arg1: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1208 let return_addr = self.pc.as_ptr();
1209 self.state.lr = return_addr.as_ptr();
1210 self.state[XReg::x0] = self.state[arg1];
1211 self.pc_rel_jump::<crate::Call1>(offset);
1212 ControlFlow::Continue(())
1213 }
1214
1215 fn call2(&mut self, arg1: XReg, arg2: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1216 let return_addr = self.pc.as_ptr();
1217 self.state.lr = return_addr.as_ptr();
1218 let (x0, x1) = (self.state[arg1], self.state[arg2]);
1219 self.state[XReg::x0] = x0;
1220 self.state[XReg::x1] = x1;
1221 self.pc_rel_jump::<crate::Call2>(offset);
1222 ControlFlow::Continue(())
1223 }
1224
1225 fn call3(
1226 &mut self,
1227 arg1: XReg,
1228 arg2: XReg,
1229 arg3: XReg,
1230 offset: PcRelOffset,
1231 ) -> ControlFlow<Done> {
1232 let return_addr = self.pc.as_ptr();
1233 self.state.lr = return_addr.as_ptr();
1234 let (x0, x1, x2) = (self.state[arg1], self.state[arg2], self.state[arg3]);
1235 self.state[XReg::x0] = x0;
1236 self.state[XReg::x1] = x1;
1237 self.state[XReg::x2] = x2;
1238 self.pc_rel_jump::<crate::Call3>(offset);
1239 ControlFlow::Continue(())
1240 }
1241
1242 fn call4(
1243 &mut self,
1244 arg1: XReg,
1245 arg2: XReg,
1246 arg3: XReg,
1247 arg4: XReg,
1248 offset: PcRelOffset,
1249 ) -> ControlFlow<Done> {
1250 let return_addr = self.pc.as_ptr();
1251 self.state.lr = return_addr.as_ptr();
1252 let (x0, x1, x2, x3) = (
1253 self.state[arg1],
1254 self.state[arg2],
1255 self.state[arg3],
1256 self.state[arg4],
1257 );
1258 self.state[XReg::x0] = x0;
1259 self.state[XReg::x1] = x1;
1260 self.state[XReg::x2] = x2;
1261 self.state[XReg::x3] = x3;
1262 self.pc_rel_jump::<crate::Call4>(offset);
1263 ControlFlow::Continue(())
1264 }
1265
1266 fn call_indirect(&mut self, dst: XReg) -> ControlFlow<Done> {
1267 let return_addr = self.pc.as_ptr();
1268 self.state.lr = return_addr.as_ptr();
1269 unsafe {
1273 self.pc = UnsafeBytecodeStream::new(NonNull::new_unchecked(self.state[dst].get_ptr()));
1274 }
1275 ControlFlow::Continue(())
1276 }
1277
1278 fn jump(&mut self, offset: PcRelOffset) -> ControlFlow<Done> {
1279 self.pc_rel_jump::<crate::Jump>(offset);
1280 ControlFlow::Continue(())
1281 }
1282
1283 fn xjump(&mut self, reg: XReg) -> ControlFlow<Done> {
1284 unsafe {
1285 self.pc = UnsafeBytecodeStream::new(NonNull::new_unchecked(self.state[reg].get_ptr()));
1286 }
1287 ControlFlow::Continue(())
1288 }
1289
1290 fn br_if32(&mut self, cond: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1291 let cond = self.state[cond].get_u32();
1292 if cond != 0 {
1293 self.pc_rel_jump::<crate::BrIf>(offset)
1294 } else {
1295 ControlFlow::Continue(())
1296 }
1297 }
1298
1299 fn br_if_not32(&mut self, cond: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1300 let cond = self.state[cond].get_u32();
1301 if cond == 0 {
1302 self.pc_rel_jump::<crate::BrIfNot>(offset)
1303 } else {
1304 ControlFlow::Continue(())
1305 }
1306 }
1307
1308 fn br_if_xeq32(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1309 let a = self.state[a].get_u32();
1310 let b = self.state[b].get_u32();
1311 if a == b {
1312 self.pc_rel_jump::<crate::BrIfXeq32>(offset)
1313 } else {
1314 ControlFlow::Continue(())
1315 }
1316 }
1317
1318 fn br_if_xneq32(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1319 let a = self.state[a].get_u32();
1320 let b = self.state[b].get_u32();
1321 if a != b {
1322 self.pc_rel_jump::<crate::BrIfXneq32>(offset)
1323 } else {
1324 ControlFlow::Continue(())
1325 }
1326 }
1327
1328 fn br_if_xslt32(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1329 let a = self.state[a].get_i32();
1330 let b = self.state[b].get_i32();
1331 if a < b {
1332 self.pc_rel_jump::<crate::BrIfXslt32>(offset)
1333 } else {
1334 ControlFlow::Continue(())
1335 }
1336 }
1337
1338 fn br_if_xslteq32(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1339 let a = self.state[a].get_i32();
1340 let b = self.state[b].get_i32();
1341 if a <= b {
1342 self.pc_rel_jump::<crate::BrIfXslteq32>(offset)
1343 } else {
1344 ControlFlow::Continue(())
1345 }
1346 }
1347
1348 fn br_if_xult32(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1349 let a = self.state[a].get_u32();
1350 let b = self.state[b].get_u32();
1351 if a < b {
1352 self.pc_rel_jump::<crate::BrIfXult32>(offset)
1353 } else {
1354 ControlFlow::Continue(())
1355 }
1356 }
1357
1358 fn br_if_xulteq32(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1359 let a = self.state[a].get_u32();
1360 let b = self.state[b].get_u32();
1361 if a <= b {
1362 self.pc_rel_jump::<crate::BrIfXulteq32>(offset)
1363 } else {
1364 ControlFlow::Continue(())
1365 }
1366 }
1367
1368 fn br_if_xeq64(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1369 let a = self.state[a].get_u64();
1370 let b = self.state[b].get_u64();
1371 if a == b {
1372 self.pc_rel_jump::<crate::BrIfXeq64>(offset)
1373 } else {
1374 ControlFlow::Continue(())
1375 }
1376 }
1377
1378 fn br_if_xneq64(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1379 let a = self.state[a].get_u64();
1380 let b = self.state[b].get_u64();
1381 if a != b {
1382 self.pc_rel_jump::<crate::BrIfXneq64>(offset)
1383 } else {
1384 ControlFlow::Continue(())
1385 }
1386 }
1387
1388 fn br_if_xslt64(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1389 let a = self.state[a].get_i64();
1390 let b = self.state[b].get_i64();
1391 if a < b {
1392 self.pc_rel_jump::<crate::BrIfXslt64>(offset)
1393 } else {
1394 ControlFlow::Continue(())
1395 }
1396 }
1397
1398 fn br_if_xslteq64(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1399 let a = self.state[a].get_i64();
1400 let b = self.state[b].get_i64();
1401 if a <= b {
1402 self.pc_rel_jump::<crate::BrIfXslteq64>(offset)
1403 } else {
1404 ControlFlow::Continue(())
1405 }
1406 }
1407
1408 fn br_if_xult64(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1409 let a = self.state[a].get_u64();
1410 let b = self.state[b].get_u64();
1411 if a < b {
1412 self.pc_rel_jump::<crate::BrIfXult64>(offset)
1413 } else {
1414 ControlFlow::Continue(())
1415 }
1416 }
1417
1418 fn br_if_xulteq64(&mut self, a: XReg, b: XReg, offset: PcRelOffset) -> ControlFlow<Done> {
1419 let a = self.state[a].get_u64();
1420 let b = self.state[b].get_u64();
1421 if a <= b {
1422 self.pc_rel_jump::<crate::BrIfXulteq64>(offset)
1423 } else {
1424 ControlFlow::Continue(())
1425 }
1426 }
1427
1428 br_if_imm! {
1429 fn br_if_xeq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1430 = BrIfXeq32I8 / == / get_i32;
1431 fn br_if_xeq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1432 = BrIfXeq32I32 / == / get_i32;
1433 fn br_if_xneq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1434 = BrIfXneq32I8 / != / get_i32;
1435 fn br_if_xneq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1436 = BrIfXneq32I32 / != / get_i32;
1437
1438 fn br_if_xslt32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1439 = BrIfXslt32I8 / < / get_i32;
1440 fn br_if_xslt32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1441 = BrIfXslt32I32 / < / get_i32;
1442 fn br_if_xsgt32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1443 = BrIfXsgt32I8 / > / get_i32;
1444 fn br_if_xsgt32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1445 = BrIfXsgt32I32 / > / get_i32;
1446 fn br_if_xslteq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1447 = BrIfXslteq32I8 / <= / get_i32;
1448 fn br_if_xslteq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1449 = BrIfXslteq32I32 / <= / get_i32;
1450 fn br_if_xsgteq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1451 = BrIfXsgteq32I8 / >= / get_i32;
1452 fn br_if_xsgteq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1453 = BrIfXsgteq32I32 / >= / get_i32;
1454
1455 fn br_if_xult32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1456 = BrIfXult32U8 / < / get_u32;
1457 fn br_if_xult32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1458 = BrIfXult32U32 / < / get_u32;
1459 fn br_if_xugt32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1460 = BrIfXugt32U8 / > / get_u32;
1461 fn br_if_xugt32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1462 = BrIfXugt32U32 / > / get_u32;
1463 fn br_if_xulteq32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1464 = BrIfXulteq32U8 / <= / get_u32;
1465 fn br_if_xulteq32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1466 = BrIfXulteq32U32 / <= / get_u32;
1467 fn br_if_xugteq32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1468 = BrIfXugteq32U8 / >= / get_u32;
1469 fn br_if_xugteq32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1470 = BrIfXugteq32U32 / >= / get_u32;
1471
1472 fn br_if_xeq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1473 = BrIfXeq64I8 / == / get_i64;
1474 fn br_if_xeq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1475 = BrIfXeq64I32 / == / get_i64;
1476 fn br_if_xneq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1477 = BrIfXneq64I8 / != / get_i64;
1478 fn br_if_xneq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1479 = BrIfXneq64I32 / != / get_i64;
1480
1481 fn br_if_xslt64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1482 = BrIfXslt64I8 / < / get_i64;
1483 fn br_if_xslt64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1484 = BrIfXslt64I32 / < / get_i64;
1485 fn br_if_xsgt64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1486 = BrIfXsgt64I8 / > / get_i64;
1487 fn br_if_xsgt64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1488 = BrIfXsgt64I32 / > / get_i64;
1489 fn br_if_xslteq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1490 = BrIfXslteq64I8 / <= / get_i64;
1491 fn br_if_xslteq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1492 = BrIfXslteq64I32 / <= / get_i64;
1493 fn br_if_xsgteq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset)
1494 = BrIfXsgteq64I8 / >= / get_i64;
1495 fn br_if_xsgteq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset)
1496 = BrIfXsgteq64I32 / >= / get_i64;
1497
1498 fn br_if_xult64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1499 = BrIfXult64U8 / < / get_u64;
1500 fn br_if_xult64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1501 = BrIfXult64U32 / < / get_u64;
1502 fn br_if_xugt64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1503 = BrIfXugt64U8 / > / get_u64;
1504 fn br_if_xugt64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1505 = BrIfXugt64U32 / > / get_u64;
1506 fn br_if_xulteq64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1507 = BrIfXulteq64U8 / <= / get_u64;
1508 fn br_if_xulteq64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1509 = BrIfXulteq64U32 / <= / get_u64;
1510 fn br_if_xugteq64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset)
1511 = BrIfXugteq64U8 / >= / get_u64;
1512 fn br_if_xugteq64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset)
1513 = BrIfXugteq64U32 / >= / get_u64;
1514 }
1515
1516 fn xmov(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
1517 let val = self.state[src];
1518 self.state[dst] = val;
1519 ControlFlow::Continue(())
1520 }
1521
1522 fn xconst8(&mut self, dst: XReg, imm: i8) -> ControlFlow<Done> {
1523 self.state[dst].set_i64(i64::from(imm));
1524 ControlFlow::Continue(())
1525 }
1526
1527 fn xzero(&mut self, dst: XReg) -> ControlFlow<Done> {
1528 self.state[dst].set_i64(0);
1529 ControlFlow::Continue(())
1530 }
1531
1532 fn xone(&mut self, dst: XReg) -> ControlFlow<Done> {
1533 self.state[dst].set_i64(1);
1534 ControlFlow::Continue(())
1535 }
1536
1537 fn xconst16(&mut self, dst: XReg, imm: i16) -> ControlFlow<Done> {
1538 self.state[dst].set_i64(i64::from(imm));
1539 ControlFlow::Continue(())
1540 }
1541
1542 fn xconst32(&mut self, dst: XReg, imm: i32) -> ControlFlow<Done> {
1543 self.state[dst].set_i64(i64::from(imm));
1544 ControlFlow::Continue(())
1545 }
1546
1547 fn xconst64(&mut self, dst: XReg, imm: i64) -> ControlFlow<Done> {
1548 self.state[dst].set_i64(imm);
1549 ControlFlow::Continue(())
1550 }
1551
1552 fn xadd32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1553 let a = self.state[operands.src1].get_u32();
1554 let b = self.state[operands.src2].get_u32();
1555 self.state[operands.dst].set_u32(a.wrapping_add(b));
1556 ControlFlow::Continue(())
1557 }
1558
1559 fn xadd32_u8(&mut self, dst: XReg, src1: XReg, src2: u8) -> ControlFlow<Done> {
1560 self.xadd32_u32(dst, src1, src2.into())
1561 }
1562
1563 fn xadd32_u32(&mut self, dst: XReg, src1: XReg, src2: u32) -> ControlFlow<Done> {
1564 let a = self.state[src1].get_u32();
1565 self.state[dst].set_u32(a.wrapping_add(src2.into()));
1566 ControlFlow::Continue(())
1567 }
1568
1569 fn xadd64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1570 let a = self.state[operands.src1].get_u64();
1571 let b = self.state[operands.src2].get_u64();
1572 self.state[operands.dst].set_u64(a.wrapping_add(b));
1573 ControlFlow::Continue(())
1574 }
1575
1576 fn xadd64_u8(&mut self, dst: XReg, src1: XReg, src2: u8) -> ControlFlow<Done> {
1577 self.xadd64_u32(dst, src1, src2.into())
1578 }
1579
1580 fn xadd64_u32(&mut self, dst: XReg, src1: XReg, src2: u32) -> ControlFlow<Done> {
1581 let a = self.state[src1].get_u64();
1582 self.state[dst].set_u64(a.wrapping_add(src2.into()));
1583 ControlFlow::Continue(())
1584 }
1585
1586 fn xmadd32(&mut self, dst: XReg, src1: XReg, src2: XReg, src3: XReg) -> ControlFlow<Done> {
1587 let a = self.state[src1].get_u32();
1588 let b = self.state[src2].get_u32();
1589 let c = self.state[src3].get_u32();
1590 self.state[dst].set_u32(a.wrapping_mul(b).wrapping_add(c));
1591 ControlFlow::Continue(())
1592 }
1593
1594 fn xmadd64(&mut self, dst: XReg, src1: XReg, src2: XReg, src3: XReg) -> ControlFlow<Done> {
1595 let a = self.state[src1].get_u64();
1596 let b = self.state[src2].get_u64();
1597 let c = self.state[src3].get_u64();
1598 self.state[dst].set_u64(a.wrapping_mul(b).wrapping_add(c));
1599 ControlFlow::Continue(())
1600 }
1601
1602 fn xsub32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1603 let a = self.state[operands.src1].get_u32();
1604 let b = self.state[operands.src2].get_u32();
1605 self.state[operands.dst].set_u32(a.wrapping_sub(b));
1606 ControlFlow::Continue(())
1607 }
1608
1609 fn xsub32_u8(&mut self, dst: XReg, src1: XReg, src2: u8) -> ControlFlow<Done> {
1610 self.xsub32_u32(dst, src1, src2.into())
1611 }
1612
1613 fn xsub32_u32(&mut self, dst: XReg, src1: XReg, src2: u32) -> ControlFlow<Done> {
1614 let a = self.state[src1].get_u32();
1615 self.state[dst].set_u32(a.wrapping_sub(src2.into()));
1616 ControlFlow::Continue(())
1617 }
1618
1619 fn xsub64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1620 let a = self.state[operands.src1].get_u64();
1621 let b = self.state[operands.src2].get_u64();
1622 self.state[operands.dst].set_u64(a.wrapping_sub(b));
1623 ControlFlow::Continue(())
1624 }
1625
1626 fn xsub64_u8(&mut self, dst: XReg, src1: XReg, src2: u8) -> ControlFlow<Done> {
1627 self.xsub64_u32(dst, src1, src2.into())
1628 }
1629
1630 fn xsub64_u32(&mut self, dst: XReg, src1: XReg, src2: u32) -> ControlFlow<Done> {
1631 let a = self.state[src1].get_u64();
1632 self.state[dst].set_u64(a.wrapping_sub(src2.into()));
1633 ControlFlow::Continue(())
1634 }
1635
1636 fn xmul32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1637 let a = self.state[operands.src1].get_u32();
1638 let b = self.state[operands.src2].get_u32();
1639 self.state[operands.dst].set_u32(a.wrapping_mul(b));
1640 ControlFlow::Continue(())
1641 }
1642
1643 fn xmul32_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
1644 self.xmul32_s32(dst, src1, src2.into())
1645 }
1646
1647 fn xmul32_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
1648 let a = self.state[src1].get_i32();
1649 self.state[dst].set_i32(a.wrapping_mul(src2));
1650 ControlFlow::Continue(())
1651 }
1652
1653 fn xmul64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1654 let a = self.state[operands.src1].get_u64();
1655 let b = self.state[operands.src2].get_u64();
1656 self.state[operands.dst].set_u64(a.wrapping_mul(b));
1657 ControlFlow::Continue(())
1658 }
1659
1660 fn xmul64_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
1661 self.xmul64_s32(dst, src1, src2.into())
1662 }
1663
1664 fn xmul64_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
1665 let a = self.state[src1].get_i64();
1666 self.state[dst].set_i64(a.wrapping_mul(src2.into()));
1667 ControlFlow::Continue(())
1668 }
1669
1670 fn xshl32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1671 let a = self.state[operands.src1].get_u32();
1672 let b = self.state[operands.src2].get_u32();
1673 self.state[operands.dst].set_u32(a.wrapping_shl(b));
1674 ControlFlow::Continue(())
1675 }
1676
1677 fn xshr32_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1678 let a = self.state[operands.src1].get_u32();
1679 let b = self.state[operands.src2].get_u32();
1680 self.state[operands.dst].set_u32(a.wrapping_shr(b));
1681 ControlFlow::Continue(())
1682 }
1683
1684 fn xshr32_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1685 let a = self.state[operands.src1].get_i32();
1686 let b = self.state[operands.src2].get_u32();
1687 self.state[operands.dst].set_i32(a.wrapping_shr(b));
1688 ControlFlow::Continue(())
1689 }
1690
1691 fn xshl64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1692 let a = self.state[operands.src1].get_u64();
1693 let b = self.state[operands.src2].get_u32();
1694 self.state[operands.dst].set_u64(a.wrapping_shl(b));
1695 ControlFlow::Continue(())
1696 }
1697
1698 fn xshr64_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1699 let a = self.state[operands.src1].get_u64();
1700 let b = self.state[operands.src2].get_u32();
1701 self.state[operands.dst].set_u64(a.wrapping_shr(b));
1702 ControlFlow::Continue(())
1703 }
1704
1705 fn xshr64_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1706 let a = self.state[operands.src1].get_i64();
1707 let b = self.state[operands.src2].get_u32();
1708 self.state[operands.dst].set_i64(a.wrapping_shr(b));
1709 ControlFlow::Continue(())
1710 }
1711
1712 fn xshl32_u6(&mut self, operands: BinaryOperands<XReg, XReg, U6>) -> ControlFlow<Done> {
1713 let a = self.state[operands.src1].get_u32();
1714 let b = u32::from(u8::from(operands.src2));
1715 self.state[operands.dst].set_u32(a.wrapping_shl(b));
1716 ControlFlow::Continue(())
1717 }
1718
1719 fn xshr32_u_u6(&mut self, operands: BinaryOperands<XReg, XReg, U6>) -> ControlFlow<Done> {
1720 let a = self.state[operands.src1].get_u32();
1721 let b = u32::from(u8::from(operands.src2));
1722 self.state[operands.dst].set_u32(a.wrapping_shr(b));
1723 ControlFlow::Continue(())
1724 }
1725
1726 fn xshr32_s_u6(&mut self, operands: BinaryOperands<XReg, XReg, U6>) -> ControlFlow<Done> {
1727 let a = self.state[operands.src1].get_i32();
1728 let b = u32::from(u8::from(operands.src2));
1729 self.state[operands.dst].set_i32(a.wrapping_shr(b));
1730 ControlFlow::Continue(())
1731 }
1732
1733 fn xshl64_u6(&mut self, operands: BinaryOperands<XReg, XReg, U6>) -> ControlFlow<Done> {
1734 let a = self.state[operands.src1].get_u64();
1735 let b = u32::from(u8::from(operands.src2));
1736 self.state[operands.dst].set_u64(a.wrapping_shl(b));
1737 ControlFlow::Continue(())
1738 }
1739
1740 fn xshr64_u_u6(&mut self, operands: BinaryOperands<XReg, XReg, U6>) -> ControlFlow<Done> {
1741 let a = self.state[operands.src1].get_u64();
1742 let b = u32::from(u8::from(operands.src2));
1743 self.state[operands.dst].set_u64(a.wrapping_shr(b));
1744 ControlFlow::Continue(())
1745 }
1746
1747 fn xshr64_s_u6(&mut self, operands: BinaryOperands<XReg, XReg, U6>) -> ControlFlow<Done> {
1748 let a = self.state[operands.src1].get_i64();
1749 let b = u32::from(u8::from(operands.src2));
1750 self.state[operands.dst].set_i64(a.wrapping_shr(b));
1751 ControlFlow::Continue(())
1752 }
1753
1754 fn xneg32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
1755 let a = self.state[src].get_i32();
1756 self.state[dst].set_i32(a.wrapping_neg());
1757 ControlFlow::Continue(())
1758 }
1759
1760 fn xneg64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
1761 let a = self.state[src].get_i64();
1762 self.state[dst].set_i64(a.wrapping_neg());
1763 ControlFlow::Continue(())
1764 }
1765
1766 fn xeq64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1767 let a = self.state[operands.src1].get_u64();
1768 let b = self.state[operands.src2].get_u64();
1769 self.state[operands.dst].set_u32(u32::from(a == b));
1770 ControlFlow::Continue(())
1771 }
1772
1773 fn xneq64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1774 let a = self.state[operands.src1].get_u64();
1775 let b = self.state[operands.src2].get_u64();
1776 self.state[operands.dst].set_u32(u32::from(a != b));
1777 ControlFlow::Continue(())
1778 }
1779
1780 fn xslt64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1781 let a = self.state[operands.src1].get_i64();
1782 let b = self.state[operands.src2].get_i64();
1783 self.state[operands.dst].set_u32(u32::from(a < b));
1784 ControlFlow::Continue(())
1785 }
1786
1787 fn xslteq64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1788 let a = self.state[operands.src1].get_i64();
1789 let b = self.state[operands.src2].get_i64();
1790 self.state[operands.dst].set_u32(u32::from(a <= b));
1791 ControlFlow::Continue(())
1792 }
1793
1794 fn xult64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1795 let a = self.state[operands.src1].get_u64();
1796 let b = self.state[operands.src2].get_u64();
1797 self.state[operands.dst].set_u32(u32::from(a < b));
1798 ControlFlow::Continue(())
1799 }
1800
1801 fn xulteq64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1802 let a = self.state[operands.src1].get_u64();
1803 let b = self.state[operands.src2].get_u64();
1804 self.state[operands.dst].set_u32(u32::from(a <= b));
1805 ControlFlow::Continue(())
1806 }
1807
1808 fn xeq32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1809 let a = self.state[operands.src1].get_u32();
1810 let b = self.state[operands.src2].get_u32();
1811 self.state[operands.dst].set_u32(u32::from(a == b));
1812 ControlFlow::Continue(())
1813 }
1814
1815 fn xneq32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1816 let a = self.state[operands.src1].get_u32();
1817 let b = self.state[operands.src2].get_u32();
1818 self.state[operands.dst].set_u32(u32::from(a != b));
1819 ControlFlow::Continue(())
1820 }
1821
1822 fn xslt32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1823 let a = self.state[operands.src1].get_i32();
1824 let b = self.state[operands.src2].get_i32();
1825 self.state[operands.dst].set_u32(u32::from(a < b));
1826 ControlFlow::Continue(())
1827 }
1828
1829 fn xslteq32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1830 let a = self.state[operands.src1].get_i32();
1831 let b = self.state[operands.src2].get_i32();
1832 self.state[operands.dst].set_u32(u32::from(a <= b));
1833 ControlFlow::Continue(())
1834 }
1835
1836 fn xult32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1837 let a = self.state[operands.src1].get_u32();
1838 let b = self.state[operands.src2].get_u32();
1839 self.state[operands.dst].set_u32(u32::from(a < b));
1840 ControlFlow::Continue(())
1841 }
1842
1843 fn xulteq32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
1844 let a = self.state[operands.src1].get_u32();
1845 let b = self.state[operands.src2].get_u32();
1846 self.state[operands.dst].set_u32(u32::from(a <= b));
1847 ControlFlow::Continue(())
1848 }
1849
1850 fn xload8_u32_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1851 self.xload8_u32_offset32(dst, ptr, offset.into())
1852 }
1853
1854 fn xload8_s32_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1855 self.xload8_s32_offset32(dst, ptr, offset.into())
1856 }
1857
1858 fn xload16le_u32_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1859 self.xload16le_u32_offset32(dst, ptr, offset.into())
1860 }
1861
1862 fn xload16le_s32_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1863 self.xload16le_s32_offset32(dst, ptr, offset.into())
1864 }
1865
1866 fn xload32le_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1867 self.xload32le_offset32(dst, ptr, offset.into())
1868 }
1869
1870 fn xload8_u64_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1871 self.xload8_u64_offset32(dst, ptr, offset.into())
1872 }
1873
1874 fn xload8_s64_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1875 self.xload8_s64_offset32(dst, ptr, offset.into())
1876 }
1877
1878 fn xload16le_u64_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1879 self.xload16le_u64_offset32(dst, ptr, offset.into())
1880 }
1881
1882 fn xload16le_s64_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1883 self.xload16le_s64_offset32(dst, ptr, offset.into())
1884 }
1885
1886 fn xload32le_u64_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1887 self.xload32le_u64_offset32(dst, ptr, offset.into())
1888 }
1889
1890 fn xload32le_s64_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1891 self.xload32le_s64_offset32(dst, ptr, offset.into())
1892 }
1893
1894 fn xload64le_offset8(&mut self, dst: XReg, ptr: XReg, offset: u8) -> ControlFlow<Done> {
1895 self.xload64le_offset32(dst, ptr, offset.into())
1896 }
1897
1898 fn xstore8_offset8(&mut self, ptr: XReg, offset: u8, src: XReg) -> ControlFlow<Done> {
1899 self.xstore8_offset32(ptr, offset.into(), src)
1900 }
1901
1902 fn xstore16le_offset8(&mut self, ptr: XReg, offset: u8, src: XReg) -> ControlFlow<Done> {
1903 self.xstore16le_offset32(ptr, offset.into(), src)
1904 }
1905
1906 fn xstore32le_offset8(&mut self, ptr: XReg, offset: u8, src: XReg) -> ControlFlow<Done> {
1907 self.xstore32le_offset32(ptr, offset.into(), src)
1908 }
1909
1910 fn xstore64le_offset8(&mut self, ptr: XReg, offset: u8, src: XReg) -> ControlFlow<Done> {
1911 self.xstore64le_offset32(ptr, offset.into(), src)
1912 }
1913
1914 fn xload8_u32_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1915 let val = unsafe { self.load::<u8>(ptr, offset) };
1916 self.state[dst].set_u32(val.into());
1917 ControlFlow::Continue(())
1918 }
1919
1920 fn xload8_s32_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1921 let val = unsafe { self.load::<i8>(ptr, offset) };
1922 self.state[dst].set_i32(val.into());
1923 ControlFlow::Continue(())
1924 }
1925
1926 fn xload16le_u32_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1927 let val = unsafe { self.load::<u16>(ptr, offset) };
1928 self.state[dst].set_u32(u16::from_le(val).into());
1929 ControlFlow::Continue(())
1930 }
1931
1932 fn xload16le_s32_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1933 let val = unsafe { self.load::<i16>(ptr, offset) };
1934 self.state[dst].set_i32(i16::from_le(val).into());
1935 ControlFlow::Continue(())
1936 }
1937
1938 fn xload32le_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1939 let val = unsafe { self.load::<i32>(ptr, offset) };
1940 self.state[dst].set_i32(i32::from_le(val));
1941 ControlFlow::Continue(())
1942 }
1943
1944 fn xload8_u64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1945 let val = unsafe { self.load::<u8>(ptr, offset) };
1946 self.state[dst].set_u64(val.into());
1947 ControlFlow::Continue(())
1948 }
1949
1950 fn xload8_s64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1951 let val = unsafe { self.load::<i8>(ptr, offset) };
1952 self.state[dst].set_i64(val.into());
1953 ControlFlow::Continue(())
1954 }
1955
1956 fn xload16le_u64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1957 let val = unsafe { self.load::<u16>(ptr, offset) };
1958 self.state[dst].set_u64(u16::from_le(val).into());
1959 ControlFlow::Continue(())
1960 }
1961
1962 fn xload16le_s64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1963 let val = unsafe { self.load::<i16>(ptr, offset) };
1964 self.state[dst].set_i64(i16::from_le(val).into());
1965 ControlFlow::Continue(())
1966 }
1967
1968 fn xload32le_u64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1969 let val = unsafe { self.load::<u32>(ptr, offset) };
1970 self.state[dst].set_u64(u32::from_le(val).into());
1971 ControlFlow::Continue(())
1972 }
1973
1974 fn xload32le_s64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1975 let val = unsafe { self.load::<i32>(ptr, offset) };
1976 self.state[dst].set_i64(i32::from_le(val).into());
1977 ControlFlow::Continue(())
1978 }
1979
1980 fn xload64le_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
1981 let val = unsafe { self.load::<i64>(ptr, offset) };
1982 self.state[dst].set_i64(i64::from_le(val));
1983 ControlFlow::Continue(())
1984 }
1985
1986 fn xstore8_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
1987 let val = self.state[src].get_u32() as u8;
1988 unsafe {
1989 self.store(ptr, offset, val);
1990 }
1991 ControlFlow::Continue(())
1992 }
1993
1994 fn xstore16le_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
1995 let val = self.state[src].get_u32() as u16;
1996 unsafe {
1997 self.store(ptr, offset, val.to_le());
1998 }
1999 ControlFlow::Continue(())
2000 }
2001
2002 fn xstore32le_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
2003 let val = self.state[src].get_u32();
2004 unsafe {
2005 self.store(ptr, offset, val.to_le());
2006 }
2007 ControlFlow::Continue(())
2008 }
2009
2010 fn xstore64le_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
2011 let val = self.state[src].get_u64();
2012 unsafe {
2013 self.store(ptr, offset, val.to_le());
2014 }
2015 ControlFlow::Continue(())
2016 }
2017
2018 fn push_frame(&mut self) -> ControlFlow<Done> {
2019 self.push::<crate::PushFrame, _>(self.state.lr)?;
2020 self.push::<crate::PushFrame, _>(self.state.fp)?;
2021 self.state.fp = self.state[XReg::sp].get_ptr();
2022 ControlFlow::Continue(())
2023 }
2024
2025 #[inline]
2026 fn push_frame_save(&mut self, amt: u16, regs: UpperRegSet<XReg>) -> ControlFlow<Done> {
2027 let ptr_size = size_of::<usize>();
2030 let full_amt = usize::from(amt) + 2 * ptr_size;
2031 let new_sp = self.state[XReg::sp].get_ptr::<u8>().wrapping_sub(full_amt);
2032 self.set_sp::<crate::PushFrameSave>(new_sp)?;
2033
2034 unsafe {
2035 self.store(XReg::sp, (full_amt - 1 * ptr_size) as i32, self.state.lr);
2038 self.store(XReg::sp, (full_amt - 2 * ptr_size) as i32, self.state.fp);
2039
2040 let mut offset = amt as i32;
2042 self.state.fp = self.state[XReg::sp]
2043 .get_ptr::<u8>()
2044 .byte_offset(offset as isize);
2045
2046 for reg in regs {
2048 offset -= 8;
2049 self.store(XReg::sp, offset, self.state[reg].get_u64());
2050 }
2051 }
2052 ControlFlow::Continue(())
2053 }
2054
2055 fn pop_frame_restore(&mut self, amt: u16, regs: UpperRegSet<XReg>) -> ControlFlow<Done> {
2056 unsafe {
2059 let mut offset = i32::from(amt);
2060 for reg in regs {
2061 offset -= 8;
2062 let val = self.load(XReg::sp, offset);
2063 self.state[reg].set_u64(val);
2064 }
2065 }
2066 self.pop_frame()
2067 }
2068
2069 fn pop_frame(&mut self) -> ControlFlow<Done> {
2070 self.set_sp_unchecked(self.state.fp);
2071 let fp = self.pop();
2072 let lr = self.pop();
2073 self.state.fp = fp;
2074 self.state.lr = lr;
2075 ControlFlow::Continue(())
2076 }
2077
2078 fn br_table32(&mut self, idx: XReg, amt: u32) -> ControlFlow<Done> {
2079 let idx = self.state[idx].get_u32().min(amt - 1) as isize;
2080 self.pc = unsafe { self.pc.offset(idx * 4) };
2083
2084 let mut tmp = self.pc;
2087 let Ok(rel) = PcRelOffset::decode(&mut tmp);
2088 let offset = isize::try_from(i32::from(rel)).unwrap();
2089 self.pc = unsafe { self.pc.offset(offset) };
2090 ControlFlow::Continue(())
2091 }
2092
2093 fn stack_alloc32(&mut self, amt: u32) -> ControlFlow<Done> {
2094 let amt = usize::try_from(amt).unwrap();
2095 let new_sp = self.state[XReg::sp].get_ptr::<u8>().wrapping_sub(amt);
2096 self.set_sp::<crate::StackAlloc32>(new_sp)?;
2097 ControlFlow::Continue(())
2098 }
2099
2100 fn stack_free32(&mut self, amt: u32) -> ControlFlow<Done> {
2101 let amt = usize::try_from(amt).unwrap();
2102 let new_sp = self.state[XReg::sp].get_ptr::<u8>().wrapping_add(amt);
2103 self.set_sp_unchecked(new_sp);
2104 ControlFlow::Continue(())
2105 }
2106
2107 fn zext8(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2108 let src = self.state[src].get_u64() as u8;
2109 self.state[dst].set_u64(src.into());
2110 ControlFlow::Continue(())
2111 }
2112
2113 fn zext16(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2114 let src = self.state[src].get_u64() as u16;
2115 self.state[dst].set_u64(src.into());
2116 ControlFlow::Continue(())
2117 }
2118
2119 fn zext32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2120 let src = self.state[src].get_u64() as u32;
2121 self.state[dst].set_u64(src.into());
2122 ControlFlow::Continue(())
2123 }
2124
2125 fn sext8(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2126 let src = self.state[src].get_i64() as i8;
2127 self.state[dst].set_i64(src.into());
2128 ControlFlow::Continue(())
2129 }
2130
2131 fn sext16(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2132 let src = self.state[src].get_i64() as i16;
2133 self.state[dst].set_i64(src.into());
2134 ControlFlow::Continue(())
2135 }
2136
2137 fn sext32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2138 let src = self.state[src].get_i64() as i32;
2139 self.state[dst].set_i64(src.into());
2140 ControlFlow::Continue(())
2141 }
2142
2143 fn xdiv32_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2144 let a = self.state[operands.src1].get_i32();
2145 let b = self.state[operands.src2].get_i32();
2146 match a.checked_div(b) {
2147 Some(result) => {
2148 self.state[operands.dst].set_i32(result);
2149 ControlFlow::Continue(())
2150 }
2151 None => {
2152 let kind = if b == 0 {
2153 TrapKind::DivideByZero
2154 } else {
2155 TrapKind::IntegerOverflow
2156 };
2157 self.done_trap_kind::<crate::XDiv32S>(Some(kind))
2158 }
2159 }
2160 }
2161
2162 fn xdiv64_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2163 let a = self.state[operands.src1].get_i64();
2164 let b = self.state[operands.src2].get_i64();
2165 match a.checked_div(b) {
2166 Some(result) => {
2167 self.state[operands.dst].set_i64(result);
2168 ControlFlow::Continue(())
2169 }
2170 None => {
2171 let kind = if b == 0 {
2172 TrapKind::DivideByZero
2173 } else {
2174 TrapKind::IntegerOverflow
2175 };
2176 self.done_trap_kind::<crate::XDiv64S>(Some(kind))
2177 }
2178 }
2179 }
2180
2181 fn xdiv32_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2182 let a = self.state[operands.src1].get_u32();
2183 let b = self.state[operands.src2].get_u32();
2184 match a.checked_div(b) {
2185 Some(result) => {
2186 self.state[operands.dst].set_u32(result);
2187 ControlFlow::Continue(())
2188 }
2189 None => self.done_trap_kind::<crate::XDiv64U>(Some(TrapKind::DivideByZero)),
2190 }
2191 }
2192
2193 fn xdiv64_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2194 let a = self.state[operands.src1].get_u64();
2195 let b = self.state[operands.src2].get_u64();
2196 match a.checked_div(b) {
2197 Some(result) => {
2198 self.state[operands.dst].set_u64(result);
2199 ControlFlow::Continue(())
2200 }
2201 None => self.done_trap_kind::<crate::XDiv64U>(Some(TrapKind::DivideByZero)),
2202 }
2203 }
2204
2205 fn xrem32_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2206 let a = self.state[operands.src1].get_i32();
2207 let b = self.state[operands.src2].get_i32();
2208 let result = if a == i32::MIN && b == -1 {
2209 Some(0)
2210 } else {
2211 a.checked_rem(b)
2212 };
2213 match result {
2214 Some(result) => {
2215 self.state[operands.dst].set_i32(result);
2216 ControlFlow::Continue(())
2217 }
2218 None => self.done_trap_kind::<crate::XRem32S>(Some(TrapKind::DivideByZero)),
2219 }
2220 }
2221
2222 fn xrem64_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2223 let a = self.state[operands.src1].get_i64();
2224 let b = self.state[operands.src2].get_i64();
2225 let result = if a == i64::MIN && b == -1 {
2226 Some(0)
2227 } else {
2228 a.checked_rem(b)
2229 };
2230 match result {
2231 Some(result) => {
2232 self.state[operands.dst].set_i64(result);
2233 ControlFlow::Continue(())
2234 }
2235 None => self.done_trap_kind::<crate::XRem64S>(Some(TrapKind::DivideByZero)),
2236 }
2237 }
2238
2239 fn xrem32_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2240 let a = self.state[operands.src1].get_u32();
2241 let b = self.state[operands.src2].get_u32();
2242 match a.checked_rem(b) {
2243 Some(result) => {
2244 self.state[operands.dst].set_u32(result);
2245 ControlFlow::Continue(())
2246 }
2247 None => self.done_trap_kind::<crate::XRem32U>(Some(TrapKind::DivideByZero)),
2248 }
2249 }
2250
2251 fn xrem64_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2252 let a = self.state[operands.src1].get_u64();
2253 let b = self.state[operands.src2].get_u64();
2254 match a.checked_rem(b) {
2255 Some(result) => {
2256 self.state[operands.dst].set_u64(result);
2257 ControlFlow::Continue(())
2258 }
2259 None => self.done_trap_kind::<crate::XRem64U>(Some(TrapKind::DivideByZero)),
2260 }
2261 }
2262
2263 fn xband32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2264 let a = self.state[operands.src1].get_u32();
2265 let b = self.state[operands.src2].get_u32();
2266 self.state[operands.dst].set_u32(a & b);
2267 ControlFlow::Continue(())
2268 }
2269
2270 fn xband32_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
2271 self.xband32_s32(dst, src1, src2.into())
2272 }
2273
2274 fn xband32_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
2275 let a = self.state[src1].get_i32();
2276 self.state[dst].set_i32(a & src2);
2277 ControlFlow::Continue(())
2278 }
2279
2280 fn xband64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2281 let a = self.state[operands.src1].get_u64();
2282 let b = self.state[operands.src2].get_u64();
2283 self.state[operands.dst].set_u64(a & b);
2284 ControlFlow::Continue(())
2285 }
2286
2287 fn xband64_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
2288 self.xband64_s32(dst, src1, src2.into())
2289 }
2290
2291 fn xband64_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
2292 let a = self.state[src1].get_i64();
2293 self.state[dst].set_i64(a & i64::from(src2));
2294 ControlFlow::Continue(())
2295 }
2296
2297 fn xbor32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2298 let a = self.state[operands.src1].get_u32();
2299 let b = self.state[operands.src2].get_u32();
2300 self.state[operands.dst].set_u32(a | b);
2301 ControlFlow::Continue(())
2302 }
2303
2304 fn xbor32_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
2305 self.xbor32_s32(dst, src1, src2.into())
2306 }
2307
2308 fn xbor32_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
2309 let a = self.state[src1].get_i32();
2310 self.state[dst].set_i32(a | src2);
2311 ControlFlow::Continue(())
2312 }
2313
2314 fn xbor64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2315 let a = self.state[operands.src1].get_u64();
2316 let b = self.state[operands.src2].get_u64();
2317 self.state[operands.dst].set_u64(a | b);
2318 ControlFlow::Continue(())
2319 }
2320
2321 fn xbor64_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
2322 self.xbor64_s32(dst, src1, src2.into())
2323 }
2324
2325 fn xbor64_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
2326 let a = self.state[src1].get_i64();
2327 self.state[dst].set_i64(a | i64::from(src2));
2328 ControlFlow::Continue(())
2329 }
2330
2331 fn xbxor32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2332 let a = self.state[operands.src1].get_u32();
2333 let b = self.state[operands.src2].get_u32();
2334 self.state[operands.dst].set_u32(a ^ b);
2335 ControlFlow::Continue(())
2336 }
2337
2338 fn xbxor32_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
2339 self.xbxor32_s32(dst, src1, src2.into())
2340 }
2341
2342 fn xbxor32_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
2343 let a = self.state[src1].get_i32();
2344 self.state[dst].set_i32(a ^ src2);
2345 ControlFlow::Continue(())
2346 }
2347
2348 fn xbxor64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2349 let a = self.state[operands.src1].get_u64();
2350 let b = self.state[operands.src2].get_u64();
2351 self.state[operands.dst].set_u64(a ^ b);
2352 ControlFlow::Continue(())
2353 }
2354
2355 fn xbxor64_s8(&mut self, dst: XReg, src1: XReg, src2: i8) -> ControlFlow<Done> {
2356 self.xbxor64_s32(dst, src1, src2.into())
2357 }
2358
2359 fn xbxor64_s32(&mut self, dst: XReg, src1: XReg, src2: i32) -> ControlFlow<Done> {
2360 let a = self.state[src1].get_i64();
2361 self.state[dst].set_i64(a ^ i64::from(src2));
2362 ControlFlow::Continue(())
2363 }
2364
2365 fn xbnot32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2366 let a = self.state[src].get_u32();
2367 self.state[dst].set_u32(!a);
2368 ControlFlow::Continue(())
2369 }
2370
2371 fn xbnot64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2372 let a = self.state[src].get_u64();
2373 self.state[dst].set_u64(!a);
2374 ControlFlow::Continue(())
2375 }
2376
2377 fn xmin32_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2378 let a = self.state[operands.src1].get_u32();
2379 let b = self.state[operands.src2].get_u32();
2380 self.state[operands.dst].set_u32(a.min(b));
2381 ControlFlow::Continue(())
2382 }
2383
2384 fn xmin32_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2385 let a = self.state[operands.src1].get_i32();
2386 let b = self.state[operands.src2].get_i32();
2387 self.state[operands.dst].set_i32(a.min(b));
2388 ControlFlow::Continue(())
2389 }
2390
2391 fn xmax32_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2392 let a = self.state[operands.src1].get_u32();
2393 let b = self.state[operands.src2].get_u32();
2394 self.state[operands.dst].set_u32(a.max(b));
2395 ControlFlow::Continue(())
2396 }
2397
2398 fn xmax32_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2399 let a = self.state[operands.src1].get_i32();
2400 let b = self.state[operands.src2].get_i32();
2401 self.state[operands.dst].set_i32(a.max(b));
2402 ControlFlow::Continue(())
2403 }
2404
2405 fn xmin64_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2406 let a = self.state[operands.src1].get_u64();
2407 let b = self.state[operands.src2].get_u64();
2408 self.state[operands.dst].set_u64(a.min(b));
2409 ControlFlow::Continue(())
2410 }
2411
2412 fn xmin64_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2413 let a = self.state[operands.src1].get_i64();
2414 let b = self.state[operands.src2].get_i64();
2415 self.state[operands.dst].set_i64(a.min(b));
2416 ControlFlow::Continue(())
2417 }
2418
2419 fn xmax64_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2420 let a = self.state[operands.src1].get_u64();
2421 let b = self.state[operands.src2].get_u64();
2422 self.state[operands.dst].set_u64(a.max(b));
2423 ControlFlow::Continue(())
2424 }
2425
2426 fn xmax64_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2427 let a = self.state[operands.src1].get_i64();
2428 let b = self.state[operands.src2].get_i64();
2429 self.state[operands.dst].set_i64(a.max(b));
2430 ControlFlow::Continue(())
2431 }
2432
2433 fn xctz32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2434 let a = self.state[src].get_u32();
2435 self.state[dst].set_u32(a.trailing_zeros());
2436 ControlFlow::Continue(())
2437 }
2438
2439 fn xctz64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2440 let a = self.state[src].get_u64();
2441 self.state[dst].set_u64(a.trailing_zeros().into());
2442 ControlFlow::Continue(())
2443 }
2444
2445 fn xclz32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2446 let a = self.state[src].get_u32();
2447 self.state[dst].set_u32(a.leading_zeros());
2448 ControlFlow::Continue(())
2449 }
2450
2451 fn xclz64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2452 let a = self.state[src].get_u64();
2453 self.state[dst].set_u64(a.leading_zeros().into());
2454 ControlFlow::Continue(())
2455 }
2456
2457 fn xpopcnt32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2458 let a = self.state[src].get_u32();
2459 self.state[dst].set_u32(a.count_ones());
2460 ControlFlow::Continue(())
2461 }
2462
2463 fn xpopcnt64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2464 let a = self.state[src].get_u64();
2465 self.state[dst].set_u64(a.count_ones().into());
2466 ControlFlow::Continue(())
2467 }
2468
2469 fn xrotl32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2470 let a = self.state[operands.src1].get_u32();
2471 let b = self.state[operands.src2].get_u32();
2472 self.state[operands.dst].set_u32(a.rotate_left(b));
2473 ControlFlow::Continue(())
2474 }
2475
2476 fn xrotl64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2477 let a = self.state[operands.src1].get_u64();
2478 let b = self.state[operands.src2].get_u32();
2479 self.state[operands.dst].set_u64(a.rotate_left(b));
2480 ControlFlow::Continue(())
2481 }
2482
2483 fn xrotr32(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2484 let a = self.state[operands.src1].get_u32();
2485 let b = self.state[operands.src2].get_u32();
2486 self.state[operands.dst].set_u32(a.rotate_right(b));
2487 ControlFlow::Continue(())
2488 }
2489
2490 fn xrotr64(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2491 let a = self.state[operands.src1].get_u64();
2492 let b = self.state[operands.src2].get_u32();
2493 self.state[operands.dst].set_u64(a.rotate_right(b));
2494 ControlFlow::Continue(())
2495 }
2496
2497 fn xselect32(
2498 &mut self,
2499 dst: XReg,
2500 cond: XReg,
2501 if_nonzero: XReg,
2502 if_zero: XReg,
2503 ) -> ControlFlow<Done> {
2504 let result = if self.state[cond].get_u32() != 0 {
2505 self.state[if_nonzero].get_u32()
2506 } else {
2507 self.state[if_zero].get_u32()
2508 };
2509 self.state[dst].set_u32(result);
2510 ControlFlow::Continue(())
2511 }
2512
2513 fn xselect64(
2514 &mut self,
2515 dst: XReg,
2516 cond: XReg,
2517 if_nonzero: XReg,
2518 if_zero: XReg,
2519 ) -> ControlFlow<Done> {
2520 let result = if self.state[cond].get_u32() != 0 {
2521 self.state[if_nonzero].get_u64()
2522 } else {
2523 self.state[if_zero].get_u64()
2524 };
2525 self.state[dst].set_u64(result);
2526 ControlFlow::Continue(())
2527 }
2528
2529 fn xabs32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2530 let a = self.state[src].get_i32();
2531 self.state[dst].set_i32(a.wrapping_abs());
2532 ControlFlow::Continue(())
2533 }
2534
2535 fn xabs64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2536 let a = self.state[src].get_i64();
2537 self.state[dst].set_i64(a.wrapping_abs());
2538 ControlFlow::Continue(())
2539 }
2540
2541 fn xbc32_bound_trap(&mut self, addr: XReg, bound: XReg, size: u8) -> ControlFlow<Done> {
2542 let bound = self.state[bound].get_u64() as usize;
2543 let addr = self.state[addr].get_u32() as usize;
2544 if addr > bound.wrapping_sub(usize::from(size)) {
2545 self.done_trap::<crate::XBc32BoundTrap>()
2546 } else {
2547 ControlFlow::Continue(())
2548 }
2549 }
2550
2551 fn xbc32_boundne_trap(
2552 &mut self,
2553 addr: XReg,
2554 bound_ptr: XReg,
2555 bound_off: u8,
2556 size: u8,
2557 ) -> ControlFlow<Done> {
2558 let bound = unsafe { self.load::<usize>(bound_ptr, bound_off.into()) };
2559 let addr = self.state[addr].get_u32() as usize;
2560 if addr > bound.wrapping_sub(usize::from(size)) {
2561 self.done_trap::<crate::XBc32BoundNeTrap>()
2562 } else {
2563 ControlFlow::Continue(())
2564 }
2565 }
2566
2567 fn xbc32_strict_bound_trap(&mut self, addr: XReg, bound: XReg) -> ControlFlow<Done> {
2568 let bound = self.state[bound].get_u64() as usize;
2569 let addr = self.state[addr].get_u32() as usize;
2570 if addr >= bound {
2571 self.done_trap::<crate::XBc32StrictBoundTrap>()
2572 } else {
2573 ControlFlow::Continue(())
2574 }
2575 }
2576
2577 fn xbc32_strict_boundne_trap(
2578 &mut self,
2579 addr: XReg,
2580 bound_ptr: XReg,
2581 bound_off: u8,
2582 ) -> ControlFlow<Done> {
2583 let bound = unsafe { self.load::<usize>(bound_ptr, bound_off.into()) };
2584 let addr = self.state[addr].get_u32() as usize;
2585 if addr >= bound {
2586 self.done_trap::<crate::XBc32StrictBoundNeTrap>()
2587 } else {
2588 ControlFlow::Continue(())
2589 }
2590 }
2591
2592 fn xload8_u32_g32(
2593 &mut self,
2594 dst: XReg,
2595 base: XReg,
2596 addr: XReg,
2597 offset: u8,
2598 ) -> ControlFlow<Done> {
2599 let result = unsafe { self.load_g32::<u8>(base, addr, offset) };
2600 self.state[dst].set_u32(result.into());
2601 ControlFlow::Continue(())
2602 }
2603
2604 fn xload8_s32_g32(
2605 &mut self,
2606 dst: XReg,
2607 base: XReg,
2608 addr: XReg,
2609 offset: u8,
2610 ) -> ControlFlow<Done> {
2611 let result = unsafe { self.load_g32::<i8>(base, addr, offset) };
2612 self.state[dst].set_i32(result.into());
2613 ControlFlow::Continue(())
2614 }
2615
2616 fn xload16le_u32_g32(
2617 &mut self,
2618 dst: XReg,
2619 base: XReg,
2620 addr: XReg,
2621 offset: u8,
2622 ) -> ControlFlow<Done> {
2623 let result = unsafe { self.load_g32::<u16>(base, addr, offset) };
2624 self.state[dst].set_u32(u16::from_le(result).into());
2625 ControlFlow::Continue(())
2626 }
2627
2628 fn xload16le_s32_g32(
2629 &mut self,
2630 dst: XReg,
2631 base: XReg,
2632 addr: XReg,
2633 offset: u8,
2634 ) -> ControlFlow<Done> {
2635 let result = unsafe { self.load_g32::<i16>(base, addr, offset) };
2636 self.state[dst].set_i32(i16::from_le(result).into());
2637 ControlFlow::Continue(())
2638 }
2639
2640 fn xload32le_g32(
2641 &mut self,
2642 dst: XReg,
2643 base: XReg,
2644 addr: XReg,
2645 offset: u8,
2646 ) -> ControlFlow<Done> {
2647 let result = unsafe { self.load_g32::<i32>(base, addr, offset) };
2648 self.state[dst].set_i32(i32::from_le(result));
2649 ControlFlow::Continue(())
2650 }
2651
2652 fn xload64le_g32(
2653 &mut self,
2654 dst: XReg,
2655 base: XReg,
2656 addr: XReg,
2657 offset: u8,
2658 ) -> ControlFlow<Done> {
2659 let result = unsafe { self.load_g32::<i64>(base, addr, offset) };
2660 self.state[dst].set_i64(i64::from_le(result));
2661 ControlFlow::Continue(())
2662 }
2663
2664 fn xstore8_g32(&mut self, base: XReg, addr: XReg, offset: u8, val: XReg) -> ControlFlow<Done> {
2665 let val = self.state[val].get_u32() as u8;
2666 unsafe {
2667 self.store_g32(base, addr, offset, val);
2668 }
2669 ControlFlow::Continue(())
2670 }
2671
2672 fn xstore16le_g32(
2673 &mut self,
2674 base: XReg,
2675 addr: XReg,
2676 offset: u8,
2677 val: XReg,
2678 ) -> ControlFlow<Done> {
2679 let val = self.state[val].get_u32() as u16;
2680 unsafe {
2681 self.store_g32(base, addr, offset, val.to_le());
2682 }
2683 ControlFlow::Continue(())
2684 }
2685
2686 fn xstore32le_g32(
2687 &mut self,
2688 base: XReg,
2689 addr: XReg,
2690 offset: u8,
2691 val: XReg,
2692 ) -> ControlFlow<Done> {
2693 let val = self.state[val].get_u32();
2694 unsafe {
2695 self.store_g32(base, addr, offset, val.to_le());
2696 }
2697 ControlFlow::Continue(())
2698 }
2699
2700 fn xstore64le_g32(
2701 &mut self,
2702 base: XReg,
2703 addr: XReg,
2704 offset: u8,
2705 val: XReg,
2706 ) -> ControlFlow<Done> {
2707 let val = self.state[val].get_u64();
2708 unsafe {
2709 self.store_g32(base, addr, offset, val.to_le());
2710 }
2711 ControlFlow::Continue(())
2712 }
2713}
2714
2715impl ExtendedOpVisitor for Interpreter<'_> {
2716 fn nop(&mut self) -> ControlFlow<Done> {
2717 ControlFlow::Continue(())
2718 }
2719
2720 fn trap(&mut self) -> ControlFlow<Done> {
2721 self.done_trap::<crate::Trap>()
2722 }
2723
2724 fn call_indirect_host(&mut self, id: u8) -> ControlFlow<Done> {
2725 self.done_call_indirect_host(id)
2726 }
2727
2728 fn bswap32(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2729 let src = self.state[src].get_u32();
2730 self.state[dst].set_u32(src.swap_bytes());
2731 ControlFlow::Continue(())
2732 }
2733
2734 fn bswap64(&mut self, dst: XReg, src: XReg) -> ControlFlow<Done> {
2735 let src = self.state[src].get_u64();
2736 self.state[dst].set_u64(src.swap_bytes());
2737 ControlFlow::Continue(())
2738 }
2739
2740 fn xbmask32(&mut self, dst: XReg, src: XReg) -> Self::Return {
2741 let a = self.state[src].get_u32();
2742 if a == 0 {
2743 self.state[dst].set_u32(0);
2744 } else {
2745 self.state[dst].set_i32(-1);
2746 }
2747 ControlFlow::Continue(())
2748 }
2749
2750 fn xbmask64(&mut self, dst: XReg, src: XReg) -> Self::Return {
2751 let a = self.state[src].get_u64();
2752 if a == 0 {
2753 self.state[dst].set_u64(0);
2754 } else {
2755 self.state[dst].set_i64(-1);
2756 }
2757 ControlFlow::Continue(())
2758 }
2759
2760 fn xadd32_uoverflow_trap(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2761 let a = self.state[operands.src1].get_u32();
2762 let b = self.state[operands.src2].get_u32();
2763 match a.checked_add(b) {
2764 Some(c) => {
2765 self.state[operands.dst].set_u32(c);
2766 ControlFlow::Continue(())
2767 }
2768 None => self.done_trap::<crate::Xadd32UoverflowTrap>(),
2769 }
2770 }
2771
2772 fn xadd64_uoverflow_trap(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2773 let a = self.state[operands.src1].get_u64();
2774 let b = self.state[operands.src2].get_u64();
2775 match a.checked_add(b) {
2776 Some(c) => {
2777 self.state[operands.dst].set_u64(c);
2778 ControlFlow::Continue(())
2779 }
2780 None => self.done_trap::<crate::Xadd64UoverflowTrap>(),
2781 }
2782 }
2783
2784 fn xmulhi64_s(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2785 let a = self.state[operands.src1].get_i64();
2786 let b = self.state[operands.src2].get_i64();
2787 let result = ((i128::from(a) * i128::from(b)) >> 64) as i64;
2788 self.state[operands.dst].set_i64(result);
2789 ControlFlow::Continue(())
2790 }
2791
2792 fn xmulhi64_u(&mut self, operands: BinaryOperands<XReg>) -> ControlFlow<Done> {
2793 let a = self.state[operands.src1].get_u64();
2794 let b = self.state[operands.src2].get_u64();
2795 let result = ((u128::from(a) * u128::from(b)) >> 64) as u64;
2796 self.state[operands.dst].set_u64(result);
2797 ControlFlow::Continue(())
2798 }
2799
2800 fn xload16be_u64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2801 let val = unsafe { self.load::<u16>(ptr, offset) };
2802 self.state[dst].set_u64(u16::from_be(val).into());
2803 ControlFlow::Continue(())
2804 }
2805
2806 fn xload16be_s64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2807 let val = unsafe { self.load::<i16>(ptr, offset) };
2808 self.state[dst].set_i64(i16::from_be(val).into());
2809 ControlFlow::Continue(())
2810 }
2811
2812 fn xload32be_u64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2813 let val = unsafe { self.load::<u32>(ptr, offset) };
2814 self.state[dst].set_u64(u32::from_be(val).into());
2815 ControlFlow::Continue(())
2816 }
2817
2818 fn xload32be_s64_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2819 let val = unsafe { self.load::<i32>(ptr, offset) };
2820 self.state[dst].set_i64(i32::from_be(val).into());
2821 ControlFlow::Continue(())
2822 }
2823
2824 fn xload64be_offset32(&mut self, dst: XReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2825 let val = unsafe { self.load::<i64>(ptr, offset) };
2826 self.state[dst].set_i64(i64::from_be(val));
2827 ControlFlow::Continue(())
2828 }
2829
2830 fn xstore16be_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
2831 let val = self.state[src].get_u32() as u16;
2832 unsafe {
2833 self.store(ptr, offset, val.to_be());
2834 }
2835 ControlFlow::Continue(())
2836 }
2837
2838 fn xstore32be_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
2839 let val = self.state[src].get_u32();
2840 unsafe {
2841 self.store(ptr, offset, val.to_be());
2842 }
2843 ControlFlow::Continue(())
2844 }
2845
2846 fn xstore64be_offset32(&mut self, ptr: XReg, offset: i32, src: XReg) -> ControlFlow<Done> {
2847 let val = self.state[src].get_u64();
2848 unsafe {
2849 self.store(ptr, offset, val.to_be());
2850 }
2851 ControlFlow::Continue(())
2852 }
2853
2854 fn fload32be_offset32(&mut self, dst: FReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2855 let val = unsafe { self.load::<u32>(ptr, offset) };
2856 self.state[dst].set_f32(f32::from_bits(u32::from_be(val)));
2857 ControlFlow::Continue(())
2858 }
2859
2860 fn fload64be_offset32(&mut self, dst: FReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2861 let val = unsafe { self.load::<u64>(ptr, offset) };
2862 self.state[dst].set_f64(f64::from_bits(u64::from_be(val)));
2863 ControlFlow::Continue(())
2864 }
2865
2866 fn fstore32be_offset32(&mut self, ptr: XReg, offset: i32, src: FReg) -> ControlFlow<Done> {
2867 let val = self.state[src].get_f32();
2868 unsafe {
2869 self.store(ptr, offset, val.to_bits().to_be());
2870 }
2871 ControlFlow::Continue(())
2872 }
2873
2874 fn fstore64be_offset32(&mut self, ptr: XReg, offset: i32, src: FReg) -> ControlFlow<Done> {
2875 let val = self.state[src].get_f64();
2876 unsafe {
2877 self.store(ptr, offset, val.to_bits().to_be());
2878 }
2879 ControlFlow::Continue(())
2880 }
2881
2882 fn fload32le_offset32(&mut self, dst: FReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2883 let val = unsafe { self.load::<u32>(ptr, offset) };
2884 self.state[dst].set_f32(f32::from_bits(u32::from_le(val)));
2885 ControlFlow::Continue(())
2886 }
2887
2888 fn fload64le_offset32(&mut self, dst: FReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2889 let val = unsafe { self.load::<u64>(ptr, offset) };
2890 self.state[dst].set_f64(f64::from_bits(u64::from_le(val)));
2891 ControlFlow::Continue(())
2892 }
2893
2894 fn fstore32le_offset32(&mut self, ptr: XReg, offset: i32, src: FReg) -> ControlFlow<Done> {
2895 let val = self.state[src].get_f32();
2896 unsafe {
2897 self.store(ptr, offset, val.to_bits().to_le());
2898 }
2899 ControlFlow::Continue(())
2900 }
2901
2902 fn fstore64le_offset32(&mut self, ptr: XReg, offset: i32, src: FReg) -> ControlFlow<Done> {
2903 let val = self.state[src].get_f64();
2904 unsafe {
2905 self.store(ptr, offset, val.to_bits().to_le());
2906 }
2907 ControlFlow::Continue(())
2908 }
2909
2910 fn vload128le_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
2911 let val = unsafe { self.load::<u128>(ptr, offset) };
2912 self.state[dst].set_u128(u128::from_le(val));
2913 ControlFlow::Continue(())
2914 }
2915
2916 fn vstore128le_offset32(&mut self, ptr: XReg, offset: i32, src: VReg) -> ControlFlow<Done> {
2917 let val = self.state[src].get_u128();
2918 unsafe {
2919 self.store(ptr, offset, val.to_le());
2920 }
2921 ControlFlow::Continue(())
2922 }
2923
2924 fn xmov_fp(&mut self, dst: XReg) -> ControlFlow<Done> {
2925 let fp = self.state.fp;
2926 self.state[dst].set_ptr(fp);
2927 ControlFlow::Continue(())
2928 }
2929
2930 fn xmov_lr(&mut self, dst: XReg) -> ControlFlow<Done> {
2931 let lr = self.state.lr;
2932 self.state[dst].set_ptr(lr);
2933 ControlFlow::Continue(())
2934 }
2935
2936 fn fmov(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
2937 let val = self.state[src];
2938 self.state[dst] = val;
2939 ControlFlow::Continue(())
2940 }
2941
2942 fn vmov(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
2943 let val = self.state[src];
2944 self.state[dst] = val;
2945 ControlFlow::Continue(())
2946 }
2947
2948 fn fconst32(&mut self, dst: FReg, bits: u32) -> ControlFlow<Done> {
2949 self.state[dst].set_f32(f32::from_bits(bits));
2950 ControlFlow::Continue(())
2951 }
2952
2953 fn fconst64(&mut self, dst: FReg, bits: u64) -> ControlFlow<Done> {
2954 self.state[dst].set_f64(f64::from_bits(bits));
2955 ControlFlow::Continue(())
2956 }
2957
2958 fn bitcast_int_from_float_32(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
2959 let val = self.state[src].get_f32();
2960 self.state[dst].set_u32(val.to_bits());
2961 ControlFlow::Continue(())
2962 }
2963
2964 fn bitcast_int_from_float_64(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
2965 let val = self.state[src].get_f64();
2966 self.state[dst].set_u64(val.to_bits());
2967 ControlFlow::Continue(())
2968 }
2969
2970 fn bitcast_float_from_int_32(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
2971 let val = self.state[src].get_u32();
2972 self.state[dst].set_f32(f32::from_bits(val));
2973 ControlFlow::Continue(())
2974 }
2975
2976 fn bitcast_float_from_int_64(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
2977 let val = self.state[src].get_u64();
2978 self.state[dst].set_f64(f64::from_bits(val));
2979 ControlFlow::Continue(())
2980 }
2981
2982 fn feq32(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
2983 let a = self.state[src1].get_f32();
2984 let b = self.state[src2].get_f32();
2985 self.state[dst].set_u32(u32::from(a == b));
2986 ControlFlow::Continue(())
2987 }
2988
2989 fn fneq32(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
2990 let a = self.state[src1].get_f32();
2991 let b = self.state[src2].get_f32();
2992 self.state[dst].set_u32(u32::from(a != b));
2993 ControlFlow::Continue(())
2994 }
2995
2996 fn flt32(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
2997 let a = self.state[src1].get_f32();
2998 let b = self.state[src2].get_f32();
2999 self.state[dst].set_u32(u32::from(a < b));
3000 ControlFlow::Continue(())
3001 }
3002
3003 fn flteq32(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
3004 let a = self.state[src1].get_f32();
3005 let b = self.state[src2].get_f32();
3006 self.state[dst].set_u32(u32::from(a <= b));
3007 ControlFlow::Continue(())
3008 }
3009
3010 fn feq64(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
3011 let a = self.state[src1].get_f64();
3012 let b = self.state[src2].get_f64();
3013 self.state[dst].set_u32(u32::from(a == b));
3014 ControlFlow::Continue(())
3015 }
3016
3017 fn fneq64(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
3018 let a = self.state[src1].get_f64();
3019 let b = self.state[src2].get_f64();
3020 self.state[dst].set_u32(u32::from(a != b));
3021 ControlFlow::Continue(())
3022 }
3023
3024 fn flt64(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
3025 let a = self.state[src1].get_f64();
3026 let b = self.state[src2].get_f64();
3027 self.state[dst].set_u32(u32::from(a < b));
3028 ControlFlow::Continue(())
3029 }
3030
3031 fn flteq64(&mut self, dst: XReg, src1: FReg, src2: FReg) -> ControlFlow<Done> {
3032 let a = self.state[src1].get_f64();
3033 let b = self.state[src2].get_f64();
3034 self.state[dst].set_u32(u32::from(a <= b));
3035 ControlFlow::Continue(())
3036 }
3037
3038 fn fselect32(
3039 &mut self,
3040 dst: FReg,
3041 cond: XReg,
3042 if_nonzero: FReg,
3043 if_zero: FReg,
3044 ) -> ControlFlow<Done> {
3045 let result = if self.state[cond].get_u32() != 0 {
3046 self.state[if_nonzero].get_f32()
3047 } else {
3048 self.state[if_zero].get_f32()
3049 };
3050 self.state[dst].set_f32(result);
3051 ControlFlow::Continue(())
3052 }
3053
3054 fn fselect64(
3055 &mut self,
3056 dst: FReg,
3057 cond: XReg,
3058 if_nonzero: FReg,
3059 if_zero: FReg,
3060 ) -> ControlFlow<Done> {
3061 let result = if self.state[cond].get_u32() != 0 {
3062 self.state[if_nonzero].get_f64()
3063 } else {
3064 self.state[if_zero].get_f64()
3065 };
3066 self.state[dst].set_f64(result);
3067 ControlFlow::Continue(())
3068 }
3069
3070 fn f32_from_x32_s(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3071 let a = self.state[src].get_i32();
3072 self.state[dst].set_f32(a as f32);
3073 ControlFlow::Continue(())
3074 }
3075
3076 fn f32_from_x32_u(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3077 let a = self.state[src].get_u32();
3078 self.state[dst].set_f32(a as f32);
3079 ControlFlow::Continue(())
3080 }
3081
3082 fn f32_from_x64_s(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3083 let a = self.state[src].get_i64();
3084 self.state[dst].set_f32(a as f32);
3085 ControlFlow::Continue(())
3086 }
3087
3088 fn f32_from_x64_u(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3089 let a = self.state[src].get_u64();
3090 self.state[dst].set_f32(a as f32);
3091 ControlFlow::Continue(())
3092 }
3093
3094 fn f64_from_x32_s(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3095 let a = self.state[src].get_i32();
3096 self.state[dst].set_f64(a as f64);
3097 ControlFlow::Continue(())
3098 }
3099
3100 fn f64_from_x32_u(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3101 let a = self.state[src].get_u32();
3102 self.state[dst].set_f64(a as f64);
3103 ControlFlow::Continue(())
3104 }
3105
3106 fn f64_from_x64_s(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3107 let a = self.state[src].get_i64();
3108 self.state[dst].set_f64(a as f64);
3109 ControlFlow::Continue(())
3110 }
3111
3112 fn f64_from_x64_u(&mut self, dst: FReg, src: XReg) -> ControlFlow<Done> {
3113 let a = self.state[src].get_u64();
3114 self.state[dst].set_f64(a as f64);
3115 ControlFlow::Continue(())
3116 }
3117
3118 fn x32_from_f32_s(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3119 let a = self.state[src].get_f32();
3120 self.check_xnn_from_fnn::<crate::X32FromF32S>(a.into(), -2147483649.0, 2147483648.0)?;
3121 self.state[dst].set_i32(a as i32);
3122 ControlFlow::Continue(())
3123 }
3124
3125 fn x32_from_f32_u(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3126 let a = self.state[src].get_f32();
3127 self.check_xnn_from_fnn::<crate::X32FromF32U>(a.into(), -1.0, 4294967296.0)?;
3128 self.state[dst].set_u32(a as u32);
3129 ControlFlow::Continue(())
3130 }
3131
3132 fn x64_from_f32_s(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3133 let a = self.state[src].get_f32();
3134 self.check_xnn_from_fnn::<crate::X64FromF32S>(
3135 a.into(),
3136 -9223372036854777856.0,
3137 9223372036854775808.0,
3138 )?;
3139 self.state[dst].set_i64(a as i64);
3140 ControlFlow::Continue(())
3141 }
3142
3143 fn x64_from_f32_u(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3144 let a = self.state[src].get_f32();
3145 self.check_xnn_from_fnn::<crate::X64FromF32U>(a.into(), -1.0, 18446744073709551616.0)?;
3146 self.state[dst].set_u64(a as u64);
3147 ControlFlow::Continue(())
3148 }
3149
3150 fn x32_from_f64_s(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3151 let a = self.state[src].get_f64();
3152 self.check_xnn_from_fnn::<crate::X32FromF64S>(a, -2147483649.0, 2147483648.0)?;
3153 self.state[dst].set_i32(a as i32);
3154 ControlFlow::Continue(())
3155 }
3156
3157 fn x32_from_f64_u(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3158 let a = self.state[src].get_f64();
3159 self.check_xnn_from_fnn::<crate::X32FromF64U>(a, -1.0, 4294967296.0)?;
3160 self.state[dst].set_u32(a as u32);
3161 ControlFlow::Continue(())
3162 }
3163
3164 fn x64_from_f64_s(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3165 let a = self.state[src].get_f64();
3166 self.check_xnn_from_fnn::<crate::X64FromF64S>(
3167 a,
3168 -9223372036854777856.0,
3169 9223372036854775808.0,
3170 )?;
3171 self.state[dst].set_i64(a as i64);
3172 ControlFlow::Continue(())
3173 }
3174
3175 fn x64_from_f64_u(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3176 let a = self.state[src].get_f64();
3177 self.check_xnn_from_fnn::<crate::X64FromF64U>(a, -1.0, 18446744073709551616.0)?;
3178 self.state[dst].set_u64(a as u64);
3179 ControlFlow::Continue(())
3180 }
3181
3182 fn x32_from_f32_s_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3183 let a = self.state[src].get_f32();
3184 self.state[dst].set_i32(a as i32);
3185 ControlFlow::Continue(())
3186 }
3187
3188 fn x32_from_f32_u_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3189 let a = self.state[src].get_f32();
3190 self.state[dst].set_u32(a as u32);
3191 ControlFlow::Continue(())
3192 }
3193
3194 fn x64_from_f32_s_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3195 let a = self.state[src].get_f32();
3196 self.state[dst].set_i64(a as i64);
3197 ControlFlow::Continue(())
3198 }
3199
3200 fn x64_from_f32_u_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3201 let a = self.state[src].get_f32();
3202 self.state[dst].set_u64(a as u64);
3203 ControlFlow::Continue(())
3204 }
3205
3206 fn x32_from_f64_s_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3207 let a = self.state[src].get_f64();
3208 self.state[dst].set_i32(a as i32);
3209 ControlFlow::Continue(())
3210 }
3211
3212 fn x32_from_f64_u_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3213 let a = self.state[src].get_f64();
3214 self.state[dst].set_u32(a as u32);
3215 ControlFlow::Continue(())
3216 }
3217
3218 fn x64_from_f64_s_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3219 let a = self.state[src].get_f64();
3220 self.state[dst].set_i64(a as i64);
3221 ControlFlow::Continue(())
3222 }
3223
3224 fn x64_from_f64_u_sat(&mut self, dst: XReg, src: FReg) -> ControlFlow<Done> {
3225 let a = self.state[src].get_f64();
3226 self.state[dst].set_u64(a as u64);
3227 ControlFlow::Continue(())
3228 }
3229
3230 fn f32_from_f64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3231 let a = self.state[src].get_f64();
3232 self.state[dst].set_f32(a as f32);
3233 ControlFlow::Continue(())
3234 }
3235
3236 fn f64_from_f32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3237 let a = self.state[src].get_f32();
3238 self.state[dst].set_f64(a.into());
3239 ControlFlow::Continue(())
3240 }
3241
3242 fn fcopysign32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3243 let a = self.state[operands.src1].get_f32();
3244 let b = self.state[operands.src2].get_f32();
3245 self.state[operands.dst].set_f32(a.wasm_copysign(b));
3246 ControlFlow::Continue(())
3247 }
3248
3249 fn fcopysign64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3250 let a = self.state[operands.src1].get_f64();
3251 let b = self.state[operands.src2].get_f64();
3252 self.state[operands.dst].set_f64(a.wasm_copysign(b));
3253 ControlFlow::Continue(())
3254 }
3255
3256 fn fadd32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3257 let a = self.state[operands.src1].get_f32();
3258 let b = self.state[operands.src2].get_f32();
3259 self.state[operands.dst].set_f32(a + b);
3260 ControlFlow::Continue(())
3261 }
3262
3263 fn fsub32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3264 let a = self.state[operands.src1].get_f32();
3265 let b = self.state[operands.src2].get_f32();
3266 self.state[operands.dst].set_f32(a - b);
3267 ControlFlow::Continue(())
3268 }
3269
3270 fn vsubf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3271 let mut a = self.state[operands.src1].get_f32x4();
3272 let b = self.state[operands.src2].get_f32x4();
3273 for (a, b) in a.iter_mut().zip(b) {
3274 *a = *a - b;
3275 }
3276 self.state[operands.dst].set_f32x4(a);
3277 ControlFlow::Continue(())
3278 }
3279
3280 fn fmul32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3281 let a = self.state[operands.src1].get_f32();
3282 let b = self.state[operands.src2].get_f32();
3283 self.state[operands.dst].set_f32(a * b);
3284 ControlFlow::Continue(())
3285 }
3286
3287 fn vmulf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3288 let mut a = self.state[operands.src1].get_f32x4();
3289 let b = self.state[operands.src2].get_f32x4();
3290 for (a, b) in a.iter_mut().zip(b) {
3291 *a = *a * b;
3292 }
3293 self.state[operands.dst].set_f32x4(a);
3294 ControlFlow::Continue(())
3295 }
3296
3297 fn fdiv32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3298 let a = self.state[operands.src1].get_f32();
3299 let b = self.state[operands.src2].get_f32();
3300 self.state[operands.dst].set_f32(a / b);
3301 ControlFlow::Continue(())
3302 }
3303
3304 fn vdivf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3305 let a = self.state[operands.src1].get_f32x4();
3306 let b = self.state[operands.src2].get_f32x4();
3307 let mut result = [0.0f32; 4];
3308
3309 for i in 0..4 {
3310 result[i] = a[i] / b[i];
3311 }
3312
3313 self.state[operands.dst].set_f32x4(result);
3314 ControlFlow::Continue(())
3315 }
3316
3317 fn vdivf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3318 let a = self.state[operands.src1].get_f64x2();
3319 let b = self.state[operands.src2].get_f64x2();
3320 let mut result = [0.0f64; 2];
3321
3322 for i in 0..2 {
3323 result[i] = a[i] / b[i];
3324 }
3325
3326 self.state[operands.dst].set_f64x2(result);
3327 ControlFlow::Continue(())
3328 }
3329
3330 fn fmaximum32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3331 let a = self.state[operands.src1].get_f32();
3332 let b = self.state[operands.src2].get_f32();
3333 self.state[operands.dst].set_f32(a.wasm_maximum(b));
3334 ControlFlow::Continue(())
3335 }
3336
3337 fn fminimum32(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3338 let a = self.state[operands.src1].get_f32();
3339 let b = self.state[operands.src2].get_f32();
3340 self.state[operands.dst].set_f32(a.wasm_minimum(b));
3341 ControlFlow::Continue(())
3342 }
3343
3344 fn ftrunc32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3345 let a = self.state[src].get_f32();
3346 self.state[dst].set_f32(a.wasm_trunc());
3347 ControlFlow::Continue(())
3348 }
3349
3350 fn vtrunc32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3351 let mut a = self.state[src].get_f32x4();
3352 for elem in a.iter_mut() {
3353 *elem = elem.wasm_trunc();
3354 }
3355 self.state[dst].set_f32x4(a);
3356 ControlFlow::Continue(())
3357 }
3358
3359 fn vtrunc64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3360 let mut a = self.state[src].get_f64x2();
3361 for elem in a.iter_mut() {
3362 *elem = elem.wasm_trunc();
3363 }
3364 self.state[dst].set_f64x2(a);
3365 ControlFlow::Continue(())
3366 }
3367
3368 fn ffloor32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3369 let a = self.state[src].get_f32();
3370 self.state[dst].set_f32(a.wasm_floor());
3371 ControlFlow::Continue(())
3372 }
3373
3374 fn vfloor32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3375 let mut a = self.state[src].get_f32x4();
3376 for elem in a.iter_mut() {
3377 *elem = elem.wasm_floor();
3378 }
3379 self.state[dst].set_f32x4(a);
3380 ControlFlow::Continue(())
3381 }
3382
3383 fn vfloor64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3384 let mut a = self.state[src].get_f64x2();
3385 for elem in a.iter_mut() {
3386 *elem = elem.wasm_floor();
3387 }
3388 self.state[dst].set_f64x2(a);
3389 ControlFlow::Continue(())
3390 }
3391
3392 fn fceil32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3393 let a = self.state[src].get_f32();
3394 self.state[dst].set_f32(a.wasm_ceil());
3395 ControlFlow::Continue(())
3396 }
3397
3398 fn vceil32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3399 let mut a = self.state[src].get_f32x4();
3400 for elem in a.iter_mut() {
3401 *elem = elem.wasm_ceil();
3402 }
3403 self.state[dst].set_f32x4(a);
3404
3405 ControlFlow::Continue(())
3406 }
3407
3408 fn vceil64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3409 let mut a = self.state[src].get_f64x2();
3410 for elem in a.iter_mut() {
3411 *elem = elem.wasm_ceil();
3412 }
3413 self.state[dst].set_f64x2(a);
3414
3415 ControlFlow::Continue(())
3416 }
3417
3418 fn fnearest32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3419 let a = self.state[src].get_f32();
3420 self.state[dst].set_f32(a.wasm_nearest());
3421 ControlFlow::Continue(())
3422 }
3423
3424 fn vnearest32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3425 let mut a = self.state[src].get_f32x4();
3426 for elem in a.iter_mut() {
3427 *elem = elem.wasm_nearest();
3428 }
3429 self.state[dst].set_f32x4(a);
3430 ControlFlow::Continue(())
3431 }
3432
3433 fn vnearest64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3434 let mut a = self.state[src].get_f64x2();
3435 for elem in a.iter_mut() {
3436 *elem = elem.wasm_nearest();
3437 }
3438 self.state[dst].set_f64x2(a);
3439 ControlFlow::Continue(())
3440 }
3441
3442 fn fsqrt32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3443 let a = self.state[src].get_f32();
3444 self.state[dst].set_f32(a.wasm_sqrt());
3445 ControlFlow::Continue(())
3446 }
3447
3448 fn vsqrt32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3449 let mut a = self.state[src].get_f32x4();
3450 for elem in a.iter_mut() {
3451 *elem = elem.wasm_sqrt();
3452 }
3453 self.state[dst].set_f32x4(a);
3454 ControlFlow::Continue(())
3455 }
3456
3457 fn vsqrt64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3458 let mut a = self.state[src].get_f64x2();
3459 for elem in a.iter_mut() {
3460 *elem = elem.wasm_sqrt();
3461 }
3462 self.state[dst].set_f64x2(a);
3463 ControlFlow::Continue(())
3464 }
3465
3466 fn fneg32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3467 let a = self.state[src].get_f32();
3468 self.state[dst].set_f32(-a);
3469 ControlFlow::Continue(())
3470 }
3471
3472 fn vnegf32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3473 let mut a = self.state[src].get_f32x4();
3474 for elem in a.iter_mut() {
3475 *elem = -*elem;
3476 }
3477 self.state[dst].set_f32x4(a);
3478 ControlFlow::Continue(())
3479 }
3480
3481 fn fabs32(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3482 let a = self.state[src].get_f32();
3483 self.state[dst].set_f32(a.wasm_abs());
3484 ControlFlow::Continue(())
3485 }
3486
3487 fn fadd64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3488 let a = self.state[operands.src1].get_f64();
3489 let b = self.state[operands.src2].get_f64();
3490 self.state[operands.dst].set_f64(a + b);
3491 ControlFlow::Continue(())
3492 }
3493
3494 fn fsub64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3495 let a = self.state[operands.src1].get_f64();
3496 let b = self.state[operands.src2].get_f64();
3497 self.state[operands.dst].set_f64(a - b);
3498 ControlFlow::Continue(())
3499 }
3500
3501 fn fmul64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3502 let a = self.state[operands.src1].get_f64();
3503 let b = self.state[operands.src2].get_f64();
3504 self.state[operands.dst].set_f64(a * b);
3505 ControlFlow::Continue(())
3506 }
3507
3508 fn fdiv64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3509 let a = self.state[operands.src1].get_f64();
3510 let b = self.state[operands.src2].get_f64();
3511 self.state[operands.dst].set_f64(a / b);
3512 ControlFlow::Continue(())
3513 }
3514
3515 fn fmaximum64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3516 let a = self.state[operands.src1].get_f64();
3517 let b = self.state[operands.src2].get_f64();
3518 self.state[operands.dst].set_f64(a.wasm_maximum(b));
3519 ControlFlow::Continue(())
3520 }
3521
3522 fn fminimum64(&mut self, operands: BinaryOperands<FReg>) -> ControlFlow<Done> {
3523 let a = self.state[operands.src1].get_f64();
3524 let b = self.state[operands.src2].get_f64();
3525 self.state[operands.dst].set_f64(a.wasm_minimum(b));
3526 ControlFlow::Continue(())
3527 }
3528
3529 fn ftrunc64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3530 let a = self.state[src].get_f64();
3531 self.state[dst].set_f64(a.wasm_trunc());
3532 ControlFlow::Continue(())
3533 }
3534
3535 fn ffloor64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3536 let a = self.state[src].get_f64();
3537 self.state[dst].set_f64(a.wasm_floor());
3538 ControlFlow::Continue(())
3539 }
3540
3541 fn fceil64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3542 let a = self.state[src].get_f64();
3543 self.state[dst].set_f64(a.wasm_ceil());
3544 ControlFlow::Continue(())
3545 }
3546
3547 fn fnearest64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3548 let a = self.state[src].get_f64();
3549 self.state[dst].set_f64(a.wasm_nearest());
3550 ControlFlow::Continue(())
3551 }
3552
3553 fn fsqrt64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3554 let a = self.state[src].get_f64();
3555 self.state[dst].set_f64(a.wasm_sqrt());
3556 ControlFlow::Continue(())
3557 }
3558
3559 fn fneg64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3560 let a = self.state[src].get_f64();
3561 self.state[dst].set_f64(-a);
3562 ControlFlow::Continue(())
3563 }
3564
3565 fn fabs64(&mut self, dst: FReg, src: FReg) -> ControlFlow<Done> {
3566 let a = self.state[src].get_f64();
3567 self.state[dst].set_f64(a.wasm_abs());
3568 ControlFlow::Continue(())
3569 }
3570
3571 fn vaddi8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3572 let mut a = self.state[operands.src1].get_i8x16();
3573 let b = self.state[operands.src2].get_i8x16();
3574 for (a, b) in a.iter_mut().zip(b) {
3575 *a = a.wrapping_add(b);
3576 }
3577 self.state[operands.dst].set_i8x16(a);
3578 ControlFlow::Continue(())
3579 }
3580
3581 fn vaddi16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3582 let mut a = self.state[operands.src1].get_i16x8();
3583 let b = self.state[operands.src2].get_i16x8();
3584 for (a, b) in a.iter_mut().zip(b) {
3585 *a = a.wrapping_add(b);
3586 }
3587 self.state[operands.dst].set_i16x8(a);
3588 ControlFlow::Continue(())
3589 }
3590
3591 fn vaddi32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3592 let mut a = self.state[operands.src1].get_i32x4();
3593 let b = self.state[operands.src2].get_i32x4();
3594 for (a, b) in a.iter_mut().zip(b) {
3595 *a = a.wrapping_add(b);
3596 }
3597 self.state[operands.dst].set_i32x4(a);
3598 ControlFlow::Continue(())
3599 }
3600
3601 fn vaddi64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3602 let mut a = self.state[operands.src1].get_i64x2();
3603 let b = self.state[operands.src2].get_i64x2();
3604 for (a, b) in a.iter_mut().zip(b) {
3605 *a = a.wrapping_add(b);
3606 }
3607 self.state[operands.dst].set_i64x2(a);
3608 ControlFlow::Continue(())
3609 }
3610
3611 fn vaddf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3612 let mut a = self.state[operands.src1].get_f32x4();
3613 let b = self.state[operands.src2].get_f32x4();
3614 for (a, b) in a.iter_mut().zip(b) {
3615 *a += b;
3616 }
3617 self.state[operands.dst].set_f32x4(a);
3618 ControlFlow::Continue(())
3619 }
3620
3621 fn vaddf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3622 let mut a = self.state[operands.src1].get_f64x2();
3623 let b = self.state[operands.src2].get_f64x2();
3624 for (a, b) in a.iter_mut().zip(b) {
3625 *a += b;
3626 }
3627 self.state[operands.dst].set_f64x2(a);
3628 ControlFlow::Continue(())
3629 }
3630
3631 fn vaddi8x16_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3632 let mut a = self.state[operands.src1].get_i8x16();
3633 let b = self.state[operands.src2].get_i8x16();
3634 for (a, b) in a.iter_mut().zip(b) {
3635 *a = (*a).saturating_add(b);
3636 }
3637 self.state[operands.dst].set_i8x16(a);
3638 ControlFlow::Continue(())
3639 }
3640
3641 fn vaddu8x16_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3642 let mut a = self.state[operands.src1].get_u8x16();
3643 let b = self.state[operands.src2].get_u8x16();
3644 for (a, b) in a.iter_mut().zip(b) {
3645 *a = (*a).saturating_add(b);
3646 }
3647 self.state[operands.dst].set_u8x16(a);
3648 ControlFlow::Continue(())
3649 }
3650
3651 fn vaddi16x8_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3652 let mut a = self.state[operands.src1].get_i16x8();
3653 let b = self.state[operands.src2].get_i16x8();
3654 for (a, b) in a.iter_mut().zip(b) {
3655 *a = (*a).saturating_add(b);
3656 }
3657 self.state[operands.dst].set_i16x8(a);
3658 ControlFlow::Continue(())
3659 }
3660
3661 fn vaddu16x8_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3662 let mut a = self.state[operands.src1].get_u16x8();
3663 let b = self.state[operands.src2].get_u16x8();
3664 for (a, b) in a.iter_mut().zip(b) {
3665 *a = (*a).saturating_add(b);
3666 }
3667 self.state[operands.dst].set_u16x8(a);
3668 ControlFlow::Continue(())
3669 }
3670
3671 fn vaddpairwisei16x8_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3672 let a = self.state[operands.src1].get_i16x8();
3673 let b = self.state[operands.src2].get_i16x8();
3674 let mut result = [0i16; 8];
3675 let half = result.len() / 2;
3676 for i in 0..half {
3677 result[i] = a[2 * i].wrapping_add(a[2 * i + 1]);
3678 result[i + half] = b[2 * i].wrapping_add(b[2 * i + 1]);
3679 }
3680 self.state[operands.dst].set_i16x8(result);
3681 ControlFlow::Continue(())
3682 }
3683
3684 fn vaddpairwisei32x4_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3685 let a = self.state[operands.src1].get_i32x4();
3686 let b = self.state[operands.src2].get_i32x4();
3687 let mut result = [0i32; 4];
3688 result[0] = a[0].wrapping_add(a[1]);
3689 result[1] = a[2].wrapping_add(a[3]);
3690 result[2] = b[0].wrapping_add(b[1]);
3691 result[3] = b[2].wrapping_add(b[3]);
3692 self.state[operands.dst].set_i32x4(result);
3693 ControlFlow::Continue(())
3694 }
3695
3696 fn vshli8x16(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3697 let a = self.state[operands.src1].get_i8x16();
3698 let b = self.state[operands.src2].get_u32();
3699 self.state[operands.dst].set_i8x16(a.map(|a| a.wrapping_shl(b)));
3700 ControlFlow::Continue(())
3701 }
3702
3703 fn vshli16x8(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3704 let a = self.state[operands.src1].get_i16x8();
3705 let b = self.state[operands.src2].get_u32();
3706 self.state[operands.dst].set_i16x8(a.map(|a| a.wrapping_shl(b)));
3707 ControlFlow::Continue(())
3708 }
3709
3710 fn vshli32x4(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3711 let a = self.state[operands.src1].get_i32x4();
3712 let b = self.state[operands.src2].get_u32();
3713 self.state[operands.dst].set_i32x4(a.map(|a| a.wrapping_shl(b)));
3714 ControlFlow::Continue(())
3715 }
3716
3717 fn vshli64x2(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3718 let a = self.state[operands.src1].get_i64x2();
3719 let b = self.state[operands.src2].get_u32();
3720 self.state[operands.dst].set_i64x2(a.map(|a| a.wrapping_shl(b)));
3721 ControlFlow::Continue(())
3722 }
3723
3724 fn vshri8x16_s(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3725 let a = self.state[operands.src1].get_i8x16();
3726 let b = self.state[operands.src2].get_u32();
3727 self.state[operands.dst].set_i8x16(a.map(|a| a.wrapping_shr(b)));
3728 ControlFlow::Continue(())
3729 }
3730
3731 fn vshri16x8_s(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3732 let a = self.state[operands.src1].get_i16x8();
3733 let b = self.state[operands.src2].get_u32();
3734 self.state[operands.dst].set_i16x8(a.map(|a| a.wrapping_shr(b)));
3735 ControlFlow::Continue(())
3736 }
3737
3738 fn vshri32x4_s(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3739 let a = self.state[operands.src1].get_i32x4();
3740 let b = self.state[operands.src2].get_u32();
3741 self.state[operands.dst].set_i32x4(a.map(|a| a.wrapping_shr(b)));
3742 ControlFlow::Continue(())
3743 }
3744
3745 fn vshri64x2_s(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3746 let a = self.state[operands.src1].get_i64x2();
3747 let b = self.state[operands.src2].get_u32();
3748 self.state[operands.dst].set_i64x2(a.map(|a| a.wrapping_shr(b)));
3749 ControlFlow::Continue(())
3750 }
3751
3752 fn vshri8x16_u(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3753 let a = self.state[operands.src1].get_u8x16();
3754 let b = self.state[operands.src2].get_u32();
3755 self.state[operands.dst].set_u8x16(a.map(|a| a.wrapping_shr(b)));
3756 ControlFlow::Continue(())
3757 }
3758
3759 fn vshri16x8_u(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3760 let a = self.state[operands.src1].get_u16x8();
3761 let b = self.state[operands.src2].get_u32();
3762 self.state[operands.dst].set_u16x8(a.map(|a| a.wrapping_shr(b)));
3763 ControlFlow::Continue(())
3764 }
3765
3766 fn vshri32x4_u(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3767 let a = self.state[operands.src1].get_u32x4();
3768 let b = self.state[operands.src2].get_u32();
3769 self.state[operands.dst].set_u32x4(a.map(|a| a.wrapping_shr(b)));
3770 ControlFlow::Continue(())
3771 }
3772
3773 fn vshri64x2_u(&mut self, operands: BinaryOperands<VReg, VReg, XReg>) -> ControlFlow<Done> {
3774 let a = self.state[operands.src1].get_u64x2();
3775 let b = self.state[operands.src2].get_u32();
3776 self.state[operands.dst].set_u64x2(a.map(|a| a.wrapping_shr(b)));
3777 ControlFlow::Continue(())
3778 }
3779
3780 fn vconst128(&mut self, dst: VReg, val: u128) -> ControlFlow<Done> {
3781 self.state[dst].set_u128(val);
3782 ControlFlow::Continue(())
3783 }
3784
3785 fn vsplatx8(&mut self, dst: VReg, src: XReg) -> ControlFlow<Done> {
3786 let val = self.state[src].get_u32() as u8;
3787 self.state[dst].set_u8x16([val; 16]);
3788 ControlFlow::Continue(())
3789 }
3790
3791 fn vsplatx16(&mut self, dst: VReg, src: XReg) -> ControlFlow<Done> {
3792 let val = self.state[src].get_u32() as u16;
3793 self.state[dst].set_u16x8([val; 8]);
3794 ControlFlow::Continue(())
3795 }
3796
3797 fn vsplatx32(&mut self, dst: VReg, src: XReg) -> ControlFlow<Done> {
3798 let val = self.state[src].get_u32();
3799 self.state[dst].set_u32x4([val; 4]);
3800 ControlFlow::Continue(())
3801 }
3802
3803 fn vsplatx64(&mut self, dst: VReg, src: XReg) -> ControlFlow<Done> {
3804 let val = self.state[src].get_u64();
3805 self.state[dst].set_u64x2([val; 2]);
3806 ControlFlow::Continue(())
3807 }
3808
3809 fn vsplatf32(&mut self, dst: VReg, src: FReg) -> ControlFlow<Done> {
3810 let val = self.state[src].get_f32();
3811 self.state[dst].set_f32x4([val; 4]);
3812 ControlFlow::Continue(())
3813 }
3814
3815 fn vsplatf64(&mut self, dst: VReg, src: FReg) -> ControlFlow<Done> {
3816 let val = self.state[src].get_f64();
3817 self.state[dst].set_f64x2([val; 2]);
3818 ControlFlow::Continue(())
3819 }
3820
3821 fn vload8x8_s_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
3822 let val = unsafe { self.load::<[i8; 8]>(ptr, offset) };
3823 self.state[dst].set_i16x8(val.map(|i| i.into()));
3824 ControlFlow::Continue(())
3825 }
3826
3827 fn vload8x8_u_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
3828 let val = unsafe { self.load::<[u8; 8]>(ptr, offset) };
3829 self.state[dst].set_u16x8(val.map(|i| i.into()));
3830 ControlFlow::Continue(())
3831 }
3832
3833 fn vload16x4le_s_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
3834 let val = unsafe { self.load::<[i16; 4]>(ptr, offset) };
3835 self.state[dst].set_i32x4(val.map(|i| i16::from_le(i).into()));
3836 ControlFlow::Continue(())
3837 }
3838
3839 fn vload16x4le_u_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
3840 let val = unsafe { self.load::<[u16; 4]>(ptr, offset) };
3841 self.state[dst].set_u32x4(val.map(|i| u16::from_le(i).into()));
3842 ControlFlow::Continue(())
3843 }
3844
3845 fn vload32x2le_s_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
3846 let val = unsafe { self.load::<[i32; 2]>(ptr, offset) };
3847 self.state[dst].set_i64x2(val.map(|i| i32::from_le(i).into()));
3848 ControlFlow::Continue(())
3849 }
3850
3851 fn vload32x2le_u_offset32(&mut self, dst: VReg, ptr: XReg, offset: i32) -> ControlFlow<Done> {
3852 let val = unsafe { self.load::<[u32; 2]>(ptr, offset) };
3853 self.state[dst].set_u64x2(val.map(|i| u32::from_le(i).into()));
3854 ControlFlow::Continue(())
3855 }
3856
3857 fn vband128(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3858 let a = self.state[operands.src1].get_u128();
3859 let b = self.state[operands.src2].get_u128();
3860 self.state[operands.dst].set_u128(a & b);
3861 ControlFlow::Continue(())
3862 }
3863
3864 fn vbor128(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3865 let a = self.state[operands.src1].get_u128();
3866 let b = self.state[operands.src2].get_u128();
3867 self.state[operands.dst].set_u128(a | b);
3868 ControlFlow::Continue(())
3869 }
3870
3871 fn vbxor128(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
3872 let a = self.state[operands.src1].get_u128();
3873 let b = self.state[operands.src2].get_u128();
3874 self.state[operands.dst].set_u128(a ^ b);
3875 ControlFlow::Continue(())
3876 }
3877
3878 fn vbnot128(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3879 let a = self.state[src].get_u128();
3880 self.state[dst].set_u128(!a);
3881 ControlFlow::Continue(())
3882 }
3883
3884 fn vbitselect128(&mut self, dst: VReg, c: VReg, x: VReg, y: VReg) -> ControlFlow<Done> {
3885 let c = self.state[c].get_u128();
3886 let x = self.state[x].get_u128();
3887 let y = self.state[y].get_u128();
3888 self.state[dst].set_u128((c & x) | (!c & y));
3889 ControlFlow::Continue(())
3890 }
3891
3892 fn vbitmask8x16(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3893 let a = self.state[src].get_u8x16();
3894 let mut result = 0;
3895 for item in a.iter().rev() {
3896 result <<= 1;
3897 result |= (*item >> 7) as u32;
3898 }
3899 self.state[dst].set_u32(result);
3900 ControlFlow::Continue(())
3901 }
3902
3903 fn vbitmask16x8(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3904 let a = self.state[src].get_u16x8();
3905 let mut result = 0;
3906 for item in a.iter().rev() {
3907 result <<= 1;
3908 result |= (*item >> 15) as u32;
3909 }
3910 self.state[dst].set_u32(result);
3911 ControlFlow::Continue(())
3912 }
3913
3914 fn vbitmask32x4(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3915 let a = self.state[src].get_u32x4();
3916 let mut result = 0;
3917 for item in a.iter().rev() {
3918 result <<= 1;
3919 result |= *item >> 31;
3920 }
3921 self.state[dst].set_u32(result);
3922 ControlFlow::Continue(())
3923 }
3924
3925 fn vbitmask64x2(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3926 let a = self.state[src].get_u64x2();
3927 let mut result = 0;
3928 for item in a.iter().rev() {
3929 result <<= 1;
3930 result |= (*item >> 63) as u32;
3931 }
3932 self.state[dst].set_u32(result);
3933 ControlFlow::Continue(())
3934 }
3935
3936 fn valltrue8x16(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3937 let a = self.state[src].get_u8x16();
3938 let result = a.iter().all(|a| *a != 0);
3939 self.state[dst].set_u32(u32::from(result));
3940 ControlFlow::Continue(())
3941 }
3942
3943 fn valltrue16x8(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3944 let a = self.state[src].get_u16x8();
3945 let result = a.iter().all(|a| *a != 0);
3946 self.state[dst].set_u32(u32::from(result));
3947 ControlFlow::Continue(())
3948 }
3949
3950 fn valltrue32x4(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3951 let a = self.state[src].get_u32x4();
3952 let result = a.iter().all(|a| *a != 0);
3953 self.state[dst].set_u32(u32::from(result));
3954 ControlFlow::Continue(())
3955 }
3956
3957 fn valltrue64x2(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3958 let a = self.state[src].get_u64x2();
3959 let result = a.iter().all(|a| *a != 0);
3960 self.state[dst].set_u32(u32::from(result));
3961 ControlFlow::Continue(())
3962 }
3963
3964 fn vanytrue8x16(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3965 let a = self.state[src].get_u8x16();
3966 let result = a.iter().any(|a| *a != 0);
3967 self.state[dst].set_u32(u32::from(result));
3968 ControlFlow::Continue(())
3969 }
3970
3971 fn vanytrue16x8(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3972 let a = self.state[src].get_u16x8();
3973 let result = a.iter().any(|a| *a != 0);
3974 self.state[dst].set_u32(u32::from(result));
3975 ControlFlow::Continue(())
3976 }
3977
3978 fn vanytrue32x4(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3979 let a = self.state[src].get_u32x4();
3980 let result = a.iter().any(|a| *a != 0);
3981 self.state[dst].set_u32(u32::from(result));
3982 ControlFlow::Continue(())
3983 }
3984
3985 fn vanytrue64x2(&mut self, dst: XReg, src: VReg) -> ControlFlow<Done> {
3986 let a = self.state[src].get_u64x2();
3987 let result = a.iter().any(|a| *a != 0);
3988 self.state[dst].set_u32(u32::from(result));
3989 ControlFlow::Continue(())
3990 }
3991
3992 fn vf32x4_from_i32x4_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3993 let a = self.state[src].get_i32x4();
3994 self.state[dst].set_f32x4(a.map(|i| i as f32));
3995 ControlFlow::Continue(())
3996 }
3997
3998 fn vf32x4_from_i32x4_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
3999 let a = self.state[src].get_u32x4();
4000 self.state[dst].set_f32x4(a.map(|i| i as f32));
4001 ControlFlow::Continue(())
4002 }
4003
4004 fn vf64x2_from_i64x2_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4005 let a = self.state[src].get_i64x2();
4006 self.state[dst].set_f64x2(a.map(|i| i as f64));
4007 ControlFlow::Continue(())
4008 }
4009
4010 fn vf64x2_from_i64x2_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4011 let a = self.state[src].get_u64x2();
4012 self.state[dst].set_f64x2(a.map(|i| i as f64));
4013 ControlFlow::Continue(())
4014 }
4015
4016 fn vi32x4_from_f32x4_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4017 let a = self.state[src].get_f32x4();
4018 self.state[dst].set_i32x4(a.map(|f| f as i32));
4019 ControlFlow::Continue(())
4020 }
4021
4022 fn vi32x4_from_f32x4_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4023 let a = self.state[src].get_f32x4();
4024 self.state[dst].set_u32x4(a.map(|f| f as u32));
4025 ControlFlow::Continue(())
4026 }
4027
4028 fn vi64x2_from_f64x2_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4029 let a = self.state[src].get_f64x2();
4030 self.state[dst].set_i64x2(a.map(|f| f as i64));
4031 ControlFlow::Continue(())
4032 }
4033
4034 fn vi64x2_from_f64x2_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4035 let a = self.state[src].get_f64x2();
4036 self.state[dst].set_u64x2(a.map(|f| f as u64));
4037 ControlFlow::Continue(())
4038 }
4039
4040 fn vwidenlow8x16_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4041 let a = *self.state[src].get_i8x16().first_chunk().unwrap();
4042 self.state[dst].set_i16x8(a.map(|i| i.into()));
4043 ControlFlow::Continue(())
4044 }
4045
4046 fn vwidenlow8x16_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4047 let a = *self.state[src].get_u8x16().first_chunk().unwrap();
4048 self.state[dst].set_u16x8(a.map(|i| i.into()));
4049 ControlFlow::Continue(())
4050 }
4051
4052 fn vwidenlow16x8_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4053 let a = *self.state[src].get_i16x8().first_chunk().unwrap();
4054 self.state[dst].set_i32x4(a.map(|i| i.into()));
4055 ControlFlow::Continue(())
4056 }
4057
4058 fn vwidenlow16x8_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4059 let a = *self.state[src].get_u16x8().first_chunk().unwrap();
4060 self.state[dst].set_u32x4(a.map(|i| i.into()));
4061 ControlFlow::Continue(())
4062 }
4063
4064 fn vwidenlow32x4_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4065 let a = *self.state[src].get_i32x4().first_chunk().unwrap();
4066 self.state[dst].set_i64x2(a.map(|i| i.into()));
4067 ControlFlow::Continue(())
4068 }
4069
4070 fn vwidenlow32x4_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4071 let a = *self.state[src].get_u32x4().first_chunk().unwrap();
4072 self.state[dst].set_u64x2(a.map(|i| i.into()));
4073 ControlFlow::Continue(())
4074 }
4075
4076 fn vwidenhigh8x16_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4077 let a = *self.state[src].get_i8x16().last_chunk().unwrap();
4078 self.state[dst].set_i16x8(a.map(|i| i.into()));
4079 ControlFlow::Continue(())
4080 }
4081
4082 fn vwidenhigh8x16_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4083 let a = *self.state[src].get_u8x16().last_chunk().unwrap();
4084 self.state[dst].set_u16x8(a.map(|i| i.into()));
4085 ControlFlow::Continue(())
4086 }
4087
4088 fn vwidenhigh16x8_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4089 let a = *self.state[src].get_i16x8().last_chunk().unwrap();
4090 self.state[dst].set_i32x4(a.map(|i| i.into()));
4091 ControlFlow::Continue(())
4092 }
4093
4094 fn vwidenhigh16x8_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4095 let a = *self.state[src].get_u16x8().last_chunk().unwrap();
4096 self.state[dst].set_u32x4(a.map(|i| i.into()));
4097 ControlFlow::Continue(())
4098 }
4099
4100 fn vwidenhigh32x4_s(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4101 let a = *self.state[src].get_i32x4().last_chunk().unwrap();
4102 self.state[dst].set_i64x2(a.map(|i| i.into()));
4103 ControlFlow::Continue(())
4104 }
4105
4106 fn vwidenhigh32x4_u(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4107 let a = *self.state[src].get_u32x4().last_chunk().unwrap();
4108 self.state[dst].set_u64x2(a.map(|i| i.into()));
4109 ControlFlow::Continue(())
4110 }
4111
4112 fn vnarrow16x8_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4113 let a = self.state[operands.src1].get_i16x8();
4114 let b = self.state[operands.src2].get_i16x8();
4115 let mut result = [0; 16];
4116 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4117 *d = (*i)
4118 .try_into()
4119 .unwrap_or(if *i < 0 { i8::MIN } else { i8::MAX });
4120 }
4121 self.state[operands.dst].set_i8x16(result);
4122 ControlFlow::Continue(())
4123 }
4124
4125 fn vnarrow16x8_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4126 let a = self.state[operands.src1].get_i16x8();
4127 let b = self.state[operands.src2].get_i16x8();
4128 let mut result = [0; 16];
4129 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4130 *d = (*i)
4131 .try_into()
4132 .unwrap_or(if *i < 0 { u8::MIN } else { u8::MAX });
4133 }
4134 self.state[operands.dst].set_u8x16(result);
4135 ControlFlow::Continue(())
4136 }
4137
4138 fn vnarrow32x4_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4139 let a = self.state[operands.src1].get_i32x4();
4140 let b = self.state[operands.src2].get_i32x4();
4141 let mut result = [0; 8];
4142 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4143 *d = (*i)
4144 .try_into()
4145 .unwrap_or(if *i < 0 { i16::MIN } else { i16::MAX });
4146 }
4147 self.state[operands.dst].set_i16x8(result);
4148 ControlFlow::Continue(())
4149 }
4150
4151 fn vnarrow32x4_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4152 let a = self.state[operands.src1].get_i32x4();
4153 let b = self.state[operands.src2].get_i32x4();
4154 let mut result = [0; 8];
4155 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4156 *d = (*i)
4157 .try_into()
4158 .unwrap_or(if *i < 0 { u16::MIN } else { u16::MAX });
4159 }
4160 self.state[operands.dst].set_u16x8(result);
4161 ControlFlow::Continue(())
4162 }
4163
4164 fn vnarrow64x2_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4165 let a = self.state[operands.src1].get_i64x2();
4166 let b = self.state[operands.src2].get_i64x2();
4167 let mut result = [0; 4];
4168 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4169 *d = (*i)
4170 .try_into()
4171 .unwrap_or(if *i < 0 { i32::MIN } else { i32::MAX });
4172 }
4173 self.state[operands.dst].set_i32x4(result);
4174 ControlFlow::Continue(())
4175 }
4176
4177 fn vnarrow64x2_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4178 let a = self.state[operands.src1].get_i64x2();
4179 let b = self.state[operands.src2].get_i64x2();
4180 let mut result = [0; 4];
4181 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4182 *d = (*i)
4183 .try_into()
4184 .unwrap_or(if *i < 0 { u32::MIN } else { u32::MAX });
4185 }
4186 self.state[operands.dst].set_u32x4(result);
4187 ControlFlow::Continue(())
4188 }
4189
4190 fn vunarrow64x2_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4191 let a = self.state[operands.src1].get_u64x2();
4192 let b = self.state[operands.src2].get_u64x2();
4193 let mut result = [0; 4];
4194 for (i, d) in a.iter().chain(&b).zip(&mut result) {
4195 *d = (*i).try_into().unwrap_or(u32::MAX);
4196 }
4197 self.state[operands.dst].set_u32x4(result);
4198 ControlFlow::Continue(())
4199 }
4200
4201 fn vfpromotelow(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4202 let a = self.state[src].get_f32x4();
4203 self.state[dst].set_f64x2([a[0].into(), a[1].into()]);
4204 ControlFlow::Continue(())
4205 }
4206
4207 fn vfdemote(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4208 let a = self.state[src].get_f64x2();
4209 self.state[dst].set_f32x4([a[0] as f32, a[1] as f32, 0.0, 0.0]);
4210 ControlFlow::Continue(())
4211 }
4212
4213 fn vsubi8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4214 let mut a = self.state[operands.src1].get_i8x16();
4215 let b = self.state[operands.src2].get_i8x16();
4216 for (a, b) in a.iter_mut().zip(b) {
4217 *a = a.wrapping_sub(b);
4218 }
4219 self.state[operands.dst].set_i8x16(a);
4220 ControlFlow::Continue(())
4221 }
4222
4223 fn vsubi16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4224 let mut a = self.state[operands.src1].get_i16x8();
4225 let b = self.state[operands.src2].get_i16x8();
4226 for (a, b) in a.iter_mut().zip(b) {
4227 *a = a.wrapping_sub(b);
4228 }
4229 self.state[operands.dst].set_i16x8(a);
4230 ControlFlow::Continue(())
4231 }
4232
4233 fn vsubi32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4234 let mut a = self.state[operands.src1].get_i32x4();
4235 let b = self.state[operands.src2].get_i32x4();
4236 for (a, b) in a.iter_mut().zip(b) {
4237 *a = a.wrapping_sub(b);
4238 }
4239 self.state[operands.dst].set_i32x4(a);
4240 ControlFlow::Continue(())
4241 }
4242
4243 fn vsubi64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4244 let mut a = self.state[operands.src1].get_i64x2();
4245 let b = self.state[operands.src2].get_i64x2();
4246 for (a, b) in a.iter_mut().zip(b) {
4247 *a = a.wrapping_sub(b);
4248 }
4249 self.state[operands.dst].set_i64x2(a);
4250 ControlFlow::Continue(())
4251 }
4252
4253 fn vsubi8x16_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4254 let mut a = self.state[operands.src1].get_i8x16();
4255 let b = self.state[operands.src2].get_i8x16();
4256 for (a, b) in a.iter_mut().zip(b) {
4257 *a = a.saturating_sub(b);
4258 }
4259 self.state[operands.dst].set_i8x16(a);
4260 ControlFlow::Continue(())
4261 }
4262
4263 fn vsubu8x16_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4264 let mut a = self.state[operands.src1].get_u8x16();
4265 let b = self.state[operands.src2].get_u8x16();
4266 for (a, b) in a.iter_mut().zip(b) {
4267 *a = a.saturating_sub(b);
4268 }
4269 self.state[operands.dst].set_u8x16(a);
4270 ControlFlow::Continue(())
4271 }
4272
4273 fn vsubi16x8_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4274 let mut a = self.state[operands.src1].get_i16x8();
4275 let b = self.state[operands.src2].get_i16x8();
4276 for (a, b) in a.iter_mut().zip(b) {
4277 *a = a.saturating_sub(b);
4278 }
4279 self.state[operands.dst].set_i16x8(a);
4280 ControlFlow::Continue(())
4281 }
4282
4283 fn vsubu16x8_sat(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4284 let mut a = self.state[operands.src1].get_u16x8();
4285 let b = self.state[operands.src2].get_u16x8();
4286 for (a, b) in a.iter_mut().zip(b) {
4287 *a = a.saturating_sub(b);
4288 }
4289 self.state[operands.dst].set_u16x8(a);
4290 ControlFlow::Continue(())
4291 }
4292
4293 fn vsubf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4294 let mut a = self.state[operands.src1].get_f64x2();
4295 let b = self.state[operands.src2].get_f64x2();
4296 for (a, b) in a.iter_mut().zip(b) {
4297 *a = *a - b;
4298 }
4299 self.state[operands.dst].set_f64x2(a);
4300 ControlFlow::Continue(())
4301 }
4302
4303 fn vmuli8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4304 let mut a = self.state[operands.src1].get_i8x16();
4305 let b = self.state[operands.src2].get_i8x16();
4306 for (a, b) in a.iter_mut().zip(b) {
4307 *a = a.wrapping_mul(b);
4308 }
4309 self.state[operands.dst].set_i8x16(a);
4310 ControlFlow::Continue(())
4311 }
4312
4313 fn vmuli16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4314 let mut a = self.state[operands.src1].get_i16x8();
4315 let b = self.state[operands.src2].get_i16x8();
4316 for (a, b) in a.iter_mut().zip(b) {
4317 *a = a.wrapping_mul(b);
4318 }
4319 self.state[operands.dst].set_i16x8(a);
4320 ControlFlow::Continue(())
4321 }
4322
4323 fn vmuli32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4324 let mut a = self.state[operands.src1].get_i32x4();
4325 let b = self.state[operands.src2].get_i32x4();
4326 for (a, b) in a.iter_mut().zip(b) {
4327 *a = a.wrapping_mul(b);
4328 }
4329 self.state[operands.dst].set_i32x4(a);
4330 ControlFlow::Continue(())
4331 }
4332
4333 fn vmuli64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4334 let mut a = self.state[operands.src1].get_i64x2();
4335 let b = self.state[operands.src2].get_i64x2();
4336 for (a, b) in a.iter_mut().zip(b) {
4337 *a = a.wrapping_mul(b);
4338 }
4339 self.state[operands.dst].set_i64x2(a);
4340 ControlFlow::Continue(())
4341 }
4342
4343 fn vmulf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4344 let mut a = self.state[operands.src1].get_f64x2();
4345 let b = self.state[operands.src2].get_f64x2();
4346 for (a, b) in a.iter_mut().zip(b) {
4347 *a = *a * b;
4348 }
4349 self.state[operands.dst].set_f64x2(a);
4350 ControlFlow::Continue(())
4351 }
4352
4353 fn vqmulrsi16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4354 let mut a = self.state[operands.src1].get_i16x8();
4355 let b = self.state[operands.src2].get_i16x8();
4356 const MIN: i32 = i16::MIN as i32;
4357 const MAX: i32 = i16::MAX as i32;
4358 for (a, b) in a.iter_mut().zip(b) {
4359 let r = (i32::from(*a) * i32::from(b) + (1 << 14)) >> 15;
4360 *a = r.clamp(MIN, MAX) as i16;
4361 }
4362 self.state[operands.dst].set_i16x8(a);
4363 ControlFlow::Continue(())
4364 }
4365
4366 fn vpopcnt8x16(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4367 let a = self.state[src].get_u8x16();
4368 self.state[dst].set_u8x16(a.map(|i| i.count_ones() as u8));
4369 ControlFlow::Continue(())
4370 }
4371
4372 fn xextractv8x16(&mut self, dst: XReg, src: VReg, lane: u8) -> ControlFlow<Done> {
4373 let a = unsafe { *self.state[src].get_u8x16().get_unchecked(usize::from(lane)) };
4374 self.state[dst].set_u32(u32::from(a));
4375 ControlFlow::Continue(())
4376 }
4377
4378 fn xextractv16x8(&mut self, dst: XReg, src: VReg, lane: u8) -> ControlFlow<Done> {
4379 let a = unsafe { *self.state[src].get_u16x8().get_unchecked(usize::from(lane)) };
4380 self.state[dst].set_u32(u32::from(a));
4381 ControlFlow::Continue(())
4382 }
4383
4384 fn xextractv32x4(&mut self, dst: XReg, src: VReg, lane: u8) -> ControlFlow<Done> {
4385 let a = unsafe { *self.state[src].get_u32x4().get_unchecked(usize::from(lane)) };
4386 self.state[dst].set_u32(a);
4387 ControlFlow::Continue(())
4388 }
4389
4390 fn xextractv64x2(&mut self, dst: XReg, src: VReg, lane: u8) -> ControlFlow<Done> {
4391 let a = unsafe { *self.state[src].get_u64x2().get_unchecked(usize::from(lane)) };
4392 self.state[dst].set_u64(a);
4393 ControlFlow::Continue(())
4394 }
4395
4396 fn fextractv32x4(&mut self, dst: FReg, src: VReg, lane: u8) -> ControlFlow<Done> {
4397 let a = unsafe { *self.state[src].get_f32x4().get_unchecked(usize::from(lane)) };
4398 self.state[dst].set_f32(a);
4399 ControlFlow::Continue(())
4400 }
4401
4402 fn fextractv64x2(&mut self, dst: FReg, src: VReg, lane: u8) -> ControlFlow<Done> {
4403 let a = unsafe { *self.state[src].get_f64x2().get_unchecked(usize::from(lane)) };
4404 self.state[dst].set_f64(a);
4405 ControlFlow::Continue(())
4406 }
4407
4408 fn vinsertx8(
4409 &mut self,
4410 operands: BinaryOperands<VReg, VReg, XReg>,
4411 lane: u8,
4412 ) -> ControlFlow<Done> {
4413 let mut a = self.state[operands.src1].get_u8x16();
4414 let b = self.state[operands.src2].get_u32() as u8;
4415 unsafe {
4416 *a.get_unchecked_mut(usize::from(lane)) = b;
4417 }
4418 self.state[operands.dst].set_u8x16(a);
4419 ControlFlow::Continue(())
4420 }
4421
4422 fn vinsertx16(
4423 &mut self,
4424 operands: BinaryOperands<VReg, VReg, XReg>,
4425 lane: u8,
4426 ) -> ControlFlow<Done> {
4427 let mut a = self.state[operands.src1].get_u16x8();
4428 let b = self.state[operands.src2].get_u32() as u16;
4429 unsafe {
4430 *a.get_unchecked_mut(usize::from(lane)) = b;
4431 }
4432 self.state[operands.dst].set_u16x8(a);
4433 ControlFlow::Continue(())
4434 }
4435
4436 fn vinsertx32(
4437 &mut self,
4438 operands: BinaryOperands<VReg, VReg, XReg>,
4439 lane: u8,
4440 ) -> ControlFlow<Done> {
4441 let mut a = self.state[operands.src1].get_u32x4();
4442 let b = self.state[operands.src2].get_u32();
4443 unsafe {
4444 *a.get_unchecked_mut(usize::from(lane)) = b;
4445 }
4446 self.state[operands.dst].set_u32x4(a);
4447 ControlFlow::Continue(())
4448 }
4449
4450 fn vinsertx64(
4451 &mut self,
4452 operands: BinaryOperands<VReg, VReg, XReg>,
4453 lane: u8,
4454 ) -> ControlFlow<Done> {
4455 let mut a = self.state[operands.src1].get_u64x2();
4456 let b = self.state[operands.src2].get_u64();
4457 unsafe {
4458 *a.get_unchecked_mut(usize::from(lane)) = b;
4459 }
4460 self.state[operands.dst].set_u64x2(a);
4461 ControlFlow::Continue(())
4462 }
4463
4464 fn vinsertf32(
4465 &mut self,
4466 operands: BinaryOperands<VReg, VReg, FReg>,
4467 lane: u8,
4468 ) -> ControlFlow<Done> {
4469 let mut a = self.state[operands.src1].get_f32x4();
4470 let b = self.state[operands.src2].get_f32();
4471 unsafe {
4472 *a.get_unchecked_mut(usize::from(lane)) = b;
4473 }
4474 self.state[operands.dst].set_f32x4(a);
4475 ControlFlow::Continue(())
4476 }
4477
4478 fn vinsertf64(
4479 &mut self,
4480 operands: BinaryOperands<VReg, VReg, FReg>,
4481 lane: u8,
4482 ) -> ControlFlow<Done> {
4483 let mut a = self.state[operands.src1].get_f64x2();
4484 let b = self.state[operands.src2].get_f64();
4485 unsafe {
4486 *a.get_unchecked_mut(usize::from(lane)) = b;
4487 }
4488 self.state[operands.dst].set_f64x2(a);
4489 ControlFlow::Continue(())
4490 }
4491
4492 fn veq8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4493 let a = self.state[operands.src1].get_u8x16();
4494 let b = self.state[operands.src2].get_u8x16();
4495 let mut c = [0; 16];
4496 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4497 *c = if a == b { u8::MAX } else { 0 };
4498 }
4499 self.state[operands.dst].set_u8x16(c);
4500 ControlFlow::Continue(())
4501 }
4502
4503 fn vneq8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4504 let a = self.state[operands.src1].get_u8x16();
4505 let b = self.state[operands.src2].get_u8x16();
4506 let mut c = [0; 16];
4507 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4508 *c = if a != b { u8::MAX } else { 0 };
4509 }
4510 self.state[operands.dst].set_u8x16(c);
4511 ControlFlow::Continue(())
4512 }
4513
4514 fn vslt8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4515 let a = self.state[operands.src1].get_i8x16();
4516 let b = self.state[operands.src2].get_i8x16();
4517 let mut c = [0; 16];
4518 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4519 *c = if a < b { u8::MAX } else { 0 };
4520 }
4521 self.state[operands.dst].set_u8x16(c);
4522 ControlFlow::Continue(())
4523 }
4524
4525 fn vslteq8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4526 let a = self.state[operands.src1].get_i8x16();
4527 let b = self.state[operands.src2].get_i8x16();
4528 let mut c = [0; 16];
4529 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4530 *c = if a <= b { u8::MAX } else { 0 };
4531 }
4532 self.state[operands.dst].set_u8x16(c);
4533 ControlFlow::Continue(())
4534 }
4535
4536 fn vult8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4537 let a = self.state[operands.src1].get_u8x16();
4538 let b = self.state[operands.src2].get_u8x16();
4539 let mut c = [0; 16];
4540 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4541 *c = if a < b { u8::MAX } else { 0 };
4542 }
4543 self.state[operands.dst].set_u8x16(c);
4544 ControlFlow::Continue(())
4545 }
4546
4547 fn vulteq8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4548 let a = self.state[operands.src1].get_u8x16();
4549 let b = self.state[operands.src2].get_u8x16();
4550 let mut c = [0; 16];
4551 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4552 *c = if a <= b { u8::MAX } else { 0 };
4553 }
4554 self.state[operands.dst].set_u8x16(c);
4555 ControlFlow::Continue(())
4556 }
4557
4558 fn veq16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4559 let a = self.state[operands.src1].get_u16x8();
4560 let b = self.state[operands.src2].get_u16x8();
4561 let mut c = [0; 8];
4562 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4563 *c = if a == b { u16::MAX } else { 0 };
4564 }
4565 self.state[operands.dst].set_u16x8(c);
4566 ControlFlow::Continue(())
4567 }
4568
4569 fn vneq16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4570 let a = self.state[operands.src1].get_u16x8();
4571 let b = self.state[operands.src2].get_u16x8();
4572 let mut c = [0; 8];
4573 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4574 *c = if a != b { u16::MAX } else { 0 };
4575 }
4576 self.state[operands.dst].set_u16x8(c);
4577 ControlFlow::Continue(())
4578 }
4579
4580 fn vslt16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4581 let a = self.state[operands.src1].get_i16x8();
4582 let b = self.state[operands.src2].get_i16x8();
4583 let mut c = [0; 8];
4584 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4585 *c = if a < b { u16::MAX } else { 0 };
4586 }
4587 self.state[operands.dst].set_u16x8(c);
4588 ControlFlow::Continue(())
4589 }
4590
4591 fn vslteq16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4592 let a = self.state[operands.src1].get_i16x8();
4593 let b = self.state[operands.src2].get_i16x8();
4594 let mut c = [0; 8];
4595 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4596 *c = if a <= b { u16::MAX } else { 0 };
4597 }
4598 self.state[operands.dst].set_u16x8(c);
4599 ControlFlow::Continue(())
4600 }
4601
4602 fn vult16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4603 let a = self.state[operands.src1].get_u16x8();
4604 let b = self.state[operands.src2].get_u16x8();
4605 let mut c = [0; 8];
4606 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4607 *c = if a < b { u16::MAX } else { 0 };
4608 }
4609 self.state[operands.dst].set_u16x8(c);
4610 ControlFlow::Continue(())
4611 }
4612
4613 fn vulteq16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4614 let a = self.state[operands.src1].get_u16x8();
4615 let b = self.state[operands.src2].get_u16x8();
4616 let mut c = [0; 8];
4617 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4618 *c = if a <= b { u16::MAX } else { 0 };
4619 }
4620 self.state[operands.dst].set_u16x8(c);
4621 ControlFlow::Continue(())
4622 }
4623
4624 fn veq32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4625 let a = self.state[operands.src1].get_u32x4();
4626 let b = self.state[operands.src2].get_u32x4();
4627 let mut c = [0; 4];
4628 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4629 *c = if a == b { u32::MAX } else { 0 };
4630 }
4631 self.state[operands.dst].set_u32x4(c);
4632 ControlFlow::Continue(())
4633 }
4634
4635 fn vneq32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4636 let a = self.state[operands.src1].get_u32x4();
4637 let b = self.state[operands.src2].get_u32x4();
4638 let mut c = [0; 4];
4639 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4640 *c = if a != b { u32::MAX } else { 0 };
4641 }
4642 self.state[operands.dst].set_u32x4(c);
4643 ControlFlow::Continue(())
4644 }
4645
4646 fn vslt32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4647 let a = self.state[operands.src1].get_i32x4();
4648 let b = self.state[operands.src2].get_i32x4();
4649 let mut c = [0; 4];
4650 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4651 *c = if a < b { u32::MAX } else { 0 };
4652 }
4653 self.state[operands.dst].set_u32x4(c);
4654 ControlFlow::Continue(())
4655 }
4656
4657 fn vslteq32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4658 let a = self.state[operands.src1].get_i32x4();
4659 let b = self.state[operands.src2].get_i32x4();
4660 let mut c = [0; 4];
4661 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4662 *c = if a <= b { u32::MAX } else { 0 };
4663 }
4664 self.state[operands.dst].set_u32x4(c);
4665 ControlFlow::Continue(())
4666 }
4667
4668 fn vult32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4669 let a = self.state[operands.src1].get_u32x4();
4670 let b = self.state[operands.src2].get_u32x4();
4671 let mut c = [0; 4];
4672 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4673 *c = if a < b { u32::MAX } else { 0 };
4674 }
4675 self.state[operands.dst].set_u32x4(c);
4676 ControlFlow::Continue(())
4677 }
4678
4679 fn vulteq32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4680 let a = self.state[operands.src1].get_u32x4();
4681 let b = self.state[operands.src2].get_u32x4();
4682 let mut c = [0; 4];
4683 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4684 *c = if a <= b { u32::MAX } else { 0 };
4685 }
4686 self.state[operands.dst].set_u32x4(c);
4687 ControlFlow::Continue(())
4688 }
4689
4690 fn veq64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4691 let a = self.state[operands.src1].get_u64x2();
4692 let b = self.state[operands.src2].get_u64x2();
4693 let mut c = [0; 2];
4694 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4695 *c = if a == b { u64::MAX } else { 0 };
4696 }
4697 self.state[operands.dst].set_u64x2(c);
4698 ControlFlow::Continue(())
4699 }
4700
4701 fn vneq64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4702 let a = self.state[operands.src1].get_u64x2();
4703 let b = self.state[operands.src2].get_u64x2();
4704 let mut c = [0; 2];
4705 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4706 *c = if a != b { u64::MAX } else { 0 };
4707 }
4708 self.state[operands.dst].set_u64x2(c);
4709 ControlFlow::Continue(())
4710 }
4711
4712 fn vslt64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4713 let a = self.state[operands.src1].get_i64x2();
4714 let b = self.state[operands.src2].get_i64x2();
4715 let mut c = [0; 2];
4716 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4717 *c = if a < b { u64::MAX } else { 0 };
4718 }
4719 self.state[operands.dst].set_u64x2(c);
4720 ControlFlow::Continue(())
4721 }
4722
4723 fn vslteq64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4724 let a = self.state[operands.src1].get_i64x2();
4725 let b = self.state[operands.src2].get_i64x2();
4726 let mut c = [0; 2];
4727 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4728 *c = if a <= b { u64::MAX } else { 0 };
4729 }
4730 self.state[operands.dst].set_u64x2(c);
4731 ControlFlow::Continue(())
4732 }
4733
4734 fn vult64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4735 let a = self.state[operands.src1].get_u64x2();
4736 let b = self.state[operands.src2].get_u64x2();
4737 let mut c = [0; 2];
4738 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4739 *c = if a < b { u64::MAX } else { 0 };
4740 }
4741 self.state[operands.dst].set_u64x2(c);
4742 ControlFlow::Continue(())
4743 }
4744
4745 fn vulteq64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4746 let a = self.state[operands.src1].get_u64x2();
4747 let b = self.state[operands.src2].get_u64x2();
4748 let mut c = [0; 2];
4749 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
4750 *c = if a <= b { u64::MAX } else { 0 };
4751 }
4752 self.state[operands.dst].set_u64x2(c);
4753 ControlFlow::Continue(())
4754 }
4755
4756 fn vneg8x16(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4757 let a = self.state[src].get_i8x16();
4758 self.state[dst].set_i8x16(a.map(|i| i.wrapping_neg()));
4759 ControlFlow::Continue(())
4760 }
4761
4762 fn vneg16x8(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4763 let a = self.state[src].get_i16x8();
4764 self.state[dst].set_i16x8(a.map(|i| i.wrapping_neg()));
4765 ControlFlow::Continue(())
4766 }
4767
4768 fn vneg32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4769 let a = self.state[src].get_i32x4();
4770 self.state[dst].set_i32x4(a.map(|i| i.wrapping_neg()));
4771 ControlFlow::Continue(())
4772 }
4773
4774 fn vneg64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4775 let a = self.state[src].get_i64x2();
4776 self.state[dst].set_i64x2(a.map(|i| i.wrapping_neg()));
4777 ControlFlow::Continue(())
4778 }
4779
4780 fn vnegf64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4781 let a = self.state[src].get_f64x2();
4782 self.state[dst].set_f64x2(a.map(|i| -i));
4783 ControlFlow::Continue(())
4784 }
4785
4786 fn vmin8x16_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4787 let mut a = self.state[operands.src1].get_i8x16();
4788 let b = self.state[operands.src2].get_i8x16();
4789 for (a, b) in a.iter_mut().zip(&b) {
4790 *a = (*a).min(*b);
4791 }
4792 self.state[operands.dst].set_i8x16(a);
4793 ControlFlow::Continue(())
4794 }
4795
4796 fn vmin8x16_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4797 let mut a = self.state[operands.src1].get_u8x16();
4798 let b = self.state[operands.src2].get_u8x16();
4799 for (a, b) in a.iter_mut().zip(&b) {
4800 *a = (*a).min(*b);
4801 }
4802 self.state[operands.dst].set_u8x16(a);
4803 ControlFlow::Continue(())
4804 }
4805
4806 fn vmin16x8_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4807 let mut a = self.state[operands.src1].get_i16x8();
4808 let b = self.state[operands.src2].get_i16x8();
4809 for (a, b) in a.iter_mut().zip(&b) {
4810 *a = (*a).min(*b);
4811 }
4812 self.state[operands.dst].set_i16x8(a);
4813 ControlFlow::Continue(())
4814 }
4815
4816 fn vmin16x8_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4817 let mut a = self.state[operands.src1].get_u16x8();
4818 let b = self.state[operands.src2].get_u16x8();
4819 for (a, b) in a.iter_mut().zip(&b) {
4820 *a = (*a).min(*b);
4821 }
4822 self.state[operands.dst].set_u16x8(a);
4823 ControlFlow::Continue(())
4824 }
4825
4826 fn vmin32x4_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4827 let mut a = self.state[operands.src1].get_i32x4();
4828 let b = self.state[operands.src2].get_i32x4();
4829 for (a, b) in a.iter_mut().zip(&b) {
4830 *a = (*a).min(*b);
4831 }
4832 self.state[operands.dst].set_i32x4(a);
4833 ControlFlow::Continue(())
4834 }
4835
4836 fn vmin32x4_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4837 let mut a = self.state[operands.src1].get_u32x4();
4838 let b = self.state[operands.src2].get_u32x4();
4839 for (a, b) in a.iter_mut().zip(&b) {
4840 *a = (*a).min(*b);
4841 }
4842 self.state[operands.dst].set_u32x4(a);
4843 ControlFlow::Continue(())
4844 }
4845
4846 fn vmax8x16_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4847 let mut a = self.state[operands.src1].get_i8x16();
4848 let b = self.state[operands.src2].get_i8x16();
4849 for (a, b) in a.iter_mut().zip(&b) {
4850 *a = (*a).max(*b);
4851 }
4852 self.state[operands.dst].set_i8x16(a);
4853 ControlFlow::Continue(())
4854 }
4855
4856 fn vmax8x16_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4857 let mut a = self.state[operands.src1].get_u8x16();
4858 let b = self.state[operands.src2].get_u8x16();
4859 for (a, b) in a.iter_mut().zip(&b) {
4860 *a = (*a).max(*b);
4861 }
4862 self.state[operands.dst].set_u8x16(a);
4863 ControlFlow::Continue(())
4864 }
4865
4866 fn vmax16x8_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4867 let mut a = self.state[operands.src1].get_i16x8();
4868 let b = self.state[operands.src2].get_i16x8();
4869 for (a, b) in a.iter_mut().zip(&b) {
4870 *a = (*a).max(*b);
4871 }
4872 self.state[operands.dst].set_i16x8(a);
4873 ControlFlow::Continue(())
4874 }
4875
4876 fn vmax16x8_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4877 let mut a = self.state[operands.src1].get_u16x8();
4878 let b = self.state[operands.src2].get_u16x8();
4879 for (a, b) in a.iter_mut().zip(&b) {
4880 *a = (*a).max(*b);
4881 }
4882 self.state[operands.dst].set_u16x8(a);
4883 ControlFlow::Continue(())
4884 }
4885
4886 fn vmax32x4_s(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4887 let mut a = self.state[operands.src1].get_i32x4();
4888 let b = self.state[operands.src2].get_i32x4();
4889 for (a, b) in a.iter_mut().zip(&b) {
4890 *a = (*a).max(*b);
4891 }
4892 self.state[operands.dst].set_i32x4(a);
4893 ControlFlow::Continue(())
4894 }
4895
4896 fn vmax32x4_u(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4897 let mut a = self.state[operands.src1].get_u32x4();
4898 let b = self.state[operands.src2].get_u32x4();
4899 for (a, b) in a.iter_mut().zip(&b) {
4900 *a = (*a).max(*b);
4901 }
4902 self.state[operands.dst].set_u32x4(a);
4903 ControlFlow::Continue(())
4904 }
4905
4906 fn vabs8x16(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4907 let a = self.state[src].get_i8x16();
4908 self.state[dst].set_i8x16(a.map(|i| i.wrapping_abs()));
4909 ControlFlow::Continue(())
4910 }
4911
4912 fn vabs16x8(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4913 let a = self.state[src].get_i16x8();
4914 self.state[dst].set_i16x8(a.map(|i| i.wrapping_abs()));
4915 ControlFlow::Continue(())
4916 }
4917
4918 fn vabs32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4919 let a = self.state[src].get_i32x4();
4920 self.state[dst].set_i32x4(a.map(|i| i.wrapping_abs()));
4921 ControlFlow::Continue(())
4922 }
4923
4924 fn vabs64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4925 let a = self.state[src].get_i64x2();
4926 self.state[dst].set_i64x2(a.map(|i| i.wrapping_abs()));
4927 ControlFlow::Continue(())
4928 }
4929
4930 fn vabsf32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4931 let a = self.state[src].get_f32x4();
4932 self.state[dst].set_f32x4(a.map(|i| i.wasm_abs()));
4933 ControlFlow::Continue(())
4934 }
4935
4936 fn vabsf64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow<Done> {
4937 let a = self.state[src].get_f64x2();
4938 self.state[dst].set_f64x2(a.map(|i| i.wasm_abs()));
4939 ControlFlow::Continue(())
4940 }
4941
4942 fn vmaximumf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4943 let mut a = self.state[operands.src1].get_f32x4();
4944 let b = self.state[operands.src2].get_f32x4();
4945 for (a, b) in a.iter_mut().zip(&b) {
4946 *a = a.wasm_maximum(*b);
4947 }
4948 self.state[operands.dst].set_f32x4(a);
4949 ControlFlow::Continue(())
4950 }
4951
4952 fn vmaximumf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4953 let mut a = self.state[operands.src1].get_f64x2();
4954 let b = self.state[operands.src2].get_f64x2();
4955 for (a, b) in a.iter_mut().zip(&b) {
4956 *a = a.wasm_maximum(*b);
4957 }
4958 self.state[operands.dst].set_f64x2(a);
4959 ControlFlow::Continue(())
4960 }
4961
4962 fn vminimumf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4963 let mut a = self.state[operands.src1].get_f32x4();
4964 let b = self.state[operands.src2].get_f32x4();
4965 for (a, b) in a.iter_mut().zip(&b) {
4966 *a = a.wasm_minimum(*b);
4967 }
4968 self.state[operands.dst].set_f32x4(a);
4969 ControlFlow::Continue(())
4970 }
4971
4972 fn vminimumf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4973 let mut a = self.state[operands.src1].get_f64x2();
4974 let b = self.state[operands.src2].get_f64x2();
4975 for (a, b) in a.iter_mut().zip(&b) {
4976 *a = a.wasm_minimum(*b);
4977 }
4978 self.state[operands.dst].set_f64x2(a);
4979 ControlFlow::Continue(())
4980 }
4981
4982 fn vshuffle(&mut self, dst: VReg, src1: VReg, src2: VReg, mask: u128) -> ControlFlow<Done> {
4983 let a = self.state[src1].get_u8x16();
4984 let b = self.state[src2].get_u8x16();
4985 let result = mask.to_le_bytes().map(|m| {
4986 if m < 16 {
4987 a[m as usize]
4988 } else {
4989 b[m as usize - 16]
4990 }
4991 });
4992 self.state[dst].set_u8x16(result);
4993 ControlFlow::Continue(())
4994 }
4995
4996 fn vswizzlei8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
4997 let src1 = self.state[operands.src1].get_i8x16();
4998 let src2 = self.state[operands.src2].get_i8x16();
4999 let mut dst = [0i8; 16];
5000 for (i, &idx) in src2.iter().enumerate() {
5001 if (idx as usize) < 16 {
5002 dst[i] = src1[idx as usize];
5003 } else {
5004 dst[i] = 0
5005 }
5006 }
5007 self.state[operands.dst].set_i8x16(dst);
5008 ControlFlow::Continue(())
5009 }
5010
5011 fn vavground8x16(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5012 let mut a = self.state[operands.src1].get_u8x16();
5013 let b = self.state[operands.src2].get_u8x16();
5014 for (a, b) in a.iter_mut().zip(&b) {
5015 *a = ((u32::from(*a) + u32::from(*b) + 1) / 2) as u8;
5017 }
5018 self.state[operands.dst].set_u8x16(a);
5019 ControlFlow::Continue(())
5020 }
5021
5022 fn vavground16x8(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5023 let mut a = self.state[operands.src1].get_u16x8();
5024 let b = self.state[operands.src2].get_u16x8();
5025 for (a, b) in a.iter_mut().zip(&b) {
5026 *a = ((u32::from(*a) + u32::from(*b) + 1) / 2) as u16;
5028 }
5029 self.state[operands.dst].set_u16x8(a);
5030 ControlFlow::Continue(())
5031 }
5032
5033 fn veqf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5034 let a = self.state[operands.src1].get_f32x4();
5035 let b = self.state[operands.src2].get_f32x4();
5036 let mut c = [0; 4];
5037 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5038 *c = if a == b { u32::MAX } else { 0 };
5039 }
5040 self.state[operands.dst].set_u32x4(c);
5041 ControlFlow::Continue(())
5042 }
5043
5044 fn vneqf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5045 let a = self.state[operands.src1].get_f32x4();
5046 let b = self.state[operands.src2].get_f32x4();
5047 let mut c = [0; 4];
5048 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5049 *c = if a != b { u32::MAX } else { 0 };
5050 }
5051 self.state[operands.dst].set_u32x4(c);
5052 ControlFlow::Continue(())
5053 }
5054
5055 fn vltf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5056 let a = self.state[operands.src1].get_f32x4();
5057 let b = self.state[operands.src2].get_f32x4();
5058 let mut c = [0; 4];
5059 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5060 *c = if a < b { u32::MAX } else { 0 };
5061 }
5062 self.state[operands.dst].set_u32x4(c);
5063 ControlFlow::Continue(())
5064 }
5065
5066 fn vlteqf32x4(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5067 let a = self.state[operands.src1].get_f32x4();
5068 let b = self.state[operands.src2].get_f32x4();
5069 let mut c = [0; 4];
5070 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5071 *c = if a <= b { u32::MAX } else { 0 };
5072 }
5073 self.state[operands.dst].set_u32x4(c);
5074 ControlFlow::Continue(())
5075 }
5076
5077 fn veqf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5078 let a = self.state[operands.src1].get_f64x2();
5079 let b = self.state[operands.src2].get_f64x2();
5080 let mut c = [0; 2];
5081 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5082 *c = if a == b { u64::MAX } else { 0 };
5083 }
5084 self.state[operands.dst].set_u64x2(c);
5085 ControlFlow::Continue(())
5086 }
5087
5088 fn vneqf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5089 let a = self.state[operands.src1].get_f64x2();
5090 let b = self.state[operands.src2].get_f64x2();
5091 let mut c = [0; 2];
5092 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5093 *c = if a != b { u64::MAX } else { 0 };
5094 }
5095 self.state[operands.dst].set_u64x2(c);
5096 ControlFlow::Continue(())
5097 }
5098
5099 fn vltf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5100 let a = self.state[operands.src1].get_f64x2();
5101 let b = self.state[operands.src2].get_f64x2();
5102 let mut c = [0; 2];
5103 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5104 *c = if a < b { u64::MAX } else { 0 };
5105 }
5106 self.state[operands.dst].set_u64x2(c);
5107 ControlFlow::Continue(())
5108 }
5109
5110 fn vlteqf64x2(&mut self, operands: BinaryOperands<VReg>) -> ControlFlow<Done> {
5111 let a = self.state[operands.src1].get_f64x2();
5112 let b = self.state[operands.src2].get_f64x2();
5113 let mut c = [0; 2];
5114 for ((a, b), c) in a.iter().zip(&b).zip(&mut c) {
5115 *c = if a <= b { u64::MAX } else { 0 };
5116 }
5117 self.state[operands.dst].set_u64x2(c);
5118 ControlFlow::Continue(())
5119 }
5120
5121 fn vfma32x4(&mut self, dst: VReg, a: VReg, b: VReg, c: VReg) -> ControlFlow<Done> {
5122 let mut a = self.state[a].get_f32x4();
5123 let b = self.state[b].get_f32x4();
5124 let c = self.state[c].get_f32x4();
5125 for ((a, b), c) in a.iter_mut().zip(b).zip(c) {
5126 *a = a.wasm_mul_add(b, c);
5127 }
5128 self.state[dst].set_f32x4(a);
5129 ControlFlow::Continue(())
5130 }
5131
5132 fn vfma64x2(&mut self, dst: VReg, a: VReg, b: VReg, c: VReg) -> ControlFlow<Done> {
5133 let mut a = self.state[a].get_f64x2();
5134 let b = self.state[b].get_f64x2();
5135 let c = self.state[c].get_f64x2();
5136 for ((a, b), c) in a.iter_mut().zip(b).zip(c) {
5137 *a = a.wasm_mul_add(b, c);
5138 }
5139 self.state[dst].set_f64x2(a);
5140 ControlFlow::Continue(())
5141 }
5142
5143 fn vselect(
5144 &mut self,
5145 dst: VReg,
5146 cond: XReg,
5147 if_nonzero: VReg,
5148 if_zero: VReg,
5149 ) -> ControlFlow<Done> {
5150 let result = if self.state[cond].get_u32() != 0 {
5151 self.state[if_nonzero]
5152 } else {
5153 self.state[if_zero]
5154 };
5155 self.state[dst] = result;
5156 ControlFlow::Continue(())
5157 }
5158
5159 fn xadd128(
5160 &mut self,
5161 dst_lo: XReg,
5162 dst_hi: XReg,
5163 lhs_lo: XReg,
5164 lhs_hi: XReg,
5165 rhs_lo: XReg,
5166 rhs_hi: XReg,
5167 ) -> ControlFlow<Done> {
5168 let lhs = self.get_i128(lhs_lo, lhs_hi);
5169 let rhs = self.get_i128(rhs_lo, rhs_hi);
5170 let result = lhs.wrapping_add(rhs);
5171 self.set_i128(dst_lo, dst_hi, result);
5172 ControlFlow::Continue(())
5173 }
5174
5175 fn xsub128(
5176 &mut self,
5177 dst_lo: XReg,
5178 dst_hi: XReg,
5179 lhs_lo: XReg,
5180 lhs_hi: XReg,
5181 rhs_lo: XReg,
5182 rhs_hi: XReg,
5183 ) -> ControlFlow<Done> {
5184 let lhs = self.get_i128(lhs_lo, lhs_hi);
5185 let rhs = self.get_i128(rhs_lo, rhs_hi);
5186 let result = lhs.wrapping_sub(rhs);
5187 self.set_i128(dst_lo, dst_hi, result);
5188 ControlFlow::Continue(())
5189 }
5190
5191 fn xwidemul64_s(
5192 &mut self,
5193 dst_lo: XReg,
5194 dst_hi: XReg,
5195 lhs: XReg,
5196 rhs: XReg,
5197 ) -> ControlFlow<Done> {
5198 let lhs = self.state[lhs].get_i64();
5199 let rhs = self.state[rhs].get_i64();
5200 let result = i128::from(lhs).wrapping_mul(i128::from(rhs));
5201 self.set_i128(dst_lo, dst_hi, result);
5202 ControlFlow::Continue(())
5203 }
5204
5205 fn xwidemul64_u(
5206 &mut self,
5207 dst_lo: XReg,
5208 dst_hi: XReg,
5209 lhs: XReg,
5210 rhs: XReg,
5211 ) -> ControlFlow<Done> {
5212 let lhs = self.state[lhs].get_u64();
5213 let rhs = self.state[rhs].get_u64();
5214 let result = u128::from(lhs).wrapping_mul(u128::from(rhs));
5215 self.set_i128(dst_lo, dst_hi, result as i128);
5216 ControlFlow::Continue(())
5217 }
5218}