xref: /wasmtime-44.0.1/pulley/tests/all/interp.rs (revision 2283e84f)
1 //! Interpreter tests.
2 
3 use interp::Val;
4 use pulley_interpreter::{
5     interp::{DoneReason, Vm},
6     *,
7 };
8 use std::{cell::UnsafeCell, fmt::Debug, ptr::NonNull};
9 
encoded(ops: &[Op]) -> Vec<u8>10 fn encoded(ops: &[Op]) -> Vec<u8> {
11     let mut encoded = vec![];
12     for op in ops {
13         op.encode(&mut encoded);
14     }
15     log::trace!("encoded: {encoded:?}");
16     encoded
17 }
18 
run(vm: &mut Vm, ops: &[Op]) -> Result<(), NonNull<u8>>19 unsafe fn run(vm: &mut Vm, ops: &[Op]) -> Result<(), NonNull<u8>> {
20     let _ = env_logger::try_init();
21     let ops = encoded(ops);
22     match unsafe { vm.call(NonNull::from(&ops[..]).cast(), &[], []) } {
23         DoneReason::ReturnToHost(_) => Ok(()),
24         DoneReason::Trap { pc, .. } => Err(pc),
25         DoneReason::CallIndirectHost { .. } => unimplemented!(),
26     }
27 }
28 
assert_one<R0, R1, V>( xs: impl IntoIterator<Item = (R0, V)>, op: impl Into<Op> + Debug, result: R1, expected: u64, ) where R0: Into<AnyReg>, R1: Into<AnyReg>, V: Into<Val>,29 unsafe fn assert_one<R0, R1, V>(
30     xs: impl IntoIterator<Item = (R0, V)>,
31     op: impl Into<Op> + Debug,
32     result: R1,
33     expected: u64,
34 ) where
35     R0: Into<AnyReg>,
36     R1: Into<AnyReg>,
37     V: Into<Val>,
38 {
39     eprintln!("=======================================================");
40     let mut vm = Vm::new().unwrap();
41 
42     for (reg, val) in xs {
43         let reg = reg.into();
44         let val = val.into();
45         eprintln!("{reg} = {val:#018x}");
46         match (reg, val) {
47             (AnyReg::X(r), Val::XReg(v)) => vm.state_mut()[r] = v,
48             (AnyReg::F(r), Val::FReg(v)) => vm.state_mut()[r] = v,
49             (AnyReg::V(_), Val::VReg(_)) => todo!(),
50             (kind, val) => panic!("register kind and value mismatch: {kind:?} and {val:?}"),
51         }
52     }
53 
54     eprintln!("op = {op:?}");
55     let op = op.into();
56 
57     unsafe {
58         run(&mut vm, &[op, Op::Ret(Ret {})]).expect("should not trap");
59     }
60 
61     eprintln!("expected = {expected:#018x}");
62 
63     let actual = match result.into() {
64         AnyReg::X(r) => vm.state_mut()[r].get_u64(),
65         AnyReg::F(r) => vm.state_mut()[r].get_f64().to_bits(),
66         AnyReg::V(_) => todo!(),
67     };
68     eprintln!("actual   = {actual:#018x}");
69 
70     assert_eq!(expected, actual);
71 }
72 
x(x: u8) -> XReg73 fn x(x: u8) -> XReg {
74     XReg::new(x).unwrap()
75 }
76 
f(f: u8) -> FReg77 fn f(f: u8) -> FReg {
78     FReg::new(f).unwrap()
79 }
80 
81 #[test]
xconst8()82 fn xconst8() {
83     for (expected, imm) in [(42u64, 42i8), (u64::MAX, -1i8)] {
84         unsafe {
85             assert_one(
86                 [(x(0), 0x1234567812345678u64)],
87                 Xconst8 { dst: x(0), imm },
88                 x(0),
89                 expected,
90             );
91         }
92     }
93 }
94 
95 #[test]
xconst16()96 fn xconst16() {
97     for (expected, imm) in [(42u64, 42i16), (u64::MAX, -1i16)] {
98         unsafe {
99             assert_one(
100                 [(x(0), 0x1234567812345678u64)],
101                 Xconst16 { dst: x(0), imm },
102                 x(0),
103                 expected,
104             );
105         }
106     }
107 }
108 
109 #[test]
xconst32()110 fn xconst32() {
111     for (expected, imm) in [(42u64, 42i32), (u64::MAX, -1i32)] {
112         unsafe {
113             assert_one(
114                 [(x(0), 0x1234567812345678u64)],
115                 Xconst32 { dst: x(0), imm },
116                 x(0),
117                 expected,
118             );
119         }
120     }
121 }
122 
123 #[test]
xconst64()124 fn xconst64() {
125     for (expected, imm) in [(42u64, 42i64), (u64::MAX, -1i64)] {
126         unsafe {
127             assert_one(
128                 [(x(0), 0x1234567812345678u64)],
129                 Xconst64 { dst: x(0), imm },
130                 x(0),
131                 expected,
132             );
133         }
134     }
135 }
136 
137 #[test]
xadd32()138 fn xadd32() {
139     for (expected, a, b) in [
140         (42u64 | 0x1234567800000000, 10u64, 32u64),
141         (0x1234567800000000, u32::MAX as _, 1),
142     ] {
143         unsafe {
144             assert_one(
145                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
146                 Xadd32 {
147                     operands: BinaryOperands {
148                         dst: x(0),
149                         src1: x(1),
150                         src2: x(2),
151                     },
152                 },
153                 x(0),
154                 expected,
155             );
156         }
157     }
158 }
159 
160 #[test]
xadd64()161 fn xadd64() {
162     for (expected, a, b) in [(42u64, 10u64, 32u64), (0, u64::MAX, 1)] {
163         unsafe {
164             assert_one(
165                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
166                 Xadd64 {
167                     operands: BinaryOperands {
168                         dst: x(0),
169                         src1: x(1),
170                         src2: x(2),
171                     },
172                 },
173                 x(0),
174                 expected,
175             );
176         }
177     }
178 }
179 
180 #[test]
xeq64()181 fn xeq64() {
182     for (expected, a, b) in [
183         (1u64, 0u64, 0u64),
184         (0, 0, 1),
185         (1, u64::MAX, u64::MAX),
186         (0, u64::MAX, u64::MAX - 1),
187     ] {
188         unsafe {
189             assert_one(
190                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
191                 Xeq64 {
192                     operands: BinaryOperands {
193                         dst: x(0),
194                         src1: x(1),
195                         src2: x(2),
196                     },
197                 },
198                 x(0),
199                 expected | 0x1234567800000000,
200             );
201         }
202     }
203 }
204 
205 #[test]
xneq64()206 fn xneq64() {
207     for (expected, a, b) in [
208         (0u64, 0u64, 0u64),
209         (1, 0, 1),
210         (0, u64::MAX, u64::MAX),
211         (1, u64::MAX, u64::MAX - 1),
212     ] {
213         unsafe {
214             assert_one(
215                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
216                 Xneq64 {
217                     operands: BinaryOperands {
218                         dst: x(0),
219                         src1: x(1),
220                         src2: x(2),
221                     },
222                 },
223                 x(0),
224                 expected | 0x1234567800000000,
225             );
226         }
227     }
228 }
229 
230 #[test]
xslt64()231 fn xslt64() {
232     for (expected, a, b) in [
233         (0u64, 0u64, 0u64),
234         (0, 1, 0),
235         (1, 0, 1),
236         (0, 0, -1 as _),
237         (1, -1 as _, 0),
238         (0, i64::MAX as u64, i64::MAX as u64),
239         (0, i64::MAX as u64, i64::MAX as u64 - 1),
240         (1, i64::MAX as u64 - 1, i64::MAX as u64),
241         (0, i64::MIN as u64, i64::MIN as u64),
242         (0, i64::MIN as u64 + 1, i64::MIN as u64),
243         (1, i64::MIN as u64, i64::MIN as u64 + 1),
244     ] {
245         unsafe {
246             assert_one(
247                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
248                 Xslt64 {
249                     operands: BinaryOperands {
250                         dst: x(0),
251                         src1: x(1),
252                         src2: x(2),
253                     },
254                 },
255                 x(0),
256                 expected | 0x1234567800000000,
257             );
258         }
259     }
260 }
261 
262 #[test]
xslteq64()263 fn xslteq64() {
264     for (expected, a, b) in [
265         (1u64, 0u64, 0u64),
266         (0, 1, 0),
267         (1, 0, 1),
268         (0, 0, -1 as _),
269         (1, -1 as _, 0),
270         (1, i64::MAX as u64, i64::MAX as u64),
271         (0, i64::MAX as u64, i64::MAX as u64 - 1),
272         (1, i64::MAX as u64 - 1, i64::MAX as u64),
273         (1, i64::MIN as u64, i64::MIN as u64),
274         (0, i64::MIN as u64 + 1, i64::MIN as u64),
275         (1, i64::MIN as u64, i64::MIN as u64 + 1),
276     ] {
277         unsafe {
278             assert_one(
279                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
280                 Xslteq64 {
281                     operands: BinaryOperands {
282                         dst: x(0),
283                         src1: x(1),
284                         src2: x(2),
285                     },
286                 },
287                 x(0),
288                 expected | 0x1234567800000000,
289             );
290         }
291     }
292 }
293 
294 #[test]
xult64()295 fn xult64() {
296     for (expected, a, b) in [
297         (0u64, 0u64, 0u64),
298         (0, 1, 0),
299         (1, 0, 1),
300         (0, u64::MAX, u64::MAX),
301         (0, u64::MAX, u64::MAX - 1),
302         (1, u64::MAX - 1, u64::MAX),
303         (0, i64::MIN as u64, 0),
304         (1, 0, i64::MIN as u64),
305     ] {
306         unsafe {
307             assert_one(
308                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
309                 Xult64 {
310                     operands: BinaryOperands {
311                         dst: x(0),
312                         src1: x(1),
313                         src2: x(2),
314                     },
315                 },
316                 x(0),
317                 expected | 0x1234567800000000,
318             );
319         }
320     }
321 }
322 
323 #[test]
xulteq64()324 fn xulteq64() {
325     for (expected, a, b) in [
326         (1u64, 0u64, 0u64),
327         (0, 1, 0),
328         (1, 0, 1),
329         (1, u64::MAX, u64::MAX),
330         (0, u64::MAX, u64::MAX - 1),
331         (1, u64::MAX - 1, u64::MAX),
332         (0, i64::MIN as u64, 0),
333         (1, 0, i64::MIN as u64),
334     ] {
335         unsafe {
336             assert_one(
337                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
338                 Xulteq64 {
339                     operands: BinaryOperands {
340                         dst: x(0),
341                         src1: x(1),
342                         src2: x(2),
343                     },
344                 },
345                 x(0),
346                 expected | 0x1234567800000000,
347             );
348         }
349     }
350 }
351 
352 #[test]
xeq32()353 fn xeq32() {
354     for (expected, a, b) in [
355         (1u64, 0u64, 0u64),
356         (0, 0, 1),
357         (1, u64::MAX, u64::MAX),
358         (0, u64::MAX, u64::MAX - 1),
359         (1, 0xffffffff00000001, 1),
360         (0, 0xffffffff00000000, 1),
361         (0, 0xffffffff00000001, 0),
362         (1, 0xffffffff00000000, 0),
363     ] {
364         unsafe {
365             assert_one(
366                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
367                 Xeq32 {
368                     operands: BinaryOperands {
369                         dst: x(0),
370                         src1: x(1),
371                         src2: x(2),
372                     },
373                 },
374                 x(0),
375                 expected | 0x1234567800000000,
376             );
377         }
378     }
379 }
380 
381 #[test]
xneq32()382 fn xneq32() {
383     for (expected, a, b) in [
384         (0u64, 0u64, 0u64),
385         (1, 0, 1),
386         (0, u64::MAX, u64::MAX),
387         (1, u64::MAX, u64::MAX - 1),
388         (0, 0xffffffff00000000, 0),
389     ] {
390         unsafe {
391             assert_one(
392                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
393                 Xneq32 {
394                     operands: BinaryOperands {
395                         dst: x(0),
396                         src1: x(1),
397                         src2: x(2),
398                     },
399                 },
400                 x(0),
401                 expected | 0x1234567800000000,
402             );
403         }
404     }
405 }
406 
407 #[test]
xslt32()408 fn xslt32() {
409     for (expected, a, b) in [
410         (0u64, 0u64, 0u64),
411         (0, 1, 0),
412         (1, 0, 1),
413         (0, 0, -1 as _),
414         (1, -1 as _, 0),
415         (0, i64::MAX as u64, i64::MAX as u64),
416         (0, i64::MAX as u64, i64::MAX as u64 - 1),
417         (1, i64::MAX as u64 - 1, i64::MAX as u64),
418         (0, i64::MIN as u64, i64::MIN as u64),
419         (0, i64::MIN as u64 + 1, i64::MIN as u64),
420         (1, i64::MIN as u64, i64::MIN as u64 + 1),
421         (1, 0x00000000ffffffff, 0),
422         (0, 0, 0x00000000ffffffff),
423     ] {
424         unsafe {
425             assert_one(
426                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
427                 Xslt32 {
428                     operands: BinaryOperands {
429                         dst: x(0),
430                         src1: x(1),
431                         src2: x(2),
432                     },
433                 },
434                 x(0),
435                 expected | 0x1234567800000000,
436             );
437         }
438     }
439 }
440 
441 #[test]
xslteq32()442 fn xslteq32() {
443     for (expected, a, b) in [
444         (1u64, 0u64, 0u64),
445         (0, 1, 0),
446         (1, 0, 1),
447         (0, 0, -1 as _),
448         (1, -1 as _, 0),
449         (1, i64::MAX as u64, i64::MAX as u64),
450         (0, i64::MAX as u64, i64::MAX as u64 - 1),
451         (1, i64::MAX as u64 - 1, i64::MAX as u64),
452         (1, i64::MIN as u64, i64::MIN as u64),
453         (0, i64::MIN as u64 + 1, i64::MIN as u64),
454         (1, i64::MIN as u64, i64::MIN as u64 + 1),
455     ] {
456         unsafe {
457             assert_one(
458                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
459                 Xslteq32 {
460                     operands: BinaryOperands {
461                         dst: x(0),
462                         src1: x(1),
463                         src2: x(2),
464                     },
465                 },
466                 x(0),
467                 expected | 0x1234567800000000,
468             );
469         }
470     }
471 }
472 
473 #[test]
xult32()474 fn xult32() {
475     for (expected, a, b) in [
476         (0u64, 0u64, 0u64),
477         (0, 1, 0),
478         (1, 0, 1),
479         (0, 0x00000000ffffffff, 0xfffffffffffffffe),
480         (1, 0xfffffffffffffffe, 0x00000000ffffffff),
481         (0, 0x00000000ffffffff, 0xffffffffffffffff),
482         (0, 0xfffffffffffffffe, 0x00000000fffffffe),
483     ] {
484         unsafe {
485             assert_one(
486                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
487                 Xult32 {
488                     operands: BinaryOperands {
489                         dst: x(0),
490                         src1: x(1),
491                         src2: x(2),
492                     },
493                 },
494                 x(0),
495                 expected | 0x1234567800000000,
496             );
497         }
498     }
499 }
500 
501 #[test]
xulteq32()502 fn xulteq32() {
503     for (expected, a, b) in [
504         (1u64, 0u64, 0u64),
505         (0, 1, 0),
506         (1, 0, 1),
507         (0, 0x00000000ffffffff, 0xfffffffffffffffe),
508         (1, 0xfffffffffffffffe, 0x00000000ffffffff),
509         (1, 0x00000000ffffffff, 0xffffffffffffffff),
510         (1, 0xfffffffffffffffe, 0x00000000fffffffe),
511     ] {
512         unsafe {
513             assert_one(
514                 [(x(0), 0x1234567812345678), (x(1), a), (x(2), b)],
515                 Xulteq32 {
516                     operands: BinaryOperands {
517                         dst: x(0),
518                         src1: x(1),
519                         src2: x(2),
520                     },
521                 },
522                 x(0),
523                 expected | 0x1234567800000000,
524             );
525         }
526     }
527 }
528 
529 #[test]
xload32le_o32()530 fn xload32le_o32() {
531     let a = UnsafeCell::new([11u32.to_le(), 22u32.to_le()]);
532     let b = UnsafeCell::new([33u32.to_le(), 44u32.to_le()]);
533     let c = UnsafeCell::new([55u32.to_le(), 66u32.to_le()]);
534     let d = UnsafeCell::new([(i32::MIN as u32).to_le(), (i32::MAX as u32).to_le()]);
535 
536     for (expected, addr, offset) in [
537         (11, a.get(), 0),
538         (22, a.get(), 4),
539         (33, b.get(), 0),
540         (44, b.get(), 4),
541         (55, c.get(), 0),
542         (66, c.get(), 4),
543         (i32::MIN as u32 as u64, d.get(), 0),
544         (i32::MAX as u32 as u64, d.get(), 4),
545     ] {
546         let init = 0x1234567812345678u64;
547         let expected = init & !u64::from(u32::MAX) | expected;
548         unsafe {
549             assert_one(
550                 [
551                     (x(0), Val::from(init)),
552                     (x(1), Val::from(addr.cast::<u8>())),
553                 ],
554                 XLoad32LeO32 {
555                     dst: x(0),
556                     addr: AddrO32 { addr: x(1), offset },
557                 },
558                 x(0),
559                 expected,
560             );
561         }
562     }
563 }
564 
565 #[test]
xload64le_o32()566 fn xload64le_o32() {
567     let a = UnsafeCell::new([11u64.to_le(), 22u64.to_le()]);
568     let b = UnsafeCell::new([33u64.to_le(), 44u64.to_le()]);
569     let c = UnsafeCell::new([55u64.to_le(), 66u64.to_le()]);
570     let d = UnsafeCell::new([(-1i64 as u64).to_le(), (i64::MAX as u64).to_le()]);
571 
572     for (expected, addr, offset) in [
573         (11, a.get(), 0),
574         (22, a.get(), 8),
575         (33, b.get(), 0),
576         (44, b.get(), 8),
577         (55, c.get(), 0),
578         (66, c.get(), 8),
579         (-1i64 as u64, d.get(), 0),
580         (i64::MAX as u64, d.get(), 8),
581     ] {
582         unsafe {
583             assert_one(
584                 [
585                     (x(0), Val::from(0x1234567812345678u64)),
586                     (x(1), Val::from(addr)),
587                 ],
588                 XLoad64LeO32 {
589                     dst: x(0),
590                     addr: AddrO32 { addr: x(1), offset },
591                 },
592                 x(0),
593                 expected,
594             );
595         }
596     }
597 }
598 
599 #[test]
xstore32_le_o32()600 fn xstore32_le_o32() {
601     let a = UnsafeCell::new([0x12u8, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78]);
602     let b = UnsafeCell::new([0x12u8, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78]);
603     let c = UnsafeCell::new([0x12u8, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78]);
604 
605     unsafe {
606         for (val, addr, offset) in [
607             (0x11111111u32, a.get(), 0),
608             (0x22222222, b.get(), 4),
609             (0x33333333, c.get(), 2),
610         ] {
611             let val = val as u64;
612             assert_one(
613                 [(x(0), Val::from(addr)), (x(1), Val::from(val))],
614                 XStore32LeO32 {
615                     addr: AddrO32 { addr: x(0), offset },
616                     src: x(1),
617                 },
618                 x(1),
619                 val,
620             );
621         }
622     }
623 
624     let a = u64::from_be_bytes(a.into_inner());
625     let expected = 0x1111111112345678u64;
626     eprintln!("expected(a) = {expected:#018x}");
627     eprintln!("actual(a)   = {a:#018x}");
628     assert_eq!(a, expected);
629 
630     let b = u64::from_be_bytes(b.into_inner());
631     let expected = 0x1234567822222222u64;
632     eprintln!("expected(b) = {expected:#018x}");
633     eprintln!("actual(b)   = {b:#018x}");
634     assert_eq!(b, expected);
635 
636     let c = u64::from_be_bytes(c.into_inner());
637     let expected = 0x1234333333335678u64;
638     eprintln!("expected(c) = {expected:#018x}");
639     eprintln!("actual(c)   = {c:#018x}");
640     assert_eq!(c, expected);
641 }
642 
643 #[test]
644 
xstore64_le_o32()645 fn xstore64_le_o32() {
646     let a = UnsafeCell::new([0x1234567812345678, 0x1234567812345678, 0x1234567812345678]);
647 
648     unsafe {
649         for (val, addr, offset) in [
650             (0x1111111111111111u64, a.get(), 0),
651             (0x2222222222222222, a.get(), 8),
652             (0x3333333333333333, a.get(), 16),
653         ] {
654             assert_one(
655                 [(x(0), Val::from(addr)), (x(1), Val::from(val))],
656                 XStore64LeO32 {
657                     src: x(1),
658                     addr: AddrO32 { addr: x(0), offset },
659                 },
660                 x(1),
661                 val,
662             );
663         }
664     }
665 
666     let [a, b, c] = a.into_inner();
667 
668     let expected = 0x1111111111111111u64;
669     eprintln!("expected(a) = {expected:#018x}");
670     eprintln!("actual(a)   = {a:#018x}");
671     assert_eq!(a, expected);
672 
673     let expected = 0x2222222222222222u64;
674     eprintln!("expected(b) = {expected:#018x}");
675     eprintln!("actual(b)   = {b:#018x}");
676     assert_eq!(b, expected);
677 
678     let expected = 0x3333333333333333u64;
679     eprintln!("expected(c) = {expected:#018x}");
680     eprintln!("actual(c)   = {c:#018x}");
681     assert_eq!(c, expected);
682 }
683 
684 #[test]
bitcast_int_from_float_32()685 fn bitcast_int_from_float_32() {
686     for val in [
687         0.0,
688         1.0,
689         9.87654321,
690         f32::MAX,
691         f32::MIN,
692         f32::NAN,
693         f32::INFINITY,
694         f32::NEG_INFINITY,
695         f32::EPSILON,
696         f32::MIN_POSITIVE,
697     ] {
698         unsafe {
699             assert_one(
700                 [(f(0), val)],
701                 BitcastIntFromFloat32 {
702                     dst: x(0),
703                     src: f(0),
704                 },
705                 x(0),
706                 val.to_bits() as u64,
707             );
708         }
709     }
710 }
711 
712 #[test]
bitcast_int_from_float_64()713 fn bitcast_int_from_float_64() {
714     for val in [
715         0.0,
716         1.0,
717         9.87654321,
718         f64::MAX,
719         f64::MIN,
720         f64::NAN,
721         f64::INFINITY,
722         f64::NEG_INFINITY,
723         f64::EPSILON,
724         f64::MIN_POSITIVE,
725     ] {
726         unsafe {
727             assert_one(
728                 [(f(0), val)],
729                 BitcastIntFromFloat64 {
730                     dst: x(0),
731                     src: f(0),
732                 },
733                 x(0),
734                 val.to_bits(),
735             );
736         }
737     }
738 }
739 
740 #[test]
bitcast_float_from_int_32()741 fn bitcast_float_from_int_32() {
742     for val in [
743         0.0,
744         1.0,
745         9.87654321,
746         f32::MAX,
747         f32::MIN,
748         f32::NAN,
749         f32::INFINITY,
750         f32::NEG_INFINITY,
751         f32::EPSILON,
752         f32::MIN_POSITIVE,
753     ] {
754         let val = val.to_bits() as u64;
755         unsafe {
756             assert_one(
757                 [(x(0), val)],
758                 BitcastFloatFromInt32 {
759                     dst: f(0),
760                     src: x(0),
761                 },
762                 f(0),
763                 val,
764             );
765         }
766     }
767 }
768 
769 #[test]
bitcast_float_from_int_64()770 fn bitcast_float_from_int_64() {
771     for val in [
772         0.0,
773         1.0,
774         9.87654321,
775         f64::MAX,
776         f64::MIN,
777         f64::NAN,
778         f64::INFINITY,
779         f64::NEG_INFINITY,
780         f64::EPSILON,
781         f64::MIN_POSITIVE,
782     ] {
783         let val = val.to_bits();
784         unsafe {
785             assert_one(
786                 [(x(0), val)],
787                 BitcastFloatFromInt64 {
788                     dst: f(0),
789                     src: x(0),
790                 },
791                 f(0),
792                 val,
793             );
794         }
795     }
796 }
797 
798 #[test]
trap()799 fn trap() {
800     let mut vm = Vm::new().unwrap();
801     let dst = XReg::new(0).unwrap();
802 
803     unsafe {
804         run(
805             &mut vm,
806             &[
807                 Op::Xconst16(Xconst16 { dst, imm: 1 }),
808                 Op::ExtendedOp(ExtendedOp::Trap(Trap {})),
809                 Op::Xconst16(Xconst16 { dst, imm: 2 }),
810                 Op::Ret(Ret {}),
811             ],
812         )
813         .unwrap_err();
814     }
815 
816     // `dst` should not have been written to the second time.
817     assert_eq!(vm.state()[dst].get_u32(), 1);
818 }
819